mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
Move timing from CL_Frame() to Qcommon_Frame().
This allows us to implement the global timing without an artificial brake slowing the game unnecessary down. This is only partial working, more changes and fixes are coming.
This commit is contained in:
parent
a0aa1c87c7
commit
c32f4b0e4a
4 changed files with 171 additions and 125 deletions
|
@ -111,12 +111,6 @@ Sys_Milliseconds(void)
|
|||
return curtime;
|
||||
}
|
||||
|
||||
void
|
||||
Sys_Sleep(int msec)
|
||||
{
|
||||
usleep((unsigned int)1000 * msec);
|
||||
}
|
||||
|
||||
void
|
||||
Sys_Mkdir(char *path)
|
||||
{
|
||||
|
|
|
@ -44,14 +44,12 @@ cvar_t *cl_noskins;
|
|||
cvar_t *cl_footsteps;
|
||||
cvar_t *cl_timeout;
|
||||
cvar_t *cl_predict;
|
||||
cvar_t *cl_maxfps;
|
||||
cvar_t *cl_drawfps;
|
||||
cvar_t *cl_gun;
|
||||
cvar_t *cl_add_particles;
|
||||
cvar_t *cl_add_lights;
|
||||
cvar_t *cl_add_entities;
|
||||
cvar_t *cl_add_blend;
|
||||
cvar_t *cl_async;
|
||||
|
||||
cvar_t *cl_shownet;
|
||||
cvar_t *cl_showmiss;
|
||||
|
@ -83,8 +81,6 @@ cvar_t *hand;
|
|||
cvar_t *gender;
|
||||
cvar_t *gender_auto;
|
||||
|
||||
cvar_t *gl_maxfps;
|
||||
|
||||
cvar_t *gl_stereo;
|
||||
cvar_t *gl_stereo_separation;
|
||||
cvar_t *gl_stereo_convergence;
|
||||
|
@ -484,9 +480,7 @@ CL_InitLocal(void)
|
|||
cl_footsteps = Cvar_Get("cl_footsteps", "1", 0);
|
||||
cl_noskins = Cvar_Get("cl_noskins", "0", 0);
|
||||
cl_predict = Cvar_Get("cl_predict", "1", 0);
|
||||
cl_maxfps = Cvar_Get("cl_maxfps", "60", CVAR_ARCHIVE);
|
||||
cl_drawfps = Cvar_Get("cl_drawfps", "0", CVAR_ARCHIVE);
|
||||
cl_async = Cvar_Get("cl_async", "1", CVAR_ARCHIVE);
|
||||
|
||||
cl_upspeed = Cvar_Get("cl_upspeed", "200", 0);
|
||||
cl_forwardspeed = Cvar_Get("cl_forwardspeed", "200", 0);
|
||||
|
@ -513,8 +507,6 @@ CL_InitLocal(void)
|
|||
cl_paused = Cvar_Get("paused", "0", 0);
|
||||
cl_timedemo = Cvar_Get("timedemo", "0", 0);
|
||||
|
||||
gl_maxfps = Cvar_Get("gl_maxfps", "95", CVAR_ARCHIVE);
|
||||
|
||||
gl_stereo = Cvar_Get( "gl_stereo", "0", CVAR_ARCHIVE );
|
||||
gl_stereo_separation = Cvar_Get( "gl_stereo_separation", "1", CVAR_ARCHIVE );
|
||||
gl_stereo_convergence = Cvar_Get( "gl_stereo_convergence", "1.4", CVAR_ARCHIVE );
|
||||
|
@ -711,60 +703,25 @@ CL_UpdateWindowedMouse(void)
|
|||
}
|
||||
}
|
||||
|
||||
int GLimp_GetRefreshRate(void);
|
||||
qboolean R_IsVSyncActive(void);
|
||||
|
||||
void
|
||||
CL_Frame(int msec)
|
||||
CL_Frame(int packetdelta, int renderdelta, int miscdelta, int timedelta,
|
||||
qboolean packetframe, qboolean renderframe, qboolean miscframe)
|
||||
{
|
||||
int nfps;
|
||||
int rfps;
|
||||
|
||||
static int lasttimecalled;
|
||||
|
||||
static int packetdelta = 1000;
|
||||
static int renderdelta = 1000;
|
||||
static int miscdelta = 1000;
|
||||
|
||||
qboolean packetframe = true;
|
||||
qboolean renderframe = true;
|
||||
qboolean miscframe = true;
|
||||
|
||||
// Dedicated?
|
||||
if (dedicated->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Target render frame rate
|
||||
if (R_IsVSyncActive())
|
||||
{
|
||||
rfps = GLimp_GetRefreshRate();
|
||||
|
||||
if (rfps > gl_maxfps->value)
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
|
||||
// The network framerate must not be higher then the render framerate
|
||||
nfps = (cl_maxfps->value > rfps) ? rfps : cl_maxfps->value;
|
||||
|
||||
// Adjust deltas
|
||||
packetdelta += msec;
|
||||
renderdelta += msec;
|
||||
miscdelta += msec;
|
||||
|
||||
// Calculate simulation time
|
||||
cls.nframetime = packetdelta * 0.001f;
|
||||
cls.rframetime = renderdelta * 0.001f;
|
||||
// Calculate simulation time.
|
||||
cls.nframetime = packetdelta / 1000000.0f;
|
||||
cls.rframetime = renderdelta / 1000000.0f;
|
||||
cls.realtime = curtime;
|
||||
cl.time += msec;
|
||||
cl.time += timedelta / 1000;
|
||||
|
||||
// Don't extrapolate too far ahead
|
||||
// Don't extrapolate too far ahead.
|
||||
if (cls.nframetime > 0.5f)
|
||||
{
|
||||
cls.nframetime = 0.5f;
|
||||
|
@ -775,72 +732,27 @@ CL_Frame(int msec)
|
|||
cls.rframetime = 0.5f;
|
||||
}
|
||||
|
||||
/* if in the debugger last frame, don't timeout */
|
||||
if (msec > 5000)
|
||||
// if in the debugger last frame, don't timeout.
|
||||
if (timedelta > 5000000)
|
||||
{
|
||||
cls.netchan.last_received = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
if (!cl_timedemo->value)
|
||||
{
|
||||
// Don't flood while connecting
|
||||
if ((cls.state == ca_connected) && (packetdelta < 100))
|
||||
// Don't throttle too much when connecting / loading.
|
||||
if ((cls.state == ca_connected) && (packetdelta > 100000))
|
||||
{
|
||||
packetframe = false;
|
||||
}
|
||||
|
||||
if (cl_async->value)
|
||||
{
|
||||
// Network frames
|
||||
if (packetdelta < (1000.0f / nfps))
|
||||
{
|
||||
packetframe = false;
|
||||
}
|
||||
else if (cls.nframetime == cls.rframetime)
|
||||
{
|
||||
packetframe = false;
|
||||
}
|
||||
|
||||
// Render frames
|
||||
if (renderdelta < (1000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
}
|
||||
|
||||
// Misc. stuff at 10 FPS
|
||||
if (miscdelta < 100.0f)
|
||||
{
|
||||
miscframe = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cap frames at gl_maxfps
|
||||
if (renderdelta < (1000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
packetframe = false;
|
||||
miscframe = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Throttle the game a little bit. 1000 FPS are enough.
|
||||
if (!packetframe && !renderframe && !cls.forcePacket && !userinfo_modified)
|
||||
{
|
||||
double frametime = (1000.0 / cl_maxfps->value - packetdelta) <= (1000.0 / gl_maxfps->value - renderdelta) ?
|
||||
(1000.0 / cl_maxfps->value - packetdelta) : (1000.0 / gl_maxfps->value - renderdelta);
|
||||
|
||||
if (frametime > 1) // FIXME: why > ??
|
||||
{
|
||||
Sys_Sleep(1);
|
||||
}
|
||||
|
||||
return;
|
||||
packetframe = true;
|
||||
}
|
||||
}
|
||||
else if (msec < 1)
|
||||
else
|
||||
{
|
||||
return;
|
||||
/* If we're running a timedemo ignore the global timing
|
||||
and pump out as many frames as we can. */
|
||||
packetframe = true;
|
||||
renderframe = true;
|
||||
miscframe = true;
|
||||
}
|
||||
|
||||
// Update input stuff
|
||||
|
@ -870,20 +782,14 @@ CL_Frame(int msec)
|
|||
|
||||
if (packetframe)
|
||||
{
|
||||
packetdelta = 0;
|
||||
|
||||
CL_SendCmd();
|
||||
CL_CheckForResend();
|
||||
}
|
||||
|
||||
if (renderframe)
|
||||
{
|
||||
renderdelta = 0;
|
||||
|
||||
if (miscframe)
|
||||
{
|
||||
miscdelta = 0;
|
||||
|
||||
VID_CheckChanges();
|
||||
}
|
||||
|
||||
|
|
|
@ -766,7 +766,6 @@ void Sys_Error(char *error, ...);
|
|||
void Sys_Quit(void);
|
||||
char *Sys_GetHomeDir(void);
|
||||
const char *Sys_GetBinaryDir(void);
|
||||
void Sys_Sleep(int msec);
|
||||
long long Sys_Microseconds(void);
|
||||
void Sys_FreeLibrary(void *handle);
|
||||
void *Sys_LoadLibrary(const char *path, const char *sym, void **handle);
|
||||
|
@ -778,7 +777,8 @@ void Sys_RedirectStdout(void);
|
|||
void CL_Init(void);
|
||||
void CL_Drop(void);
|
||||
void CL_Shutdown(void);
|
||||
void CL_Frame(int msec);
|
||||
void CL_Frame(int packetdelta, int renderdelta, int miscdelta, int timedelta, qboolean packetframe, qboolean renderframe,
|
||||
qboolean miscframe);
|
||||
void Con_Print(char *text);
|
||||
void SCR_BeginLoadingPlaque(void);
|
||||
|
||||
|
|
|
@ -35,7 +35,11 @@ cvar_t *developer;
|
|||
cvar_t *modder;
|
||||
cvar_t *timescale;
|
||||
cvar_t *fixedtime;
|
||||
cvar_t *portable;
|
||||
|
||||
// For timing calculations.
|
||||
cvar_t *cl_maxfps;
|
||||
cvar_t *gl_maxfps;
|
||||
cvar_t *cl_async;
|
||||
|
||||
#ifndef DEDICATED_ONLY
|
||||
cvar_t *showtrace;
|
||||
|
@ -46,6 +50,10 @@ extern cvar_t *logfile_active;
|
|||
extern jmp_buf abortframe; /* an ERR_DROP occured, exit the entire frame */
|
||||
extern zhead_t z_chain;
|
||||
|
||||
// Forward declarations
|
||||
int GLimp_GetRefreshRate(void);
|
||||
qboolean R_IsVSyncActive(void);
|
||||
|
||||
static byte chktbl[1024] = {
|
||||
0x84, 0x47, 0x51, 0xc1, 0x93, 0x22, 0x21, 0x24, 0x2f, 0x66, 0x60, 0x4d, 0xb0, 0x7c, 0xda,
|
||||
0x88, 0x54, 0x15, 0x2b, 0xc6, 0x6c, 0x89, 0xc5, 0x9d, 0x48, 0xee, 0xe6, 0x8a, 0xb5, 0xf4,
|
||||
|
@ -244,6 +252,11 @@ Qcommon_Init(int argc, char **argv)
|
|||
dedicated = Cvar_Get("dedicated", "0", CVAR_NOSET);
|
||||
#endif
|
||||
|
||||
// For timing calculations.
|
||||
cl_maxfps = Cvar_Get("cl_maxfps", "60", CVAR_ARCHIVE);
|
||||
gl_maxfps = Cvar_Get("gl_maxfps", "95", CVAR_ARCHIVE);
|
||||
cl_async = Cvar_Get("cl_async", "1", CVAR_ARCHIVE);
|
||||
|
||||
s = va("%s %s %s %s", YQ2VERSION, YQ2ARCH, BUILD_DATE, YQ2OSTYPE);
|
||||
Cvar_Get("version", s, CVAR_SERVERINFO | CVAR_NOSET);
|
||||
|
||||
|
@ -299,11 +312,58 @@ Qcommon_Frame(int msec)
|
|||
int time_after;
|
||||
#endif
|
||||
|
||||
// Target packetframerate.
|
||||
int pfps;
|
||||
|
||||
//Target renderframerate.
|
||||
int rfps;
|
||||
|
||||
// Time since last packetframe in microsec.
|
||||
static int packetdelta = 1000000;
|
||||
|
||||
// Time since last renderframe in microsec.
|
||||
static int renderdelta = 1000000;
|
||||
|
||||
// Time since last misc. frame in microsec.
|
||||
static int miscdelta = 100000;
|
||||
|
||||
// Accumulated time since last (packet|render|misc|time) frame.
|
||||
static int timedelta = 1001;
|
||||
|
||||
/* A packetframe runs the server and the client,
|
||||
but not the renderer. The minimal interval of
|
||||
packetframes is about 10.000 microsec. If run
|
||||
more often the movement prediction in pmove.c
|
||||
breaks. That's the Q2 variant if the famous
|
||||
125hz bug. */
|
||||
qboolean packetframe = true;
|
||||
|
||||
/* A rendererframe runs the renderer, but not the
|
||||
client. The minimal interval is about 1000
|
||||
microseconds. */
|
||||
qboolean renderframe = true;
|
||||
|
||||
/* A miscframe runs several maintenance task like
|
||||
loading sound samples for the background music.
|
||||
An interval of 100.000 microseconds is enough. */
|
||||
qboolean miscframe = true;
|
||||
|
||||
/* Timeframes are empty frames. We need to call the
|
||||
client at regular intervals to forward several
|
||||
internal timers, even if there's nothing to do.
|
||||
This is also necessary to speed up loading times. */
|
||||
qboolean timeframe = true;
|
||||
|
||||
|
||||
/* In case of ERR_DROP we're jumping here. Don't know
|
||||
if that' really save but it seems to work. So leave
|
||||
it alone. */
|
||||
if (setjmp(abortframe))
|
||||
{
|
||||
return; /* an ERR_DROP was thrown */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (log_stats->modified)
|
||||
{
|
||||
log_stats->modified = false;
|
||||
|
@ -360,6 +420,68 @@ Qcommon_Frame(int msec)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Calculate target packet- and renderframerate.
|
||||
if (R_IsVSyncActive())
|
||||
{
|
||||
rfps = GLimp_GetRefreshRate();
|
||||
|
||||
if (rfps > gl_maxfps->value)
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
|
||||
pfps = (cl_maxfps->value > rfps) ? rfps : cl_maxfps->value;
|
||||
|
||||
|
||||
// Calculate timings.
|
||||
packetdelta += msec;
|
||||
renderdelta += msec;
|
||||
miscdelta += msec;
|
||||
timedelta += msec;
|
||||
|
||||
if (cl_async->value)
|
||||
{
|
||||
// Network frames..
|
||||
if (packetdelta < (1000000.0f / pfps))
|
||||
{
|
||||
packetframe = false;
|
||||
}
|
||||
|
||||
// Render frames.
|
||||
if (renderdelta < (1000000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
}
|
||||
|
||||
// Misc. frames.
|
||||
if (miscdelta < 100000.0f)
|
||||
{
|
||||
miscframe = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cap frames at target framerate.
|
||||
if (renderdelta < (1000000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
packetframe = false;
|
||||
miscframe = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (timedelta < 1001)
|
||||
{
|
||||
timeframe = false;
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
s = Sys_ConsoleInput();
|
||||
|
@ -380,7 +502,9 @@ Qcommon_Frame(int msec)
|
|||
}
|
||||
#endif
|
||||
|
||||
SV_Frame();
|
||||
if (packetframe) {
|
||||
SV_Frame();
|
||||
}
|
||||
|
||||
#ifndef DEDICATED_ONLY
|
||||
if (host_speeds->value)
|
||||
|
@ -388,7 +512,10 @@ Qcommon_Frame(int msec)
|
|||
time_between = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
CL_Frame(msec / 1000);
|
||||
if (packetframe || renderframe || miscframe || timeframe) {
|
||||
CL_Frame(packetdelta, renderdelta, miscdelta, timedelta,
|
||||
packetframe, renderframe, miscframe);
|
||||
}
|
||||
|
||||
if (host_speeds->value)
|
||||
{
|
||||
|
@ -406,6 +533,25 @@ Qcommon_Frame(int msec)
|
|||
all, sv, gm, cl, rf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Reset deltas if necessary.
|
||||
if (packetframe) {
|
||||
packetdelta = 0;
|
||||
}
|
||||
|
||||
if (renderframe) {
|
||||
renderdelta = 0;
|
||||
}
|
||||
|
||||
if (miscframe) {
|
||||
miscdelta = 0;
|
||||
}
|
||||
|
||||
if (timeframe) {
|
||||
timedelta = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue