static void saveg_read_header(void) { int i; int size; byte a, b, c; // skip the description field for(i = 0; i < SAVESTRINGSIZE; i++) { saveg_read8(); } // skip the date for(i = 0; i < 32; i++) { saveg_read8(); } size = saveg_read32() / sizeof(int); // skip the thumbnail for(i = 0; i < size; i++) { saveg_read32(); } for(i = 0; i < 16; i++) { passwordData[i] = saveg_read8(); } gameskill = saveg_read8(); gamemap = saveg_read8(); nextmap = saveg_read8(); saveg_read_pad(); globalint = saveg_read16(); // // [kex] 12/26/11 - read total stat info // saveg_read_pad(); totalkills = saveg_read32(); totalitems = saveg_read32(); totalsecret = saveg_read32(); for(i = 0; i < MAXPLAYERS; i++) { playeringame[i] = saveg_read8(); } // get the times a = saveg_read8(); b = saveg_read8(); c = saveg_read8(); leveltime = (a<<16) + (b<<8) + c; saveg_read_pad(); }
void P_UnArchiveMacros(void) { int i; int current; byte havemacro; saveg_read_pad(); // [kex] 12/26/11 - read tracked info for disabled macros for(i = 0; i < macros.macrocount; i++) { if(saveg_read8()) { macros.def[i].data[0].id = 0; } } havemacro = saveg_read8(); if(!havemacro) { return; } macroid = saveg_read16(); macrocounter = saveg_read16(); current = saveg_read16(); mobjmacro = saveg_read_mobjindex(); taglistidx = saveg_read16(); macro = ¯os.def[macroid]; nextmacro = ¯o->data[current]; for(i = 0; i < MAXQUEUELIST; i++) { taglist[i] = saveg_read16(); } }
// // P_UnArchivePlayers // // [STRIFE] Verified unmodified. // void P_UnArchivePlayers (boolean userload) { int i; for (i=0 ; i<MAXPLAYERS ; i++) { player_t dummy; if (!playeringame[i]) continue; saveg_read_pad(); // haleyjd [STRIFE]: not exactly how vanilla did it, but this is // necessary because of Choco's change to the savegame code which // reads it directly from file. When not a userload, all the player_t // data loaded from the save is thrown away. if(userload) { saveg_read_player_t(&players[i]); players[i].mo = NULL; } else saveg_read_player_t(&dummy); // will be set when unarc thinker players[i].message = NULL; players[i].attacker = NULL; } }
static dboolean saveg_read_marker(int marker) { int value; saveg_read_pad(); value = saveg_read32(); return value == marker; }
static void saveg_read_mapthing_t(mapthing_t* mt) { mt->x = saveg_read16(); mt->y = saveg_read16(); mt->z = saveg_read16(); mt->angle = saveg_read16(); mt->type = saveg_read16(); mt->options = saveg_read16(); mt->tid = saveg_read16(); saveg_read_pad(); }
// // 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 = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: saveg_read_pad(); mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); saveg_read_mobj_t(mobj); mobj->target = NULL; mobj->tracer = NULL; 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_UnArchivePlayers // void P_UnArchivePlayers(void) { int i; for(i = 0; i < MAXPLAYERS; i++) { if(!playeringame[i]) { continue; } saveg_read_pad(); saveg_read_player_t(&players[i]); } }
void P_UnArchiveMobjs(void) { mobj_t* current; mobj_t* next; mobj_t* mobj; int i; // remove all the current thinkers current = mobjhead.next; while(current != &mobjhead) { next = current->next; P_RemoveMobj(current); current = next; } saveg_setup_mobjread(); mobjhead.next = mobjhead.prev = &mobjhead; for(i = 0; i < savegmobjnum; i++) { mobj = savegmobj[i].mobj; saveg_read_pad(); saveg_read_mobj_t(mobj); if(!saveg_read_marker(SAVEGAME_MOBJ)) I_Error("P_UnArchiveMobjs: Mobj read is inconsistent\nfile offset: %i\nmobj count: %i", save_offset, savegmobjnum); P_SetThingPosition(mobj); P_LinkMobj(mobj); mobj->info = &mobjinfo[mobj->type]; } saveg_read_pad(); }
// // P_UnArchivePlayers // void P_UnArchivePlayers (void) { int i; for (i=0 ; i<MAXPLAYERS ; i++) { if (!playeringame[i]) continue; saveg_read_pad(); saveg_read_player_t(&players[i]); // will be set when unarc thinker players[i].mo = NULL; players[i].message = NULL; players[i].attacker = NULL; } }
// // 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 = saveg_read8(); switch (tclass) { case tc_endspecials: return; // end of list case tc_ceiling: saveg_read_pad(); ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); saveg_read_ceiling_t(ceiling); 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: saveg_read_pad(); door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); saveg_read_vldoor_t(door); door->sector->specialdata = door; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; P_AddThinker (&door->thinker); break; case tc_floor: saveg_read_pad(); floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); saveg_read_floormove_t(floor); floor->sector->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; P_AddThinker (&floor->thinker); break; case tc_plat: saveg_read_pad(); plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); saveg_read_plat_t(plat); 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: saveg_read_pad(); flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); saveg_read_lightflash_t(flash); flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; P_AddThinker (&flash->thinker); break; case tc_strobe: saveg_read_pad(); strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); saveg_read_strobe_t(strobe); strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; P_AddThinker (&strobe->thinker); break; case tc_glow: saveg_read_pad(); glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); saveg_read_glow_t(glow); glow->thinker.function.acp1 = (actionf_p1)T_Glow; P_AddThinker (&glow->thinker); break; default: I_Error ("P_UnarchiveSpecials:Unknown tclass %i " "in savegame",tclass); } } }
// // P_UnArchivePlayer // void P_UnArchivePlayer(void) { saveg_read_pad(); P_InitCards(); saveg_read_player_t(); }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials(void) { // read in saved thinkers while (true) { byte tclass = saveg_read8(); switch (tclass) { case tc_endspecials: // end of list return; case tc_ceiling: { ceiling_t *ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_ceiling_t(ceiling); ceiling->sector->ceilingdata = ceiling; ceiling->thinker.function = T_MoveCeiling; P_AddThinker(&ceiling->thinker); P_AddActiveCeiling(ceiling); break; } case tc_door: { vldoor_t *door = Z_Malloc(sizeof(*door), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_vldoor_t(door); door->sector->ceilingdata = door; door->thinker.function = T_VerticalDoor; P_AddThinker(&door->thinker); break; } case tc_floor: { floormove_t *floor = Z_Malloc(sizeof(*floor), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_floormove_t(floor); floor->sector->floordata = floor; floor->thinker.function = T_MoveFloor; P_AddThinker(&floor->thinker); break; } case tc_plat: { plat_t *plat = Z_Malloc(sizeof(*plat), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_plat_t(plat); plat->sector->floordata = plat; P_AddThinker(&plat->thinker); P_AddActivePlat(plat); break; } case tc_flash: { lightflash_t *flash = Z_Malloc(sizeof(*flash), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_lightflash_t(flash); flash->thinker.function = T_LightFlash; P_AddThinker(&flash->thinker); break; } case tc_strobe: { strobe_t *strobe = Z_Malloc(sizeof(*strobe), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_strobe_t(strobe); strobe->thinker.function = T_StrobeFlash; P_AddThinker(&strobe->thinker); break; } case tc_glow: { glow_t *glow = Z_Malloc(sizeof(*glow), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_glow_t(glow); glow->thinker.function = T_Glow; P_AddThinker(&glow->thinker); break; } case tc_fireflicker: { fireflicker_t *fireflicker = Z_Malloc(sizeof(*fireflicker), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_fireflicker_t(fireflicker); fireflicker->thinker.function = T_FireFlicker; P_AddThinker(&fireflicker->thinker); break; } case tc_elevator: { elevator_t *elevator = Z_Malloc(sizeof(*elevator), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_elevator_t(elevator); elevator->sector->ceilingdata = elevator; elevator->thinker.function = T_MoveElevator; P_AddThinker(&elevator->thinker); break; } case tc_scroll: { scroll_t *scroll = Z_Malloc(sizeof(*scroll), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_scroll_t(scroll); scroll->thinker.function = T_Scroll; P_AddThinker(&scroll->thinker); break; } case tc_pusher: { pusher_t *pusher = Z_Malloc(sizeof(*pusher), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_pusher_t(pusher); pusher->thinker.function = T_Pusher; pusher->source = P_GetPushThing(pusher->affectee); P_AddThinker(&pusher->thinker); break; } case tc_button: { button_t *button = Z_Malloc(sizeof(*button), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_button_t(button); P_StartButton(button->line, button->where, button->btexture, button->btimer); break; } default: I_Error("This savegame is invalid."); } } }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers(void) { thinker_t *currentthinker = thinkers[th_all].next; // remove all the current thinkers while (currentthinker != &thinkers[th_all]) { thinker_t *next = currentthinker->next; if (currentthinker->function == P_MobjThinker || currentthinker->function == MusInfoThinker) { P_RemoveMobj((mobj_t *)currentthinker); P_RemoveThinkerDelayed(currentthinker); } else Z_Free(currentthinker); currentthinker = next; } P_InitThinkers(); // remove all bloodsplats for (int i = 0; i < numsectors; i++) { bloodsplat_t *splat = sectors[i].splatlist; while (splat) { bloodsplat_t *next = splat->snext; P_UnsetBloodSplatPosition(splat); splat = next; } } r_bloodsplats_total = 0; thingindex = 0; // read in saved thinkers while (true) { byte tclass = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: { mobj_t *mobj = Z_Calloc(1, sizeof(*mobj), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_mobj_t(mobj); mobj->info = &mobjinfo[mobj->type]; P_SetThingPosition(mobj); mobj->thinker.function = (mobj->type == MT_MUSICSOURCE ? MusInfoThinker : P_MobjThinker); P_AddThinker(&mobj->thinker); mobj->colfunc = mobj->info->colfunc; mobj->altcolfunc = mobj->info->altcolfunc; P_SetShadowColumnFunction(mobj); thingindex = MIN(thingindex + 1, TARGETLIMIT - 1); break; } case tc_bloodsplat: { bloodsplat_t *splat = calloc(1, sizeof(*splat)); saveg_read_pad(); saveg_read_bloodsplat_t(splat); if (r_bloodsplats_total < r_bloodsplats_max) { splat->width = spritewidth[splat->patch]; splat->sector = R_PointInSubsector(splat->x, splat->y)->sector; P_SetBloodSplatPosition(splat); splat->colfunc = (splat->blood == FUZZYBLOOD ? fuzzcolfunc : bloodsplatcolfunc); r_bloodsplats_total++; } break; } default: I_Error("This savegame is invalid."); } } }
void P_UnArchiveSpecials(void) { int i; dboolean specialthinker; byte tclass; void* thinker; thinker_t* currentthinker; thinker_t* next; // remove all the current thinkers currentthinker = thinkercap.next; while(currentthinker != &thinkercap) { next = currentthinker->next; Z_Free(currentthinker); currentthinker = next; } thinkercap.prev = thinkercap.next = &thinkercap; while(1) { tclass = saveg_read8(); if(tclass == tc_endthinkers) { return; } if(tclass > tc_endthinkers) { I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); } for(i = 0; saveg_specials[i].type != tc_endthinkers; i++) { if(tclass == saveg_specials[i].type) { saveg_read_pad(); thinker = Z_Malloc(saveg_specials[i].structsize, PU_LEVEL, NULL); saveg_specials[i].readfunc(thinker); ((thinker_t*)thinker)->function.acp1 = (actionf_p1)saveg_specials[i].function.acp1; P_AddThinker(thinker); // handle special cases switch(tclass) { case tc_ceiling: specialthinker = saveg_read32(); if(!specialthinker) { ((thinker_t*)thinker)->function.acp1 = NULL; } P_AddActiveCeiling(thinker); break; case tc_plat: specialthinker = saveg_read32(); if(!specialthinker) { ((thinker_t*)thinker)->function.acp1 = NULL; } P_AddActivePlat(thinker); break; case tc_combine: P_CombineLightSpecials(((combine_t*)thinker)->sector); P_RemoveThinker(thinker); break; } if(((thinker_t*)thinker)->function.acp1 != NULL) { specialthinker = saveg_read32(); if(specialthinker) { macrothinker = (thinker_t*)thinker; } } break; } } } }
// // P_UnArchiveWorld // void P_UnArchiveWorld(void) { int i; int j; sector_t *sec; line_t *li; light_t *light; side_t *si; // do sectors for(i = 0, sec = sectors; i < numsectors; i++, sec++) { sec->floorheight = INT2F(saveg_read16()); sec->ceilingheight = INT2F(saveg_read16()); sec->floorpic = saveg_read16(); sec->ceilingpic = saveg_read16(); sec->special = saveg_read16(); sec->tag = saveg_read16(); sec->flags = saveg_read16(); sec->lightlevel = saveg_read16(); sec->xoffset = saveg_read32(); sec->yoffset = saveg_read32(); saveg_set_mobjtarget(&sec->soundtarget, saveg_read_mobjindex()); for(j = 0; j < 5; j++) { sec->colors[j] = saveg_read16(); } sec->specialdata = 0; } // do lines for(i = 0, li = lines; i < numlines; i++, li++) { li->flags = (saveg_read16() << 16); li->flags = li->flags | (saveg_read16() & 0xFFFF); li->special = saveg_read16(); li->tag = saveg_read16(); for(j = 0; j < 2; j++) { if(li->sidenum[j] == NO_SIDE_INDEX) { continue; } si = &sides[li->sidenum[j]]; si->textureoffset = INT2F(saveg_read16()); si->rowoffset = INT2F(saveg_read16()); si->toptexture = saveg_read16(); si->bottomtexture = saveg_read16(); si->midtexture = saveg_read16(); } } // do lights for(i = 0, light = lights; i < numlights; i++, light++) { light->base_r = saveg_read8(); light->base_g = saveg_read8(); light->base_b = saveg_read8(); light->active_r = saveg_read8(); light->active_g = saveg_read8(); light->active_b = saveg_read8(); light->r = saveg_read8(); light->g = saveg_read8(); light->b = saveg_read8(); saveg_read_pad(); light->tag = saveg_read16(); } }
// // 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 = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: saveg_read_pad(); mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); saveg_read_mobj_t(mobj); // haleyjd 09/29/10: Strife sets the targets of non-allied creatures // who had a non-NULL target at save time to players[0].mo so that // they won't fall back asleep. // // BUG: As the player may not have been spawned yet, we could be // setting monsters' targets to the mobj which was spawned by // P_SetupLevel and then removed just above. Due to a subtle glitch // in the DOOM engine whereby all things removed in this function // are leaked until the next time P_SetupLevel is called, this is a // safe operation - the call to P_InitThinkers above stops any of // the objects removed, including the player's previous body, from // being passed to Z_Free. One glitch relying on another! if(mobj->target != NULL && (mobj->flags & MF_ALLY) != MF_ALLY) mobj->target = players[0].mo; else mobj->target = NULL; // WARNING! Strife does not seem to set tracer! I am leaving it be // for now because so far no crashes have been observed, and failing // to set this here will almost certainly crash Choco. mobj->tracer = NULL; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // [STRIFE]: doesn't set these //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); } } }