1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-15 06:04:49 +01:00

use waitable timer also for fps limiter

This commit is contained in:
FunkyFr3sh 2018-11-29 21:26:43 +01:00
parent 435854456b
commit 97ca023f09
6 changed files with 111 additions and 44 deletions

View File

@ -126,6 +126,7 @@ typedef struct IDirectDrawImpl
BOOL hidecursor;
SpeedLimiter ticksLimiter;
SpeedLimiter flipLimiter;
SpeedLimiter fpsLimiter;
} IDirectDrawImpl;

View File

@ -162,7 +162,7 @@ void LimitGameTicks()
{
if (ddraw->ticksLimiter.hTimer)
{
FILETIME ft;
FILETIME ft = { 0 };
GetSystemTimeAsFileTime(&ft);
if (CompareFileTime((FILETIME *)&ddraw->ticksLimiter.dueTime, &ft) == -1)
@ -1499,6 +1499,13 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
This->flipLimiter.hTimer = NULL;
}
if (This->fpsLimiter.hTimer)
{
CancelWaitableTimer(This->fpsLimiter.hTimer);
CloseHandle(This->fpsLimiter.hTimer);
This->fpsLimiter.hTimer = NULL;
}
DeleteCriticalSection(&This->cs);
/* restore old wndproc, subsequent ddraw creation will otherwise fail */

View File

@ -25,8 +25,6 @@
#define TEXTURE_COUNT 4
static HGLRC OpenGLContext;
static int MaxFPS;
static DWORD FrameLength;
static GLuint MainProgram;
static GLuint ScaleProgram;
static BOOL GotError;
@ -50,7 +48,7 @@ static BOOL UseOpenGL;
static BOOL AdjustAlignment;
static HGLRC CreateContext(HDC hdc);
static void SetMaxFPS(int baseMaxFPS);
static void SetMaxFPS();
static void BuildPrograms();
static void CreateTextures(int width, int height);
static void InitMainProgram();
@ -69,7 +67,7 @@ DWORD WINAPI render_main(void)
if (OpenGLContext)
{
OpenGL_Init();
SetMaxFPS(ddraw->render.maxfps);
SetMaxFPS();
BuildPrograms();
CreateTextures(ddraw->width, ddraw->height);
InitMainProgram();
@ -114,9 +112,11 @@ static HGLRC CreateContext(HDC hdc)
return context;
}
static void SetMaxFPS(int baseMaxFPS)
static void SetMaxFPS()
{
MaxFPS = baseMaxFPS;
int maxFPS = ddraw->render.maxfps;
ddraw->fpsLimiter.tickLengthNs = 0;
ddraw->fpsLimiter.ticklength = 0;
if (OpenGL_ExtExists("WGL_EXT_swap_control_tear", ddraw->render.hDC))
{
@ -125,7 +125,7 @@ static void SetMaxFPS(int baseMaxFPS)
if (ddraw->vsync)
{
wglSwapIntervalEXT(-1);
MaxFPS = 1000;
maxFPS = 0;
}
else
wglSwapIntervalEXT(0);
@ -138,21 +138,25 @@ static void SetMaxFPS(int baseMaxFPS)
if (ddraw->vsync)
{
wglSwapIntervalEXT(1);
MaxFPS = 1000;
maxFPS = 0;
}
else
wglSwapIntervalEXT(0);
}
}
if (MaxFPS < 0)
MaxFPS = ddraw->mode.dmDisplayFrequency;
if (maxFPS < 0)
maxFPS = ddraw->mode.dmDisplayFrequency;
if (MaxFPS >= 1000)
MaxFPS = 0;
if (maxFPS > 1000)
maxFPS = 0;
if (MaxFPS > 0)
FrameLength = 1000.0f / MaxFPS;
if (maxFPS > 0)
{
float len = 1000.0f / maxFPS;
ddraw->fpsLimiter.tickLengthNs = len * 10000;
ddraw->fpsLimiter.ticklength = len + 0.5f;
}
}
static void BuildPrograms()
@ -543,8 +547,8 @@ static void InitScaleProgram()
static void Render()
{
DWORD tick_start = 0;
DWORD tick_end = 0;
DWORD tickStart = 0;
DWORD tickEnd = 0;
BOOL needsUpdate = FALSE;
glViewport(
@ -569,8 +573,8 @@ static void Render()
BOOL scaleChanged = FALSE;
if (MaxFPS > 0)
tick_start = timeGetTime();
if (ddraw->fpsLimiter.ticklength > 0)
tickStart = timeGetTime();
EnterCriticalSection(&ddraw->cs);
@ -785,12 +789,32 @@ static void Render()
DrawFrameInfoEnd();
#endif
if (MaxFPS > 0)
if (ddraw->fpsLimiter.ticklength > 0)
{
tick_end = timeGetTime();
if (ddraw->fpsLimiter.hTimer)
{
FILETIME ft = { 0 };
GetSystemTimeAsFileTime(&ft);
if (tick_end - tick_start < FrameLength)
Sleep(FrameLength - (tick_end - tick_start));
if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
{
memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
}
else
{
WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
}
ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
}
else
{
tickEnd = timeGetTime();
if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
}
}
}
}

View File

@ -19,8 +19,6 @@ static IDirect3DTexture9 *PaletteTex[TEXTURE_COUNT];
static IDirect3DPixelShader9 *PixelShader;
static float ScaleW;
static float ScaleH;
static int MaxFPS;
static DWORD FrameLength;
static int BitsPerPixel;
static BOOL CreateResources();
@ -276,16 +274,22 @@ static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
static void SetMaxFPS()
{
MaxFPS = ddraw->render.maxfps;
int maxFPS = ddraw->render.maxfps;
ddraw->fpsLimiter.tickLengthNs = 0;
ddraw->fpsLimiter.ticklength = 0;
if (MaxFPS < 0)
MaxFPS = ddraw->mode.dmDisplayFrequency;
if (maxFPS < 0)
maxFPS = ddraw->mode.dmDisplayFrequency;
if (MaxFPS >= 1000 || ddraw->vsync)
MaxFPS = 0;
if (maxFPS > 1000 || ddraw->vsync)
maxFPS = 0;
if (MaxFPS > 0)
FrameLength = 1000.0f / MaxFPS;
if (maxFPS > 0)
{
float len = 1000.0f / maxFPS;
ddraw->fpsLimiter.tickLengthNs = len * 10000;
ddraw->fpsLimiter.ticklength = len + 0.5f;
}
}
DWORD WINAPI render_d3d9_main(void)
@ -312,7 +316,7 @@ DWORD WINAPI render_d3d9_main(void)
static int texIndex = 0, palIndex = 0;
if (MaxFPS > 0)
if (ddraw->fpsLimiter.ticklength > 0)
tickStart = timeGetTime();
EnterCriticalSection(&ddraw->cs);
@ -416,12 +420,32 @@ DWORD WINAPI render_d3d9_main(void)
DrawFrameInfoEnd();
#endif
if (MaxFPS > 0)
if (ddraw->fpsLimiter.ticklength > 0)
{
tickEnd = timeGetTime();
if (ddraw->fpsLimiter.hTimer)
{
FILETIME ft = { 0 };
GetSystemTimeAsFileTime(&ft);
if (tickEnd - tickStart < FrameLength)
Sleep(FrameLength - (tickEnd - tickStart));
if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
{
memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
}
else
{
WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
}
ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
}
else
{
tickEnd = timeGetTime();
if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
}
}
}
return 0;

View File

@ -40,25 +40,30 @@ DWORD WINAPI render_soft_main(void)
else
Sleep(500);
int maxFPS = ddraw->render.maxfps;
DWORD frameLength = 0;
DWORD lastTick = 0;
int maxFPS = ddraw->render.maxfps;
ddraw->fpsLimiter.tickLengthNs = 0;
ddraw->fpsLimiter.ticklength = 0;
if (maxFPS < 0)
maxFPS = ddraw->mode.dmDisplayFrequency;
if (maxFPS >= 1000)
if (maxFPS > 1000)
maxFPS = 0;
if (maxFPS > 0)
frameLength = 1000.0f / maxFPS;
{
float len = 1000.0f / maxFPS;
ddraw->fpsLimiter.tickLengthNs = len * 10000;
ddraw->fpsLimiter.ticklength = len + 0.5f;
}
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
{
if (maxFPS > 0)
if (ddraw->fpsLimiter.ticklength > 0)
{
DWORD curTick = timeGetTime();
if (lastTick + frameLength > curTick)
if (lastTick + ddraw->fpsLimiter.ticklength > curTick)
{
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
SetEvent(ddraw->render.ev);

View File

@ -41,12 +41,18 @@ void Settings_Load()
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
ddraw->vhack = GetBool("vhack", FALSE);
ddraw->render.maxfps = GetInt("maxfps", 125);
WindowRect.right = GetInt("width", 0);
WindowRect.bottom = GetInt("height", 0);
WindowRect.left = GetInt("posX", -32000);
WindowRect.top = GetInt("posY", -32000);
ddraw->render.maxfps = GetInt("maxfps", 125);
if (ddraw->render.maxfps)
{
ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
//can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency
}
int maxTicks = GetInt("maxgameticks", 0);
if (maxTicks > 0 && maxTicks <= 1000)
{