| 134 | } |
| 135 | |
| 136 | void load(void) // load map into memory and extract everything important about it (assumes struct to be zeroed: can only be called once) |
| 137 | { |
| 138 | static uchar *staticbuffer = NULL; |
| 139 | if(!staticbuffer) staticbuffer = new uchar[FLOORPLANBUFSIZE]; // this buffer gets reused for every map load several times (also: because of this, load() is not thread safe) |
| 140 | |
| 141 | stream *f = NULL; |
| 142 | int restofhead; |
| 143 | string filename, tmp; |
| 144 | |
| 145 | if(!validmapname(fname)) err = "illegal filename"; |
| 146 | if(err) goto loadfailed; |
| 147 | |
| 148 | // load map files, prepare sendmap buffer |
| 149 | { |
| 150 | formatstring(filename)("%s%s.cfg", fpath, fname); |
| 151 | path(filename); |
| 152 | uchar *cfgraw = (uchar *)loadfile(filename, &cfglen); |
| 153 | if(cfgraw) |
| 154 | { |
| 155 | tigerhash(cfghash, cfgraw, cfglen); |
| 156 | loopk(cfglen) if(cfgraw[k] > 0x7f || (cfgraw[k] < 0x20 && !isspace(cfgraw[k]))) err = "illegal chars in cfg file"; |
| 157 | } |
| 158 | formatstring(filename)("%s%s.cgz", fpath, fname); |
| 159 | path(filename); |
| 160 | cgzraw = (uchar *)loadfile(filename, &cgzlen); |
| 161 | if(cgzraw) tigerhash(cgzhash, cgzraw, cgzlen); |
| 162 | if(!cgzraw) err = "loading cgz failed"; |
| 163 | else if(cfglen > MAXCFGFILESIZE) err = "cfg file too big"; |
| 164 | else if(cgzlen >= MAXMAPSENDSIZE) err = "cgz file too big"; |
| 165 | else if(cfgraw) |
| 166 | { |
| 167 | uLongf gzbufsize = GZBUFSIZE; |
| 168 | ASSERT(GZBUFSIZE < FLOORPLANBUFSIZE); |
| 169 | if(compress2(staticbuffer, &gzbufsize, cfgraw, cfglen, 9) != Z_OK) gzbufsize = 0; |
| 170 | cfggzlen = (int) gzbufsize; |
| 171 | if(cgzlen + cfggzlen < MAXMAPSENDSIZE) |
| 172 | { // map is small enough to be sent |
| 173 | cfgrawgz = new uchar[cfggzlen]; |
| 174 | memcpy(cfgrawgz, staticbuffer, cfggzlen); |
| 175 | } |
| 176 | else err = "cgz + cfg.gz too big to send"; |
| 177 | } |
| 178 | DELETEA(cfgraw); |
| 179 | } |
| 180 | if(err) goto loadfailed; |
| 181 | |
| 182 | // extract entity data and header info; compile map statistics; create floorplan |
| 183 | { |
| 184 | const int sizeof_header = sizeof(header), sizeof_baseheader = sizeof(header) - sizeof(int) * 16; |
| 185 | f = opengzfile(filename, "rb"); |
| 186 | header *h = (header *)staticbuffer; |
| 187 | if(!f) err = "can't open map file"; |
| 188 | else if(f->read(h, sizeof_baseheader) != sizeof_baseheader || (strncmp(h->head, "CUBE", 4) && strncmp(h->head, "ACMP",4))) err = "bad map file"; |
| 189 | if(err) goto loadfailed; |
| 190 | |
| 191 | lilswap(&h->version, 4); // version, headersize, sfactor, numents |
| 192 | version = h->version; |
| 193 | headersize = fixmapheadersize(h->version, h->headersize); |
nothing calls this directly
no test coverage detected