diff --git a/include/DLL_VERSION.H b/include/DLL_VERSION.H index cbb0afd..b867f19 100644 --- a/include/DLL_VERSION.H +++ b/include/DLL_VERSION.H @@ -2,8 +2,8 @@ #define TBF_MAJOR 0 -#define TBF_MINOR 1 -#define TBF_BUILD 7 +#define TBF_MINOR 2 +#define TBF_BUILD 0 #define TBF_REV 0 diff --git a/include/config.h b/include/config.h index 9543582..02ba9f4 100644 --- a/include/config.h +++ b/include/config.h @@ -31,41 +31,26 @@ extern std::wstring DEFAULT_BK2; struct tbf_config_t { struct { - uint32_t sample_hz = 48000; - uint32_t channels = 6; // OBSOLETE - bool compatibility = false; - bool enable_fix = true; + uint32_t sample_hz = -1; + uint32_t channels = 6; + bool compatibility = false; + bool enable_fix = true; } audio; struct { - bool yield_processor = true; - bool allow_fake_sleep = false; - bool minimize_latency = false; - DWORD speedresetcode_addr = 0x0046C0F9; //0x0046C529; - DWORD speedresetcode2_addr = 0x0056EB41; //0x0056E441; 0x217B464 - DWORD speedresetcode3_addr = 0x0056E03F; //0x0056D93F; - DWORD limiter_branch_addr = 0x00990F53; //0x00990873; - bool disable_limiter = true; - bool auto_adjust = false; - int target = 60; - int battle_target = 60; - bool battle_adaptive = false; - int cutscene_target = 30; - bool reshade_fix = false; + bool replace_limiter = true; + int target = 60; + bool reshade_fix = false; } framerate; struct { - bool capture = false; + bool capture = false; } file_io; struct { - bool allow_broadcasts = false; + bool allow_broadcasts = false; } steam; - struct { - bool fix_priest = true; - } lua; - struct { float fovy = 0.785398f; float aspect_ratio = 1.777778f; @@ -81,11 +66,13 @@ struct tbf_config_t } render; struct { - bool dump = false; - bool remaster = true; - bool cache = true; - int32_t max_cache_in_mib = 2048L; - int32_t worker_threads = 6; + bool dump = false; + bool remaster = true; + bool cache = true; + bool uncompressed = false; + float lod_bias = -0.2666f; + int32_t max_cache_in_mib = 2048L; + int32_t worker_threads = 6; } textures; struct { diff --git a/include/framerate.h b/include/framerate.h index 46d29db..80864a4 100644 --- a/include/framerate.h +++ b/include/framerate.h @@ -1,12 +1,12 @@ /** - * This file is part of Tales of Zestiria "Fix". + * This file is part of Tales of Berseria "Fix". * - * Tales of Zestiria "Fix" is free software : you can redistribute it + * Tales of Berseria "Fix" is free software : you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by The Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * - * Tales of Zestiria "Fix" is distributed in the hope that it will be + * Tales of Berseria "Fix" is distributed in the hope that it will be * useful, * * But WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,20 +14,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Tales of Zestiria "Fix". + * along with Tales of Berseria "Fix". * * If not, see . * **/ -#ifndef __TZF__FRAMERATE_H__ -#define __TZF__FRAMERATE_H__ +#ifndef __TBF__FRAMERATE_H__ +#define __TBF__FRAMERATE_H__ #include #include #include "command.h" -namespace tzf +namespace tbf { namespace FrameRateFix { @@ -39,10 +39,7 @@ namespace tzf void RenderTick (void); - // Determine the appropriate value for TickScale - long CalcTickScale (double elapsed_ms); - - +#if 0 // // At key points during the game, we need to disable the code that // cuts timing in half. These places will be wrapped by calls to @@ -52,6 +49,7 @@ namespace tzf void End30FPSEvent (void); void SetFPS (int fps); +#endif class CommandProcessor : public SK_IVariableListener { public: @@ -74,23 +72,12 @@ namespace tzf static CommandProcessor* pCommProc; }; - - // True if the game is running in fullscreen - extern bool fullscreen; - - // True if the game is being framerate limited by the DRIVER - extern bool driver_limit_setup; - // True if the executable has been modified (at run-time) to allow 60 FPS extern bool variable_speed_installed; // This is actually setup in the SK DLL that loads this one extern uint32_t target_fps; - // Store the original unmodifed game instructions - extern uint8_t old_speed_reset_code2 [7]; - extern uint8_t old_limiter_instruction [6]; - // Cache the game's tick scale for timing -- this can be changed without // our knowledge, so this is more or less a hint rather than a rule extern int32_t tick_scale; @@ -104,4 +91,4 @@ namespace tzf } } -#endif /* __TZF__FRAMERATE_H__ */ \ No newline at end of file +#endif /* __TBF__FRAMERATE_H__ */ \ No newline at end of file diff --git a/include/parameter.h b/include/parameter.h index 889ef51..7d9e99e 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -163,8 +163,16 @@ class ParameterBool : public Parameter bool load (bool& ref); + enum boolean_term_t { + TrueFalse = 0, + OnOff = 1, + YesNo = 2, + ZeroNonZero = 3 + }; + protected: - bool value; + bool value; + boolean_term_t type = TrueFalse; }; class ParameterFloat : public Parameter diff --git a/include/scanner.h b/include/scanner.h index 1db517b..9ae4d93 100644 --- a/include/scanner.h +++ b/include/scanner.h @@ -20,11 +20,12 @@ * **/ -#ifndef __TZF__SCANNER_H__ -#define __TZF__SCANNER_H__ +#ifndef __TBF__SCANNER_H__ +#define __TBF__SCANNER_H__ #include -void* TBF_Scan (uint8_t* pattern, size_t len, uint8_t* mask = nullptr); +void* TBF_Scan (uint8_t* pattern, size_t len, uint8_t* mask = nullptr); +uintptr_t TBF_GetBaseAddr (void); -#endif /* __TZF__SCANNER_H__ */ \ No newline at end of file +#endif /* __TBF__SCANNER_H__ */ \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 4987ad7..faca1bd 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -51,19 +51,7 @@ struct { } audio; struct { - tbf::ParameterBool* allow_fake_sleep; - tbf::ParameterBool* yield_processor; - tbf::ParameterBool* minimize_latency; - tbf::ParameterInt* speedresetcode_addr; - tbf::ParameterInt* speedresetcode2_addr; - tbf::ParameterInt* speedresetcode3_addr; - tbf::ParameterInt* limiter_branch_addr; - tbf::ParameterBool* disable_limiter; - tbf::ParameterBool* auto_adjust; - tbf::ParameterInt* target; - tbf::ParameterInt* battle_target; - tbf::ParameterBool* battle_adaptive; - tbf::ParameterInt* cutscene_target; + tbf::ParameterBool* replace_limiter; } framerate; struct { @@ -84,6 +72,8 @@ struct { struct { tbf::ParameterBool* remaster; + tbf::ParameterBool* uncompressed; + tbf::ParameterFloat* lod_bias; tbf::ParameterBool* cache; tbf::ParameterBool* dump; tbf::ParameterInt* cache_size; @@ -101,10 +91,6 @@ struct { } keyboard; -struct { - tbf::ParameterBool* fix_priest; -} lua; - struct { struct { tbf::ParameterStringW* texture_set; @@ -225,6 +211,26 @@ TBF_LoadConfig (std::wstring name) L"Texture.System", L"Remaster" ); + textures.uncompressed = + static_cast + (g_ParameterFactory.create_parameter ( + L"Do Not Re-Compress Remastered Textures") + ); + textures.uncompressed->register_to_ini ( + render_ini, + L"Texture.System", + L"UncompressedRemasters" ); + + textures.lod_bias = + static_cast + (g_ParameterFactory.create_parameter ( + L"Texture LOD Bias") + ); + textures.lod_bias->register_to_ini ( + render_ini, + L"Texture.System", + L"LODBias" ); + textures.cache_size = static_cast (g_ParameterFactory.create_parameter ( @@ -277,6 +283,16 @@ TBF_LoadConfig (std::wstring name) L"Shadow.Quality", L"RescaleEnvShadows" ); + framerate.replace_limiter = + static_cast + (g_ParameterFactory.create_parameter ( + L"Replace Namco's Framerate Limiter") + ); + framerate.replace_limiter->register_to_ini ( + render_ini, + L"Framerate.Fix", + L"ReplaceLimiter" ); + input.gamepad.texture_set = static_cast @@ -345,7 +361,11 @@ TBF_LoadConfig (std::wstring name) render.dump_shaders->load (config.render.dump_shaders); + framerate.replace_limiter->load (config.framerate.replace_limiter); + textures.remaster->load (config.textures.remaster); + textures.uncompressed->load (config.textures.uncompressed); + textures.lod_bias->load (config.textures.lod_bias); textures.cache->load (config.textures.cache); textures.dump->load (config.textures.dump); textures.cache_size->load (config.textures.max_cache_in_mib); @@ -365,12 +385,16 @@ TBF_SaveConfig (std::wstring name, bool close_config) audio.compatibility->store (config.audio.compatibility); audio.enable_fix->store (config.audio.enable_fix); + framerate.replace_limiter->store (config.framerate.replace_limiter); + render.dump_shaders->store (config.render.dump_shaders); render.rescale_shadows->store (config.render.shadow_rescale); render.rescale_env_shadows->store (config.render.env_shadow_rescale); textures.remaster->store (config.textures.remaster); + textures.uncompressed->store (config.textures.uncompressed); + textures.lod_bias->store (config.textures.lod_bias); textures.cache->store (config.textures.cache); textures.dump->store (config.textures.dump); textures.cache_size->store (config.textures.max_cache_in_mib); diff --git a/src/dllmain.cpp b/src/dllmain.cpp index 9787096..9f0e7fd 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -35,6 +35,8 @@ #include "command.h" #include "hook.h" +#include "scanner.h" + #pragma comment (lib, "kernel32.lib") typedef HRESULT (__stdcall *SK_UpdateSoftware_pfn) (const wchar_t* wszProduct); @@ -74,15 +76,17 @@ SKPlugIn_Init (HMODULE hModSpecialK) TBF_VER_STR.c_str () ); if (! TBF_LoadConfig ()) { - config.audio.channels = 6; - config.audio.sample_hz = 48000; + config.audio.channels = 6; + config.audio.sample_hz = -1; config.audio.compatibility = false; config.audio.enable_fix = true; config.file_io.capture = false; config.steam.allow_broadcasts = false; - config.lua.fix_priest = true; + + config.framerate.replace_limiter = true; + config.framerate.target = 20; config.render.aspect_ratio = 1.777778f; config.render.fovy = 0.785398f; @@ -123,7 +127,7 @@ SKPlugIn_Init (HMODULE hModSpecialK) //tbf::FileIO::Init (); //tbf::SteamFix::Init (); tbf::RenderFix::Init (); - //tbf::FrameRateFix::Init (); + tbf::FrameRateFix::Init (); //tbf::KeyboardFix::Init (); // Uncomment this when spawning a thread @@ -176,7 +180,7 @@ DllMain (HMODULE hModule, //tbf::FileIO::Shutdown (); //tbf::SteamFix::Shutdown (); tbf::RenderFix::Shutdown (); - //tbf::FrameRateFix::Shutdown (); + tbf::FrameRateFix::Shutdown (); //tbf::KeyboardFix::Shutdown (); TBF_UnInit_MinHook (); diff --git a/src/framerate.cpp b/src/framerate.cpp index 89245b2..4a47e72 100644 --- a/src/framerate.cpp +++ b/src/framerate.cpp @@ -28,270 +28,25 @@ #include "hook.h" #include "scanner.h" -#include "priest.lua.h" - #include "render.h" #include "textures.h" #include -uint32_t TICK_ADDR_BASE = 0x217B464; -// 0x0217B3D4 1.3 - -uint8_t tzf::FrameRateFix::old_speed_reset_code2 [7]; -uint8_t tzf::FrameRateFix::old_limiter_instruction [6]; -int32_t tzf::FrameRateFix::tick_scale = 2; // 30 FPS - -CRITICAL_SECTION tzf::FrameRateFix::alter_speed_cs = { 0 }; - -bool tzf::FrameRateFix::variable_speed_installed = false; -bool tzf::FrameRateFix::fullscreen = false; - -uint32_t tzf::FrameRateFix::target_fps = 30; - -HMODULE tzf::FrameRateFix::bink_dll = 0; -HMODULE tzf::FrameRateFix::kernel32_dll = 0; - -float limiter_tolerance = 0.40f; -int max_latency = 2; -bool wait_for_vblank = true; - -typedef void (WINAPI *Sleep_pfn)(DWORD dwMilliseconds); -Sleep_pfn Sleep_Original = nullptr; - -typedef BOOL(WINAPI *QueryPerformanceCounter_pfn)(_Out_ LARGE_INTEGER *lpPerformanceCount); -QueryPerformanceCounter_pfn QueryPerformanceCounter_Original = nullptr; - -class FramerateLimiter -{ -public: - FramerateLimiter (double target = 60.0) { - init (target); - } - ~FramerateLimiter (void) { - } - - void init (double target) { - ms = 1000.0 / target; - fps = target; - - frames = 0; - - IDirect3DDevice9Ex* d3d9ex = nullptr; - if (tzf::RenderFix::pDevice != nullptr) { - tzf::RenderFix::pDevice->QueryInterface ( - __uuidof (IDirect3DDevice9Ex), - (void **)&d3d9ex ); - } - - QueryPerformanceFrequency (&freq); - - // Align the start to VBlank for minimum input latency - if (d3d9ex != nullptr) { - d3d9ex->SetMaximumFrameLatency (1); - d3d9ex->WaitForVBlank (0); - d3d9ex->SetMaximumFrameLatency (max_latency); - d3d9ex->Release (); - } - - QueryPerformanceCounter_Original (&start); - - next.QuadPart = 0ULL; - time.QuadPart = 0ULL; - last.QuadPart = 0ULL; - - last.QuadPart = start.QuadPart - (ms / 1000.0) * freq.QuadPart; - next.QuadPart = start.QuadPart + (ms / 1000.0) * freq.QuadPart; - } - - void wait (void) { - static bool restart = false; - - frames++; - - QueryPerformanceCounter_Original (&time); - - if ((double)(time.QuadPart - next.QuadPart) / (double)freq.QuadPart / (ms / 1000.0) > (limiter_tolerance * fps)) { - //dll_log->Log ( L" * Frame ran long (%3.01fx expected) - restarting" - //L" limiter...", - //(double)(time.QuadPart - next.QuadPart) / (double)freq.QuadPart / (ms / 1000.0) / fps ); - restart = true; - } - - if (restart) { - frames = 0; - start.QuadPart = time.QuadPart + (ms / 1000.0) * (double)freq.QuadPart; - restart = false; - } - - next.QuadPart = (start.QuadPart + (double)frames * (ms / 1000.0) * (double)freq.QuadPart); - - if (next.QuadPart > 0ULL) { - // If available (Windows 7+), wait on the swapchain - IDirect3DDevice9Ex* d3d9ex = nullptr; - if (tzf::RenderFix::pDevice != nullptr) { - tzf::RenderFix::pDevice->QueryInterface ( - __uuidof (IDirect3DDevice9Ex), - (void **)&d3d9ex ); - } - - while (time.QuadPart < next.QuadPart) { - if (wait_for_vblank && (double)(next.QuadPart - time.QuadPart) > (0.0166667 * (double)freq.QuadPart)) { - if (d3d9ex != nullptr) { - d3d9ex->WaitForVBlank (0); - } - } - - if (GetForegroundWindow () != tzf::RenderFix::hWndDevice && - tzf::FrameRateFix::fullscreen) { - //dll_log->Log (L"[FrameLimit] # Restarting framerate limiter; fullscreen Alt+Tab..."); - restart = true; - break; - } - - QueryPerformanceCounter_Original (&time); - } - - if (d3d9ex != nullptr) - d3d9ex->Release (); - } - - else { - dll_log->Log (L"[FrameLimit] Lost time"); - start.QuadPart += -next.QuadPart; - } - - last.QuadPart = time.QuadPart; - } - - void change_limit (double target) { - init (target); - } - -private: - double ms, fps; - - LARGE_INTEGER start, last, next, time, freq; - - uint32_t frames; -} *limiter = nullptr; - - -typedef D3DPRESENT_PARAMETERS* (__stdcall *SK_SetPresentParamsD3D9_pfn) - (IDirect3DDevice9* device, - D3DPRESENT_PARAMETERS* pparams); -SK_SetPresentParamsD3D9_pfn SK_SetPresentParamsD3D9_Original = nullptr; - -COM_DECLSPEC_NOTHROW -D3DPRESENT_PARAMETERS* -__stdcall -SK_SetPresentParamsD3D9_Detour (IDirect3DDevice9* device, - D3DPRESENT_PARAMETERS* pparams) -{ - D3DPRESENT_PARAMETERS present_params; - - // - // TODO: Figure out what the hell is doing this when RTSS is allowed to use - // custom D3D libs. 1x1@0Hz is obviously NOT for rendering! - // - if ( pparams->BackBufferWidth == 1 && - pparams->BackBufferHeight == 1 && - pparams->FullScreen_RefreshRateInHz == 0 ) { - dll_log->Log (L"[ D3D9 ] * Fake D3D9Ex Device Detected... Ignoring!"); - return SK_SetPresentParamsD3D9_Original (device, pparams); - } - - tzf::RenderFix::pDevice = device; - tzf::RenderFix::pPostProcessSurface = nullptr; - - if (pparams != nullptr) { - memcpy (&present_params, pparams, sizeof D3DPRESENT_PARAMETERS); - - if (device != nullptr) { - dll_log->Log ( L"[ D3D9 ] %% Caught D3D9 Swapchain :: Fullscreen=%s " - L" (%lux%lu@%lu Hz) " - L" [Device Window: 0x%04X]", - pparams->Windowed ? L"False" : - L"True", - pparams->BackBufferWidth, - pparams->BackBufferHeight, - pparams->FullScreen_RefreshRateInHz, - pparams->hDeviceWindow ); - } - - tzf::RenderFix::hWndDevice = pparams->hDeviceWindow; - - tzf::RenderFix::width = present_params.BackBufferWidth; - tzf::RenderFix::height = present_params.BackBufferHeight; - tzf::FrameRateFix::fullscreen = (! pparams->Windowed); - - // Change the Aspect Ratio - char szAspectCommand [64]; - sprintf (szAspectCommand, "AspectRatio %f", (float)tzf::RenderFix::width / (float)tzf::RenderFix::height); - - SK_GetCommandProcessor ()->ProcessCommandLine (szAspectCommand); - } - - return SK_SetPresentParamsD3D9_Original (device, pparams); -} - -bool render_sleep0 = false; -LARGE_INTEGER last_perfCount = { 0 }; - -void -WINAPI -Sleep_Detour (DWORD dwMilliseconds) -{ - if ((! config.framerate.disable_limiter) && GetCurrentThreadId () == tzf::RenderFix::dwRenderThreadID) { - if (dwMilliseconds == 0) - render_sleep0 = true; - else { - render_sleep0 = false; - } - } - - if (config.framerate.yield_processor && dwMilliseconds == 0) - YieldProcessor (); - - if (dwMilliseconds != 0 || config.framerate.allow_fake_sleep) { - Sleep_Original (dwMilliseconds); - } -} - -BOOL -WINAPI -QueryPerformanceCounter_Detour (_Out_ LARGE_INTEGER *lpPerformanceCount) -{ - BOOL ret = QueryPerformanceCounter_Original (lpPerformanceCount); - - DWORD dwThreadId = GetCurrentThreadId (); - - // - // Handle threads that aren't render-related NORMALLY as well as the render - // thread when it DID NOT just voluntarily relinquish its scheduling - // timeslice - // - if (dwThreadId != tzf::RenderFix::dwRenderThreadID || (! render_sleep0) || tzf::RenderFix::bink) { - if (dwThreadId == tzf::RenderFix::dwRenderThreadID) - memcpy (&last_perfCount, lpPerformanceCount, sizeof (LARGE_INTEGER)); - - return ret; - } - - // - // At this point, we're fixing up the thread that throttles the swapchain. - // - render_sleep0 = false; +// +// @TODO: Develop a heuristic to scan for this memory address; +// hardcoding it is going to break stuff :) +// +uintptr_t TICK_ADDR_BASE = 0xB1B074; - LARGE_INTEGER freq; - QueryPerformanceFrequency (&freq); +int32_t tbf::FrameRateFix::tick_scale = INT32_MAX; // 0 FPS - // Mess with the numbers slightly to prevent scheduling from wreaking havoc - lpPerformanceCount->QuadPart += (double)freq.QuadPart * ((double)tzf::FrameRateFix::target_fps / 1000.0); +CRITICAL_SECTION tbf::FrameRateFix::alter_speed_cs = { 0 }; - memcpy (&last_perfCount, lpPerformanceCount, sizeof (LARGE_INTEGER)); +bool tbf::FrameRateFix::variable_speed_installed = false; +uint32_t tbf::FrameRateFix::target_fps = 0; - return ret; -} +HMODULE tbf::FrameRateFix::bink_dll = 0; +HMODULE tbf::FrameRateFix::kernel32_dll = 0; typedef void* (__stdcall *BinkOpen_pfn)(const char* filename, DWORD unknown0); BinkOpen_pfn BinkOpen_Original = nullptr; @@ -325,8 +80,8 @@ BinkOpen_Detour ( const char* filename, if (bink_ret != nullptr) { dll_log->Log (L"[FrameLimit] * Disabling TargetFPS -- Bink Video Opened"); - tzf::RenderFix::bink = true; - tzf::FrameRateFix::Begin30FPSEvent (); + tbf::RenderFix::bink = true; + //tbf::FrameRateFix::Begin30FPSEvent (); } return bink_ret; @@ -343,22 +98,18 @@ BinkClose_Detour (DWORD unknown) dll_log->Log (L"[FrameLimit] * Restoring TargetFPS -- Bink Video Closed"); - tzf::RenderFix::bink = false; - tzf::FrameRateFix::End30FPSEvent (); + tbf::RenderFix::bink = false; + //tbf::FrameRateFix::End30FPSEvent (); } -LPVOID pfnQueryPerformanceCounter = nullptr; -LPVOID pfnSleep = nullptr; -LPVOID pfnSK_SetPresentParamsD3D9 = nullptr; - // Hook these to properly synch audio subtitles during FMVs LPVOID pfnBinkOpen = nullptr; LPVOID pfnBinkClose = nullptr; void -TZF_FlushInstructionCache ( LPCVOID base_addr, +TBF_FlushInstructionCache ( LPCVOID base_addr, size_t code_size ) { FlushInstructionCache ( GetCurrentProcess (), @@ -367,11 +118,11 @@ TZF_FlushInstructionCache ( LPCVOID base_addr, } void -TZF_InjectByteCode ( LPVOID base_addr, - uint8_t* new_code, - size_t code_size, - DWORD permissions, - uint8_t* old_code = nullptr ) +TBF_InjectMachineCode ( LPVOID base_addr, + uint8_t* new_code, + size_t code_size, + DWORD permissions, + uint8_t* old_code = nullptr ) { DWORD dwOld; @@ -384,67 +135,7 @@ TZF_InjectByteCode ( LPVOID base_addr, } VirtualProtect (base_addr, code_size, dwOld, &dwOld); - TZF_FlushInstructionCache (base_addr, code_size); -} - -LPVOID pLuaReturn = nullptr; - -void -__declspec(naked) -TZF_LuaHook (void) -{ - char *name; - size_t *pSz; - char **pBuffer; - - __asm - { - pushad - pushfd - - // save luaL_loadbuffer's stack frame because we need some stuff on it - mov ebx, ebp - - push ebp - mov ebp, esp - sub esp, __LOCAL_SIZE - - // compiler must've optimised away the calling convention here - mov name, eax - - mov eax, ebx - add eax, 0xC - mov pSz, eax - mov eax, ebx - add eax, 0x8 - mov pBuffer, eax - } - -#if 0 - dll_log->Log (L"[ 60 FPS ]Lua script loaded: \"%S\"", name); -#endif - - if (! strcmp (name, "MEP_100_130_010_PF_Script")) { - dll_log->Log (L"[ 60 FPS ] * Replacing priest script..."); - - *pSz = lua_bytecode_priest_size; - *pBuffer = lua_bytecode_priest; - } - - __asm - { - mov esp, ebp - pop ebp - - popfd - popad - - // overwritten instructions from original function - mov ecx, [ebp + 0x8] - mov [esp + 0x4], ecx - - jmp pLuaReturn - } + TBF_FlushInstructionCache (base_addr, code_size); } typedef BOOL (WINAPI *CreateTimerQueueTimer_pfn) @@ -482,521 +173,113 @@ CreateTimerQueueTimer_Override ( } void -tzf::FrameRateFix::Init (void) +tbf::FrameRateFix::Init (void) { - CommandProcessor* comm_proc = CommandProcessor::getInstance (); + //CommandProcessor* comm_proc = CommandProcessor::getInstance (); InitializeCriticalSectionAndSpinCount (&alter_speed_cs, 1000UL); - target_fps = config.framerate.target; + target_fps = 0; + bink_dll = LoadLibrary (L"bink2w64.dll"); - TZF_CreateDLLHook2 ( config.system.injector.c_str (), "SK_SetPresentParamsD3D9", - SK_SetPresentParamsD3D9_Detour, - (LPVOID *)&SK_SetPresentParamsD3D9_Original, - &pfnSK_SetPresentParamsD3D9 ); - - bink_dll = LoadLibrary (L"bink2w32.dll"); - - TZF_CreateDLLHook2 ( L"bink2w32.dll", "_BinkOpen@8", +#if 0 + TBF_CreateDLLHook2 ( L"bink2w64.dll", "_BinkOpen@8", BinkOpen_Detour, (LPVOID *)&BinkOpen_Original, &pfnBinkOpen ); - TZF_CreateDLLHook2 ( L"bink2w32.dll", "_BinkClose@4", + TBF_CreateDLLHook2 ( L"bink2w64.dll", "_BinkClose@4", BinkClose_Detour, (LPVOID *)&BinkClose_Original, &pfnBinkClose ); +#endif - TZF_CreateDLLHook2 ( config.system.injector.c_str (), "QueryPerformanceCounter_Detour", - QueryPerformanceCounter_Detour, - (LPVOID *)&QueryPerformanceCounter_Original, - (LPVOID *)&pfnQueryPerformanceCounter ); - - TZF_CreateDLLHook2 ( L"kernel32.dll", "CreateTimerQueueTimer", + TBF_CreateDLLHook2 ( L"kernel32.dll", "CreateTimerQueueTimer", CreateTimerQueueTimer_Override, (LPVOID *)&CreateTimerQueueTimer_Original ); - TZF_ApplyQueuedHooks (); - - if (true) { - if (*((DWORD *)config.framerate.speedresetcode_addr) != 0x428CB08D) { - uint8_t sig [] = { 0x8D, 0xB0, 0x8C, 0x42, - 0x00, 0x00, 0x8D, 0xBB, - 0x8C, 0x42, 0x00, 0x00, - 0xB9, 0x0B, 0x00, 0x00 }; - uintptr_t addr = (uintptr_t)TZF_Scan (sig, 16); - - if (addr != NULL) { - dll_log->Log (L"[FrameLimit] Scanned SpeedResetCode Address: %06Xh", addr); - config.framerate.speedresetcode_addr = addr; - } - else { - dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find SpeedResetCode memory!"); - } - } - - if (*((DWORD *)config.framerate.speedresetcode3_addr) != 0x02) { - uint8_t sig [] = { 0x0F, 0x95, 0xC0, 0x3A, - 0xC3, 0x74, 0x17, 0xB8, - 0x02, 0x00, 0x00, 0x00 }; - uintptr_t addr = (uintptr_t)TZF_Scan (sig, 12); - - if (addr != NULL && *((DWORD *)((uint8_t *)addr + 8)) == 0x2) { - dll_log->Log (L"[FrameLimit] Scanned SpeedResetCode3 Address: %06Xh", addr + 8); - config.framerate.speedresetcode3_addr = addr + 8; - } - else { - dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find SpeedResetCode3 memory!"); - } - } - - dll_log->LogEx (true, L"[FrameLimit] * Installing variable rate simulation... "); - - DWORD dwOld; - - // - // original code: - // - // >> lea esi, [eax+0000428C] - // >> lea edi, [ebx+0000428C] - // >> mov ecx, 11 - // rep movsd - // - // we want to skip the first two dwords - // - VirtualProtect((LPVOID)config.framerate.speedresetcode_addr, 17, PAGE_EXECUTE_READWRITE, &dwOld); - *((DWORD *)(config.framerate.speedresetcode_addr + 2)) += 8; - *((DWORD *)(config.framerate.speedresetcode_addr + 8)) += 8; - *((DWORD *)(config.framerate.speedresetcode_addr + 13)) -= 2; - VirtualProtect((LPVOID)config.framerate.speedresetcode_addr, 17, dwOld, &dwOld); - - TZF_FlushInstructionCache ((LPCVOID)config.framerate.speedresetcode_addr, 17); - - uint8_t mask [] = { 0xff, 0xff, 0xff, // cmp [ebx+28h], eax - 0, 0, // jz short <...> - 0xff, 0xff, 0xff, // cmp eax, 2 - 0, 0, // jl short <...> - 0xff, 0, 0, 0, 0, // mov , eax - 0xff, 0, 0, 0, 0, // mov , eax - 0xff, 0xff, 0xff // mov [ebx+28h], eax - }; - - uint8_t sig [] = { 0x39, 0x43, 0x28, // cmp [ebx+28h], eax - 0x74, 0x12, // jz short <...> - 0x83, 0xF8, 0x02, // cmp eax, 2 - 0x7C, 0x0D, // jl short <...> - 0xA3, 0x64, 0xB4, 0x17, 0x02, // mov , eax - 0xA3, 0x68, 0xB4, 0x17, 0x02, // mov , eax - 0x89, 0x43, 0x28 // mov [ebx+28h], eax - }; - - if (*((DWORD *)config.framerate.speedresetcode2_addr) != 0x0F8831274) { - uintptr_t addr = (uintptr_t)TZF_Scan (sig, 23, mask); - - if (addr != NULL) { - config.framerate.speedresetcode2_addr = addr + 3; - - dll_log->Log (L"[FrameLimit] Scanned SpeedResetCode2 Address: %06Xh", addr + 3); - - TICK_ADDR_BASE = *(DWORD *)((uint8_t *)(addr + 11)); - - dll_log->Log (L"[FrameLimit] >> TICK_ADDR_BASE: %06Xh", TICK_ADDR_BASE); - } - else { - dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find SpeedResetCode2 memory!"); - } - } + TBF_ApplyQueuedHooks (); - // - // original code: - // - // ... - // cmp [ebx+28], eax - // >> jz after_set - // >> cmp eax, 2 - // >> jl after_set - // mov 0217B3D4, eax - // mov 0217B3D8, eax - // mov [ebx+28], eax - // after_set: - // ... - // - // we just want this to be 1 always - // - // new code: - // mov eax, 01 - // nop - // nop - // - uint8_t new_code [7] = { 0xB8, 0x01, 0x00, 0x00, 0x00, 0x90, 0x90 }; - - TZF_InjectByteCode ( (LPVOID)config.framerate.speedresetcode2_addr, - new_code, - 7, - PAGE_EXECUTE_READWRITE, - old_speed_reset_code2 ); - - variable_speed_installed = true; - - // mov eax, 02 to mov eax, 01 - char scale [32]; - sprintf ( scale, - "TickScale %li", - CalcTickScale (1000.0f * (1.0f / target_fps)) ); - SK_GetCommandProcessor ()->ProcessCommandLine (scale); - - dll_log->LogEx ( false, L"Field=%lu FPS, Battle=%lu FPS (%s), Cutscene=%lu FPS\n", - target_fps, - config.framerate.battle_target, - config.framerate.battle_adaptive ? L"Adaptive" : L"Fixed", - config.framerate.cutscene_target ); - } + if (config.framerate.replace_limiter) { + /* + 6D3610 0x48 0x83 0xec 0x38 ; Namco Limiter + 6D3610 0xc3 0x90 0x90 0x90 ; No Limiter - variable_speed_installed = true; + Tales of Berseria.exe+6D3610 - 48 83 EC 38 - sub rsp,38 { 56 } - if (config.framerate.disable_limiter) { - // Replace the original jump (jb) with an unconditional jump (jmp) - uint8_t new_code [6] = { 0xE9, 0x8B, 0x00, 0x00, 0x00, 0x90 }; + 0x48 0x83 0xec 0x38 0x8b 0x0d -------- 0x85 0xc9 + */ - if (*(DWORD *)config.framerate.limiter_branch_addr != 0x8A820F) { - uint8_t sig [] = { 0x53, // push ebx - 0x56, // push esi - 0x57, // push edi - 0x0F, 0x82, 0x8A, 0x0, 0x0, 0x0 // jb - }; - uintptr_t addr = (uintptr_t)TZF_Scan (sig, 9); + uint8_t sig [] = { 0x48, 0x83, 0xec, 0x38, + 0x8b, 0x0d, 0xff, 0xff, 0xff, 0xff, + 0x85, 0xc9 }; + uint8_t mask [] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff }; - if (addr != NULL) { - config.framerate.limiter_branch_addr = addr + 3; + void* limiter_addr = + TBF_Scan (sig, sizeof (sig), mask); - dll_log->Log (L"[FrameLimit] Scanned Limiter Branch Address: %06Xh", addr + 3); - } - else { - dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find LimiterBranchAddr memory!"); - } + if (limiter_addr != nullptr) { + dll_log->Log ( L"[FrameLimit] Scanned Namco's Framerate Limit Bug Address: %ph", + limiter_addr ); + } else { + dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find Framerate Limiter code!"); } - TZF_InjectByteCode ( (LPVOID)config.framerate.limiter_branch_addr, - new_code, - 6, - PAGE_EXECUTE_READWRITE ); - } - - if (config.lua.fix_priest) { - uint8_t sig[14] = { 0x8B, 0x4D, 0x08, // mov ecx, [ebp+08] - 0x89, 0x4C, 0x24, 0x04, // mov [esp+04], ecx - 0x8B, 0x4D, 0x0C, // mov ecx, [ebp+0C] - 0x89, 0x4C, 0x24, 0x08 // mov [esp+08], ecx - }; - uint8_t new_code[7] = { 0xE9, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 }; + if (limiter_addr != nullptr) { + //dll_log->LogEx (true, L"[FrameLimit] * Installing variable rate simulation... "); - void *addr = TZF_Scan (sig, 14); + uint8_t disable_inst [] = { 0xc3, 0x90, 0x90, 0x90 }; - if (addr != NULL) { - dll_log->Log (L"[ 60 FPS ] Scanned Lua Loader Address: %06Xh", addr); + TBF_InjectMachineCode ( limiter_addr, + disable_inst, + sizeof (disable_inst), + PAGE_EXECUTE_READWRITE ); - DWORD hookOffset = (PtrToUlong (&TZF_LuaHook) - (uintptr_t)addr - 5); - memcpy (new_code + 1, &hookOffset, 4); - TZF_InjectByteCode (addr, new_code, 7, PAGE_EXECUTE_READWRITE); - pLuaReturn = (LPVOID)((uintptr_t)addr + 7); - } - else { - dll_log->Log (L"[ 60 FPS ] >> ERROR: Unable to find Lua loader address! Priest bug will occur."); + variable_speed_installed = true; } } - - SK_ICommandProcessor* pCmdProc = - SK_GetCommandProcessor (); - - // Special K already has something named this ... get it out of there! - pCmdProc->RemoveVariable ("TargetFPS"); - - pCmdProc->AddVariable ("TargetFPS", TZF_CreateVar (SK_IVariable::Int, (int *)&config.framerate.target)); - pCmdProc->AddVariable ("BattleFPS", TZF_CreateVar (SK_IVariable::Int, (int *)&config.framerate.battle_target)); - pCmdProc->AddVariable ("BattleAdaptive", TZF_CreateVar (SK_IVariable::Boolean, (bool *)&config.framerate.battle_adaptive)); - pCmdProc->AddVariable ("CutsceneFPS", TZF_CreateVar (SK_IVariable::Int, (int *)&config.framerate.cutscene_target)); - - // No matter which technique we use, these things need to be options - pCmdProc->AddVariable ("MinimizeLatency", TZF_CreateVar (SK_IVariable::Boolean, &config.framerate.minimize_latency)); - - // Hook this no matter what, because it lowers the _REPORTED_ CPU usage, - // and some people would object if we suddenly changed this behavior :P - TZF_CreateDLLHook ( config.system.injector.c_str (), "Sleep_Detour", - Sleep_Detour, - (LPVOID *)&Sleep_Original, - (LPVOID *)&pfnSleep ); - TZF_EnableHook (pfnSleep); - - pCmdProc->AddVariable ("AllowFakeSleep", TZF_CreateVar (SK_IVariable::Boolean, &config.framerate.allow_fake_sleep)); - pCmdProc->AddVariable ("YieldProcessor", TZF_CreateVar (SK_IVariable::Boolean, &config.framerate.yield_processor)); - - pCmdProc->AddVariable ("AutoAdjust", TZF_CreateVar (SK_IVariable::Boolean, &config.framerate.auto_adjust)); } void -tzf::FrameRateFix::Shutdown (void) +tbf::FrameRateFix::Shutdown (void) { + DeleteCriticalSection (&alter_speed_cs); + FreeLibrary (kernel32_dll); FreeLibrary (bink_dll); - ////TZF_DisableHook (pfnSK_SetPresentParamsD3D9); + ////TBF_DisableHook (pfnSK_SetPresentParamsD3D9); if (variable_speed_installed) { - DWORD dwOld; - - VirtualProtect ((LPVOID)config.framerate.speedresetcode_addr, 17, PAGE_EXECUTE_READWRITE, &dwOld); - *((DWORD *)(config.framerate.speedresetcode_addr + 2)) -= 8; - *((DWORD *)(config.framerate.speedresetcode_addr + 8)) -= 8; - *((DWORD *)(config.framerate.speedresetcode_addr + 13)) += 2; - VirtualProtect ((LPVOID)config.framerate.speedresetcode_addr, 17, dwOld, &dwOld); - - TZF_FlushInstructionCache ((LPCVOID)config.framerate.speedresetcode_addr, 17); - - TZF_InjectByteCode ( (LPVOID)config.framerate.speedresetcode2_addr, - old_speed_reset_code2, - 7, - PAGE_EXECUTE_READWRITE ); - - SK_GetCommandProcessor ()->ProcessCommandLine ("TickScale 2"); - - variable_speed_installed = false; - } - - ////TZF_DisableHook (pfnSleep); -} - -static int fps_before = 60; -bool forced_30 = false; - -void -tzf::FrameRateFix::Begin30FPSEvent (void) -{ - //EnterCriticalSection (&alter_speed_cs); - - if (variable_speed_installed && (! forced_30)) { - forced_30 = true; - fps_before = target_fps; - SetFPS (30); - } - - //LeaveCriticalSection (&alter_speed_cs); -} - -void -tzf::FrameRateFix::End30FPSEvent (void) -{ - //EnterCriticalSection (&alter_speed_cs); - - if (variable_speed_installed && (forced_30)) { - forced_30 = false; - SetFPS (fps_before); - } - - //LeaveCriticalSection (&alter_speed_cs); -} - -void -tzf::FrameRateFix::SetFPS (int fps) -{ - //EnterCriticalSection (&alter_speed_cs); - - if (variable_speed_installed && (target_fps != fps)) { - target_fps = fps; - char szRescale [32]; - sprintf (szRescale, "TickScale %li", CalcTickScale (1000.0f * (1.0f / fps))); - SK_GetCommandProcessor ()->ProcessCommandLine (szRescale); - } - - //LeaveCriticalSection (&alter_speed_cs); -} - - - - -bool use_accumulator = false; - -tzf::FrameRateFix::CommandProcessor* tzf::FrameRateFix::CommandProcessor::pCommProc; - -tzf::FrameRateFix::CommandProcessor::CommandProcessor (void) -{ - tick_scale_ = TZF_CreateVar (SK_IVariable::Int, &tick_scale, this); - - SK_ICommandProcessor* pCmdProc = - SK_GetCommandProcessor (); - - pCmdProc->AddVariable ("TickScale", tick_scale_); - - pCmdProc->AddVariable ("UseAccumulator", TZF_CreateVar (SK_IVariable::Boolean, &use_accumulator)); - pCmdProc->AddVariable ("MaxFrameLatency", TZF_CreateVar (SK_IVariable::Int, &max_latency)); - pCmdProc->AddVariable ("WaitForVBLANK", TZF_CreateVar (SK_IVariable::Boolean, &wait_for_vblank)); - pCmdProc->AddVariable ("LimiterTolerance", TZF_CreateVar (SK_IVariable::Float, &limiter_tolerance)); -} - -bool -tzf::FrameRateFix::CommandProcessor::OnVarChange (SK_IVariable* var, void* val) -{ - DWORD dwOld; - - if (var == tick_scale_) { - DWORD original0 = *((DWORD *)(TICK_ADDR_BASE )); - DWORD original1 = *((DWORD *)(TICK_ADDR_BASE + 4)); - - if (val != nullptr) { - VirtualProtect ((LPVOID)TICK_ADDR_BASE, 8, PAGE_READWRITE, &dwOld); - - if (variable_speed_installed) { - // Battle Tickrate - *(DWORD *)(TICK_ADDR_BASE) = *(DWORD *)val; - } - - if (variable_speed_installed) { - // World Tickrate - *(DWORD *)(TICK_ADDR_BASE + 4) = *(DWORD *)val; - } - *(DWORD *)val = *(DWORD *)(TICK_ADDR_BASE + 4); - - VirtualProtect ((LPVOID)TICK_ADDR_BASE, 8, dwOld, &dwOld); - - if (variable_speed_installed) { - // mov eax, 02 to mov eax, - VirtualProtect ((LPVOID)config.framerate.speedresetcode3_addr, 4, PAGE_EXECUTE_READWRITE, &dwOld); - *(DWORD *)config.framerate.speedresetcode3_addr = *(DWORD *)val; - VirtualProtect ((LPVOID)config.framerate.speedresetcode3_addr, 4, dwOld, &dwOld); - - uint8_t new_code [7] = { 0xB8, (uint8_t)*(DWORD *)val, 0x00, 0x00, 0x00, 0x90, 0x90 }; - - TZF_InjectByteCode ( (LPVOID)config.framerate.speedresetcode2_addr, - new_code, - 7, - PAGE_EXECUTE_READWRITE, - old_speed_reset_code2 ); - } - //InterlockedExchange ((DWORD *)val, *(DWORD *)config.framerate.speedresetcode3_addr); - - tick_scale = *(int32_t *)val; - } } - return true; -} - - - -long -tzf::FrameRateFix::CalcTickScale (double elapsed_ms) -{ - const double tick_ms = (1.0 / 60.0) * 1000.0; - const double inv_rate = 1.0 / target_fps; - - long scale = min (max (elapsed_ms / tick_ms, 1), 7); - - if (scale > 6) - scale = max (inv_rate / (1.0 / 60.0), 1); - - return scale; + ////TBF_DisableHook (pfnSleep); } - +// +// Called at the end of every frame to make sure the mod's replacement framerate limiter +// is following user preferences. +// void -tzf::FrameRateFix::RenderTick (void) +tbf::FrameRateFix::RenderTick (void) { - if (! forced_30) { - //if (config.framerate.cutscene_target != config.framerate.target) - if (game_state.inCutscene ()) - SetFPS (config.framerate.cutscene_target); - - //if (config.framerate.battle_target != config.framerate.target) - else if (game_state.inBattle ()) - SetFPS (config.framerate.battle_target); - - else //if (! (game_state.inBattle () || game_state.inCutscene ())) - SetFPS (config.framerate.target); - } - - static LARGE_INTEGER last_time = { 0 }; - static LARGE_INTEGER freq = { 0 }; - - LARGE_INTEGER time; - - QueryPerformanceFrequency (&freq); - - static uint32_t last_limit = target_fps; - - if (limiter == nullptr) { - limiter = new FramerateLimiter (); - last_limit = 0; - } - - if (last_limit != target_fps) { - limiter->change_limit (target_fps); - - last_limit = target_fps; - } - - // Skip the limiter while loading, it needlessly - // prolongs loading screens otherwise. - if (! game_state.isLoading ()) - limiter->wait (); - - QueryPerformanceCounter_Original (&time); - - - if (forced_30) { - last_time.QuadPart = time.QuadPart; - return; - } - - - double dt = ((double)(time.QuadPart - last_time.QuadPart) / (double)freq.QuadPart) / (1.0 / 60.0); - - -#ifdef ACCUMULATOR - static double accum = 0.0; - - if (use_accumulator) { - accum += dt - floor (dt); - - time.QuadPart += - (dt - floor (dt)) * (1.0 / 60.0) * freq.QuadPart; - - dt -= (dt - floor (dt)); - - if (accum >= 1.0) { - time.QuadPart -= - (accum - (accum - floor (accum))) * (1.0 / 60.0) * freq.QuadPart; - dt += accum - (accum - floor (accum)); - accum -= accum - (accum - floor (accum)); - } - } else { - accum = 0.0; + uint32_t* pTickScale = + (uint32_t *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); + + if (*pTickScale != tick_scale) { + dll_log->Log ( L"[FrameLimit] [@] Framerate limit changed from " + L"%04.1f FPS to %04.1f FPS...", + 60.0f / (float)tick_scale, + 60.0f / (float)*pTickScale ); + + tick_scale = *pTickScale; + target_fps = 60 / max (0, tick_scale); + + SK_GetCommandProcessor ()->ProcessCommandFormatted ( + "TargetFPS %f", + 60.0f / (float)tick_scale + ); } -#endif - - long scale = CalcTickScale (dt * (1.0 / 60.0) * 1000.0); - - static bool last_frame_battle = false; - - if (scale != tick_scale) { - if (config.framerate.auto_adjust || (config.framerate.battle_adaptive && game_state.inBattle ())) { - if (config.framerate.battle_adaptive && game_state.inBattle ()) { - last_frame_battle = true; - -#if 0 - dll_log->Log ( L"[FrameLimit] ** Adjusting TickScale because of battle framerate change " - L"(Expected: ~%4.2f ms, Got: %4.2f ms)", - last_scale * 16.666667f, dt * (1.0 / 60.0) * 1000.0 ); -#endif - } - - SK_GetCommandProcessor ()->ProcessCommandFormatted ("TickScale %li", scale); - } - } - - if (last_frame_battle && (! game_state.inBattle ())) - target_fps = 1; // Reset FPS and TickScale on the next frame. - - if (! game_state.inBattle ()) - last_frame_battle = false; - - last_time.QuadPart = time.QuadPart; -} +} \ No newline at end of file diff --git a/src/log.cpp b/src/log.cpp index ef270ad..721ec8a 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -24,7 +24,7 @@ #include #include "log.h" -iSK_Logger* dll_log; +iSK_Logger* dll_log = nullptr; iSK_Logger* TBF_CreateLog (const wchar_t* const wszName) diff --git a/src/parameter.cpp b/src/parameter.cpp index 5a66e3b..c578f61 100644 --- a/src/parameter.cpp +++ b/src/parameter.cpp @@ -142,10 +142,17 @@ tbf::ParameterInt64::load (int64_t& ref) std::wstring tbf::ParameterBool::get_value_str (void) { - if (value == true) - return L"true"; - - return L"false"; + switch (type) { + case ZeroNonZero: + return value ? L"1" : L"0"; + case YesNo: + return value ? L"Yes" : L"No"; + case OnOff: + return value ? L"On" : L"Off"; + case TrueFalse: + default: + return value ? L"True" : L"False"; + } } bool @@ -164,19 +171,57 @@ tbf::ParameterBool::set_value (bool val) void tbf::ParameterBool::set_value_str (std::wstring str) { - if (str.length () == 1 && - str [0] == L'1') - value = true; + size_t len = str.length (); + + type = TrueFalse; + + switch (len) + { + case 1: + type = ZeroNonZero; - else if (str.length () == 4 && - towlower (str [0]) == L't' && - towlower (str [1]) == L'r' && - towlower (str [2]) == L'u' && - towlower (str [3]) == L'e') - value = true; + if (str [0] == L'1') + value = true; + break; + + case 2: + if ( towlower (str [0]) == L'o' && + towlower (str [1]) == L'n' ) { + type = OnOff; + value = true; + } else if ( towlower (str [0]) == L'n' && + towlower (str [1]) == L'o' ) { + type = YesNo; + value = false; + } + break; - else - value = false; + case 3: + if ( towlower (str [0]) == L'y' && + towlower (str [1]) == L'e' && + towlower (str [2]) == L's' ) { + type = YesNo; + value = true; + } else if ( towlower (str [0]) == L'o' && + towlower (str [1]) == L'f' && + towlower (str [2]) == L'f' ) { + type = OnOff; + value = false; + } + break; + + case 4: + if ( towlower (str [0]) == L't' && + towlower (str [1]) == L'r' && + towlower (str [2]) == L'u' && + towlower (str [3]) == L'e' ) + value = true; + break; + + default: + value = false; + break; + } } diff --git a/src/render.cpp b/src/render.cpp index 28dae20..4d17c69 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -138,7 +138,7 @@ D3D9SetSamplerState_Detour (IDirect3DDevice9* This, Type == D3DSAMP_MIPMAPLODBIAS) { //dll_log->Log (L" [!] IDirect3DDevice9::SetSamplerState (...)"); - if (Type < 8) { + if (Type <= 8) { //dll_log->Log (L" %s Filter: %x", Type == D3DSAMP_MIPFILTER ? L"Mip" : Type == D3DSAMP_MINFILTER ? L"Min" : L"Mag", Value); if (Type == D3DSAMP_MIPFILTER && Value != D3DTEXF_NONE) { Value = D3DTEXF_LINEAR; @@ -151,11 +151,11 @@ D3D9SetSamplerState_Detour (IDirect3DDevice9* This, // Clamp [0, oo) if (Type == D3DSAMP_MIPMAPLODBIAS) { - float fMax = - max (0.0f, *(float *)&Value); + float fMax = config.textures.lod_bias; + //float fMax = + //max (0.0f, *reinterpret_cast (&Value)); - *(DWORD *)&Value = - *(DWORD *)&fMax; + Value = *reinterpret_cast (&fMax); } } } @@ -659,6 +659,11 @@ D3D9EndFrame_Post (HRESULT hr, IUnknown* device) hr = SK_EndBufferSwap (hr, device); + if ( config.framerate.replace_limiter && + tbf::FrameRateFix::variable_speed_installed ) { + tbf::FrameRateFix::RenderTick (); + } + //if (config.framerate.minimize_latency) //tbf::FrameRateFix::RenderTick (); @@ -1780,22 +1785,30 @@ tbf::RenderFix::CommandProcessor::CommandProcessor (void) SK_IVariable* aspect_correct_vids = TBF_CreateVar (SK_IVariable::Boolean, &config.render.blackbar_videos); SK_IVariable* aspect_correction = TBF_CreateVar (SK_IVariable::Boolean, &config.render.aspect_correction); + SK_IVariable* postproc_ratio = TBF_CreateVar (SK_IVariable::Float, &config.render.postproc_ratio); + SK_IVariable* clear_blackbars = TBF_CreateVar (SK_IVariable::Boolean, &config.render.clear_blackbars); + SK_IVariable* remaster_textures = TBF_CreateVar (SK_IVariable::Boolean, &config.textures.remaster); + SK_IVariable* lod_bias = TBF_CreateVar (SK_IVariable::Float, &config.textures.lod_bias); + SK_IVariable* uncompressed = TBF_CreateVar (SK_IVariable::Boolean, &config.textures.uncompressed); + SK_IVariable* rescale_shadows = TBF_CreateVar (SK_IVariable::Int, &config.render.shadow_rescale); SK_IVariable* rescale_env_shadows = TBF_CreateVar (SK_IVariable::Int, &config.render.env_shadow_rescale); - SK_IVariable* postproc_ratio = TBF_CreateVar (SK_IVariable::Float, &config.render.postproc_ratio); - SK_IVariable* clear_blackbars = TBF_CreateVar (SK_IVariable::Boolean, &config.render.clear_blackbars); //command.AddVariable ("AspectRatio", aspect_ratio_); //command.AddVariable ("FOVY", fovy_); - command.AddVariable ("AspectCorrectVideos", aspect_correct_vids); - command.AddVariable ("AspectCorrection", aspect_correction); - command.AddVariable ("RemasterTextures", remaster_textures); - command.AddVariable ("RescaleShadows", rescale_shadows); - command.AddVariable ("RescaleEnvShadows", rescale_env_shadows); - command.AddVariable ("PostProcessRatio", postproc_ratio); - command.AddVariable ("ClearBlackbars", clear_blackbars); + command.AddVariable ("Textures.Remaster", remaster_textures); + command.AddVariable ("Textures.LODBias", lod_bias); + command.AddVariable ("Textures.Uncompressed", uncompressed); + + command.AddVariable ("Shadows.Rescale", rescale_shadows); + command.AddVariable ("Shadows.RescaleEnv", rescale_env_shadows); + + command.AddVariable ("AspectCorrectVideos", aspect_correct_vids); + command.AddVariable ("AspectCorrection", aspect_correction); + command.AddVariable ("PostProcessRatio", postproc_ratio); + command.AddVariable ("ClearBlackbars", clear_blackbars); command.AddVariable ("TestVS", TBF_CreateVar (SK_IVariable::Int, &TEST_VS)); diff --git a/src/scanner.cpp b/src/scanner.cpp index a2511cd..1df5679 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -24,6 +24,12 @@ #include +uintptr_t +TBF_GetBaseAddr (void) +{ + return (uintptr_t)GetModuleHandle (nullptr); +} + void* TBF_Scan (uint8_t* pattern, size_t len, uint8_t* mask) { diff --git a/src/textures.cpp b/src/textures.cpp index efdf6f1..c399c6f 100644 --- a/src/textures.cpp +++ b/src/textures.cpp @@ -59,31 +59,28 @@ typedef HRESULT (STDMETHODCALLTYPE *SetRenderState_pfn) static D3DXSaveTextureToFile_pfn D3DXSaveTextureToFile = nullptr; -static D3DXCreateTextureFromFileInMemoryEx_pfn D3DXCreateTextureFromFileInMemoryEx_Original = nullptr; +static D3DXCreateTextureFromFileInMemoryEx_pfn D3DXCreateTextureFromFileInMemoryEx = nullptr; -static BeginScene_pfn D3D9BeginScene_Original = nullptr; -static EndScene_pfn D3D9EndScene_Original = nullptr; - SetRenderState_pfn D3D9SetRenderState_Original = nullptr; +static BeginScene_pfn D3D9BeginScene = nullptr; +static EndScene_pfn D3D9EndScene = nullptr; + SetRenderState_pfn D3D9SetRenderState = nullptr; -static StretchRect_pfn D3D9StretchRect_Original = nullptr; -static CreateTexture_pfn D3D9CreateTexture_Original = nullptr; -static CreateRenderTarget_pfn D3D9CreateRenderTarget_Original = nullptr; -static CreateDepthStencilSurface_pfn D3D9CreateDepthStencilSurface_Original = nullptr; +static StretchRect_pfn D3D9StretchRect = nullptr; +static CreateTexture_pfn D3D9CreateTexture = nullptr; +static CreateRenderTarget_pfn D3D9CreateRenderTarget = nullptr; +static CreateDepthStencilSurface_pfn D3D9CreateDepthStencilSurface = nullptr; -static SetTexture_pfn D3D9SetTexture_Original = nullptr; -static SetRenderTarget_pfn D3D9SetRenderTarget_Original = nullptr; -static SetDepthStencilSurface_pfn D3D9SetDepthStencilSurface_Original = nullptr; +static SetTexture_pfn D3D9SetTexture = nullptr; +static SetRenderTarget_pfn D3D9SetRenderTarget = nullptr; +static SetDepthStencilSurface_pfn D3D9SetDepthStencilSurface = nullptr; extern uint32_t TBF_MakeShadowBitShift (uint32_t dim); -typedef BOOL(WINAPI *QueryPerformanceCounter_t)(_Out_ LARGE_INTEGER *lpPerformanceCount); -extern QueryPerformanceCounter_t QueryPerformanceCounter_Original; - tbf::RenderFix::TextureManager tbf::RenderFix::tex_mgr; -iSK_Logger* tex_log; +iSK_Logger* tex_log = nullptr; #include @@ -453,7 +450,7 @@ D3D9StretchRect_Detour ( IDirect3DDevice9 *This, dumping = false; - return D3D9StretchRect_Original (This, pSourceSurface, pSourceRect, + return D3D9StretchRect (This, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); } @@ -470,7 +467,7 @@ D3D9SetRenderState_Detour (IDirect3DDevice9* This, if (This != tbf::RenderFix::pDevice) { dll_log->Log (L"[Render Fix] >> WARNING: SetRenderState came from unknown IDirect3DDevice9! << "); - return D3D9SetRenderState_Original (This, State, Value); + return D3D9SetRenderState (This, State, Value); } #if 0 @@ -481,7 +478,7 @@ D3D9SetRenderState_Detour (IDirect3DDevice9* This, } #endif - return D3D9SetRenderState_Original (This, State, Value); + return D3D9SetRenderState (This, State, Value); } COM_DECLSPEC_NOTHROW @@ -502,7 +499,7 @@ D3D9CreateRenderTarget_Detour (IDirect3DDevice9 *This, Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); - return D3D9CreateRenderTarget_Original (This, Width, Height, Format, + return D3D9CreateRenderTarget (This, Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); } @@ -525,7 +522,7 @@ D3D9CreateDepthStencilSurface_Detour (IDirect3DDevice9 *This, Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); - return D3D9CreateDepthStencilSurface_Original (This, Width, Height, Format, + return D3D9CreateDepthStencilSurface (This, Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); } @@ -569,7 +566,7 @@ D3D9StretchRect_Detour ( IDirect3DDevice9 *This, { dumping = false; - return D3D9StretchRect_Original (This, pSourceSurface, pSourceRect, + return D3D9StretchRect (This, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); } @@ -588,10 +585,10 @@ D3D9SetDepthStencilSurface_Detour ( { // Ignore anything that's not the primary render device. if (This != tbf::RenderFix::pDevice) { - return D3D9SetDepthStencilSurface_Original (This, pNewZStencil); + return D3D9SetDepthStencilSurface (This, pNewZStencil); } - return D3D9SetDepthStencilSurface_Original (This, pNewZStencil); + return D3D9SetDepthStencilSurface (This, pNewZStencil); } @@ -609,7 +606,7 @@ D3D9SetTexture_Detour ( { // Ignore anything that's not the primary render device. if (This != tbf::RenderFix::pDevice) { - return D3D9SetTexture_Original (This, Sampler, pTexture); + return D3D9SetTexture (This, Sampler, pTexture); } //if (tbf::RenderFix::tracer.log) { @@ -627,7 +624,7 @@ D3D9SetTexture_Detour ( textures_used.insert (pSKTex->tex_crc32); - QueryPerformanceCounter/*_Original*/ (&pSKTex->last_used); + QueryPerformanceCounter (&pSKTex->last_used); // // This is how blocking is implemented -- only do it when a texture that needs @@ -656,7 +653,7 @@ D3D9SetTexture_Detour ( else tsf::RenderFix::active_samplers.erase (Sampler); #endif - return D3D9SetTexture_Original (This, Sampler, pTexture); + return D3D9SetTexture (This, Sampler, pTexture); } D3DXSaveSurfaceToFile_pfn D3DXSaveSurfaceToFileW = nullptr; @@ -678,7 +675,7 @@ D3D9CreateTexture_Detour (IDirect3DDevice9 *This, { // Ignore anything that's not the primary render device. if (This != tbf::RenderFix::pDevice) { - return D3D9CreateTexture_Original ( This, Width, Height, + return D3D9CreateTexture ( This, Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle ); } @@ -755,7 +752,7 @@ D3D9CreateTexture_Detour (IDirect3DDevice9 *This, int levels = Levels; HRESULT result = - D3D9CreateTexture_Original (This, Width, Height, levels, Usage, + D3D9CreateTexture (This, Width, Height, levels, Usage, Format, Pool, ppTexture, pSharedHandle); return result; @@ -770,7 +767,7 @@ D3D9BeginScene_Detour (IDirect3DDevice9* This) if (This != tbf::RenderFix::pDevice) { dll_log->Log (L"[Render Fix] >> WARNING: D3D9 BeginScene came from unknown IDirect3DDevice9! << "); - return D3D9BeginScene_Original (This); + return D3D9BeginScene (This); } tbf::RenderFix::draw_state.draws = 0; @@ -781,7 +778,7 @@ D3D9BeginScene_Detour (IDirect3DDevice9* This) D3D9_VIRTUAL_OVERRIDE ( &This, 16, L"IDirect3DDevice9::Reset", D3D9Reset_Detour, - D3D9Reset_Original, + D3D9Reset, Reset_pfn ); D3DXCreateFontW ( This, @@ -795,7 +792,7 @@ sss L"Arial", } #endif - HRESULT result = D3D9BeginScene_Original (This); + HRESULT result = D3D9BeginScene (This); return result; } @@ -808,9 +805,9 @@ D3D9EndScene_Detour (IDirect3DDevice9* This) { // Ignore anything that's not the primary render device. if (This != tbf::RenderFix::pDevice) { - return D3D9EndScene_Original (This); + return D3D9EndScene (This); } - return D3D9EndScene_Original (This); + return D3D9EndScene (This); } #endif @@ -938,14 +935,11 @@ static D3DXCreateTextureFromFile_pfn #define D3DX_SKIP_DDS_MIP_LEVELS(l, f) ((((l) & D3DX_SKIP_DDS_MIP_LEVELS_MASK) \ << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT) | ((f) == D3DX_DEFAULT ? D3DX_FILTER_BOX : (f))) -typedef BOOL(WINAPI *QueryPerformanceCounter_t)(_Out_ LARGE_INTEGER *lpPerformanceCount); -extern QueryPerformanceCounter_t QueryPerformanceCounter_Original; - #define __PTR_SIZE sizeof LPCVOID #define __PAGE_PRIVS PAGE_EXECUTE_READWRITE -#define D3D9_VIRTUAL_OVERRIDE(_Base,_Index,_Name,_Override,_Original,_Type) { \ +#define D3D9_VIRTUAL_OVERRIDE(_Base,_Index,_Name,_Override,_Type) { \ void** vftable = *(void***)*_Base; \ \ if (vftable [_Index] != _Override) { \ @@ -957,10 +951,10 @@ extern QueryPerformanceCounter_t QueryPerformanceCounter_Original; /*L##_Name, vftable [_Index], */\ /*SK_DescribeVirtualProtectFlags (dwProtect)); */\ \ - if (_Original == NULL) \ - _Original = (##_Type)vftable [_Index]; \ + if ( == NULL) \ + = (##_Type)vftable [_Index]; \ \ - /*dll_log->Log (L" + %s: %08Xh", L#_Original, _Original);*/ \ + /*dll_log->Log (L" + %s: %08Xh", L#, );*/ \ \ vftable [_Index] = _Override; \ \ @@ -1489,7 +1483,7 @@ InjectTexture (tbf_tex_load_s* load) load->SrcDataSize, &img_info ); - hr = D3DXCreateTextureFromFileInMemoryEx_Original ( + hr = D3DXCreateTextureFromFileInMemoryEx ( load->pDevice, load->pSrcData, load->SrcDataSize, D3DX_DEFAULT, D3DX_DEFAULT, img_info.MipLevels, @@ -1591,7 +1585,7 @@ TBFix_LoadQueuedTextures (void) tbf_tex_load_s* load = *it; - QueryPerformanceCounter/*_Original*/ (&load->end); + QueryPerformanceCounter (&load->end); if (true) { tex_log->Log ( L"[%s] Finished %s texture %08x (%5.2f MiB in %9.4f ms)", @@ -1623,7 +1617,7 @@ TBFix_LoadQueuedTextures (void) tex_log->Log (L"[ Tex. Mgr ] >> Original texture no longer referenced, discarding new one!"); load->pSrc->Release (); } else { - QueryPerformanceCounter/*_Original*/ (&pSKTex->last_used); + QueryPerformanceCounter (&pSKTex->last_used); pSKTex->pTexOverride = load->pSrc; pSKTex->override_size = load->SrcDataSize; @@ -1706,7 +1700,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( // Injection would recurse slightly and cause impossible to diagnose reference counting problems // with texture caching if we did not check for this! if (inject_thread) { - return D3DXCreateTextureFromFileInMemoryEx_Original ( + return D3DXCreateTextureFromFileInMemoryEx ( pDevice, pSrcData, SrcDataSize, Width, Height, MipLevels, @@ -1734,7 +1728,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( if (freq.QuadPart == 0LL) QueryPerformanceFrequency (&freq); - QueryPerformanceCounter/*_Original*/ (&start); + QueryPerformanceCounter (&start); uint32_t checksum = crc32 (0, pSrcData, SrcDataSize); @@ -1760,7 +1754,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( // Necessary to make D3DX texture write functions work if ( Pool == D3DPOOL_DEFAULT && config.textures.dump && - (! dumped_textures.count (checksum)) && + (! dumped_textures.count (checksum)) && (! injectable_textures.count (checksum)) ) Usage = D3DUSAGE_DYNAMIC; @@ -1775,7 +1769,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( if (true) {//fmt_real == D3DFMT_DXT1 || //fmt_real == D3DFMT_DXT3 || //fmt_real == D3DFMT_DXT5) { - if (/*info.Width >= 128 && info.Height >= 128 && */info.MipLevels == 3) { + if (/*info.Width >= 128 && info.Height >= 128 && */ info.MipLevels > 1 || config.textures.uncompressed) { // Don't resample faces if ( resample_blacklist.count (checksum) == 0 ) resample = true; @@ -1844,9 +1838,9 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( //tex_log->Log (L"D3DXCreateTextureFromFileInMemoryEx (... MipLevels=%lu ...)", MipLevels); hr = - D3DXCreateTextureFromFileInMemoryEx_Original ( pDevice, + D3DXCreateTextureFromFileInMemoryEx ( pDevice, pSrcData, SrcDataSize, - Width, Height, will_replace ? 1 : MipLevels, + Width, Height, MipLevels, Usage, Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, @@ -1968,7 +1962,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( // else if (load_op != nullptr && load_op->type == tsf_tex_load_s::Immediate) { QueryPerformanceFrequency (&load_op->freq); - QueryPerformanceCounter/*_Original*/ (&load_op->start); + QueryPerformanceCounter (&load_op->start); EnterCriticalSection (&cs_tex_inject); inject_tids.insert (GetCurrentThreadId ()); @@ -1982,7 +1976,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( inject_tids.erase (GetCurrentThreadId ()); LeaveCriticalSection (&cs_tex_inject); - QueryPerformanceCounter/*_Original*/ (&load_op->end); + QueryPerformanceCounter (&load_op->end); if (SUCCEEDED (hr)) { tex_log->Log ( L"[Inject Tex] Finished synchronous texture %08x (%5.2f MiB in %9.4f ms)", @@ -2036,7 +2030,7 @@ D3DXCreateTextureFromFileInMemoryEx_Detour ( load_op = nullptr; } - QueryPerformanceCounter/*_Original*/ (&end); + QueryPerformanceCounter (&end); if (SUCCEEDED (hr)) { if (config.textures.cache && checksum != 0x00) { @@ -2206,7 +2200,7 @@ D3D9SetRenderTarget_Detour ( // Ignore anything that's not the primary render device. if (This != tbf::RenderFix::pDevice) { - return D3D9SetRenderTarget_Original (This, RenderTargetIndex, pRenderTarget); + return D3D9SetRenderTarget (This, RenderTargetIndex, pRenderTarget); } //if (tsf::RenderFix::tracer.log) { @@ -2249,7 +2243,7 @@ D3D9SetRenderTarget_Detour ( #endif //} - return D3D9SetRenderTarget_Original (This, RenderTargetIndex, pRenderTarget); + return D3D9SetRenderTarget (This, RenderTargetIndex, pRenderTarget); } void @@ -2548,47 +2542,47 @@ tbf::RenderFix::TextureManager::Init (void) TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9SetRenderState_Override", D3D9SetRenderState_Detour, - (LPVOID*)&D3D9SetRenderState_Original ); + (LPVOID*)&D3D9SetRenderState ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9BeginScene_Override", D3D9BeginScene_Detour, - (LPVOID*)&D3D9BeginScene_Original ); + (LPVOID*)&D3D9BeginScene ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9StretchRect_Override", D3D9StretchRect_Detour, - (LPVOID*)&D3D9StretchRect_Original ); + (LPVOID*)&D3D9StretchRect ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9CreateDepthStencilSurface_Override", D3D9CreateDepthStencilSurface_Detour, - (LPVOID*)&D3D9CreateDepthStencilSurface_Original ); + (LPVOID*)&D3D9CreateDepthStencilSurface ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9CreateTexture_Override", D3D9CreateTexture_Detour, - (LPVOID*)&D3D9CreateTexture_Original ); + (LPVOID*)&D3D9CreateTexture ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9SetTexture_Override", D3D9SetTexture_Detour, - (LPVOID*)&D3D9SetTexture_Original ); + (LPVOID*)&D3D9SetTexture ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9SetRenderTarget_Override", D3D9SetRenderTarget_Detour, - (LPVOID*)&D3D9SetRenderTarget_Original ); + (LPVOID*)&D3D9SetRenderTarget ); TBF_CreateDLLHook ( config.system.injector.c_str (), "D3D9SetDepthStencilSurface_Override", D3D9SetDepthStencilSurface_Detour, - (LPVOID*)&D3D9SetDepthStencilSurface_Original ); + (LPVOID*)&D3D9SetDepthStencilSurface ); TBF_CreateDLLHook ( L"D3DX9_43.DLL", "D3DXCreateTextureFromFileInMemoryEx", D3DXCreateTextureFromFileInMemoryEx_Detour, - (LPVOID *)&D3DXCreateTextureFromFileInMemoryEx_Original ); + (LPVOID *)&D3DXCreateTextureFromFileInMemoryEx ); D3DXSaveTextureToFile = (D3DXSaveTextureToFile_pfn) @@ -2616,19 +2610,19 @@ tbf::RenderFix::TextureManager::Init (void) "D3DXGetImageInfoFromFileW" ); // We don't hook this, but we still use it... - if (D3D9CreateRenderTarget_Original == nullptr) { + if (D3D9CreateRenderTarget == nullptr) { static HMODULE hModD3D9 = GetModuleHandle (config.system.injector.c_str ()); - D3D9CreateRenderTarget_Original = + D3D9CreateRenderTarget = (CreateRenderTarget_pfn) GetProcAddress (hModD3D9, "D3D9CreateRenderTarget_Override"); } // We don't hook this, but we still use it... - if (D3D9CreateDepthStencilSurface_Original == nullptr) { + if (D3D9CreateDepthStencilSurface == nullptr) { static HMODULE hModD3D9 = GetModuleHandle (config.system.injector.c_str ()); - D3D9CreateDepthStencilSurface_Original = + D3D9CreateDepthStencilSurface = (CreateDepthStencilSurface_pfn) GetProcAddress (hModD3D9, "D3D9CreateDepthStencilSurface_Override"); } @@ -2677,6 +2671,12 @@ bool shutting_down = false; void tbf::RenderFix::TextureManager::Shutdown (void) { + // It is possible for the DLL to be unloaded before the texture manager is + // initialized, in which case a nullptr value for tex_log is the easiest + // way to detect this. + if (tex_log == nullptr) + return; + // 16.6 ms per-frame (60 FPS) const float frame_time = 16.6f; @@ -3033,8 +3033,8 @@ HRESULT WINAPI ResampleTexture (tbf_tex_load_s* load) { - QueryPerformanceFrequency (&load->freq); - QueryPerformanceCounter/*_Original*/ (&load->start); + QueryPerformanceFrequency (&load->freq); + QueryPerformanceCounter (&load->start); D3DXIMAGE_INFO img_info; @@ -3047,13 +3047,14 @@ ResampleTexture (tbf_tex_load_s* load) if (img_info.Depth == 1) { hr = - D3DXCreateTextureFromFileInMemoryEx_Original ( + D3DXCreateTextureFromFileInMemoryEx ( load->pDevice, load->pSrcData, load->SrcDataSize, - img_info.Width, img_info.Height, 0,//D3DX_DEFAULT, - 0, img_info.Format, + img_info.Width, img_info.Height, 0, + 0, config.textures.uncompressed ? D3DFMT_A8R8G8B8 : img_info.Format, D3DPOOL_DEFAULT, - D3DX_FILTER_POINT, D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER, + D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER, + D3DX_FILTER_BOX | D3DX_FILTER_DITHER, 0, nullptr, nullptr, &load->pSrc ); @@ -3135,13 +3136,13 @@ SK_TextureWorkerThread::ThreadProc (LPVOID user) if (pStream->type == tbf_tex_load_s::Resample) { InterlockedIncrement (&resampling); - QueryPerformanceFrequency (&pStream->freq); - QueryPerformanceCounter/*_Original*/ (&pStream->start); + QueryPerformanceFrequency (&pStream->freq); + QueryPerformanceCounter (&pStream->start); HRESULT hr = ResampleTexture (pStream);//InjectTexture (pStream); - QueryPerformanceCounter/*_Original*/ (&pStream->end); + QueryPerformanceCounter (&pStream->end); InterlockedDecrement (&resampling); @@ -3153,13 +3154,13 @@ SK_TextureWorkerThread::ThreadProc (LPVOID user) InterlockedIncrement (&streaming); InterlockedExchangeAdd (&streaming_bytes, pStream->SrcDataSize); - QueryPerformanceFrequency (&pStream->freq); - QueryPerformanceCounter/*_Original*/ (&pStream->start); + QueryPerformanceFrequency (&pStream->freq); + QueryPerformanceCounter (&pStream->start); HRESULT hr = InjectTexture (pStream); - QueryPerformanceCounter/*_Original*/ (&pStream->end); + QueryPerformanceCounter (&pStream->end); InterlockedExchangeSubtract (&streaming_bytes, pStream->SrcDataSize); InterlockedDecrement (&streaming); diff --git a/tbf.VC.db b/tbf.VC.db index f6d3ecf..d6d9c9d 100644 Binary files a/tbf.VC.db and b/tbf.VC.db differ diff --git a/tbf.vcxproj b/tbf.vcxproj index 6e72c93..39f24d5 100644 --- a/tbf.vcxproj +++ b/tbf.vcxproj @@ -229,6 +229,7 @@ + diff --git a/tbf.vcxproj.filters b/tbf.vcxproj.filters index 0dac966..c74d31a 100644 --- a/tbf.vcxproj.filters +++ b/tbf.vcxproj.filters @@ -40,6 +40,9 @@ Source Files + + Source Files + diff --git a/version.ini b/version.ini index 85a0419..fc40ce9 100644 Binary files a/version.ini and b/version.ini differ