mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-24 17:49:52 +01:00
use waitable timer also for fps limiter
This commit is contained in:
parent
435854456b
commit
97ca023f09
@ -126,6 +126,7 @@ typedef struct IDirectDrawImpl
|
|||||||
BOOL hidecursor;
|
BOOL hidecursor;
|
||||||
SpeedLimiter ticksLimiter;
|
SpeedLimiter ticksLimiter;
|
||||||
SpeedLimiter flipLimiter;
|
SpeedLimiter flipLimiter;
|
||||||
|
SpeedLimiter fpsLimiter;
|
||||||
|
|
||||||
} IDirectDrawImpl;
|
} IDirectDrawImpl;
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ void LimitGameTicks()
|
|||||||
{
|
{
|
||||||
if (ddraw->ticksLimiter.hTimer)
|
if (ddraw->ticksLimiter.hTimer)
|
||||||
{
|
{
|
||||||
FILETIME ft;
|
FILETIME ft = { 0 };
|
||||||
GetSystemTimeAsFileTime(&ft);
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
|
||||||
if (CompareFileTime((FILETIME *)&ddraw->ticksLimiter.dueTime, &ft) == -1)
|
if (CompareFileTime((FILETIME *)&ddraw->ticksLimiter.dueTime, &ft) == -1)
|
||||||
@ -1499,6 +1499,13 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
|
|||||||
This->flipLimiter.hTimer = NULL;
|
This->flipLimiter.hTimer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (This->fpsLimiter.hTimer)
|
||||||
|
{
|
||||||
|
CancelWaitableTimer(This->fpsLimiter.hTimer);
|
||||||
|
CloseHandle(This->fpsLimiter.hTimer);
|
||||||
|
This->fpsLimiter.hTimer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DeleteCriticalSection(&This->cs);
|
DeleteCriticalSection(&This->cs);
|
||||||
|
|
||||||
/* restore old wndproc, subsequent ddraw creation will otherwise fail */
|
/* restore old wndproc, subsequent ddraw creation will otherwise fail */
|
||||||
|
68
src/render.c
68
src/render.c
@ -25,8 +25,6 @@
|
|||||||
#define TEXTURE_COUNT 4
|
#define TEXTURE_COUNT 4
|
||||||
|
|
||||||
static HGLRC OpenGLContext;
|
static HGLRC OpenGLContext;
|
||||||
static int MaxFPS;
|
|
||||||
static DWORD FrameLength;
|
|
||||||
static GLuint MainProgram;
|
static GLuint MainProgram;
|
||||||
static GLuint ScaleProgram;
|
static GLuint ScaleProgram;
|
||||||
static BOOL GotError;
|
static BOOL GotError;
|
||||||
@ -50,7 +48,7 @@ static BOOL UseOpenGL;
|
|||||||
static BOOL AdjustAlignment;
|
static BOOL AdjustAlignment;
|
||||||
|
|
||||||
static HGLRC CreateContext(HDC hdc);
|
static HGLRC CreateContext(HDC hdc);
|
||||||
static void SetMaxFPS(int baseMaxFPS);
|
static void SetMaxFPS();
|
||||||
static void BuildPrograms();
|
static void BuildPrograms();
|
||||||
static void CreateTextures(int width, int height);
|
static void CreateTextures(int width, int height);
|
||||||
static void InitMainProgram();
|
static void InitMainProgram();
|
||||||
@ -69,7 +67,7 @@ DWORD WINAPI render_main(void)
|
|||||||
if (OpenGLContext)
|
if (OpenGLContext)
|
||||||
{
|
{
|
||||||
OpenGL_Init();
|
OpenGL_Init();
|
||||||
SetMaxFPS(ddraw->render.maxfps);
|
SetMaxFPS();
|
||||||
BuildPrograms();
|
BuildPrograms();
|
||||||
CreateTextures(ddraw->width, ddraw->height);
|
CreateTextures(ddraw->width, ddraw->height);
|
||||||
InitMainProgram();
|
InitMainProgram();
|
||||||
@ -114,9 +112,11 @@ static HGLRC CreateContext(HDC hdc)
|
|||||||
return context;
|
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))
|
if (OpenGL_ExtExists("WGL_EXT_swap_control_tear", ddraw->render.hDC))
|
||||||
{
|
{
|
||||||
@ -125,7 +125,7 @@ static void SetMaxFPS(int baseMaxFPS)
|
|||||||
if (ddraw->vsync)
|
if (ddraw->vsync)
|
||||||
{
|
{
|
||||||
wglSwapIntervalEXT(-1);
|
wglSwapIntervalEXT(-1);
|
||||||
MaxFPS = 1000;
|
maxFPS = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wglSwapIntervalEXT(0);
|
wglSwapIntervalEXT(0);
|
||||||
@ -138,21 +138,25 @@ static void SetMaxFPS(int baseMaxFPS)
|
|||||||
if (ddraw->vsync)
|
if (ddraw->vsync)
|
||||||
{
|
{
|
||||||
wglSwapIntervalEXT(1);
|
wglSwapIntervalEXT(1);
|
||||||
MaxFPS = 1000;
|
maxFPS = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wglSwapIntervalEXT(0);
|
wglSwapIntervalEXT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MaxFPS < 0)
|
if (maxFPS < 0)
|
||||||
MaxFPS = ddraw->mode.dmDisplayFrequency;
|
maxFPS = ddraw->mode.dmDisplayFrequency;
|
||||||
|
|
||||||
if (MaxFPS >= 1000)
|
if (maxFPS > 1000)
|
||||||
MaxFPS = 0;
|
maxFPS = 0;
|
||||||
|
|
||||||
if (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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuildPrograms()
|
static void BuildPrograms()
|
||||||
@ -543,8 +547,8 @@ static void InitScaleProgram()
|
|||||||
|
|
||||||
static void Render()
|
static void Render()
|
||||||
{
|
{
|
||||||
DWORD tick_start = 0;
|
DWORD tickStart = 0;
|
||||||
DWORD tick_end = 0;
|
DWORD tickEnd = 0;
|
||||||
BOOL needsUpdate = FALSE;
|
BOOL needsUpdate = FALSE;
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
@ -569,8 +573,8 @@ static void Render()
|
|||||||
|
|
||||||
BOOL scaleChanged = FALSE;
|
BOOL scaleChanged = FALSE;
|
||||||
|
|
||||||
if (MaxFPS > 0)
|
if (ddraw->fpsLimiter.ticklength > 0)
|
||||||
tick_start = timeGetTime();
|
tickStart = timeGetTime();
|
||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
|
|
||||||
@ -785,12 +789,32 @@ static void Render()
|
|||||||
DrawFrameInfoEnd();
|
DrawFrameInfoEnd();
|
||||||
#endif
|
#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)
|
if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
|
||||||
Sleep(FrameLength - (tick_end - tick_start));
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@ static IDirect3DTexture9 *PaletteTex[TEXTURE_COUNT];
|
|||||||
static IDirect3DPixelShader9 *PixelShader;
|
static IDirect3DPixelShader9 *PixelShader;
|
||||||
static float ScaleW;
|
static float ScaleW;
|
||||||
static float ScaleH;
|
static float ScaleH;
|
||||||
static int MaxFPS;
|
|
||||||
static DWORD FrameLength;
|
|
||||||
static int BitsPerPixel;
|
static int BitsPerPixel;
|
||||||
|
|
||||||
static BOOL CreateResources();
|
static BOOL CreateResources();
|
||||||
@ -276,16 +274,22 @@ static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
|
|||||||
|
|
||||||
static void SetMaxFPS()
|
static void SetMaxFPS()
|
||||||
{
|
{
|
||||||
MaxFPS = ddraw->render.maxfps;
|
int maxFPS = ddraw->render.maxfps;
|
||||||
|
ddraw->fpsLimiter.tickLengthNs = 0;
|
||||||
|
ddraw->fpsLimiter.ticklength = 0;
|
||||||
|
|
||||||
if (MaxFPS < 0)
|
if (maxFPS < 0)
|
||||||
MaxFPS = ddraw->mode.dmDisplayFrequency;
|
maxFPS = ddraw->mode.dmDisplayFrequency;
|
||||||
|
|
||||||
if (MaxFPS >= 1000 || ddraw->vsync)
|
if (maxFPS > 1000 || ddraw->vsync)
|
||||||
MaxFPS = 0;
|
maxFPS = 0;
|
||||||
|
|
||||||
if (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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI render_d3d9_main(void)
|
DWORD WINAPI render_d3d9_main(void)
|
||||||
@ -312,7 +316,7 @@ DWORD WINAPI render_d3d9_main(void)
|
|||||||
|
|
||||||
static int texIndex = 0, palIndex = 0;
|
static int texIndex = 0, palIndex = 0;
|
||||||
|
|
||||||
if (MaxFPS > 0)
|
if (ddraw->fpsLimiter.ticklength > 0)
|
||||||
tickStart = timeGetTime();
|
tickStart = timeGetTime();
|
||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
@ -416,12 +420,32 @@ DWORD WINAPI render_d3d9_main(void)
|
|||||||
DrawFrameInfoEnd();
|
DrawFrameInfoEnd();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (MaxFPS > 0)
|
if (ddraw->fpsLimiter.ticklength > 0)
|
||||||
{
|
{
|
||||||
tickEnd = timeGetTime();
|
if (ddraw->fpsLimiter.hTimer)
|
||||||
|
{
|
||||||
|
FILETIME ft = { 0 };
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
|
||||||
if (tickEnd - tickStart < FrameLength)
|
if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
|
||||||
Sleep(FrameLength - (tickEnd - tickStart));
|
{
|
||||||
|
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;
|
return 0;
|
||||||
|
@ -40,25 +40,30 @@ DWORD WINAPI render_soft_main(void)
|
|||||||
else
|
else
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
|
|
||||||
int maxFPS = ddraw->render.maxfps;
|
|
||||||
DWORD frameLength = 0;
|
|
||||||
DWORD lastTick = 0;
|
DWORD lastTick = 0;
|
||||||
|
int maxFPS = ddraw->render.maxfps;
|
||||||
|
ddraw->fpsLimiter.tickLengthNs = 0;
|
||||||
|
ddraw->fpsLimiter.ticklength = 0;
|
||||||
|
|
||||||
if (maxFPS < 0)
|
if (maxFPS < 0)
|
||||||
maxFPS = ddraw->mode.dmDisplayFrequency;
|
maxFPS = ddraw->mode.dmDisplayFrequency;
|
||||||
|
|
||||||
if (maxFPS >= 1000)
|
if (maxFPS > 1000)
|
||||||
maxFPS = 0;
|
maxFPS = 0;
|
||||||
|
|
||||||
if (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)
|
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
||||||
{
|
{
|
||||||
if (maxFPS > 0)
|
if (ddraw->fpsLimiter.ticklength > 0)
|
||||||
{
|
{
|
||||||
DWORD curTick = timeGetTime();
|
DWORD curTick = timeGetTime();
|
||||||
if (lastTick + frameLength > curTick)
|
if (lastTick + ddraw->fpsLimiter.ticklength > curTick)
|
||||||
{
|
{
|
||||||
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
||||||
SetEvent(ddraw->render.ev);
|
SetEvent(ddraw->render.ev);
|
||||||
|
@ -41,12 +41,18 @@ void Settings_Load()
|
|||||||
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
||||||
ddraw->vhack = GetBool("vhack", FALSE);
|
ddraw->vhack = GetBool("vhack", FALSE);
|
||||||
|
|
||||||
ddraw->render.maxfps = GetInt("maxfps", 125);
|
|
||||||
WindowRect.right = GetInt("width", 0);
|
WindowRect.right = GetInt("width", 0);
|
||||||
WindowRect.bottom = GetInt("height", 0);
|
WindowRect.bottom = GetInt("height", 0);
|
||||||
WindowRect.left = GetInt("posX", -32000);
|
WindowRect.left = GetInt("posX", -32000);
|
||||||
WindowRect.top = GetInt("posY", -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);
|
int maxTicks = GetInt("maxgameticks", 0);
|
||||||
if (maxTicks > 0 && maxTicks <= 1000)
|
if (maxTicks > 0 && maxTicks <= 1000)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user