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:
parent
435854456b
commit
97ca023f09
@ -126,6 +126,7 @@ typedef struct IDirectDrawImpl
|
||||
BOOL hidecursor;
|
||||
SpeedLimiter ticksLimiter;
|
||||
SpeedLimiter flipLimiter;
|
||||
SpeedLimiter fpsLimiter;
|
||||
|
||||
} IDirectDrawImpl;
|
||||
|
||||
|
@ -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 */
|
||||
|
68
src/render.c
68
src/render.c
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user