p_saveg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. // Archiving: SaveGame I/O.
  21. //
  22. //-----------------------------------------------------------------------------
  23. static const char
  24. rcsid[] = "$Id: p_tick.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  25. #include "i_system.h"
  26. #include "z_zone.h"
  27. #include "p_local.h"
  28. // State.
  29. #include "doomstat.h"
  30. #include "r_state.h"
  31. byte* save_p;
  32. // Pads save_p to a 4-byte boundary
  33. // so that the load/save works on SGI&Gecko.
  34. #define PADSAVEP() save_p += (4 - ((int) save_p & 3)) & 3
  35. //
  36. // P_ArchivePlayers
  37. //
  38. void P_ArchivePlayers (void)
  39. {
  40. int i;
  41. int j;
  42. player_t* dest;
  43. for (i=0 ; i<MAXPLAYERS ; i++)
  44. {
  45. if (!playeringame[i])
  46. continue;
  47. PADSAVEP();
  48. dest = (player_t *)save_p;
  49. memcpy (dest,&players[i],sizeof(player_t));
  50. save_p += sizeof(player_t);
  51. for (j=0 ; j<NUMPSPRITES ; j++)
  52. {
  53. if (dest->psprites[j].state)
  54. {
  55. dest->psprites[j].state
  56. = (state_t *)(dest->psprites[j].state-states);
  57. }
  58. }
  59. }
  60. }
  61. //
  62. // P_UnArchivePlayers
  63. //
  64. void P_UnArchivePlayers (void)
  65. {
  66. int i;
  67. int j;
  68. for (i=0 ; i<MAXPLAYERS ; i++)
  69. {
  70. if (!playeringame[i])
  71. continue;
  72. PADSAVEP();
  73. memcpy (&players[i],save_p, sizeof(player_t));
  74. save_p += sizeof(player_t);
  75. // will be set when unarc thinker
  76. players[i].mo = NULL;
  77. players[i].message = NULL;
  78. players[i].attacker = NULL;
  79. for (j=0 ; j<NUMPSPRITES ; j++)
  80. {
  81. if (players[i]. psprites[j].state)
  82. {
  83. players[i]. psprites[j].state
  84. = &states[ (int)players[i].psprites[j].state ];
  85. }
  86. }
  87. }
  88. }
  89. //
  90. // P_ArchiveWorld
  91. //
  92. void P_ArchiveWorld (void)
  93. {
  94. int i;
  95. int j;
  96. sector_t* sec;
  97. line_t* li;
  98. side_t* si;
  99. short* put;
  100. put = (short *)save_p;
  101. // do sectors
  102. for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  103. {
  104. *put++ = sec->floorheight >> FRACBITS;
  105. *put++ = sec->ceilingheight >> FRACBITS;
  106. *put++ = sec->floorpic;
  107. *put++ = sec->ceilingpic;
  108. *put++ = sec->lightlevel;
  109. *put++ = sec->special; // needed?
  110. *put++ = sec->tag; // needed?
  111. }
  112. // do lines
  113. for (i=0, li = lines ; i<numlines ; i++,li++)
  114. {
  115. *put++ = li->flags;
  116. *put++ = li->special;
  117. *put++ = li->tag;
  118. for (j=0 ; j<2 ; j++)
  119. {
  120. if (li->sidenum[j] == -1)
  121. continue;
  122. si = &sides[li->sidenum[j]];
  123. *put++ = si->textureoffset >> FRACBITS;
  124. *put++ = si->rowoffset >> FRACBITS;
  125. *put++ = si->toptexture;
  126. *put++ = si->bottomtexture;
  127. *put++ = si->midtexture;
  128. }
  129. }
  130. save_p = (byte *)put;
  131. }
  132. //
  133. // P_UnArchiveWorld
  134. //
  135. void P_UnArchiveWorld (void)
  136. {
  137. int i;
  138. int j;
  139. sector_t* sec;
  140. line_t* li;
  141. side_t* si;
  142. short* get;
  143. get = (short *)save_p;
  144. // do sectors
  145. for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  146. {
  147. sec->floorheight = *get++ << FRACBITS;
  148. sec->ceilingheight = *get++ << FRACBITS;
  149. sec->floorpic = *get++;
  150. sec->ceilingpic = *get++;
  151. sec->lightlevel = *get++;
  152. sec->special = *get++; // needed?
  153. sec->tag = *get++; // needed?
  154. sec->specialdata = 0;
  155. sec->soundtarget = 0;
  156. }
  157. // do lines
  158. for (i=0, li = lines ; i<numlines ; i++,li++)
  159. {
  160. li->flags = *get++;
  161. li->special = *get++;
  162. li->tag = *get++;
  163. for (j=0 ; j<2 ; j++)
  164. {
  165. if (li->sidenum[j] == -1)
  166. continue;
  167. si = &sides[li->sidenum[j]];
  168. si->textureoffset = *get++ << FRACBITS;
  169. si->rowoffset = *get++ << FRACBITS;
  170. si->toptexture = *get++;
  171. si->bottomtexture = *get++;
  172. si->midtexture = *get++;
  173. }
  174. }
  175. save_p = (byte *)get;
  176. }
  177. //
  178. // Thinkers
  179. //
  180. typedef enum
  181. {
  182. tc_end,
  183. tc_mobj
  184. } thinkerclass_t;
  185. //
  186. // P_ArchiveThinkers
  187. //
  188. void P_ArchiveThinkers (void)
  189. {
  190. thinker_t* th;
  191. mobj_t* mobj;
  192. // save off the current thinkers
  193. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  194. {
  195. if (th->function.acp1 == (actionf_p1)P_MobjThinker)
  196. {
  197. *save_p++ = tc_mobj;
  198. PADSAVEP();
  199. mobj = (mobj_t *)save_p;
  200. memcpy (mobj, th, sizeof(*mobj));
  201. save_p += sizeof(*mobj);
  202. mobj->state = (state_t *)(mobj->state - states);
  203. if (mobj->player)
  204. mobj->player = (player_t *)((mobj->player-players) + 1);
  205. continue;
  206. }
  207. // I_Error ("P_ArchiveThinkers: Unknown thinker function");
  208. }
  209. // add a terminating marker
  210. *save_p++ = tc_end;
  211. }
  212. //
  213. // P_UnArchiveThinkers
  214. //
  215. void P_UnArchiveThinkers (void)
  216. {
  217. byte tclass;
  218. thinker_t* currentthinker;
  219. thinker_t* next;
  220. mobj_t* mobj;
  221. // remove all the current thinkers
  222. currentthinker = thinkercap.next;
  223. while (currentthinker != &thinkercap)
  224. {
  225. next = currentthinker->next;
  226. if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
  227. P_RemoveMobj ((mobj_t *)currentthinker);
  228. else
  229. Z_Free (currentthinker);
  230. currentthinker = next;
  231. }
  232. P_InitThinkers ();
  233. // read in saved thinkers
  234. while (1)
  235. {
  236. tclass = *save_p++;
  237. switch (tclass)
  238. {
  239. case tc_end:
  240. return; // end of list
  241. case tc_mobj:
  242. PADSAVEP();
  243. mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
  244. memcpy (mobj, save_p, sizeof(*mobj));
  245. save_p += sizeof(*mobj);
  246. mobj->state = &states[(int)mobj->state];
  247. mobj->target = NULL;
  248. if (mobj->player)
  249. {
  250. mobj->player = &players[(int)mobj->player-1];
  251. mobj->player->mo = mobj;
  252. }
  253. P_SetThingPosition (mobj);
  254. mobj->info = &mobjinfo[mobj->type];
  255. mobj->floorz = mobj->subsector->sector->floorheight;
  256. mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  257. mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
  258. P_AddThinker (&mobj->thinker);
  259. break;
  260. default:
  261. I_Error ("Unknown tclass %i in savegame",tclass);
  262. }
  263. }
  264. }
  265. //
  266. // P_ArchiveSpecials
  267. //
  268. enum
  269. {
  270. tc_ceiling,
  271. tc_door,
  272. tc_floor,
  273. tc_plat,
  274. tc_flash,
  275. tc_strobe,
  276. tc_glow,
  277. tc_endspecials
  278. } specials_e;
  279. //
  280. // Things to handle:
  281. //
  282. // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
  283. // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
  284. // T_MoveFloor, (floormove_t: sector_t * swizzle),
  285. // T_LightFlash, (lightflash_t: sector_t * swizzle),
  286. // T_StrobeFlash, (strobe_t: sector_t *),
  287. // T_Glow, (glow_t: sector_t *),
  288. // T_PlatRaise, (plat_t: sector_t *), - active list
  289. //
  290. void P_ArchiveSpecials (void)
  291. {
  292. thinker_t* th;
  293. ceiling_t* ceiling;
  294. vldoor_t* door;
  295. floormove_t* floor;
  296. plat_t* plat;
  297. lightflash_t* flash;
  298. strobe_t* strobe;
  299. glow_t* glow;
  300. int i;
  301. // save off the current thinkers
  302. for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  303. {
  304. if (th->function.acv == (actionf_v)NULL)
  305. {
  306. for (i = 0; i < MAXCEILINGS;i++)
  307. if (activeceilings[i] == (ceiling_t *)th)
  308. break;
  309. if (i<MAXCEILINGS)
  310. {
  311. *save_p++ = tc_ceiling;
  312. PADSAVEP();
  313. ceiling = (ceiling_t *)save_p;
  314. memcpy (ceiling, th, sizeof(*ceiling));
  315. save_p += sizeof(*ceiling);
  316. ceiling->sector = (sector_t *)(ceiling->sector - sectors);
  317. }
  318. continue;
  319. }
  320. if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
  321. {
  322. *save_p++ = tc_ceiling;
  323. PADSAVEP();
  324. ceiling = (ceiling_t *)save_p;
  325. memcpy (ceiling, th, sizeof(*ceiling));
  326. save_p += sizeof(*ceiling);
  327. ceiling->sector = (sector_t *)(ceiling->sector - sectors);
  328. continue;
  329. }
  330. if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
  331. {
  332. *save_p++ = tc_door;
  333. PADSAVEP();
  334. door = (vldoor_t *)save_p;
  335. memcpy (door, th, sizeof(*door));
  336. save_p += sizeof(*door);
  337. door->sector = (sector_t *)(door->sector - sectors);
  338. continue;
  339. }
  340. if (th->function.acp1 == (actionf_p1)T_MoveFloor)
  341. {
  342. *save_p++ = tc_floor;
  343. PADSAVEP();
  344. floor = (floormove_t *)save_p;
  345. memcpy (floor, th, sizeof(*floor));
  346. save_p += sizeof(*floor);
  347. floor->sector = (sector_t *)(floor->sector - sectors);
  348. continue;
  349. }
  350. if (th->function.acp1 == (actionf_p1)T_PlatRaise)
  351. {
  352. *save_p++ = tc_plat;
  353. PADSAVEP();
  354. plat = (plat_t *)save_p;
  355. memcpy (plat, th, sizeof(*plat));
  356. save_p += sizeof(*plat);
  357. plat->sector = (sector_t *)(plat->sector - sectors);
  358. continue;
  359. }
  360. if (th->function.acp1 == (actionf_p1)T_LightFlash)
  361. {
  362. *save_p++ = tc_flash;
  363. PADSAVEP();
  364. flash = (lightflash_t *)save_p;
  365. memcpy (flash, th, sizeof(*flash));
  366. save_p += sizeof(*flash);
  367. flash->sector = (sector_t *)(flash->sector - sectors);
  368. continue;
  369. }
  370. if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
  371. {
  372. *save_p++ = tc_strobe;
  373. PADSAVEP();
  374. strobe = (strobe_t *)save_p;
  375. memcpy (strobe, th, sizeof(*strobe));
  376. save_p += sizeof(*strobe);
  377. strobe->sector = (sector_t *)(strobe->sector - sectors);
  378. continue;
  379. }
  380. if (th->function.acp1 == (actionf_p1)T_Glow)
  381. {
  382. *save_p++ = tc_glow;
  383. PADSAVEP();
  384. glow = (glow_t *)save_p;
  385. memcpy (glow, th, sizeof(*glow));
  386. save_p += sizeof(*glow);
  387. glow->sector = (sector_t *)(glow->sector - sectors);
  388. continue;
  389. }
  390. }
  391. // add a terminating marker
  392. *save_p++ = tc_endspecials;
  393. }
  394. //
  395. // P_UnArchiveSpecials
  396. //
  397. void P_UnArchiveSpecials (void)
  398. {
  399. byte tclass;
  400. ceiling_t* ceiling;
  401. vldoor_t* door;
  402. floormove_t* floor;
  403. plat_t* plat;
  404. lightflash_t* flash;
  405. strobe_t* strobe;
  406. glow_t* glow;
  407. // read in saved thinkers
  408. while (1)
  409. {
  410. tclass = *save_p++;
  411. switch (tclass)
  412. {
  413. case tc_endspecials:
  414. return; // end of list
  415. case tc_ceiling:
  416. PADSAVEP();
  417. ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
  418. memcpy (ceiling, save_p, sizeof(*ceiling));
  419. save_p += sizeof(*ceiling);
  420. ceiling->sector = &sectors[(int)ceiling->sector];
  421. ceiling->sector->specialdata = ceiling;
  422. if (ceiling->thinker.function.acp1)
  423. ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
  424. P_AddThinker (&ceiling->thinker);
  425. P_AddActiveCeiling(ceiling);
  426. break;
  427. case tc_door:
  428. PADSAVEP();
  429. door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
  430. memcpy (door, save_p, sizeof(*door));
  431. save_p += sizeof(*door);
  432. door->sector = &sectors[(int)door->sector];
  433. door->sector->specialdata = door;
  434. door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  435. P_AddThinker (&door->thinker);
  436. break;
  437. case tc_floor:
  438. PADSAVEP();
  439. floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  440. memcpy (floor, save_p, sizeof(*floor));
  441. save_p += sizeof(*floor);
  442. floor->sector = &sectors[(int)floor->sector];
  443. floor->sector->specialdata = floor;
  444. floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
  445. P_AddThinker (&floor->thinker);
  446. break;
  447. case tc_plat:
  448. PADSAVEP();
  449. plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  450. memcpy (plat, save_p, sizeof(*plat));
  451. save_p += sizeof(*plat);
  452. plat->sector = &sectors[(int)plat->sector];
  453. plat->sector->specialdata = plat;
  454. if (plat->thinker.function.acp1)
  455. plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
  456. P_AddThinker (&plat->thinker);
  457. P_AddActivePlat(plat);
  458. break;
  459. case tc_flash:
  460. PADSAVEP();
  461. flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  462. memcpy (flash, save_p, sizeof(*flash));
  463. save_p += sizeof(*flash);
  464. flash->sector = &sectors[(int)flash->sector];
  465. flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
  466. P_AddThinker (&flash->thinker);
  467. break;
  468. case tc_strobe:
  469. PADSAVEP();
  470. strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  471. memcpy (strobe, save_p, sizeof(*strobe));
  472. save_p += sizeof(*strobe);
  473. strobe->sector = &sectors[(int)strobe->sector];
  474. strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
  475. P_AddThinker (&strobe->thinker);
  476. break;
  477. case tc_glow:
  478. PADSAVEP();
  479. glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  480. memcpy (glow, save_p, sizeof(*glow));
  481. save_p += sizeof(*glow);
  482. glow->sector = &sectors[(int)glow->sector];
  483. glow->thinker.function.acp1 = (actionf_p1)T_Glow;
  484. P_AddThinker (&glow->thinker);
  485. break;
  486. default:
  487. I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
  488. "in savegame",tclass);
  489. }
  490. }
  491. }