Add basic demo recording with M_WriteFile

This commit is contained in:
Lephenixnoir 2021-10-01 11:48:33 +02:00
parent 4605dc94f4
commit 073f1ba9b0
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
9 changed files with 106 additions and 18 deletions

4
README
View File

@ -34,10 +34,6 @@ Status for other games:
-> HellRaiser: not tested
-> Freedoom phase 1: E1 works, E2 crashes
UI improvements TODO:
* Better keyboard layout (including more keys, eg. Run)
* Edit messages accordingly ("press y"/etc)
Technical support TODO:
* Built-in overclocking?
* Auto frameskip?

View File

@ -543,7 +543,7 @@ void UI_Controls(void)
int UI_Main(CGD_WADFileInfo *wads, int wad_count, int *dev_info, int *use_mmap,
int *startmap, int *startepisode, int *trustunaligned,
int *autostart, int *enabledemos, int *enable2MBline)
int *autostart, int *enabledemos, int *enable2MBline, int *recorddemo)
{
Layout l;
Layout_Init(&l);
@ -588,6 +588,8 @@ int UI_Main(CGD_WADFileInfo *wads, int wad_count, int *dev_info, int *use_mmap,
Layout_Spacing(&l, 10);
if(enable2MBline)
Layout_Checkbox(&l, "Use experimental RAM:", enable2MBline);
int i_demo = Layout_Text(&l, "Record demo:",
(*recorddemo < 0) ? "None" : "DEMO%02d.lmp", *recorddemo);
int i_controls = Layout_Text(&l, "Customize controls...", "");
int i_advanced = Layout_Text(&l, "Advanced options...", "");
Layout_EndFrame(&l);
@ -597,13 +599,14 @@ int UI_Main(CGD_WADFileInfo *wads, int wad_count, int *dev_info, int *use_mmap,
GetKey(&key);
if(Layout_Event(&l, key)) {
/* Autostart when changing starting episode/map */
/* Set autostart when changing starting episode/map */
int startparam = (l.focus == wad_count || l.focus == wad_count+1);
int changekey = (key == KEY_CTRL_EXE || key == KEY_CTRL_LEFT ||
key == KEY_CTRL_RIGHT);
if(startparam && changekey)
*autostart = 1;
}
/* Title screen options */
else if(key == KEY_CTRL_EXE && l.focus == i_title) {
if (!*autostart && *enabledemos)
*autostart = 1;
@ -612,12 +615,21 @@ int UI_Main(CGD_WADFileInfo *wads, int wad_count, int *dev_info, int *use_mmap,
else
*autostart = 0, *enabledemos = 0;
}
/* Submenus */
else if(key == KEY_CTRL_EXE && l.focus == i_controls) {
UI_Controls();
}
else if(key == KEY_CTRL_EXE && l.focus == i_advanced) {
UI_AdvancedOptions(dev_info, use_mmap, trustunaligned);
}
/* Select demo file to save */
else if(key == KEY_CTRL_LEFT && l.focus == i_demo) {
*recorddemo -= (*recorddemo >= 0);
}
else if(key == KEY_CTRL_RIGHT && l.focus == i_demo) {
*recorddemo += (*recorddemo < 99);
}
/* Start game */
else if(key == KEY_CTRL_EXE && l.focus < wad_count) {
return l.focus;
}

View File

@ -71,7 +71,8 @@ int UI_Main(CGD_WADFileInfo *wads, int wad_count,
int *trustunaligned, /* Trust unaligned lumps */
int *autostart, /* Skip title screen, straight to gameplay */
int *enabledemos, /* Enable demos on the title screen */
int *enable2MBline /* Enable memory past the 2MB line */
int *enable2MBline, /* Enable memory past the 2MB line */
int *recorddemo /* Number of demo to record (-1 for none) */
);
/* Show an error with custom formatting. */

View File

@ -8,6 +8,7 @@
#include "m_misc.h"
#include "d_main.h"
#include "v_video.h"
#include "g_game.h"
#include "cgdoom-alloc.h"
#include "cgdoom-kbd.h"
@ -127,6 +128,7 @@ int CGD_SingleEpisodeUltimate = 0;
int CGD_2MBLineMemory = 0;
int CGD_Frameskip = 1;
const char *CGD_WADFileName = NULL;
const char *CGD_RecordDemoName = NULL;
/* Delayed file accesses */
CGD_DelayedFileWrite CGD_DelayedSaves[6] = { 0 };
@ -583,6 +585,7 @@ int main(void)
int wad_count = FindWADs(wads, 16);
int dev_info = 0;
int recorddemo = -1;
/* Set initial keyboard layout to thumbs-only */
CGD_LoadKeymap(CGD_Keymap_ThumbsOnly);
@ -600,7 +603,7 @@ int main(void)
int choice = UI_Main(wads, wad_count, &dev_info, &CGD_WADMethod,
&startmap, &startepisode, &CGD_TrustUnalignedLumps, &autostart_,
&CGD_EnableDemos, enable_2MBline);
&CGD_EnableDemos, enable_2MBline, &recorddemo);
if(choice < 0)
return 1;
@ -712,6 +715,13 @@ int main(void)
/* Initialize the PRAM allocator */
CGD_PRAM_Init(PRAM0_alloc_start, PRAM0_END);
/* Set up demo recording for this session */
if(recorddemo >= 0) {
static char demoname[20];
sprintf(demoname, "DEMO%02d", recorddemo);
CGD_RecordDemoName = demoname;
}
memset(VRAM, 0, WIDTH*HEIGHT*2);
D_DoomMain();

View File

@ -71,6 +71,8 @@ extern int startmap, startepisode;
extern const char *CGD_WADFileName;
/* Save Game operations delayed until closing the add-in (one per save) */
extern CGD_DelayedFileWrite CGD_DelayedSaves[6];
/* Name of record demo file */
extern const char *CGD_RecordDemoName;
// Keyboard interface.

View File

@ -258,6 +258,9 @@ extern boolean demorecording;
void D_DoomLoop (void)
{
if (demorecording)
G_BeginRecording ();
I_InitGraphics ();
while (!fuck)
@ -278,7 +281,8 @@ void D_DoomLoop (void)
if(!(gametic % (CGD_Frameskip + 1)))
D_Display ();
}
// I_ShutdownGraphics();
G_CheckDemoStatus();
Z_Free(lumpinfo);
CGD_PRAM_Free(lumpcache);
I_ShutdownGraphics();
@ -556,6 +560,9 @@ void D_DoomMain()
ST_Init ();
printf ("Engage... \n");
if (CGD_RecordDemoName)
G_RecordDemo(CGD_RecordDemoName);
if (autostart)
G_DeferedInitNew (startskill, startepisode, startmap);
else

View File

@ -121,13 +121,14 @@ int gametic;
int levelstarttic; // gametic at level start
int totalkills, totalitems, totalsecret; // for intermission
//char demoname[32];
boolean demoplayback;
boolean netdemo = 0;
char demoname[32];
boolean demorecording;
boolean demoplayback;
boolean netdemo = 0;
byte* demobuffer;
byte* demo_p;
byte* demoend;
boolean singledemo; // quit after playing a demo from cmdline
boolean singledemo; // quit after playing a demo from cmdline
boolean precache = false; // if true, load all graphics at start
@ -501,6 +502,9 @@ void G_Ticker (void)
else
G_BuildTiccmd (cmd);
if (demorecording)
G_WriteDemoTiccmd (cmd);
if (players[0].cmd.buttons & BT_SPECIAL)
{
switch (players[0].cmd.buttons & BT_SPECIALMASK)
@ -1257,21 +1261,22 @@ void G_ReadDemoTiccmd (ticcmd_t* cmd)
void G_WriteDemoTiccmd (ticcmd_t* cmd)
{
if (gamekeydown['q']) // press q to end demo recording
if (gamekeydown[KEY_ESCAPE]) // press MENU to end demo recording
G_CheckDemoStatus ();
*demo_p++ = (byte)cmd->forwardmove;
*demo_p++ = (byte)cmd->sidemove;
*demo_p++ = (byte)((cmd->angleturn+128)>>8);
*demo_p++ = (byte)cmd->buttons;
demo_p -= 4;
if (demo_p > demoend - 16)
// demo_p -= 4;
if (demo_p > demoend - 12)
{
// no more space
G_CheckDemoStatus ();
return;
}
G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same
// G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same
cmd->angleturn = demo_p[-2] << 8;
}
@ -1279,6 +1284,43 @@ void G_WriteDemoTiccmd (ticcmd_t* cmd)
//
// G_RecordDemo
//
void G_RecordDemo (const char* name)
{
int maxsize;
usergame = false;
strcpy (demoname, name);
strcat (demoname, ".lmp");
/* CGDoom: Maximum is 64 kiB instead of 128 kiB */
maxsize = 0x10000;
demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL);
if (demobuffer) {
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];
}
//
@ -1389,7 +1431,16 @@ boolean G_CheckDemoStatus (void)
return true;
}
return false;
if (demorecording)
{
*demo_p++ = DEMOMARKER;
M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
Z_Free (demobuffer);
demorecording = false;
printf ("Demo %s recorded", demoname);
}
return false;
}

View File

@ -51,6 +51,10 @@ void G_DoLoadGame (void);
void G_LoadGame (int slot);
void G_SaveGame (int slot, char* description);
void G_RecordDemo (const char* name);
void G_BeginRecording (void);
void G_PlayDemo (char* name);
void G_TimeDemo (char* name);
boolean G_CheckDemoStatus (void);

View File

@ -186,6 +186,8 @@ int toupper_int(int i)
//
// I_Error
//
extern boolean demorecording;
void I_Error (const char *error, ...)
{
va_list args;
@ -199,6 +201,9 @@ void I_Error (const char *error, ...)
va_start(args, error);
#endif
if (demorecording)
G_CheckDemoStatus();
I_ShutdownGraphics();
UI_Error(error, args);
I_ReinitAfterError();