p_setup.c (10349B)
1 #include <math.h> 2 3 #include "m_swap.h" 4 #include "z_zone.h" 5 #include "m_bbox.h" 6 #include "g_game.h" 7 #include "i_system.h" 8 #include "w_wad.h" 9 #include "doomdef.h" 10 #include "p_local.h" 11 #include "s_sound.h" 12 #include "doomstat.h" 13 14 #define MAX_DEATHMATCH_STARTS 10 15 16 vertex_t* vertexes; 17 int numvertexes; 18 int numsegs; 19 seg_t* segs; 20 int numsectors; 21 sector_t* sectors; 22 int numsubsectors; 23 subsector_t* subsectors; 24 int numnodes; 25 node_t* nodes; 26 int numlines; 27 line_t* lines; 28 int numsides; 29 side_t* sides; 30 int bmapwidth; 31 int bmapheight; 32 short* blockmap; 33 short* blockmaplump; 34 fixed_t bmaporgx; 35 fixed_t bmaporgy; 36 mobj_t** blocklinks; 37 byte* rejectmatrix; 38 mapthing_t deathmatchstarts[MAX_DEATHMATCH_STARTS]; 39 mapthing_t* deathmatch_p; 40 mapthing_t playerstarts[MAXPLAYERS]; 41 42 void P_SpawnMapThing(mapthing_t* mthing); 43 44 void 45 P_LoadVertexes(int lump) 46 { 47 mapvertex_t* ml; 48 vertex_t* li; 49 byte* data; 50 int i; 51 52 numvertexes = W_LumpLength(lump) / sizeof(mapvertex_t); 53 vertexes = Z_Malloc(numvertexes*sizeof(vertex_t),PU_LEVEL,0); 54 data = W_CacheLumpNum(lump,PU_STATIC); 55 ml = (mapvertex_t *)data; 56 li = vertexes; 57 for (i = 0; i < numvertexes; ++i, ++li, ++ml) { 58 li->x = SHORT(ml->x)<<FRACBITS; 59 li->y = SHORT(ml->y)<<FRACBITS; 60 } 61 Z_Free(data); 62 } 63 64 void 65 P_LoadSegs(int lump) 66 { 67 byte* data; 68 mapseg_t* ml; 69 seg_t* li; 70 line_t* ldef; 71 int i, linedef, side; 72 73 numsegs = W_LumpLength(lump) / sizeof(mapseg_t); 74 segs = Z_Malloc(numsegs*sizeof(seg_t),PU_LEVEL,0); 75 memset(segs, 0, numsegs*sizeof(seg_t)); 76 data = W_CacheLumpNum(lump,PU_STATIC); 77 ml = (mapseg_t*)data; 78 li = segs; 79 for (i = 0; i < numsegs; ++i, ++li, ++ml) { 80 li->v1 = &vertexes[SHORT(ml->v1)]; 81 li->v2 = &vertexes[SHORT(ml->v2)]; 82 li->angle = (SHORT(ml->angle))<<16; 83 li->offset = (SHORT(ml->offset))<<16; 84 linedef = SHORT(ml->linedef); 85 ldef = &lines[linedef]; 86 li->linedef = ldef; 87 side = SHORT(ml->side); 88 li->sidedef = &sides[ldef->sidenum[side]]; 89 li->frontsector = sides[ldef->sidenum[side]].sector; 90 if(ldef-> flags & ML_TWOSIDED) li->backsector = sides[ldef->sidenum[side^1]].sector; 91 else li->backsector = 0; 92 } 93 Z_Free(data); 94 } 95 96 void 97 P_LoadSubsectors(int lump) 98 { 99 mapsubsector_t* ms; 100 subsector_t* ss; 101 byte* data; 102 int i; 103 104 numsubsectors = W_LumpLength(lump) / sizeof(mapsubsector_t); 105 subsectors = Z_Malloc(numsubsectors * sizeof(subsector_t), PU_LEVEL, 0); 106 data = W_CacheLumpNum(lump, PU_STATIC); 107 ms = (mapsubsector_t*)data; 108 memset(subsectors, 0, numsubsectors*sizeof(subsector_t)); 109 ss = subsectors; 110 for (i = 0; i < numsubsectors; ++i, ++ss, ++ms) { 111 ss->numlines = SHORT(ms->numsegs); 112 ss->firstline = SHORT(ms->firstseg); 113 } 114 Z_Free(data); 115 } 116 117 void 118 P_LoadSectors(int lump) 119 { 120 mapsector_t* ms; 121 sector_t* ss; 122 byte* data; 123 int i; 124 125 numsectors = W_LumpLength(lump) / sizeof(mapsector_t); 126 sectors = Z_Malloc(numsectors * sizeof(sector_t), PU_LEVEL, 0); 127 memset(sectors, 0, numsectors * sizeof(sector_t)); 128 data = W_CacheLumpNum(lump,PU_STATIC); 129 ms = (mapsector_t*)data; 130 ss = sectors; 131 for (i = 0; i < numsectors; ++i, ++ss, ++ms) { 132 ss->floorheight = SHORT(ms->floorheight)<<FRACBITS; 133 ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS; 134 ss->floorpic = R_FlatNumForName(ms->floorpic); 135 ss->ceilingpic = R_FlatNumForName(ms->ceilingpic); 136 ss->lightlevel = SHORT(ms->lightlevel); 137 ss->special = SHORT(ms->special); 138 ss->tag = SHORT(ms->tag); 139 ss->thinglist = NULL; 140 } 141 Z_Free(data); 142 } 143 144 void 145 P_LoadNodes(int lump) 146 { 147 byte* data; 148 mapnode_t* mn; 149 node_t* no; 150 int i, j, k; 151 152 numnodes = W_LumpLength(lump) / sizeof(mapnode_t); 153 nodes = Z_Malloc(numnodes*sizeof(node_t),PU_LEVEL,0); 154 data = W_CacheLumpNum(lump,PU_STATIC); 155 mn = (mapnode_t*)data; 156 no = nodes; 157 for (i = 0; i < numnodes; ++i, ++no, ++mn) { 158 no->x = SHORT(mn->x)<<FRACBITS; 159 no->y = SHORT(mn->y)<<FRACBITS; 160 no->dx = SHORT(mn->dx)<<FRACBITS; 161 no->dy = SHORT(mn->dy)<<FRACBITS; 162 for (j = 0; j < 2; ++j) { 163 no->children[j] = SHORT(mn->children[j]); 164 for (k = 0; k < 4; ++k) no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS; 165 } 166 } 167 Z_Free(data); 168 } 169 170 void 171 P_LoadThings(int lump) 172 { 173 mapthing_t* mt; 174 byte* data; 175 int i, numthings; 176 boolean spawn; 177 data = W_CacheLumpNum(lump, PU_STATIC); 178 179 numthings = W_LumpLength(lump) / sizeof(mapthing_t); 180 mt = (mapthing_t *)data; 181 for (i = 0; i < numthings; ++i, ++mt) { 182 spawn = true; 183 if(spawn == false) break; 184 mt->x = SHORT(mt->x); 185 mt->y = SHORT(mt->y); 186 mt->angle = SHORT(mt->angle); 187 mt->type = SHORT(mt->type); 188 mt->options = SHORT(mt->options); 189 P_SpawnMapThing(mt); 190 } 191 Z_Free(data); 192 } 193 194 void 195 P_LoadLineDefs(int lump) 196 { 197 line_t* ld; 198 vertex_t* v1; 199 vertex_t* v2; 200 byte* data; 201 int i; 202 maplinedef_t* mld; 203 204 numlines = W_LumpLength(lump) / sizeof(maplinedef_t); 205 lines = Z_Malloc(numlines*sizeof(line_t),PU_LEVEL,0); 206 memset(lines, 0, numlines*sizeof(line_t)); 207 data = W_CacheLumpNum(lump,PU_STATIC); 208 mld = (maplinedef_t*)data; 209 ld = lines; 210 for (i = 0; i < numlines; ++i, ++mld, ++ld) { 211 ld->flags = SHORT(mld->flags); 212 ld->special = SHORT(mld->special); 213 ld->tag = SHORT(mld->tag); 214 v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; 215 v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; 216 ld->dx = v2->x - v1->x; 217 ld->dy = v2->y - v1->y; 218 if(!ld->dx) ld->slopetype = ST_VERTICAL; 219 else if (!ld->dy) ld->slopetype = ST_HORIZONTAL; 220 else { 221 if(FixedDiv(ld->dy , ld->dx) > 0) ld->slopetype = ST_POSITIVE; 222 else ld->slopetype = ST_NEGATIVE; 223 } 224 if(v1->x < v2->x) { 225 ld->bbox[BOXLEFT] = v1->x; 226 ld->bbox[BOXRIGHT] = v2->x; 227 } else { 228 ld->bbox[BOXLEFT] = v2->x; 229 ld->bbox[BOXRIGHT] = v1->x; 230 } 231 if (v1->y < v2->y) { 232 ld->bbox[BOXBOTTOM] = v1->y; 233 ld->bbox[BOXTOP] = v2->y; 234 } else { 235 ld->bbox[BOXBOTTOM] = v2->y; 236 ld->bbox[BOXTOP] = v1->y; 237 } 238 ld->sidenum[0] = SHORT(mld->sidenum[0]); 239 ld->sidenum[1] = SHORT(mld->sidenum[1]); 240 if(ld->sidenum[0] != -1) ld->frontsector = sides[ld->sidenum[0]].sector; 241 else ld->frontsector = 0; 242 if(ld->sidenum[1] != -1) ld->backsector = sides[ld->sidenum[1]].sector; 243 else ld->backsector = 0; 244 } 245 Z_Free(data); 246 } 247 248 void 249 P_LoadSideDefs(int lump) 250 { 251 mapsidedef_t* msd; 252 side_t* sd; 253 byte* data; 254 int i; 255 256 numsides = W_LumpLength(lump) / sizeof(mapsidedef_t); 257 sides = Z_Malloc(numsides*sizeof(side_t),PU_LEVEL,0); 258 memset(sides, 0, numsides*sizeof(side_t)); 259 data = W_CacheLumpNum(lump,PU_STATIC); 260 msd = (mapsidedef_t*)data; 261 sd = sides; 262 for (i = 0; i < numsides; ++i, ++msd, ++sd) { 263 sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS; 264 sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS; 265 sd->toptexture = R_TextureNumForName(msd->toptexture); 266 sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); 267 sd->midtexture = R_TextureNumForName(msd->midtexture); 268 sd->sector = §ors[SHORT(msd->sector)]; 269 } 270 Z_Free(data); 271 } 272 273 void 274 P_LoadBlockMap(int lump) 275 { 276 int i, count; 277 278 blockmaplump = W_CacheLumpNum(lump,PU_LEVEL); 279 blockmap = blockmaplump+4; 280 count = W_LumpLength(lump)/2; 281 for (i = 0 ; i < count ; ++i) blockmaplump[i] = SHORT(blockmaplump[i]); 282 bmaporgx = blockmaplump[0]<<FRACBITS; 283 bmaporgy = blockmaplump[1]<<FRACBITS; 284 bmapwidth = blockmaplump[2]; 285 bmapheight = blockmaplump[3]; 286 count = sizeof(*blocklinks) * bmapwidth*bmapheight; 287 blocklinks = Z_Malloc(count,PU_LEVEL, 0); 288 memset(blocklinks, 0, count); 289 } 290 291 void 292 P_GroupLines() 293 { 294 line_t** linebuffer; 295 line_t* li; 296 sector_t* sector; 297 subsector_t* ss; 298 seg_t* seg; 299 fixed_t bbox[4]; 300 int i, j , total, block; 301 302 ss = subsectors; 303 for (i = 0; i < numsubsectors; ++i, ++ss) { 304 seg = &segs[ss->firstline]; 305 ss->sector = seg->sidedef->sector; 306 } 307 li = lines; 308 total = 0; 309 for (i = 0; i < numlines; ++i, ++li) { 310 ++total; 311 ++li->frontsector->linecount; 312 if (li->backsector && li->backsector != li->frontsector) { 313 ++total; 314 ++li->backsector->linecount; 315 } 316 } 317 linebuffer = Z_Malloc(total * 4 * 4, PU_LEVEL, 0); /* todo: figure out proper size */ 318 sector = sectors; 319 for (i = 0; i < numsectors; ++i, ++sector) { 320 M_ClearBox(bbox); 321 sector->lines = linebuffer; 322 li = lines; 323 for (j = 0; j < numlines; ++j, ++li) { 324 if(li->frontsector == sector || li->backsector == sector) { 325 *linebuffer++ = li; 326 M_AddToBox(bbox, li->v1->x, li->v1->y); 327 M_AddToBox(bbox, li->v2->x, li->v2->y); 328 } 329 } 330 if (linebuffer - sector->lines != sector->linecount) I_Error("P_GroupLines: miscounted"); 331 sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2; 332 sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2; 333 block = (bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT; 334 block = block >= bmapheight ? bmapheight-1 : block; 335 sector->blockbox[BOXTOP]=block; 336 block = (bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT; 337 block = block < 0 ? 0 : block; 338 sector->blockbox[BOXBOTTOM]=block; 339 block = (bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT; 340 block = block >= bmapwidth ? bmapwidth-1 : block; 341 sector->blockbox[BOXRIGHT]=block; 342 block = (bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT; 343 block = block < 0 ? 0 : block; 344 sector->blockbox[BOXLEFT]=block; 345 } 346 } 347 348 void 349 P_SetupLevel(int episode, int map, int playermask, skill_t skill) 350 { 351 char lumpname[9]; 352 int i, lumpnum; 353 354 totalkills = totalitems = totalsecret = wminfo.maxfrags = 0; 355 wminfo.partime = 180; 356 for (i = 0 ; i < MAXPLAYERS ; ++i) 357 players[i].killcount = players[i].secretcount = players[i].itemcount = 0; 358 players[consoleplayer].viewz = 1; 359 S_Start(); 360 Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); 361 P_InitThinkers(); 362 lumpname[0] = 'E'; 363 lumpname[1] = '0' + episode; 364 lumpname[2] = 'M'; 365 lumpname[3] = '0' + map; 366 lumpname[4] = '\0'; 367 lumpnum = W_GetNumForName(lumpname); 368 leveltime = 0; 369 P_LoadBlockMap(lumpnum+ML_BLOCKMAP); 370 P_LoadVertexes(lumpnum+ML_VERTEXES); 371 P_LoadSectors(lumpnum+ML_SECTORS); 372 P_LoadSideDefs(lumpnum+ML_SIDEDEFS); 373 P_LoadLineDefs(lumpnum+ML_LINEDEFS); 374 P_LoadSubsectors(lumpnum+ML_SSECTORS); 375 P_LoadNodes(lumpnum+ML_NODES); 376 P_LoadSegs(lumpnum+ML_SEGS); 377 rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT,PU_LEVEL); 378 P_GroupLines(); 379 bodyqueslot = 0; 380 deathmatch_p = deathmatchstarts; 381 P_LoadThings(lumpnum+ML_THINGS); 382 if(deathmatch) { 383 for (i = 0 ; i < MAXPLAYERS; ++i) 384 if (playeringame[i]) { 385 players[i].mo = NULL; 386 G_DeathMatchSpawnPlayer(i); 387 } 388 } 389 iquehead = iquetail = 0; 390 P_SpawnSpecials(); 391 if(precache) R_PrecacheLevel(); 392 } 393 394 void 395 P_Init() 396 { 397 P_InitSwitchList(); 398 P_InitPicAnims(); 399 R_InitSprites(sprnames); 400 }