DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
cl_demo.c File Reference
#include "quakedef.h"
+ Include dependency graph for cl_demo.c:

Go to the source code of this file.

Data Structures

struct  benchmarkhistory_t
 

Macros

#define DO_MAX(f)
 
#define DO_MED(f)
 
#define DO_MIN(f)
 

Functions

void CL_CutDemo (unsigned char **buf, fs_offset_t *filesize)
 
void CL_Demo_Init (void)
 
static void CL_Demos_f (cmd_state_t *cmd)
 
static void CL_FinishTimeDemo (void)
 
void CL_NextDemo (void)
 
void CL_PasteDemo (unsigned char **buf, fs_offset_t *filesize)
 
static void CL_PauseDemo_f (cmd_state_t *cmd)
 
void CL_PlayDemo (const char *demo)
 
void CL_PlayDemo_f (cmd_state_t *cmd)
 
void CL_ReadDemoMessage (void)
 
void CL_Record_f (cmd_state_t *cmd)
 
static void CL_Startdemos_f (cmd_state_t *cmd)
 
void CL_Stop_f (cmd_state_t *cmd)
 
static void CL_Stopdemo_f (cmd_state_t *cmd)
 
void CL_StopPlayback (void)
 
void CL_TimeDemo_f (cmd_state_t *cmd)
 
void CL_WriteDemoMessage (sizebuf_t *message)
 
static int doublecmp_withoffset (const void *a_, const void *b_)
 

Variables

static size_t doublecmp_offset
 

Macro Definition Documentation

◆ DO_MAX

#define DO_MAX ( f)
Value:
for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f > f)) f = history[i].f
GLint first
Definition glquake.h:671
conbuffer_t history
Definition keys.c:45
int i
float f

Referenced by CL_FinishTimeDemo().

◆ DO_MED

#define DO_MED ( f)
Value:
doublecmp_offset = (char *)&history->f - (char *)history; \
qsort(history + first, benchmark_runs - first, sizeof(*history), doublecmp_withoffset); \
if((first + benchmark_runs) & 1) \
f = history[(first + benchmark_runs - 1) / 2].f; \
else \
f = (history[(first + benchmark_runs - 2) / 2].f + history[(first + benchmark_runs) / 2].f) / 2
static int doublecmp_withoffset(const void *a_, const void *b_)
Definition cl_demo.c:487
static size_t doublecmp_offset
Definition cl_demo.c:486

Referenced by CL_FinishTimeDemo().

◆ DO_MIN

#define DO_MIN ( f)
Value:
for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f < f)) f = history[i].f

Referenced by CL_FinishTimeDemo().

Function Documentation

◆ CL_CutDemo()

void CL_CutDemo ( unsigned char ** buf,
fs_offset_t * filesize )

Definition at line 137 of file cl_demo.c.

138{
139 *buf = NULL;
140 *filesize = 0;
141
143 *buf = FS_LoadFile(cls.demoname, tempmempool, false, filesize);
144
145 // restart the demo recording
146 cls.demofile = FS_OpenRealFile(cls.demoname, "wb", false);
147 if(!cls.demofile)
148 Sys_Error("failed to reopen the demo file");
150}
client_static_t cls
Definition cl_main.c:116
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
Definition fs.c:2901
int FS_Close(qfile_t *file)
Definition fs.c:2970
int FS_Printf(qfile_t *file, const char *format,...)
Definition fs.c:3273
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
#define NULL
Definition qtypes.h:12
qfile_t * demofile
Definition client.h:592
char demoname[MAX_QPATH]
Definition client.h:580
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:724
mempool_t * tempmempool
Definition zone.c:794

References buf, cls, client_static_t::demofile, client_static_t::demoname, client_static_t::forcetrack, FS_Close(), FS_LoadFile(), FS_OpenRealFile(), FS_Printf(), NULL, Sys_Error(), and tempmempool.

Referenced by CL_VM_Init().

◆ CL_Demo_Init()

void CL_Demo_Init ( void )

Definition at line 737 of file cl_demo.c.

738{
739 Cmd_AddCommand(CF_CLIENT, "record", CL_Record_f, "record a demo");
740 Cmd_AddCommand(CF_CLIENT, "stop", CL_Stop_f, "stop recording or playing a demo");
741 Cmd_AddCommand(CF_CLIENT, "playdemo", CL_PlayDemo_f, "watch a demo file");
742 Cmd_AddCommand(CF_CLIENT, "timedemo", CL_TimeDemo_f, "play back a demo as fast as possible and save statistics to benchmark.log");
743 Cmd_AddCommand(CF_CLIENT, "startdemos", CL_Startdemos_f, "start playing back the selected demos sequentially (used at end of startup script)");
744 Cmd_AddCommand(CF_CLIENT, "demos", CL_Demos_f, "restart looping demos defined by the last startdemos command");
745 Cmd_AddCommand(CF_CLIENT, "stopdemo", CL_Stopdemo_f, "stop playing or recording demo (like stop command) and return to looping demos");
746 // LadyHavoc: added pausedemo
747 Cmd_AddCommand(CF_CLIENT, "pausedemo", CL_PauseDemo_f, "pause demo playback (can also safely pause demo recording if using QUAKE, QUAKEDP or NEHAHRAMOVIE protocol, useful for making movies)");
752}
void CL_PlayDemo_f(cmd_state_t *cmd)
Definition cl_demo.c:468
void CL_Stop_f(cmd_state_t *cmd)
Definition cl_demo.c:307
static void CL_Demos_f(cmd_state_t *cmd)
Definition cl_demo.c:703
static void CL_PauseDemo_f(cmd_state_t *cmd)
Definition cl_demo.c:728
static void CL_Stopdemo_f(cmd_state_t *cmd)
Definition cl_demo.c:720
static void CL_Startdemos_f(cmd_state_t *cmd)
Definition cl_demo.c:654
void CL_TimeDemo_f(cmd_state_t *cmd)
Definition cl_demo.c:612
void CL_Record_f(cmd_state_t *cmd)
Definition cl_demo.c:346
cvar_t cl_autodemo_delete
Definition cl_main.c:64
cvar_t cl_autodemo
Definition cl_main.c:62
cvar_t cl_autodemo_nameformat
Definition cl_main.c:63
cvar_t cl_startdemos
Definition cl_main.c:65
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599

References CF_CLIENT, cl_autodemo, cl_autodemo_delete, cl_autodemo_nameformat, CL_Demos_f(), CL_PauseDemo_f(), CL_PlayDemo_f(), CL_Record_f(), cl_startdemos, CL_Startdemos_f(), CL_Stop_f(), CL_Stopdemo_f(), CL_TimeDemo_f(), Cmd_AddCommand(), and Cvar_RegisterVariable().

Referenced by CL_Init().

◆ CL_Demos_f()

static void CL_Demos_f ( cmd_state_t * cmd)
static

Definition at line 703 of file cl_demo.c.

704{
705 if (cls.state == ca_dedicated)
706 return;
707 if (cls.demonum == -1)
708 cls.demonum = 1;
710 CL_NextDemo();
711}
void CL_NextDemo(void)
Definition cl_demo.c:50
void CL_Disconnect(void)
Definition cl_main.c:478
@ ca_dedicated
Definition client.h:530
cactive_t state
Definition client.h:568

References ca_dedicated, CL_Disconnect(), CL_NextDemo(), cls, client_static_t::demonum, and client_static_t::state.

Referenced by CL_Demo_Init().

◆ CL_FinishTimeDemo()

static void CL_FinishTimeDemo ( void )
static

Definition at line 504 of file cl_demo.c.

505{
506 int frames;
507 int i;
508 double time, totalfpsavg;
509 double fpsmin, fpsavg, fpsmax; // report min/avg/max fps
510 static int benchmark_runs = 0;
511 char vabuf[1024];
512
513 cls.timedemo = host.restless = false;
514
515 frames = cls.td_frames;
517 totalfpsavg = time > 0 ? frames / time : 0;
518 fpsmin = cls.td_onesecondminfps;
520 fpsmax = cls.td_onesecondmaxfps;
521 // LadyHavoc: timedemo now prints out 7 digits of fraction, and min/avg/max
522 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);
523 Sys_TimeString(vabuf, sizeof(vabuf), "%Y-%m-%d %H:%M:%S");
524 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", vabuf, engineversion, cls.demoname, cmdline.string, benchmark_runs + 1, frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
525 if (Sys_CheckParm("-benchmark"))
526 {
527 ++benchmark_runs;
528 i = Sys_CheckParm("-benchmarkruns");
529 if(i && i + 1 < sys.argc)
530 {
532 if(!history)
533 history = (benchmarkhistory_t *)Z_Malloc(sizeof(*history) * atoi(sys.argv[i + 1]));
534
535 history[benchmark_runs - 1].frames = frames;
536 history[benchmark_runs - 1].time = time;
537 history[benchmark_runs - 1].totalfpsavg = totalfpsavg;
538 history[benchmark_runs - 1].fpsmin = fpsmin;
539 history[benchmark_runs - 1].fpsavg = fpsavg;
540 history[benchmark_runs - 1].fpsmax = fpsmax;
541
542 if(atoi(sys.argv[i + 1]) > benchmark_runs)
543 {
544 // restart the benchmark
545 Cbuf_AddText(cmd_local, va(vabuf, sizeof(vabuf), "timedemo %s\n", cls.demoname));
546 // cannot execute here
547 }
548 else
549 {
550 // print statistics
551 int first = Sys_CheckParm("-benchmarkruns_skipfirst") ? 1 : 0;
552 if(benchmark_runs > first)
553 {
554#define DO_MIN(f) \
555 for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f < f)) f = history[i].f
556
557#define DO_MAX(f) \
558 for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f > f)) f = history[i].f
559
560#define DO_MED(f) \
561 doublecmp_offset = (char *)&history->f - (char *)history; \
562 qsort(history + first, benchmark_runs - first, sizeof(*history), doublecmp_withoffset); \
563 if((first + benchmark_runs) & 1) \
564 f = history[(first + benchmark_runs - 1) / 2].f; \
565 else \
566 f = (history[(first + benchmark_runs - 2) / 2].f + history[(first + benchmark_runs) / 2].f) / 2
567
568 DO_MIN(frames);
569 DO_MAX(time);
570 DO_MIN(totalfpsavg);
571 DO_MIN(fpsmin);
572 DO_MIN(fpsavg);
573 DO_MIN(fpsmax);
574 Con_Printf("MIN: %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);
575
576 DO_MED(frames);
577 DO_MED(time);
578 DO_MED(totalfpsavg);
579 DO_MED(fpsmin);
580 DO_MED(fpsavg);
581 DO_MED(fpsmax);
582 Con_Printf("MED: %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);
583
584 DO_MAX(frames);
585 DO_MIN(time);
586 DO_MAX(totalfpsavg);
587 DO_MAX(fpsmin);
588 DO_MAX(fpsavg);
589 DO_MAX(fpsmax);
590 Con_Printf("MAX: %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);
591 }
593 history = NULL;
595 }
596 }
597 else
599 }
600
601 // Might need to re-enable vsync
603}
#define DO_MIN(f)
#define DO_MAX(f)
#define DO_MED(f)
void Cbuf_AddText(cmd_state_t *cmd, const char *text)
Definition cmd.c:264
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
Definition cmd.c:25
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
cvar_t cmdline
Definition common.c:33
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
void Log_Printf(const char *logfilename, const char *fmt,...)
Definition console.c:655
float time
void Cvar_Callback(cvar_t *var)
Definition cvar.c:372
char engineversion[128]
version string for the corner of the console, crash messages, status command, etc
Definition host.c:304
host_static_t host
Definition host.c:41
@ host_shutdown
states >= host_shutdown cause graceful shutdown, see Sys_HandleCrash() comments
Definition host.h:27
qbool timedemo
Definition client.h:589
double td_onesecondavgfps
Definition client.h:601
double td_onesecondmaxfps
Definition client.h:600
int td_onesecondavgcount
Definition client.h:602
double td_starttime
Definition client.h:594
double td_onesecondminfps
Definition client.h:599
const char * string
Definition cvar.h:71
qbool restless
don't sleep
Definition host.h:49
int state
Definition host.h:44
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
int argc
Definition sys.h:146
const char ** argv
Definition sys.h:147
size_t Sys_TimeString(char buf[], size_t bufsize, const char *timeformat)
Definition sys_shared.c:45
sys_t sys
Definition sys_shared.c:42
int Sys_CheckParm(const char *parm)
Definition sys_shared.c:327
cvar_t vid_vsync
Definition vid_shared.c:149
#define Z_Malloc(size)
Definition zone.h:161
#define Z_Free(data)
Definition zone.h:164

References sys_t::argc, sys_t::argv, Cbuf_AddText(), cls, cmd_local, cmdline, Con_Printf(), Cvar_Callback(), client_static_t::demoname, DO_MAX, DO_MED, DO_MIN, engineversion, first, history, host, host_shutdown, i, Log_Printf(), NULL, host_static_t::realtime, host_static_t::restless, host_static_t::state, cvar_t::string, sys, Sys_CheckParm(), Sys_TimeString(), client_static_t::td_frames, client_static_t::td_onesecondavgcount, client_static_t::td_onesecondavgfps, client_static_t::td_onesecondmaxfps, client_static_t::td_onesecondminfps, client_static_t::td_starttime, time, client_static_t::timedemo, va(), vid_vsync, Z_Free, and Z_Malloc.

Referenced by CL_StopPlayback().

◆ CL_NextDemo()

void CL_NextDemo ( void )

Definition at line 50 of file cl_demo.c.

51{
52 char str[MAX_INPUTLINE];
53
54 if (cls.demonum == -1)
55 return; // don't play demos
56
57 if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS)
58 {
59 cls.demonum = 0;
60 if (!cls.demos[cls.demonum][0])
61 {
62 Con_Print("No demos listed with startdemos\n");
63 cls.demonum = -1;
64 return;
65 }
66 }
67
68 dpsnprintf (str, sizeof(str), "playdemo %s\n", cls.demos[cls.demonum]);
70 cls.demonum++;
71}
void Cbuf_InsertText(cmd_state_t *cmd, const char *text)
Definition cmd.c:292
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
#define MAX_DEMOS
max demos provided to demos command
Definition qdefs.h:118
char demos[MAX_DEMOS][MAX_DEMONAME]
Definition client.h:578

References Cbuf_InsertText(), cls, cmd_local, Con_Print(), client_static_t::demonum, client_static_t::demos, dpsnprintf(), MAX_DEMOS, and MAX_INPUTLINE.

Referenced by CL_Demos_f(), CL_ParseServerMessage(), and CL_Startdemos_f().

◆ CL_PasteDemo()

void CL_PasteDemo ( unsigned char ** buf,
fs_offset_t * filesize )

Definition at line 160 of file cl_demo.c.

161{
162 fs_offset_t startoffset = 0;
163
164 if(!*buf)
165 return;
166
167 // skip cdtrack
168 while(startoffset < *filesize && ((char *)(*buf))[startoffset] != '\n')
169 ++startoffset;
170 if(startoffset < *filesize)
171 ++startoffset;
172
173 FS_Write(cls.demofile, *buf + startoffset, *filesize - startoffset);
174
175 Mem_Free(*buf);
176 *buf = NULL;
177 *filesize = 0;
178}
fs_offset_t FS_Write(qfile_t *file, const void *data, size_t datasize)
Definition fs.c:3019
int64_t fs_offset_t
Definition fs.h:37
#define Mem_Free(mem)
Definition zone.h:96

References buf, cls, client_static_t::demofile, FS_Write(), Mem_Free, and NULL.

Referenced by CL_VM_Init().

◆ CL_PauseDemo_f()

static void CL_PauseDemo_f ( cmd_state_t * cmd)
static

Definition at line 728 of file cl_demo.c.

729{
731 if (cls.demopaused)
732 Con_Print("Demo paused\n");
733 else
734 Con_Print("Demo unpaused\n");
735}
qbool demopaused
Definition client.h:604

References cls, Con_Print(), and client_static_t::demopaused.

Referenced by CL_Demo_Init().

◆ CL_PlayDemo()

void CL_PlayDemo ( const char * demo)

Definition at line 413 of file cl_demo.c.

414{
415 char name[MAX_QPATH];
416 int c;
417 qbool neg = false;
418 qfile_t *f;
419
420 // open the demo file
421 dp_strlcpy (name, demo, sizeof (name));
422 FS_DefaultExtension (name, ".dem", sizeof (name));
423 f = FS_OpenVirtualFile(name, false);
424 if (!f)
425 {
426 Con_Printf(CON_ERROR "ERROR: couldn't open %s.\n", name);
427 cls.demonum = -1; // stop demo loop
428 return;
429 }
430
431 cls.demostarting = true;
432
433 // disconnect from server
435
436 // update networking ports (this is mainly just needed at startup)
438
440
441 Con_Printf("Playing demo %s.\n", name);
442 cls.demofile = f;
444
445 cls.demoplayback = true;
447 cls.forcetrack = 0;
448
449 while ((c = FS_Getc (cls.demofile)) != '\n')
450 if (c == '-')
451 neg = true;
452 else
453 cls.forcetrack = cls.forcetrack * 10 + (c - '0');
454
455 if (neg)
457
458 cls.demostarting = false;
459}
@ ca_connected
Definition client.h:532
@ PROTOCOL_QUAKE
quake (aka netquake/normalquake/nq) protocol
Definition common.h:144
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
#define CON_ERROR
Definition console.h:102
qfile_t * FS_OpenVirtualFile(const char *filepath, qbool quiet)
Definition fs.c:2928
void FS_DefaultExtension(char *path, const char *extension, size_t size_path)
Definition fs.c:3641
int FS_Getc(qfile_t *file)
Definition fs.c:3323
const GLchar * name
Definition glquake.h:601
void NetConn_UpdateSockets(void)
Definition netconn.c:1306
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
bool qbool
Definition qtypes.h:9
qbool demoplayback
Definition client.h:587
qbool demostarting
Definition client.h:588
protocolversion_t protocol
Definition client.h:617

References ca_connected, CL_Disconnect(), cls, CON_ERROR, Con_Printf(), client_static_t::demofile, client_static_t::demoname, client_static_t::demonum, client_static_t::demoplayback, client_static_t::demostarting, dp_strlcpy, f, client_static_t::forcetrack, FS_DefaultExtension(), FS_Getc(), FS_OpenVirtualFile(), MAX_QPATH, name, NetConn_UpdateSockets(), client_static_t::protocol, PROTOCOL_QUAKE, and client_static_t::state.

Referenced by CL_PlayDemo_f(), and CL_TimeDemo_f().

◆ CL_PlayDemo_f()

void CL_PlayDemo_f ( cmd_state_t * cmd)

Definition at line 468 of file cl_demo.c.

469{
470 if (Cmd_Argc(cmd) != 2)
471 {
472 Con_Print("playdemo <demoname> : plays a demo\n");
473 return;
474 }
475
477}
void CL_PlayDemo(const char *demo)
Definition cl_demo.c:413
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
void cmd(string command,...)

References CL_PlayDemo(), cmd(), Cmd_Argc(), Cmd_Argv(), and Con_Print().

Referenced by CL_Demo_Init().

◆ CL_ReadDemoMessage()

void CL_ReadDemoMessage ( void )

Definition at line 187 of file cl_demo.c.

188{
189 int i;
190 float f;
191
192 if (!cls.demoplayback)
193 return;
194
195 // LadyHavoc: pausedemo
196 if (cls.demopaused)
197 return;
198
199 for (;;)
200 {
201 // decide if it is time to grab the next message
202 // always grab until fully connected
203 if (cls.signon == SIGNONS)
204 {
205 if (cls.timedemo)
206 {
207 cls.td_frames++;
209 // if this is the first official frame we can now grab the real
210 // td_starttime so the bogus time on the first frame doesn't
211 // count against the final report
212 if (cls.td_frames == 0)
213 {
222 }
224 {
226 if (cls.td_onesecondavgcount == 0)
227 {
230 }
234 cls.td_onesecondavgfps += fps;
238 }
239 }
240 else if (cl.time < cl.mtime[0])
241 {
242 // don't need another message yet
243 return;
244 }
245 }
246
247 /* At signon 1 the cl_begindownloads command starts the world and, if applicable,
248 * boots up CSQC which may be required to parse the next message.
249 * That will be delayed if curl must first (down)load the map.
250 */
251 if (cls.signon == 1 && cl.loadcsqc) // waiting for CL_VM_Init() to be called
252 return;
253
254 // get the next message
257 if(cl_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now!
258 {
259 // skip over demo packet
261 continue;
262 }
264 {
265 CL_DisconnectEx(false, "Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
267 return;
268 }
270 for (i = 0;i < 3;i++)
271 {
272 FS_Read(cls.demofile, &f, 4);
274 }
275
277 {
280
281 if (cls.signon != SIGNONS)
282 Cbuf_Execute((cmd_local)->cbuf); // immediately execute svc_stufftext if in the demo before connect!
283
284 // In case the demo contains a "svc_disconnect" message
285 if (!cls.demoplayback)
286 return;
287
288 if (cls.timedemo)
289 return;
290 }
291 else
292 {
294 return;
295 }
296 }
297}
void CL_DisconnectEx(qbool kicked, const char *fmt,...)
Definition cl_main.c:370
client_state_t cl
Definition cl_main.c:117
void CL_ParseServerMessage(void)
Definition cl_parse.c:3435
#define SIGNONS
Definition client.h:525
void Cbuf_Execute(cmd_buf_t *cbuf)
Definition cmd.c:351
void MSG_BeginReading(sizebuf_t *sb)
Definition com_msg.c:257
#define LittleLong(l)
Definition common.h:92
#define LittleFloat(l)
Definition common.h:94
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
int FS_Seek(qfile_t *file, fs_offset_t offset, int whence)
Definition fs.c:3359
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define VectorCopy(in, out)
Definition mathlib.h:101
sizebuf_t cl_message
Definition netconn.c:71
#define DEMOMSG_CLIENT_TO_SERVER
Definition quakedef.h:178
qbool loadcsqc
Definition client.h:1026
double time
Definition client.h:868
double mtime[2]
Definition client.h:861
vec3_t mviewangles[2]
Definition client.h:786
double td_onesecondframes
Definition client.h:597
double td_onesecondrealtime
Definition client.h:598
double td_onesecondnexttime
Definition client.h:596
unsigned char * data
Definition common.h:52
int cursize
Definition common.h:54
int maxsize
Definition common.h:53

References Cbuf_Execute(), cl, CL_Disconnect(), CL_DisconnectEx(), cl_message, CL_ParseServerMessage(), cls, cmd_local, sizebuf_t::cursize, sizebuf_t::data, client_static_t::demofile, DEMOMSG_CLIENT_TO_SERVER, client_static_t::demopaused, client_static_t::demoplayback, f, FS_Read(), FS_Seek(), host, i, LittleFloat, LittleLong, client_state_t::loadcsqc, max, sizebuf_t::maxsize, min, MSG_BeginReading(), client_state_t::mtime, client_state_t::mviewangles, host_static_t::realtime, client_static_t::signon, SIGNONS, client_static_t::td_frames, client_static_t::td_onesecondavgcount, client_static_t::td_onesecondavgfps, client_static_t::td_onesecondframes, client_static_t::td_onesecondmaxfps, client_static_t::td_onesecondminfps, client_static_t::td_onesecondnexttime, client_static_t::td_onesecondrealtime, client_static_t::td_starttime, client_state_t::time, client_static_t::timedemo, and VectorCopy.

Referenced by CL_Frame().

◆ CL_Record_f()

void CL_Record_f ( cmd_state_t * cmd)

Definition at line 346 of file cl_demo.c.

347{
348 int c, track;
349 char name[MAX_OSPATH];
350 char vabuf[1024];
351 int vabuf_len;
352
353 c = Cmd_Argc(cmd);
354 if (c != 2 && c != 3 && c != 4)
355 {
356 Con_Print("record <demoname> [<map> [cd track]]\n");
357 return;
358 }
359
360 if (strstr(Cmd_Argv(cmd, 1), ".."))
361 {
362 Con_Print("Relative pathnames are not allowed.\n");
363 return;
364 }
365
366 if (c == 2 && cls.state == ca_connected)
367 {
368 Con_Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n");
369 return;
370 }
371
372 if (cls.state == ca_connected)
374
375 // write the forced cd track number, or -1
376 if (c == 4)
377 {
378 track = atoi(Cmd_Argv(cmd, 3));
379 Con_Printf("Forcing CD track to %i\n", cls.forcetrack);
380 }
381 else
382 track = -1;
383
384 // get the demo name
385 dp_strlcpy (name, Cmd_Argv(cmd, 1), sizeof (name));
386 FS_DefaultExtension (name, ".dem", sizeof (name));
387
388 // start the map up
389 if (c > 2)
390 {
391 vabuf_len = dpsnprintf(vabuf, sizeof(vabuf), "map %s", Cmd_Argv(cmd, 2));
392 Cmd_ExecuteString(cmd, vabuf, vabuf_len, src_local, false);
393 }
394
395 // open the demo file
396 Con_Printf("recording to %s.\n", name);
397 cls.demofile = FS_OpenRealFile(name, "wb", false);
398 if (!cls.demofile)
399 {
400 Con_Print(CON_ERROR "ERROR: couldn't open.\n");
401 return;
402 }
404
405 cls.forcetrack = track;
407
408 cls.demorecording = true;
411}
void Cmd_ExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex)
Parses a single line of text into arguments and tries to execute it.
Definition cmd.c:2068
@ src_local
from the command buffer
Definition cmd.h:75
#define MAX_OSPATH
max length of a filesystem pathname
Definition qdefs.h:175
int demo_lastcsprogscrc
Definition client.h:586
fs_offset_t demo_lastcsprogssize
Definition client.h:585
qbool demorecording
Definition client.h:584

References ca_connected, CL_Disconnect(), cls, cmd(), Cmd_Argc(), Cmd_Argv(), Cmd_ExecuteString(), CON_ERROR, Con_Print(), Con_Printf(), client_static_t::demo_lastcsprogscrc, client_static_t::demo_lastcsprogssize, client_static_t::demofile, client_static_t::demoname, client_static_t::demorecording, dp_strlcpy, dpsnprintf(), client_static_t::forcetrack, FS_DefaultExtension(), FS_OpenRealFile(), FS_Printf(), MAX_OSPATH, name, src_local, and client_static_t::state.

Referenced by CL_Demo_Init().

◆ CL_Startdemos_f()

static void CL_Startdemos_f ( cmd_state_t * cmd)
static

Definition at line 654 of file cl_demo.c.

655{
656 int i, c;
657
658 if (cls.state == ca_dedicated || Sys_CheckParm("-listen") || Sys_CheckParm("-benchmark") || Sys_CheckParm("-demo") || Sys_CheckParm("-capturedemo"))
659 return;
660
661 c = Cmd_Argc(cmd) - 1;
662 if (c > MAX_DEMOS)
663 {
664 Con_Printf("Max %i demos in demoloop\n", MAX_DEMOS);
665 c = MAX_DEMOS;
666 }
667 Con_DPrintf("%i demo(s) in loop\n", c);
668
669 for (i=1 ; i<c+1 ; i++)
670 dp_strlcpy (cls.demos[i-1], Cmd_Argv(cmd, i), sizeof (cls.demos[i-1]));
671
672 // LadyHavoc: clear the remaining slots
673 for (;i <= MAX_DEMOS;i++)
674 cls.demos[i-1][0] = 0;
675
676 if (!sv.active && cls.demonum != -1 && !cls.demoplayback)
677 {
679 {
680 cls.demonum = -1;
681#ifdef CONFIG_MENU
682 // make the menu appear after a gamedir change
683 if(MR_ToggleMenu)
684 MR_ToggleMenu(1);
685#endif
686 return;
687 }
688 cls.demonum = 0;
689 CL_NextDemo ();
690 }
691 else
692 cls.demonum = -1;
693}
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void(* MR_ToggleMenu)(int mode)
Definition menu.c:5480
server_t sv
local server
Definition sv_main.c:223
int integer
Definition cvar.h:73
qbool active
false if only a net client
Definition server.h:66

References server_t::active, ca_dedicated, CL_NextDemo(), cl_startdemos, cls, cmd(), Cmd_Argc(), Cmd_Argv(), Con_DPrintf(), Con_Printf(), client_static_t::demonum, client_static_t::demoplayback, client_static_t::demos, dp_strlcpy, i, cvar_t::integer, MAX_DEMOS, MR_ToggleMenu, client_static_t::state, sv, and Sys_CheckParm().

Referenced by CL_Demo_Init().

◆ CL_Stop_f()

void CL_Stop_f ( cmd_state_t * cmd)

Definition at line 307 of file cl_demo.c.

308{
310 unsigned char bufdata[64];
311
312 if (!cls.demorecording)
313 {
314 Con_Print("Not recording a demo.\n");
315 return;
316 }
317
318// write a disconnect message to the demo file
319 // LadyHavoc: don't replace the cl_message when doing this
320 buf.data = bufdata;
321 buf.maxsize = sizeof(bufdata);
322 SZ_Clear(&buf);
325
326// finish up
328 {
330 Con_Print("Completed and deleted demo\n");
331 }
332 else
333 Con_Print("Completed demo\n");
335 cls.demofile = NULL;
336 cls.demorecording = false;
337}
void CL_WriteDemoMessage(sizebuf_t *message)
Definition cl_demo.c:110
void MSG_WriteByte(sizebuf_t *sb, int c)
Definition com_msg.c:130
void SZ_Clear(sizebuf_t *buf)
Definition common.c:44
void FS_RemoveOnClose(qfile_t *file)
Definition fs.c:3007
#define svc_disconnect
Definition protocol.h:216

References buf, cl_autodemo, cl_autodemo_delete, CL_WriteDemoMessage(), cls, Con_Print(), client_static_t::demofile, client_static_t::demorecording, FS_Close(), FS_RemoveOnClose(), cvar_t::integer, MSG_WriteByte(), NULL, svc_disconnect, and SZ_Clear().

Referenced by CL_Demo_Init(), CL_DisconnectEx(), CL_ParseServerInfo(), and Sys_Error().

◆ CL_Stopdemo_f()

static void CL_Stopdemo_f ( cmd_state_t * cmd)
static

Definition at line 720 of file cl_demo.c.

721{
722 if (!cls.demoplayback)
723 return;
725}

References CL_Disconnect(), cls, and client_static_t::demoplayback.

Referenced by CL_Demo_Init().

◆ CL_StopPlayback()

void CL_StopPlayback ( void )

Definition at line 81 of file cl_demo.c.

82{
83#ifdef CONFIG_VIDEO_CAPTURE
84 if (cl_capturevideo_demo_stop.integer)
85 Cvar_SetQuick(&cl_capturevideo, "0");
86#endif
87
88 if (!cls.demoplayback)
89 return;
90
92 cls.demoplayback = false;
94
95 if (cls.timedemo)
97
98 if (!cls.demostarting) // only quit if not starting another demo
99 if (Sys_CheckParm("-demo") || Sys_CheckParm("-capturedemo"))
101}
static void CL_FinishTimeDemo(void)
Definition cl_demo.c:504
void Cvar_SetQuick(cvar_t *var, const char *value)
Definition cvar.c:436

References CL_FinishTimeDemo(), cls, Cvar_SetQuick(), client_static_t::demofile, client_static_t::demoplayback, client_static_t::demostarting, FS_Close(), host, host_shutdown, cvar_t::integer, NULL, host_static_t::state, Sys_CheckParm(), and client_static_t::timedemo.

Referenced by CL_DisconnectEx().

◆ CL_TimeDemo_f()

void CL_TimeDemo_f ( cmd_state_t * cmd)

Definition at line 612 of file cl_demo.c.

613{
614 if (Cmd_Argc(cmd) != 2)
615 {
616 Con_Print("timedemo <demoname> : gets demo speeds\n");
617 return;
618 }
619
620 srand(0); // predictable random sequence for benchmarking
621
623
624// cls.td_starttime will be grabbed at the second frame of the demo, so
625// all the loading time doesn't get counted
626
627 // instantly hide console and deactivate it
630 scr_con_current = 0;
631
632 cls.timedemo = host.restless = true;
633 cls.td_frames = -2; // skip the first frame
634 cls.demonum = -1; // stop demo loop
635
636 // Might need to disable vsync
638}
unsigned int scr_con_current
Definition cl_screen.c:106
keydest_t key_dest
Definition keys.c:37
int key_consoleactive
Definition keys.c:38
@ key_game
Definition keys.h:372

References CL_PlayDemo(), cls, cmd(), Cmd_Argc(), Cmd_Argv(), Con_Print(), Cvar_Callback(), client_static_t::demonum, host, key_consoleactive, key_dest, key_game, host_static_t::restless, scr_con_current, client_static_t::td_frames, client_static_t::timedemo, and vid_vsync.

Referenced by CL_Demo_Init().

◆ CL_WriteDemoMessage()

void CL_WriteDemoMessage ( sizebuf_t * message)

Definition at line 110 of file cl_demo.c.

111{
112 int len;
113 int i;
114 float f;
115
116 if (cls.demopaused) // LadyHavoc: pausedemo
117 return;
118
119 len = LittleLong (message->cursize);
120 FS_Write (cls.demofile, &len, 4);
121 for (i=0 ; i<3 ; i++)
122 {
124 FS_Write (cls.demofile, &f, 4);
125 }
126 FS_Write (cls.demofile, message->data, message->cursize);
127}
string message
Definition progsdefs.qc:205
vec3_t viewangles
Definition client.h:786

References cl, cls, client_static_t::demofile, client_static_t::demopaused, f, FS_Write(), i, LittleFloat, LittleLong, message, and client_state_t::viewangles.

Referenced by CL_ParseServerMessage(), CL_Stop_f(), and CL_VM_Init().

◆ doublecmp_withoffset()

static int doublecmp_withoffset ( const void * a_,
const void * b_ )
static

Definition at line 487 of file cl_demo.c.

488{
489 const double *a = (const double *) ((const char *) a_ + doublecmp_offset);
490 const double *b = (const double *) ((const char *) b_ + doublecmp_offset);
491 if(*a > *b)
492 return +1;
493 if(*a < *b)
494 return -1;
495 return 0;
496}
dp_FragColor b
ret a

References a, b, and doublecmp_offset.

Variable Documentation

◆ doublecmp_offset

size_t doublecmp_offset
static

Definition at line 486 of file cl_demo.c.

Referenced by doublecmp_withoffset().