//Emacsstylemodeselect-*-C++-*-//////$Id:$////Copyright(C)1993-1996byidSoftware,Inc.////Thissourceisavailablefordistributionand/ormodification//onlyunderthetermsoftheDOOMSourceCodeLicenseas//publishedbyidSoftware.Allrightsreserved.////Thesourceisdistribute
dinthehopethatitwillbeuseful,//butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof//FITNESSFORAPARTICULARPURPOSE.SeetheDOOMSourceCodeLicense//formoredetails.////$Log:$////DESCRIPTION:none////staticconstcharrcsid[]="$Id:g_game.c,v1.81997/02/0322:45:09b1Ex
p$";#include<string.h>#include<stdlib.h>#include"doomdef.h"#include"doomstat.h"#include"z_zone.h"#include"f_finale.h"#include"m_argv.h"#include"m_misc.h"#include"m_menu.h"#include"m_random.h"#include"i_system.h"#include"p_setup.h"#include"p_saveg.h"#includ
e"p_tick.h"#include"d_main.h"#include"wi_stuff.h"#include"hu_stuff.h"#include"st_stuff.h"#include"am_map.h"//NeedsaccesstoLFB.#include"v_video.h"#include"w_wad.h"#include"p_local.h"#include"s_sound.h"//Data.#include"dstrings.h"#include"sounds.h"//SKYhandli
ng-stillthewrongplace.#include"r_data.h"#include"r_sky.h"#include"g_game.h"#defineSAVEGAMESIZE0x2c000#defineSAVESTRINGSIZE24booleanG_CheckDemoStatus(void);voidG_ReadDemoTiccmd(ticcmd_t*cmd);voidG_WriteDemoTiccmd(ticcmd_t*cmd);voidG_PlayerReborn(intplayer);
voidG_InitNew(skill_tskill,intepisode,intmap);voidG_DoReborn(intplayernum);voidG_DoLoadLevel(void);voidG_DoNewGame(void);voidG_DoLoadGame(void);voidG_DoPlayDemo(void);voidG_DoCompleted(void);voidG_DoVictory(void);voidG_DoWorldDone(void);voidG_DoSaveGame(vo
id);gameaction_tgameaction;gamestate_tgamestate;skill_tgameskill;booleanrespawnmonsters;intgameepisode;intgamemap;booleanpaused;booleansendpause;//sendapauseeventnextticbooleansendsave;//sendasaveeventnextticbooleanusergame;//oktosave/endgamebooleantimingd
emo;//iftrue,exitwithreportoncompletionbooleannodrawers;//forcomparativetimingpurposesbooleannoblit;//forcomparativetimingpurposesintstarttime;//forcomparativetimingpurposesbooleanviewactive;booleandeathmatch;//onlyifstartedasnetdeathbooleannetgame;//onlyt
rueifpacketsarebroadcastbooleanplayeringame[MAXPLAYERS];player_tplayers[MAXPLAYERS];intconsoleplayer;//playertakingeventsanddisplayingintdisplayplayer;//viewbeingdisplayedintgametic;intlevelstarttic;//gameticatlevelstartinttotalkills,totalitems,totalsecret
;//forintermissionchardemoname[32];booleandemorecording;booleandemoplayback;booleannetdemo;byte*demobuffer;byte*demo_p;byte*demoend;booleansingledemo;//quitafterplayingademofromcmdlinebooleanprecache=true;//iftrue,loadallgraphicsatstartwbstartstruct_twminf
o;//parmsforworldmap/intermissionshortconsistancy[MAXPLAYERS][BACKUPTICS];byte*savebuffer;////controls(havedefaults)//intkey_right;intkey_left;intkey_up;intkey_down;intkey_strafeleft;intkey_straferight;intkey_fire;intkey_use;intkey_strafe;intkey_speed;intm
ousebfire;intmousebstrafe;intmousebforward;intjoybfire;intjoybstrafe;intjoybuse;intjoybspeed;#defineMAXPLMOVE(forwardmove[1])#defineTURBOTHRESHOLD0x32fixed_tforwardmove[2]={0x19,0x32};fixed_tsidemove[2]={0x18,0x28};fixed_tangleturn[3]={640,1280,320};//+slo
wturn#defineSLOWTURNTICS6#defineNUMKEYS256booleangamekeydown[NUMKEYS];intturnheld;//foraccelerativeturningbooleanmousearray[4];boolean*mousebuttons=&mousearray[1];//allow[-1]//mousevaluesareusedonceintmousex;intmousey;intdclicktime;intdclickstate;intdclick
s;intdclicktime2;intdclickstate2;intdclicks2;//joystickvaluesarerepeatedintjoyxmove;intjoyymove;booleanjoyarray[5];boolean*joybuttons=&joyarray[1];//allow[-1]intsavegameslot;charsavedescription[32];#defineBODYQUESIZE32mobj_t*bodyque[BODYQUESIZE];intbodyque
slot;void*statcopy;//forstatisticsdriverintG_CmdChecksum(ticcmd_t*cmd){inti;intsum=0;for(i=0;i<sizeof(*cmd)/4-1;i++)sum+=((int*)cmd)[i];returnsum;}////G_BuildTiccmd//Buildsaticcmdfromalloftheavailableinputs//orreadsitfromthedemobuffer.//Ifrecordingademo,wr
iteitout//voidG_BuildTiccmd(ticcmd_t*cmd){inti;booleanstrafe;booleanbstrafe;intspeed;inttspeed;intforward;intside;ticcmd_t*base;base=I_BaseTiccmd();//empty,orexternaldrivermemcpy(cmd,base,sizeof(*cmd));cmd->consistancy=consistancy[consoleplayer][maketic%BA
CKUPTICS];strafe=gamekeydown[key_strafe]||mousebuttons[mousebstrafe]||joybuttons[joybstrafe];speed=gamekeydown[key_speed]||joybuttons[joybspeed];forward=side=0;//usetwostageaccelerativeturning//onthekeyboardandjoystickif(joyxmove<0||joyxmove>0||gamekeydown
[key_right]||gamekeydown[key_left])turnheld+=ticdup;elseturnheld=0;if(turnheld<SLOWTURNTICS)tspeed=2;//slowturnelsetspeed=speed;//letmovementkeyscanceleachotheroutif(strafe){if(gamekeydown[key_right]){//fprintf(stderr,"straferight\n");side+=sidemove[speed]
;}if(gamekeydown[key_left]){//fprintf(stderr,"strafeleft\n");side-=sidemove[speed];}if(joyxmove>0)side+=sidemove[speed];if(joyxmove<0)side-=sidemove[speed];}else{if(gamekeydown[key_right])cmd->angleturn-=angleturn[tspeed];if(gamekeydown[key_left])cmd->angl
eturn+=angleturn[tspeed];if(joyxmove>0)cmd->angleturn-=angleturn[tspeed];if(joyxmove<0)cmd->angleturn+=angleturn[tspeed];}if(gamekeydown[key_up]){//fprintf(stderr,"up\n");forward+=forwardmove[speed];}if(gamekeydown[key_down]){//fprintf(stderr,"down\n");for
ward-=forwardmove[speed];}if(joyymove<0)forward+=forwardmove[speed];if(joyymove>0)forward-=forwardmove[speed];if(gamekeydown[key_straferight])side+=sidemove[speed];if(gamekeydown[key_strafeleft])side-=sidemove[speed];//buttonscmd->chatchar=HU_dequeueChatCh
ar();if(gamekeydown[key_fire]||mousebuttons[mousebfire]||joybuttons[joybfire])cmd->buttons|=BT_ATTACK;if(gamekeydown[key_use]||joybuttons[joybuse]){cmd->buttons|=BT_USE;//cleardoubleclicksifhitusebuttondclicks=0;}//chainsawoverridesfor(i=0;i<NUMWEAPONS-1;i
++)if(gamekeydown['1'+i]){cmd->buttons|=BT_CHANGE;cmd->buttons|=i<<BT_WEAPONSHIFT;break;}//mouseif(mousebuttons[mousebforward])forward+=forwardmove[speed];//forwarddoubleclickif(mousebuttons[mousebforward]!=dclickstate&&dclicktime>1){dclickstate=mousebutto
ns[mousebforward];if(dclickstate)dclicks++;if(dclicks==2){cmd->buttons|=BT_USE;dclicks=0;}elsedclicktime=0;}else{dclicktime+=ticdup;if(dclicktime>20){dclicks=0;dclickstate=0;}}//strafedoubleclickbstrafe=mousebuttons[mousebstrafe]||joybuttons[joybstrafe];if
(bstrafe!=dclickstate2&&dclicktime2>1){dclickstate2=bstrafe;if(dclickstate2)dclicks2++;if(dclicks2==2){cmd->buttons|=BT_USE;dclicks2=0;}elsedclicktime2=0;}else{dclicktime2+=ticdup;if(dclicktime2>20){dclicks2=0;dclickstate2=0;}}forward+=mousey;if(strafe)sid
e+=mousex*2;elsecmd->angleturn-=mousex*0x8;mousex=mousey=0;if(forward>MAXPLMOVE)forward=MAXPLMOVE;elseif(forward<-MAXPLMOVE)forward=-MAXPLMOVE;if(side>MAXPLMOVE)side=MAXPLMOVE;elseif(side<-MAXPLMOVE)side=-MAXPLMOVE;cmd->forwardmove+=forward;cmd->sidemove+=
side;//specialbuttonsif(sendpause){sendpause=false;cmd->buttons=BT_SPECIAL|BTS_PAUSE;}if(sendsave){sendsave=false;cmd->buttons=BT_SPECIAL|BTS_SAVEGAME|(savegameslot<<BTS_SAVESHIFT);}}////G_DoLoadLevel//externgamestate_twipegamestate;voidG_DoLoadLevel(void)
{inti;//Settheskymap.//Firstthing,wehaveadummyskytexturename,//aflat.ThedataisintheWADonlybecause//welookforanactualindex,insteadofsimply//settingone.skyflatnum=R_FlatNumForName(SKYFLATNAME);//DOOMdeterminestheskytexturetobeused//dependingonthecurrentepiso
de,andthegameversion.if((gamemode==commercial)||(gamemode==pack_tnt)||(gamemode==pack_plut)){skytexture=R_TextureNumForName("SKY3");if(gamemap<12)skytexture=R_TextureNumForName("SKY1");elseif(gamemap<21)skytexture=R_TextureNumForName("SKY2");}levelstarttic
=gametic;//fortimecalculationif(wipegamestate==GS_LEVEL)wipegamestate=-1;//forceawipegamestate=GS_LEVEL;for(i=0;i<MAXPLAYERS;i++){if(playeringame[i]&&players[i].playerstate==PST_DEAD)players[i].playerstate=PST_REBORN;memset(players[i].frags,0,sizeof(player
s[i].frags));}P_SetupLevel(gameepisode,gamemap,0,gameskill);displayplayer=consoleplayer;//viewtheguyyouareplayingstarttime=I_GetTime();gameaction=ga_nothing;Z_CheckHeap();//clearcmdbuildingstuffmemset(gamekeydown,0,sizeof(gamekeydown));joyxmove=joyymove=0;
mousex=mousey=0;sendpause=sendsave=paused=false;memset(mousebuttons,0,sizeof(mousebuttons));memset(joybuttons,0,sizeof(joybuttons));}////G_Responder//Getinfoneededtomaketiccmd_tsfortheplayers.//booleanG_Responder(event_t*ev){//allowspymodechangesevenduring
thedemoif(gamestate==GS_LEVEL&&ev->type==ev_keydown&&ev->data1==KEY_F12&&(singledemo||!deathmatch)){//spymodedo{displayplayer++;if(displayplayer==MAXPLAYERS)displayplayer=0;}while(!playeringame[displayplayer]&&displayplayer!=consoleplayer);returntrue;}//an
yotherkeypopsupmenuifindemosif(gameaction==ga_nothing&&!singledemo&&(demoplayback||gamestate==GS_DEMOSCREEN)){if(ev->type==ev_keydown||(ev->type==ev_mouse&&ev->data1)||(ev->type==ev_joystick&&ev->data1)){M_StartControlPanel();returntrue;}returnfalse;}if(ga
mestate==GS_LEVEL){#if0if(devparm&&ev->type==ev_keydown&&ev->data1==';'){G_DeathMatchSpawnPlayer(0);returntrue;}#endifif(HU_Responder(ev))returntrue;//chatatetheeventif(ST_Responder(ev))returntrue;//statuswindowateitif(AM_Responder(ev))returntrue;//automap
ateit}if(gamestate==GS_FINALE){if(F_Responder(ev))returntrue;//finaleatetheevent}switch(ev->type){caseev_keydown:if(ev->data1==KEY_PAUSE){sendpause=true;returntrue;}if(ev->data1<NUMKEYS)gamekeydown[ev->data1]=true;returntrue;//eatkeydowneventscaseev_keyup:
if(ev->data1<NUMKEYS)gamekeydown[ev->data1]=false;returnfalse;//alwaysletkeyupeventsfilterdowncaseev_mouse:mousebuttons[0]=ev->data1&1;mousebuttons[1]=ev->data1&2;mousebuttons[2]=ev->data1&4;mousex=ev->data2*(mouseSensitivity+5)/10;mousey=ev->data3*(mouseS
ensitivity+5)/10;returntrue;//eateventscaseev_joystick:joybuttons[0]=ev->data1&1;joybuttons[1]=ev->data1&2;joybuttons[2]=ev->data1&4;joybuttons[3]=ev->data1&8;joyxmove=ev->data2;joyymove=ev->data3;returntrue;//eateventsdefault:break;}returnfalse;}////G_Tic
ker//Maketiccmd_tsfortheplayers.//voidG_Ticker(void){inti;intbuf;ticcmd_t*cmd;//doplayerrebornsifneededfor(i=0;i<MAXPLAYERS;i++)if(playeringame[i]&&players[i].playerstate==PST_REBORN)G_DoReborn(i);//dothingstochangethegamestatewhile(gameaction!=ga_nothing)
{switch(gameaction){casega_loadlevel:G_DoLoadLevel();break;casega_newgame:G_DoNewGame();break;casega_loadgame:G_DoLoadGame();break;casega_savegame:G_DoSaveGame();break;casega_playdemo:G_DoPlayDemo();break;casega_completed:G_DoCompleted();break;casega_victo
ry:F_StartFinale();break;casega_worlddone:G_DoWorldDone();break;casega_screenshot:M_ScreenShot();gameaction=ga_nothing;break;casega_nothing:break;}}//getcommands,checkconsistancy,//andbuildnewconsistancycheckbuf=(gametic/ticdup)%BACKUPTICS;for(i=0;i<MAXPLA
YERS;i++){if(playeringame[i]){cmd=&players[i].cmd;memcpy(cmd,&netcmds[i][buf],sizeof(ticcmd_t));if(demoplayback)G_ReadDemoTiccmd(cmd);if(demorecording)G_WriteDemoTiccmd(cmd);//checkforturbocheatsif(cmd->forwardmove>TURBOTHRESHOLD&&!(gametic&31)&&((gametic>
>5)&3)==i){staticcharturbomessage[80];externchar*player_names[4];sprintf(turbomessage,"%sisturbo!",player_names[i]);players[consoleplayer].message=turbomessage;}if(netgame&&!netdemo&&!(gametic%ticdup)){if(gametic>BACKUPTICS&&consistancy[i][buf]!=cmd->consi
stancy){I_Error("consistencyfailure(%ishouldbe%i)",cmd->consistancy,consistancy[i][buf]);}if(players[i].mo)consistancy[i][buf]=players[i].mo->x;elseconsistancy[i][buf]=rndindex;}}}//checkforspecialbuttonsfor(i=0;i<MAXPLAYERS;i++){if(playeringame[i]){if(pla
yers[i].cmd.buttons&BT_SPECIAL){switch(players[i].cmd.buttons&BT_SPECIALMASK){caseBTS_PAUSE:paused^=1;if(paused)S_PauseSound();elseS_ResumeSound();break;caseBTS_SAVEGAME:if(!savedescription[0])strcpy(savedescription,"NETGAME");savegameslot=(players[i].cmd.
buttons&BTS_SAVEMASK)>>BTS_SAVESHIFT;gameaction=ga_savegame;break;}}}}//domainactionsswitch(gamestate){caseGS_LEVEL:P_Ticker();ST_Ticker();AM_Ticker();HU_Ticker();break;caseGS_INTERMISSION:WI_Ticker();break;caseGS_FINALE:F_Ticker();break;caseGS_DEMOSCREEN:
D_PageTicker();break;}}////PLAYERSTRUCTUREFUNCTIONS//alsoseeP_SpawnPlayerinP_Things//////G_InitPlayer//Calledatthestart.//Calledbythegameinitializationfunctions.//voidG_InitPlayer(intplayer){player_t*p;//setupthesavedinfop=&players[player];//cleareverythin
gelsetodefaultsG_PlayerReborn(player);}////G_PlayerFinishLevel//Canwhenaplayercompletesalevel.//voidG_PlayerFinishLevel(intplayer){player_t*p;p=&players[player];memset(p->powers,0,sizeof(p->powers));memset(p->cards,0,sizeof(p->cards));p->mo->flags&=~MF_SHA
DOW;//cancelinvisibilityp->extralight=0;//cancelgunflashesp->fixedcolormap=0;//cancelirgoglesp->damagecount=0;//nopalettechangesp->bonuscount=0;}////G_PlayerReborn//Calledafteraplayerdies//almosteverythingisclearedandinitialized//voidG_PlayerReborn(intplay
er){player_t*p;inti;intfrags[MAXPLAYERS];intkillcount;intitemcount;intsecretcount;memcpy(frags,players[player].frags,sizeof(frags));killcount=players[player].killcount;itemcount=players[player].itemcount;secretcount=players[player].secretcount;p=&players[p
layer];memset(p,0,sizeof(*p));memcpy(players[player].frags,frags,sizeof(players[player].frags));players[player].killcount=killcount;players[player].itemcount=itemcount;players[player].secretcount=secretcount;p->usedown=p->attackdown=true;//don'tdoanythingi
mmediatelyp->playerstate=PST_LIVE;p->health=MAXHEALTH;p->readyweapon=p->pendingweapon=wp_pistol;p->weaponowned[wp_fist]=true;p->weaponowned[wp_pistol]=true;p->ammo[am_clip]=50;for(i=0;i<NUMAMMO;i++)p->maxammo[i]=maxammo[i];}////G_CheckSpot//Returnsfalseift
heplayercannotberespawned//atthegivenmapthing_tspot//becausesomethingisoccupyingit//voidP_SpawnPlayer(mapthing_t*mthing);booleanG_CheckSpot(intplayernum,mapthing_t*mthing){fixed_tx;fixed_ty;subsector_t*ss;unsignedan;mobj_t*mo;inti;if(!players[playernum].mo
){//firstspawnoflevel,beforecorpsesfor(i=0;i<playernum;i++)if(players[i].mo->x==mthing->x<<FRACBITS&&players[i].mo->y==mthing->y<<FRACBITS)returnfalse;returntrue;}x=mthing->x<<FRACBITS;y=mthing->y<<FRACBITS;if(!P_CheckPosition(players[playernum].mo,x,y))re
turnfalse;//flushanoldcorpseifneededif(bodyqueslot>=BODYQUESIZE)P_RemoveMobj(bodyque[bodyqueslot%BODYQUESIZE]);bodyque[bodyqueslot%BODYQUESIZE]=players[playernum].mo;bodyqueslot++;//spawnateleportfogss=R_PointInSubsector(x,y);an=(ANG45*(mthing->angle/45))>
>ANGLETOFINESHIFT;mo=P_SpawnMobj(x+20*finecosine[an],y+20*finesine[an],ss->sector->floorheight,MT_TFOG);if(players[consoleplayer].viewz!=1)S_StartSound(mo,sfx_telept);//don'tstartsoundonfirstframereturntrue;}////G_DeathMatchSpawnPlayer//Spawnsaplayeratoneo
ftherandomdeathmatchspots//calledatlevelloadandeachdeath//voidG_DeathMatchSpawnPlayer(intplayernum){inti,j;intselections;selections=deathmatch_p-deathmatchstarts;if(selections<4)I_Error("Only%ideathmatchspots,4required",selections);for(j=0;j<20;j++){i=P_Ra
ndom()%selections;if(G_CheckSpot(playernum,&deathmatchstarts[i])){deathmatchstarts[i].type=playernum+1;P_SpawnPlayer(&deathmatchstarts[i]);return;}}//nogoodspot,sotheplayerwillprobablygetstuckP_SpawnPlayer(&playerstarts[playernum]);}////G_DoReborn//voidG_D
oReborn(intplayernum){inti;if(!netgame){//reloadthelevelfromscratchgameaction=ga_loadlevel;}else{//respawnatthestart//firstdissasociatethecorpseplayers[playernum].mo->player=NULL;//spawnatrandomspotifindeathmatchif(deathmatch){G_DeathMatchSpawnPlayer(playe
rnum);return;}if(G_CheckSpot(playernum,&playerstarts[playernum])){P_SpawnPlayer(&playerstarts[playernum]);return;}//trytospawnatoneoftheotherplayersspotsfor(i=0;i<MAXPLAYERS;i++){if(G_CheckSpot(playernum,&playerstarts[i])){playerstarts[i].type=playernum+1;
//fakeasotherplayerP_SpawnPlayer(&playerstarts[i]);playerstarts[i].type=i+1;//restorereturn;}//he'sgoingtobeinsidesomething.Toobad.}P_SpawnPlayer(&playerstarts[playernum]);}}voidG_ScreenShot(void){gameaction=ga_screenshot;}//DOOMParTimesintpars[4][10]={{0}
,{0,30,75,120,90,165,180,180,30,165},{0,90,90,90,120,90,360,240,30,170},{0,90,45,90,150,90,90,165,30,135}};//DOOMIIParTimesintcpars[32]={30,90,120,120,90,150,120,120,270,90,//1-10210,150,150,150,210,150,420,150,210,150,//11-20240,150,180,150,150,300,330,42
0,300,180,//21-30120,30//31-32};////G_DoCompleted//booleansecretexit;externchar*pagename;voidG_ExitLevel(void){secretexit=false;gameaction=ga_completed;}//Here'sforthegermanedition.voidG_SecretExitLevel(void){//IFNOWOLF3DLEVELS,NOSECRETEXIT!if((gamemode==c
ommercial)&&(W_CheckNumForName("map31")<0))secretexit=false;elsesecretexit=true;gameaction=ga_completed;}voidG_DoCompleted(void){inti;gameaction=ga_nothing;for(i=0;i<MAXPLAYERS;i++)if(playeringame[i])G_PlayerFinishLevel(i);//takeawaycardsandstuffif(automap
active)AM_Stop();if(gamemode!=commercial)switch(gamemap){case8:gameaction=ga_victory;return;case9:for(i=0;i<MAXPLAYERS;i++)players[i].didsecret=true;break;}//#if0Hmmm-why?if((gamemap==8)&&(gamemode!=commercial)){//victorygameaction=ga_victory;return;}if((g
amemap==9)&&(gamemode!=commercial)){//exitsecretlevelfor(i=0;i<MAXPLAYERS;i++)players[i].didsecret=true;}//#endifwminfo.didsecret=players[consoleplayer].didsecret;wminfo.epsd=gameepisode-1;wminfo.last=gamemap-1;//wminfo.nextis0biased,unlikegamemapif(gamemo
de==commercial){if(secretexit)switch(gamemap){case15:wminfo.next=30;break;case31:wminfo.next=31;break;}elseswitch(gamemap){case31:case32:wminfo.next=15;break;default:wminfo.next=gamemap;}}else{if(secretexit)wminfo.next=8;//gotosecretlevelelseif(gamemap==9)
{//returningfromsecretlevelswitch(gameepisode){case1:wminfo.next=3;break;case2:wminfo.next=5;break;case3:wminfo.next=6;break;case4:wminfo.next=2;break;}}elsewminfo.next=gamemap;//gotonextlevel}wminfo.maxkills=totalkills;wminfo.maxitems=totalitems;wminfo.ma
xsecret=totalsecret;wminfo.maxfrags=0;if(gamemode==commercial)wminfo.partime=35*cpars[gamemap-1];elsewminfo.partime=35*pars[gameepisode][gamemap];wminfo.pnum=consoleplayer;for(i=0;i<MAXPLAYERS;i++){wminfo.plyr[i].in=playeringame[i];wminfo.plyr[i].skills=pl
ayers[i].killcount;wminfo.plyr[i].sitems=players[i].itemcount;wminfo.plyr[i].ssecret=players[i].secretcount;wminfo.plyr[i].stime=leveltime;memcpy(wminfo.plyr[i].frags,players[i].frags,sizeof(wminfo.plyr[i].frags));}gamestate=GS_INTERMISSION;viewactive=fals
e;automapactive=false;if(statcopy)memcpy(statcopy,&wminfo,sizeof(wminfo));WI_Start(&wminfo);}////G_WorldDone//voidG_WorldDone(void){gameaction=ga_worlddone;if(secretexit)players[consoleplayer].didsecret=true;if(gamemode==commercial){switch(gamemap){case15:
case31:if(!secretexit)break;case6:case11:case20:case30:F_StartFinale();break;}}}voidG_DoWorldDone(void){gamestate=GS_LEVEL;gamemap=wminfo.next+1;G_DoLoadLevel();gameaction=ga_nothing;viewactive=true;}////G_InitFromSavegame//Canbecalledbythestartupcodeorthe
menutask.//externbooleansetsizeneeded;voidR_ExecuteSetViewSize(void);charsavename[256];voidG_LoadGame(char*name){strcpy(savename,name);gameaction=ga_loadgame;}#defineVERSIONSIZE16voidG_DoLoadGame(void){intlength;inti;inta,b,c;charvcheck[VERSIONSIZE];gameac
tion=ga_nothing;length=M_ReadFile(savename,&savebuffer);save_p=savebuffer+SAVESTRINGSIZE;//skipthedescriptionfieldmemset(vcheck,0,sizeof(vcheck));sprintf(vcheck,"version%i",VERSION);if(strcmp(save_p,vcheck))return;//badversionsave_p+=VERSIONSIZE;gameskill=
*save_p++;gameepisode=*save_p++;gamemap=*save_p++;for(i=0;i<MAXPLAYERS;i++)playeringame[i]=*save_p++;//loadabaselevelG_InitNew(gameskill,gameepisode,gamemap);//getthetimesa=*save_p++;b=*save_p++;c=*save_p++;leveltime=(a<<16)+(b<<8)+c;//dearchiveallthemodif
icationsP_UnArchivePlayers();P_UnArchiveWorld();P_UnArchiveThinkers();P_UnArchiveSpecials();if(*save_p!=0x1d)I_Error("Badsavegame");//doneZ_Free(savebuffer);if(setsizeneeded)R_ExecuteSetViewSize();//drawthepatternintothebackscreenR_FillBackScreen();}////G_
SaveGame//Calledbythemenutask.//Descriptionisa24bytetextstring//voidG_SaveGame(intslot,char*description){savegameslot=slot;strcpy(savedescription,description);sendsave=true;}voidG_DoSaveGame(void){charname[100];charname2[VERSIONSIZE];char*description;intle
ngth;inti;if(M_CheckParm("-cdrom"))sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot);elsesprintf(name,SAVEGAMENAME"%d.dsg",savegameslot);description=savedescription;save_p=savebuffer=screens[1]+0x4000;memcpy(save_p,description,SAVESTRINGSIZE)
;save_p+=SAVESTRINGSIZE;memset(name2,0,sizeof(name2));sprintf(name2,"version%i",VERSION);memcpy(save_p,name2,VERSIONSIZE);save_p+=VERSIONSIZE;*save_p++=gameskill;*save_p++=gameepisode;*save_p++=gamemap;for(i=0;i<MAXPLAYERS;i++)*save_p++=playeringame[i];*sa
ve_p++=leveltime>>16;*save_p++=leveltime>>8;*save_p++=leveltime;P_ArchivePlayers();P_ArchiveWorld();P_ArchiveThinkers();P_ArchiveSpecials();*save_p++=0x1d;//consistancymarkerlength=save_p-savebuffer;if(length>SAVEGAMESIZE)I_Error("Savegamebufferoverrun");M