P_SETUP.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. // P_main.c
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include "DoomDef.h"
  5. #include "P_local.h"
  6. #include "soundst.h"
  7. void P_SpawnMapThing (mapthing_t *mthing);
  8. int numvertexes;
  9. vertex_t *vertexes;
  10. int numsegs;
  11. seg_t *segs;
  12. int numsectors;
  13. sector_t *sectors;
  14. int numsubsectors;
  15. subsector_t *subsectors;
  16. int numnodes;
  17. node_t *nodes;
  18. int numlines;
  19. line_t *lines;
  20. int numsides;
  21. side_t *sides;
  22. short *blockmaplump; // offsets in blockmap are from here
  23. short *blockmap;
  24. int bmapwidth, bmapheight; // in mapblocks
  25. fixed_t bmaporgx, bmaporgy; // origin of block map
  26. mobj_t **blocklinks; // for thing chains
  27. byte *rejectmatrix; // for fast sight rejection
  28. mapthing_t deathmatchstarts[10], *deathmatch_p;
  29. mapthing_t playerstarts[MAXPLAYERS];
  30. /*
  31. =================
  32. =
  33. = P_LoadVertexes
  34. =
  35. =================
  36. */
  37. void P_LoadVertexes (int lump)
  38. {
  39. byte *data;
  40. int i;
  41. mapvertex_t *ml;
  42. vertex_t *li;
  43. numvertexes = W_LumpLength (lump) / sizeof(mapvertex_t);
  44. vertexes = Z_Malloc (numvertexes*sizeof(vertex_t),PU_LEVEL,0);
  45. data = W_CacheLumpNum (lump,PU_STATIC);
  46. ml = (mapvertex_t *)data;
  47. li = vertexes;
  48. for (i=0 ; i<numvertexes ; i++, li++, ml++)
  49. {
  50. li->x = SHORT(ml->x)<<FRACBITS;
  51. li->y = SHORT(ml->y)<<FRACBITS;
  52. }
  53. Z_Free (data);
  54. }
  55. /*
  56. =================
  57. =
  58. = P_LoadSegs
  59. =
  60. =================
  61. */
  62. void P_LoadSegs (int lump)
  63. {
  64. byte *data;
  65. int i;
  66. mapseg_t *ml;
  67. seg_t *li;
  68. line_t *ldef;
  69. int linedef, side;
  70. numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
  71. segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0);
  72. memset (segs, 0, numsegs*sizeof(seg_t));
  73. data = W_CacheLumpNum (lump,PU_STATIC);
  74. ml = (mapseg_t *)data;
  75. li = segs;
  76. for (i=0 ; i<numsegs ; i++, li++, ml++)
  77. {
  78. li->v1 = &vertexes[SHORT(ml->v1)];
  79. li->v2 = &vertexes[SHORT(ml->v2)];
  80. li->angle = (SHORT(ml->angle))<<16;
  81. li->offset = (SHORT(ml->offset))<<16;
  82. linedef = SHORT(ml->linedef);
  83. ldef = &lines[linedef];
  84. li->linedef = ldef;
  85. side = SHORT(ml->side);
  86. li->sidedef = &sides[ldef->sidenum[side]];
  87. li->frontsector = sides[ldef->sidenum[side]].sector;
  88. if (ldef-> flags & ML_TWOSIDED)
  89. li->backsector = sides[ldef->sidenum[side^1]].sector;
  90. else
  91. li->backsector = 0;
  92. }
  93. Z_Free (data);
  94. }
  95. /*
  96. =================
  97. =
  98. = P_LoadSubsectors
  99. =
  100. =================
  101. */
  102. void P_LoadSubsectors (int lump)
  103. {
  104. byte *data;
  105. int i;
  106. mapsubsector_t *ms;
  107. subsector_t *ss;
  108. numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_t);
  109. subsectors = Z_Malloc (numsubsectors*sizeof(subsector_t),PU_LEVEL,0);
  110. data = W_CacheLumpNum (lump,PU_STATIC);
  111. ms = (mapsubsector_t *)data;
  112. memset (subsectors,0, numsubsectors*sizeof(subsector_t));
  113. ss = subsectors;
  114. for (i=0 ; i<numsubsectors ; i++, ss++, ms++)
  115. {
  116. ss->numlines = SHORT(ms->numsegs);
  117. ss->firstline = SHORT(ms->firstseg);
  118. }
  119. Z_Free (data);
  120. }
  121. /*
  122. =================
  123. =
  124. = P_LoadSectors
  125. =
  126. =================
  127. */
  128. void P_LoadSectors (int lump)
  129. {
  130. byte *data;
  131. int i;
  132. mapsector_t *ms;
  133. sector_t *ss;
  134. numsectors = W_LumpLength (lump) / sizeof(mapsector_t);
  135. sectors = Z_Malloc (numsectors*sizeof(sector_t),PU_LEVEL,0);
  136. memset (sectors, 0, numsectors*sizeof(sector_t));
  137. data = W_CacheLumpNum (lump,PU_STATIC);
  138. ms = (mapsector_t *)data;
  139. ss = sectors;
  140. for (i=0 ; i<numsectors ; i++, ss++, ms++)
  141. {
  142. ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
  143. ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
  144. ss->floorpic = R_FlatNumForName(ms->floorpic);
  145. ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
  146. ss->lightlevel = SHORT(ms->lightlevel);
  147. ss->special = SHORT(ms->special);
  148. ss->tag = SHORT(ms->tag);
  149. ss->thinglist = NULL;
  150. }
  151. Z_Free (data);
  152. }
  153. /*
  154. =================
  155. =
  156. = P_LoadNodes
  157. =
  158. =================
  159. */
  160. void P_LoadNodes (int lump)
  161. {
  162. byte *data;
  163. int i,j,k;
  164. mapnode_t *mn;
  165. node_t *no;
  166. numnodes = W_LumpLength (lump) / sizeof(mapnode_t);
  167. nodes = Z_Malloc (numnodes*sizeof(node_t),PU_LEVEL,0);
  168. data = W_CacheLumpNum (lump,PU_STATIC);
  169. mn = (mapnode_t *)data;
  170. no = nodes;
  171. for (i=0 ; i<numnodes ; i++, no++, mn++)
  172. {
  173. no->x = SHORT(mn->x)<<FRACBITS;
  174. no->y = SHORT(mn->y)<<FRACBITS;
  175. no->dx = SHORT(mn->dx)<<FRACBITS;
  176. no->dy = SHORT(mn->dy)<<FRACBITS;
  177. for (j=0 ; j<2 ; j++)
  178. {
  179. no->children[j] = SHORT(mn->children[j]);
  180. for (k=0 ; k<4 ; k++)
  181. no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
  182. }
  183. }
  184. Z_Free (data);
  185. }
  186. /*
  187. =================
  188. =
  189. = P_LoadThings
  190. =
  191. =================
  192. */
  193. void P_LoadThings (int lump)
  194. {
  195. byte *data;
  196. int i;
  197. mapthing_t *mt;
  198. int numthings;
  199. data = W_CacheLumpNum (lump,PU_STATIC);
  200. numthings = W_LumpLength (lump) / sizeof(mapthing_t);
  201. mt = (mapthing_t *)data;
  202. for (i=0 ; i<numthings ; i++, mt++)
  203. {
  204. mt->x = SHORT(mt->x);
  205. mt->y = SHORT(mt->y);
  206. mt->angle = SHORT(mt->angle);
  207. mt->type = SHORT(mt->type);
  208. mt->options = SHORT(mt->options);
  209. P_SpawnMapThing (mt);
  210. }
  211. Z_Free (data);
  212. }
  213. /*
  214. =================
  215. =
  216. = P_LoadLineDefs
  217. =
  218. = Also counts secret lines for intermissions
  219. =================
  220. */
  221. void P_LoadLineDefs (int lump)
  222. {
  223. byte *data;
  224. int i;
  225. maplinedef_t *mld;
  226. line_t *ld;
  227. vertex_t *v1, *v2;
  228. numlines = W_LumpLength (lump) / sizeof(maplinedef_t);
  229. lines = Z_Malloc (numlines*sizeof(line_t),PU_LEVEL,0);
  230. memset (lines, 0, numlines*sizeof(line_t));
  231. data = W_CacheLumpNum (lump,PU_STATIC);
  232. mld = (maplinedef_t *)data;
  233. ld = lines;
  234. for (i=0 ; i<numlines ; i++, mld++, ld++)
  235. {
  236. ld->flags = SHORT(mld->flags);
  237. ld->special = SHORT(mld->special);
  238. ld->tag = SHORT(mld->tag);
  239. v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
  240. v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
  241. ld->dx = v2->x - v1->x;
  242. ld->dy = v2->y - v1->y;
  243. if (!ld->dx)
  244. ld->slopetype = ST_VERTICAL;
  245. else if (!ld->dy)
  246. ld->slopetype = ST_HORIZONTAL;
  247. else
  248. {
  249. if (FixedDiv (ld->dy , ld->dx) > 0)
  250. ld->slopetype = ST_POSITIVE;
  251. else
  252. ld->slopetype = ST_NEGATIVE;
  253. }
  254. if (v1->x < v2->x)
  255. {
  256. ld->bbox[BOXLEFT] = v1->x;
  257. ld->bbox[BOXRIGHT] = v2->x;
  258. }
  259. else
  260. {
  261. ld->bbox[BOXLEFT] = v2->x;
  262. ld->bbox[BOXRIGHT] = v1->x;
  263. }
  264. if (v1->y < v2->y)
  265. {
  266. ld->bbox[BOXBOTTOM] = v1->y;
  267. ld->bbox[BOXTOP] = v2->y;
  268. }
  269. else
  270. {
  271. ld->bbox[BOXBOTTOM] = v2->y;
  272. ld->bbox[BOXTOP] = v1->y;
  273. }
  274. ld->sidenum[0] = SHORT(mld->sidenum[0]);
  275. ld->sidenum[1] = SHORT(mld->sidenum[1]);
  276. if (ld->sidenum[0] != -1)
  277. ld->frontsector = sides[ld->sidenum[0]].sector;
  278. else
  279. ld->frontsector = 0;
  280. if (ld->sidenum[1] != -1)
  281. ld->backsector = sides[ld->sidenum[1]].sector;
  282. else
  283. ld->backsector = 0;
  284. }
  285. Z_Free (data);
  286. }
  287. /*
  288. =================
  289. =
  290. = P_LoadSideDefs
  291. =
  292. =================
  293. */
  294. void P_LoadSideDefs (int lump)
  295. {
  296. byte *data;
  297. int i;
  298. mapsidedef_t *msd;
  299. side_t *sd;
  300. numsides = W_LumpLength (lump) / sizeof(mapsidedef_t);
  301. sides = Z_Malloc (numsides*sizeof(side_t),PU_LEVEL,0);
  302. memset (sides, 0, numsides*sizeof(side_t));
  303. data = W_CacheLumpNum (lump,PU_STATIC);
  304. msd = (mapsidedef_t *)data;
  305. sd = sides;
  306. for (i=0 ; i<numsides ; i++, msd++, sd++)
  307. {
  308. sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS;
  309. sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS;
  310. sd->toptexture = R_TextureNumForName(msd->toptexture);
  311. sd->bottomtexture = R_TextureNumForName(msd->bottomtexture);
  312. sd->midtexture = R_TextureNumForName(msd->midtexture);
  313. sd->sector = &sectors[SHORT(msd->sector)];
  314. }
  315. Z_Free (data);
  316. }
  317. /*
  318. =================
  319. =
  320. = P_LoadBlockMap
  321. =
  322. =================
  323. */
  324. void P_LoadBlockMap (int lump)
  325. {
  326. int i, count;
  327. blockmaplump = W_CacheLumpNum (lump,PU_LEVEL);
  328. blockmap = blockmaplump+4;
  329. count = W_LumpLength (lump)/2;
  330. for (i=0 ; i<count ; i++)
  331. blockmaplump[i] = SHORT(blockmaplump[i]);
  332. bmaporgx = blockmaplump[0]<<FRACBITS;
  333. bmaporgy = blockmaplump[1]<<FRACBITS;
  334. bmapwidth = blockmaplump[2];
  335. bmapheight = blockmaplump[3];
  336. // clear out mobj chains
  337. count = sizeof(*blocklinks)* bmapwidth*bmapheight;
  338. blocklinks = Z_Malloc (count,PU_LEVEL, 0);
  339. memset (blocklinks, 0, count);
  340. }
  341. /*
  342. =================
  343. =
  344. = P_GroupLines
  345. =
  346. = Builds sector line lists and subsector sector numbers
  347. = Finds block bounding boxes for sectors
  348. =================
  349. */
  350. void P_GroupLines (void)
  351. {
  352. line_t **linebuffer;
  353. int i, j, total;
  354. line_t *li;
  355. sector_t *sector;
  356. subsector_t *ss;
  357. seg_t *seg;
  358. fixed_t bbox[4];
  359. int block;
  360. // look up sector number for each subsector
  361. ss = subsectors;
  362. for (i=0 ; i<numsubsectors ; i++, ss++)
  363. {
  364. seg = &segs[ss->firstline];
  365. ss->sector = seg->sidedef->sector;
  366. }
  367. // count number of lines in each sector
  368. li = lines;
  369. total = 0;
  370. for (i=0 ; i<numlines ; i++, li++)
  371. {
  372. total++;
  373. li->frontsector->linecount++;
  374. if (li->backsector && li->backsector != li->frontsector)
  375. {
  376. li->backsector->linecount++;
  377. total++;
  378. }
  379. }
  380. // build line tables for each sector
  381. linebuffer = Z_Malloc (total*4, PU_LEVEL, 0);
  382. sector = sectors;
  383. for (i=0 ; i<numsectors ; i++, sector++)
  384. {
  385. M_ClearBox (bbox);
  386. sector->lines = linebuffer;
  387. li = lines;
  388. for (j=0 ; j<numlines ; j++, li++)
  389. {
  390. if (li->frontsector == sector || li->backsector == sector)
  391. {
  392. *linebuffer++ = li;
  393. M_AddToBox (bbox, li->v1->x, li->v1->y);
  394. M_AddToBox (bbox, li->v2->x, li->v2->y);
  395. }
  396. }
  397. if (linebuffer - sector->lines != sector->linecount)
  398. I_Error ("P_GroupLines: miscounted");
  399. // set the degenmobj_t to the middle of the bounding box
  400. sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2;
  401. sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2;
  402. // adjust bounding box to map blocks
  403. block = (bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
  404. block = block >= bmapheight ? bmapheight-1 : block;
  405. sector->blockbox[BOXTOP]=block;
  406. block = (bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
  407. block = block < 0 ? 0 : block;
  408. sector->blockbox[BOXBOTTOM]=block;
  409. block = (bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
  410. block = block >= bmapwidth ? bmapwidth-1 : block;
  411. sector->blockbox[BOXRIGHT]=block;
  412. block = (bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
  413. block = block < 0 ? 0 : block;
  414. sector->blockbox[BOXLEFT]=block;
  415. }
  416. }
  417. //=============================================================================
  418. /*
  419. =================
  420. =
  421. = P_SetupLevel
  422. =
  423. =================
  424. */
  425. void P_SetupLevel (int episode, int map, int playermask, skill_t skill)
  426. {
  427. int i;
  428. int parm;
  429. char lumpname[9];
  430. int lumpnum;
  431. mobj_t *mobj;
  432. totalkills = totalitems = totalsecret = 0;
  433. for (i=0 ; i<MAXPLAYERS ; i++)
  434. {
  435. players[i].killcount = players[i].secretcount
  436. = players[i].itemcount = 0;
  437. }
  438. players[consoleplayer].viewz = 1; // will be set by player think
  439. S_Start (); // make sure all sounds are stopped before Z_FreeTags
  440. Z_FreeTags (PU_LEVEL, PU_PURGELEVEL-1);
  441. P_InitThinkers ();
  442. //
  443. // look for a regular (development) map first
  444. //
  445. lumpname[0] = 'E';
  446. lumpname[1] = '0' + episode;
  447. lumpname[2] = 'M';
  448. lumpname[3] = '0' + map;
  449. lumpname[4] = 0;
  450. leveltime = 0;
  451. lumpnum = W_GetNumForName (lumpname);
  452. // note: most of this ordering is important
  453. P_LoadBlockMap (lumpnum+ML_BLOCKMAP);
  454. P_LoadVertexes (lumpnum+ML_VERTEXES);
  455. P_LoadSectors (lumpnum+ML_SECTORS);
  456. P_LoadSideDefs (lumpnum+ML_SIDEDEFS);
  457. P_LoadLineDefs (lumpnum+ML_LINEDEFS);
  458. P_LoadSubsectors (lumpnum+ML_SSECTORS);
  459. P_LoadNodes (lumpnum+ML_NODES);
  460. P_LoadSegs (lumpnum+ML_SEGS);
  461. rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL);
  462. P_GroupLines ();
  463. bodyqueslot = 0;
  464. deathmatch_p = deathmatchstarts;
  465. P_InitAmbientSound();
  466. P_InitMonsters();
  467. P_OpenWeapons();
  468. P_LoadThings(lumpnum+ML_THINGS);
  469. P_CloseWeapons();
  470. //
  471. // if deathmatch, randomly spawn the active players
  472. //
  473. TimerGame = 0;
  474. if(deathmatch)
  475. {
  476. for (i=0 ; i<MAXPLAYERS ; i++)
  477. {
  478. if (playeringame[i])
  479. { // must give a player spot before deathmatchspawn
  480. mobj = P_SpawnMobj (playerstarts[i].x<<16,
  481. playerstarts[i].y<<16,0, MT_PLAYER);
  482. players[i].mo = mobj;
  483. G_DeathMatchSpawnPlayer (i);
  484. P_RemoveMobj (mobj);
  485. }
  486. }
  487. parm = M_CheckParm("-timer");
  488. if(parm && parm < myargc-1)
  489. {
  490. TimerGame = atoi(myargv[parm+1])*35*60;
  491. }
  492. }
  493. // set up world state
  494. P_SpawnSpecials ();
  495. // build subsector connect matrix
  496. // P_ConnectSubsectors ();
  497. // preload graphics
  498. if (precache)
  499. R_PrecacheLevel ();
  500. //printf ("free memory: 0x%x\n", Z_FreeMemory());
  501. }
  502. /*
  503. =================
  504. =
  505. = P_Init
  506. =
  507. =================
  508. */
  509. void P_Init (void)
  510. {
  511. P_InitSwitchList();
  512. P_InitPicAnims();
  513. P_InitTerrainTypes();
  514. P_InitLava();
  515. R_InitSprites(sprnames);
  516. }