Prevent frame-rate dependant games from running too fast

This commit is contained in:
Luke Usher 2018-03-06 09:15:04 +00:00
parent 779be6c823
commit 65dfda6e2e
11 changed files with 173 additions and 137 deletions

Binary file not shown.

Binary file not shown.

View File

@ -40,7 +40,7 @@
// ****************************************************************** // ******************************************************************
// * func: XBVideo::XBVideo // * func: XBVideo::XBVideo
// ****************************************************************** // ******************************************************************
XBVideo::XBVideo() : m_bVSync(true), m_bFullscreen(false), m_bHardwareYUV(false) XBVideo::XBVideo() : m_bVSync(false), m_bFullscreen(false), m_bHardwareYUV(false)
{ {
strcpy(m_szVideoResolution, "Automatic (Default)"); strcpy(m_szVideoResolution, "Automatic (Default)");
} }

View File

@ -1,123 +1,124 @@
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by C:\Work\Cxbx-Reloaded\resource\Cxbx.rc // Used by C:\Users\Luke\Desktop\Projects\Cxbx-Reloaded\resource\Cxbx.rc
// //
#define IDI_CXBX 101 #define IDI_CXBX 101
#define IDB_SPLASH 102 #define IDB_SPLASH 102
#define IDR_MAINMENU 103 #define IDR_MAINMENU 103
#define IDB_LOGO 106 #define IDB_LOGO 106
#define IDB_ABOUT 108 #define IDB_ABOUT 108
#define IDD_CONTROLLER_CFG 111 #define IDD_CONTROLLER_CFG 111
#define IDD_VIDEO_CFG 113 #define IDD_VIDEO_CFG 113
#define IDD_AUDIO_CFG 114 #define IDD_AUDIO_CFG 114
#define IDR_JPEG_ABOUT 116 #define IDR_JPEG_ABOUT 116
#define IDR_JPEG_SPLASH 118 #define IDR_JPEG_SPLASH 118
#define IDD_ABOUT 119 #define IDD_ABOUT 119
#define IDR_CONTRIBUTORS 121 #define IDR_CONTRIBUTORS 121
#define IDR_COPYING 122 #define IDR_COPYING 122
#define IDS_UEM 123 #define IDS_UEM 123
#define IDC_SET_X 1000 #define IDC_SET_X 1000
#define IDC_SET_Y 1001 #define IDC_SET_Y 1001
#define IDC_SET_A 1002 #define IDC_SET_A 1002
#define IDC_SET_B 1003 #define IDC_SET_B 1003
#define IDC_SET_WHITE 1004 #define IDC_SET_WHITE 1004
#define IDC_SET_BLACK 1005 #define IDC_SET_BLACK 1005
#define IDC_SET_LTRIGGER 1006 #define IDC_SET_LTRIGGER 1006
#define IDC_SET_RTRIGGER 1007 #define IDC_SET_RTRIGGER 1007
#define IDC_SET_LTHUMB 1008 #define IDC_SET_LTHUMB 1008
#define IDC_SET_RTHUMB 1009 #define IDC_SET_RTHUMB 1009
#define IDC_SET_START 1010 #define IDC_SET_START 1010
#define IDC_SET_BACK 1011 #define IDC_SET_BACK 1011
#define IDC_SET_DPAD_LEFT 1012 #define IDC_SET_DPAD_LEFT 1012
#define IDC_SET_DPAD_RIGHT 1013 #define IDC_SET_DPAD_RIGHT 1013
#define IDC_SET_DPAD_UP 1014 #define IDC_SET_DPAD_UP 1014
#define IDC_SET_DPAD_DOWN 1015 #define IDC_SET_DPAD_DOWN 1015
#define IDC_SET_LEFT_POSY 1016 #define IDC_SET_LEFT_POSY 1016
#define IDC_SET_LEFT_NEGX 1017 #define IDC_SET_LEFT_NEGX 1017
#define IDC_SET_LEFT_NEGY 1018 #define IDC_SET_LEFT_NEGY 1018
#define IDC_SET_LEFT_POSX 1019 #define IDC_SET_LEFT_POSX 1019
#define IDC_INPUT_CONFIG_CANCEL 1022 #define IDC_INPUT_CONFIG_CANCEL 1022
#define IDC_INPUT_CONFIG_ACCEPT 1023 #define IDC_INPUT_CONFIG_ACCEPT 1023
#define IDC_CONFIG_STATUS 1025 #define IDC_CONFIG_STATUS 1025
#define IDC_SET_RIGHT_POSY 1026 #define IDC_SET_RIGHT_POSY 1026
#define IDC_SET_RIGHT_NEGY 1027 #define IDC_SET_RIGHT_NEGY 1027
#define IDC_SET_RIGHT_NEGX 1028 #define IDC_SET_RIGHT_NEGX 1028
#define IDC_SET_RIGHT_POSX 1029 #define IDC_SET_RIGHT_POSX 1029
#define IDC_BUTTON1 1030 #define IDC_BUTTON1 1030
#define IDC_CONFIGURE_ALL 1030 #define IDC_CONFIGURE_ALL 1030
#define IDC_BUTTON2 1031 #define IDC_BUTTON2 1031
#define IDC_CV_FULLSCREEN 1034 #define IDC_CV_FULLSCREEN 1034
#define IDC_VC_DISPLAY_ADAPTER 1037 #define IDC_VC_DISPLAY_ADAPTER 1037
#define IDC_VC_D3D_DEVICE 1038 #define IDC_VC_D3D_DEVICE 1038
#define IDC_VC_ACCEPT 1040 #define IDC_VC_ACCEPT 1040
#define IDC_VC_CANCEL 1041 #define IDC_VC_CANCEL 1041
#define IDC_CV_VSYNC 1042 #define IDC_CV_VSYNC 1042
#define IDC_VC_VIDEO_RESOLUTION 1047 #define IDC_VC_VIDEO_RESOLUTION 1047
#define IDC_CV_HARDWAREYUV 1050 #define IDC_CV_HARDWAREYUV 1050
#define IDC_LIST2 1055 #define IDC_LIST2 1055
#define IDC_ABOUT 1056 #define IDC_ABOUT 1056
#define IDC_TAB1 1057 #define IDC_TAB1 1057
#define IDC_AC_ACCEPT 1058 #define IDC_AC_ACCEPT 1058
#define IDC_AC_CANCEL 1059 #define IDC_AC_CANCEL 1059
#define IDC_AC_AUDIO_ADAPTER 1060 #define IDC_AC_AUDIO_ADAPTER 1060
#define IDC_AC_LEGACY_AUDIO_HACK 1061 #define IDC_AC_LEGACY_AUDIO_HACK 1061
#define IDC_AC_PCM 1062 #define IDC_AC_PCM 1062
#define IDC_AC_XADPCM 1063 #define IDC_AC_XADPCM 1063
#define IDC_AC_UNKNOWN_CODEC 1064 #define IDC_AC_UNKNOWN_CODEC 1064
#define ID_FILE_EXIT 40005 #define ID_FILE_EXIT 40005
#define ID_HELP_ABOUT 40008 #define ID_HELP_ABOUT 40008
#define ID_EMULATION_START 40009 #define ID_EMULATION_START 40009
#define ID_FILE_OPEN_XBE 40013 #define ID_FILE_OPEN_XBE 40013
#define ID_FILE_CLOSE_XBE 40014 #define ID_FILE_CLOSE_XBE 40014
#define ID_HELP_HOMEPAGE 40019 #define ID_HELP_HOMEPAGE 40019
#define ID_FILE_SAVEXBEFILE 40021 #define ID_FILE_SAVEXBEFILE 40021
#define ID_FILE_SAVEXBEFILEAS 40022 #define ID_FILE_SAVEXBEFILEAS 40022
#define ID_EDIT_LOGOBITMAP_EXPORT 40025 #define ID_EDIT_LOGOBITMAP_EXPORT 40025
#define ID_EDIT_LOGOBITMAP_IMPORT 40026 #define ID_EDIT_LOGOBITMAP_IMPORT 40026
#define ID_EDIT_PATCH_ALLOW64MB 40027 #define ID_EDIT_PATCH_ALLOW64MB 40027
#define ID_EDIT_PATCH_DEBUGMODE 40031 #define ID_EDIT_PATCH_DEBUGMODE 40031
#define ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE 40035 #define ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE 40035
#define ID_EMULATION_DEBUGOUTPUTGUI_FILE 40036 #define ID_EMULATION_DEBUGOUTPUTGUI_FILE 40036
#define ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE 40037 #define ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE 40037
#define ID_EMULATION_DEBUGOUTPUTKERNEL_FILE 40038 #define ID_EMULATION_DEBUGOUTPUTKERNEL_FILE 40038
#define ID_EMULATION_LLE_APU 40039 #define ID_EMULATION_LLE_APU 40039
#define ID_EMULATION_LLE_GPU 40040 #define ID_EMULATION_LLE_GPU 40040
#define ID_EMULATION_LLE_JIT 40041 #define ID_EMULATION_LLE_JIT 40041
#define ID_SETTINGS_CONFIG_CONTROLLER 40046 #define ID_SETTINGS_CONFIG_CONTROLLER 40046
#define ID_SETTINGS_CONFIG_VIDEO 40047 #define ID_SETTINGS_CONFIG_VIDEO 40047
#define ID_SETTINGS_CONFIG_AUDIO 40048 #define ID_SETTINGS_CONFIG_AUDIO 40048
#define ID_FILE_RXBE_0 40050 #define ID_FILE_RXBE_0 40050
#define ID_FILE_RXBE_1 40051 #define ID_FILE_RXBE_1 40051
#define ID_FILE_RXBE_2 40052 #define ID_FILE_RXBE_2 40052
#define ID_FILE_RXBE_3 40053 #define ID_FILE_RXBE_3 40053
#define ID_FILE_RXBE_4 40054 #define ID_FILE_RXBE_4 40054
#define ID_FILE_RXBE_5 40055 #define ID_FILE_RXBE_5 40055
#define ID_FILE_RXBE_6 40056 #define ID_FILE_RXBE_6 40056
#define ID_FILE_RXBE_7 40057 #define ID_FILE_RXBE_7 40057
#define ID_FILE_RXBE_8 40058 #define ID_FILE_RXBE_8 40058
#define ID_FILE_RXBE_9 40059 #define ID_FILE_RXBE_9 40059
#define ID_EDIT_DUMPXBEINFOTO_FILE 40071 #define ID_EDIT_DUMPXBEINFOTO_FILE 40071
#define ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE 40072 #define ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE 40072
#define ID_EMULATION_STOP 40082 #define ID_EMULATION_STOP 40082
#define ID_SETTINGS_CACHE 40083 #define ID_SETTINGS_CACHE 40083
#define ID_CACHE_CLEARHLECACHE_ALL 40084 #define ID_CACHE_CLEARHLECACHE_ALL 40084
#define ID_CACHE_CLEARHLECACHE_CURRENT 40085 #define ID_CACHE_CLEARHLECACHE_CURRENT 40085
#define ID_SETTINGS_XINPUT 40086 #define ID_SETTINGS_XINPUT 40086
#define ID_SETTINGS_HACKS 40088 #define ID_SETTINGS_HACKS 40088
#define ID_HACKS_DISABLEPIXELSHADERS 40089 #define ID_HACKS_DISABLEPIXELSHADERS 40089
#define ID_LED 40090 #define ID_LED 40090
#define ID_SETTINGS_INITIALIZE 40091 #define ID_SETTINGS_INITIALIZE 40091
#define ID_EMULATION_STARTDEBUGGER 40092 #define ID_EMULATION_STARTDEBUGGER 40092
#define ID_FPS 40096 #define ID_FPS 40096
#define IDC_STATIC -1 #define ID_HACKS_UNCAPFRAMERATE 40097
#define IDC_STATIC -1
// Next default values for new objects
// // Next default values for new objects
#ifdef APSTUDIO_INVOKED //
#ifndef APSTUDIO_READONLY_SYMBOLS #ifdef APSTUDIO_INVOKED
#define _APS_NEXT_RESOURCE_VALUE 130 #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_COMMAND_VALUE 40097 #define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_CONTROL_VALUE 1058 #define _APS_NEXT_COMMAND_VALUE 40097
#define _APS_NEXT_SYMED_VALUE 104 #define _APS_NEXT_CONTROL_VALUE 1058
#endif #define _APS_NEXT_SYMED_VALUE 104
#endif #endif
#endif

View File

@ -180,6 +180,12 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
m_DisablePixelShaders = 0; m_DisablePixelShaders = 0;
} }
dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "HackUncapFrameRate", NULL, &dwType, (PBYTE)&m_UncapFramerate, &dwSize);
if (result != ERROR_SUCCESS) {
m_UncapFramerate = 0;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize); result = RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize);
if (result != ERROR_SUCCESS) { if (result != ERROR_SUCCESS) {
@ -1296,6 +1302,12 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
RefreshMenus(); RefreshMenus();
break; break;
case ID_HACKS_UNCAPFRAMERATE:
m_UncapFramerate = !m_UncapFramerate;
RefreshMenus();
break;
case ID_HELP_ABOUT: case ID_HELP_ABOUT:
{ {
ShowAboutDialog(hwnd); ShowAboutDialog(hwnd);
@ -1715,6 +1727,9 @@ void WndMain::RefreshMenus()
chk_flag = (m_DisablePixelShaders) ? MF_CHECKED : MF_UNCHECKED; chk_flag = (m_DisablePixelShaders) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_HACKS_DISABLEPIXELSHADERS, chk_flag); CheckMenuItem(settings_menu, ID_HACKS_DISABLEPIXELSHADERS, chk_flag);
chk_flag = (m_UncapFramerate) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_HACKS_UNCAPFRAMERATE, chk_flag);
} }
// emulation menu // emulation menu
@ -2070,6 +2085,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /
// register Hacks with emulator process // register Hacks with emulator process
g_EmuShared->SetDisablePixelShaders(&m_DisablePixelShaders); g_EmuShared->SetDisablePixelShaders(&m_DisablePixelShaders);
g_EmuShared->SetUncapFramerate(&m_UncapFramerate);
// shell exe // shell exe
{ {

View File

@ -212,6 +212,7 @@ class WndMain : public Wnd
// * Hack Flags // * Hack Flags
// ****************************************************************** // ******************************************************************
int m_DisablePixelShaders; int m_DisablePixelShaders;
int m_UncapFramerate;
// ****************************************************************** // ******************************************************************
// * debug output filenames // * debug output filenames

View File

@ -490,6 +490,7 @@ void PrintCurrentConfigurationLog()
{ {
printf("--------------------------- HACKS CONFIG ---------------------------\n"); printf("--------------------------- HACKS CONFIG ---------------------------\n");
printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off"); printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off");
printf("Uncap Framerate: %s\n", g_UncapFramerate == 1 ? "On" : "Off");
} }
printf("------------------------- END OF CONFIG LOG ------------------------\n"); printf("------------------------- END OF CONFIG LOG ------------------------\n");
@ -939,6 +940,8 @@ __declspec(noreturn) void CxbxKrnlInit
int HackEnabled = 0; int HackEnabled = 0;
g_EmuShared->GetDisablePixelShaders(&HackEnabled); g_EmuShared->GetDisablePixelShaders(&HackEnabled);
g_DisablePixelShaders = !!HackEnabled; g_DisablePixelShaders = !!HackEnabled;
g_EmuShared->GetUncapFramerate(&HackEnabled);
g_UncapFramerate = !!HackEnabled;
} }
#ifdef _DEBUG_PRINT_CURRENT_CONF #ifdef _DEBUG_PRINT_CURRENT_CONF

View File

@ -65,6 +65,7 @@ volatile bool g_bEmuSuspended = false;
volatile bool g_bPrintfOn = true; volatile bool g_bPrintfOn = true;
bool g_XInputEnabled = false; bool g_XInputEnabled = false;
bool g_DisablePixelShaders = false; bool g_DisablePixelShaders = false;
bool g_UncapFramerate = false;
// Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime // Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime
LARGE_INTEGER HostSystemTimeDelta = {}; LARGE_INTEGER HostSystemTimeDelta = {};

View File

@ -108,5 +108,5 @@ typedef struct DUMMY_KERNEL
extern bool g_DisablePixelShaders; extern bool g_DisablePixelShaders;
extern bool g_UncapFramerate;
#endif #endif

View File

@ -3982,37 +3982,48 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_Present)
EMUPATCH(D3DDevice_Swap)(CXBX_SWAP_PRESENT_FORWARD); // Xbox present ignores EMUPATCH(D3DDevice_Swap)(CXBX_SWAP_PRESENT_FORWARD); // Xbox present ignores
} }
std::chrono::time_point<std::chrono::high_resolution_clock> frameStartTime;
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_Swap // * patch: D3DDevice_Swap
// ****************************************************************** // ******************************************************************
DWORD WINAPI XTL::EMUPATCH(D3DDevice_Swap) DWORD WINAPI XTL::EMUPATCH(D3DDevice_Swap)
( (
DWORD Flags DWORD Flags
) )
{ {
FUNC_EXPORTS FUNC_EXPORTS
LOG_FUNC_ONE_ARG(Flags); LOG_FUNC_ONE_ARG(Flags);
static clock_t lastDrawFunctionCallTime = 0; static clock_t lastDrawFunctionCallTime = 0;
// TODO: Ensure this flag is always the same across library versions // TODO: Ensure this flag is always the same across library versions
if(Flags != 0) if (Flags != 0)
if (Flags != CXBX_SWAP_PRESENT_FORWARD) // Avoid a warning when forwarded if (Flags != CXBX_SWAP_PRESENT_FORWARD) // Avoid a warning when forwarded
EmuWarning("XTL::EmuD3DDevice_Swap: Flags != 0"); EmuWarning("XTL::EmuD3DDevice_Swap: Flags != 0");
CxbxReleaseBackBufferLock(); CxbxReleaseBackBufferLock();
// TODO: Make a video option to wait for VBlank before calling Present.
// Makes syncing to 30fps easier (which is the native frame rate for Azurik
// and Halo).
// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
clock_t currentDrawFunctionCallTime = clock(); clock_t currentDrawFunctionCallTime = clock();
HRESULT hRet = g_pD3DDevice8->Present(0, 0, 0, 0); HRESULT hRet = g_pD3DDevice8->Present(0, 0, 0, 0);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice8->Present"); DEBUG_D3DRESULT(hRet, "g_pD3DDevice8->Present");
if (!g_UncapFramerate) {
// If the last frame completed faster than the Xbox VBlank period, wait for it
// TODO: Read the frame rate target from the Xbox display mode
// See comments in GetNextVblankTime();
auto targetDuration = 16.6666666667ms;
while (std::chrono::high_resolution_clock::now() - frameStartTime < targetDuration) {
// We use an empty while loop because actually sleeping is too unstable
// Sleeping causes the frame duration to jitter...
;
}
frameStartTime = std::chrono::high_resolution_clock::now();
}
g_DeltaTime += currentDrawFunctionCallTime - lastDrawFunctionCallTime; g_DeltaTime += currentDrawFunctionCallTime - lastDrawFunctionCallTime;
lastDrawFunctionCallTime = currentDrawFunctionCallTime; lastDrawFunctionCallTime = currentDrawFunctionCallTime;
g_Frames++; g_Frames++;

View File

@ -124,6 +124,8 @@ class EmuShared : public Mutex
// ****************************************************************** // ******************************************************************
void GetDisablePixelShaders(int* value) { Lock(); *value = m_DisablePixelShaders; Unlock(); } void GetDisablePixelShaders(int* value) { Lock(); *value = m_DisablePixelShaders; Unlock(); }
void SetDisablePixelShaders(int* value) { Lock(); m_DisablePixelShaders = *value; Unlock(); } void SetDisablePixelShaders(int* value) { Lock(); m_DisablePixelShaders = *value; Unlock(); }
void GetUncapFramerate(int* value) { Lock(); *value = m_UncapFramerate; Unlock(); }
void SetUncapFramerate(int* value) { Lock(); m_UncapFramerate = *value; Unlock(); }
// ****************************************************************** // ******************************************************************
// * MSpF/Benchmark values Accessors // * MSpF/Benchmark values Accessors
@ -196,6 +198,7 @@ class EmuShared : public Mutex
int m_FlagsLLE; int m_FlagsLLE;
int m_XInputEnabled; int m_XInputEnabled;
int m_DisablePixelShaders; int m_DisablePixelShaders;
int m_UncapFramerate;
float m_MSpF; float m_MSpF;
float m_FPS; float m_FPS;
bool m_bKeQuickReboot; bool m_bKeQuickReboot;