p_saveg.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:13k
源码类别:

射击游戏

开发平台:

Visual C++

  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.     
  102.     // do sectors
  103.     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  104.     {
  105. *put++ = sec->floorheight >> FRACBITS;
  106. *put++ = sec->ceilingheight >> FRACBITS;
  107. *put++ = sec->floorpic;
  108. *put++ = sec->ceilingpic;
  109. *put++ = sec->lightlevel;
  110. *put++ = sec->special; // needed?
  111. *put++ = sec->tag; // needed?
  112.     }
  113.     
  114.     // do lines
  115.     for (i=0, li = lines ; i<numlines ; i++,li++)
  116.     {
  117. *put++ = li->flags;
  118. *put++ = li->special;
  119. *put++ = li->tag;
  120. for (j=0 ; j<2 ; j++)
  121. {
  122.     if (li->sidenum[j] == -1)
  123. continue;
  124.     
  125.     si = &sides[li->sidenum[j]];
  126.     *put++ = si->textureoffset >> FRACBITS;
  127.     *put++ = si->rowoffset >> FRACBITS;
  128.     *put++ = si->toptexture;
  129.     *put++ = si->bottomtexture;
  130.     *put++ = si->midtexture;
  131. }
  132.     }
  133.     save_p = (byte *)put;
  134. }
  135. //
  136. // P_UnArchiveWorld
  137. //
  138. void P_UnArchiveWorld (void)
  139. {
  140.     int i;
  141.     int j;
  142.     sector_t* sec;
  143.     line_t* li;
  144.     side_t* si;
  145.     short* get;
  146.     get = (short *)save_p;
  147.     
  148.     // do sectors
  149.     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
  150.     {
  151. sec->floorheight = *get++ << FRACBITS;
  152. sec->ceilingheight = *get++ << FRACBITS;
  153. sec->floorpic = *get++;
  154. sec->ceilingpic = *get++;
  155. sec->lightlevel = *get++;
  156. sec->special = *get++; // needed?
  157. sec->tag = *get++; // needed?
  158. sec->specialdata = 0;
  159. sec->soundtarget = 0;
  160.     }
  161.     
  162.     // do lines
  163.     for (i=0, li = lines ; i<numlines ; i++,li++)
  164.     {
  165. li->flags = *get++;
  166. li->special = *get++;
  167. li->tag = *get++;
  168. for (j=0 ; j<2 ; j++)
  169. {
  170.     if (li->sidenum[j] == -1)
  171. continue;
  172.     si = &sides[li->sidenum[j]];
  173.     si->textureoffset = *get++ << FRACBITS;
  174.     si->rowoffset = *get++ << FRACBITS;
  175.     si->toptexture = *get++;
  176.     si->bottomtexture = *get++;
  177.     si->midtexture = *get++;
  178. }
  179.     }
  180.     save_p = (byte *)get;
  181. }
  182. //
  183. // Thinkers
  184. //
  185. typedef enum
  186. {
  187.     tc_end,
  188.     tc_mobj
  189. } thinkerclass_t;
  190. //
  191. // P_ArchiveThinkers
  192. //
  193. void P_ArchiveThinkers (void)
  194. {
  195.     thinker_t* th;
  196.     mobj_t* mobj;
  197.     // save off the current thinkers
  198.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  199.     {
  200. if (th->function.acp1 == (actionf_p1)P_MobjThinker)
  201. {
  202.     *save_p++ = tc_mobj;
  203.     PADSAVEP();
  204.     mobj = (mobj_t *)save_p;
  205.     memcpy (mobj, th, sizeof(*mobj));
  206.     save_p += sizeof(*mobj);
  207.     mobj->state = (state_t *)(mobj->state - states);
  208.     
  209.     if (mobj->player)
  210. mobj->player = (player_t *)((mobj->player-players) + 1);
  211.     continue;
  212. }
  213. // I_Error ("P_ArchiveThinkers: Unknown thinker function");
  214.     }
  215.     // add a terminating marker
  216.     *save_p++ = tc_end;
  217. }
  218. //
  219. // P_UnArchiveThinkers
  220. //
  221. void P_UnArchiveThinkers (void)
  222. {
  223.     byte tclass;
  224.     thinker_t* currentthinker;
  225.     thinker_t* next;
  226.     mobj_t* mobj;
  227.     
  228.     // remove all the current thinkers
  229.     currentthinker = thinkercap.next;
  230.     while (currentthinker != &thinkercap)
  231.     {
  232. next = currentthinker->next;
  233. if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
  234.     P_RemoveMobj ((mobj_t *)currentthinker);
  235. else
  236.     Z_Free (currentthinker);
  237. currentthinker = next;
  238.     }
  239.     P_InitThinkers ();
  240.     // read in saved thinkers
  241.     while (1)
  242.     {
  243. tclass = *save_p++;
  244. switch (tclass)
  245. {
  246.   case tc_end:
  247.     return;  // end of list
  248.   case tc_mobj:
  249.     PADSAVEP();
  250.     mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
  251.     memcpy (mobj, save_p, sizeof(*mobj));
  252.     save_p += sizeof(*mobj);
  253.     mobj->state = &states[(int)mobj->state];
  254.     mobj->target = NULL;
  255.     if (mobj->player)
  256.     {
  257. mobj->player = &players[(int)mobj->player-1];
  258. mobj->player->mo = mobj;
  259.     }
  260.     P_SetThingPosition (mobj);
  261.     mobj->info = &mobjinfo[mobj->type];
  262.     mobj->floorz = mobj->subsector->sector->floorheight;
  263.     mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  264.     mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
  265.     P_AddThinker (&mobj->thinker);
  266.     break;
  267.   default:
  268.     I_Error ("Unknown tclass %i in savegame",tclass);
  269. }
  270.     }
  271. }
  272. //
  273. // P_ArchiveSpecials
  274. //
  275. enum
  276. {
  277.     tc_ceiling,
  278.     tc_door,
  279.     tc_floor,
  280.     tc_plat,
  281.     tc_flash,
  282.     tc_strobe,
  283.     tc_glow,
  284.     tc_endspecials
  285. } specials_e;
  286. //
  287. // Things to handle:
  288. //
  289. // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
  290. // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
  291. // T_MoveFloor, (floormove_t: sector_t * swizzle),
  292. // T_LightFlash, (lightflash_t: sector_t * swizzle),
  293. // T_StrobeFlash, (strobe_t: sector_t *),
  294. // T_Glow, (glow_t: sector_t *),
  295. // T_PlatRaise, (plat_t: sector_t *), - active list
  296. //
  297. void P_ArchiveSpecials (void)
  298. {
  299.     thinker_t* th;
  300.     ceiling_t* ceiling;
  301.     vldoor_t* door;
  302.     floormove_t* floor;
  303.     plat_t* plat;
  304.     lightflash_t* flash;
  305.     strobe_t* strobe;
  306.     glow_t* glow;
  307.     int i;
  308.     // save off the current thinkers
  309.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  310.     {
  311. if (th->function.acv == (actionf_v)NULL)
  312. {
  313.     for (i = 0; i < MAXCEILINGS;i++)
  314. if (activeceilings[i] == (ceiling_t *)th)
  315.     break;
  316.     
  317.     if (i<MAXCEILINGS)
  318.     {
  319. *save_p++ = tc_ceiling;
  320. PADSAVEP();
  321. ceiling = (ceiling_t *)save_p;
  322. memcpy (ceiling, th, sizeof(*ceiling));
  323. save_p += sizeof(*ceiling);
  324. ceiling->sector = (sector_t *)(ceiling->sector - sectors);
  325.     }
  326.     continue;
  327. }
  328. if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
  329. {
  330.     *save_p++ = tc_ceiling;
  331.     PADSAVEP();
  332.     ceiling = (ceiling_t *)save_p;
  333.     memcpy (ceiling, th, sizeof(*ceiling));
  334.     save_p += sizeof(*ceiling);
  335.     ceiling->sector = (sector_t *)(ceiling->sector - sectors);
  336.     continue;
  337. }
  338. if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
  339. {
  340.     *save_p++ = tc_door;
  341.     PADSAVEP();
  342.     door = (vldoor_t *)save_p;
  343.     memcpy (door, th, sizeof(*door));
  344.     save_p += sizeof(*door);
  345.     door->sector = (sector_t *)(door->sector - sectors);
  346.     continue;
  347. }
  348. if (th->function.acp1 == (actionf_p1)T_MoveFloor)
  349. {
  350.     *save_p++ = tc_floor;
  351.     PADSAVEP();
  352.     floor = (floormove_t *)save_p;
  353.     memcpy (floor, th, sizeof(*floor));
  354.     save_p += sizeof(*floor);
  355.     floor->sector = (sector_t *)(floor->sector - sectors);
  356.     continue;
  357. }
  358. if (th->function.acp1 == (actionf_p1)T_PlatRaise)
  359. {
  360.     *save_p++ = tc_plat;
  361.     PADSAVEP();
  362.     plat = (plat_t *)save_p;
  363.     memcpy (plat, th, sizeof(*plat));
  364.     save_p += sizeof(*plat);
  365.     plat->sector = (sector_t *)(plat->sector - sectors);
  366.     continue;
  367. }
  368. if (th->function.acp1 == (actionf_p1)T_LightFlash)
  369. {
  370.     *save_p++ = tc_flash;
  371.     PADSAVEP();
  372.     flash = (lightflash_t *)save_p;
  373.     memcpy (flash, th, sizeof(*flash));
  374.     save_p += sizeof(*flash);
  375.     flash->sector = (sector_t *)(flash->sector - sectors);
  376.     continue;
  377. }
  378. if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
  379. {
  380.     *save_p++ = tc_strobe;
  381.     PADSAVEP();
  382.     strobe = (strobe_t *)save_p;
  383.     memcpy (strobe, th, sizeof(*strobe));
  384.     save_p += sizeof(*strobe);
  385.     strobe->sector = (sector_t *)(strobe->sector - sectors);
  386.     continue;
  387. }
  388. if (th->function.acp1 == (actionf_p1)T_Glow)
  389. {
  390.     *save_p++ = tc_glow;
  391.     PADSAVEP();
  392.     glow = (glow_t *)save_p;
  393.     memcpy (glow, th, sizeof(*glow));
  394.     save_p += sizeof(*glow);
  395.     glow->sector = (sector_t *)(glow->sector - sectors);
  396.     continue;
  397. }
  398.     }
  399.     // add a terminating marker
  400.     *save_p++ = tc_endspecials;
  401. }
  402. //
  403. // P_UnArchiveSpecials
  404. //
  405. void P_UnArchiveSpecials (void)
  406. {
  407.     byte tclass;
  408.     ceiling_t* ceiling;
  409.     vldoor_t* door;
  410.     floormove_t* floor;
  411.     plat_t* plat;
  412.     lightflash_t* flash;
  413.     strobe_t* strobe;
  414.     glow_t* glow;
  415.     // read in saved thinkers
  416.     while (1)
  417.     {
  418. tclass = *save_p++;
  419. switch (tclass)
  420. {
  421.   case tc_endspecials:
  422.     return; // end of list
  423.   case tc_ceiling:
  424.     PADSAVEP();
  425.     ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
  426.     memcpy (ceiling, save_p, sizeof(*ceiling));
  427.     save_p += sizeof(*ceiling);
  428.     ceiling->sector = &sectors[(int)ceiling->sector];
  429.     ceiling->sector->specialdata = ceiling;
  430.     if (ceiling->thinker.function.acp1)
  431. ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
  432.     P_AddThinker (&ceiling->thinker);
  433.     P_AddActiveCeiling(ceiling);
  434.     break;
  435.   case tc_door:
  436.     PADSAVEP();
  437.     door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
  438.     memcpy (door, save_p, sizeof(*door));
  439.     save_p += sizeof(*door);
  440.     door->sector = &sectors[(int)door->sector];
  441.     door->sector->specialdata = door;
  442.     door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  443.     P_AddThinker (&door->thinker);
  444.     break;
  445.   case tc_floor:
  446.     PADSAVEP();
  447.     floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
  448.     memcpy (floor, save_p, sizeof(*floor));
  449.     save_p += sizeof(*floor);
  450.     floor->sector = &sectors[(int)floor->sector];
  451.     floor->sector->specialdata = floor;
  452.     floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
  453.     P_AddThinker (&floor->thinker);
  454.     break;
  455.   case tc_plat:
  456.     PADSAVEP();
  457.     plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
  458.     memcpy (plat, save_p, sizeof(*plat));
  459.     save_p += sizeof(*plat);
  460.     plat->sector = &sectors[(int)plat->sector];
  461.     plat->sector->specialdata = plat;
  462.     if (plat->thinker.function.acp1)
  463. plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
  464.     P_AddThinker (&plat->thinker);
  465.     P_AddActivePlat(plat);
  466.     break;
  467.   case tc_flash:
  468.     PADSAVEP();
  469.     flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
  470.     memcpy (flash, save_p, sizeof(*flash));
  471.     save_p += sizeof(*flash);
  472.     flash->sector = &sectors[(int)flash->sector];
  473.     flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
  474.     P_AddThinker (&flash->thinker);
  475.     break;
  476.   case tc_strobe:
  477.     PADSAVEP();
  478.     strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
  479.     memcpy (strobe, save_p, sizeof(*strobe));
  480.     save_p += sizeof(*strobe);
  481.     strobe->sector = &sectors[(int)strobe->sector];
  482.     strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
  483.     P_AddThinker (&strobe->thinker);
  484.     break;
  485.   case tc_glow:
  486.     PADSAVEP();
  487.     glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
  488.     memcpy (glow, save_p, sizeof(*glow));
  489.     save_p += sizeof(*glow);
  490.     glow->sector = &sectors[(int)glow->sector];
  491.     glow->thinker.function.acp1 = (actionf_p1)T_Glow;
  492.     P_AddThinker (&glow->thinker);
  493.     break;
  494.   default:
  495.     I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
  496.      "in savegame",tclass);
  497. }
  498.     }
  499. }