Iskhodnyy_kod_Doom
.pdfcase 31: wminfo.next = 31; break;
}
else
switch(gamemap)
{
case 31:
case 32: wminfo.next = 15; break; default: wminfo.next = gamemap;
} |
|
} |
|
else |
|
{ |
|
if (secretexit) |
|
wminfo.next = 8; |
// go to secret level |
else if (gamemap == 9) |
|
{ |
|
// returning from secret level |
|
switch (gameepisode) |
|
{ |
|
case 1: |
|
wminfo.next = 3; |
|
break; |
|
case 2: |
|
wminfo.next = 5; |
|
break; |
|
case 3: |
|
wminfo.next = 6; |
|
break; |
|
case 4: |
|
wminfo.next = 2; |
|
break; |
|
} |
|
} |
|
else |
|
wminfo.next = gamemap; |
// go to next level |
} |
|
wminfo.maxkills = totalkills; wminfo.maxitems = totalitems; wminfo.maxsecret = totalsecret; wminfo.maxfrags = 0;
if ( gamemode == commercial ) wminfo.partime = 35*cpars[gamemap-1];
else
wminfo.partime = 35*pars[gameepisode][gamemap]; wminfo.pnum = consoleplayer;
for (i=0 ; i<MAXPLAYERS ; i++)
{
wminfo.plyr[i].in = playeringame[i]; wminfo.plyr[i].skills = players[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 = false; automapactive = false;
if (statcopy)
memcpy (statcopy, &wminfo, sizeof(wminfo));
141
WI_Start (&wminfo);
}
//
// G_WorldDone
//
void G_WorldDone (void)
{
gameaction = ga_worlddone;
if (secretexit) players[consoleplayer].didsecret = true;
if ( gamemode == commercial )
{
switch |
(gamemap) |
{ |
|
case |
15: |
case |
31: |
if |
(!secretexit) |
|
break; |
case |
6: |
case |
11: |
case |
20: |
case |
30: |
F_StartFinale (); break;
}
}
}
void G_DoWorldDone (void)
{
gamestate = GS_LEVEL; gamemap = wminfo.next+1; G_DoLoadLevel (); gameaction = ga_nothing; viewactive = true;
}
//
//G_InitFromSavegame
//Can be called by the startup code or the menu task.
extern boolean setsizeneeded; void R_ExecuteSetViewSize (void);
char savename[256];
void G_LoadGame (char* name)
{
strcpy (savename, name); gameaction = ga_loadgame;
}
#define VERSIONSIZE |
16 |
void G_DoLoadGame (void) |
|
{ |
|
int |
length; |
int |
i; |
142
int |
a,b,c; |
char |
vcheck[VERSIONSIZE]; |
gameaction = ga_nothing;
length = M_ReadFile (savename, &savebuffer); save_p = savebuffer + SAVESTRINGSIZE;
// skip the description field memset (vcheck,0,sizeof(vcheck));
sprintf (vcheck,"version %i",VERSION); |
|
if (strcmp (save_p, vcheck)) |
|
return; |
// bad version |
save_p += VERSIONSIZE; |
|
gameskill = *save_p++; |
|
gameepisode = *save_p++; |
|
gamemap = *save_p++; |
|
for (i=0 ; i<MAXPLAYERS ; i++) |
|
playeringame[i] = *save_p++; |
|
// load a base level
G_InitNew (gameskill, gameepisode, gamemap);
//get the times a = *save_p++;
b = *save_p++; c = *save_p++;
leveltime = (a<<16) + (b<<8) + c;
//dearchive all the modifications P_UnArchivePlayers (); P_UnArchiveWorld (); P_UnArchiveThinkers (); P_UnArchiveSpecials ();
if (*save_p != 0x1d)
I_Error ("Bad savegame");
// done
Z_Free (savebuffer);
if (setsizeneeded) R_ExecuteSetViewSize ();
// draw the pattern into the back screen R_FillBackScreen ();
}
//
//G_SaveGame
//Called by the menu task.
//Description is a 24 byte text string
void G_SaveGame
( int |
slot, |
char* |
description ) |
{ |
|
savegameslot = slot;
strcpy (savedescription, description); sendsave = true;
}
143
void G_DoSaveGame (void)
{
char |
name[100]; |
char |
name2[VERSIONSIZE]; |
char* |
description; |
int |
length; |
int |
i; |
if (M_CheckParm("-cdrom")) sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot);
else
sprintf (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];
*save_p++ = leveltime>>16; *save_p++ = leveltime>>8; *save_p++ = leveltime;
P_ArchivePlayers ();
P_ArchiveWorld ();
P_ArchiveThinkers ();
P_ArchiveSpecials ();
*save_p++ = 0x1d; |
// consistancy marker |
length = save_p - savebuffer; if (length > SAVEGAMESIZE)
I_Error ("Savegame buffer overrun"); M_WriteFile (name, savebuffer, length); gameaction = ga_nothing; savedescription[0] = 0;
players[consoleplayer].message = GGSAVED;
// draw the pattern into the back screen R_FillBackScreen ();
}
//
//G_InitNew
//Can be called by the startup code or the menu task,
//consoleplayer, displayplayer, playeringame[] should be set.
skill_t |
d_skill; |
int |
d_episode; |
int |
d_map; |
void G_DeferedInitNew
( skill_t skill,
144
int |
episode, |
int |
map) |
{
d_skill = skill; d_episode = episode; d_map = map;
gameaction = ga_newgame;
}
void G_DoNewGame (void)
{
demoplayback = false; netdemo = false; netgame = false; deathmatch = false;
playeringame[1] = playeringame[2] = playeringame[3] = 0; respawnparm = false;
fastparm = false; nomonsters = false; consoleplayer = 0;
G_InitNew (d_skill, d_episode, d_map); gameaction = ga_nothing;
}
// The sky texture to be used instead of the F_SKY1 dummy.
extern int |
skytexture; |
void |
|
G_InitNew |
|
( skill_t |
skill, |
int |
episode, |
int |
map ) |
{ |
|
int |
i; |
if (paused)
{
paused = false; S_ResumeSound ();
}
if (skill > sk_nightmare) skill = sk_nightmare;
//This was quite messy with SPECIAL and commented parts.
//Supposedly hacks to make the latest edition work.
//It might not work properly.
if (episode < 1) episode = 1;
if ( gamemode == retail )
{
if (episode > 4) episode = 4;
}
else if ( gamemode == shareware )
{
if (episode > 1)
episode = 1; // only start episode 1 on shareware
}
else
145
{
if (episode > 3) episode = 3;
}
if |
(map |
< |
1) |
|
map |
= |
1; |
if |
( (map |
> 9) |
|
|
&& |
( gamemode != commercial) ) |
|
|
map = |
9; |
|
M_ClearRandom ();
if (skill == sk_nightmare || respawnparm ) respawnmonsters = true;
else
respawnmonsters = false;
if (fastparm || (skill == sk_nightmare && gameskill != sk_nightmare) )
{
for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) states[i].tics >>= 1;
mobjinfo[MT_BRUISERSHOT].speed = 20*FRACUNIT; mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT; mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT;
}
else if (skill != sk_nightmare && gameskill == sk_nightmare)
{
for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) states[i].tics <<= 1;
mobjinfo[MT_BRUISERSHOT].speed = 15*FRACUNIT; mobjinfo[MT_HEADSHOT].speed = 10*FRACUNIT; mobjinfo[MT_TROOPSHOT].speed = 10*FRACUNIT;
}
// force players to be initialized upon first level load for (i=0 ; i<MAXPLAYERS ; i++)
players[i].playerstate = PST_REBORN;
usergame = true; |
// will be set false if a demo |
paused = false; |
|
demoplayback = false; |
|
automapactive = false; |
|
viewactive = true; |
|
gameepisode = episode; |
|
gamemap = map; |
|
gameskill = skill; |
|
viewactive = true; |
|
// set the sky map for the episode if ( gamemode == commercial)
{
skytexture = R_TextureNumForName ("SKY3"); if (gamemap < 12)
skytexture = R_TextureNumForName ("SKY1");
else
if (gamemap < 21)
skytexture = R_TextureNumForName ("SKY2");
}
else
146
switch (episode)
{
case 1:
skytexture = R_TextureNumForName ("SKY1"); break;
case 2:
skytexture = R_TextureNumForName ("SKY2"); break;
case 3:
skytexture = R_TextureNumForName ("SKY3");
break; |
|
case 4: |
// Special Edition sky |
skytexture = R_TextureNumForName ("SKY4"); |
|
break; |
|
} |
|
G_DoLoadLevel (); |
|
} |
|
// |
|
// DEMO RECORDING |
|
// |
|
#define DEMOMARKER |
0x80 |
void G_ReadDemoTiccmd (ticcmd_t* cmd)
{
if (*demo_p == DEMOMARKER)
{
// end of demo data stream G_CheckDemoStatus (); return;
}
cmd->forwardmove = ((signed char)*demo_p++); cmd->sidemove = ((signed char)*demo_p++); cmd->angleturn = ((unsigned char)*demo_p++)<<8; cmd->buttons = (unsigned char)*demo_p++;
}
void G_WriteDemoTiccmd (ticcmd_t* cmd)
{ |
|
if (gamekeydown[’q’]) |
// press q to end demo recording |
G_CheckDemoStatus (); |
|
*demo_p++ = cmd->forwardmove; |
|
*demo_p++ = cmd->sidemove; *demo_p++ = (cmd->angleturn+128)>>8; *demo_p++ = cmd->buttons;
demo_p -= 4;
if (demo_p > demoend - 16)
{
// no more space G_CheckDemoStatus (); return;
}
G_ReadDemoTiccmd (cmd); |
// make SURE it is exactly the same |
}
//
// G_RecordDemo
//
147
void G_RecordDemo (char* name)
{ |
|
int |
i; |
int |
maxsize; |
usergame = false;
strcpy (demoname, name); strcat (demoname, ".lmp"); maxsize = 0x20000;
i = M_CheckParm ("-maxdemo"); if (i && i<myargc-1)
maxsize = atoi(myargv[i+1])*1024; demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL); demoend = demobuffer + maxsize;
demorecording = true;
}
void G_BeginRecording (void)
{
int |
i; |
demo_p = demobuffer;
*demo_p++ = VERSION; *demo_p++ = gameskill; *demo_p++ = gameepisode; *demo_p++ = gamemap; *demo_p++ = deathmatch; *demo_p++ = respawnparm; *demo_p++ = fastparm; *demo_p++ = nomonsters; *demo_p++ = consoleplayer;
for (i=0 ; i<MAXPLAYERS ; i++) *demo_p++ = playeringame[i];
}
//
// G_PlayDemo
//
char* defdemoname;
void G_DeferedPlayDemo (char* name)
{
defdemoname = name; gameaction = ga_playdemo;
}
void G_DoPlayDemo (void)
{ |
|
skill_t skill; |
|
int |
i, episode, map; |
gameaction = ga_nothing;
demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); if ( *demo_p++ != VERSION)
{
fprintf( stderr, "Demo is from a different game version!\n"); gameaction = ga_nothing;
return;
}
148
skill = *demo_p++; episode = *demo_p++; map = *demo_p++; deathmatch = *demo_p++;
respawnparm = *demo_p++; fastparm = *demo_p++; nomonsters = *demo_p++; consoleplayer = *demo_p++;
for (i=0 ; i<MAXPLAYERS ; i++) playeringame[i] = *demo_p++;
if (playeringame[1])
{
netgame = true; netdemo = true;
}
// don’t spend a lot of time in loadlevel precache = false;
G_InitNew (skill, episode, map); precache = true;
usergame = false; demoplayback = true;
}
//
// G_TimeDemo
//
void G_TimeDemo (char* name)
{
nodrawers = M_CheckParm ("-nodraw"); noblit = M_CheckParm ("-noblit"); timingdemo = true;
singletics = true;
defdemoname = name; gameaction = ga_playdemo;
}
/*
===================
=
=G_CheckDemoStatus
=Called after a death or level completion to allow demos to be cleaned up
=Returns true if a new demo loop action will take place
===================
*/
boolean G_CheckDemoStatus (void)
{ |
|
int |
endtime; |
if (timingdemo)
{
endtime = I_GetTime ();
I_Error ("timed %i gametics in %i realtics",gametic , endtime-starttime);
}
if (demoplayback)
{
149
if (singledemo) I_Quit ();
Z_ChangeTag (demobuffer, PU_CACHE); demoplayback = false;
netdemo = false; netgame = false; deathmatch = false;
playeringame[1] = playeringame[2] = playeringame[3] = 0; respawnparm = false;
fastparm = false; nomonsters = false; consoleplayer = 0; D_AdvanceDemo (); return true;
}
if (demorecording)
{
*demo_p++ = DEMOMARKER;
M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
Z_Free (demobuffer);
demorecording = false;
I_Error ("Demo %s recorded",demoname);
}
return false;
}
5.2g game.h
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------
//
//$Id:$
//Copyright (C) 1993-1996 by id Software, Inc.
//This program 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 2
//of the License, or (at your option) any later version.
//
//This program 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.
//
//DESCRIPTION:
//Duh.
//
//-----------------------------------------------------------------------------
#ifndef __G_GAME__ #define __G_GAME__
#include "doomdef.h" #include "d_event.h"
150