📄 g_game.c
字号:
//
// 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[KEY_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
//
void G_RecordDemo (char* name)
{
int i;
int maxsize;
usergame = false;
strcpy (demoname, name);
strcat (demoname, ".lmp");
sprintf(MsgText, "Record demo : %s\n", demoname);
WriteDebug(MsgText);
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;
demotype = DEMO_I;
demorecording = true;
}
//
// New Demo Recording stuff...
//
// Doom demos assume that the demo starts at the
// beginning of a level and that the normal level
// state will apply - any deviation from that
// and playback will be out of "sync". Synchronization
// information must be written out to the demo file
// so that the state of the entire game is saved
// Probably it should use the save game function to
// save the game state then save the demo data after
// it... A new extension of "DEM" should also be used.
//
// G_RecordDemo_II
//
void G_RecordDemo_II (char* name)
{
int i;
int maxsize;
usergame = false;
strcpy (demoname, name);
strcat (demoname, ".dem");
sprintf(MsgText, "Record demo II : %s\n", demoname);
WriteDebug(MsgText);
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;
demotype = DEMO_II;
demorecording = true;
}
void G_BeginRecording_II (void)
{
char name2[VERSIONSIZE];
char description[] = "WINDOOM: DEMO VERSION II";
int length;
int i;
save_p = demobuffer;
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++ = deathmatch;
*save_p++ = respawnparm;
*save_p++ = fastparm;
*save_p++ = nomonsters;
*save_p++ = consoleplayer;
*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 - demobuffer;
if (length > SAVEGAMESIZE)
I_Error ("Savegame buffer overrun");
M_WriteFile (demoname, demobuffer, length);
gameaction = ga_nothing;
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];
// }
// draw the pattern into the back screen
R_FillBackScreen ();
}
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];
demotype = DEMO_I;
}
//
// G_PlayDemo
//
int access( const char *path, int mode );
char* defdemoname;
boolean G_DeferedPlayDemo_II (char* name)
{
static char demofilename[128];
sprintf(demofilename, "%s.dem", name);
if (access(demofilename, 0) != 0)
return false;
sprintf(MsgText, "-playdemo2: %s\n", demofilename);
WriteDebug(MsgText);
defdemoname = demofilename;
gameaction = ga_playdemo;
demotype = DEMO_II;
return true;
}
void G_DoPlayDemo_II(void)
{
int length;
int i;
int a,b,c;
char vcheck[VERSIONSIZE];
skill_t skill;
int episode, map, dversion, tversion;
demotype = DEMO_II;
gameaction = ga_nothing;
sprintf(MsgText, "Playing demo II : %s\n", defdemoname);
WriteDebug(MsgText);
length = M_GetFileSize(defdemoname);
demobuffer = (unsigned char *)malloc(length);
demoend = demobuffer + length;
length = M_ReadFile(defdemoname, &demobuffer);
save_p = demobuffer + 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++;
deathmatch = *save_p++;
respawnparm = *save_p++;
fastparm = *save_p++;
nomonsters = *save_p++;
consoleplayer = *save_p++;
// for (i=0 ; i<MAXPLAYERS ; i++)
// playeringame[i] = *demo_p++;
if (playeringame[1])
{
netgame = true;
netdemo = true;
}
// 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
WriteDebug("Calling R_FillBackScreen...\n");
R_FillBackScreen();
WriteDebug("Calling R_DrawViewBorder...\n");
R_DrawViewBorder();
// tversion = VERSION;
// gameaction = ga_nothing;
// demobuffer = demo_p = W_CacheLumpName(defdemoname, PU_STATIC);
// if (demobuffer == NULL)
// {
// sprintf(MsgText,"Demo %s is not in the WAD...\n", defdemoname);
// WriteDebug(MsgText);
// gameaction = ga_nothing;
// return;
// }
demo_p = save_p;
/*
dversion = *demo_p;
if ( *demo_p++ != tversion)
{
sprintf(MsgText, "Demo version : %d.%d Game version : %d.%d\n",
dversion/100, dversion %100, VERSION/100, VERSION%100);
WriteDebug(MsgText);
gameaction = ga_nothing;
return;
}
*/
// 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;
}
void G_DeferedPlayDemo (char* name)
{
sprintf(MsgText, "-playdemo: %s\n", name);
WriteDebug(MsgText);
defdemoname = name;
gameaction = ga_playdemo;
demotype = DEMO_I;
}
void G_DoPlayDemo (void)
{
skill_t skill;
int i, episode, map, dversion, tversion;
demotype = DEMO_I;
tversion = VERSION;
gameaction = ga_nothing;
demobuffer = demo_p = W_CacheLumpName(defdemoname, PU_STATIC);
if (demobuffer == NULL)
{
sprintf(MsgText,"Demo %s is not in the WAD...\n", defdemoname);
WriteDebug(MsgText);
gameaction = ga_nothing;
return;
}
dversion = *demo_p;
if ( *demo_p++ != tversion)
{
sprintf(MsgText, "Demo version : %d.%d Game version : %d.%d\n",
dversion/100, dversion %100, VERSION/100, VERSION%100);
WriteDebug(MsgText);
gameaction = ga_nothing;
return;
}
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
//
boolean G_TimeDemo_II (char* name)
{
static char demofilename[128];
sprintf(demofilename, "%s.dem", name);
if (access(demofilename, 0) != 0)
return false;
nodrawers = M_CheckParm ("-nodraw");
noblit = M_CheckParm ("-noblit");
timingdemo = true;
singletics = true;
defdemoname = demofilename;
gameaction = ga_playdemo;
demotype = DEMO_II;
sprintf(MsgText, "Playing timedemo II %s -noblit %d -nodraw %d\n", name, noblit, nodrawers);
WriteDebug(MsgText);
return 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;
sprintf(MsgText, "Playing timedemo %s -noblit %d -nodraw %d\n", name, noblit, nodrawers);
WriteDebug(MsgText);
}
/*
===================
=
= 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;
WriteDebug("G_CheckDemoStatus...\n");
if (timingdemo)
{
endtime = I_GetTime ();
I_Error ("timed %i gametics in %i realtics : %d FPS" ,gametic, endtime-starttime, (gametic*TICRATE)/(endtime-starttime));
}
if (demoplayback)
{
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)
{
G_EndDemo();
I_Error ("Demo %s recorded",demoname);
}
return false;
}
void G_EndDemo_II()
{
*demo_p++ = DEMOMARKER;
M_AppendFile(demoname, demobuffer, demo_p - demobuffer);
Z_Free (demobuffer);
demorecording = false;
}
void G_EndDemo()
{
*demo_p++ = DEMOMARKER;
M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
Z_Free (demobuffer);
demorecording = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -