p_saveg.cpp 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include "i_system.h"
  23. #include "z_zone.h"
  24. #include "p_local.h"
  25. // State.
  26. #include "doomstat.h"
  27. #include "r_state.h"
  28. // Pads ::g->save_p to a 4-byte boundary
  29. // so that the load/save works on SGI&Gecko.
  30. //
  31. // P_ArchivePlayers
  32. //
  33. void P_ArchivePlayers (void)
  34. {
  35. int i;
  36. int j;
  37. player_t* dest;
  38. for (i=0 ; i<MAXPLAYERS ; i++)
  39. {
  40. if (!::g->playeringame[i])
  41. continue;
  42. PADSAVEP();
  43. dest = (player_t *)::g->save_p;
  44. memcpy (dest,&::g->players[i],sizeof(player_t));
  45. ::g->save_p += sizeof(player_t);
  46. for (j=0 ; j<NUMPSPRITES ; j++)
  47. {
  48. if (dest->psprites[j].state)
  49. {
  50. dest->psprites[j].state
  51. = (state_t *)(dest->psprites[j].state-::g->states);
  52. }
  53. }
  54. }
  55. }
  56. //
  57. // P_UnArchivePlayers
  58. //
  59. void P_UnArchivePlayers (void)
  60. {
  61. int i;
  62. int j;
  63. for (i=0 ; i<MAXPLAYERS ; i++)
  64. {
  65. if (!::g->playeringame[i])
  66. continue;
  67. PADSAVEP();
  68. memcpy (&::g->players[i],::g->save_p, sizeof(player_t));
  69. ::g->save_p += sizeof(player_t);
  70. // will be set when unarc thinker
  71. ::g->players[i].mo = NULL;
  72. ::g->players[i].message = NULL;
  73. ::g->players[i].attacker = NULL;
  74. for (j=0 ; j<NUMPSPRITES ; j++)
  75. {
  76. if (::g->players[i]. psprites[j].state)
  77. {
  78. ::g->players[i]. psprites[j].state
  79. = &::g->states[ (int)::g->players[i].psprites[j].state ];
  80. }
  81. }
  82. }
  83. }
  84. //
  85. // P_ArchiveWorld
  86. //
  87. void P_ArchiveWorld (void)
  88. {
  89. int i;
  90. int j;
  91. sector_t* sec;
  92. line_t* li;
  93. side_t* si;
  94. short* put;
  95. put = (short *)::g->save_p;
  96. // do ::g->sectors
  97. for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
  98. {
  99. *put++ = sec->floorheight >> FRACBITS;
  100. *put++ = sec->ceilingheight >> FRACBITS;
  101. *put++ = sec->floorpic;
  102. *put++ = sec->ceilingpic;
  103. *put++ = sec->lightlevel;
  104. *put++ = sec->special; // needed?
  105. *put++ = sec->tag; // needed?
  106. }
  107. // do ::g->lines
  108. for (i=0, li = ::g->lines ; i < ::g->numlines ; i++,li++)
  109. {
  110. *put++ = li->flags;
  111. *put++ = li->special;
  112. *put++ = li->tag;
  113. for (j=0 ; j<2 ; j++)
  114. {
  115. if (li->sidenum[j] == -1)
  116. continue;
  117. si = &::g->sides[li->sidenum[j]];
  118. *put++ = si->textureoffset >> FRACBITS;
  119. *put++ = si->rowoffset >> FRACBITS;
  120. *put++ = si->toptexture;
  121. *put++ = si->bottomtexture;
  122. *put++ = si->midtexture;
  123. }
  124. }
  125. // Doom 2 level 30 requires some global pointers, wheee!
  126. *put++ = ::g->braintargeton;
  127. *put++ = ::g->easy;
  128. ::g->save_p = (byte *)put;
  129. }
  130. //
  131. // P_UnArchiveWorld
  132. //
  133. void P_UnArchiveWorld (void)
  134. {
  135. int i;
  136. int j;
  137. sector_t* sec;
  138. line_t* li;
  139. side_t* si;
  140. short* get;
  141. get = (short *)::g->save_p;
  142. // do ::g->sectors
  143. for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
  144. {
  145. sec->floorheight = *get++ << FRACBITS;
  146. sec->ceilingheight = *get++ << FRACBITS;
  147. sec->floorpic = *get++;
  148. sec->ceilingpic = *get++;
  149. sec->lightlevel = *get++;
  150. sec->special = *get++; // needed?
  151. sec->tag = *get++; // needed?
  152. sec->specialdata = 0;
  153. sec->soundtarget = 0;
  154. }
  155. // do ::g->lines
  156. for (i=0, li = ::g->lines ; i < ::g->numlines ; i++,li++)
  157. {
  158. li->flags = *get++;
  159. li->special = *get++;
  160. li->tag = *get++;
  161. for (j=0 ; j<2 ; j++)
  162. {
  163. if (li->sidenum[j] == -1)
  164. continue;
  165. si = &::g->sides[li->sidenum[j]];
  166. si->textureoffset = *get++ << FRACBITS;
  167. si->rowoffset = *get++ << FRACBITS;
  168. si->toptexture = *get++;
  169. si->bottomtexture = *get++;
  170. si->midtexture = *get++;
  171. }
  172. }
  173. // Doom 2 level 30 requires some global pointers, wheee!
  174. ::g->braintargeton = *get++;
  175. ::g->easy = *get++;
  176. ::g->save_p = (byte *)get;
  177. }
  178. //
  179. // Thinkers
  180. //
  181. int GetMOIndex( mobj_t* findme ) {
  182. thinker_t* th;
  183. mobj_t* mobj;
  184. int index = 0;
  185. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
  186. {
  187. if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
  188. index++;
  189. mobj = (mobj_t*)th;
  190. if ( mobj == findme ) {
  191. return index;
  192. }
  193. }
  194. }
  195. return 0;
  196. }
  197. mobj_t* GetMO( int index ) {
  198. thinker_t* th;
  199. int testindex = 0;
  200. if ( !index ) {
  201. return NULL;
  202. }
  203. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
  204. {
  205. if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
  206. testindex++;
  207. if ( testindex == index ) {
  208. return (mobj_t*)th;
  209. }
  210. }
  211. }
  212. return NULL;
  213. }
  214. //
  215. // P_ArchiveThinkers
  216. //
  217. void P_ArchiveThinkers (void)
  218. {
  219. thinker_t* th;
  220. mobj_t* mobj;
  221. ceiling_t* ceiling;
  222. vldoor_t* door;
  223. floormove_t* floor;
  224. plat_t* plat;
  225. fireflicker_t* fire;
  226. lightflash_t* flash;
  227. strobe_t* strobe;
  228. glow_t* glow;
  229. int i;
  230. // save off the current thinkers
  231. //I_Printf( "Savegame on leveltime %d\n====================\n", ::g->leveltime );
  232. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
  233. {
  234. //mobj_t* test = (mobj_t*)th;
  235. //I_Printf( "%3d: %x == function\n", index++, th->function.acp1 );
  236. if (th->function.acp1 == (actionf_p1)P_MobjThinker)
  237. {
  238. *::g->save_p++ = tc_mobj;
  239. PADSAVEP();
  240. mobj = (mobj_t *)::g->save_p;
  241. memcpy (mobj, th, sizeof(*mobj));
  242. ::g->save_p += sizeof(*mobj);
  243. mobj->state = (state_t *)(mobj->state - ::g->states);
  244. if (mobj->player)
  245. mobj->player = (player_t *)((mobj->player-::g->players) + 1);
  246. // Save out 'target'
  247. int moIndex = GetMOIndex( mobj->target );
  248. *::g->save_p++ = moIndex >> 8;
  249. *::g->save_p++ = moIndex;
  250. // Save out 'tracer'
  251. moIndex = GetMOIndex( mobj->tracer );
  252. *::g->save_p++ = moIndex >> 8;
  253. *::g->save_p++ = moIndex;
  254. moIndex = GetMOIndex( mobj->snext );
  255. *::g->save_p++ = moIndex >> 8;
  256. *::g->save_p++ = moIndex;
  257. moIndex = GetMOIndex( mobj->sprev );
  258. *::g->save_p++ = moIndex >> 8;
  259. *::g->save_p++ = moIndex;
  260. // Is this the head of a sector list?
  261. if ( mobj->subsector->sector->thinglist == (mobj_t*)th ) {
  262. *::g->save_p++ = 1;
  263. }
  264. else {
  265. *::g->save_p++ = 0;
  266. }
  267. moIndex = GetMOIndex( mobj->bnext );
  268. *::g->save_p++ = moIndex >> 8;
  269. *::g->save_p++ = moIndex;
  270. moIndex = GetMOIndex( mobj->bprev );
  271. *::g->save_p++ = moIndex >> 8;
  272. *::g->save_p++ = moIndex;
  273. // Is this the head of a block list?
  274. int blockx = (mobj->x - ::g->bmaporgx)>>MAPBLOCKSHIFT;
  275. int blocky = (mobj->y - ::g->bmaporgy)>>MAPBLOCKSHIFT;
  276. if ( blockx >= 0 && blockx < ::g->bmapwidth && blocky >= 0 && blocky < ::g->bmapheight
  277. && (mobj_t*)th == ::g->blocklinks[blocky*::g->bmapwidth+blockx] ) {
  278. *::g->save_p++ = 1;
  279. }
  280. else {
  281. *::g->save_p++ = 0;
  282. }
  283. continue;
  284. }
  285. if (th->function.acv == (actionf_v)NULL)
  286. {
  287. for (i = 0; i < MAXCEILINGS;i++)
  288. if (::g->activeceilings[i] == (ceiling_t *)th)
  289. break;
  290. if (i<MAXCEILINGS)
  291. {
  292. *::g->save_p++ = tc_ceiling;
  293. PADSAVEP();
  294. ceiling = (ceiling_t *)::g->save_p;
  295. memcpy (ceiling, th, sizeof(*ceiling));
  296. ::g->save_p += sizeof(*ceiling);
  297. ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
  298. }
  299. continue;
  300. }
  301. if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
  302. {
  303. *::g->save_p++ = tc_ceiling;
  304. PADSAVEP();
  305. ceiling = (ceiling_t *)::g->save_p;
  306. memcpy (ceiling, th, sizeof(*ceiling));
  307. ::g->save_p += sizeof(*ceiling);
  308. ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
  309. continue;
  310. }
  311. if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
  312. {
  313. *::g->save_p++ = tc_door;
  314. PADSAVEP();
  315. door = (vldoor_t *)::g->save_p;
  316. memcpy (door, th, sizeof(*door));
  317. ::g->save_p += sizeof(*door);
  318. door->sector = (sector_t *)(door->sector - ::g->sectors);
  319. continue;
  320. }
  321. if (th->function.acp1 == (actionf_p1)T_MoveFloor)
  322. {
  323. *::g->save_p++ = tc_floor;
  324. PADSAVEP();
  325. floor = (floormove_t *)::g->save_p;
  326. memcpy (floor, th, sizeof(*floor));
  327. ::g->save_p += sizeof(*floor);
  328. floor->sector = (sector_t *)(floor->sector - ::g->sectors);
  329. continue;
  330. }
  331. if (th->function.acp1 == (actionf_p1)T_PlatRaise)
  332. {
  333. *::g->save_p++ = tc_plat;
  334. PADSAVEP();
  335. plat = (plat_t *)::g->save_p;
  336. memcpy (plat, th, sizeof(*plat));
  337. ::g->save_p += sizeof(*plat);
  338. plat->sector = (sector_t *)(plat->sector - ::g->sectors);
  339. continue;
  340. }
  341. if (th->function.acp1 == (actionf_p1)T_FireFlicker)
  342. {
  343. *::g->save_p++ = tc_fire;
  344. PADSAVEP();
  345. fire = (fireflicker_t *)::g->save_p;
  346. memcpy (fire, th, sizeof(*fire));
  347. ::g->save_p += sizeof(*fire);
  348. fire->sector = (sector_t *)(fire->sector - ::g->sectors);
  349. continue;
  350. }
  351. if (th->function.acp1 == (actionf_p1)T_LightFlash)
  352. {
  353. *::g->save_p++ = tc_flash;
  354. PADSAVEP();
  355. flash = (lightflash_t *)::g->save_p;
  356. memcpy (flash, th, sizeof(*flash));
  357. ::g->save_p += sizeof(*flash);
  358. flash->sector = (sector_t *)(flash->sector - ::g->sectors);
  359. continue;
  360. }
  361. if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
  362. {
  363. *::g->save_p++ = tc_strobe;
  364. PADSAVEP();
  365. strobe = (strobe_t *)::g->save_p;
  366. memcpy (strobe, th, sizeof(*strobe));
  367. ::g->save_p += sizeof(*strobe);
  368. strobe->sector = (sector_t *)(strobe->sector - ::g->sectors);
  369. continue;
  370. }
  371. if (th->function.acp1 == (actionf_p1)T_Glow)
  372. {
  373. *::g->save_p++ = tc_glow;
  374. PADSAVEP();
  375. glow = (glow_t *)::g->save_p;
  376. memcpy (glow, th, sizeof(*glow));
  377. ::g->save_p += sizeof(*glow);
  378. glow->sector = (sector_t *)(glow->sector - ::g->sectors);
  379. continue;
  380. }
  381. }
  382. // add a terminating marker
  383. *::g->save_p++ = tc_end;
  384. sector_t* sec;
  385. short* put = (short *)::g->save_p;
  386. for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++) {
  387. *put++ = (short)GetMOIndex( sec->soundtarget );
  388. }
  389. ::g->save_p = (byte *)put;
  390. // add a terminating marker
  391. *::g->save_p++ = tc_end;
  392. }
  393. //
  394. // P_UnArchiveThinkers
  395. //
  396. void P_UnArchiveThinkers (void)
  397. {
  398. byte tclass;
  399. thinker_t* currentthinker;
  400. thinker_t* next;
  401. mobj_t* mobj;
  402. ceiling_t* ceiling;
  403. vldoor_t* door;
  404. floormove_t* floor;
  405. plat_t* plat;
  406. fireflicker_t* fire;
  407. lightflash_t* flash;
  408. strobe_t* strobe;
  409. glow_t* glow;
  410. thinker_t* th;
  411. int count = 0;
  412. sector_t* ss = NULL;
  413. int mo_index = 0;
  414. int mo_targets[1024];
  415. int mo_tracers[1024];
  416. int mo_snext[1024];
  417. int mo_sprev[1024];
  418. bool mo_shead[1024];
  419. int mo_bnext[1024];
  420. int mo_bprev[1024];
  421. bool mo_bhead[1024];
  422. // remove all the current thinkers
  423. currentthinker = ::g->thinkercap.next;
  424. while (currentthinker != &::g->thinkercap)
  425. {
  426. next = currentthinker->next;
  427. if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
  428. P_RemoveMobj ((mobj_t *)currentthinker);
  429. else
  430. Z_Free(currentthinker);
  431. currentthinker = next;
  432. }
  433. P_InitThinkers ();
  434. // read in saved thinkers
  435. while (1)
  436. {
  437. tclass = *::g->save_p++;
  438. switch (tclass)
  439. {
  440. case tc_end:
  441. // clear sector thing lists
  442. ss = ::g->sectors;
  443. for (int i=0 ; i < ::g->numsectors ; i++, ss++) {
  444. ss->thinglist = NULL;
  445. }
  446. // clear blockmap thing lists
  447. count = sizeof(*::g->blocklinks) * ::g->bmapwidth * ::g->bmapheight;
  448. memset (::g->blocklinks, 0, count);
  449. // Doom 2 level 30 requires some global pointers, wheee!
  450. ::g->numbraintargets = 0;
  451. // fixup mobj_t pointers now that all thinkers have been restored
  452. mo_index = 0;
  453. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next) {
  454. if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
  455. mobj = (mobj_t*)th;
  456. mobj->target = GetMO( mo_targets[mo_index] );
  457. mobj->tracer = GetMO( mo_tracers[mo_index] );
  458. mobj->snext = GetMO( mo_snext[mo_index] );
  459. mobj->sprev = GetMO( mo_sprev[mo_index] );
  460. if ( mo_shead[mo_index] ) {
  461. mobj->subsector->sector->thinglist = mobj;
  462. }
  463. mobj->bnext = GetMO( mo_bnext[mo_index] );
  464. mobj->bprev = GetMO( mo_bprev[mo_index] );
  465. if ( mo_bhead[mo_index] ) {
  466. // Is this the head of a block list?
  467. int blockx = (mobj->x - ::g->bmaporgx)>>MAPBLOCKSHIFT;
  468. int blocky = (mobj->y - ::g->bmaporgy)>>MAPBLOCKSHIFT;
  469. if ( blockx >= 0 && blockx < ::g->bmapwidth && blocky >= 0 && blocky < ::g->bmapheight ) {
  470. ::g->blocklinks[blocky*::g->bmapwidth+blockx] = mobj;
  471. }
  472. }
  473. // Doom 2 level 30 requires some global pointers, wheee!
  474. if ( mobj->type == MT_BOSSTARGET ) {
  475. ::g->braintargets[::g->numbraintargets] = mobj;
  476. ::g->numbraintargets++;
  477. }
  478. mo_index++;
  479. }
  480. }
  481. int i;
  482. sector_t* sec;
  483. short* get;
  484. get = (short *)::g->save_p;
  485. for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
  486. {
  487. sec->soundtarget = GetMO( *get++ );
  488. }
  489. ::g->save_p = (byte *)get;
  490. tclass = *::g->save_p++;
  491. if ( tclass != tc_end ) {
  492. I_Error( "Savegame error after loading sector soundtargets." );
  493. }
  494. // print the current thinkers
  495. //I_Printf( "Loadgame on leveltime %d\n====================\n", ::g->leveltime );
  496. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
  497. {
  498. //mobj_t* test = (mobj_t*)th;
  499. //I_Printf( "%3d: %x == function\n", index++, th->function.acp1 );
  500. }
  501. return; // end of list
  502. case tc_mobj:
  503. PADSAVEP();
  504. mobj = (mobj_t*)DoomLib::Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL);
  505. memcpy (mobj, ::g->save_p, sizeof(*mobj));
  506. ::g->save_p += sizeof(*mobj);
  507. mobj->state = &::g->states[(int)mobj->state];
  508. mobj->target = NULL;
  509. mobj->tracer = NULL;
  510. if (mobj->player)
  511. {
  512. mobj->player = &::g->players[(int)mobj->player-1];
  513. mobj->player->mo = mobj;
  514. }
  515. P_SetThingPosition (mobj);
  516. mobj->info = &mobjinfo[mobj->type];
  517. mobj->floorz = mobj->subsector->sector->floorheight;
  518. mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  519. mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
  520. // Read in 'target' and store for fixup
  521. int a, b, foundIndex;
  522. a = *::g->save_p++;
  523. b = *::g->save_p++;
  524. foundIndex = (a << 8) + b;
  525. mo_targets[mo_index] = foundIndex;
  526. // Read in 'tracer' and store for fixup
  527. a = *::g->save_p++;
  528. b = *::g->save_p++;
  529. foundIndex = (a << 8) + b;
  530. mo_tracers[mo_index] = foundIndex;
  531. // Read in 'snext' and store for fixup
  532. a = *::g->save_p++;
  533. b = *::g->save_p++;
  534. foundIndex = (a << 8) + b;
  535. mo_snext[mo_index] = foundIndex;
  536. // Read in 'sprev' and store for fixup
  537. a = *::g->save_p++;
  538. b = *::g->save_p++;
  539. foundIndex = (a << 8) + b;
  540. mo_sprev[mo_index] = foundIndex;
  541. foundIndex = *::g->save_p++;
  542. mo_shead[mo_index] = foundIndex == 1;
  543. // Read in 'bnext' and store for fixup
  544. a = *::g->save_p++;
  545. b = *::g->save_p++;
  546. foundIndex = (a << 8) + b;
  547. mo_bnext[mo_index] = foundIndex;
  548. // Read in 'bprev' and store for fixup
  549. a = *::g->save_p++;
  550. b = *::g->save_p++;
  551. foundIndex = (a << 8) + b;
  552. mo_bprev[mo_index] = foundIndex;
  553. foundIndex = *::g->save_p++;
  554. mo_bhead[mo_index] = foundIndex == 1;
  555. mo_index++;
  556. P_AddThinker (&mobj->thinker);
  557. break;
  558. case tc_ceiling:
  559. PADSAVEP();
  560. ceiling = (ceiling_t*)DoomLib::Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL);
  561. memcpy (ceiling, ::g->save_p, sizeof(*ceiling));
  562. ::g->save_p += sizeof(*ceiling);
  563. ceiling->sector = &::g->sectors[(int)ceiling->sector];
  564. ceiling->sector->specialdata = ceiling;
  565. if (ceiling->thinker.function.acp1)
  566. ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
  567. P_AddThinker (&ceiling->thinker);
  568. P_AddActiveCeiling(ceiling);
  569. break;
  570. case tc_door:
  571. PADSAVEP();
  572. door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, NULL);
  573. memcpy (door, ::g->save_p, sizeof(*door));
  574. ::g->save_p += sizeof(*door);
  575. door->sector = &::g->sectors[(int)door->sector];
  576. door->sector->specialdata = door;
  577. door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  578. P_AddThinker (&door->thinker);
  579. break;
  580. case tc_floor:
  581. PADSAVEP();
  582. floor = (floormove_t*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  583. memcpy (floor, ::g->save_p, sizeof(*floor));
  584. ::g->save_p += sizeof(*floor);
  585. floor->sector = &::g->sectors[(int)floor->sector];
  586. floor->sector->specialdata = floor;
  587. floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
  588. P_AddThinker (&floor->thinker);
  589. break;
  590. case tc_plat:
  591. PADSAVEP();
  592. plat = (plat_t*)DoomLib::Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  593. memcpy (plat, ::g->save_p, sizeof(*plat));
  594. ::g->save_p += sizeof(*plat);
  595. plat->sector = &::g->sectors[(int)plat->sector];
  596. plat->sector->specialdata = plat;
  597. if (plat->thinker.function.acp1)
  598. plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
  599. P_AddThinker (&plat->thinker);
  600. P_AddActivePlat(plat);
  601. break;
  602. case tc_fire:
  603. PADSAVEP();
  604. fire = (fireflicker_t*)DoomLib::Z_Malloc (sizeof(*fire), PU_LEVEL, NULL);
  605. memcpy (fire, ::g->save_p, sizeof(*fire));
  606. ::g->save_p += sizeof(*fire);
  607. fire->sector = &::g->sectors[(int)fire->sector];
  608. fire->thinker.function.acp1 = (actionf_p1)T_FireFlicker;
  609. P_AddThinker (&fire->thinker);
  610. break;
  611. case tc_flash:
  612. PADSAVEP();
  613. flash = (lightflash_t*)DoomLib::Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  614. memcpy (flash, ::g->save_p, sizeof(*flash));
  615. ::g->save_p += sizeof(*flash);
  616. flash->sector = &::g->sectors[(int)flash->sector];
  617. flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
  618. P_AddThinker (&flash->thinker);
  619. break;
  620. case tc_strobe:
  621. PADSAVEP();
  622. strobe = (strobe_t*)DoomLib::Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  623. memcpy (strobe, ::g->save_p, sizeof(*strobe));
  624. ::g->save_p += sizeof(*strobe);
  625. strobe->sector = &::g->sectors[(int)strobe->sector];
  626. strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
  627. P_AddThinker (&strobe->thinker);
  628. break;
  629. case tc_glow:
  630. PADSAVEP();
  631. glow = (glow_t*)DoomLib::Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  632. memcpy (glow, ::g->save_p, sizeof(*glow));
  633. ::g->save_p += sizeof(*glow);
  634. glow->sector = &::g->sectors[(int)glow->sector];
  635. glow->thinker.function.acp1 = (actionf_p1)T_Glow;
  636. P_AddThinker (&glow->thinker);
  637. break;
  638. default:
  639. I_Error ("Unknown tclass %i in savegame",tclass);
  640. }
  641. }
  642. }
  643. //
  644. // P_ArchiveSpecials
  645. //
  646. //
  647. // Things to handle:
  648. //
  649. // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
  650. // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
  651. // T_MoveFloor, (floormove_t: sector_t * swizzle),
  652. // T_LightFlash, (lightflash_t: sector_t * swizzle),
  653. // T_StrobeFlash, (strobe_t: sector_t *),
  654. // T_Glow, (glow_t: sector_t *),
  655. // T_PlatRaise, (plat_t: sector_t *), - active list
  656. //
  657. void P_ArchiveSpecials (void)
  658. {
  659. thinker_t* th;
  660. ceiling_t* ceiling;
  661. vldoor_t* door;
  662. floormove_t* floor;
  663. plat_t* plat;
  664. lightflash_t* flash;
  665. strobe_t* strobe;
  666. glow_t* glow;
  667. int i;
  668. // save off the current thinkers
  669. for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
  670. {
  671. if (th->function.acv == (actionf_v)NULL)
  672. {
  673. for (i = 0; i < MAXCEILINGS;i++)
  674. if (::g->activeceilings[i] == (ceiling_t *)th)
  675. break;
  676. if (i<MAXCEILINGS)
  677. {
  678. *::g->save_p++ = tc_ceiling;
  679. PADSAVEP();
  680. ceiling = (ceiling_t *)::g->save_p;
  681. memcpy (ceiling, th, sizeof(*ceiling));
  682. ::g->save_p += sizeof(*ceiling);
  683. ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
  684. }
  685. continue;
  686. }
  687. if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
  688. {
  689. *::g->save_p++ = tc_ceiling;
  690. PADSAVEP();
  691. ceiling = (ceiling_t *)::g->save_p;
  692. memcpy (ceiling, th, sizeof(*ceiling));
  693. ::g->save_p += sizeof(*ceiling);
  694. ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
  695. continue;
  696. }
  697. if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
  698. {
  699. *::g->save_p++ = tc_door;
  700. PADSAVEP();
  701. door = (vldoor_t *)::g->save_p;
  702. memcpy (door, th, sizeof(*door));
  703. ::g->save_p += sizeof(*door);
  704. door->sector = (sector_t *)(door->sector - ::g->sectors);
  705. continue;
  706. }
  707. if (th->function.acp1 == (actionf_p1)T_MoveFloor)
  708. {
  709. *::g->save_p++ = tc_floor;
  710. PADSAVEP();
  711. floor = (floormove_t *)::g->save_p;
  712. memcpy (floor, th, sizeof(*floor));
  713. ::g->save_p += sizeof(*floor);
  714. floor->sector = (sector_t *)(floor->sector - ::g->sectors);
  715. continue;
  716. }
  717. if (th->function.acp1 == (actionf_p1)T_PlatRaise)
  718. {
  719. *::g->save_p++ = tc_plat;
  720. PADSAVEP();
  721. plat = (plat_t *)::g->save_p;
  722. memcpy (plat, th, sizeof(*plat));
  723. ::g->save_p += sizeof(*plat);
  724. plat->sector = (sector_t *)(plat->sector - ::g->sectors);
  725. continue;
  726. }
  727. if (th->function.acp1 == (actionf_p1)T_LightFlash)
  728. {
  729. *::g->save_p++ = tc_flash;
  730. PADSAVEP();
  731. flash = (lightflash_t *)::g->save_p;
  732. memcpy (flash, th, sizeof(*flash));
  733. ::g->save_p += sizeof(*flash);
  734. flash->sector = (sector_t *)(flash->sector - ::g->sectors);
  735. continue;
  736. }
  737. if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
  738. {
  739. *::g->save_p++ = tc_strobe;
  740. PADSAVEP();
  741. strobe = (strobe_t *)::g->save_p;
  742. memcpy (strobe, th, sizeof(*strobe));
  743. ::g->save_p += sizeof(*strobe);
  744. strobe->sector = (sector_t *)(strobe->sector - ::g->sectors);
  745. continue;
  746. }
  747. if (th->function.acp1 == (actionf_p1)T_Glow)
  748. {
  749. *::g->save_p++ = tc_glow;
  750. PADSAVEP();
  751. glow = (glow_t *)::g->save_p;
  752. memcpy (glow, th, sizeof(*glow));
  753. ::g->save_p += sizeof(*glow);
  754. glow->sector = (sector_t *)(glow->sector - ::g->sectors);
  755. continue;
  756. }
  757. }
  758. // add a terminating marker
  759. *::g->save_p++ = tc_endspecials;
  760. }
  761. //
  762. // P_UnArchiveSpecials
  763. //
  764. void P_UnArchiveSpecials (void)
  765. {
  766. byte tclass;
  767. ceiling_t* ceiling;
  768. vldoor_t* door;
  769. floormove_t* floor;
  770. plat_t* plat;
  771. lightflash_t* flash;
  772. strobe_t* strobe;
  773. glow_t* glow;
  774. // read in saved thinkers
  775. while (1)
  776. {
  777. tclass = *::g->save_p++;
  778. switch (tclass)
  779. {
  780. case tc_endspecials:
  781. return; // end of list
  782. case tc_ceiling:
  783. PADSAVEP();
  784. ceiling = (ceiling_t*)DoomLib::Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL);
  785. memcpy (ceiling, ::g->save_p, sizeof(*ceiling));
  786. ::g->save_p += sizeof(*ceiling);
  787. ceiling->sector = &::g->sectors[(int)ceiling->sector];
  788. ceiling->sector->specialdata = ceiling;
  789. if (ceiling->thinker.function.acp1)
  790. ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
  791. P_AddThinker (&ceiling->thinker);
  792. P_AddActiveCeiling(ceiling);
  793. break;
  794. case tc_door:
  795. PADSAVEP();
  796. door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, NULL);
  797. memcpy (door, ::g->save_p, sizeof(*door));
  798. ::g->save_p += sizeof(*door);
  799. door->sector = &::g->sectors[(int)door->sector];
  800. door->sector->specialdata = door;
  801. door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  802. P_AddThinker (&door->thinker);
  803. break;
  804. case tc_floor:
  805. PADSAVEP();
  806. floor = (floormove_t*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  807. memcpy (floor, ::g->save_p, sizeof(*floor));
  808. ::g->save_p += sizeof(*floor);
  809. floor->sector = &::g->sectors[(int)floor->sector];
  810. floor->sector->specialdata = floor;
  811. floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
  812. P_AddThinker (&floor->thinker);
  813. break;
  814. case tc_plat:
  815. PADSAVEP();
  816. plat = (plat_t*)DoomLib::Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  817. memcpy (plat, ::g->save_p, sizeof(*plat));
  818. ::g->save_p += sizeof(*plat);
  819. plat->sector = &::g->sectors[(int)plat->sector];
  820. plat->sector->specialdata = plat;
  821. if (plat->thinker.function.acp1)
  822. plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
  823. P_AddThinker (&plat->thinker);
  824. P_AddActivePlat(plat);
  825. break;
  826. case tc_flash:
  827. PADSAVEP();
  828. flash = (lightflash_t*)DoomLib::Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  829. memcpy (flash, ::g->save_p, sizeof(*flash));
  830. ::g->save_p += sizeof(*flash);
  831. flash->sector = &::g->sectors[(int)flash->sector];
  832. flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
  833. P_AddThinker (&flash->thinker);
  834. break;
  835. case tc_strobe:
  836. PADSAVEP();
  837. strobe = (strobe_t*)DoomLib::Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  838. memcpy (strobe, ::g->save_p, sizeof(*strobe));
  839. ::g->save_p += sizeof(*strobe);
  840. strobe->sector = &::g->sectors[(int)strobe->sector];
  841. strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
  842. P_AddThinker (&strobe->thinker);
  843. break;
  844. case tc_glow:
  845. PADSAVEP();
  846. glow = (glow_t*)DoomLib::Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  847. memcpy (glow, ::g->save_p, sizeof(*glow));
  848. ::g->save_p += sizeof(*glow);
  849. glow->sector = &::g->sectors[(int)glow->sector];
  850. glow->thinker.function.acp1 = (actionf_p1)T_Glow;
  851. P_AddThinker (&glow->thinker);
  852. break;
  853. default:
  854. I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
  855. "in savegame",tclass);
  856. }
  857. }
  858. }