mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 23:11:38 +00:00
Add demo to "movie" conversion.
It currently writes a series of png files (QF/qfmvNNNNNN.png), at a fixed rate of 30fps, with no sound recording.
This commit is contained in:
parent
b13a2b6dbd
commit
423e08ce21
12 changed files with 186 additions and 38 deletions
|
@ -56,6 +56,7 @@ void SCR_DrawTurtle (void);
|
||||||
void SCR_DrawPause (void);
|
void SCR_DrawPause (void);
|
||||||
|
|
||||||
struct tex_s *SCR_ScreenShot (int width, int height);
|
struct tex_s *SCR_ScreenShot (int width, int height);
|
||||||
|
struct tex_s *SCR_CaptureBGR (void);
|
||||||
void SCR_DrawStringToSnap (const char *s, struct tex_s *tex, int x, int y);
|
void SCR_DrawStringToSnap (const char *s, struct tex_s *tex, int x, int y);
|
||||||
int MipColor (int r, int g, int b);
|
int MipColor (int r, int g, int b);
|
||||||
int SCR_ModalMessage (const char *text);
|
int SCR_ModalMessage (const char *text);
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __attribute__ ((used)) const char rcsid[] =
|
static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
"$Id$";
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
#ifdef HAVE_STRING_H
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
@ -66,6 +65,24 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
|
|
||||||
/* SCREEN SHOTS */
|
/* SCREEN SHOTS */
|
||||||
|
|
||||||
|
VISIBLE tex_t *
|
||||||
|
SCR_CaptureBGR (void)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
tex_t *tex;
|
||||||
|
|
||||||
|
count = vid.width * vid.height;
|
||||||
|
tex = malloc (field_offset (tex_t, data[count * 3]));
|
||||||
|
SYS_CHECKMEM (tex);
|
||||||
|
tex->width = vid.width;
|
||||||
|
tex->height = vid.height;
|
||||||
|
tex->format = tex_rgb;
|
||||||
|
tex->palette = 0;
|
||||||
|
qfglReadPixels (0, 0, tex->width, tex->height, GL_BGR_EXT,
|
||||||
|
GL_UNSIGNED_BYTE, tex->data);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
VISIBLE tex_t *
|
VISIBLE tex_t *
|
||||||
SCR_ScreenShot (int width, int height)
|
SCR_ScreenShot (int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -133,20 +150,18 @@ SCR_ScreenShot (int width, int height)
|
||||||
void
|
void
|
||||||
SCR_ScreenShot_f (void)
|
SCR_ScreenShot_f (void)
|
||||||
{
|
{
|
||||||
byte *buffer;
|
|
||||||
dstring_t *pcxname = dstring_new ();
|
dstring_t *pcxname = dstring_new ();
|
||||||
|
|
||||||
// find a file name to save it to
|
// find a file name to save it to
|
||||||
if (!QFS_NextFilename (pcxname,
|
if (!QFS_NextFilename (pcxname,
|
||||||
va ("%s/qf", qfs_gamedir->dir.shots), ".tga")) {
|
va ("%s/qf", qfs_gamedir->dir.shots), ".tga")) {
|
||||||
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
|
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
|
||||||
} else {
|
} else {
|
||||||
buffer = malloc (vid.width * vid.height * 3);
|
tex_t *tex;
|
||||||
SYS_CHECKMEM (buffer);
|
|
||||||
qfglReadPixels (0, 0, vid.width, vid.height, GL_BGR_EXT,
|
tex = SCR_CaptureBGR ();
|
||||||
GL_UNSIGNED_BYTE, buffer);
|
WriteTGAfile (pcxname->str, tex->data, tex->width, tex->height);
|
||||||
WriteTGAfile (pcxname->str, buffer, vid.width, vid.height);
|
free (tex);
|
||||||
free (buffer);
|
|
||||||
Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str);
|
Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str);
|
||||||
}
|
}
|
||||||
dstring_delete (pcxname);
|
dstring_delete (pcxname);
|
||||||
|
|
|
@ -203,6 +203,31 @@ SCR_UpdateScreen (double realtime, SCR_Func *scr_funcs)
|
||||||
qfglFlush ();
|
qfglFlush ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VISIBLE tex_t *
|
||||||
|
SCR_CaptureBGR (void)
|
||||||
|
{
|
||||||
|
byte *r, *b;
|
||||||
|
int count, i;
|
||||||
|
tex_t *tex;
|
||||||
|
|
||||||
|
count = vid.width * vid.height;
|
||||||
|
tex = malloc (field_offset (tex_t, data[count * 3]));
|
||||||
|
SYS_CHECKMEM (tex);
|
||||||
|
tex->width = vid.width;
|
||||||
|
tex->height = vid.height;
|
||||||
|
tex->format = tex_rgb;
|
||||||
|
tex->palette = 0;
|
||||||
|
qfglReadPixels (0, 0, vid.width, vid.height, GL_RGB,
|
||||||
|
GL_UNSIGNED_BYTE, tex->data);
|
||||||
|
for (i = 0, r = tex->data, b = tex->data + 2; i < count;
|
||||||
|
i++, r += 3, b += 3) {
|
||||||
|
byte t = *b;
|
||||||
|
*b = *r;
|
||||||
|
*r = t;
|
||||||
|
}
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
VISIBLE tex_t *
|
VISIBLE tex_t *
|
||||||
SCR_ScreenShot (int width, int height)
|
SCR_ScreenShot (int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -212,28 +237,18 @@ SCR_ScreenShot (int width, int height)
|
||||||
VISIBLE void
|
VISIBLE void
|
||||||
SCR_ScreenShot_f (void)
|
SCR_ScreenShot_f (void)
|
||||||
{
|
{
|
||||||
byte *buffer, *r, *b;
|
|
||||||
dstring_t *name = dstring_new ();
|
dstring_t *name = dstring_new ();
|
||||||
int size, i;
|
|
||||||
|
|
||||||
// find a file name to save it to
|
// find a file name to save it to
|
||||||
if (!QFS_NextFilename (name,
|
if (!QFS_NextFilename (name,
|
||||||
va ("%s/qf", qfs_gamedir->dir.shots), ".png")) {
|
va ("%s/qf", qfs_gamedir->dir.shots), ".png")) {
|
||||||
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PNG file\n");
|
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PNG file\n");
|
||||||
} else {
|
} else {
|
||||||
size = vid.width * vid.height;
|
tex_t *tex;
|
||||||
buffer = malloc (size * 3);
|
|
||||||
SYS_CHECKMEM (buffer);
|
tex = SCR_CaptureBGR ();
|
||||||
qfglReadPixels (0, 0, vid.width, vid.height, GL_RGB,
|
WritePNGqfs (name->str, tex->data, tex->width, tex->height);
|
||||||
GL_UNSIGNED_BYTE, buffer);
|
free (tex);
|
||||||
// FIXME have to swap rgb (WritePNG bug?)
|
|
||||||
for (i = 0, r = buffer, b = buffer + 2; i < size; i++, r+=3, b+=3) {
|
|
||||||
byte t = *b;
|
|
||||||
*b = *r;
|
|
||||||
*r = t;
|
|
||||||
}
|
|
||||||
WritePNGqfs (name->str, buffer, vid.width, vid.height);
|
|
||||||
free (buffer);
|
|
||||||
Sys_Printf ("Wrote %s/%s\n", qfs_userpath, name->str);
|
Sys_Printf ("Wrote %s/%s\n", qfs_userpath, name->str);
|
||||||
}
|
}
|
||||||
dstring_delete (name);
|
dstring_delete (name);
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __attribute__ ((used)) const char rcsid[] =
|
static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
"$Id$";
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
#ifdef HAVE_STRING_H
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
@ -87,6 +86,36 @@ SCR_ApplyBlend (void) // Used to be V_UpdatePalette
|
||||||
|
|
||||||
/* SCREEN SHOTS */
|
/* SCREEN SHOTS */
|
||||||
|
|
||||||
|
VISIBLE tex_t *
|
||||||
|
SCR_CaptureBGR (void)
|
||||||
|
{
|
||||||
|
int count, x, y;
|
||||||
|
tex_t *tex;
|
||||||
|
const byte *src;
|
||||||
|
byte *dst;
|
||||||
|
|
||||||
|
count = vid.width * vid.height;
|
||||||
|
tex = malloc (field_offset (tex_t, data[count * 3]));
|
||||||
|
SYS_CHECKMEM (tex);
|
||||||
|
tex->width = vid.width;
|
||||||
|
tex->height = vid.height;
|
||||||
|
tex->format = tex_rgb;
|
||||||
|
tex->palette = 0;
|
||||||
|
D_EnableBackBufferAccess ();
|
||||||
|
src = vid.buffer;
|
||||||
|
for (y = 0; y < tex->height; y++) {
|
||||||
|
dst = tex->data + (tex->height - 1 - y) * tex->width * 3;
|
||||||
|
for (x = 0; x < tex->width; x++) {
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 2]; // blue
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 1]; // green
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 0]; // red
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
D_DisableBackBufferAccess ();
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
tex_t *
|
tex_t *
|
||||||
SCR_ScreenShot (int width, int height)
|
SCR_ScreenShot (int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +188,7 @@ SCR_ScreenShot_f (void)
|
||||||
pcx_t *pcx;
|
pcx_t *pcx;
|
||||||
int pcx_len;
|
int pcx_len;
|
||||||
|
|
||||||
// find a file name to save it to
|
// find a file name to save it to
|
||||||
if (!QFS_NextFilename (pcxname,
|
if (!QFS_NextFilename (pcxname,
|
||||||
va ("%s/qf", qfs_gamedir->dir.shots), ".pcx")) {
|
va ("%s/qf", qfs_gamedir->dir.shots), ".pcx")) {
|
||||||
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
|
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __attribute__ ((used)) const char rcsid[] =
|
static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
"$Id$";
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
#ifdef HAVE_STRING_H
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
@ -155,6 +154,36 @@ SCR_ApplyBlend (void) // Used to be V_UpdatePalette
|
||||||
|
|
||||||
/* SCREEN SHOTS */
|
/* SCREEN SHOTS */
|
||||||
|
|
||||||
|
VISIBLE tex_t *
|
||||||
|
SCR_CaptureBGR (void)
|
||||||
|
{
|
||||||
|
int count, x, y;
|
||||||
|
tex_t *tex;
|
||||||
|
const byte *src;
|
||||||
|
byte *dst;
|
||||||
|
|
||||||
|
count = vid.width * vid.height;
|
||||||
|
tex = malloc (field_offset (tex_t, data[count * 3]));
|
||||||
|
SYS_CHECKMEM (tex);
|
||||||
|
tex->width = vid.width;
|
||||||
|
tex->height = vid.height;
|
||||||
|
tex->format = tex_rgb;
|
||||||
|
tex->palette = 0;
|
||||||
|
D_EnableBackBufferAccess ();
|
||||||
|
src = vid.buffer;
|
||||||
|
for (y = 0; y < tex->height; y++) {
|
||||||
|
dst = tex->data + (tex->height - 1 - y) * tex->width * 3;
|
||||||
|
for (x = 0; x < tex->width; x++) {
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 2]; // blue
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 1]; // green
|
||||||
|
*dst++ = vid.basepal[*src * 3 + 0]; // red
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
D_DisableBackBufferAccess ();
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
VISIBLE tex_t *
|
VISIBLE tex_t *
|
||||||
SCR_ScreenShot (int width, int height)
|
SCR_ScreenShot (int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -168,7 +197,7 @@ SCR_ScreenShot_f (void)
|
||||||
pcx_t *pcx = 0;
|
pcx_t *pcx = 0;
|
||||||
int pcx_len;
|
int pcx_len;
|
||||||
|
|
||||||
// find a file name to save it to
|
// find a file name to save it to
|
||||||
if (!QFS_NextFilename (pcxname,
|
if (!QFS_NextFilename (pcxname,
|
||||||
va ("%s/qf", qfs_gamedir->dir.shots), ".pcx")) {
|
va ("%s/qf", qfs_gamedir->dir.shots), ".pcx")) {
|
||||||
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
|
Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
|
||||||
|
|
|
@ -119,6 +119,7 @@ typedef struct
|
||||||
// demo recording info must be here, because record is started before
|
// demo recording info must be here, because record is started before
|
||||||
// entering a map (and clearing client_state_t)
|
// entering a map (and clearing client_state_t)
|
||||||
qboolean demorecording;
|
qboolean demorecording;
|
||||||
|
qboolean demo_capture;
|
||||||
qboolean demoplayback;
|
qboolean demoplayback;
|
||||||
qboolean timedemo;
|
qboolean timedemo;
|
||||||
int forcetrack; // -1 = use normal cd track
|
int forcetrack; // -1 = use normal cd track
|
||||||
|
|
|
@ -126,6 +126,7 @@ CL_StopPlayback (void)
|
||||||
Qclose (cls.demofile);
|
Qclose (cls.demofile);
|
||||||
cls.demofile = NULL;
|
cls.demofile = NULL;
|
||||||
CL_SetState (ca_disconnected);
|
CL_SetState (ca_disconnected);
|
||||||
|
cls.demo_capture = 0;
|
||||||
cls.demoplayback = 0;
|
cls.demoplayback = 0;
|
||||||
key_game_target = IMT_0;
|
key_game_target = IMT_0;
|
||||||
Key_SetKeyDest (key_game);
|
Key_SetKeyDest (key_game);
|
||||||
|
@ -384,9 +385,19 @@ CL_PlayDemo_f (void)
|
||||||
if (cmd_source != src_command)
|
if (cmd_source != src_command)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Cmd_Argc () != 2) {
|
switch (Cmd_Argc ()) {
|
||||||
Sys_Printf ("play <demoname> : plays a demo\n");
|
case 2:
|
||||||
return;
|
cls.demo_capture = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (!strcmp (Cmd_Argv (2), "rec")) {
|
||||||
|
cls.demo_capture = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
Sys_Printf ("play <demoname> : plays a demo\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop
|
timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop
|
||||||
strncpy (demoname, Cmd_Argv (1), sizeof (demoname));
|
strncpy (demoname, Cmd_Argv (1), sizeof (demoname));
|
||||||
|
|
|
@ -41,12 +41,15 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
#include "QF/cmd.h"
|
#include "QF/cmd.h"
|
||||||
#include "QF/console.h"
|
#include "QF/console.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/image.h"
|
||||||
#include "QF/input.h"
|
#include "QF/input.h"
|
||||||
#include "QF/keys.h"
|
#include "QF/keys.h"
|
||||||
#include "QF/msg.h"
|
#include "QF/msg.h"
|
||||||
#include "QF/plugin.h"
|
#include "QF/plugin.h"
|
||||||
|
#include "QF/png.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
#include "QF/qargs.h"
|
#include "QF/qargs.h"
|
||||||
|
#include "QF/screen.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
#include "QF/vid.h"
|
#include "QF/vid.h"
|
||||||
|
@ -638,6 +641,9 @@ _Host_Frame (float time)
|
||||||
|
|
||||||
rand (); // keep the random time dependent
|
rand (); // keep the random time dependent
|
||||||
|
|
||||||
|
if (cls.demo_capture)
|
||||||
|
time = 1.0 / 30; //FIXME fixed 30fps atm
|
||||||
|
|
||||||
// decide the simulation time
|
// decide the simulation time
|
||||||
if ((sleeptime = Host_FilterTime (time)) != 0) {
|
if ((sleeptime = Host_FilterTime (time)) != 0) {
|
||||||
// don't run too fast, or packet will flood outs
|
// don't run too fast, or packet will flood outs
|
||||||
|
@ -685,6 +691,14 @@ _Host_Frame (float time)
|
||||||
else
|
else
|
||||||
host_time += host_frametime; //FIXME is this needed? vcr stuff
|
host_time += host_frametime; //FIXME is this needed? vcr stuff
|
||||||
|
|
||||||
|
if (cls.demo_capture) {
|
||||||
|
tex_t *tex = SCR_CaptureBGR ();
|
||||||
|
WritePNGqfs (va ("%s/qfmv%06d.png", qfs_gamedir->dir.shots,
|
||||||
|
cls.demo_capture++),
|
||||||
|
tex->data, tex->width, tex->height);
|
||||||
|
free (tex);
|
||||||
|
}
|
||||||
|
|
||||||
host_framecount++;
|
host_framecount++;
|
||||||
fps_count++;
|
fps_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
#include "QF/cdaudio.h"
|
#include "QF/cdaudio.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/plugin.h"
|
#include "QF/plugin.h"
|
||||||
|
#include "QF/screen.h"
|
||||||
|
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
@ -70,6 +71,13 @@ CL_UpdateScreen (double realtime)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tex_s *
|
||||||
|
SCR_CaptureBGR (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_Cmd_ForwardToServer (void)
|
CL_Cmd_ForwardToServer (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,6 +167,7 @@ typedef struct
|
||||||
// demo recording info must be here, because record is started before
|
// demo recording info must be here, because record is started before
|
||||||
// entering a map (and clearing client_state_t)
|
// entering a map (and clearing client_state_t)
|
||||||
qboolean demorecording;
|
qboolean demorecording;
|
||||||
|
qboolean demo_capture;
|
||||||
qboolean demoplayback;
|
qboolean demoplayback;
|
||||||
qboolean demoplayback2;
|
qboolean demoplayback2;
|
||||||
qboolean findtrack;
|
qboolean findtrack;
|
||||||
|
|
|
@ -144,6 +144,7 @@ CL_StopPlayback (void)
|
||||||
Qclose (cls.demofile);
|
Qclose (cls.demofile);
|
||||||
cls.demofile = NULL;
|
cls.demofile = NULL;
|
||||||
CL_SetState (ca_disconnected);
|
CL_SetState (ca_disconnected);
|
||||||
|
cls.demo_capture = 0;
|
||||||
cls.demoplayback = 0;
|
cls.demoplayback = 0;
|
||||||
cls.demoplayback2 = 0;
|
cls.demoplayback2 = 0;
|
||||||
demotime_cached = 0;
|
demotime_cached = 0;
|
||||||
|
@ -933,9 +934,19 @@ CL_StartDemo (void)
|
||||||
static void
|
static void
|
||||||
CL_PlayDemo_f (void)
|
CL_PlayDemo_f (void)
|
||||||
{
|
{
|
||||||
if (Cmd_Argc () != 2) {
|
switch (Cmd_Argc ()) {
|
||||||
Sys_Printf ("play <demoname> : plays a demo\n");
|
case 2:
|
||||||
return;
|
cls.demo_capture = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (!strcmp (Cmd_Argv (2), "rec")) {
|
||||||
|
cls.demo_capture = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
Sys_Printf ("play <demoname> : plays a demo\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop
|
timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop
|
||||||
// disconnect from server
|
// disconnect from server
|
||||||
|
|
|
@ -71,11 +71,13 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
#include "QF/console.h"
|
#include "QF/console.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/draw.h"
|
#include "QF/draw.h"
|
||||||
|
#include "QF/image.h"
|
||||||
#include "QF/input.h"
|
#include "QF/input.h"
|
||||||
#include "QF/keys.h"
|
#include "QF/keys.h"
|
||||||
#include "QF/model.h"
|
#include "QF/model.h"
|
||||||
#include "QF/msg.h"
|
#include "QF/msg.h"
|
||||||
#include "QF/plugin.h"
|
#include "QF/plugin.h"
|
||||||
|
#include "QF/png.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
#include "QF/qargs.h"
|
#include "QF/qargs.h"
|
||||||
#include "QF/qendian.h"
|
#include "QF/qendian.h"
|
||||||
|
@ -1488,7 +1490,7 @@ Host_SimulationTime (float time)
|
||||||
if (oldrealtime > realtime)
|
if (oldrealtime > realtime)
|
||||||
oldrealtime = 0;
|
oldrealtime = 0;
|
||||||
|
|
||||||
if (cls.timedemo)
|
if (cls.demoplayback)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (cl_maxfps->value <= 0)
|
if (cl_maxfps->value <= 0)
|
||||||
|
@ -1523,6 +1525,9 @@ Host_Frame (float time)
|
||||||
// something bad happened, or the server disconnected
|
// something bad happened, or the server disconnected
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (cls.demo_capture)
|
||||||
|
time = 1.0 / 30; //FIXME fixed 30fps atm
|
||||||
|
|
||||||
// decide the simulation time
|
// decide the simulation time
|
||||||
if ((sleeptime = Host_SimulationTime (time)) != 0) {
|
if ((sleeptime = Host_SimulationTime (time)) != 0) {
|
||||||
#ifdef HAVE_USLEEP
|
#ifdef HAVE_USLEEP
|
||||||
|
@ -1623,6 +1628,14 @@ Host_Frame (float time)
|
||||||
pass1 + pass2 + pass3, pass1, pass2, pass3);
|
pass1 + pass2 + pass3, pass1, pass2, pass3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cls.demo_capture) {
|
||||||
|
tex_t *tex = SCR_CaptureBGR ();
|
||||||
|
WritePNGqfs (va ("%s/qfmv%06d.png", qfs_gamedir->dir.shots,
|
||||||
|
cls.demo_capture++),
|
||||||
|
tex->data, tex->width, tex->height);
|
||||||
|
free (tex);
|
||||||
|
}
|
||||||
|
|
||||||
host_framecount++;
|
host_framecount++;
|
||||||
fps_count++;
|
fps_count++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue