From 1d9b8d357b00fbd6633a232b566f3ac439d211b5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 23:05:06 -0500 Subject: [PATCH 1/4] Add framecount increment to HWR_RenderPlayerView Analogue to R_RenderPlayerView; used for timedemo FPS reading --- src/hardware/hw_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index efecac524..9bfe7afb4 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6032,6 +6032,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // note: sets viewangle, viewx, viewy, viewz R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here + framecount++; // timedemo // copy view cam position for local use dup_viewx = viewx; From 89c12a4ee838742b8cd27a28fc2f73a61238a4a0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 23:23:09 -0500 Subject: [PATCH 2/4] Reset timedemo counters after wipe --- src/d_main.c | 7 +++++++ src/g_game.c | 2 +- src/g_game.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index dd2cfe0e5..481818754 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -483,6 +483,13 @@ static void D_Display(void) F_WipeEndScreen(); F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); } + + // reset counters so timedemo doesn't count the wipe duration + if (timingdemo) + { + framecount = 0; + demostarttime = I_GetTime(); + } } NetUpdate(); // send out any new accumulation diff --git a/src/g_game.c b/src/g_game.c index 213c3b83e..273b582a4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -97,7 +97,7 @@ UINT32 demoIdleTime = 3*TICRATE; boolean timingdemo; // if true, exit with report on completion boolean nodrawers; // for comparative timing purposes boolean noblit; // for comparative timing purposes -static tic_t demostarttime; // for comparative timing purposes +tic_t demostarttime; // for comparative timing purposes boolean netgame; // only true if packets are broadcast boolean multiplayer; diff --git a/src/g_game.h b/src/g_game.h index 5259eacbb..7260d3384 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -37,6 +37,7 @@ extern boolean playeringame[MAXPLAYERS]; // demoplaying back and demo recording extern boolean demoplayback, titledemo, demorecording, timingdemo; +extern tic_t demostarttime; // Quit after playing a demo from cmdline. extern boolean singledemo; From 56892c13ab47c6f681dc9df33e4d57795ed3fe0d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 28 Dec 2018 22:59:54 -0500 Subject: [PATCH 3/4] Add framecount to timedemo message --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 273b582a4..800492d47 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5660,7 +5660,7 @@ boolean G_CheckDemoStatus(void) timingdemo = false; f1 = (double)demotime; f2 = (double)framecount*TICRATE; - CONS_Printf(M_GetText("timed %u gametics in %d realtics\n%f seconds, %f avg fps\n"), leveltime,demotime,f1/TICRATE,f2/f1); + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); if (restorecv_vidwait != cv_vidwait.value) CV_SetValue(&cv_vidwait, restorecv_vidwait); D_AdvanceDemo(); From b3908755afc96e14e96d637402d586fc7cf6a600 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 29 Dec 2018 04:51:00 -0500 Subject: [PATCH 4/4] Add CSV functionality to timedemo * Append timedemo trials to timedemo.csv * Specify -csv to toggle CSV behavior * Specify -quit to immediately quit after timedemo * Add ticrate, rendermode, video mode, demo name, bits to CSV timedemo row --- src/d_clisrv.c | 7 ++++++- src/d_netcmd.c | 28 ++++++++++++++++++++++------ src/d_netcmd.h | 5 +++++ src/g_game.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2529b05d0..0fb903ff9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4596,7 +4596,12 @@ void TryRunTics(tic_t realtics) if (neededtic > gametic) { if (advancedemo) - D_StartTitle(); + { + if (timedemo_quit) + COM_ImmedExecute("quit"); + else + D_StartTitle(); + } else // run the count * tics while (neededtic > gametic) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 11b9413a8..d1101a69d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -364,6 +364,11 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; +char timedemo_name[256]; +boolean timedemo_csv; +char timedemo_csv_id[256]; +boolean timedemo_quit; + INT16 gametype = GT_COOP; boolean splitscreen = false; boolean circuitmap = false; @@ -1479,11 +1484,11 @@ static void Command_Playdemo_f(void) static void Command_Timedemo_f(void) { - char name[256]; + size_t i = 0; - if (COM_Argc() != 2) + if (COM_Argc() < 2) { - CONS_Printf(M_GetText("timedemo : time a demo\n")); + CONS_Printf(M_GetText("timedemo [-csv []] [-quit]: time a demo\n")); return; } @@ -1500,12 +1505,23 @@ static void Command_Timedemo_f(void) G_StopMetalDemo(); // open the demo file - strcpy (name, COM_Argv(1)); + strcpy (timedemo_name, COM_Argv(1)); // dont add .lmp so internal game demos can be played - CONS_Printf(M_GetText("Timing demo '%s'.\n"), name); + // print timedemo results as CSV? + i = COM_CheckParm("-csv"); + timedemo_csv = (i > 0); + if (COM_CheckParm("-quit") != i + 1) + strcpy(timedemo_csv_id, COM_Argv(i + 1)); // user-defined string to identify row + else + timedemo_csv_id[0] = 0; - G_TimeDemo(name); + // exit after the timedemo? + timedemo_quit = (COM_CheckParm("-quit") > 0); + + CONS_Printf(M_GetText("Timing demo '%s'.\n"), timedemo_name); + + G_TimeDemo(timedemo_name); } // stop current demo diff --git a/src/d_netcmd.h b/src/d_netcmd.h index b82065c82..505434541 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -111,6 +111,11 @@ extern consvar_t cv_skipmapcheck; extern consvar_t cv_sleep; +extern char timedemo_name[256]; +extern boolean timedemo_csv; +extern char timedemo_csv_id[256]; +extern boolean timedemo_quit; + typedef enum { XD_NAMEANDCOLOR = 1, diff --git a/src/g_game.c b/src/g_game.c index 800492d47..93342c1f3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5660,7 +5660,46 @@ boolean G_CheckDemoStatus(void) timingdemo = false; f1 = (double)demotime; f2 = (double)framecount*TICRATE; - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + if (restorecv_vidwait != cv_vidwait.value) CV_SetValue(&cv_vidwait, restorecv_vidwait); D_AdvanceDemo();