Add demo replay
This commit is contained in:
parent
05968fe5be
commit
a9851c2c7c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue