X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=cl_demo.c;h=ea10bff641738fdbcc909187d2d6e5a828c5a58b;hb=cf74e01c006d2937bf1e3a522efc7b2dd0f40ba2;hp=9d8e4a0056c8fab3ed84402109746ad8f19e2eda;hpb=e3226167dcbebd5838002e432c8052c6fdc005cb;p=xonotic%2Fdarkplaces.git diff --git a/cl_demo.c b/cl_demo.c index 9d8e4a00..ea10bff6 100644 --- a/cl_demo.c +++ b/cl_demo.c @@ -63,7 +63,7 @@ void CL_NextDemo (void) } } - sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); + dpsnprintf (str, sizeof(str), "playdemo %s\n", cls.demos[cls.demonum]); Cbuf_InsertText (str); cls.demonum++; } @@ -119,6 +119,57 @@ void CL_WriteDemoMessage (sizebuf_t *message) FS_Write (cls.demofile, message->data, message->cursize); } +/* +==================== +CL_CutDemo + +Dumps the current demo to a buffer, and resets the demo to its starting point. +Used to insert csprogs.dat files as a download to the beginning of a demo file. +==================== +*/ +void CL_CutDemo (unsigned char **buf, fs_offset_t *filesize) +{ + *buf = NULL; + *filesize = 0; + + FS_Close(cls.demofile); + *buf = FS_LoadFile(cls.demoname, tempmempool, false, filesize); + + // restart the demo recording + cls.demofile = FS_OpenRealFile(cls.demoname, "wb", false); + if(!cls.demofile) + Host_Error("failed to reopen the demo file"); + FS_Printf(cls.demofile, "%i\n", cls.forcetrack); +} + +/* +==================== +CL_PasteDemo + +Adds the cut stuff back to the demo. Also frees the buffer. +Used to insert csprogs.dat files as a download to the beginning of a demo file. +==================== +*/ +void CL_PasteDemo (unsigned char **buf, fs_offset_t *filesize) +{ + fs_offset_t startoffset = 0; + + if(!*buf) + return; + + // skip cdtrack + while(startoffset < *filesize && ((char *)(*buf))[startoffset] != '\n') + ++startoffset; + if(startoffset < *filesize) + ++startoffset; + + FS_Write(cls.demofile, *buf + startoffset, *filesize - startoffset); + + Mem_Free(*buf); + *buf = NULL; + *filesize = 0; +} + /* ==================== CL_ReadDemoMessage @@ -128,7 +179,7 @@ Handles playback of demos */ void CL_ReadDemoMessage(void) { - int r, i; + int i; float f; if (!cls.demoplayback) @@ -155,22 +206,25 @@ void CL_ReadDemoMessage(void) { cls.td_starttime = realtime; cls.td_onesecondnexttime = cl.time + 1; + cls.td_onesecondrealtime = realtime; cls.td_onesecondframes = 0; - cls.td_onesecondminframes = 0; - cls.td_onesecondmaxframes = 0; - cls.td_onesecondavgframes = 0; + cls.td_onesecondminfps = 0; + cls.td_onesecondmaxfps = 0; + cls.td_onesecondavgfps = 0; cls.td_onesecondavgcount = 0; } if (cl.time >= cls.td_onesecondnexttime) { + double fps = cls.td_onesecondframes / (realtime - cls.td_onesecondrealtime); if (cls.td_onesecondavgcount == 0) { - cls.td_onesecondminframes = cls.td_onesecondframes; - cls.td_onesecondmaxframes = cls.td_onesecondframes; + cls.td_onesecondminfps = fps; + cls.td_onesecondmaxfps = fps; } - cls.td_onesecondminframes = min(cls.td_onesecondminframes, cls.td_onesecondframes); - cls.td_onesecondmaxframes = max(cls.td_onesecondmaxframes, cls.td_onesecondframes); - cls.td_onesecondavgframes += cls.td_onesecondframes; + cls.td_onesecondrealtime = realtime; + cls.td_onesecondminfps = min(cls.td_onesecondminfps, fps); + cls.td_onesecondmaxfps = max(cls.td_onesecondmaxfps, fps); + cls.td_onesecondavgfps += fps; cls.td_onesecondavgcount++; cls.td_onesecondframes = 0; cls.td_onesecondnexttime++; @@ -186,12 +240,18 @@ void CL_ReadDemoMessage(void) // get the next message FS_Read(cls.demofile, &net_message.cursize, 4); net_message.cursize = LittleLong(net_message.cursize); + if(net_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now! + { + // skip over demo packet + FS_Seek(cls.demofile, 12 + (net_message.cursize & (~DEMOMSG_CLIENT_TO_SERVER)), SEEK_CUR); + continue; + } if (net_message.cursize > net_message.maxsize) Host_Error("Demo message (%i) > net_message.maxsize (%i)", net_message.cursize, net_message.maxsize); VectorCopy(cl.mviewangles[0], cl.mviewangles[1]); for (i = 0;i < 3;i++) { - r = (int)FS_Read(cls.demofile, &f, 4); + FS_Read(cls.demofile, &f, 4); cl.mviewangles[0][i] = LittleFloat(f); } @@ -200,6 +260,9 @@ void CL_ReadDemoMessage(void) MSG_BeginReading(); CL_ParseServerMessage(); + if (cls.signon != SIGNONS) + Cbuf_Execute(); // immediately execute svc_stufftext if in the demo before connect! + // In case the demo contains a "svc_disconnect" message if (!cls.demoplayback) return; @@ -243,10 +306,16 @@ void CL_Stop_f (void) CL_WriteDemoMessage(&buf); // finish up + if(cl_autodemo.integer && (cl_autodemo_delete.integer & 1)) + { + FS_RemoveOnClose(cls.demofile); + Con_Print("Completed and deleted demo\n"); + } + else + Con_Print("Completed demo\n"); FS_Close (cls.demofile); cls.demofile = NULL; cls.demorecording = false; - Con_Print("Completed demo\n"); } /* @@ -302,17 +371,20 @@ void CL_Record_f (void) // open the demo file Con_Printf("recording to %s.\n", name); - cls.demofile = FS_Open (name, "wb", false, false); + cls.demofile = FS_OpenRealFile(name, "wb", false); if (!cls.demofile) { Con_Print("ERROR: couldn't open.\n"); return; } + strlcpy(cls.demoname, name, sizeof(cls.demoname)); cls.forcetrack = track; FS_Printf(cls.demofile, "%i\n", cls.forcetrack); cls.demorecording = true; + cls.demo_lastcsprogssize = -1; + cls.demo_lastcsprogscrc = -1; } @@ -347,16 +419,16 @@ void CL_PlayDemo_f (void) FS_DefaultExtension (name, ".dem", sizeof (name)); cls.protocol = PROTOCOL_QUAKE; - Con_Printf("Playing demo from %s.\n", name); - cls.demofile = FS_Open (name, "rb", false, false); + Con_Printf("Playing demo %s.\n", name); + cls.demofile = FS_OpenVirtualFile(name, false); if (!cls.demofile) { Con_Print("ERROR: couldn't open.\n"); cls.demonum = -1; // stop demo loop return; } - strlcpy(cls.demoname, name, sizeof(cls.demoname)); + cls.demoplayback = true; cls.state = ca_connected; cls.forcetrack = 0; @@ -380,22 +452,40 @@ CL_FinishTimeDemo void CL_FinishTimeDemo (void) { int frames; + int i; double time, totalfpsavg; double fpsmin, fpsavg, fpsmax; // report min/avg/max fps + static int benchmark_runs = 0; cls.timedemo = false; frames = cls.td_frames; time = realtime - cls.td_starttime; totalfpsavg = time > 0 ? frames / time : 0; - fpsmin = cls.td_onesecondminframes; - fpsavg = cls.td_onesecondavgcount ? cls.td_onesecondavgframes / cls.td_onesecondavgcount : 0; - fpsmax = cls.td_onesecondmaxframes; + fpsmin = cls.td_onesecondminfps; + fpsavg = cls.td_onesecondavgcount ? cls.td_onesecondavgfps / cls.td_onesecondavgcount : 0; + fpsmax = cls.td_onesecondmaxfps; // LordHavoc: timedemo now prints out 7 digits of fraction, and min/avg/max - Con_Printf("%i frames %5.7f seconds %5.7f fps, one-second min/avg/max: %.0f %.0f %.0f\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax); - Log_Printf("benchmark.log", "date %s | enginedate %s | demo %s | commandline %s | result %i frames %5.7f seconds %5.7f fps, one-second min/avg/max: %.0f %.0f %.0f\n", Sys_TimeString("%Y-%m-%d %H:%M:%S"), buildstring, cls.demoname, cmdline.string, frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax); + Con_Printf("%i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount); + Log_Printf("benchmark.log", "date %s | enginedate %s | demo %s | commandline %s | run %d | result %i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", Sys_TimeString("%Y-%m-%d %H:%M:%S"), buildstring, cls.demoname, cmdline.string, benchmark_runs + 1, frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount); if (COM_CheckParm("-benchmark")) - Host_Quit_f(); + { + ++benchmark_runs; + i = COM_CheckParm("-benchmarkruns"); + if(i && i + 1 < com_argc) + { + if(atoi(com_argv[i + 1]) > benchmark_runs) + { + // restart the benchmark + Cbuf_AddText(va("timedemo %s\n", cls.demoname)); + // cannot execute here + } + else + Host_Quit_f(); + } + else + Host_Quit_f(); + } } /*