P_TICK.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. // P_tick.c
  2. #include "DoomDef.h"
  3. #include "P_local.h"
  4. int leveltime;
  5. int TimerGame;
  6. /*
  7. ====================
  8. =
  9. = P_ArchivePlayers
  10. =
  11. ====================
  12. */
  13. void P_ArchivePlayers(void)
  14. {
  15. int i;
  16. int j;
  17. player_t dest;
  18. for(i = 0; i < MAXPLAYERS; i++)
  19. {
  20. if(!playeringame[i])
  21. {
  22. continue;
  23. }
  24. memcpy(&dest, &players[i], sizeof(player_t));
  25. for(j = 0; j < NUMPSPRITES; j++)
  26. {
  27. if(dest.psprites[j].state)
  28. {
  29. dest.psprites[j].state =
  30. (state_t *)(dest.psprites[j].state-states);
  31. }
  32. }
  33. SV_Write(&dest, sizeof(player_t));
  34. }
  35. }
  36. /*
  37. ====================
  38. =
  39. = P_UnArchivePlayers
  40. =
  41. ====================
  42. */
  43. void P_UnArchivePlayers (void)
  44. {
  45. int i,j;
  46. for (i=0 ; i<MAXPLAYERS ; i++)
  47. {
  48. if (!playeringame[i])
  49. continue;
  50. memcpy (&players[i],save_p, sizeof(player_t));
  51. save_p += sizeof(player_t);
  52. players[i].mo = NULL; // will be set when unarc thinker
  53. players[i].message = NULL;
  54. players[i].attacker = NULL;
  55. for (j=0 ; j<NUMPSPRITES ; j++)
  56. if (players[i]. psprites[j].state)
  57. players[i]. psprites[j].state
  58. = &states[ (int)players[i].psprites[j].state ];
  59. }
  60. }
  61. //=============================================================================
  62. /*
  63. ====================
  64. =
  65. = P_ArchiveWorld
  66. =
  67. ====================
  68. */
  69. void P_ArchiveWorld(void)
  70. {
  71. int i, j;
  72. sector_t *sec;
  73. line_t *li;
  74. side_t *si;
  75. // Sectors
  76. for(i = 0, sec = sectors; i < numsectors; i++, sec++)
  77. {
  78. SV_WriteWord(sec->floorheight>>FRACBITS);
  79. SV_WriteWord(sec->ceilingheight>>FRACBITS);
  80. SV_WriteWord(sec->floorpic);
  81. SV_WriteWord(sec->ceilingpic);
  82. SV_WriteWord(sec->lightlevel);
  83. SV_WriteWord(sec->special); // needed?
  84. SV_WriteWord(sec->tag); // needed?
  85. }
  86. // Lines
  87. for(i = 0, li = lines; i < numlines; i++, li++)
  88. {
  89. SV_WriteWord(li->flags);
  90. SV_WriteWord(li->special);
  91. SV_WriteWord(li->tag);
  92. for(j = 0; j < 2; j++)
  93. {
  94. if(li->sidenum[j] == -1)
  95. {
  96. continue;
  97. }
  98. si = &sides[li->sidenum[j]];
  99. SV_WriteWord(si->textureoffset>>FRACBITS);
  100. SV_WriteWord(si->rowoffset>>FRACBITS);
  101. SV_WriteWord(si->toptexture);
  102. SV_WriteWord(si->bottomtexture);
  103. SV_WriteWord(si->midtexture);
  104. }
  105. }
  106. }
  107. /*
  108. ====================
  109. =
  110. = P_UnArchiveWorld
  111. =
  112. ====================
  113. */
  114. void P_UnArchiveWorld (void)
  115. {
  116. int i,j;
  117. sector_t *sec;
  118. line_t *li;
  119. side_t *si;
  120. short *get;
  121. get = (short *)save_p;
  122. //
  123. // do sectors
  124. //
  125. for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  126. {
  127. sec->floorheight = *get++ << FRACBITS;
  128. sec->ceilingheight = *get++ << FRACBITS;
  129. sec->floorpic = *get++;
  130. sec->ceilingpic = *get++;
  131. sec->lightlevel = *get++;
  132. sec->special = *get++; // needed?
  133. sec->tag = *get++; // needed?
  134. sec->specialdata = 0;
  135. sec->soundtarget = 0;
  136. }
  137. //
  138. // do lines
  139. //
  140. for (i=0, li = lines ; i<numlines ; i++,li++)
  141. {
  142. li->flags = *get++;
  143. li->special = *get++;
  144. li->tag = *get++;
  145. for (j=0 ; j<2 ; j++)
  146. {
  147. if (li->sidenum[j] == -1)
  148. continue;
  149. si = &sides[li->sidenum[j]];
  150. si->textureoffset = *get++ << FRACBITS;
  151. si->rowoffset = *get++ << FRACBITS;
  152. si->toptexture = *get++;
  153. si->bottomtexture = *get++;
  154. si->midtexture = *get++;
  155. }
  156. }
  157. save_p = (byte *)get;
  158. }
  159. //=============================================================================
  160. typedef enum
  161. {
  162. tc_end,
  163. tc_mobj
  164. } thinkerclass_t;
  165. /*
  166. ====================
  167. =
  168. = P_ArchiveThinkers
  169. =
  170. ====================
  171. */
  172. void P_ArchiveThinkers(void)
  173. {
  174. thinker_t *th;
  175. mobj_t mobj;
  176. for(th = thinkercap.next; th != &thinkercap; th = th->next)
  177. {
  178. if(th->function == P_MobjThinker)
  179. {
  180. SV_WriteByte(tc_mobj);
  181. memcpy(&mobj, th, sizeof(mobj_t));
  182. mobj.state = (state_t *)(mobj.state-states);
  183. if(mobj.player)
  184. {
  185. mobj.player = (player_t *)((mobj.player-players)+1);
  186. }
  187. SV_Write(&mobj, sizeof(mobj_t));
  188. continue;
  189. }
  190. //I_Error("P_ArchiveThinkers: Unknown thinker function");
  191. }
  192. // Add a terminating marker
  193. SV_WriteByte(tc_end);
  194. }
  195. /*
  196. ====================
  197. =
  198. = P_UnArchiveThinkers
  199. =
  200. ====================
  201. */
  202. void P_UnArchiveThinkers (void)
  203. {
  204. byte tclass;
  205. thinker_t *currentthinker, *next;
  206. mobj_t *mobj;
  207. //
  208. // remove all the current thinkers
  209. //
  210. currentthinker = thinkercap.next;
  211. while (currentthinker != &thinkercap)
  212. {
  213. next = currentthinker->next;
  214. if (currentthinker->function == P_MobjThinker)
  215. P_RemoveMobj ((mobj_t *)currentthinker);
  216. else
  217. Z_Free (currentthinker);
  218. currentthinker = next;
  219. }
  220. P_InitThinkers ();
  221. // read in saved thinkers
  222. while (1)
  223. {
  224. tclass = *save_p++;
  225. switch (tclass)
  226. {
  227. case tc_end:
  228. return; // end of list
  229. case tc_mobj:
  230. mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
  231. memcpy (mobj, save_p, sizeof(*mobj));
  232. save_p += sizeof(*mobj);
  233. mobj->state = &states[(int)mobj->state];
  234. mobj->target = NULL;
  235. if (mobj->player)
  236. {
  237. mobj->player = &players[(int)mobj->player-1];
  238. mobj->player->mo = mobj;
  239. }
  240. P_SetThingPosition (mobj);
  241. mobj->info = &mobjinfo[mobj->type];
  242. mobj->floorz = mobj->subsector->sector->floorheight;
  243. mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  244. mobj->thinker.function = P_MobjThinker;
  245. P_AddThinker (&mobj->thinker);
  246. break;
  247. default:
  248. I_Error ("Unknown tclass %i in savegame",tclass);
  249. }
  250. }
  251. }
  252. //=============================================================================
  253. /*
  254. ====================
  255. =
  256. = P_ArchiveSpecials
  257. =
  258. ====================
  259. */
  260. enum
  261. {
  262. tc_ceiling,
  263. tc_door,
  264. tc_floor,
  265. tc_plat,
  266. tc_flash,
  267. tc_strobe,
  268. tc_glow,
  269. tc_endspecials
  270. } specials_e;
  271. void P_ArchiveSpecials(void)
  272. {
  273. /*
  274. T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
  275. T_VerticalDoor, (vldoor_t: sector_t * swizzle),
  276. T_MoveFloor, (floormove_t: sector_t * swizzle),
  277. T_LightFlash, (lightflash_t: sector_t * swizzle),
  278. T_StrobeFlash, (strobe_t: sector_t *),
  279. T_Glow, (glow_t: sector_t *),
  280. T_PlatRaise, (plat_t: sector_t *), - active list
  281. */
  282. thinker_t *th;
  283. ceiling_t ceiling;
  284. vldoor_t door;
  285. floormove_t floor;
  286. plat_t plat;
  287. lightflash_t flash;
  288. strobe_t strobe;
  289. glow_t glow;
  290. for(th = thinkercap.next; th != &thinkercap; th = th->next)
  291. {
  292. if(th->function == T_MoveCeiling)
  293. {
  294. SV_WriteByte(tc_ceiling);
  295. memcpy(&ceiling, th, sizeof(ceiling_t));
  296. ceiling.sector = (sector_t *)(ceiling.sector-sectors);
  297. SV_Write(&ceiling, sizeof(ceiling_t));
  298. continue;
  299. }
  300. if(th->function == T_VerticalDoor)
  301. {
  302. SV_WriteByte(tc_door);
  303. memcpy(&door, th, sizeof(vldoor_t));
  304. door.sector = (sector_t *)(door.sector-sectors);
  305. SV_Write(&door, sizeof(vldoor_t));
  306. continue;
  307. }
  308. if(th->function == T_MoveFloor)
  309. {
  310. SV_WriteByte(tc_floor);
  311. memcpy(&floor, th, sizeof(floormove_t));
  312. floor.sector = (sector_t *)(floor.sector-sectors);
  313. SV_Write(&floor, sizeof(floormove_t));
  314. continue;
  315. }
  316. if(th->function == T_PlatRaise)
  317. {
  318. SV_WriteByte(tc_plat);
  319. memcpy(&plat, th, sizeof(plat_t));
  320. plat.sector = (sector_t *)(plat.sector-sectors);
  321. SV_Write(&plat, sizeof(plat_t));
  322. continue;
  323. }
  324. if(th->function == T_LightFlash)
  325. {
  326. SV_WriteByte(tc_flash);
  327. memcpy(&flash, th, sizeof(lightflash_t));
  328. flash.sector = (sector_t *)(flash.sector-sectors);
  329. SV_Write(&flash, sizeof(lightflash_t));
  330. continue;
  331. }
  332. if(th->function == T_StrobeFlash)
  333. {
  334. SV_WriteByte(tc_strobe);
  335. memcpy(&strobe, th, sizeof(strobe_t));
  336. strobe.sector = (sector_t *)(strobe.sector-sectors);
  337. SV_Write(&strobe, sizeof(strobe_t));
  338. continue;
  339. }
  340. if(th->function == T_Glow)
  341. {
  342. SV_WriteByte(tc_glow);
  343. memcpy(&glow, th, sizeof(glow_t));
  344. glow.sector = (sector_t *)(glow.sector-sectors);
  345. SV_Write(&glow, sizeof(glow_t));
  346. continue;
  347. }
  348. }
  349. // Add a terminating marker
  350. SV_WriteByte(tc_endspecials);
  351. }
  352. /*
  353. ====================
  354. =
  355. = P_UnArchiveSpecials
  356. =
  357. ====================
  358. */
  359. void P_UnArchiveSpecials (void)
  360. {
  361. byte tclass;
  362. ceiling_t *ceiling;
  363. vldoor_t *door;
  364. floormove_t *floor;
  365. plat_t *plat;
  366. lightflash_t *flash;
  367. strobe_t *strobe;
  368. glow_t *glow;
  369. // read in saved thinkers
  370. while (1)
  371. {
  372. tclass = *save_p++;
  373. switch (tclass)
  374. {
  375. case tc_endspecials:
  376. return; // end of list
  377. case tc_ceiling:
  378. ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
  379. memcpy (ceiling, save_p, sizeof(*ceiling));
  380. save_p += sizeof(*ceiling);
  381. ceiling->sector = &sectors[(int)ceiling->sector];
  382. ceiling->sector->specialdata = T_MoveCeiling;
  383. if (ceiling->thinker.function)
  384. ceiling->thinker.function = T_MoveCeiling;
  385. P_AddThinker (&ceiling->thinker);
  386. P_AddActiveCeiling(ceiling);
  387. break;
  388. case tc_door:
  389. door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
  390. memcpy (door, save_p, sizeof(*door));
  391. save_p += sizeof(*door);
  392. door->sector = &sectors[(int)door->sector];
  393. door->sector->specialdata = door;
  394. door->thinker.function = T_VerticalDoor;
  395. P_AddThinker (&door->thinker);
  396. break;
  397. case tc_floor:
  398. floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  399. memcpy (floor, save_p, sizeof(*floor));
  400. save_p += sizeof(*floor);
  401. floor->sector = &sectors[(int)floor->sector];
  402. floor->sector->specialdata = T_MoveFloor;
  403. floor->thinker.function = T_MoveFloor;
  404. P_AddThinker (&floor->thinker);
  405. break;
  406. case tc_plat:
  407. plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  408. memcpy (plat, save_p, sizeof(*plat));
  409. save_p += sizeof(*plat);
  410. plat->sector = &sectors[(int)plat->sector];
  411. plat->sector->specialdata = T_PlatRaise;
  412. if (plat->thinker.function)
  413. plat->thinker.function = T_PlatRaise;
  414. P_AddThinker (&plat->thinker);
  415. P_AddActivePlat(plat);
  416. break;
  417. case tc_flash:
  418. flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  419. memcpy (flash, save_p, sizeof(*flash));
  420. save_p += sizeof(*flash);
  421. flash->sector = &sectors[(int)flash->sector];
  422. flash->thinker.function = T_LightFlash;
  423. P_AddThinker (&flash->thinker);
  424. break;
  425. case tc_strobe:
  426. strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  427. memcpy (strobe, save_p, sizeof(*strobe));
  428. save_p += sizeof(*strobe);
  429. strobe->sector = &sectors[(int)strobe->sector];
  430. strobe->thinker.function = T_StrobeFlash;
  431. P_AddThinker (&strobe->thinker);
  432. break;
  433. case tc_glow:
  434. glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  435. memcpy (glow, save_p, sizeof(*glow));
  436. save_p += sizeof(*glow);
  437. glow->sector = &sectors[(int)glow->sector];
  438. glow->thinker.function = T_Glow;
  439. P_AddThinker (&glow->thinker);
  440. break;
  441. default:
  442. I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
  443. "in savegame",tclass);
  444. }
  445. }
  446. }
  447. /*
  448. ===============================================================================
  449. THINKERS
  450. All thinkers should be allocated by Z_Malloc so they can be operated on uniformly. The actual
  451. structures will vary in size, but the first element must be thinker_t.
  452. ===============================================================================
  453. */
  454. thinker_t thinkercap; // both the head and tail of the thinker list
  455. /*
  456. ===============
  457. =
  458. = P_InitThinkers
  459. =
  460. ===============
  461. */
  462. void P_InitThinkers (void)
  463. {
  464. thinkercap.prev = thinkercap.next = &thinkercap;
  465. }
  466. /*
  467. ===============
  468. =
  469. = P_AddThinker
  470. =
  471. = Adds a new thinker at the end of the list
  472. =
  473. ===============
  474. */
  475. void P_AddThinker (thinker_t *thinker)
  476. {
  477. thinkercap.prev->next = thinker;
  478. thinker->next = &thinkercap;
  479. thinker->prev = thinkercap.prev;
  480. thinkercap.prev = thinker;
  481. }
  482. /*
  483. ===============
  484. =
  485. = P_RemoveThinker
  486. =
  487. = Deallocation is lazy -- it will not actually be freed until its
  488. = thinking turn comes up
  489. =
  490. ===============
  491. */
  492. void P_RemoveThinker (thinker_t *thinker)
  493. {
  494. thinker->function = (think_t)-1;
  495. }
  496. /*
  497. ===============
  498. =
  499. = P_AllocateThinker
  500. =
  501. = Allocates memory and adds a new thinker at the end of the list
  502. =
  503. ===============
  504. */
  505. void P_AllocateThinker (thinker_t *thinker)
  506. {
  507. }
  508. /*
  509. ===============
  510. =
  511. = P_RunThinkers
  512. =
  513. ===============
  514. */
  515. void P_RunThinkers (void)
  516. {
  517. thinker_t *currentthinker;
  518. currentthinker = thinkercap.next;
  519. while (currentthinker != &thinkercap)
  520. {
  521. if (currentthinker->function == (think_t)-1)
  522. { // time to remove it
  523. currentthinker->next->prev = currentthinker->prev;
  524. currentthinker->prev->next = currentthinker->next;
  525. Z_Free (currentthinker);
  526. }
  527. else
  528. {
  529. if (currentthinker->function)
  530. currentthinker->function (currentthinker);
  531. }
  532. currentthinker = currentthinker->next;
  533. }
  534. }
  535. //----------------------------------------------------------------------------
  536. //
  537. // PROC P_Ticker
  538. //
  539. //----------------------------------------------------------------------------
  540. void P_Ticker(void)
  541. {
  542. int i;
  543. if(paused)
  544. {
  545. return;
  546. }
  547. for(i = 0; i < MAXPLAYERS; i++)
  548. {
  549. if(playeringame[i])
  550. {
  551. P_PlayerThink(&players[i]);
  552. }
  553. }
  554. if(TimerGame)
  555. {
  556. if(!--TimerGame)
  557. {
  558. G_ExitLevel();
  559. }
  560. }
  561. P_RunThinkers();
  562. P_UpdateSpecials();
  563. P_AmbientSound();
  564. leveltime++;
  565. }