p_setup.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. // Do all the WAD I/O, get map description,
  21. // set up initial state and misc. LUTs.
  22. //
  23. //-----------------------------------------------------------------------------
  24. static const char
  25. rcsid[] = "$Id: p_setup.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
  26. #include <math.h>
  27. #include "z_zone.h"
  28. #include "m_swap.h"
  29. #include "m_bbox.h"
  30. #include "g_game.h"
  31. #include "i_system.h"
  32. #include "w_wad.h"
  33. #include "doomdef.h"
  34. #include "p_local.h"
  35. #include "s_sound.h"
  36. #include "doomstat.h"
  37. void P_SpawnMapThing (mapthing_t* mthing);
  38. //
  39. // MAP related Lookup tables.
  40. // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
  41. //
  42. int numvertexes;
  43. vertex_t* vertexes;
  44. int numsegs;
  45. seg_t* segs;
  46. int numsectors;
  47. sector_t* sectors;
  48. int numsubsectors;
  49. subsector_t* subsectors;
  50. int numnodes;
  51. node_t* nodes;
  52. int numlines;
  53. line_t* lines;
  54. int numsides;
  55. side_t* sides;
  56. // BLOCKMAP
  57. // Created from axis aligned bounding box
  58. // of the map, a rectangular array of
  59. // blocks of size ...
  60. // Used to speed up collision detection
  61. // by spatial subdivision in 2D.
  62. //
  63. // Blockmap size.
  64. int bmapwidth;
  65. int bmapheight; // size in mapblocks
  66. short* blockmap; // int for larger maps
  67. // offsets in blockmap are from here
  68. short* blockmaplump;
  69. // origin of block map
  70. fixed_t bmaporgx;
  71. fixed_t bmaporgy;
  72. // for thing chains
  73. mobj_t** blocklinks;
  74. // REJECT
  75. // For fast sight rejection.
  76. // Speeds up enemy AI by skipping detailed
  77. // LineOf Sight calculation.
  78. // Without special effect, this could be
  79. // used as a PVS lookup as well.
  80. //
  81. byte* rejectmatrix;
  82. // Maintain single and multi player starting spots.
  83. #define MAX_DEATHMATCH_STARTS 10
  84. mapthing_t deathmatchstarts[MAX_DEATHMATCH_STARTS];
  85. mapthing_t* deathmatch_p;
  86. mapthing_t playerstarts[MAXPLAYERS];
  87. //
  88. // P_LoadVertexes
  89. //
  90. void P_LoadVertexes (int lump)
  91. {
  92. byte* data;
  93. int i;
  94. mapvertex_t* ml;
  95. vertex_t* li;
  96. // Determine number of lumps:
  97. // total lump length / vertex record length.
  98. numvertexes = W_LumpLength (lump) / sizeof(mapvertex_t);
  99. // Allocate zone memory for buffer.
  100. vertexes = Z_Malloc (numvertexes*sizeof(vertex_t),PU_LEVEL,0);
  101. // Load data into cache.
  102. data = W_CacheLumpNum (lump,PU_STATIC);
  103. ml = (mapvertex_t *)data;
  104. li = vertexes;
  105. // Copy and convert vertex coordinates,
  106. // internal representation as fixed.
  107. for (i=0 ; i<numvertexes ; i++, li++, ml++)
  108. {
  109. li->x = SHORT(ml->x)<<FRACBITS;
  110. li->y = SHORT(ml->y)<<FRACBITS;
  111. }
  112. // Free buffer memory.
  113. Z_Free (data);
  114. }
  115. //
  116. // P_LoadSegs
  117. //
  118. void P_LoadSegs (int lump)
  119. {
  120. byte* data;
  121. int i;
  122. mapseg_t* ml;
  123. seg_t* li;
  124. line_t* ldef;
  125. int linedef;
  126. int side;
  127. numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
  128. segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0);
  129. memset (segs, 0, numsegs*sizeof(seg_t));
  130. data = W_CacheLumpNum (lump,PU_STATIC);
  131. ml = (mapseg_t *)data;
  132. li = segs;
  133. for (i=0 ; i<numsegs ; i++, li++, ml++)
  134. {
  135. li->v1 = &vertexes[SHORT(ml->v1)];
  136. li->v2 = &vertexes[SHORT(ml->v2)];
  137. li->angle = (SHORT(ml->angle))<<16;
  138. li->offset = (SHORT(ml->offset))<<16;
  139. linedef = SHORT(ml->linedef);
  140. ldef = &lines[linedef];
  141. li->linedef = ldef;
  142. side = SHORT(ml->side);
  143. li->sidedef = &sides[ldef->sidenum[side]];
  144. li->frontsector = sides[ldef->sidenum[side]].sector;
  145. if (ldef-> flags & ML_TWOSIDED)
  146. li->backsector = sides[ldef->sidenum[side^1]].sector;
  147. else
  148. li->backsector = 0;
  149. }
  150. Z_Free (data);
  151. }
  152. //
  153. // P_LoadSubsectors
  154. //
  155. void P_LoadSubsectors (int lump)
  156. {
  157. byte* data;
  158. int i;
  159. mapsubsector_t* ms;
  160. subsector_t* ss;
  161. numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_t);
  162. subsectors = Z_Malloc (numsubsectors*sizeof(subsector_t),PU_LEVEL,0);
  163. data = W_CacheLumpNum (lump,PU_STATIC);
  164. ms = (mapsubsector_t *)data;
  165. memset (subsectors,0, numsubsectors*sizeof(subsector_t));
  166. ss = subsectors;
  167. for (i=0 ; i<numsubsectors ; i++, ss++, ms++)
  168. {
  169. ss->numlines = SHORT(ms->numsegs);
  170. ss->firstline = SHORT(ms->firstseg);
  171. }
  172. Z_Free (data);
  173. }
  174. //
  175. // P_LoadSectors
  176. //
  177. void P_LoadSectors (int lump)
  178. {
  179. byte* data;
  180. int i;
  181. mapsector_t* ms;
  182. sector_t* ss;
  183. numsectors = W_LumpLength (lump) / sizeof(mapsector_t);
  184. sectors = Z_Malloc (numsectors*sizeof(sector_t),PU_LEVEL,0);
  185. memset (sectors, 0, numsectors*sizeof(sector_t));
  186. data = W_CacheLumpNum (lump,PU_STATIC);
  187. ms = (mapsector_t *)data;
  188. ss = sectors;
  189. for (i=0 ; i<numsectors ; i++, ss++, ms++)
  190. {
  191. ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
  192. ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
  193. ss->floorpic = R_FlatNumForName(ms->floorpic);
  194. ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
  195. ss->lightlevel = SHORT(ms->lightlevel);
  196. ss->special = SHORT(ms->special);
  197. ss->tag = SHORT(ms->tag);
  198. ss->thinglist = NULL;
  199. }
  200. Z_Free (data);
  201. }
  202. //
  203. // P_LoadNodes
  204. //
  205. void P_LoadNodes (int lump)
  206. {
  207. byte* data;
  208. int i;
  209. int j;
  210. int k;
  211. mapnode_t* mn;
  212. node_t* no;
  213. numnodes = W_LumpLength (lump) / sizeof(mapnode_t);
  214. nodes = Z_Malloc (numnodes*sizeof(node_t),PU_LEVEL,0);
  215. data = W_CacheLumpNum (lump,PU_STATIC);
  216. mn = (mapnode_t *)data;
  217. no = nodes;
  218. for (i=0 ; i<numnodes ; i++, no++, mn++)
  219. {
  220. no->x = SHORT(mn->x)<<FRACBITS;
  221. no->y = SHORT(mn->y)<<FRACBITS;
  222. no->dx = SHORT(mn->dx)<<FRACBITS;
  223. no->dy = SHORT(mn->dy)<<FRACBITS;
  224. for (j=0 ; j<2 ; j++)
  225. {
  226. no->children[j] = SHORT(mn->children[j]);
  227. for (k=0 ; k<4 ; k++)
  228. no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
  229. }
  230. }
  231. Z_Free (data);
  232. }
  233. //
  234. // P_LoadThings
  235. //
  236. void P_LoadThings (int lump)
  237. {
  238. byte* data;
  239. int i;
  240. mapthing_t* mt;
  241. int numthings;
  242. boolean spawn;
  243. data = W_CacheLumpNum (lump,PU_STATIC);
  244. numthings = W_LumpLength (lump) / sizeof(mapthing_t);
  245. mt = (mapthing_t *)data;
  246. for (i=0 ; i<numthings ; i++, mt++)
  247. {
  248. spawn = true;
  249. // Do not spawn cool, new monsters if !commercial
  250. if ( gamemode != commercial)
  251. {
  252. switch(mt->type)
  253. {
  254. case 68: // Arachnotron
  255. case 64: // Archvile
  256. case 88: // Boss Brain
  257. case 89: // Boss Shooter
  258. case 69: // Hell Knight
  259. case 67: // Mancubus
  260. case 71: // Pain Elemental
  261. case 65: // Former Human Commando
  262. case 66: // Revenant
  263. case 84: // Wolf SS
  264. spawn = false;
  265. break;
  266. }
  267. }
  268. if (spawn == false)
  269. break;
  270. // Do spawn all other stuff.
  271. mt->x = SHORT(mt->x);
  272. mt->y = SHORT(mt->y);
  273. mt->angle = SHORT(mt->angle);
  274. mt->type = SHORT(mt->type);
  275. mt->options = SHORT(mt->options);
  276. P_SpawnMapThing (mt);
  277. }
  278. Z_Free (data);
  279. }
  280. //
  281. // P_LoadLineDefs
  282. // Also counts secret lines for intermissions.
  283. //
  284. void P_LoadLineDefs (int lump)
  285. {
  286. byte* data;
  287. int i;
  288. maplinedef_t* mld;
  289. line_t* ld;
  290. vertex_t* v1;
  291. vertex_t* v2;
  292. numlines = W_LumpLength (lump) / sizeof(maplinedef_t);
  293. lines = Z_Malloc (numlines*sizeof(line_t),PU_LEVEL,0);
  294. memset (lines, 0, numlines*sizeof(line_t));
  295. data = W_CacheLumpNum (lump,PU_STATIC);
  296. mld = (maplinedef_t *)data;
  297. ld = lines;
  298. for (i=0 ; i<numlines ; i++, mld++, ld++)
  299. {
  300. ld->flags = SHORT(mld->flags);
  301. ld->special = SHORT(mld->special);
  302. ld->tag = SHORT(mld->tag);
  303. v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
  304. v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
  305. ld->dx = v2->x - v1->x;
  306. ld->dy = v2->y - v1->y;
  307. if (!ld->dx)
  308. ld->slopetype = ST_VERTICAL;
  309. else if (!ld->dy)
  310. ld->slopetype = ST_HORIZONTAL;
  311. else
  312. {
  313. if (FixedDiv (ld->dy , ld->dx) > 0)
  314. ld->slopetype = ST_POSITIVE;
  315. else
  316. ld->slopetype = ST_NEGATIVE;
  317. }
  318. if (v1->x < v2->x)
  319. {
  320. ld->bbox[BOXLEFT] = v1->x;
  321. ld->bbox[BOXRIGHT] = v2->x;
  322. }
  323. else
  324. {
  325. ld->bbox[BOXLEFT] = v2->x;
  326. ld->bbox[BOXRIGHT] = v1->x;
  327. }
  328. if (v1->y < v2->y)
  329. {
  330. ld->bbox[BOXBOTTOM] = v1->y;
  331. ld->bbox[BOXTOP] = v2->y;
  332. }
  333. else
  334. {
  335. ld->bbox[BOXBOTTOM] = v2->y;
  336. ld->bbox[BOXTOP] = v1->y;
  337. }
  338. ld->sidenum[0] = SHORT(mld->sidenum[0]);
  339. ld->sidenum[1] = SHORT(mld->sidenum[1]);
  340. if (ld->sidenum[0] != -1)
  341. ld->frontsector = sides[ld->sidenum[0]].sector;
  342. else
  343. ld->frontsector = 0;
  344. if (ld->sidenum[1] != -1)
  345. ld->backsector = sides[ld->sidenum[1]].sector;
  346. else
  347. ld->backsector = 0;
  348. }
  349. Z_Free (data);
  350. }
  351. //
  352. // P_LoadSideDefs
  353. //
  354. void P_LoadSideDefs (int lump)
  355. {
  356. byte* data;
  357. int i;
  358. mapsidedef_t* msd;
  359. side_t* sd;
  360. numsides = W_LumpLength (lump) / sizeof(mapsidedef_t);
  361. sides = Z_Malloc (numsides*sizeof(side_t),PU_LEVEL,0);
  362. memset (sides, 0, numsides*sizeof(side_t));
  363. data = W_CacheLumpNum (lump,PU_STATIC);
  364. msd = (mapsidedef_t *)data;
  365. sd = sides;
  366. for (i=0 ; i<numsides ; i++, msd++, sd++)
  367. {
  368. sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS;
  369. sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS;
  370. sd->toptexture = R_TextureNumForName(msd->toptexture);
  371. sd->bottomtexture = R_TextureNumForName(msd->bottomtexture);
  372. sd->midtexture = R_TextureNumForName(msd->midtexture);
  373. sd->sector = &sectors[SHORT(msd->sector)];
  374. }
  375. Z_Free (data);
  376. }
  377. //
  378. // P_LoadBlockMap
  379. //
  380. void P_LoadBlockMap (int lump)
  381. {
  382. int i;
  383. int count;
  384. blockmaplump = W_CacheLumpNum (lump,PU_LEVEL);
  385. blockmap = blockmaplump+4;
  386. count = W_LumpLength (lump)/2;
  387. for (i=0 ; i<count ; i++)
  388. blockmaplump[i] = SHORT(blockmaplump[i]);
  389. bmaporgx = blockmaplump[0]<<FRACBITS;
  390. bmaporgy = blockmaplump[1]<<FRACBITS;
  391. bmapwidth = blockmaplump[2];
  392. bmapheight = blockmaplump[3];
  393. // clear out mobj chains
  394. count = sizeof(*blocklinks)* bmapwidth*bmapheight;
  395. blocklinks = Z_Malloc (count,PU_LEVEL, 0);
  396. memset (blocklinks, 0, count);
  397. }
  398. //
  399. // P_GroupLines
  400. // Builds sector line lists and subsector sector numbers.
  401. // Finds block bounding boxes for sectors.
  402. //
  403. void P_GroupLines (void)
  404. {
  405. line_t** linebuffer;
  406. int i;
  407. int j;
  408. int total;
  409. line_t* li;
  410. sector_t* sector;
  411. subsector_t* ss;
  412. seg_t* seg;
  413. fixed_t bbox[4];
  414. int block;
  415. // look up sector number for each subsector
  416. ss = subsectors;
  417. for (i=0 ; i<numsubsectors ; i++, ss++)
  418. {
  419. seg = &segs[ss->firstline];
  420. ss->sector = seg->sidedef->sector;
  421. }
  422. // count number of lines in each sector
  423. li = lines;
  424. total = 0;
  425. for (i=0 ; i<numlines ; i++, li++)
  426. {
  427. total++;
  428. li->frontsector->linecount++;
  429. if (li->backsector && li->backsector != li->frontsector)
  430. {
  431. li->backsector->linecount++;
  432. total++;
  433. }
  434. }
  435. // build line tables for each sector
  436. linebuffer = Z_Malloc (total*4, PU_LEVEL, 0);
  437. sector = sectors;
  438. for (i=0 ; i<numsectors ; i++, sector++)
  439. {
  440. M_ClearBox (bbox);
  441. sector->lines = linebuffer;
  442. li = lines;
  443. for (j=0 ; j<numlines ; j++, li++)
  444. {
  445. if (li->frontsector == sector || li->backsector == sector)
  446. {
  447. *linebuffer++ = li;
  448. M_AddToBox (bbox, li->v1->x, li->v1->y);
  449. M_AddToBox (bbox, li->v2->x, li->v2->y);
  450. }
  451. }
  452. if (linebuffer - sector->lines != sector->linecount)
  453. I_Error ("P_GroupLines: miscounted");
  454. // set the degenmobj_t to the middle of the bounding box
  455. sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2;
  456. sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2;
  457. // adjust bounding box to map blocks
  458. block = (bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
  459. block = block >= bmapheight ? bmapheight-1 : block;
  460. sector->blockbox[BOXTOP]=block;
  461. block = (bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
  462. block = block < 0 ? 0 : block;
  463. sector->blockbox[BOXBOTTOM]=block;
  464. block = (bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
  465. block = block >= bmapwidth ? bmapwidth-1 : block;
  466. sector->blockbox[BOXRIGHT]=block;
  467. block = (bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
  468. block = block < 0 ? 0 : block;
  469. sector->blockbox[BOXLEFT]=block;
  470. }
  471. }
  472. //
  473. // P_SetupLevel
  474. //
  475. void
  476. P_SetupLevel
  477. ( int episode,
  478. int map,
  479. int playermask,
  480. skill_t skill)
  481. {
  482. int i;
  483. char lumpname[9];
  484. int lumpnum;
  485. totalkills = totalitems = totalsecret = wminfo.maxfrags = 0;
  486. wminfo.partime = 180;
  487. for (i=0 ; i<MAXPLAYERS ; i++)
  488. {
  489. players[i].killcount = players[i].secretcount
  490. = players[i].itemcount = 0;
  491. }
  492. // Initial height of PointOfView
  493. // will be set by player think.
  494. players[consoleplayer].viewz = 1;
  495. // Make sure all sounds are stopped before Z_FreeTags.
  496. S_Start ();
  497. #if 0 // UNUSED
  498. if (debugfile)
  499. {
  500. Z_FreeTags (PU_LEVEL, MAXINT);
  501. Z_FileDumpHeap (debugfile);
  502. }
  503. else
  504. #endif
  505. Z_FreeTags (PU_LEVEL, PU_PURGELEVEL-1);
  506. // UNUSED W_Profile ();
  507. P_InitThinkers ();
  508. // if working with a devlopment map, reload it
  509. W_Reload ();
  510. // find map name
  511. if ( gamemode == commercial)
  512. {
  513. if (map<10)
  514. sprintf (lumpname,"map0%i", map);
  515. else
  516. sprintf (lumpname,"map%i", map);
  517. }
  518. else
  519. {
  520. lumpname[0] = 'E';
  521. lumpname[1] = '0' + episode;
  522. lumpname[2] = 'M';
  523. lumpname[3] = '0' + map;
  524. lumpname[4] = 0;
  525. }
  526. lumpnum = W_GetNumForName (lumpname);
  527. leveltime = 0;
  528. // note: most of this ordering is important
  529. P_LoadBlockMap (lumpnum+ML_BLOCKMAP);
  530. P_LoadVertexes (lumpnum+ML_VERTEXES);
  531. P_LoadSectors (lumpnum+ML_SECTORS);
  532. P_LoadSideDefs (lumpnum+ML_SIDEDEFS);
  533. P_LoadLineDefs (lumpnum+ML_LINEDEFS);
  534. P_LoadSubsectors (lumpnum+ML_SSECTORS);
  535. P_LoadNodes (lumpnum+ML_NODES);
  536. P_LoadSegs (lumpnum+ML_SEGS);
  537. rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL);
  538. P_GroupLines ();
  539. bodyqueslot = 0;
  540. deathmatch_p = deathmatchstarts;
  541. P_LoadThings (lumpnum+ML_THINGS);
  542. // if deathmatch, randomly spawn the active players
  543. if (deathmatch)
  544. {
  545. for (i=0 ; i<MAXPLAYERS ; i++)
  546. if (playeringame[i])
  547. {
  548. players[i].mo = NULL;
  549. G_DeathMatchSpawnPlayer (i);
  550. }
  551. }
  552. // clear special respawning que
  553. iquehead = iquetail = 0;
  554. // set up world state
  555. P_SpawnSpecials ();
  556. // build subsector connect matrix
  557. // UNUSED P_ConnectSubsectors ();
  558. // preload graphics
  559. if (precache)
  560. R_PrecacheLevel ();
  561. //printf ("free memory: 0x%x\n", Z_FreeMemory());
  562. }
  563. //
  564. // P_Init
  565. //
  566. void P_Init (void)
  567. {
  568. P_InitSwitchList ();
  569. P_InitPicAnims ();
  570. R_InitSprites (sprnames);
  571. }