With cordite in the air, splintered steel, shell casings and powder burns, there’s only one explanation...
Discuss & improve the game engine.

Moderators: sparcdr, torhu, Tequila

Demo & screenshot updates for 1.1

Postby Lucky Bro » Sat Aug 15, 2009 9:12 pm

Good day,

I just made a patch basing on my 1.0 patch.

Nothing added or changed. I'm just not very interested in that now. I'll try to improve it later.
But I need it for my own purposes :)

1. New variables.
cl_autoRecordDemo 0 by default.
If set to 1 will record every game you play. 0 turns off this feature.
cl_autoDemoName 0 by default.
Will use improved demo naming instead of default one if set to 1. 0 turns this feature off.
cl_hideDemoMessage 0 by default.
Will hide big text "Recoding <demo name> : <amount> Kb" if set to 1. 0 turns off this feature.
cl_autoScreenshot 0 by default.
Will do a screenshot after each team match (only Team games and Timeouts!) if set to 1.
cl_autoScreenshotJPEG 0 by default.
Will do a screenshotJPEG after each team match (only Team games and Timeouts!) if set to 1.
cl_autoConsoleDump 0 by default.
Will do a console dump after each team match (only Team games and Timeouts!) if set to 1.
cl_autoScreenshotTime 220 by default.
Sets amout of frames to wait before take auto screenshot.
2. How to use new variables.
Just open the console and type:
/<variable name> <value>
For example:
/cl_autoRecordDemo 1
to turn on this feature.
NB: The autoscreenshot feature just checks for scorelimit/timout print message to arrive. I haven't found other way to do autoscreenshot feature without modifying QVMs. So you have to set cl_autoScreenshotTime value as it fits your game. If you set it to 0 you'll get the screenshot right when the message arrives (there is no scoretable in that particular moment).
Also TGA screenshot is taken for one frame later than JPEG one. It is done beause you can't do both at the same frame.
I suggest that you'll use only one value from these that will fit your needs. But still you are free to use both.

3. The source code patch.
You also may took my source code patch (at the bottom of the post).
If you can improve it - please post it in this topic after. I would like to use better version if it is possible.
If you want just to read it take a look in the spoiler:
Index: code/client/cl_cgame.c
===================================================================
--- code/client/cl_cgame.c (revision 263)
+++ code/client/cl_cgame.c (working copy)
@@ -456,11 +456,52 @@
====================
*/
intptr_t CL_CgameSystemCalls( intptr_t *args ) {
+ char timestamp[MAX_OSPATH]; //Required for auto Screenshot&ConsoleDump stuff
switch( args[0] ) {
case CG_PRINT:
#ifndef SMOKINGUNS
Com_Printf( "%s", (const char*)VMA(1) );
#else
+ if (cl_autoScreenshotJPEG->integer || cl_autoScreenshot->integer || cl_autoConsoleDump->integer) {
+ if (Q_strncmp(VMA(1),Cvar_VariableString("g_blueteamname"),strlen(Cvar_VariableString("g_blueteamname"))) == 0) {
+ if (Q_strncmp((const char*)VMA(1)+strlen(Cvar_VariableString("g_blueteamname"))," hit the scorelimit.",20) == 0) {
+ CL_CurrentTimestamp(timestamp);
+ if (cl_autoConsoleDump->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; condump \"%s.txt\"",cl_autoScreenshotTime->integer, timestamp) );
+ }
+ if (cl_autoScreenshotJPEG->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshotJPEG \"%s\"",cl_autoScreenshotTime->integer, timestamp ) );
+ }
+ if (cl_autoScreenshot->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshot \"%s\"",cl_autoScreenshotTime->integer+1, timestamp ) );
+ }
+ }
+ } else if (Q_strncmp(VMA(1),Cvar_VariableString("g_redteamname"),strlen(Cvar_VariableString("g_redteamname"))) == 0) {
+ if (Q_strncmp((const char*)VMA(1)+strlen(Cvar_VariableString("g_redteamname"))," hit the scorelimit.",20) == 0) {
+ CL_CurrentTimestamp(timestamp);
+ if (cl_autoConsoleDump->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; condump \"%s.txt\"",cl_autoScreenshotTime->integer, timestamp) );
+ }
+ if (cl_autoScreenshotJPEG->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshotJPEG \"%s\"",cl_autoScreenshotTime->integer, timestamp ) );
+ }
+ if (cl_autoScreenshot->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshot \"%s\"",cl_autoScreenshotTime->integer+1, timestamp ) );
+ }
+ }
+ } else if (Q_strncmp(VMA(1),"Timelimit hit.",14) == 0) {
+ CL_CurrentTimestamp(timestamp);
+ if (cl_autoConsoleDump->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; condump \"%s.txt\"",cl_autoScreenshotTime->integer, timestamp) );
+ }
+ if (cl_autoScreenshotJPEG->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshotJPEG \"%s\"",cl_autoScreenshotTime->integer, timestamp ) );
+ }
+ if (cl_autoScreenshot->integer) {
+ Cbuf_ExecuteText( EXEC_INSERT, va( "wait %d; screenshot \"%s\"",cl_autoScreenshotTime->integer+1, timestamp ) );
+ }
+ }
+ }
Com_Printf( "%s", (const char*)fixBadWords( VMA(1) ) );
#endif
return 0;
Index: code/client/cl_main.c
===================================================================
--- code/client/cl_main.c (revision 263)
+++ code/client/cl_main.c (working copy)
@@ -66,6 +66,12 @@
cvar_t *cl_timedemo;
cvar_t *cl_timedemoLog;
cvar_t *cl_autoRecordDemo;
+cvar_t *cl_autoDemoName;
+cvar_t *cl_hideDemoMessage;
+cvar_t *cl_autoScreenshot;
+cvar_t *cl_autoScreenshotJPEG;
+cvar_t *cl_autoConsoleDump;
+cvar_t *cl_autoScreenshotTime;
cvar_t *cl_aviFrameRate;
cvar_t *cl_aviMotionJpeg;
cvar_t *cl_forceavidemo;
@@ -531,6 +537,37 @@
Com_Printf ("Stopped demo.\n");
}

+void CL_CurrentTimestamp(char *fileName) {
+ //Build the name:
+ qtime_t now;
+ char *nowString;
+ char *p;
+ char mapName[ MAX_QPATH ];
+ char serverName[ MAX_OSPATH ];
+
+ Com_RealTime( &now );
+ nowString = va( "%04d%02d%02d-%02d%02d%02d",
+ 1900 + now.tm_year,
+ 1 + now.tm_mon,
+ now.tm_mday,
+ now.tm_hour,
+ now.tm_min,
+ now.tm_sec );
+
+ Q_strncpyz( serverName, cls.servername, MAX_OSPATH );
+ // Replace the ":" in the address as it is not a valid
+ // file name character
+ p = strstr( serverName, ":" );
+ if( p ) {
+ *p = '.';
+ }
+
+ Q_strncpyz( mapName, COM_SkipPath( cl.mapname ), sizeof( cl.mapname ) );
+ COM_StripExtension(mapName, mapName, sizeof(mapName));
+
+ Com_sprintf (fileName, MAX_OSPATH, "%s-%s-%s-%s",Cvar_VariableString("name"),nowString, serverName, mapName);
+}
+
/*
==================
CL_DemoFilename
@@ -601,15 +638,21 @@
Q_strncpyz( demoName, s, sizeof( demoName ) );
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
} else {
- int number;
-
- // scan for a free demo name
- for ( number = 0 ; number <= 9999 ; number++ ) {
- CL_DemoFilename( number, demoName );
+ if (cl_autoDemoName->integer) {
+ CL_CurrentTimestamp(demoName);
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
+ } else {
+ int number;
+ // scan for a free demo name
+ for ( number = 0 ; number <= 9999 ; number++ ) {
+ CL_DemoFilename( number, demoName );
+ Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );

- if (!FS_FileExists(name))
- break; // file doesn't exist
+ len = FS_ReadFile( name, NULL );
+ if ( len <= 0 ) {
+ break; // file doesn't exist
+ }
+ }
}
}

@@ -2665,34 +2708,10 @@
if( cl_autoRecordDemo->integer ) {
if( cls.state == CA_ACTIVE && !clc.demorecording && !clc.demoplaying ) {
// If not recording a demo, and we should be, start one
- qtime_t now;
- char *nowString;
- char *p;
- char mapName[ MAX_QPATH ];
- char serverName[ MAX_OSPATH ];
+ char timestamp[MAX_OSPATH];
+ CL_CurrentTimestamp(timestamp);

- Com_RealTime( &now );
- nowString = va( "%04d%02d%02d%02d%02d%02d",
- 1900 + now.tm_year,
- 1 + now.tm_mon,
- now.tm_mday,
- now.tm_hour,
- now.tm_min,
- now.tm_sec );
-
- Q_strncpyz( serverName, cls.servername, MAX_OSPATH );
- // Replace the ":" in the address as it is not a valid
- // file name character
- p = strstr( serverName, ":" );
- if( p ) {
- *p = '.';
- }
-
- Q_strncpyz( mapName, COM_SkipPath( cl.mapname ), sizeof( cl.mapname ) );
- COM_StripExtension(mapName, mapName, sizeof(mapName));
-
- Cbuf_ExecuteText( EXEC_NOW,
- va( "record %s-%s-%s", nowString, serverName, mapName ) );
+ Cbuf_ExecuteText( EXEC_NOW, va( "record %s", timestamp) );
}
else if( cls.state != CA_ACTIVE && clc.demorecording ) {
// Recording, but not CA_ACTIVE, so stop recording
@@ -3105,6 +3124,12 @@
cl_timedemo = Cvar_Get ("timedemo", "0", 0);
cl_timedemoLog = Cvar_Get ("cl_timedemoLog", "", CVAR_ARCHIVE);
cl_autoRecordDemo = Cvar_Get ("cl_autoRecordDemo", "0", CVAR_ARCHIVE);
+ cl_autoDemoName = Cvar_Get ("cl_autoDemoName", "0", CVAR_ARCHIVE);
+ cl_hideDemoMessage = Cvar_Get ("cl_hideDemoMessage", "0", CVAR_ARCHIVE);
+ cl_autoScreenshot = Cvar_Get ("cl_autoScreenshot", "0", CVAR_ARCHIVE);
+ cl_autoScreenshotJPEG = Cvar_Get ("cl_autoScreenshotJPEG", "0", CVAR_ARCHIVE);
+ cl_autoScreenshotTime = Cvar_Get ("cl_autoScreenshotTime", "260", CVAR_ARCHIVE);
+ cl_autoConsoleDump = Cvar_Get ("cl_autoConsoleDump", "0", CVAR_ARCHIVE);
cl_aviFrameRate = Cvar_Get ("cl_aviFrameRate", "25", CVAR_ARCHIVE);
cl_aviMotionJpeg = Cvar_Get ("cl_aviMotionJpeg", "1", CVAR_ARCHIVE);
cl_forceavidemo = Cvar_Get ("cl_forceavidemo", "0", 0);
Index: code/client/cl_scrn.c
===================================================================
--- code/client/cl_scrn.c (revision 263)
+++ code/client/cl_scrn.c (working copy)
@@ -530,7 +530,7 @@
case CA_ACTIVE:
// always supply STEREO_CENTER as vieworg offset is now done by the engine.
CL_CGameRendering(stereoFrame);
- SCR_DrawDemoRecording();
+ if (!cl_hideDemoMessage->integer)SCR_DrawDemoRecording();
#ifdef USE_VOIP
SCR_DrawVoipMeter();
#endif
Index: code/client/client.h
===================================================================
--- code/client/client.h (revision 263)
+++ code/client/client.h (working copy)
@@ -405,6 +405,12 @@

extern cvar_t *cl_lanForcePackets;
extern cvar_t *cl_autoRecordDemo;
+extern cvar_t *cl_autoDemoName;
+extern cvar_t *cl_hideDemoMessage;
+extern cvar_t *cl_autoScreenshot;
+extern cvar_t *cl_autoScreenshotJPEG;
+extern cvar_t *cl_autoScreenshotTime;
+extern cvar_t *cl_autoConsoleDump;

extern cvar_t *cl_consoleKeys;

@@ -449,6 +455,8 @@
void CL_ReadDemoMessage( void );
void CL_StopRecord_f(void);

+void CL_CurrentTimestamp(char *fileName);
+
void CL_InitDownloads(void);
void CL_NextDownload(void);

4. File names description.
For every feature it is the following:
<player name><timestamp>-<server name>-<map name>
5. Improvement plans
To include explicitly game mode in timestamp.
To write players names if it is Duel (DM 1vs1) without specs names.
To improve screenshot taking system by sending proper message from server VM and catch it on client side.
To include teamnames after g_blue(red)teamname will be allowed to vote to make it easy for clan matches.
To make appear "Recording" message as it was suggested by mLy in right upper corner with smaller text if we won't get custom HUDs. If we get them to make that message editable via HUD files.

Feel free to suggest improvements to these variables. As well as to ask help about them.
Also if you have better solutions or ways to record and playback demos - post them too (maybe not in this thread, but still - share them - I'm looking for those things too).

Here is the patch:
DemoImpr.patch

Thank you for attention!
Have fun!

P.S. Thank you Conq for helping figure out some hard things during this patch creation ;)
"You should know that the lies won't hide your flaws/No sense in hiding all of yours/You gave up on your dreams along the way" (c) "Fake it" by Seether
P.S. English isn't my native language.
User avatar
Lucky Bro
Gunslinger
 
Posts: 143
Joined: Mon Mar 09, 2009 4:12 pm



Return to Code

Show Sidebar
Show Sidebar

User Control Panel

cron