mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- Added vid_maxfps cvar to limit the frame rate to some arbitrary rate between 35 and 1000 FPS. It
defaults to 200. Setting it to 0 will restore the previous behavior of having no frame rate limit. Note that vid_maxfps 35 is NOT the same as cl_capfps 1. cl_capfps caps the frame rate by tying the video update directly to the game timer. With vid_maxfps 35, the video update and game timer are running on separate timers, and results will not be as good as with cl_capfps 1, which uses only one timer. SVN r3872 (trunk)
This commit is contained in:
parent
1e234c9853
commit
11ca707485
8 changed files with 125 additions and 2 deletions
|
@ -60,6 +60,7 @@
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
|
#include "hardware.h"
|
||||||
#include "intermission/intermission.h"
|
#include "intermission/intermission.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Int, disableautosave)
|
EXTERN_CVAR (Int, disableautosave)
|
||||||
|
@ -135,7 +136,18 @@ static int oldentertics;
|
||||||
|
|
||||||
extern bool advancedemo;
|
extern bool advancedemo;
|
||||||
|
|
||||||
CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
{
|
||||||
|
// Do not use the separate FPS limit timer if we are limiting FPS with this.
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
I_SetFPSLimit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_SetFPSLimit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [RH] Special "ticcmds" get stored in here
|
// [RH] Special "ticcmds" get stored in here
|
||||||
static struct TicSpecial
|
static struct TicSpecial
|
||||||
|
|
|
@ -177,6 +177,10 @@ void I_ClosestResolution (int *width, int *height, int bits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_SetFPSLimit(int limit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
||||||
|
|
||||||
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
|
|
@ -59,6 +59,8 @@ void I_InitGraphics ();
|
||||||
void I_ShutdownGraphics ();
|
void I_ShutdownGraphics ();
|
||||||
void I_CreateRenderer();
|
void I_CreateRenderer();
|
||||||
|
|
||||||
|
void I_SetFPSLimit(int limit);
|
||||||
|
|
||||||
extern IVideo *Video;
|
extern IVideo *Video;
|
||||||
|
|
||||||
#endif // __HARDWARE_H__
|
#endif // __HARDWARE_H__
|
||||||
|
|
|
@ -1208,6 +1208,11 @@ void D3DFB::Flip()
|
||||||
BlockSurface[BlockNum]->UnlockRect();
|
BlockSurface[BlockNum]->UnlockRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Limiting the frame rate is as simple as waiting for the timer to signal this event.
|
||||||
|
if (FPSLimitEvent != NULL)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(FPSLimitEvent, 1000);
|
||||||
|
}
|
||||||
D3DDevice->Present(NULL, NULL, NULL, NULL);
|
D3DDevice->Present(NULL, NULL, NULL, NULL);
|
||||||
InScene = false;
|
InScene = false;
|
||||||
|
|
||||||
|
|
|
@ -1201,6 +1201,10 @@ void DDrawFB::Update ()
|
||||||
LockCount = 0;
|
LockCount = 0;
|
||||||
UpdatePending = false;
|
UpdatePending = false;
|
||||||
|
|
||||||
|
if (FPSLimitEvent != NULL)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(FPSLimitEvent, 1000);
|
||||||
|
}
|
||||||
if (!Windowed && AppActive && !SessionState /*&& !UseBlitter && !MustBuffer*/)
|
if (!Windowed && AppActive && !SessionState /*&& !UseBlitter && !MustBuffer*/)
|
||||||
{
|
{
|
||||||
HRESULT hr = PrimarySurf->Flip (NULL, FlipFlags);
|
HRESULT hr = PrimarySurf->Flip (NULL, FlipFlags);
|
||||||
|
|
|
@ -62,6 +62,9 @@ void I_CreateRenderer();
|
||||||
void I_SaveWindowedPos ();
|
void I_SaveWindowedPos ();
|
||||||
void I_RestoreWindowedPos ();
|
void I_RestoreWindowedPos ();
|
||||||
|
|
||||||
|
void I_SetFPSLimit(int limit);
|
||||||
|
|
||||||
|
|
||||||
extern IVideo *Video;
|
extern IVideo *Video;
|
||||||
|
|
||||||
#endif // __HARDWARE_H__
|
#endif // __HARDWARE_H__
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
|
|
||||||
EXTERN_CVAR (Bool, vid_vsync)
|
EXTERN_CVAR (Bool, vid_vsync)
|
||||||
|
|
||||||
|
extern HANDLE FPSLimitEvent;
|
||||||
|
|
||||||
class D3DTex;
|
class D3DTex;
|
||||||
class D3DPal;
|
class D3DPal;
|
||||||
struct FSoftwareRenderer;
|
struct FSoftwareRenderer;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define _WIN32_WINNT 0x0501
|
#define _WIN32_WINNT 0x0501
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
|
||||||
|
@ -87,6 +88,8 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
|
static void StopFPSLimit();
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
extern HWND Window;
|
extern HWND Window;
|
||||||
|
@ -98,20 +101,38 @@ extern bool VidResizing;
|
||||||
|
|
||||||
EXTERN_CVAR (Bool, fullscreen)
|
EXTERN_CVAR (Bool, fullscreen)
|
||||||
EXTERN_CVAR (Float, Gamma)
|
EXTERN_CVAR (Float, Gamma)
|
||||||
|
EXTERN_CVAR (Bool, cl_capfps)
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
static HMODULE D3D9_dll;
|
static HMODULE D3D9_dll;
|
||||||
static HMODULE DDraw_dll;
|
static HMODULE DDraw_dll;
|
||||||
|
static UINT FPSLimitTimer;
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
IDirectDraw2 *DDraw;
|
IDirectDraw2 *DDraw;
|
||||||
IDirect3D9 *D3D;
|
IDirect3D9 *D3D;
|
||||||
IDirect3DDevice9 *D3Device;
|
IDirect3DDevice9 *D3Device;
|
||||||
|
HANDLE FPSLimitEvent;
|
||||||
|
|
||||||
CVAR (Bool, vid_forceddraw, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR (Bool, vid_forceddraw, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
{
|
||||||
|
if (vid_maxfps < TICRATE && vid_maxfps != 0)
|
||||||
|
{
|
||||||
|
vid_maxfps = TICRATE;
|
||||||
|
}
|
||||||
|
else if (vid_maxfps > 1000)
|
||||||
|
{
|
||||||
|
vid_maxfps = 1000;
|
||||||
|
}
|
||||||
|
else if (cl_capfps == 0)
|
||||||
|
{
|
||||||
|
I_SetFPSLimit(vid_maxfps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if VID_FILE_DEBUG
|
#if VID_FILE_DEBUG
|
||||||
FILE *dbg;
|
FILE *dbg;
|
||||||
|
@ -714,4 +735,74 @@ void Win32Video::SetWindowedScale (float scale)
|
||||||
// FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
// FrameBuffer implementation -----------------------------------------------
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// SetFPSLimit
|
||||||
|
//
|
||||||
|
// Initializes an event timer to fire at a rate of <limit>/sec. The video
|
||||||
|
// update will wait for this timer to trigger before updating.
|
||||||
|
//
|
||||||
|
// Pass 0 as the limit for unlimited.
|
||||||
|
// Pass a negative value for the limit to use the value of vid_maxfps.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void I_SetFPSLimit(int limit)
|
||||||
|
{
|
||||||
|
if (limit < 0)
|
||||||
|
{
|
||||||
|
limit = vid_maxfps;
|
||||||
|
}
|
||||||
|
// Kill any leftover timer.
|
||||||
|
if (FPSLimitTimer != 0)
|
||||||
|
{
|
||||||
|
timeKillEvent(FPSLimitTimer);
|
||||||
|
FPSLimitTimer = 0;
|
||||||
|
}
|
||||||
|
if (limit == 0)
|
||||||
|
{ // no limit
|
||||||
|
if (FPSLimitEvent != NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(FPSLimitEvent);
|
||||||
|
FPSLimitEvent = NULL;
|
||||||
|
}
|
||||||
|
DPrintf("FPS timer disabled\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FPSLimitEvent == NULL)
|
||||||
|
{
|
||||||
|
FPSLimitEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
|
||||||
|
if (FPSLimitEvent == NULL)
|
||||||
|
{ // Could not create event, so cannot use timer.
|
||||||
|
Printf("Failed to create FPS limitter event\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atterm(StopFPSLimit);
|
||||||
|
// Set timer event as close as we can to limit/sec, in milliseconds.
|
||||||
|
UINT period = 1000 / limit;
|
||||||
|
FPSLimitTimer = timeSetEvent(period, 0, (LPTIMECALLBACK)FPSLimitEvent, 0, TIME_PERIODIC | TIME_CALLBACK_EVENT_SET);
|
||||||
|
if (FPSLimitTimer == 0)
|
||||||
|
{
|
||||||
|
CloseHandle(FPSLimitEvent);
|
||||||
|
FPSLimitEvent = NULL;
|
||||||
|
Printf("Failed to create FPS limitter timer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DPrintf("FPS timer set to %u ms\n", period);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// StopFPSLimit
|
||||||
|
//
|
||||||
|
// Used for cleanup during application shutdown.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void StopFPSLimit()
|
||||||
|
{
|
||||||
|
I_SetFPSLimit(0);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue