p_saveg.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Archiving: SaveGame I/O.
  31. *
  32. *-----------------------------------------------------------------------------*/
  33. #include "doomstat.h"
  34. #include "r_main.h"
  35. #include "p_maputl.h"
  36. #include "p_spec.h"
  37. #include "p_tick.h"
  38. #include "p_saveg.h"
  39. #include "m_random.h"
  40. #include "am_map.h"
  41. #include "p_enemy.h"
  42. #include "lprintf.h"
  43. byte *save_p;
  44. // Pads save_p to a 4-byte boundary
  45. // so that the load/save works on SGI&Gecko.
  46. #define PADSAVEP() do { save_p += (4 - ((int) save_p & 3)) & 3; } while (0)
  47. //
  48. // P_ArchivePlayers
  49. //
  50. void P_ArchivePlayers (void)
  51. {
  52. int i;
  53. CheckSaveGame(sizeof(player_t) * MAXPLAYERS); // killough
  54. for (i=0 ; i<MAXPLAYERS ; i++)
  55. if (playeringame[i])
  56. {
  57. int j;
  58. player_t *dest;
  59. PADSAVEP();
  60. dest = (player_t *) save_p;
  61. memcpy(dest, &players[i], sizeof(player_t));
  62. save_p += sizeof(player_t);
  63. for (j=0; j<NUMPSPRITES; j++)
  64. if (dest->psprites[j].state)
  65. dest->psprites[j].state =
  66. (state_t *)(dest->psprites[j].state-states);
  67. }
  68. }
  69. //
  70. // P_UnArchivePlayers
  71. //
  72. void P_UnArchivePlayers (void)
  73. {
  74. int i;
  75. for (i=0 ; i<MAXPLAYERS ; i++)
  76. if (playeringame[i])
  77. {
  78. int j;
  79. PADSAVEP();
  80. memcpy(&players[i], save_p, sizeof(player_t));
  81. save_p += sizeof(player_t);
  82. // will be set when unarc thinker
  83. players[i].mo = NULL;
  84. players[i].message = NULL;
  85. players[i].attacker = NULL;
  86. for (j=0 ; j<NUMPSPRITES ; j++)
  87. if (players[i]. psprites[j].state)
  88. players[i]. psprites[j].state =
  89. &states[ (int)players[i].psprites[j].state ];
  90. }
  91. }
  92. //
  93. // P_ArchiveWorld
  94. //
  95. void P_ArchiveWorld (void)
  96. {
  97. int i;
  98. const sector_t *sec;
  99. const line_t *li;
  100. const side_t *si;
  101. short *put;
  102. // killough 3/22/98: fix bug caused by hoisting save_p too early
  103. // killough 10/98: adjust size for changes below
  104. size_t size =
  105. (sizeof(short)*5 + sizeof sec->floorheight + sizeof sec->ceilingheight)
  106. * numsectors + sizeof(short)*3*numlines + 4;
  107. for (i=0; i<numlines; i++)
  108. {
  109. if (lines[i].sidenum[0] != NO_INDEX)
  110. size +=
  111. sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset;
  112. if (lines[i].sidenum[1] != NO_INDEX)
  113. size +=
  114. sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset;
  115. }
  116. CheckSaveGame(size); // killough
  117. PADSAVEP(); // killough 3/22/98
  118. put = (short *)save_p;
  119. // do sectors
  120. for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  121. {
  122. // killough 10/98: save full floor & ceiling heights, including fraction
  123. memcpy(put, &sec->floorheight, sizeof sec->floorheight);
  124. put = (void *)((char *) put + sizeof sec->floorheight);
  125. memcpy(put, &sec->ceilingheight, sizeof sec->ceilingheight);
  126. put = (void *)((char *) put + sizeof sec->ceilingheight);
  127. *put++ = sec->floorpic;
  128. *put++ = sec->ceilingpic;
  129. *put++ = sec->lightlevel;
  130. *put++ = sec->special; // needed? yes -- transfer types
  131. *put++ = sec->tag; // needed? need them -- killough
  132. }
  133. // do lines
  134. for (i=0, li = lines ; i<numlines ; i++,li++)
  135. {
  136. int j;
  137. *put++ = li->flags;
  138. *put++ = li->special;
  139. *put++ = li->tag;
  140. for (j=0; j<2; j++)
  141. if (li->sidenum[j] != NO_INDEX)
  142. {
  143. si = &sides[li->sidenum[j]];
  144. // killough 10/98: save full sidedef offsets,
  145. // preserving fractional scroll offsets
  146. memcpy(put, &si->textureoffset, sizeof si->textureoffset);
  147. put = (void *)((char *) put + sizeof si->textureoffset);
  148. memcpy(put, &si->rowoffset, sizeof si->rowoffset);
  149. put = (void *)((char *) put + sizeof si->rowoffset);
  150. *put++ = si->toptexture;
  151. *put++ = si->bottomtexture;
  152. *put++ = si->midtexture;
  153. }
  154. }
  155. save_p = (byte *) put;
  156. }
  157. //
  158. // P_UnArchiveWorld
  159. //
  160. void P_UnArchiveWorld (void)
  161. {
  162. int i;
  163. sector_t *sec;
  164. line_t *li;
  165. const short *get;
  166. PADSAVEP(); // killough 3/22/98
  167. get = (short *) save_p;
  168. // do sectors
  169. for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  170. {
  171. // killough 10/98: load full floor & ceiling heights, including fractions
  172. memcpy(&sec->floorheight, get, sizeof sec->floorheight);
  173. get = (void *)((char *) get + sizeof sec->floorheight);
  174. memcpy(&sec->ceilingheight, get, sizeof sec->ceilingheight);
  175. get = (void *)((char *) get + sizeof sec->ceilingheight);
  176. sec->floorpic = *get++;
  177. sec->ceilingpic = *get++;
  178. sec->lightlevel = *get++;
  179. sec->special = *get++;
  180. sec->tag = *get++;
  181. sec->ceilingdata = 0; //jff 2/22/98 now three thinker fields, not two
  182. sec->floordata = 0;
  183. sec->lightingdata = 0;
  184. sec->soundtarget = 0;
  185. }
  186. // do lines
  187. for (i=0, li = lines ; i<numlines ; i++,li++)
  188. {
  189. int j;
  190. li->flags = *get++;
  191. li->special = *get++;
  192. li->tag = *get++;
  193. for (j=0 ; j<2 ; j++)
  194. if (li->sidenum[j] != NO_INDEX)
  195. {
  196. side_t *si = &sides[li->sidenum[j]];
  197. // killough 10/98: load full sidedef offsets, including fractions
  198. memcpy(&si->textureoffset, get, sizeof si->textureoffset);
  199. get = (void *)((char *) get + sizeof si->textureoffset);
  200. memcpy(&si->rowoffset, get, sizeof si->rowoffset);
  201. get = (void *)((char *) get + sizeof si->rowoffset);
  202. si->toptexture = *get++;
  203. si->bottomtexture = *get++;
  204. si->midtexture = *get++;
  205. }
  206. }
  207. save_p = (byte *) get;
  208. }
  209. //
  210. // Thinkers
  211. //
  212. typedef enum {
  213. tc_end,
  214. tc_mobj
  215. } thinkerclass_t;
  216. // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
  217. // thinker indices could be used by the code that saves sector info.
  218. static int number_of_thinkers;
  219. void P_ThinkerToIndex(void)
  220. {
  221. thinker_t *th;
  222. // killough 2/14/98:
  223. // count the number of thinkers, and mark each one with its index, using
  224. // the prev field as a placeholder, since it can be restored later.
  225. number_of_thinkers = 0;
  226. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  227. if (th->function == P_MobjThinker)
  228. th->prev = (thinker_t *) ++number_of_thinkers;
  229. }
  230. // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
  231. // thinker indices could be used by the code that saves sector info.
  232. void P_IndexToThinker(void)
  233. {
  234. // killough 2/14/98: restore prev pointers
  235. thinker_t *th;
  236. thinker_t *prev = &thinkercap;
  237. for (th = thinkercap.next ; th != &thinkercap ; prev=th, th=th->next)
  238. th->prev = prev;
  239. }
  240. //
  241. // P_ArchiveThinkers
  242. //
  243. // 2/14/98 killough: substantially modified to fix savegame bugs
  244. void P_ArchiveThinkers (void)
  245. {
  246. thinker_t *th;
  247. CheckSaveGame(sizeof brain); // killough 3/26/98: Save boss brain state
  248. memcpy(save_p, &brain, sizeof brain);
  249. save_p += sizeof brain;
  250. /* check that enough room is available in savegame buffer
  251. * - killough 2/14/98
  252. * cph - use number_of_thinkers saved by P_ThinkerToIndex above
  253. * size per object is sizeof(mobj_t) - 2*sizeof(void*) - 4*sizeof(fixed_t) plus
  254. * padded type (4) plus 5*sizeof(void*), i.e. sizeof(mobj_t) + 4 +
  255. * 3*sizeof(void*)
  256. * cph - +1 for the tc_end
  257. */
  258. CheckSaveGame(number_of_thinkers*(sizeof(mobj_t)-3*sizeof(fixed_t)+4+3*sizeof(void*)) +1);
  259. // save off the current thinkers
  260. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  261. if (th->function == P_MobjThinker)
  262. {
  263. mobj_t *mobj;
  264. *save_p++ = tc_mobj;
  265. PADSAVEP();
  266. mobj = (mobj_t *)save_p;
  267. /* cph 2006/07/30 -
  268. * The end of mobj_t changed from
  269. * boolean invisible;
  270. * mobj_t* lastenemy;
  271. * mobj_t* above_monster;
  272. * mobj_t* below_monster;
  273. * void* touching_sectorlist;
  274. * to
  275. * mobj_t* lastenemy;
  276. * void* touching_sectorlist;
  277. * fixed_t PrevX, PrevY, PrevZ, padding;
  278. * at prboom 2.4.4. There is code here to preserve the savegame format.
  279. *
  280. * touching_sectorlist is reconstructed anyway, so we now leave off the
  281. * last 2 words of mobj_t, write 5 words of 0 and then write lastenemy
  282. * into the second of these.
  283. */
  284. memcpy (mobj, th, sizeof(*mobj) - 2*sizeof(void*));
  285. save_p += sizeof(*mobj) - 2*sizeof(void*) - 4*sizeof(fixed_t);
  286. memset (save_p, 0, 5*sizeof(void*));
  287. mobj->state = (state_t *)(mobj->state - states);
  288. // killough 2/14/98: convert pointers into indices.
  289. // Fixes many savegame problems, by properly saving
  290. // target and tracer fields. Note: we store NULL if
  291. // the thinker pointed to by these fields is not a
  292. // mobj thinker.
  293. if (mobj->target)
  294. mobj->target = mobj->target->thinker.function ==
  295. P_MobjThinker ?
  296. (mobj_t *) mobj->target->thinker.prev : NULL;
  297. if (mobj->tracer)
  298. mobj->tracer = mobj->tracer->thinker.function ==
  299. P_MobjThinker ?
  300. (mobj_t *) mobj->tracer->thinker.prev : NULL;
  301. // killough 2/14/98: new field: save last known enemy. Prevents
  302. // monsters from going to sleep after killing monsters and not
  303. // seeing player anymore.
  304. if (((mobj_t*)th)->lastenemy && ((mobj_t*)th)->lastenemy->thinker.function == P_MobjThinker) {
  305. memcpy (save_p + sizeof(void*), &(((mobj_t*)th)->lastenemy->thinker.prev), sizeof(void*));
  306. }
  307. // killough 2/14/98: end changes
  308. save_p += 5*sizeof(void*);
  309. if (mobj->player)
  310. mobj->player = (player_t *)((mobj->player-players) + 1);
  311. }
  312. // add a terminating marker
  313. *save_p++ = tc_end;
  314. // killough 9/14/98: save soundtargets
  315. {
  316. int i;
  317. CheckSaveGame(numsectors * sizeof(mobj_t *)); // killough 9/14/98
  318. for (i = 0; i < numsectors; i++)
  319. {
  320. mobj_t *target = sectors[i].soundtarget;
  321. // Fix crash on reload when a soundtarget points to a removed corpse
  322. // (prboom bug #1590350)
  323. if (target && target->thinker.function == P_MobjThinker)
  324. target = (mobj_t *) target->thinker.prev;
  325. else
  326. target = NULL;
  327. memcpy(save_p, &target, sizeof target);
  328. save_p += sizeof target;
  329. }
  330. }
  331. }
  332. /*
  333. * killough 11/98
  334. *
  335. * Same as P_SetTarget() in p_tick.c, except that the target is nullified
  336. * first, so that no old target's reference count is decreased (when loading
  337. * savegames, old targets are indices, not really pointers to targets).
  338. */
  339. static void P_SetNewTarget(mobj_t **mop, mobj_t *targ)
  340. {
  341. *mop = NULL;
  342. P_SetTarget(mop, targ);
  343. }
  344. //
  345. // P_UnArchiveThinkers
  346. //
  347. // 2/14/98 killough: substantially modified to fix savegame bugs
  348. //
  349. // savegame file stores ints in the corresponding * field; this function
  350. // safely casts them back to int.
  351. static int P_GetMobj(mobj_t* mi, size_t s)
  352. {
  353. size_t i = (size_t)mi;
  354. if (i >= s) I_Error("Corrupt savegame");
  355. return i;
  356. }
  357. void P_UnArchiveThinkers (void)
  358. {
  359. thinker_t *th;
  360. mobj_t **mobj_p; // killough 2/14/98: Translation table
  361. size_t size; // killough 2/14/98: size of or index into table
  362. totallive = 0;
  363. // killough 3/26/98: Load boss brain state
  364. memcpy(&brain, save_p, sizeof brain);
  365. save_p += sizeof brain;
  366. // remove all the current thinkers
  367. for (th = thinkercap.next; th != &thinkercap; )
  368. {
  369. thinker_t *next = th->next;
  370. if (th->function == P_MobjThinker)
  371. P_RemoveMobj ((mobj_t *) th);
  372. else
  373. Z_Free (th);
  374. th = next;
  375. }
  376. P_InitThinkers ();
  377. // killough 2/14/98: count number of thinkers by skipping through them
  378. {
  379. byte *sp = save_p; // save pointer and skip header
  380. for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98
  381. { // skip all entries, adding up count
  382. PADSAVEP();
  383. /* cph 2006/07/30 - see comment below for change in layout of mobj_t */
  384. save_p += sizeof(mobj_t)+3*sizeof(void*)-4*sizeof(fixed_t);
  385. }
  386. if (*--save_p != tc_end)
  387. I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p);
  388. // first table entry special: 0 maps to NULL
  389. *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers
  390. save_p = sp; // restore save pointer
  391. }
  392. // read in saved thinkers
  393. for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98
  394. {
  395. mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL);
  396. // killough 2/14/98 -- insert pointers to thinkers into table, in order:
  397. mobj_p[size] = mobj;
  398. PADSAVEP();
  399. /* cph 2006/07/30 -
  400. * The end of mobj_t changed from
  401. * boolean invisible;
  402. * mobj_t* lastenemy;
  403. * mobj_t* above_monster;
  404. * mobj_t* below_monster;
  405. * void* touching_sectorlist;
  406. * to
  407. * mobj_t* lastenemy;
  408. * void* touching_sectorlist;
  409. * fixed_t PrevX, PrevY, PrevZ;
  410. * at prboom 2.4.4. There is code here to preserve the savegame format.
  411. *
  412. * touching_sectorlist is reconstructed anyway, so we now read in all
  413. * but the last 5 words from the savegame (filling all but the last 2
  414. * fields of our current mobj_t. We then pull lastenemy from the 2nd of
  415. * the 5 leftover words, and skip the others.
  416. */
  417. memcpy (mobj, save_p, sizeof(mobj_t)-2*sizeof(void*)-4*sizeof(fixed_t));
  418. save_p += sizeof(mobj_t)-sizeof(void*)-4*sizeof(fixed_t);
  419. memcpy (&(mobj->lastenemy), save_p, sizeof(void*));
  420. save_p += 4*sizeof(void*);
  421. mobj->state = states + (int) mobj->state;
  422. if (mobj->player)
  423. (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj;
  424. P_SetThingPosition (mobj);
  425. mobj->info = &mobjinfo[mobj->type];
  426. // killough 2/28/98:
  427. // Fix for falling down into a wall after savegame loaded:
  428. // mobj->floorz = mobj->subsector->sector->floorheight;
  429. // mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  430. mobj->thinker.function = P_MobjThinker;
  431. P_AddThinker (&mobj->thinker);
  432. if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE)))
  433. totallive++;
  434. }
  435. // killough 2/14/98: adjust target and tracer fields, plus
  436. // lastenemy field, to correctly point to mobj thinkers.
  437. // NULL entries automatically handled by first table entry.
  438. //
  439. // killough 11/98: use P_SetNewTarget() to set fields
  440. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  441. {
  442. P_SetNewTarget(&((mobj_t *) th)->target,
  443. mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]);
  444. P_SetNewTarget(&((mobj_t *) th)->tracer,
  445. mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]);
  446. P_SetNewTarget(&((mobj_t *) th)->lastenemy,
  447. mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]);
  448. }
  449. { // killough 9/14/98: restore soundtargets
  450. int i;
  451. for (i = 0; i < numsectors; i++)
  452. {
  453. mobj_t *target;
  454. memcpy(&target, save_p, sizeof target);
  455. save_p += sizeof target;
  456. // Must verify soundtarget. See P_ArchiveThinkers.
  457. P_SetNewTarget(&sectors[i].soundtarget, mobj_p[P_GetMobj(target,size)]);
  458. }
  459. }
  460. free(mobj_p); // free translation table
  461. // killough 3/26/98: Spawn icon landings:
  462. if (gamemode == commercial)
  463. P_SpawnBrainTargets();
  464. }
  465. //
  466. // P_ArchiveSpecials
  467. //
  468. enum {
  469. tc_ceiling,
  470. tc_door,
  471. tc_floor,
  472. tc_plat,
  473. tc_flash,
  474. tc_strobe,
  475. tc_glow,
  476. tc_elevator, //jff 2/22/98 new elevator type thinker
  477. tc_scroll, // killough 3/7/98: new scroll effect thinker
  478. tc_pusher, // phares 3/22/98: new push/pull effect thinker
  479. tc_flicker, // killough 10/4/98
  480. tc_endspecials
  481. } specials_e;
  482. //
  483. // Things to handle:
  484. //
  485. // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
  486. // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
  487. // T_MoveFloor, (floormove_t: sector_t * swizzle),
  488. // T_LightFlash, (lightflash_t: sector_t * swizzle),
  489. // T_StrobeFlash, (strobe_t: sector_t *),
  490. // T_Glow, (glow_t: sector_t *),
  491. // T_PlatRaise, (plat_t: sector_t *), - active list
  492. // T_MoveElevator, (plat_t: sector_t *), - active list // jff 2/22/98
  493. // T_Scroll // killough 3/7/98
  494. // T_Pusher // phares 3/22/98
  495. // T_FireFlicker // killough 10/4/98
  496. //
  497. void P_ArchiveSpecials (void)
  498. {
  499. thinker_t *th;
  500. size_t size = 0; // killough
  501. // save off the current thinkers (memory size calculation -- killough)
  502. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  503. if (!th->function)
  504. {
  505. platlist_t *pl;
  506. ceilinglist_t *cl; //jff 2/22/98 need this for ceilings too now
  507. for (pl=activeplats; pl; pl=pl->next)
  508. if (pl->plat == (plat_t *) th) // killough 2/14/98
  509. {
  510. size += 4+sizeof(plat_t);
  511. goto end;
  512. }
  513. for (cl=activeceilings; cl; cl=cl->next) // search for activeceiling
  514. if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98
  515. {
  516. size += 4+sizeof(ceiling_t);
  517. goto end;
  518. }
  519. end:;
  520. }
  521. else
  522. size +=
  523. th->function==T_MoveCeiling ? 4+sizeof(ceiling_t) :
  524. th->function==T_VerticalDoor ? 4+sizeof(vldoor_t) :
  525. th->function==T_MoveFloor ? 4+sizeof(floormove_t):
  526. th->function==T_PlatRaise ? 4+sizeof(plat_t) :
  527. th->function==T_LightFlash ? 4+sizeof(lightflash_t):
  528. th->function==T_StrobeFlash ? 4+sizeof(strobe_t) :
  529. th->function==T_Glow ? 4+sizeof(glow_t) :
  530. th->function==T_MoveElevator ? 4+sizeof(elevator_t):
  531. th->function==T_Scroll ? 4+sizeof(scroll_t) :
  532. th->function==T_Pusher ? 4+sizeof(pusher_t) :
  533. th->function==T_FireFlicker? 4+sizeof(fireflicker_t) :
  534. 0;
  535. CheckSaveGame(size + 1); // killough; cph: +1 for the tc_endspecials
  536. // save off the current thinkers
  537. for (th=thinkercap.next; th!=&thinkercap; th=th->next)
  538. {
  539. if (!th->function)
  540. {
  541. platlist_t *pl;
  542. ceilinglist_t *cl; //jff 2/22/98 add iter variable for ceilings
  543. // killough 2/8/98: fix plat original height bug.
  544. // Since acv==NULL, this could be a plat in stasis.
  545. // so check the active plats list, and save this
  546. // plat (jff: or ceiling) even if it is in stasis.
  547. for (pl=activeplats; pl; pl=pl->next)
  548. if (pl->plat == (plat_t *) th) // killough 2/14/98
  549. goto plat;
  550. for (cl=activeceilings; cl; cl=cl->next)
  551. if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98
  552. goto ceiling;
  553. continue;
  554. }
  555. if (th->function == T_MoveCeiling)
  556. {
  557. ceiling_t *ceiling;
  558. ceiling: // killough 2/14/98
  559. *save_p++ = tc_ceiling;
  560. PADSAVEP();
  561. ceiling = (ceiling_t *)save_p;
  562. memcpy (ceiling, th, sizeof(*ceiling));
  563. save_p += sizeof(*ceiling);
  564. ceiling->sector = (sector_t *)(ceiling->sector - sectors);
  565. continue;
  566. }
  567. if (th->function == T_VerticalDoor)
  568. {
  569. vldoor_t *door;
  570. *save_p++ = tc_door;
  571. PADSAVEP();
  572. door = (vldoor_t *) save_p;
  573. memcpy (door, th, sizeof *door);
  574. save_p += sizeof(*door);
  575. door->sector = (sector_t *)(door->sector - sectors);
  576. //jff 1/31/98 archive line remembered by door as well
  577. door->line = (line_t *) (door->line ? door->line-lines : -1);
  578. continue;
  579. }
  580. if (th->function == T_MoveFloor)
  581. {
  582. floormove_t *floor;
  583. *save_p++ = tc_floor;
  584. PADSAVEP();
  585. floor = (floormove_t *)save_p;
  586. memcpy (floor, th, sizeof(*floor));
  587. save_p += sizeof(*floor);
  588. floor->sector = (sector_t *)(floor->sector - sectors);
  589. continue;
  590. }
  591. if (th->function == T_PlatRaise)
  592. {
  593. plat_t *plat;
  594. plat: // killough 2/14/98: added fix for original plat height above
  595. *save_p++ = tc_plat;
  596. PADSAVEP();
  597. plat = (plat_t *)save_p;
  598. memcpy (plat, th, sizeof(*plat));
  599. save_p += sizeof(*plat);
  600. plat->sector = (sector_t *)(plat->sector - sectors);
  601. continue;
  602. }
  603. if (th->function == T_LightFlash)
  604. {
  605. lightflash_t *flash;
  606. *save_p++ = tc_flash;
  607. PADSAVEP();
  608. flash = (lightflash_t *)save_p;
  609. memcpy (flash, th, sizeof(*flash));
  610. save_p += sizeof(*flash);
  611. flash->sector = (sector_t *)(flash->sector - sectors);
  612. continue;
  613. }
  614. if (th->function == T_StrobeFlash)
  615. {
  616. strobe_t *strobe;
  617. *save_p++ = tc_strobe;
  618. PADSAVEP();
  619. strobe = (strobe_t *)save_p;
  620. memcpy (strobe, th, sizeof(*strobe));
  621. save_p += sizeof(*strobe);
  622. strobe->sector = (sector_t *)(strobe->sector - sectors);
  623. continue;
  624. }
  625. if (th->function == T_Glow)
  626. {
  627. glow_t *glow;
  628. *save_p++ = tc_glow;
  629. PADSAVEP();
  630. glow = (glow_t *)save_p;
  631. memcpy (glow, th, sizeof(*glow));
  632. save_p += sizeof(*glow);
  633. glow->sector = (sector_t *)(glow->sector - sectors);
  634. continue;
  635. }
  636. // killough 10/4/98: save flickers
  637. if (th->function == T_FireFlicker)
  638. {
  639. fireflicker_t *flicker;
  640. *save_p++ = tc_flicker;
  641. PADSAVEP();
  642. flicker = (fireflicker_t *)save_p;
  643. memcpy (flicker, th, sizeof(*flicker));
  644. save_p += sizeof(*flicker);
  645. flicker->sector = (sector_t *)(flicker->sector - sectors);
  646. continue;
  647. }
  648. //jff 2/22/98 new case for elevators
  649. if (th->function == T_MoveElevator)
  650. {
  651. elevator_t *elevator; //jff 2/22/98
  652. *save_p++ = tc_elevator;
  653. PADSAVEP();
  654. elevator = (elevator_t *)save_p;
  655. memcpy (elevator, th, sizeof(*elevator));
  656. save_p += sizeof(*elevator);
  657. elevator->sector = (sector_t *)(elevator->sector - sectors);
  658. continue;
  659. }
  660. // killough 3/7/98: Scroll effect thinkers
  661. if (th->function == T_Scroll)
  662. {
  663. *save_p++ = tc_scroll;
  664. memcpy (save_p, th, sizeof(scroll_t));
  665. save_p += sizeof(scroll_t);
  666. continue;
  667. }
  668. // phares 3/22/98: Push/Pull effect thinkers
  669. if (th->function == T_Pusher)
  670. {
  671. *save_p++ = tc_pusher;
  672. memcpy (save_p, th, sizeof(pusher_t));
  673. save_p += sizeof(pusher_t);
  674. continue;
  675. }
  676. }
  677. // add a terminating marker
  678. *save_p++ = tc_endspecials;
  679. }
  680. //
  681. // P_UnArchiveSpecials
  682. //
  683. void P_UnArchiveSpecials (void)
  684. {
  685. byte tclass;
  686. // read in saved thinkers
  687. while ((tclass = *save_p++) != tc_endspecials) // killough 2/14/98
  688. switch (tclass)
  689. {
  690. case tc_ceiling:
  691. PADSAVEP();
  692. {
  693. ceiling_t *ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
  694. memcpy (ceiling, save_p, sizeof(*ceiling));
  695. save_p += sizeof(*ceiling);
  696. ceiling->sector = &sectors[(int)ceiling->sector];
  697. ceiling->sector->ceilingdata = ceiling; //jff 2/22/98
  698. if (ceiling->thinker.function)
  699. ceiling->thinker.function = T_MoveCeiling;
  700. P_AddThinker (&ceiling->thinker);
  701. P_AddActiveCeiling(ceiling);
  702. break;
  703. }
  704. case tc_door:
  705. PADSAVEP();
  706. {
  707. vldoor_t *door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
  708. memcpy (door, save_p, sizeof(*door));
  709. save_p += sizeof(*door);
  710. door->sector = &sectors[(int)door->sector];
  711. //jff 1/31/98 unarchive line remembered by door as well
  712. door->line = (int)door->line!=-1? &lines[(int)door->line] : NULL;
  713. door->sector->ceilingdata = door; //jff 2/22/98
  714. door->thinker.function = T_VerticalDoor;
  715. P_AddThinker (&door->thinker);
  716. break;
  717. }
  718. case tc_floor:
  719. PADSAVEP();
  720. {
  721. floormove_t *floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  722. memcpy (floor, save_p, sizeof(*floor));
  723. save_p += sizeof(*floor);
  724. floor->sector = &sectors[(int)floor->sector];
  725. floor->sector->floordata = floor; //jff 2/22/98
  726. floor->thinker.function = T_MoveFloor;
  727. P_AddThinker (&floor->thinker);
  728. break;
  729. }
  730. case tc_plat:
  731. PADSAVEP();
  732. {
  733. plat_t *plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  734. memcpy (plat, save_p, sizeof(*plat));
  735. save_p += sizeof(*plat);
  736. plat->sector = &sectors[(int)plat->sector];
  737. plat->sector->floordata = plat; //jff 2/22/98
  738. if (plat->thinker.function)
  739. plat->thinker.function = T_PlatRaise;
  740. P_AddThinker (&plat->thinker);
  741. P_AddActivePlat(plat);
  742. break;
  743. }
  744. case tc_flash:
  745. PADSAVEP();
  746. {
  747. lightflash_t *flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  748. memcpy (flash, save_p, sizeof(*flash));
  749. save_p += sizeof(*flash);
  750. flash->sector = &sectors[(int)flash->sector];
  751. flash->thinker.function = T_LightFlash;
  752. P_AddThinker (&flash->thinker);
  753. break;
  754. }
  755. case tc_strobe:
  756. PADSAVEP();
  757. {
  758. strobe_t *strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  759. memcpy (strobe, save_p, sizeof(*strobe));
  760. save_p += sizeof(*strobe);
  761. strobe->sector = &sectors[(int)strobe->sector];
  762. strobe->thinker.function = T_StrobeFlash;
  763. P_AddThinker (&strobe->thinker);
  764. break;
  765. }
  766. case tc_glow:
  767. PADSAVEP();
  768. {
  769. glow_t *glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  770. memcpy (glow, save_p, sizeof(*glow));
  771. save_p += sizeof(*glow);
  772. glow->sector = &sectors[(int)glow->sector];
  773. glow->thinker.function = T_Glow;
  774. P_AddThinker (&glow->thinker);
  775. break;
  776. }
  777. case tc_flicker: // killough 10/4/98
  778. PADSAVEP();
  779. {
  780. fireflicker_t *flicker = Z_Malloc (sizeof(*flicker), PU_LEVEL, NULL);
  781. memcpy (flicker, save_p, sizeof(*flicker));
  782. save_p += sizeof(*flicker);
  783. flicker->sector = &sectors[(int)flicker->sector];
  784. flicker->thinker.function = T_FireFlicker;
  785. P_AddThinker (&flicker->thinker);
  786. break;
  787. }
  788. //jff 2/22/98 new case for elevators
  789. case tc_elevator:
  790. PADSAVEP();
  791. {
  792. elevator_t *elevator = Z_Malloc (sizeof(*elevator), PU_LEVEL, NULL);
  793. memcpy (elevator, save_p, sizeof(*elevator));
  794. save_p += sizeof(*elevator);
  795. elevator->sector = &sectors[(int)elevator->sector];
  796. elevator->sector->floordata = elevator; //jff 2/22/98
  797. elevator->sector->ceilingdata = elevator; //jff 2/22/98
  798. elevator->thinker.function = T_MoveElevator;
  799. P_AddThinker (&elevator->thinker);
  800. break;
  801. }
  802. case tc_scroll: // killough 3/7/98: scroll effect thinkers
  803. {
  804. scroll_t *scroll = Z_Malloc (sizeof(scroll_t), PU_LEVEL, NULL);
  805. memcpy (scroll, save_p, sizeof(scroll_t));
  806. save_p += sizeof(scroll_t);
  807. scroll->thinker.function = T_Scroll;
  808. P_AddThinker(&scroll->thinker);
  809. break;
  810. }
  811. case tc_pusher: // phares 3/22/98: new Push/Pull effect thinkers
  812. {
  813. pusher_t *pusher = Z_Malloc (sizeof(pusher_t), PU_LEVEL, NULL);
  814. memcpy (pusher, save_p, sizeof(pusher_t));
  815. save_p += sizeof(pusher_t);
  816. pusher->thinker.function = T_Pusher;
  817. pusher->source = P_GetPushThing(pusher->affectee);
  818. P_AddThinker(&pusher->thinker);
  819. break;
  820. }
  821. default:
  822. I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass);
  823. }
  824. }
  825. // killough 2/16/98: save/restore random number generator state information
  826. void P_ArchiveRNG(void)
  827. {
  828. CheckSaveGame(sizeof rng);
  829. memcpy(save_p, &rng, sizeof rng);
  830. save_p += sizeof rng;
  831. }
  832. void P_UnArchiveRNG(void)
  833. {
  834. memcpy(&rng, save_p, sizeof rng);
  835. save_p += sizeof rng;
  836. }
  837. // killough 2/22/98: Save/restore automap state
  838. // killough 2/22/98: Save/restore automap state
  839. void P_ArchiveMap(void)
  840. {
  841. int zero = 0, one = 1;
  842. CheckSaveGame(2 * sizeof zero + sizeof markpointnum +
  843. markpointnum * sizeof *markpoints +
  844. sizeof automapmode + sizeof one);
  845. memcpy(save_p, &automapmode, sizeof automapmode);
  846. save_p += sizeof automapmode;
  847. memcpy(save_p, &one, sizeof one); // CPhipps - used to be viewactive, now
  848. save_p += sizeof one; // that's worked out locally by D_Display
  849. memcpy(save_p, &zero, sizeof zero); // CPhipps - used to be followplayer
  850. save_p += sizeof zero; // that is now part of automapmode
  851. memcpy(save_p, &zero, sizeof zero); // CPhipps - used to be automap_grid, ditto
  852. save_p += sizeof zero;
  853. memcpy(save_p, &markpointnum, sizeof markpointnum);
  854. save_p += sizeof markpointnum;
  855. if (markpointnum)
  856. {
  857. memcpy(save_p, markpoints, sizeof *markpoints * markpointnum);
  858. save_p += markpointnum * sizeof *markpoints;
  859. }
  860. }
  861. void P_UnArchiveMap(void)
  862. {
  863. int unused;
  864. memcpy(&automapmode, save_p, sizeof automapmode);
  865. save_p += sizeof automapmode;
  866. memcpy(&unused, save_p, sizeof unused);
  867. save_p += sizeof unused;
  868. memcpy(&unused, save_p, sizeof unused);
  869. save_p += sizeof unused;
  870. memcpy(&unused, save_p, sizeof unused);
  871. save_p += sizeof unused;
  872. if (automapmode & am_active)
  873. AM_Start();
  874. memcpy(&markpointnum, save_p, sizeof markpointnum);
  875. save_p += sizeof markpointnum;
  876. if (markpointnum)
  877. {
  878. while (markpointnum >= markpointnum_max)
  879. markpoints = realloc(markpoints, sizeof *markpoints *
  880. (markpointnum_max = markpointnum_max ? markpointnum_max*2 : 16));
  881. memcpy(markpoints, save_p, markpointnum * sizeof *markpoints);
  882. save_p += markpointnum * sizeof *markpoints;
  883. }
  884. }