Add demo replay

This commit is contained in:
Lephenixnoir 2021-10-01 23:10:49 +02:00
parent 05968fe5be
commit a9851c2c7c
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
8 changed files with 143 additions and 37 deletions

View File

@ -392,7 +392,7 @@ int Layout_Event(Layout *l, int key)
return 0;
}
void UI_AdvancedOptions(CGDoom_Options *o)
static void UI_AdvancedOptions(CGDoom_Options *o)
{
Layout l;
Layout_Init(&l);
@ -438,7 +438,7 @@ void UI_AdvancedOptions(CGDoom_Options *o)
}
}
void UI_Controls(CGDoom_Keymap map)
static void UI_Controls(CGDoom_Keymap map)
{
int focus_x=0, focus_y=-1;
int dflt = 0;
@ -549,7 +549,41 @@ void UI_Controls(CGDoom_Keymap map)
}
}
int UI_Main(CGDoom_FileInfo *wads, int wad_count, CGDoom_Options *o,
static int UI_DemoSelection(CGDoom_FileInfo *demos, int demo_count)
{
Layout l;
Layout_Init(&l);
while(1)
{
Bdisp_AllClr_VRAM();
Layout_StartFrame(&l);
Layout_CenteredText(&l, "Select a demo file");
Layout_Spacing(&l, 10);
for(int i = 0; i < demo_count; i++)
Layout_Text(&l, demos[i].name, "(%dk)", demos[i].size >> 10);
Layout_EndFrame(&l);
Bdisp_PutDisp_DD();
int key;
GetKey(&key);
if(Layout_Event(&l, key))
{}
else if(key == KEY_CTRL_EXIT)
return -1;
else if(key == KEY_CTRL_EXE) {
return l.focus;
}
}
}
CGDoom_FileInfo *UI_Main(
CGDoom_FileInfo *wads, int wad_count,
CGDoom_FileInfo *demos, int demo_count,
CGDoom_Options *o,
int *startmap, int *startepisode, int *recorddemo,
int allow_experimental_memory)
{
@ -602,8 +636,12 @@ int UI_Main(CGDoom_FileInfo *wads, int wad_count, CGDoom_Options *o,
if(allow_experimental_memory)
Layout_Checkbox(&l, "Use experimental RAM:",
&o->EnableExperimentalMemory);
int i_demo = Layout_Text(&l, "Record demo:",
(*recorddemo < 0) ? "None" : "DEMO%02d.lmp", *recorddemo);
int i_demo = Layout_Text(&l, "Record on demo slot:",
(*recorddemo < 0) ? "None >" : "< %d%s", *recorddemo,
(*recorddemo < 99) ? " >" : "");
int i_replay = -1;
if(demo_count > 0)
i_replay = Layout_Text(&l, "Replay demo...", "");
int i_controls = Layout_Text(&l, "Customize controls...", "");
int i_advanced = Layout_Text(&l, "Advanced options...", "");
Layout_EndFrame(&l);
@ -626,6 +664,11 @@ int UI_Main(CGDoom_FileInfo *wads, int wad_count, CGDoom_Options *o,
else if(key == KEY_CTRL_RIGHT && l.focus == i_title)
title += (title < TS_FULL);
/* Submenus */
else if(key == KEY_CTRL_EXE && l.focus == i_replay) {
int n = UI_DemoSelection(demos, demo_count);
if(n >= 0)
return &demos[n];
}
else if(key == KEY_CTRL_EXE && l.focus == i_controls) {
UI_Controls(o->Keymap);
}
@ -641,7 +684,7 @@ int UI_Main(CGDoom_FileInfo *wads, int wad_count, CGDoom_Options *o,
}
/* Start game */
else if(key == KEY_CTRL_EXE && l.focus < wad_count) {
return l.focus;
return &wads[l.focus];
}
if(*startmap < 1)
@ -653,7 +696,7 @@ int UI_Main(CGDoom_FileInfo *wads, int wad_count, CGDoom_Options *o,
o->EnableDemos = (title == TS_FULL);
}
return -1;
return NULL;
}
static int isspace_(int c)
@ -661,7 +704,7 @@ static int isspace_(int c)
return (c == ' ' || c == '\t' || c == '\n');
}
void UI_Error(const char *fmt, va_list args)
void UI_Errorv(const char *fmt, va_list args)
{
char message[256], *str=message;
vsnprintf(message, 256, fmt, args);
@ -715,6 +758,14 @@ void UI_Error(const char *fmt, va_list args)
GetKey(&key);
}
void UI_Error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
UI_Errorv(fmt, args);
va_end(args);
}
void UI_DelayedWrites(CGDoom_DelayedFileWrite const *dfw, int count,
int current_file, int current_file_done)
{

View File

@ -64,7 +64,9 @@ int Layout_Event(Layout *l, int key);
/* Larger-scale functions. */
/* Show the program's main screen; returns index of selected WAD file. */
int UI_Main(CGDoom_FileInfo *wads, int wad_count,
CGDoom_FileInfo *UI_Main(
CGDoom_FileInfo *wads, int wad_count,
CGDoom_FileInfo *demos, int demo_count,
CGDoom_Options *options,
int *startmap, /* Warp to this map (autostart only) */
int *startepisode, /* Warp to this episode (autostart only) */
@ -73,7 +75,8 @@ int UI_Main(CGDoom_FileInfo *wads, int wad_count,
);
/* Show an error with custom formatting. */
void UI_Error(const char *fmt, va_list args);
void UI_Error(const char *fmt, ...);
void UI_Errorv(const char *fmt, va_list args);
/* Show a file save with a progress bar. */
void UI_DelayedWrites(CGDoom_DelayedFileWrite const *dfw, int count,

View File

@ -128,7 +128,8 @@ int CGD_SingleEpisodeUltimate = 0;
int CGD_2MBLineMemory = 0;
int CGD_Frameskip = 1;
const char *CGD_WADFileName = NULL;
const char *CGD_RecordDemoName = NULL;
int CGD_RecordDemoSlot = -1;
int CGD_PlayDemoOnly = 0;
/* Delayed file accesses */
CGDoom_DelayedFileWrite CGD_DelayedSaves[CGD_DELAYEDSAVES_COUNT] = { 0 };
@ -395,14 +396,14 @@ int Flash_ReadFile(void *buf, int size, int readpos)
return iRet;
}
/* Find WAD files in the filesystem. */
int FindWADs(CGDoom_FileInfo *files, int max)
/* Find files in the filesystem based on a pattern. */
static int FindFiles(const uint16_t *wildcard, CGDoom_FileInfo *files, int max)
{
uint16_t path[32];
Bfile_FileInfo info;
int sd, rc, total=0;
rc = Bfile_FindFirst(u"\\\\fls0\\*.wad", &sd, path, &info);
rc = Bfile_FindFirst(wildcard, &sd, path, &info);
while(rc != -16 && total < max)
{
@ -628,8 +629,6 @@ int main(void)
extern int startepisode;
startmap = 1;
startepisode = 1;
/* Don't record demos by default */
int recorddemo = -1;
//---
// Run main menu and apply settings
@ -637,12 +636,39 @@ int main(void)
/* Look for WAD files at the root of the filesystem */
CGDoom_FileInfo wads[16];
int wad_count = FindWADs(wads, 16);
int wad_count = FindFiles(u"\\\\fls0\\*.wad", wads, 16);
int choice = UI_Main(wads, wad_count, &CGD_Options,
&startmap, &startepisode, &recorddemo, allow_experimental_RAM);
if(choice < 0)
return 1;
/* Look for demo files to replay, also at the root */
CGDoom_FileInfo demos[32];
int demo_count = FindFiles(u"\\\\fls0\\*_demo*.lmp", demos, 32);
CGDoom_FileInfo *selection = UI_Main(wads, wad_count, demos, demo_count,
&CGD_Options, &startmap, &startepisode, &CGD_RecordDemoSlot,
allow_experimental_RAM);
int choice = -1;
if(selection >= demos && selection < demos + demo_count) {
/* Find the WAD file with the correct name */
for(int i = 0; i < wad_count; i++) {
int len = strlen(wads[i].name) - 4; /* omit ".wad" */
if(!strncmp(selection->name, wads[i].name, len)
&& !strncmp(selection->name + len, "_demo", 5)) {
choice = i;
break;
}
}
if(choice == -1) {
UI_Error("The WAD file for %s has been removed or renamed!",
selection->name);
return 1;
}
G_DeferedPlayDemoFile(selection->name);
CGD_PlayDemoOnly = 1;
}
else if(selection >= wads && selection < wads + wad_count) {
choice = selection - wads;
}
else return 1;
/* Override parameters unavailable on the SDL2 build */
#ifdef CG_EMULATOR
@ -766,13 +792,6 @@ 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

@ -103,8 +103,10 @@ extern int CGD_SingleEpisodeUltimate;
extern int CGD_Frameskip;
/* WAD file name (without .wad), used to name save and demo files */
extern const char *CGD_WADFileName;
/* Name of record demo file */
extern const char *CGD_RecordDemoName;
/* Slot of demo file to record */
extern int CGD_RecordDemoSlot;
/* Whether we're only playing a demo and leaving */
extern int CGD_PlayDemoOnly;
//---
// Control functions (mapped to special keys)

View File

@ -557,10 +557,16 @@ void D_DoomMain()
ST_Init ();
printf ("Engage... \n");
if (CGD_RecordDemoName)
G_RecordDemo(CGD_RecordDemoName);
if (CGD_RecordDemoSlot >= 0) {
static char filename[32];
sprintf(filename, "%s_demo%02d", CGD_WADFileName, CGD_RecordDemoSlot);
G_RecordDemo(filename);
}
if (autostart)
/* CGDoom: Demo file was specified from main menu */
if (gameaction == ga_playdemo)
{}
else if (autostart)
G_DeferedInitNew (startskill, startepisode, startmap);
else
D_StartTitle ();

View File

@ -1296,8 +1296,8 @@ void G_RecordDemo (const char* name)
usergame = false;
strcpy (demoname, name);
strcat (demoname, ".lmp");
/* CGDoom: Maximum is 64 kiB instead of 128 kiB */
maxsize = 0x10000;
/* CGDoom: Maximum is 64 kiB instead of 128 kiB to save RAM */
maxsize = CGD_Options.EnableExperimentalMemory ? 0x20000 : 0x10000;
demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL);
if (demobuffer) {
@ -1333,20 +1333,38 @@ void G_BeginRecording (void)
//
char* defdemoname;
char* defdemofilename;
void G_DeferedPlayDemo (char* name)
{
defdemoname = name;
defdemofilename = NULL;
gameaction = ga_playdemo;
}
void G_DeferedPlayDemoFile (char* name)
{
defdemoname = NULL;
defdemofilename = name;
gameaction = ga_playdemo;
}
void G_DoPlayDemo (void)
{
skill_t skill;
int i, episode, map;
gameaction = ga_nothing;
demobuffer = demo_p = (byte *)W_CacheLumpNameConst (defdemoname, PU_STATIC);
if (defdemoname)
{
demobuffer = demo_p = (byte *)W_CacheLumpNameConst(defdemoname, PU_STATIC);
}
else if (defdemofilename)
{
demobuffer = NULL;
M_ReadFile(defdemofilename, &demobuffer, 1);
demo_p = demobuffer;
}
/* CGDoom: We have old WADs with demos at versions 108 and 109. The decoding
work similarly, it's probably enemy position/AI that mess up */
@ -1422,6 +1440,12 @@ boolean G_CheckDemoStatus (void)
if (demoplayback)
{
if(CGD_PlayDemoOnly)
{
fuck = true;
return true;
}
Z_ChangeTag (demobuffer, PU_CACHE);
demoplayback = false;
netdemo = false;

View File

@ -41,6 +41,7 @@ void G_InitNew (skill_t skill, int episode, int map);
void G_DeferedInitNew (skill_t skill, int episode, int map);
void G_DeferedPlayDemo (char* demo);
void G_DeferedPlayDemoFile (char* file);
// Can be called by the startup code or M_Responder,
// calls P_SetupLevel or W_EnterWorld.

View File

@ -205,7 +205,7 @@ void I_Error (const char *error, ...)
G_CheckDemoStatus();
I_ShutdownGraphics();
UI_Error(error, args);
UI_Errorv(error, args);
I_ReinitAfterError();
va_end(args);