Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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