mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-14 22:03:27 +01:00
improve fps limiter for vsync and maxfps=-1
This commit is contained in:
parent
d2903413a0
commit
a6f85fbd73
1
Makefile
1
Makefile
@ -33,6 +33,7 @@ FILES = src/IDirect3D/IDirect3D.c \
|
||||
src/dllmain.c \
|
||||
src/wndproc.c \
|
||||
src/utils.c \
|
||||
src/fps_limiter.c \
|
||||
src/opengl_utils.c
|
||||
|
||||
all:
|
||||
|
@ -32,6 +32,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\directinput.c" />
|
||||
<ClCompile Include="src\dllmain.c" />
|
||||
<ClCompile Include="src\fps_limiter.c" />
|
||||
<ClCompile Include="src\IDirect3D\IDirect3D.c" />
|
||||
<ClCompile Include="src\IDirect3D\IDirect3D2.c" />
|
||||
<ClCompile Include="src\IDirect3D\IDirect3D3.c" />
|
||||
@ -63,6 +64,7 @@
|
||||
<ClInclude Include="inc\ddclipper.h" />
|
||||
<ClInclude Include="inc\directinput.h" />
|
||||
<ClInclude Include="inc\dllmain.h" />
|
||||
<ClInclude Include="inc\fps_limiter.h" />
|
||||
<ClInclude Include="inc\glcorearb.h" />
|
||||
<ClInclude Include="inc\IDirect3D.h" />
|
||||
<ClInclude Include="inc\IAMMediaStream.h" />
|
||||
|
@ -147,6 +147,9 @@
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawGammaControl.c">
|
||||
<Filter>Source Files\IDirectDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fps_limiter.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="inc\ddraw.h">
|
||||
@ -248,6 +251,9 @@
|
||||
<ClInclude Include="inc\IDirectDrawGammaControl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\fps_limiter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ddraw.rc">
|
||||
|
1
inc/dd.h
1
inc/dd.h
@ -118,7 +118,6 @@ typedef struct cnc_ddraw
|
||||
BOOL show_driver_warning;
|
||||
speed_limiter ticks_limiter;
|
||||
speed_limiter flip_limiter;
|
||||
speed_limiter fps_limiter;
|
||||
|
||||
} cnc_ddraw;
|
||||
|
||||
|
52
inc/fps_limiter.h
Normal file
52
inc/fps_limiter.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef FPS_LIMITER_H
|
||||
#define FPS_LIMITER_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
|
||||
typedef struct _D3DKMT_WAITFORVERTICALBLANKEVENT {
|
||||
UINT hAdapter;
|
||||
UINT hDevice;
|
||||
UINT VidPnSourceId;
|
||||
} D3DKMT_WAITFORVERTICALBLANKEVENT;
|
||||
|
||||
typedef struct _D3DKMT_OPENADAPTERFROMHDC {
|
||||
HDC hDc;
|
||||
UINT hAdapter;
|
||||
LUID AdapterLuid;
|
||||
UINT VidPnSourceId;
|
||||
} D3DKMT_OPENADAPTERFROMHDC;
|
||||
|
||||
typedef struct _D3DKMT_CLOSEADAPTER {
|
||||
UINT hAdapter;
|
||||
} D3DKMT_CLOSEADAPTER;
|
||||
|
||||
typedef struct fps_limiter
|
||||
{
|
||||
DWORD tick_start;
|
||||
DWORD tick_end;
|
||||
DWORD tick_length;
|
||||
LONGLONG tick_length_ns;
|
||||
HANDLE htimer;
|
||||
LARGE_INTEGER due_time;
|
||||
D3DKMT_WAITFORVERTICALBLANKEVENT vblank_event;
|
||||
D3DKMT_OPENADAPTERFROMHDC adapter;
|
||||
D3DKMT_CLOSEADAPTER close_adapter;
|
||||
HRESULT(WINAPI* DwmFlush)(VOID);
|
||||
HRESULT(WINAPI* DwmIsCompositionEnabled)(BOOL*);
|
||||
NTSTATUS(WINAPI* D3DKMTWaitForVerticalBlankEvent)(const D3DKMT_WAITFORVERTICALBLANKEVENT* Arg1);
|
||||
NTSTATUS(WINAPI* D3DKMTOpenAdapterFromHdc)(D3DKMT_OPENADAPTERFROMHDC* Arg1);
|
||||
NTSTATUS(WINAPI* D3DKMTCloseAdapter)(D3DKMT_CLOSEADAPTER* Arg1);
|
||||
BOOL got_adapter;
|
||||
} fps_limiter;
|
||||
|
||||
extern fps_limiter g_fpsl;
|
||||
|
||||
void fpsl_init();
|
||||
BOOL fpsl_wait_for_vblank();
|
||||
BOOL fpsl_dwn_is_enabled();
|
||||
void fpsl_frame_start();
|
||||
void fpsl_frame_end();
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <d3d9.h>
|
||||
#include "fps_limiter.h"
|
||||
#include "config.h"
|
||||
#include "dd.h"
|
||||
#include "render_d3d9.h"
|
||||
@ -78,7 +78,7 @@ void cfg_load()
|
||||
}
|
||||
|
||||
if (g_ddraw->accurate_timers || g_ddraw->vsync)
|
||||
g_ddraw->fps_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
g_fpsl.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
//can't fully set it up here due to missing g_ddraw->mode.dmDisplayFrequency
|
||||
|
||||
int max_ticks = cfg_get_int("maxgameticks", 0);
|
||||
|
9
src/dd.c
9
src/dd.c
@ -9,6 +9,7 @@
|
||||
#include "render_d3d9.h"
|
||||
#include "render_gdi.h"
|
||||
#include "render_ogl.h"
|
||||
#include "fps_limiter.h"
|
||||
#include "debug.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -817,11 +818,11 @@ ULONG dd_Release()
|
||||
g_ddraw->flip_limiter.htimer = NULL;
|
||||
}
|
||||
|
||||
if (g_ddraw->fps_limiter.htimer)
|
||||
if (g_fpsl.htimer)
|
||||
{
|
||||
CancelWaitableTimer(g_ddraw->fps_limiter.htimer);
|
||||
CloseHandle(g_ddraw->fps_limiter.htimer);
|
||||
g_ddraw->fps_limiter.htimer = NULL;
|
||||
CancelWaitableTimer(g_fpsl.htimer);
|
||||
CloseHandle(g_fpsl.htimer);
|
||||
g_fpsl.htimer = NULL;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&g_ddraw->cs);
|
||||
|
140
src/fps_limiter.c
Normal file
140
src/fps_limiter.c
Normal file
@ -0,0 +1,140 @@
|
||||
#include <windows.h>
|
||||
#include "fps_limiter.h"
|
||||
#include "dd.h"
|
||||
#include "debug.h"
|
||||
|
||||
fps_limiter g_fpsl;
|
||||
|
||||
void fpsl_init()
|
||||
{
|
||||
int max_fps = g_ddraw->render.maxfps;
|
||||
|
||||
g_fpsl.tick_length_ns = 0;
|
||||
g_fpsl.tick_length = 0;
|
||||
|
||||
if (max_fps < 0 || g_ddraw->vsync)
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
|
||||
if (max_fps > 1000)
|
||||
max_fps = 0;
|
||||
|
||||
if (max_fps > 0)
|
||||
{
|
||||
float len = 1000.0f / max_fps;
|
||||
g_fpsl.tick_length_ns = len * 10000;
|
||||
g_fpsl.tick_length = len;// + 0.5f;
|
||||
}
|
||||
|
||||
if (g_fpsl.got_adapter && g_fpsl.D3DKMTCloseAdapter)
|
||||
{
|
||||
g_fpsl.got_adapter = FALSE;
|
||||
g_fpsl.close_adapter.hAdapter = g_fpsl.adapter.hAdapter;
|
||||
g_fpsl.D3DKMTCloseAdapter(&g_fpsl.close_adapter);
|
||||
}
|
||||
|
||||
g_fpsl.DwmFlush =
|
||||
(HRESULT(WINAPI*)(VOID))GetProcAddress(GetModuleHandleA("Dwmapi.dll"), "DwmFlush");
|
||||
|
||||
g_fpsl.DwmIsCompositionEnabled =
|
||||
(HRESULT(WINAPI*)(BOOL*))GetProcAddress(GetModuleHandleA("Dwmapi.dll"), "DwmIsCompositionEnabled");
|
||||
|
||||
g_fpsl.D3DKMTWaitForVerticalBlankEvent =
|
||||
(NTSTATUS(WINAPI*)(const D3DKMT_WAITFORVERTICALBLANKEVENT * Arg1))
|
||||
GetProcAddress(GetModuleHandleA("gdi32.dll"), "D3DKMTWaitForVerticalBlankEvent");
|
||||
|
||||
g_fpsl.D3DKMTOpenAdapterFromHdc =
|
||||
(NTSTATUS(WINAPI*)(D3DKMT_OPENADAPTERFROMHDC * Arg1))
|
||||
GetProcAddress(GetModuleHandleA("gdi32.dll"), "D3DKMTOpenAdapterFromHdc");
|
||||
|
||||
g_fpsl.D3DKMTCloseAdapter =
|
||||
(NTSTATUS(WINAPI*)(D3DKMT_CLOSEADAPTER * Arg1))
|
||||
GetProcAddress(GetModuleHandleA("gdi32.dll"), "D3DKMTCloseAdapter");
|
||||
}
|
||||
|
||||
BOOL fpsl_wait_for_vblank()
|
||||
{
|
||||
if (g_fpsl.D3DKMTOpenAdapterFromHdc && !g_fpsl.got_adapter)
|
||||
{
|
||||
g_fpsl.adapter.hDc = g_ddraw->render.hdc;
|
||||
|
||||
if (g_fpsl.D3DKMTOpenAdapterFromHdc(&g_fpsl.adapter) == 0)
|
||||
{
|
||||
g_fpsl.vblank_event.hAdapter = g_fpsl.adapter.hAdapter;
|
||||
g_fpsl.got_adapter = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_fpsl.got_adapter && g_fpsl.D3DKMTWaitForVerticalBlankEvent)
|
||||
{
|
||||
return g_fpsl.D3DKMTWaitForVerticalBlankEvent(&g_fpsl.vblank_event) == 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL fpsl_dwn_is_enabled()
|
||||
{
|
||||
BOOL dwm_enabled = FALSE;
|
||||
|
||||
if (g_fpsl.DwmIsCompositionEnabled)
|
||||
g_fpsl.DwmIsCompositionEnabled(&dwm_enabled);
|
||||
|
||||
return dwm_enabled;
|
||||
}
|
||||
|
||||
void fpsl_frame_start()
|
||||
{
|
||||
if (g_fpsl.tick_length > 0)
|
||||
g_fpsl.tick_start = timeGetTime();
|
||||
}
|
||||
|
||||
void fpsl_frame_end()
|
||||
{
|
||||
if (g_ddraw->render.maxfps < 0 || g_ddraw->vsync)
|
||||
{
|
||||
if (fpsl_dwn_is_enabled() && g_fpsl.DwmFlush && SUCCEEDED(g_fpsl.DwmFlush()))
|
||||
return;
|
||||
|
||||
if (fpsl_wait_for_vblank())
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_fpsl.tick_length > 0)
|
||||
{
|
||||
if (g_fpsl.htimer)
|
||||
{
|
||||
if (g_ddraw->vsync)
|
||||
{
|
||||
WaitForSingleObject(g_fpsl.htimer, g_fpsl.tick_length * 2);
|
||||
LARGE_INTEGER due_time = { .QuadPart = -g_fpsl.tick_length_ns };
|
||||
SetWaitableTimer(g_fpsl.htimer, &due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILETIME ft = { 0 };
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
if (CompareFileTime((FILETIME*)&g_fpsl.due_time, &ft) == -1)
|
||||
{
|
||||
memcpy(&g_fpsl.due_time, &ft, sizeof(LARGE_INTEGER));
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(g_fpsl.htimer, g_fpsl.tick_length * 2);
|
||||
}
|
||||
|
||||
g_fpsl.due_time.QuadPart += g_fpsl.tick_length_ns;
|
||||
SetWaitableTimer(g_fpsl.htimer, &g_fpsl.due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_fpsl.tick_end = timeGetTime();
|
||||
|
||||
if (g_fpsl.tick_end - g_fpsl.tick_start < g_fpsl.tick_length)
|
||||
{
|
||||
Sleep(g_fpsl.tick_length - (g_fpsl.tick_end - g_fpsl.tick_start));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <d3d9.h>
|
||||
#include "fps_limiter.h"
|
||||
#include "dd.h"
|
||||
#include "ddsurface.h"
|
||||
#include "d3d9shader.h"
|
||||
@ -13,7 +14,6 @@
|
||||
static BOOL d3d9_create_resouces();
|
||||
static BOOL d3d9_set_states();
|
||||
static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch);
|
||||
static void d3d9_set_max_fps();
|
||||
|
||||
static d3d9_renderer g_d3d9;
|
||||
|
||||
@ -305,35 +305,12 @@ static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void d3d9_set_max_fps()
|
||||
{
|
||||
int max_fps = g_ddraw->render.maxfps;
|
||||
|
||||
g_ddraw->fps_limiter.tick_length_ns = 0;
|
||||
g_ddraw->fps_limiter.tick_length = 0;
|
||||
|
||||
if (max_fps < 0 || g_ddraw->vsync)
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
|
||||
if (max_fps > 1000)
|
||||
max_fps = 0;
|
||||
|
||||
if (max_fps > 0)
|
||||
{
|
||||
float len = 1000.0f / max_fps;
|
||||
g_ddraw->fps_limiter.tick_length_ns = len * 10000;
|
||||
g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI d3d9_render_main(void)
|
||||
{
|
||||
Sleep(500);
|
||||
|
||||
d3d9_set_max_fps();
|
||||
fpsl_init();
|
||||
|
||||
DWORD tick_start = 0;
|
||||
DWORD tick_end = 0;
|
||||
BOOL needs_update = FALSE;
|
||||
|
||||
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : 200;
|
||||
@ -347,8 +324,7 @@ DWORD WINAPI d3d9_render_main(void)
|
||||
|
||||
static int tex_index = 0, palIndex = 0;
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
tick_start = timeGetTime();
|
||||
fpsl_frame_start();
|
||||
|
||||
EnterCriticalSection(&g_ddraw->cs);
|
||||
|
||||
@ -456,44 +432,7 @@ DWORD WINAPI d3d9_render_main(void)
|
||||
dbg_draw_frame_info_end();
|
||||
#endif
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
{
|
||||
if (g_ddraw->fps_limiter.htimer)
|
||||
{
|
||||
if (g_ddraw->vsync)
|
||||
{
|
||||
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||
LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
|
||||
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILETIME ft = { 0 };
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
if (CompareFileTime((FILETIME *)&g_ddraw->fps_limiter.due_time, &ft) == -1)
|
||||
{
|
||||
memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||
}
|
||||
|
||||
g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
|
||||
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tick_end = timeGetTime();
|
||||
|
||||
if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
|
||||
{
|
||||
Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
|
||||
}
|
||||
}
|
||||
}
|
||||
fpsl_frame_end();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "fps_limiter.h"
|
||||
#include "dd.h"
|
||||
#include "ddsurface.h"
|
||||
#include "opengl_utils.h"
|
||||
@ -30,26 +31,7 @@ DWORD WINAPI gdi_render_main(void)
|
||||
|
||||
Sleep(500);
|
||||
|
||||
DWORD tick_start = 0;
|
||||
DWORD tick_end = 0;
|
||||
|
||||
int max_fps = g_ddraw->render.maxfps;
|
||||
|
||||
g_ddraw->fps_limiter.tick_length_ns = 0;
|
||||
g_ddraw->fps_limiter.tick_length = 0;
|
||||
|
||||
if (max_fps < 0)
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
|
||||
if (max_fps > 1000)
|
||||
max_fps = 0;
|
||||
|
||||
if (max_fps > 0)
|
||||
{
|
||||
float len = 1000.0f / max_fps;
|
||||
g_ddraw->fps_limiter.tick_length_ns = len * 10000;
|
||||
g_ddraw->fps_limiter.tick_length = len + (g_ddraw->accurate_timers ? 0.5f : 0.0f);
|
||||
}
|
||||
fpsl_init();
|
||||
|
||||
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : INFINITE;
|
||||
|
||||
@ -60,8 +42,7 @@ DWORD WINAPI gdi_render_main(void)
|
||||
dbg_draw_frame_info_start();
|
||||
#endif
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
tick_start = timeGetTime();
|
||||
fpsl_frame_start();
|
||||
|
||||
EnterCriticalSection(&g_ddraw->cs);
|
||||
|
||||
@ -155,35 +136,7 @@ DWORD WINAPI gdi_render_main(void)
|
||||
dbg_draw_frame_info_end();
|
||||
#endif
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
{
|
||||
if (g_ddraw->fps_limiter.htimer)
|
||||
{
|
||||
FILETIME ft = { 0 };
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
if (CompareFileTime((FILETIME*)&g_ddraw->fps_limiter.due_time, &ft) == -1)
|
||||
{
|
||||
memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||
}
|
||||
|
||||
g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
|
||||
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
tick_end = timeGetTime();
|
||||
|
||||
if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
|
||||
{
|
||||
Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
|
||||
}
|
||||
}
|
||||
}
|
||||
fpsl_frame_end();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
101
src/render_ogl.c
101
src/render_ogl.c
@ -1,5 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "fps_limiter.h"
|
||||
#include "opengl_utils.h"
|
||||
#include "dd.h"
|
||||
#include "ddsurface.h"
|
||||
@ -12,7 +13,6 @@
|
||||
|
||||
static HGLRC ogl_create_core_context(HDC hdc);
|
||||
static HGLRC ogl_create_context(HDC hdc);
|
||||
static void ogl_set_max_fps();
|
||||
static void ogl_build_programs();
|
||||
static void ogl_create_textures(int width, int height);
|
||||
static void ogl_init_main_program();
|
||||
@ -36,7 +36,10 @@ DWORD WINAPI ogl_render_main(void)
|
||||
|
||||
g_ogl.context = ogl_create_core_context(g_ddraw->render.hdc);
|
||||
|
||||
ogl_set_max_fps();
|
||||
if (oglu_ext_exists("WGL_EXT_swap_control", g_ddraw->render.hdc) && wglSwapIntervalEXT)
|
||||
wglSwapIntervalEXT(g_ddraw->vsync ? 1 : 0);
|
||||
|
||||
fpsl_init();
|
||||
ogl_build_programs();
|
||||
ogl_create_textures(g_ddraw->width, g_ddraw->height);
|
||||
ogl_init_main_program();
|
||||
@ -110,56 +113,6 @@ static HGLRC ogl_create_context(HDC hdc)
|
||||
return context;
|
||||
}
|
||||
|
||||
static void ogl_set_max_fps()
|
||||
{
|
||||
int max_fps = g_ddraw->render.maxfps;
|
||||
|
||||
g_ddraw->fps_limiter.tick_length_ns = 0;
|
||||
g_ddraw->fps_limiter.tick_length = 0;
|
||||
|
||||
/*
|
||||
if (oglu_ext_exists("WGL_EXT_swap_control_tear", g_ddraw->render.hDC))
|
||||
{
|
||||
if (wglSwapIntervalEXT)
|
||||
{
|
||||
if (g_ddraw->vsync)
|
||||
{
|
||||
wglSwapIntervalEXT(-1);
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
}
|
||||
else
|
||||
wglSwapIntervalEXT(0);
|
||||
}
|
||||
}
|
||||
else */
|
||||
if (oglu_ext_exists("WGL_EXT_swap_control", g_ddraw->render.hdc))
|
||||
{
|
||||
if (wglSwapIntervalEXT)
|
||||
{
|
||||
if (g_ddraw->vsync)
|
||||
{
|
||||
wglSwapIntervalEXT(1);
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
}
|
||||
else
|
||||
wglSwapIntervalEXT(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (max_fps < 0)
|
||||
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
||||
|
||||
if (max_fps > 1000)
|
||||
max_fps = 0;
|
||||
|
||||
if (max_fps > 0)
|
||||
{
|
||||
float len = 1000.0f / max_fps;
|
||||
g_ddraw->fps_limiter.tick_length_ns = len * 10000;
|
||||
g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
static void ogl_build_programs()
|
||||
{
|
||||
g_ogl.main_program = g_ogl.scale_program = 0;
|
||||
@ -573,8 +526,6 @@ static void ogl_init_scale_program()
|
||||
|
||||
static void ogl_render()
|
||||
{
|
||||
DWORD tick_start = 0;
|
||||
DWORD tick_end = 0;
|
||||
BOOL needs_update = FALSE;
|
||||
|
||||
glViewport(
|
||||
@ -606,8 +557,7 @@ static void ogl_render()
|
||||
|
||||
BOOL scale_changed = FALSE;
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
tick_start = timeGetTime();
|
||||
fpsl_frame_start();
|
||||
|
||||
EnterCriticalSection(&g_ddraw->cs);
|
||||
|
||||
@ -836,44 +786,7 @@ static void ogl_render()
|
||||
dbg_draw_frame_info_end();
|
||||
#endif
|
||||
|
||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||
{
|
||||
if (g_ddraw->fps_limiter.htimer)
|
||||
{
|
||||
if (g_ddraw->vsync)
|
||||
{
|
||||
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||
LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
|
||||
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILETIME ft = { 0 };
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
if (CompareFileTime((FILETIME *)&g_ddraw->fps_limiter.due_time, &ft) == -1)
|
||||
{
|
||||
memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||
}
|
||||
|
||||
g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
|
||||
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tick_end = timeGetTime();
|
||||
|
||||
if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
|
||||
{
|
||||
Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
|
||||
}
|
||||
}
|
||||
}
|
||||
fpsl_frame_end();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user