1
1
mirror of synced 2025-02-07 06:31:17 +01:00

Fix VSync

This commit is contained in:
esuo1198 2024-11-01 18:26:41 +09:00
parent a6c6efc2a4
commit a57bf3049e
5 changed files with 89 additions and 127 deletions

View File

@ -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 <MinHook.h>
#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<toml_table_t, void (*) (toml_table_t *)> 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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,7 +1,8 @@
#include "../patches.h"
#include "helpers.h"
#include <safetyhook.hpp>
#include <iostream>
#include <safetyhook.hpp>
namespace patches::JPN39 {
@ -69,10 +70,7 @@ 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;
@ -120,16 +118,12 @@ check_voice_tail(std::string bankName, uint8_t* pBinfBlock, std::map<std::string
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;
}
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;
}
}
@ -149,7 +143,6 @@ HOOK_MID (GenNus3bankId, ASLR (0x1407B97BD), SafetyHookContext &ctx) {
}
}
// -------------- MidHook Area End --------------
int language = 0;
@ -182,9 +175,7 @@ HOOK (i64, GetCabinetLanguage, ASLR (0x1401D1A60), i64, i64 a2) {
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;
}
@ -217,10 +208,9 @@ FUNCTION_PTR (u64*, append_chars_to_basic_string, ASLR (0x140028DA0), u64*, char
u64 *
FixToneNameEnso (u64 *Src, std::string &bankName) {
if (language == 2 || language == 4) {
if (voiceCnExist.find(bankName) != voiceCnExist.end() && voiceCnExist[bankName]) {
if (voiceCnExist.find (bankName) != voiceCnExist.end () && voiceCnExist[bankName])
Src = append_chars_to_basic_string (Src, (const char *)"_cn", 3);
}
}
return Src;
}
@ -262,6 +252,7 @@ void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
bool fixLanguage = false;
bool freezeTimer = false;
@ -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,9 +349,7 @@ Init () {
}
// Freeze Timer
if (freezeTimer) {
INSTALL_HOOK_MID (FreezeTimer);
}
if (freezeTimer) INSTALL_HOOK_MID (FreezeTimer);
// Use chs font/wordlist instead of cht
if (chsPatch) {