1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "Precompiled.h"
- #include "globaldata.h"
- #include "i_system.h"
- #include "z_zone.h"
- #include "p_local.h"
- // State.
- #include "doomstat.h"
- #include "r_state.h"
- // Pads ::g->save_p to a 4-byte boundary
- // so that the load/save works on SGI&Gecko.
- //
- // P_ArchivePlayers
- //
- void P_ArchivePlayers (void)
- {
- int i;
- int j;
- player_t* dest;
-
- for (i=0 ; i<MAXPLAYERS ; i++)
- {
- if (!::g->playeringame[i])
- continue;
-
- PADSAVEP();
- dest = (player_t *)::g->save_p;
- memcpy (dest,&::g->players[i],sizeof(player_t));
- ::g->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-::g->states);
- }
- }
- }
- }
- //
- // P_UnArchivePlayers
- //
- void P_UnArchivePlayers (void)
- {
- int i;
- int j;
-
- for (i=0 ; i<MAXPLAYERS ; i++)
- {
- if (!::g->playeringame[i])
- continue;
-
- PADSAVEP();
- memcpy (&::g->players[i],::g->save_p, sizeof(player_t));
- ::g->save_p += sizeof(player_t);
-
- // will be set when unarc thinker
- ::g->players[i].mo = NULL;
- ::g->players[i].message = NULL;
- ::g->players[i].attacker = NULL;
- for (j=0 ; j<NUMPSPRITES ; j++)
- {
- if (::g->players[i]. psprites[j].state)
- {
- ::g->players[i]. psprites[j].state
- = &::g->states[ (int)::g->players[i].psprites[j].state ];
- }
- }
- }
- }
- //
- // P_ArchiveWorld
- //
- void P_ArchiveWorld (void)
- {
- int i;
- int j;
- sector_t* sec;
- line_t* li;
- side_t* si;
- short* put;
-
- put = (short *)::g->save_p;
-
- // do ::g->sectors
- for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
- {
- *put++ = sec->floorheight >> FRACBITS;
- *put++ = sec->ceilingheight >> FRACBITS;
- *put++ = sec->floorpic;
- *put++ = sec->ceilingpic;
- *put++ = sec->lightlevel;
- *put++ = sec->special; // needed?
- *put++ = sec->tag; // needed?
- }
-
- // do ::g->lines
- for (i=0, li = ::g->lines ; i < ::g->numlines ; i++,li++)
- {
- *put++ = li->flags;
- *put++ = li->special;
- *put++ = li->tag;
- for (j=0 ; j<2 ; j++)
- {
- if (li->sidenum[j] == -1)
- continue;
-
- si = &::g->sides[li->sidenum[j]];
- *put++ = si->textureoffset >> FRACBITS;
- *put++ = si->rowoffset >> FRACBITS;
- *put++ = si->toptexture;
- *put++ = si->bottomtexture;
- *put++ = si->midtexture;
- }
- }
- // Doom 2 level 30 requires some global pointers, wheee!
- *put++ = ::g->braintargeton;
- *put++ = ::g->easy;
- ::g->save_p = (byte *)put;
- }
- //
- // P_UnArchiveWorld
- //
- void P_UnArchiveWorld (void)
- {
- int i;
- int j;
- sector_t* sec;
- line_t* li;
- side_t* si;
- short* get;
-
- get = (short *)::g->save_p;
-
- // do ::g->sectors
- for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
- {
- sec->floorheight = *get++ << FRACBITS;
- sec->ceilingheight = *get++ << FRACBITS;
- sec->floorpic = *get++;
- sec->ceilingpic = *get++;
- sec->lightlevel = *get++;
- sec->special = *get++; // needed?
- sec->tag = *get++; // needed?
- sec->specialdata = 0;
- sec->soundtarget = 0;
- }
-
- // do ::g->lines
- for (i=0, li = ::g->lines ; i < ::g->numlines ; i++,li++)
- {
- li->flags = *get++;
- li->special = *get++;
- li->tag = *get++;
- for (j=0 ; j<2 ; j++)
- {
- if (li->sidenum[j] == -1)
- continue;
- si = &::g->sides[li->sidenum[j]];
- si->textureoffset = *get++ << FRACBITS;
- si->rowoffset = *get++ << FRACBITS;
- si->toptexture = *get++;
- si->bottomtexture = *get++;
- si->midtexture = *get++;
- }
- }
- // Doom 2 level 30 requires some global pointers, wheee!
- ::g->braintargeton = *get++;
- ::g->easy = *get++;
- ::g->save_p = (byte *)get;
- }
- //
- // Thinkers
- //
- int GetMOIndex( mobj_t* findme ) {
- thinker_t* th;
- mobj_t* mobj;
- int index = 0;
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
- index++;
- mobj = (mobj_t*)th;
- if ( mobj == findme ) {
- return index;
- }
- }
- }
- return 0;
- }
- mobj_t* GetMO( int index ) {
- thinker_t* th;
- int testindex = 0;
- if ( !index ) {
- return NULL;
- }
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
- testindex++;
- if ( testindex == index ) {
- return (mobj_t*)th;
- }
- }
- }
- return NULL;
- }
- //
- // P_ArchiveThinkers
- //
- void P_ArchiveThinkers (void)
- {
- thinker_t* th;
- mobj_t* mobj;
- ceiling_t* ceiling;
- vldoor_t* door;
- floormove_t* floor;
- plat_t* plat;
- fireflicker_t* fire;
- lightflash_t* flash;
- strobe_t* strobe;
- glow_t* glow;
- int i;
-
- // save off the current thinkers
- //I_Printf( "Savegame on leveltime %d\n====================\n", ::g->leveltime );
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- //mobj_t* test = (mobj_t*)th;
- //I_Printf( "%3d: %x == function\n", index++, th->function.acp1 );
- if (th->function.acp1 == (actionf_p1)P_MobjThinker)
- {
- *::g->save_p++ = tc_mobj;
- PADSAVEP();
- mobj = (mobj_t *)::g->save_p;
- memcpy (mobj, th, sizeof(*mobj));
- ::g->save_p += sizeof(*mobj);
- mobj->state = (state_t *)(mobj->state - ::g->states);
- if (mobj->player)
- mobj->player = (player_t *)((mobj->player-::g->players) + 1);
- // Save out 'target'
- int moIndex = GetMOIndex( mobj->target );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- // Save out 'tracer'
- moIndex = GetMOIndex( mobj->tracer );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- moIndex = GetMOIndex( mobj->snext );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- moIndex = GetMOIndex( mobj->sprev );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- // Is this the head of a sector list?
- if ( mobj->subsector->sector->thinglist == (mobj_t*)th ) {
- *::g->save_p++ = 1;
- }
- else {
- *::g->save_p++ = 0;
- }
- moIndex = GetMOIndex( mobj->bnext );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- moIndex = GetMOIndex( mobj->bprev );
- *::g->save_p++ = moIndex >> 8;
- *::g->save_p++ = moIndex;
- // Is this the head of a block list?
- int blockx = (mobj->x - ::g->bmaporgx)>>MAPBLOCKSHIFT;
- int blocky = (mobj->y - ::g->bmaporgy)>>MAPBLOCKSHIFT;
- if ( blockx >= 0 && blockx < ::g->bmapwidth && blocky >= 0 && blocky < ::g->bmapheight
- && (mobj_t*)th == ::g->blocklinks[blocky*::g->bmapwidth+blockx] ) {
- *::g->save_p++ = 1;
- }
- else {
- *::g->save_p++ = 0;
- }
- continue;
- }
- if (th->function.acv == (actionf_v)NULL)
- {
- for (i = 0; i < MAXCEILINGS;i++)
- if (::g->activeceilings[i] == (ceiling_t *)th)
- break;
- if (i<MAXCEILINGS)
- {
- *::g->save_p++ = tc_ceiling;
- PADSAVEP();
- ceiling = (ceiling_t *)::g->save_p;
- memcpy (ceiling, th, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
- }
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
- {
- *::g->save_p++ = tc_ceiling;
- PADSAVEP();
- ceiling = (ceiling_t *)::g->save_p;
- memcpy (ceiling, th, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
- {
- *::g->save_p++ = tc_door;
- PADSAVEP();
- door = (vldoor_t *)::g->save_p;
- memcpy (door, th, sizeof(*door));
- ::g->save_p += sizeof(*door);
- door->sector = (sector_t *)(door->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_MoveFloor)
- {
- *::g->save_p++ = tc_floor;
- PADSAVEP();
- floor = (floormove_t *)::g->save_p;
- memcpy (floor, th, sizeof(*floor));
- ::g->save_p += sizeof(*floor);
- floor->sector = (sector_t *)(floor->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_PlatRaise)
- {
- *::g->save_p++ = tc_plat;
- PADSAVEP();
- plat = (plat_t *)::g->save_p;
- memcpy (plat, th, sizeof(*plat));
- ::g->save_p += sizeof(*plat);
- plat->sector = (sector_t *)(plat->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_FireFlicker)
- {
- *::g->save_p++ = tc_fire;
- PADSAVEP();
- fire = (fireflicker_t *)::g->save_p;
- memcpy (fire, th, sizeof(*fire));
- ::g->save_p += sizeof(*fire);
- fire->sector = (sector_t *)(fire->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_LightFlash)
- {
- *::g->save_p++ = tc_flash;
- PADSAVEP();
- flash = (lightflash_t *)::g->save_p;
- memcpy (flash, th, sizeof(*flash));
- ::g->save_p += sizeof(*flash);
- flash->sector = (sector_t *)(flash->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
- {
- *::g->save_p++ = tc_strobe;
- PADSAVEP();
- strobe = (strobe_t *)::g->save_p;
- memcpy (strobe, th, sizeof(*strobe));
- ::g->save_p += sizeof(*strobe);
- strobe->sector = (sector_t *)(strobe->sector - ::g->sectors);
- continue;
- }
- if (th->function.acp1 == (actionf_p1)T_Glow)
- {
- *::g->save_p++ = tc_glow;
- PADSAVEP();
- glow = (glow_t *)::g->save_p;
- memcpy (glow, th, sizeof(*glow));
- ::g->save_p += sizeof(*glow);
- glow->sector = (sector_t *)(glow->sector - ::g->sectors);
- continue;
- }
- }
- // add a terminating marker
- *::g->save_p++ = tc_end;
- sector_t* sec;
- short* put = (short *)::g->save_p;
- for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++) {
- *put++ = (short)GetMOIndex( sec->soundtarget );
- }
- ::g->save_p = (byte *)put;
- // add a terminating marker
- *::g->save_p++ = tc_end;
- }
- //
- // P_UnArchiveThinkers
- //
- void P_UnArchiveThinkers (void)
- {
- byte tclass;
- thinker_t* currentthinker;
- thinker_t* next;
- mobj_t* mobj;
- ceiling_t* ceiling;
- vldoor_t* door;
- floormove_t* floor;
- plat_t* plat;
- fireflicker_t* fire;
- lightflash_t* flash;
- strobe_t* strobe;
- glow_t* glow;
- thinker_t* th;
- int count = 0;
- sector_t* ss = NULL;
- int mo_index = 0;
- int mo_targets[1024];
- int mo_tracers[1024];
- int mo_snext[1024];
- int mo_sprev[1024];
- bool mo_shead[1024];
- int mo_bnext[1024];
- int mo_bprev[1024];
- bool mo_bhead[1024];
- // remove all the current thinkers
- currentthinker = ::g->thinkercap.next;
- while (currentthinker != &::g->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 = *::g->save_p++;
- switch (tclass)
- {
- case tc_end:
- // clear sector thing lists
- ss = ::g->sectors;
- for (int i=0 ; i < ::g->numsectors ; i++, ss++) {
- ss->thinglist = NULL;
- }
- // clear blockmap thing lists
- count = sizeof(*::g->blocklinks) * ::g->bmapwidth * ::g->bmapheight;
- memset (::g->blocklinks, 0, count);
- // Doom 2 level 30 requires some global pointers, wheee!
- ::g->numbraintargets = 0;
- // fixup mobj_t pointers now that all thinkers have been restored
- mo_index = 0;
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next) {
- if (th->function.acp1 == (actionf_p1)P_MobjThinker) {
- mobj = (mobj_t*)th;
- mobj->target = GetMO( mo_targets[mo_index] );
- mobj->tracer = GetMO( mo_tracers[mo_index] );
- mobj->snext = GetMO( mo_snext[mo_index] );
- mobj->sprev = GetMO( mo_sprev[mo_index] );
- if ( mo_shead[mo_index] ) {
- mobj->subsector->sector->thinglist = mobj;
- }
- mobj->bnext = GetMO( mo_bnext[mo_index] );
- mobj->bprev = GetMO( mo_bprev[mo_index] );
- if ( mo_bhead[mo_index] ) {
- // Is this the head of a block list?
- int blockx = (mobj->x - ::g->bmaporgx)>>MAPBLOCKSHIFT;
- int blocky = (mobj->y - ::g->bmaporgy)>>MAPBLOCKSHIFT;
- if ( blockx >= 0 && blockx < ::g->bmapwidth && blocky >= 0 && blocky < ::g->bmapheight ) {
- ::g->blocklinks[blocky*::g->bmapwidth+blockx] = mobj;
- }
- }
- // Doom 2 level 30 requires some global pointers, wheee!
- if ( mobj->type == MT_BOSSTARGET ) {
- ::g->braintargets[::g->numbraintargets] = mobj;
- ::g->numbraintargets++;
- }
- mo_index++;
- }
- }
- int i;
- sector_t* sec;
- short* get;
- get = (short *)::g->save_p;
- for (i=0, sec = ::g->sectors ; i < ::g->numsectors ; i++,sec++)
- {
- sec->soundtarget = GetMO( *get++ );
- }
- ::g->save_p = (byte *)get;
- tclass = *::g->save_p++;
- if ( tclass != tc_end ) {
- I_Error( "Savegame error after loading sector soundtargets." );
- }
- // print the current thinkers
- //I_Printf( "Loadgame on leveltime %d\n====================\n", ::g->leveltime );
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- //mobj_t* test = (mobj_t*)th;
- //I_Printf( "%3d: %x == function\n", index++, th->function.acp1 );
- }
- return; // end of list
- case tc_mobj:
- PADSAVEP();
- mobj = (mobj_t*)DoomLib::Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL);
- memcpy (mobj, ::g->save_p, sizeof(*mobj));
- ::g->save_p += sizeof(*mobj);
- mobj->state = &::g->states[(int)mobj->state];
- mobj->target = NULL;
- mobj->tracer = NULL;
- if (mobj->player)
- {
- mobj->player = &::g->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;
- // Read in 'target' and store for fixup
- int a, b, foundIndex;
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_targets[mo_index] = foundIndex;
- // Read in 'tracer' and store for fixup
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_tracers[mo_index] = foundIndex;
- // Read in 'snext' and store for fixup
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_snext[mo_index] = foundIndex;
- // Read in 'sprev' and store for fixup
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_sprev[mo_index] = foundIndex;
- foundIndex = *::g->save_p++;
- mo_shead[mo_index] = foundIndex == 1;
- // Read in 'bnext' and store for fixup
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_bnext[mo_index] = foundIndex;
- // Read in 'bprev' and store for fixup
- a = *::g->save_p++;
- b = *::g->save_p++;
- foundIndex = (a << 8) + b;
- mo_bprev[mo_index] = foundIndex;
- foundIndex = *::g->save_p++;
- mo_bhead[mo_index] = foundIndex == 1;
- mo_index++;
- P_AddThinker (&mobj->thinker);
- break;
- case tc_ceiling:
- PADSAVEP();
- ceiling = (ceiling_t*)DoomLib::Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL);
- memcpy (ceiling, ::g->save_p, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = &::g->sectors[(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*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, NULL);
- memcpy (door, ::g->save_p, sizeof(*door));
- ::g->save_p += sizeof(*door);
- door->sector = &::g->sectors[(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*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
- memcpy (floor, ::g->save_p, sizeof(*floor));
- ::g->save_p += sizeof(*floor);
- floor->sector = &::g->sectors[(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*)DoomLib::Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
- memcpy (plat, ::g->save_p, sizeof(*plat));
- ::g->save_p += sizeof(*plat);
- plat->sector = &::g->sectors[(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_fire:
- PADSAVEP();
- fire = (fireflicker_t*)DoomLib::Z_Malloc (sizeof(*fire), PU_LEVEL, NULL);
- memcpy (fire, ::g->save_p, sizeof(*fire));
- ::g->save_p += sizeof(*fire);
- fire->sector = &::g->sectors[(int)fire->sector];
- fire->thinker.function.acp1 = (actionf_p1)T_FireFlicker;
- P_AddThinker (&fire->thinker);
- break;
- case tc_flash:
- PADSAVEP();
- flash = (lightflash_t*)DoomLib::Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
- memcpy (flash, ::g->save_p, sizeof(*flash));
- ::g->save_p += sizeof(*flash);
- flash->sector = &::g->sectors[(int)flash->sector];
- flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
- P_AddThinker (&flash->thinker);
- break;
- case tc_strobe:
- PADSAVEP();
- strobe = (strobe_t*)DoomLib::Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
- memcpy (strobe, ::g->save_p, sizeof(*strobe));
- ::g->save_p += sizeof(*strobe);
- strobe->sector = &::g->sectors[(int)strobe->sector];
- strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
- P_AddThinker (&strobe->thinker);
- break;
- case tc_glow:
- PADSAVEP();
- glow = (glow_t*)DoomLib::Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
- memcpy (glow, ::g->save_p, sizeof(*glow));
- ::g->save_p += sizeof(*glow);
- glow->sector = &::g->sectors[(int)glow->sector];
- glow->thinker.function.acp1 = (actionf_p1)T_Glow;
- P_AddThinker (&glow->thinker);
- break;
- default:
- I_Error ("Unknown tclass %i in savegame",tclass);
- }
- }
- }
- //
- // P_ArchiveSpecials
- //
- //
- // 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 = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- if (th->function.acv == (actionf_v)NULL)
- {
- for (i = 0; i < MAXCEILINGS;i++)
- if (::g->activeceilings[i] == (ceiling_t *)th)
- break;
-
- if (i<MAXCEILINGS)
- {
- *::g->save_p++ = tc_ceiling;
- PADSAVEP();
- ceiling = (ceiling_t *)::g->save_p;
- memcpy (ceiling, th, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
- }
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
- {
- *::g->save_p++ = tc_ceiling;
- PADSAVEP();
- ceiling = (ceiling_t *)::g->save_p;
- memcpy (ceiling, th, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = (sector_t *)(ceiling->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
- {
- *::g->save_p++ = tc_door;
- PADSAVEP();
- door = (vldoor_t *)::g->save_p;
- memcpy (door, th, sizeof(*door));
- ::g->save_p += sizeof(*door);
- door->sector = (sector_t *)(door->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_MoveFloor)
- {
- *::g->save_p++ = tc_floor;
- PADSAVEP();
- floor = (floormove_t *)::g->save_p;
- memcpy (floor, th, sizeof(*floor));
- ::g->save_p += sizeof(*floor);
- floor->sector = (sector_t *)(floor->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_PlatRaise)
- {
- *::g->save_p++ = tc_plat;
- PADSAVEP();
- plat = (plat_t *)::g->save_p;
- memcpy (plat, th, sizeof(*plat));
- ::g->save_p += sizeof(*plat);
- plat->sector = (sector_t *)(plat->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_LightFlash)
- {
- *::g->save_p++ = tc_flash;
- PADSAVEP();
- flash = (lightflash_t *)::g->save_p;
- memcpy (flash, th, sizeof(*flash));
- ::g->save_p += sizeof(*flash);
- flash->sector = (sector_t *)(flash->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
- {
- *::g->save_p++ = tc_strobe;
- PADSAVEP();
- strobe = (strobe_t *)::g->save_p;
- memcpy (strobe, th, sizeof(*strobe));
- ::g->save_p += sizeof(*strobe);
- strobe->sector = (sector_t *)(strobe->sector - ::g->sectors);
- continue;
- }
-
- if (th->function.acp1 == (actionf_p1)T_Glow)
- {
- *::g->save_p++ = tc_glow;
- PADSAVEP();
- glow = (glow_t *)::g->save_p;
- memcpy (glow, th, sizeof(*glow));
- ::g->save_p += sizeof(*glow);
- glow->sector = (sector_t *)(glow->sector - ::g->sectors);
- continue;
- }
- }
-
- // add a terminating marker
- *::g->save_p++ = tc_endspecials;
- }
- //
- // 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 = *::g->save_p++;
- switch (tclass)
- {
- case tc_endspecials:
- return; // end of list
-
- case tc_ceiling:
- PADSAVEP();
- ceiling = (ceiling_t*)DoomLib::Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL);
- memcpy (ceiling, ::g->save_p, sizeof(*ceiling));
- ::g->save_p += sizeof(*ceiling);
- ceiling->sector = &::g->sectors[(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*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, NULL);
- memcpy (door, ::g->save_p, sizeof(*door));
- ::g->save_p += sizeof(*door);
- door->sector = &::g->sectors[(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*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
- memcpy (floor, ::g->save_p, sizeof(*floor));
- ::g->save_p += sizeof(*floor);
- floor->sector = &::g->sectors[(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*)DoomLib::Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
- memcpy (plat, ::g->save_p, sizeof(*plat));
- ::g->save_p += sizeof(*plat);
- plat->sector = &::g->sectors[(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*)DoomLib::Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
- memcpy (flash, ::g->save_p, sizeof(*flash));
- ::g->save_p += sizeof(*flash);
- flash->sector = &::g->sectors[(int)flash->sector];
- flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
- P_AddThinker (&flash->thinker);
- break;
-
- case tc_strobe:
- PADSAVEP();
- strobe = (strobe_t*)DoomLib::Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
- memcpy (strobe, ::g->save_p, sizeof(*strobe));
- ::g->save_p += sizeof(*strobe);
- strobe->sector = &::g->sectors[(int)strobe->sector];
- strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
- P_AddThinker (&strobe->thinker);
- break;
-
- case tc_glow:
- PADSAVEP();
- glow = (glow_t*)DoomLib::Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
- memcpy (glow, ::g->save_p, sizeof(*glow));
- ::g->save_p += sizeof(*glow);
- glow->sector = &::g->sectors[(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);
- }
-
- }
- }
|