doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

p_saveg.c (10915B)


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