mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-25 01:57:47 +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/dllmain.c \
|
||||||
src/wndproc.c \
|
src/wndproc.c \
|
||||||
src/utils.c \
|
src/utils.c \
|
||||||
|
src/fps_limiter.c \
|
||||||
src/opengl_utils.c
|
src/opengl_utils.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\directinput.c" />
|
<ClCompile Include="src\directinput.c" />
|
||||||
<ClCompile Include="src\dllmain.c" />
|
<ClCompile Include="src\dllmain.c" />
|
||||||
|
<ClCompile Include="src\fps_limiter.c" />
|
||||||
<ClCompile Include="src\IDirect3D\IDirect3D.c" />
|
<ClCompile Include="src\IDirect3D\IDirect3D.c" />
|
||||||
<ClCompile Include="src\IDirect3D\IDirect3D2.c" />
|
<ClCompile Include="src\IDirect3D\IDirect3D2.c" />
|
||||||
<ClCompile Include="src\IDirect3D\IDirect3D3.c" />
|
<ClCompile Include="src\IDirect3D\IDirect3D3.c" />
|
||||||
@ -63,6 +64,7 @@
|
|||||||
<ClInclude Include="inc\ddclipper.h" />
|
<ClInclude Include="inc\ddclipper.h" />
|
||||||
<ClInclude Include="inc\directinput.h" />
|
<ClInclude Include="inc\directinput.h" />
|
||||||
<ClInclude Include="inc\dllmain.h" />
|
<ClInclude Include="inc\dllmain.h" />
|
||||||
|
<ClInclude Include="inc\fps_limiter.h" />
|
||||||
<ClInclude Include="inc\glcorearb.h" />
|
<ClInclude Include="inc\glcorearb.h" />
|
||||||
<ClInclude Include="inc\IDirect3D.h" />
|
<ClInclude Include="inc\IDirect3D.h" />
|
||||||
<ClInclude Include="inc\IAMMediaStream.h" />
|
<ClInclude Include="inc\IAMMediaStream.h" />
|
||||||
|
@ -147,6 +147,9 @@
|
|||||||
<ClCompile Include="src\IDirectDraw\IDirectDrawGammaControl.c">
|
<ClCompile Include="src\IDirectDraw\IDirectDrawGammaControl.c">
|
||||||
<Filter>Source Files\IDirectDraw</Filter>
|
<Filter>Source Files\IDirectDraw</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fps_limiter.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="inc\ddraw.h">
|
<ClInclude Include="inc\ddraw.h">
|
||||||
@ -248,6 +251,9 @@
|
|||||||
<ClInclude Include="inc\IDirectDrawGammaControl.h">
|
<ClInclude Include="inc\IDirectDrawGammaControl.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="inc\fps_limiter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="ddraw.rc">
|
<ResourceCompile Include="ddraw.rc">
|
||||||
|
1
inc/dd.h
1
inc/dd.h
@ -118,7 +118,6 @@ typedef struct cnc_ddraw
|
|||||||
BOOL show_driver_warning;
|
BOOL show_driver_warning;
|
||||||
speed_limiter ticks_limiter;
|
speed_limiter ticks_limiter;
|
||||||
speed_limiter flip_limiter;
|
speed_limiter flip_limiter;
|
||||||
speed_limiter fps_limiter;
|
|
||||||
|
|
||||||
} cnc_ddraw;
|
} 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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
#include "fps_limiter.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "render_d3d9.h"
|
#include "render_d3d9.h"
|
||||||
@ -78,7 +78,7 @@ void cfg_load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_ddraw->accurate_timers || g_ddraw->vsync)
|
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
|
//can't fully set it up here due to missing g_ddraw->mode.dmDisplayFrequency
|
||||||
|
|
||||||
int max_ticks = cfg_get_int("maxgameticks", 0);
|
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_d3d9.h"
|
||||||
#include "render_gdi.h"
|
#include "render_gdi.h"
|
||||||
#include "render_ogl.h"
|
#include "render_ogl.h"
|
||||||
|
#include "fps_limiter.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@ -817,11 +818,11 @@ ULONG dd_Release()
|
|||||||
g_ddraw->flip_limiter.htimer = NULL;
|
g_ddraw->flip_limiter.htimer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.htimer)
|
if (g_fpsl.htimer)
|
||||||
{
|
{
|
||||||
CancelWaitableTimer(g_ddraw->fps_limiter.htimer);
|
CancelWaitableTimer(g_fpsl.htimer);
|
||||||
CloseHandle(g_ddraw->fps_limiter.htimer);
|
CloseHandle(g_fpsl.htimer);
|
||||||
g_ddraw->fps_limiter.htimer = NULL;
|
g_fpsl.htimer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteCriticalSection(&g_ddraw->cs);
|
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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
#include "fps_limiter.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "ddsurface.h"
|
#include "ddsurface.h"
|
||||||
#include "d3d9shader.h"
|
#include "d3d9shader.h"
|
||||||
@ -13,7 +14,6 @@
|
|||||||
static BOOL d3d9_create_resouces();
|
static BOOL d3d9_create_resouces();
|
||||||
static BOOL d3d9_set_states();
|
static BOOL d3d9_set_states();
|
||||||
static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch);
|
static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch);
|
||||||
static void d3d9_set_max_fps();
|
|
||||||
|
|
||||||
static d3d9_renderer g_d3d9;
|
static d3d9_renderer g_d3d9;
|
||||||
|
|
||||||
@ -305,35 +305,12 @@ static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch)
|
|||||||
return FALSE;
|
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)
|
DWORD WINAPI d3d9_render_main(void)
|
||||||
{
|
{
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
|
|
||||||
d3d9_set_max_fps();
|
fpsl_init();
|
||||||
|
|
||||||
DWORD tick_start = 0;
|
|
||||||
DWORD tick_end = 0;
|
|
||||||
BOOL needs_update = FALSE;
|
BOOL needs_update = FALSE;
|
||||||
|
|
||||||
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : 200;
|
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;
|
static int tex_index = 0, palIndex = 0;
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_start();
|
||||||
tick_start = timeGetTime();
|
|
||||||
|
|
||||||
EnterCriticalSection(&g_ddraw->cs);
|
EnterCriticalSection(&g_ddraw->cs);
|
||||||
|
|
||||||
@ -456,44 +432,7 @@ DWORD WINAPI d3d9_render_main(void)
|
|||||||
dbg_draw_frame_info_end();
|
dbg_draw_frame_info_end();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_end();
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "fps_limiter.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "ddsurface.h"
|
#include "ddsurface.h"
|
||||||
#include "opengl_utils.h"
|
#include "opengl_utils.h"
|
||||||
@ -30,26 +31,7 @@ DWORD WINAPI gdi_render_main(void)
|
|||||||
|
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
|
|
||||||
DWORD tick_start = 0;
|
fpsl_init();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : INFINITE;
|
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();
|
dbg_draw_frame_info_start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_start();
|
||||||
tick_start = timeGetTime();
|
|
||||||
|
|
||||||
EnterCriticalSection(&g_ddraw->cs);
|
EnterCriticalSection(&g_ddraw->cs);
|
||||||
|
|
||||||
@ -155,35 +136,7 @@ DWORD WINAPI gdi_render_main(void)
|
|||||||
dbg_draw_frame_info_end();
|
dbg_draw_frame_info_end();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_end();
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
101
src/render_ogl.c
101
src/render_ogl.c
@ -1,5 +1,6 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "fps_limiter.h"
|
||||||
#include "opengl_utils.h"
|
#include "opengl_utils.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "ddsurface.h"
|
#include "ddsurface.h"
|
||||||
@ -12,7 +13,6 @@
|
|||||||
|
|
||||||
static HGLRC ogl_create_core_context(HDC hdc);
|
static HGLRC ogl_create_core_context(HDC hdc);
|
||||||
static HGLRC ogl_create_context(HDC hdc);
|
static HGLRC ogl_create_context(HDC hdc);
|
||||||
static void ogl_set_max_fps();
|
|
||||||
static void ogl_build_programs();
|
static void ogl_build_programs();
|
||||||
static void ogl_create_textures(int width, int height);
|
static void ogl_create_textures(int width, int height);
|
||||||
static void ogl_init_main_program();
|
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);
|
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_build_programs();
|
||||||
ogl_create_textures(g_ddraw->width, g_ddraw->height);
|
ogl_create_textures(g_ddraw->width, g_ddraw->height);
|
||||||
ogl_init_main_program();
|
ogl_init_main_program();
|
||||||
@ -110,56 +113,6 @@ static HGLRC ogl_create_context(HDC hdc)
|
|||||||
return context;
|
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()
|
static void ogl_build_programs()
|
||||||
{
|
{
|
||||||
g_ogl.main_program = g_ogl.scale_program = 0;
|
g_ogl.main_program = g_ogl.scale_program = 0;
|
||||||
@ -573,8 +526,6 @@ static void ogl_init_scale_program()
|
|||||||
|
|
||||||
static void ogl_render()
|
static void ogl_render()
|
||||||
{
|
{
|
||||||
DWORD tick_start = 0;
|
|
||||||
DWORD tick_end = 0;
|
|
||||||
BOOL needs_update = FALSE;
|
BOOL needs_update = FALSE;
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
@ -606,8 +557,7 @@ static void ogl_render()
|
|||||||
|
|
||||||
BOOL scale_changed = FALSE;
|
BOOL scale_changed = FALSE;
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_start();
|
||||||
tick_start = timeGetTime();
|
|
||||||
|
|
||||||
EnterCriticalSection(&g_ddraw->cs);
|
EnterCriticalSection(&g_ddraw->cs);
|
||||||
|
|
||||||
@ -836,44 +786,7 @@ static void ogl_render()
|
|||||||
dbg_draw_frame_info_end();
|
dbg_draw_frame_info_end();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_ddraw->fps_limiter.tick_length > 0)
|
fpsl_frame_end();
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user