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 "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
|
@ -135,7 +136,18 @@ static int oldentertics;
|
|||
|
||||
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
|
||||
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;
|
||||
|
||||
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
|
|
@ -59,6 +59,8 @@ void I_InitGraphics ();
|
|||
void I_ShutdownGraphics ();
|
||||
void I_CreateRenderer();
|
||||
|
||||
void I_SetFPSLimit(int limit);
|
||||
|
||||
extern IVideo *Video;
|
||||
|
||||
#endif // __HARDWARE_H__
|
||||
|
|
|
@ -1208,6 +1208,11 @@ void D3DFB::Flip()
|
|||
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);
|
||||
InScene = false;
|
||||
|
||||
|
|
|
@ -1201,6 +1201,10 @@ void DDrawFB::Update ()
|
|||
LockCount = 0;
|
||||
UpdatePending = false;
|
||||
|
||||
if (FPSLimitEvent != NULL)
|
||||
{
|
||||
WaitForSingleObject(FPSLimitEvent, 1000);
|
||||
}
|
||||
if (!Windowed && AppActive && !SessionState /*&& !UseBlitter && !MustBuffer*/)
|
||||
{
|
||||
HRESULT hr = PrimarySurf->Flip (NULL, FlipFlags);
|
||||
|
|
|
@ -62,6 +62,9 @@ void I_CreateRenderer();
|
|||
void I_SaveWindowedPos ();
|
||||
void I_RestoreWindowedPos ();
|
||||
|
||||
void I_SetFPSLimit(int limit);
|
||||
|
||||
|
||||
extern IVideo *Video;
|
||||
|
||||
#endif // __HARDWARE_H__
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
|
||||
extern HANDLE FPSLimitEvent;
|
||||
|
||||
class D3DTex;
|
||||
class D3DPal;
|
||||
struct FSoftwareRenderer;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define _WIN32_WINNT 0x0501
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <ddraw.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 ---------------------------------------------
|
||||
|
||||
static void StopFPSLimit();
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern HWND Window;
|
||||
|
@ -98,20 +101,38 @@ extern bool VidResizing;
|
|||
|
||||
EXTERN_CVAR (Bool, fullscreen)
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static HMODULE D3D9_dll;
|
||||
static HMODULE DDraw_dll;
|
||||
static UINT FPSLimitTimer;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
IDirectDraw2 *DDraw;
|
||||
IDirect3D9 *D3D;
|
||||
IDirect3DDevice9 *D3Device;
|
||||
HANDLE FPSLimitEvent;
|
||||
|
||||
CVAR (Bool, vid_forceddraw, false, 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
|
||||
FILE *dbg;
|
||||
|
@ -714,4 +735,74 @@ void Win32Video::SetWindowedScale (float scale)
|
|||
// 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