// // P_UnArchivePlayers // void P_UnArchivePlayers (void) { int i; int j; for (i=0 ; i<MAXPLAYERS ; i++) { if (!playeringame[i]) continue; PADSAVEP(); memcpy (&players[i],save_p, sizeof(player_t)); save_p += sizeof(player_t); // will be set when unarc thinker players[i].mo = NULL; players[i].message = NULL; players[i].attacker = NULL; for (j=0 ; j<NUMPSPRITES ; j++) { if (players[i]. psprites[j].state) { players[i]. psprites[j].state = &states[ (int)players[i].psprites[j].state ]; } } } }
// // P_UnArchivePlayers // void P_v19_UnArchivePlayers(void) { int i; int j; for(i = 0; i < 4; i++) { if(!players[i].plr->ingame) continue; PADSAVEP(); //memcpy (&players[i],save_p, sizeof(player_t)); //P_PlayerConverter(&players[i], (saveplayer_t*) save_p, false); SV_ReadPlayer(players + i); //save_p += sizeof(saveplayer_t); // will be set when unarc thinker players[i].plr->mo = NULL; players[i].message = NULL; players[i].attacker = NULL; for(j = 0; j < NUMPSPRITES; j++) { if(players[i].psprites[j].state) { players[i].psprites[j].state = &states[(int) players[i].psprites[j].state]; } } } }
// // P_ArchivePlayers // void P_ArchivePlayers (void) { int i; int j; player_t* dest; for (i=0 ; i<MAXPLAYERS ; i++) { if (!playeringame[i]) continue; PADSAVEP(); dest = (player_t *)save_p; memcpy (dest,&players[i],sizeof(player_t)); save_p += sizeof(player_t); for (j=0 ; j<NUMPSPRITES ; j++) { if (dest->psprites[j].state) { dest->psprites[j].state = (state_t *)(dest->psprites[j].state-states); } } } }
// // P_ArchiveThinkers // void P_ArchiveThinkers (void) { thinker_t* th; mobj_t* mobj; // save off the current thinkers for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { if (th->function.acp1 == (actionf_p1)P_MobjThinker) { *save_p++ = tc_mobj; PADSAVEP(); mobj = (mobj_t *)save_p; memcpy (mobj, th, sizeof(*mobj)); save_p += sizeof(*mobj); mobj->state = (state_t *)(mobj->state - states); if (mobj->player) mobj->player = (player_t *)((mobj->player-players) + 1); continue; } // I_Error ("P_ArchiveThinkers: Unknown thinker function"); } // add a terminating marker *save_p++ = tc_end; }
// // P_UnArchiveWorld // void P_UnArchiveWorld (void) { int i; sector_t *sec; line_t *li; const short *get; PADSAVEP(); // killough 3/22/98 get = (short *) save_p; // do sectors for (i=0, sec = sectors ; i<numsectors ; i++,sec++) { // killough 10/98: load full floor & ceiling heights, including fractions memcpy(&sec->floorheight, get, sizeof sec->floorheight); get = (void *)((char *) get + sizeof sec->floorheight); memcpy(&sec->ceilingheight, get, sizeof sec->ceilingheight); get = (void *)((char *) get + sizeof sec->ceilingheight); sec->floorpic = *get++; sec->ceilingpic = *get++; sec->lightlevel = *get++; sec->special = *get++; sec->tag = *get++; sec->ceilingdata = 0; //jff 2/22/98 now three thinker fields, not two sec->floordata = 0; sec->lightingdata = 0; sec->soundtarget = 0; } // do lines for (i=0, li = lines ; i<numlines ; i++,li++) { int j; li->flags = *get++; li->special = *get++; li->tag = *get++; for (j=0 ; j<2 ; j++) if (li->sidenum[j] != -1) { side_t *si = &sides[li->sidenum[j]]; // killough 10/98: load full sidedef offsets, including fractions memcpy(&si->textureoffset, get, sizeof si->textureoffset); get = (void *)((char *) get + sizeof si->textureoffset); memcpy(&si->rowoffset, get, sizeof si->rowoffset); get = (void *)((char *) get + sizeof si->rowoffset); si->toptexture = *get++; si->bottomtexture = *get++; si->midtexture = *get++; } } save_p = (byte *) get; }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers (void) { byte tclass; thinker_t* currentthinker; thinker_t* next; mobj_t* mobj; // remove all the current thinkers currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) P_RemoveMobj ((mobj_t *)currentthinker); else Z_Free (currentthinker); currentthinker = next; } P_InitThinkers (); // read in saved thinkers while (1) { tclass = *save_p++; switch (tclass) { case tc_end: return; // end of list case tc_mobj: PADSAVEP(); mobj = (mobj_t*)Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); memcpy (mobj, save_p, sizeof(*mobj)); save_p += sizeof(*mobj); mobj->state = &states[(int)mobj->state]; mobj->target = NULL; if (mobj->player) { mobj->player = &players[(int)mobj->player-1]; mobj->player->mo = mobj; } P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; P_AddThinker (&mobj->thinker); break; default: I_Error ("Unknown tclass %i in savegame",tclass); } } }
// // P_ArchivePlayers // void P_ArchivePlayers (void) { int i; CheckSaveGame(sizeof(player_t) * MAXPLAYERS); // killough for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) { int j; player_t *dest; PADSAVEP(); dest = (player_t *) save_p; memcpy(dest, &players[i], sizeof(player_t)); save_p += sizeof(player_t); for (j=0; j<NUMPSPRITES; j++) if (dest->psprites[j].state) dest->psprites[j].state = (state_t *)(dest->psprites[j].state-states); } }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials (void) { byte tclass; ceiling_t* ceiling; vldoor_t* door; floormove_t* floor; plat_t* plat; lightflash_t* flash; strobe_t* strobe; glow_t* glow; // read in saved thinkers while (1) { tclass = *save_p++; switch (tclass) { case tc_endspecials: return; // end of list case tc_ceiling: PADSAVEP(); ceiling = (ceiling_t*)Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); memcpy (ceiling, save_p, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = §ors[(int)ceiling->sector]; ceiling->sector->specialdata = ceiling; if (ceiling->thinker.function.acp1) ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; P_AddThinker (&ceiling->thinker); P_AddActiveCeiling(ceiling); break; case tc_door: PADSAVEP(); door = (vldoor_t*)Z_Malloc (sizeof(*door), PU_LEVEL, NULL); memcpy (door, save_p, sizeof(*door)); save_p += sizeof(*door); door->sector = §ors[(int)door->sector]; door->sector->specialdata = door; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; P_AddThinker (&door->thinker); break; case tc_floor: PADSAVEP(); floor = (floormove_t*)Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); memcpy (floor, save_p, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = §ors[(int)floor->sector]; floor->sector->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; P_AddThinker (&floor->thinker); break; case tc_plat: PADSAVEP(); plat = (plat_t*)Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); memcpy (plat, save_p, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = §ors[(int)plat->sector]; plat->sector->specialdata = plat; if (plat->thinker.function.acp1) plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise; P_AddThinker (&plat->thinker); P_AddActivePlat(plat); break; case tc_flash: PADSAVEP(); flash = (lightflash_t*)Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); memcpy (flash, save_p, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = §ors[(int)flash->sector]; flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; P_AddThinker (&flash->thinker); break; case tc_strobe: PADSAVEP(); strobe = (strobe_t*)Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); memcpy (strobe, save_p, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = §ors[(int)strobe->sector]; strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; P_AddThinker (&strobe->thinker); break; case tc_glow: PADSAVEP(); glow = (glow_t*)Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); memcpy (glow, save_p, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = §ors[(int)glow->sector]; glow->thinker.function.acp1 = (actionf_p1)T_Glow; P_AddThinker (&glow->thinker); break; default: I_Error ("P_UnarchiveSpecials:Unknown tclass %i " "in savegame",tclass); } } }
// // Things to handle: // // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list // T_VerticalDoor, (vldoor_t: sector_t * swizzle), // T_MoveFloor, (floormove_t: sector_t * swizzle), // T_LightFlash, (lightflash_t: sector_t * swizzle), // T_StrobeFlash, (strobe_t: sector_t *), // T_Glow, (glow_t: sector_t *), // T_PlatRaise, (plat_t: sector_t *), - active list // void P_ArchiveSpecials (void) { thinker_t* th; ceiling_t* ceiling; vldoor_t* door; floormove_t* floor; plat_t* plat; lightflash_t* flash; strobe_t* strobe; glow_t* glow; int i; // save off the current thinkers for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { if (th->function.acv == (actionf_v)NULL) { for (i = 0; i < MAXCEILINGS;i++) if (activeceilings[i] == (ceiling_t *)th) break; if (i<MAXCEILINGS) { *save_p++ = tc_ceiling; PADSAVEP(); ceiling = (ceiling_t *)save_p; memcpy (ceiling, th, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = (sector_t *)(ceiling->sector - sectors); } continue; } if (th->function.acp1 == (actionf_p1)T_MoveCeiling) { *save_p++ = tc_ceiling; PADSAVEP(); ceiling = (ceiling_t *)save_p; memcpy (ceiling, th, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = (sector_t *)(ceiling->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_VerticalDoor) { *save_p++ = tc_door; PADSAVEP(); door = (vldoor_t *)save_p; memcpy (door, th, sizeof(*door)); save_p += sizeof(*door); door->sector = (sector_t *)(door->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_MoveFloor) { *save_p++ = tc_floor; PADSAVEP(); floor = (floormove_t *)save_p; memcpy (floor, th, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = (sector_t *)(floor->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_PlatRaise) { *save_p++ = tc_plat; PADSAVEP(); plat = (plat_t *)save_p; memcpy (plat, th, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = (sector_t *)(plat->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_LightFlash) { *save_p++ = tc_flash; PADSAVEP(); flash = (lightflash_t *)save_p; memcpy (flash, th, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = (sector_t *)(flash->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_StrobeFlash) { *save_p++ = tc_strobe; PADSAVEP(); strobe = (strobe_t *)save_p; memcpy (strobe, th, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = (sector_t *)(strobe->sector - sectors); continue; } if (th->function.acp1 == (actionf_p1)T_Glow) { *save_p++ = tc_glow; PADSAVEP(); glow = (glow_t *)save_p; memcpy (glow, th, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = (sector_t *)(glow->sector - sectors); continue; } } // add a terminating marker *save_p++ = tc_endspecials; }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials (void) { byte tclass; // read in saved thinkers while ((tclass = *save_p++) != tc_endspecials) // killough 2/14/98 switch (tclass) { case tc_ceiling: PADSAVEP(); { ceiling_t *ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); memcpy (ceiling, save_p, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = §ors[(int)ceiling->sector]; ceiling->sector->ceilingdata = ceiling; //jff 2/22/98 if (ceiling->thinker.function) ceiling->thinker.function = T_MoveCeiling; P_AddThinker (&ceiling->thinker); P_AddActiveCeiling(ceiling); break; } case tc_door: PADSAVEP(); { vldoor_t *door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); memcpy (door, save_p, sizeof(*door)); save_p += sizeof(*door); door->sector = §ors[(int)door->sector]; //jff 1/31/98 unarchive line remembered by door as well door->line = (int)door->line!=-1? &lines[(int)door->line] : NULL; door->sector->ceilingdata = door; //jff 2/22/98 door->thinker.function = T_VerticalDoor; P_AddThinker (&door->thinker); break; } case tc_floor: PADSAVEP(); { floormove_t *floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); memcpy (floor, save_p, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = §ors[(int)floor->sector]; floor->sector->floordata = floor; //jff 2/22/98 floor->thinker.function = T_MoveFloor; P_AddThinker (&floor->thinker); break; } case tc_plat: PADSAVEP(); { plat_t *plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); memcpy (plat, save_p, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = §ors[(int)plat->sector]; plat->sector->floordata = plat; //jff 2/22/98 if (plat->thinker.function) plat->thinker.function = T_PlatRaise; P_AddThinker (&plat->thinker); P_AddActivePlat(plat); break; } case tc_flash: PADSAVEP(); { lightflash_t *flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); memcpy (flash, save_p, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = §ors[(int)flash->sector]; flash->thinker.function = T_LightFlash; P_AddThinker (&flash->thinker); break; } case tc_strobe: PADSAVEP(); { strobe_t *strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); memcpy (strobe, save_p, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = §ors[(int)strobe->sector]; strobe->thinker.function = T_StrobeFlash; P_AddThinker (&strobe->thinker); break; } case tc_glow: PADSAVEP(); { glow_t *glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); memcpy (glow, save_p, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = §ors[(int)glow->sector]; glow->thinker.function = T_Glow; P_AddThinker (&glow->thinker); break; } case tc_flicker: // killough 10/4/98 PADSAVEP(); { fireflicker_t *flicker = Z_Malloc (sizeof(*flicker), PU_LEVEL, NULL); memcpy (flicker, save_p, sizeof(*flicker)); save_p += sizeof(*flicker); flicker->sector = §ors[(int)flicker->sector]; flicker->thinker.function = T_FireFlicker; P_AddThinker (&flicker->thinker); break; } //jff 2/22/98 new case for elevators case tc_elevator: PADSAVEP(); { elevator_t *elevator = Z_Malloc (sizeof(*elevator), PU_LEVEL, NULL); memcpy (elevator, save_p, sizeof(*elevator)); save_p += sizeof(*elevator); elevator->sector = §ors[(int)elevator->sector]; elevator->sector->floordata = elevator; //jff 2/22/98 elevator->sector->ceilingdata = elevator; //jff 2/22/98 elevator->thinker.function = T_MoveElevator; P_AddThinker (&elevator->thinker); break; } case tc_scroll: // killough 3/7/98: scroll effect thinkers { scroll_t *scroll = Z_Malloc (sizeof(scroll_t), PU_LEVEL, NULL); memcpy (scroll, save_p, sizeof(scroll_t)); save_p += sizeof(scroll_t); scroll->thinker.function = T_Scroll; P_AddThinker(&scroll->thinker); break; } case tc_pusher: // phares 3/22/98: new Push/Pull effect thinkers { pusher_t *pusher = Z_Malloc (sizeof(pusher_t), PU_LEVEL, NULL); memcpy (pusher, save_p, sizeof(pusher_t)); save_p += sizeof(pusher_t); pusher->thinker.function = T_Pusher; pusher->source = P_GetPushThing(pusher->affectee); P_AddThinker(&pusher->thinker); break; } default: I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); } }
void P_ArchiveSpecials (void) { thinker_t *th; size_t size = 0; // killough // save off the current thinkers (memory size calculation -- killough) for (th = thinkercap.next ; th != &thinkercap ; th=th->next) if (!th->function) { platlist_t *pl; ceilinglist_t *cl; //jff 2/22/98 need this for ceilings too now for (pl=activeplats; pl; pl=pl->next) if (pl->plat == (plat_t *) th) // killough 2/14/98 { size += 4+sizeof(plat_t); goto end; } for (cl=activeceilings; cl; cl=cl->next) // search for activeceiling if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98 { size += 4+sizeof(ceiling_t); goto end; } end:; } else size += th->function==T_MoveCeiling ? 4+sizeof(ceiling_t) : th->function==T_VerticalDoor ? 4+sizeof(vldoor_t) : th->function==T_MoveFloor ? 4+sizeof(floormove_t): th->function==T_PlatRaise ? 4+sizeof(plat_t) : th->function==T_LightFlash ? 4+sizeof(lightflash_t): th->function==T_StrobeFlash ? 4+sizeof(strobe_t) : th->function==T_Glow ? 4+sizeof(glow_t) : th->function==T_MoveElevator ? 4+sizeof(elevator_t): th->function==T_Scroll ? 4+sizeof(scroll_t) : th->function==T_Pusher ? 4+sizeof(pusher_t) : th->function==T_FireFlicker? 4+sizeof(fireflicker_t) : 0; CheckSaveGame(size + 1); // killough; cph: +1 for the tc_endspecials // save off the current thinkers for (th=thinkercap.next; th!=&thinkercap; th=th->next) { if (!th->function) { platlist_t *pl; ceilinglist_t *cl; //jff 2/22/98 add iter variable for ceilings // killough 2/8/98: fix plat original height bug. // Since acv==NULL, this could be a plat in stasis. // so check the active plats list, and save this // plat (jff: or ceiling) even if it is in stasis. for (pl=activeplats; pl; pl=pl->next) if (pl->plat == (plat_t *) th) // killough 2/14/98 goto plat; for (cl=activeceilings; cl; cl=cl->next) if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98 goto ceiling; continue; } if (th->function == T_MoveCeiling) { ceiling_t *ceiling; ceiling: // killough 2/14/98 *save_p++ = tc_ceiling; PADSAVEP(); ceiling = (ceiling_t *)save_p; memcpy (ceiling, th, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = (sector_t *)(ceiling->sector->iSectorID); continue; } if (th->function == T_VerticalDoor) { vldoor_t *door; *save_p++ = tc_door; PADSAVEP(); door = (vldoor_t *) save_p; memcpy (door, th, sizeof *door); save_p += sizeof(*door); door->sector = (sector_t *)(door->sector->iSectorID); //jff 1/31/98 archive line remembered by door as well door->line = (line_t *) (door->line ? door->line-lines : -1); continue; } if (th->function == T_MoveFloor) { floormove_t *floor; *save_p++ = tc_floor; PADSAVEP(); floor = (floormove_t *)save_p; memcpy (floor, th, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = (sector_t *)(floor->sector->iSectorID); continue; } if (th->function == T_PlatRaise) { plat_t *plat; plat: // killough 2/14/98: added fix for original plat height above *save_p++ = tc_plat; PADSAVEP(); plat = (plat_t *)save_p; memcpy (plat, th, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = (sector_t *)(plat->sector->iSectorID); continue; } if (th->function == T_LightFlash) { lightflash_t *flash; *save_p++ = tc_flash; PADSAVEP(); flash = (lightflash_t *)save_p; memcpy (flash, th, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = (sector_t *)(flash->sector->iSectorID); continue; } if (th->function == T_StrobeFlash) { strobe_t *strobe; *save_p++ = tc_strobe; PADSAVEP(); strobe = (strobe_t *)save_p; memcpy (strobe, th, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = (sector_t *)(strobe->sector->iSectorID); continue; } if (th->function == T_Glow) { glow_t *glow; *save_p++ = tc_glow; PADSAVEP(); glow = (glow_t *)save_p; memcpy (glow, th, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = (sector_t *)(glow->sector->iSectorID); continue; } // killough 10/4/98: save flickers if (th->function == T_FireFlicker) { fireflicker_t *flicker; *save_p++ = tc_flicker; PADSAVEP(); flicker = (fireflicker_t *)save_p; memcpy (flicker, th, sizeof(*flicker)); save_p += sizeof(*flicker); flicker->sector = (sector_t *)(flicker->sector->iSectorID); continue; } //jff 2/22/98 new case for elevators if (th->function == T_MoveElevator) { elevator_t *elevator; //jff 2/22/98 *save_p++ = tc_elevator; PADSAVEP(); elevator = (elevator_t *)save_p; memcpy (elevator, th, sizeof(*elevator)); save_p += sizeof(*elevator); elevator->sector = (sector_t *)(elevator->sector->iSectorID); continue; } // killough 3/7/98: Scroll effect thinkers if (th->function == T_Scroll) { *save_p++ = tc_scroll; memcpy (save_p, th, sizeof(scroll_t)); save_p += sizeof(scroll_t); continue; } // phares 3/22/98: Push/Pull effect thinkers if (th->function == T_Pusher) { *save_p++ = tc_pusher; memcpy (save_p, th, sizeof(pusher_t)); save_p += sizeof(pusher_t); continue; } } // add a terminating marker *save_p++ = tc_endspecials; }
// // P_UnArchiveThinkers // void P_v19_UnArchiveThinkers(void) { byte tclass; thinker_t *currentthinker; thinker_t *next; mobj_t *mobj; // remove all the current thinkers currentthinker = thinkercap.next; while(currentthinker != &thinkercap) { next = currentthinker->next; if(currentthinker->function == P_MobjThinker) P_RemoveMobj((mobj_t *) currentthinker); else Z_Free(currentthinker); currentthinker = next; } P_InitThinkers(); // read in saved thinkers while(1) { tclass = *save_p++; switch (tclass) { case tc_end: return; // end of list case tc_mobj: PADSAVEP(); mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL); memset(mobj, 0, sizeof(*mobj)); //memcpy (mobj, save_p, sizeof(*mobj)); //P_MobjConverter(mobj, (savemobj_t*) save_p, false); //memcpy(mobj, save_p, sizeof(*mobj)); SV_ReadMobj(mobj); //save_p += sizeof(savemobj_t); mobj->state = &states[(int) mobj->state]; mobj->target = NULL; if(mobj->player) { int pnum = (int) mobj->player - 1; mobj->player = &players[pnum]; mobj->dplayer = mobj->player->plr; mobj->dplayer->mo = mobj; mobj->dplayer->clAngle = mobj->angle; mobj->dplayer->clLookDir = 0; } P_SetThingPosition(mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker(&mobj->thinker); break; default: Con_Error("Unknown tclass %i in savegame", tclass); } } }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) { P_RemoveMobj ((mobj_t *) th); P_RemoveThinkerDelayed(th); // fix mobj leak } else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); save_p += sizeof(mobj_t);//e6y } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); memcpy (mobj, save_p, sizeof(mobj_t)); save_p += sizeof(mobj_t); mobj->state = states + (int) mobj->state; if (mobj->player) (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; // Must verify soundtarget. See P_ArchiveThinkers. P_SetNewTarget(§ors[i].soundtarget, mobj_p[P_GetMobj(target,size)]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) { // P_SpawnBrainTargets overwrites brain.targeton and brain.easy with zero. struct brain_s brain_tmp = brain; // saving P_SpawnBrainTargets(); // old demos with save/load tics should not be affected by this fix if (!prboom_comp[PC_RESET_MONSTERSPAWNER_PARAMS_AFTER_LOADING].state) { brain = brain_tmp; // restoring } } }
void P_ArchiveThinkers (void) { thinker_t *th; CheckSaveGame(sizeof brain); // killough 3/26/98: Save boss brain state memcpy(save_p, &brain, sizeof brain); save_p += sizeof brain; /* check that enough room is available in savegame buffer * - killough 2/14/98 * cph - use number_of_thinkers saved by P_ThinkerToIndex above * size per object is sizeof(mobj_t) - 2*sizeof(void*) - 4*sizeof(fixed_t) plus * padded type (4) plus 5*sizeof(void*), i.e. sizeof(mobj_t) + 4 + * 3*sizeof(void*) * cph - +1 for the tc_end */ CheckSaveGame(number_of_thinkers*(sizeof(mobj_t)-3*sizeof(fixed_t)+4+3*sizeof(void*)) +1); // save off the current thinkers for (th = thinkercap.next ; th != &thinkercap ; th=th->next) if (th->function == P_MobjThinker) { mobj_t *mobj; *save_p++ = tc_mobj; PADSAVEP(); mobj = (mobj_t *)save_p; //e6y memcpy (mobj, th, sizeof(*mobj)); save_p += sizeof(*mobj); mobj->state = (state_t *)(mobj->state - states); // killough 2/14/98: convert pointers into indices. // Fixes many savegame problems, by properly saving // target and tracer fields. Note: we store NULL if // the thinker pointed to by these fields is not a // mobj thinker. if (mobj->target) mobj->target = mobj->target->thinker.function == P_MobjThinker ? (mobj_t *) mobj->target->thinker.prev : NULL; if (mobj->tracer) mobj->tracer = mobj->tracer->thinker.function == P_MobjThinker ? (mobj_t *) mobj->tracer->thinker.prev : NULL; // killough 2/14/98: new field: save last known enemy. Prevents // monsters from going to sleep after killing monsters and not // seeing player anymore. if (mobj->lastenemy) mobj->lastenemy = mobj->lastenemy->thinker.function == P_MobjThinker ? (mobj_t *) mobj->lastenemy->thinker.prev : NULL; // killough 2/14/98: end changes if (mobj->player) mobj->player = (player_t *)((mobj->player-players) + 1); } // add a terminating marker *save_p++ = tc_end; // killough 9/14/98: save soundtargets { int i; CheckSaveGame(numsectors * sizeof(mobj_t *)); // killough 9/14/98 for (i = 0; i < numsectors; i++) { mobj_t *target = sectors[i].soundtarget; // Fix crash on reload when a soundtarget points to a removed corpse // (prboom bug #1590350) if (target && target->thinker.function == P_MobjThinker) target = (mobj_t *) target->thinker.prev; else target = NULL; memcpy(save_p, &target, sizeof target); save_p += sizeof target; } } }
// // P_ArchiveWorld // void P_ArchiveWorld (void) { int i; const sector_t *sec; const line_t *li; const side_t *si; short *put; // killough 3/22/98: fix bug caused by hoisting save_p too early // killough 10/98: adjust size for changes below size_t size = (sizeof(short)*5 + sizeof sec->floorheight + sizeof sec->ceilingheight) * numsectors + sizeof(short)*3*numlines + 4 + 2; for (i=0; i<numlines; i++) { if (lines[i].sidenum[0] != NO_INDEX) size += sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; if (lines[i].sidenum[1] != NO_INDEX) size += sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; } CheckSaveGame(size); // killough PADSAVEP(); // killough 3/22/98 put = (short *)save_p; // do sectors for (i=0, sec = sectors ; i<numsectors ; i++,sec++) { // killough 10/98: save full floor & ceiling heights, including fraction memcpy(put, &sec->floorheight, sizeof sec->floorheight); put = (void *)((char *) put + sizeof sec->floorheight); memcpy(put, &sec->ceilingheight, sizeof sec->ceilingheight); put = (void *)((char *) put + sizeof sec->ceilingheight); *put++ = sec->floorpic; *put++ = sec->ceilingpic; *put++ = sec->lightlevel; *put++ = sec->special; // needed? yes -- transfer types *put++ = sec->tag; // needed? need them -- killough } // do lines for (i=0, li = lines ; i<numlines ; i++,li++) { int j; *put++ = li->flags; *put++ = li->special; *put++ = li->tag; for (j=0; j<2; j++) if (li->sidenum[j] != NO_INDEX) { si = &sides[li->sidenum[j]]; // killough 10/98: save full sidedef offsets, // preserving fractional scroll offsets memcpy(put, &si->textureoffset, sizeof si->textureoffset); put = (void *)((char *) put + sizeof si->textureoffset); memcpy(put, &si->rowoffset, sizeof si->rowoffset); put = (void *)((char *) put + sizeof si->rowoffset); *put++ = si->toptexture; *put++ = si->bottomtexture; *put++ = si->midtexture; } } *put++ = musinfo.current_item; save_p = (byte *) put; }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) P_RemoveMobj ((mobj_t *) th); else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); save_p += sizeof(mobj_t); } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); memcpy (mobj, save_p, sizeof(mobj_t)); save_p += sizeof(mobj_t); mobj->state = states + (unsigned long) mobj->state; if (mobj->player) (mobj->player = &players[(unsigned long) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[(size_t)((mobj_t *)th)->target]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[(size_t)((mobj_t *)th)->tracer]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[(size_t)((mobj_t *)th)->lastenemy]); // phares: added two new fields for Sprite Height problem P_SetNewTarget(&((mobj_t *) th)->above_thing, mobj_p[(size_t)((mobj_t *)th)->above_thing]); P_SetNewTarget(&((mobj_t *) th)->below_thing, mobj_p[(size_t)((mobj_t *)th)->below_thing]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; P_SetNewTarget(§ors[i].soundtarget, mobj_p[(size_t) target]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) P_SpawnBrainTargets(); }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) { P_RemoveMobj ((mobj_t *) th); P_RemoveThinkerDelayed(th); // fix mobj leak } else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); /* cph 2006/07/30 - see comment below for change in layout of mobj_t */ save_p += sizeof(mobj_t)+3*sizeof(void*)-4*sizeof(fixed_t); } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); /* cph 2006/07/30 - * The end of mobj_t changed from * boolean invisible; * mobj_t* lastenemy; * mobj_t* above_monster; * mobj_t* below_monster; * void* touching_sectorlist; * to * mobj_t* lastenemy; * void* touching_sectorlist; * fixed_t PrevX, PrevY, PrevZ; * at prboom 2.4.4. There is code here to preserve the savegame format. * * touching_sectorlist is reconstructed anyway, so we now read in all * but the last 5 words from the savegame (filling all but the last 2 * fields of our current mobj_t. We then pull lastenemy from the 2nd of * the 5 leftover words, and skip the others. */ memcpy (mobj, save_p, sizeof(mobj_t)-2*sizeof(void*)-4*sizeof(fixed_t)); save_p += sizeof(mobj_t)-sizeof(void*)-4*sizeof(fixed_t); memcpy (&(mobj->lastenemy), save_p, sizeof(void*)); save_p += 4*sizeof(void*); mobj->state = states + (int) mobj->state; if (mobj->player) (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; // Must verify soundtarget. See P_ArchiveThinkers. P_SetNewTarget(§ors[i].soundtarget, mobj_p[P_GetMobj(target,size)]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) P_SpawnBrainTargets(); }
void P_ArchiveThinkers (void) { thinker_t *th; CheckSaveGame(sizeof brain); // killough 3/26/98: Save boss brain state memcpy(save_p, &brain, sizeof brain); save_p += sizeof brain; /* check that enough room is available in savegame buffer * - killough 2/14/98 * cph - use number_of_thinkers saved by P_ThinkerToIndex above * size per object is sizeof(mobj_t) - 2*sizeof(void*) - 4*sizeof(fixed_t) plus * padded type (4) plus 5*sizeof(void*), i.e. sizeof(mobj_t) + 4 + * 3*sizeof(void*) * cph - +1 for the tc_end */ CheckSaveGame(number_of_thinkers*(sizeof(mobj_t)-3*sizeof(fixed_t)+4+3*sizeof(void*)) +1); // save off the current thinkers for (th = thinkercap.next ; th != &thinkercap ; th=th->next) if (th->function == P_MobjThinker) { mobj_t *mobj; *save_p++ = tc_mobj; PADSAVEP(); mobj = (mobj_t *)save_p; /* cph 2006/07/30 - * The end of mobj_t changed from * boolean invisible; * mobj_t* lastenemy; * mobj_t* above_monster; * mobj_t* below_monster; * void* touching_sectorlist; * to * mobj_t* lastenemy; * void* touching_sectorlist; * fixed_t PrevX, PrevY, PrevZ, padding; * at prboom 2.4.4. There is code here to preserve the savegame format. * * touching_sectorlist is reconstructed anyway, so we now leave off the * last 2 words of mobj_t, write 5 words of 0 and then write lastenemy * into the second of these. */ memcpy (mobj, th, sizeof(*mobj) - 2*sizeof(void*)); save_p += sizeof(*mobj) - 2*sizeof(void*) - 4*sizeof(fixed_t); memset (save_p, 0, 5*sizeof(void*)); mobj->state = (state_t *)(mobj->state - states); // killough 2/14/98: convert pointers into indices. // Fixes many savegame problems, by properly saving // target and tracer fields. Note: we store NULL if // the thinker pointed to by these fields is not a // mobj thinker. if (mobj->target) mobj->target = mobj->target->thinker.function == P_MobjThinker ? (mobj_t *) mobj->target->thinker.prev : NULL; if (mobj->tracer) mobj->tracer = mobj->tracer->thinker.function == P_MobjThinker ? (mobj_t *) mobj->tracer->thinker.prev : NULL; // killough 2/14/98: new field: save last known enemy. Prevents // monsters from going to sleep after killing monsters and not // seeing player anymore. if (((mobj_t*)th)->lastenemy && ((mobj_t*)th)->lastenemy->thinker.function == P_MobjThinker) { memcpy (save_p + sizeof(void*), &(((mobj_t*)th)->lastenemy->thinker.prev), sizeof(void*)); } // killough 2/14/98: end changes save_p += 5*sizeof(void*); if (mobj->player) mobj->player = (player_t *)((mobj->player-players) + 1); } // add a terminating marker *save_p++ = tc_end; // killough 9/14/98: save soundtargets { int i; CheckSaveGame(numsectors * sizeof(mobj_t *)); // killough 9/14/98 for (i = 0; i < numsectors; i++) { mobj_t *target = sectors[i].soundtarget; // Fix crash on reload when a soundtarget points to a removed corpse // (prboom bug #1590350) if (target && target->thinker.function == P_MobjThinker) target = (mobj_t *) target->thinker.prev; else target = NULL; memcpy(save_p, &target, sizeof target); save_p += sizeof target; } } }