From a57bf3049e7e351f4440b12599867761cc2e6a2f Mon Sep 17 00:00:00 2001 From: esuo1198 <54134.es@gmail.com> Date: Fri, 1 Nov 2024 18:26:41 +0900 Subject: [PATCH] Fix VSync --- src/patches/dxgi.cpp | 50 ++--------- src/patches/versions/CHN00.cpp | 3 + src/patches/versions/JPN00.cpp | 3 + src/patches/versions/JPN08.cpp | 3 + src/patches/versions/JPN39.cpp | 157 +++++++++++++++------------------ 5 files changed, 89 insertions(+), 127 deletions(-) diff --git a/src/patches/dxgi.cpp b/src/patches/dxgi.cpp index e932ed5..e5e50ff 100644 --- a/src/patches/dxgi.cpp +++ b/src/patches/dxgi.cpp @@ -1,9 +1,9 @@ #define CINTERFACE #define D3D11_NO_HELPERS #define INITGUID -#pragma optimize("", off) #include "d3d11.h" +#include "d3d12.h" #include "dxgi1_2.h" #include "dxgi1_3.h" #include "dxgi1_4.h" @@ -11,9 +11,6 @@ #include "dxgi1_6.h" #include "helpers.h" #include -#pragma comment(lib, "d3d11.lib") -#include "d3d12.h" -#pragma comment(lib, "d3d12.lib") #include "bnusio.h" #include "patches.h" @@ -27,13 +24,10 @@ namespace patches::Dxgi { // Local variables static bool FpsLimiterEnable = false; -static bool DisableVSync = false; // Prototypes -static HRESULT (STDMETHODCALLTYPE *g_oldSetFullscreenState) (IDXGISwapChain *This, BOOL Fullscreen, IDXGIOutput *pTarget); static HRESULT (STDMETHODCALLTYPE *g_oldCreateSwapChain) (IDXGIFactory *This, IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGISwapChain **ppSwapChain); -static HRESULT (STDMETHODCALLTYPE *g_oldSetFullscreenState1) (IDXGISwapChain1 *This, BOOL Fullscreen, IDXGIOutput *pTarget); static HRESULT (STDMETHODCALLTYPE *g_oldCreateSwapChainForHwnd) (IDXGIFactory2 *This, IUnknown *pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1 *pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, @@ -50,10 +44,8 @@ static HRESULT (WINAPI *g_origD3D11CreateDeviceAndSwapChain) (IDXGIAdapter *pAda ID3D11Device **ppDevice, D3D_FEATURE_LEVEL *pFeatureLevel, ID3D11DeviceContext **ppImmediateContext); -static HRESULT STDMETHODCALLTYPE SetFullscreenStateWrap (IDXGISwapChain *This, BOOL Fullscreen, IDXGIOutput *pTarget); static HRESULT STDMETHODCALLTYPE CreateSwapChainWrap (IDXGIFactory *This, IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGISwapChain **ppSwapChain); -static HRESULT STDMETHODCALLTYPE SetFullscreenState1Wrap (IDXGISwapChain1 *This, BOOL Fullscreen, IDXGIOutput *pTarget); static HRESULT STDMETHODCALLTYPE CreateSwapChainForHwndWrap (IDXGIFactory2 *This, IUnknown *pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1 *pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, IDXGIOutput *pRestrictToOutput, IDXGISwapChain1 **ppSwapChain); @@ -77,22 +69,16 @@ HookVtableFunction (T *functionPtr, T target) { auto old = *functionPtr; WRITE_MEMORY (functionPtr, T, target); - // injector::WriteMemory (functionPtr, target, true); return old; } -static HRESULT STDMETHODCALLTYPE -SetFullscreenStateWrap (IDXGISwapChain *This, BOOL Fullscreen, IDXGIOutput *pTarget) { - return S_OK; -} - static HRESULT STDMETHODCALLTYPE CreateSwapChainWrap (IDXGIFactory *This, IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGISwapChain **ppSwapChain) { HRESULT hr = g_oldCreateSwapChain (This, pDevice, pDesc, ppSwapChain); if (*ppSwapChain) { - if (FpsLimiterEnable || DisableVSync) { + if (FpsLimiterEnable) { auto old2 = HookVtableFunction (&(*ppSwapChain)->lpVtbl->Present, PresentWrap); g_oldPresentWrap = (old2) ? old2 : g_oldPresentWrap; } @@ -101,18 +87,13 @@ CreateSwapChainWrap (IDXGIFactory *This, IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC return hr; } -static HRESULT STDMETHODCALLTYPE -SetFullscreenState1Wrap (IDXGISwapChain1 *This, BOOL Fullscreen, IDXGIOutput *pTarget) { - return S_OK; -} - static HRESULT STDMETHODCALLTYPE CreateSwapChainForHwndWrap (IDXGIFactory2 *This, IUnknown *pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1 *pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, IDXGIOutput *pRestrictToOutput, IDXGISwapChain1 **ppSwapChain) { HRESULT hr = g_oldCreateSwapChainForHwnd (This, pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain); if (*ppSwapChain) { - if (FpsLimiterEnable || DisableVSync) { + if (FpsLimiterEnable) { auto old2 = HookVtableFunction (&(*ppSwapChain)->lpVtbl->Present, Present1Wrap); g_oldPresent1Wrap = (old2) ? old2 : g_oldPresent1Wrap; } @@ -123,8 +104,6 @@ CreateSwapChainForHwndWrap (IDXGIFactory2 *This, IUnknown *pDevice, HWND hWnd, c static HRESULT STDMETHODCALLTYPE PresentWrap (IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags) { - if (DisableVSync) SyncInterval = 0; - if (FpsLimiterEnable) patches::FpsLimiter::Update (); bnusio::Update (); @@ -134,10 +113,10 @@ PresentWrap (IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags) { static HRESULT STDMETHODCALLTYPE Present1Wrap (IDXGISwapChain1 *pSwapChain, UINT SyncInterval, UINT Flags) { - if (DisableVSync) SyncInterval = 0; - if (FpsLimiterEnable) patches::FpsLimiter::Update (); + bnusio::Update (); + return g_oldPresent1Wrap (pSwapChain, SyncInterval, Flags); } @@ -146,7 +125,7 @@ CreateSwapChain2Wrap (IDXGIFactory2 *This, IUnknown *pDevice, DXGI_SWAP_CHAIN_DE HRESULT hr = g_oldCreateSwapChain2 (This, pDevice, pDesc, ppSwapChain); if (*ppSwapChain) { - if (FpsLimiterEnable || DisableVSync) { + if (FpsLimiterEnable) { auto old2 = HookVtableFunction (&(*ppSwapChain)->lpVtbl->Present, PresentWrap); g_oldPresentWrap = (old2) ? old2 : g_oldPresentWrap; } @@ -160,16 +139,6 @@ CreateDXGIFactory2Wrap (UINT Flags, REFIID riid, void **ppFactory) { HRESULT hr = g_origCreateDXGIFactory2 (Flags, riid, ppFactory); if (SUCCEEDED (hr)) { - int factoryType = 0; - - if (IsEqualIID (riid, IID_IDXGIFactory1)) factoryType = 1; - else if (IsEqualIID (riid, IID_IDXGIFactory2)) factoryType = 2; - else if (IsEqualIID (riid, IID_IDXGIFactory3)) factoryType = 3; - else if (IsEqualIID (riid, IID_IDXGIFactory4)) factoryType = 4; - else if (IsEqualIID (riid, IID_IDXGIFactory5)) factoryType = 5; - else if (IsEqualIID (riid, IID_IDXGIFactory6)) factoryType = 6; - else if (IsEqualIID (riid, IID_IDXGIFactory7)) factoryType = 7; - IDXGIFactory2 *factory = (IDXGIFactory2 *)*ppFactory; auto old = HookVtableFunction (&factory->lpVtbl->CreateSwapChain, CreateSwapChain2Wrap); @@ -232,20 +201,15 @@ D3D11CreateDeviceAndSwapChainWrap (IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE Drive void Init () { - bool vsync = false; i32 fpsLimit = 120; auto configPath = std::filesystem::current_path () / "config.toml"; std::unique_ptr config_ptr (openConfig (configPath), toml_free); if (config_ptr) { auto graphics = openConfigSection (config_ptr.get (), "graphics"); - if (graphics) { - vsync = readConfigBool (graphics, "vsync", vsync); - fpsLimit = readConfigInt (graphics, "fpslimit", fpsLimit); - } + if (graphics) fpsLimit = readConfigInt (graphics, "fpslimit", fpsLimit); } - DisableVSync = !vsync; FpsLimiterEnable = fpsLimit > 0; patches::FpsLimiter::Init ((float)fpsLimit); diff --git a/src/patches/versions/CHN00.cpp b/src/patches/versions/CHN00.cpp index 7a51b29..04b79c2 100644 --- a/src/patches/versions/CHN00.cpp +++ b/src/patches/versions/CHN00.cpp @@ -99,6 +99,7 @@ void Init () { i32 xRes = 1920; i32 yRes = 1080; + bool vsync = false; bool unlockSongs = true; bool fixLanguage = false; bool demoMovie = true; @@ -144,12 +145,14 @@ Init () { xRes = readConfigInt (res, "x", xRes); yRes = readConfigInt (res, "y", yRes); } + vsync = readConfigBool (graphics, "vsync", vsync); } } // Apply common config patch WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes); WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01); // Bypass errors diff --git a/src/patches/versions/JPN00.cpp b/src/patches/versions/JPN00.cpp index 4b5f475..c3595fb 100644 --- a/src/patches/versions/JPN00.cpp +++ b/src/patches/versions/JPN00.cpp @@ -48,6 +48,7 @@ void Init () { i32 xRes = 1920; i32 yRes = 1080; + bool vsync = false; bool unlockSongs = true; auto configPath = std::filesystem::current_path () / "config.toml"; @@ -63,12 +64,14 @@ Init () { xRes = readConfigInt (res, "x", xRes); yRes = readConfigInt (res, "y", yRes); } + vsync = readConfigBool (graphics, "vsync", vsync); } } // Apply common config patch WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes); WRITE_MEMORY (ASLR (0x140224B32), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x1403D6189), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); if (unlockSongs) WRITE_MEMORY (ASLR (0x1401F6B78), u8, 0xB0, 0x01); // Bypass errors diff --git a/src/patches/versions/JPN08.cpp b/src/patches/versions/JPN08.cpp index 36fe451..c22c1f1 100644 --- a/src/patches/versions/JPN08.cpp +++ b/src/patches/versions/JPN08.cpp @@ -50,6 +50,7 @@ void Init () { i32 xRes = 1920; i32 yRes = 1080; + bool vsync = false; bool unlockSongs = true; auto configPath = std::filesystem::current_path () / "config.toml"; @@ -65,12 +66,14 @@ Init () { xRes = readConfigInt (res, "x", xRes); yRes = readConfigInt (res, "y", yRes); } + vsync = readConfigBool (graphics, "vsync", vsync); } } // Apply common config patch WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes); WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01); // Bypass errors diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp index 0be3ada..af8c3c8 100644 --- a/src/patches/versions/JPN39.cpp +++ b/src/patches/versions/JPN39.cpp @@ -1,7 +1,8 @@ #include "../patches.h" #include "helpers.h" -#include #include +#include + namespace patches::JPN39 { @@ -69,15 +70,12 @@ HOOK_MID (ChangeLanguageType, ASLR (0x1400B2016), SafetyHookContext &ctx) { if (*pFontType == 4) *pFontType = 2; } -i64 __fastcall -lua_freeze_timer (i64 a1) { - return lua_pushtrue (a1); -} +i64 __fastcall lua_freeze_timer (i64 a1) { return lua_pushtrue (a1); } HOOK_MID (FreezeTimer, ASLR (0x14019FF51), SafetyHookContext &ctx) { auto a1 = ctx.rdi; - int v9 = (int)(ctx.rax + 1); - lua_pushcclosure(a1, reinterpret_cast(&lua_freeze_timer), v9); + int v9 = (int)(ctx.rax + 1); + lua_pushcclosure (a1, reinterpret_cast (&lua_freeze_timer), v9); ctx.rip = ASLR (0x14019FF65); } @@ -88,8 +86,8 @@ bool enableSwitchVoice = false; std::mutex nus3bankMtx; int -get_bank_id(std::string bankName) { - if (nus3bankMap.find(bankName) == nus3bankMap.end()) { +get_bank_id (std::string bankName) { + if (nus3bankMap.find (bankName) == nus3bankMap.end ()) { nus3bankMap[bankName] = nus3bankIdCounter; nus3bankIdCounter++; } @@ -97,59 +95,54 @@ get_bank_id(std::string bankName) { } void -check_voice_tail(std::string bankName, uint8_t* pBinfBlock, std::map &voiceExist, std::string tail) { +check_voice_tail (std::string bankName, uint8_t *pBinfBlock, std::map &voiceExist, std::string tail) { // check if any voice_xxx.nus3bank has xxx_cn audio inside while loading - if (enableSwitchVoice && bankName.starts_with("voice_")) { - int binfLength = *((int*)(pBinfBlock + 4)); - uint8_t* pGrpBlock = pBinfBlock + 8 + binfLength; - int grpLength = *((int*)(pGrpBlock + 4)); - uint8_t* pDtonBlock = pGrpBlock + 8 + grpLength; - int dtonLength = *((int*)(pDtonBlock + 4)); - uint8_t* pToneBlock = pDtonBlock + 8 + dtonLength; - int toneSize = *((int*)(pToneBlock + 8)); - uint8_t* pToneBase = pToneBlock + 12; + if (enableSwitchVoice && bankName.starts_with ("voice_")) { + int binfLength = *((int *)(pBinfBlock + 4)); + uint8_t *pGrpBlock = pBinfBlock + 8 + binfLength; + int grpLength = *((int *)(pGrpBlock + 4)); + uint8_t *pDtonBlock = pGrpBlock + 8 + grpLength; + int dtonLength = *((int *)(pDtonBlock + 4)); + uint8_t *pToneBlock = pDtonBlock + 8 + dtonLength; + int toneSize = *((int *)(pToneBlock + 8)); + uint8_t *pToneBase = pToneBlock + 12; for (int i = 0; i < toneSize; i++) { - if (*((int*)(pToneBase + i * 8 + 4)) <= 0x0C) continue; // skip empty space - uint8_t* currToneBase = pToneBase + *((int*)(pToneBase + i * 8)); - int titleOffset = -1; + if (*((int *)(pToneBase + i * 8 + 4)) <= 0x0C) continue; // skip empty space + uint8_t *currToneBase = pToneBase + *((int *)(pToneBase + i * 8)); + int titleOffset = -1; switch (*currToneBase) { - case 0xFF: titleOffset = 9; break; // audio mark - case 0x7F: titleOffset = 5; break; // randomizer mark - default: continue; // unknown mark skip + case 0xFF: titleOffset = 9; break; // audio mark + case 0x7F: titleOffset = 5; break; // randomizer mark + default: continue; // unknown mark skip } if (titleOffset > 0) { - std::string title((char*)(currToneBase + titleOffset)); - if (title.ends_with(tail)) { - if (voiceExist.find(bankName) == voiceExist.end() || !voiceExist[bankName]) { - voiceExist[bankName] = true; - } + std::string title ((char *)(currToneBase + titleOffset)); + if (title.ends_with (tail)) { + if (voiceExist.find (bankName) == voiceExist.end () || !voiceExist[bankName]) voiceExist[bankName] = true; return; } } } - if (voiceExist.find(bankName) == voiceExist.end() || voiceExist[bankName]) { - voiceExist[bankName] = false; - } + if (voiceExist.find (bankName) == voiceExist.end () || voiceExist[bankName]) voiceExist[bankName] = false; } } HOOK_MID (GenNus3bankId, ASLR (0x1407B97BD), SafetyHookContext &ctx) { - std::lock_guard lock(nus3bankMtx); - if ((uint8_t**)(ctx.rcx + 8) != nullptr) { - uint8_t* pNus3bankFile = *((uint8_t **)(ctx.rcx + 8)); + std::lock_guard lock (nus3bankMtx); + if ((uint8_t **)(ctx.rcx + 8) != nullptr) { + uint8_t *pNus3bankFile = *((uint8_t **)(ctx.rcx + 8)); if (pNus3bankFile[0] == 'N' && pNus3bankFile[1] == 'U' && pNus3bankFile[2] == 'S' && pNus3bankFile[3] == '3') { - int tocLength = *((int*)(pNus3bankFile + 16)); - uint8_t* pPropBlock = pNus3bankFile + 20 + tocLength; - int propLength = *((int*)(pPropBlock + 4)); - uint8_t* pBinfBlock = pPropBlock + 8 + propLength; - std::string bankName((char*)(pBinfBlock + 0x11)); - check_voice_tail(bankName, pBinfBlock, voiceCnExist, "_cn"); - ctx.rax = get_bank_id(bankName); + int tocLength = *((int *)(pNus3bankFile + 16)); + uint8_t *pPropBlock = pNus3bankFile + 20 + tocLength; + int propLength = *((int *)(pPropBlock + 4)); + uint8_t *pBinfBlock = pPropBlock + 8 + propLength; + std::string bankName ((char *)(pBinfBlock + 0x11)); + check_voice_tail (bankName, pBinfBlock, voiceCnExist, "_cn"); + ctx.rax = get_bank_id (bankName); } - } + } } - // -------------- MidHook Area End -------------- int language = 0; @@ -179,12 +172,10 @@ HOOK (i64, GetCabinetLanguage, ASLR (0x1401D1A60), i64, i64 a2) { return 1; } -std::string +std::string FixToneName (std::string bankName, std::string toneName) { if (language == 2 || language == 4) { - if (voiceCnExist.find(bankName) != voiceCnExist.end() && voiceCnExist[bankName]) { - return toneName + "_cn"; - } + if (voiceCnExist.find (bankName) != voiceCnExist.end () && voiceCnExist[bankName]) return toneName + "_cn"; } return toneName; } @@ -192,59 +183,58 @@ FixToneName (std::string bankName, std::string toneName) { int commonSize = 0; HOOK (i64, PlaySound, ASLR (0x1404C6DC0), i64 a1) { if (enableSwitchVoice && language != 0) { - std::string bankName((char*)lua_tolstring (a1, -3, (u64)&commonSize)); + std::string bankName ((char *)lua_tolstring (a1, -3, (u64)&commonSize)); if (bankName[0] == 'v') { - lua_pushstring(a1, (u64)(FixToneName(bankName, (char*)lua_tolstring (a1, -2, (u64)&commonSize)).c_str())); - lua_replace(a1, -3); + lua_pushstring (a1, (u64)(FixToneName (bankName, (char *)lua_tolstring (a1, -2, (u64)&commonSize)).c_str ())); + lua_replace (a1, -3); } } - return originalPlaySound(a1); + return originalPlaySound (a1); } HOOK (i64, PlaySoundMulti, ASLR (0x1404C6D60), i64 a1) { if (enableSwitchVoice && language != 0) { - std::string bankName((char*)lua_tolstring (a1, -3, (u64)&commonSize)); + std::string bankName ((char *)lua_tolstring (a1, -3, (u64)&commonSize)); if (bankName[0] == 'v') { - lua_pushstring(a1, (u64)(FixToneName(bankName, (char*)lua_tolstring (a1, -2, (u64)&commonSize)).c_str())); - lua_replace(a1, -3); + lua_pushstring (a1, (u64)(FixToneName (bankName, (char *)lua_tolstring (a1, -2, (u64)&commonSize)).c_str ())); + lua_replace (a1, -3); } } - return originalPlaySoundMulti(a1); + return originalPlaySoundMulti (a1); } -FUNCTION_PTR (u64*, append_chars_to_basic_string, ASLR (0x140028DA0), u64*, char*, size_t); +FUNCTION_PTR (u64 *, append_chars_to_basic_string, ASLR (0x140028DA0), u64 *, char *, size_t); -u64* -FixToneNameEnso(u64* Src, std::string &bankName) { +u64 * +FixToneNameEnso (u64 *Src, std::string &bankName) { if (language == 2 || language == 4) { - if (voiceCnExist.find(bankName) != voiceCnExist.end() && voiceCnExist[bankName]) { - Src = append_chars_to_basic_string (Src, (const char*)"_cn", 3); - } + if (voiceCnExist.find (bankName) != voiceCnExist.end () && voiceCnExist[bankName]) + Src = append_chars_to_basic_string (Src, (const char *)"_cn", 3); } return Src; } -HOOK (bool, PlaySoundEnso, ASLR (0x1404ED590), u64* a1, u64* a2, i64 a3) { +HOOK (bool, PlaySoundEnso, ASLR (0x1404ED590), u64 *a1, u64 *a2, i64 a3) { if (enableSwitchVoice && language != 0) { - std::string bankName = a1[3] > 0x10 ? std::string(*((char**)a1)) : std::string((char*)a1); - if (bankName[0] == 'v') a2 = FixToneNameEnso(a2, bankName); + std::string bankName = a1[3] > 0x10 ? std::string (*((char **)a1)) : std::string ((char *)a1); + if (bankName[0] == 'v') a2 = FixToneNameEnso (a2, bankName); } - return originalPlaySoundEnso(a1, a2, a3); + return originalPlaySoundEnso (a1, a2, a3); } -HOOK (bool, PlaySoundSpecial, ASLR (0x1404ED230), u64* a1, u64* a2) { +HOOK (bool, PlaySoundSpecial, ASLR (0x1404ED230), u64 *a1, u64 *a2) { if (enableSwitchVoice && language != 0) { - std::string bankName = a1[3] > 0x10 ? std::string(*((char**)a1)) : std::string((char*)a1); - if (bankName[0] == 'v') a2 = FixToneNameEnso(a2, bankName); + std::string bankName = a1[3] > 0x10 ? std::string (*((char **)a1)) : std::string ((char *)a1); + if (bankName[0] == 'v') a2 = FixToneNameEnso (a2, bankName); } - return originalPlaySoundSpecial(a1, a2); + return originalPlaySoundSpecial (a1, a2); } int loaded_fail_count = 0; HOOK (i64, LoadedBankAll, ASLR (0x1404C69F0), i64 a1) { originalLoadedBankAll (a1); - auto result = lua_toboolean(a1, -1); - lua_settop(a1, 0); + auto result = lua_toboolean (a1, -1); + lua_settop (a1, 0); if (result) { loaded_fail_count = 0; lua_pushboolean (a1, 1); @@ -262,6 +252,7 @@ void Init () { i32 xRes = 1920; i32 yRes = 1080; + bool vsync = false; bool unlockSongs = true; bool fixLanguage = false; bool freezeTimer = false; @@ -270,7 +261,7 @@ Init () { bool modeCollabo026 = false; bool modeAprilFool001 = false; - bool useLayeredfs = false; + bool useLayeredfs = false; auto configPath = std::filesystem::current_path () / "config.toml"; std::unique_ptr config_ptr (openConfig (configPath), toml_free); @@ -296,17 +287,17 @@ Init () { xRes = readConfigInt (res, "x", xRes); yRes = readConfigInt (res, "y", yRes); } + vsync = readConfigBool (graphics, "vsync", vsync); } auto layeredfs = openConfigSection (config_ptr.get (), "layeredfs"); - if (layeredfs) { - useLayeredfs = readConfigBool (layeredfs, "enabled", useLayeredfs); - } + if (layeredfs) useLayeredfs = readConfigBool (layeredfs, "enabled", useLayeredfs); } // Apply common config patch WRITE_MEMORY (ASLR (0x140494533), i32, xRes); WRITE_MEMORY (ASLR (0x14049453A), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01); // Bypass errors @@ -358,17 +349,15 @@ Init () { } // Freeze Timer - if (freezeTimer) { - INSTALL_HOOK_MID (FreezeTimer); - } + if (freezeTimer) INSTALL_HOOK_MID (FreezeTimer); // Use chs font/wordlist instead of cht if (chsPatch) { bool fontExistAll = true; - const char* fontToCheck[] {"cn_30.nutexb", "cn_30.xml", "cn_32.nutexb", "cn_32.xml", "cn_64.nutexb", "cn_64.xml"}; + const char *fontToCheck[]{"cn_30.nutexb", "cn_30.xml", "cn_32.nutexb", "cn_32.xml", "cn_64.nutexb", "cn_64.xml"}; for (int i = 0; i < 6; i++) { - if (useLayeredfs && std::filesystem::exists(std::string("..\\..\\Data_mods\\x64\\font\\") + fontToCheck[i])) continue; - if (std::filesystem::exists(std::string("..\\..\\Data\\x64\\font\\") + fontToCheck[i])) continue; + if (useLayeredfs && std::filesystem::exists (std::string ("..\\..\\Data_mods\\x64\\font\\") + fontToCheck[i])) continue; + if (std::filesystem::exists (std::string ("..\\..\\Data\\x64\\font\\") + fontToCheck[i])) continue; fontExistAll = false; } @@ -384,7 +373,7 @@ Init () { // Fix language if (fixLanguage) { - INSTALL_HOOK (GetLanguage); // Language will use in other place + INSTALL_HOOK (GetLanguage); // Language will use in other place INSTALL_HOOK (GetRegionLanguage); INSTALL_HOOK (GetCabinetLanguage); }