mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 23:03:01 +05:00
Metric/Imperial check based on Windows locale settings and on INI/debug menu override (III/VC)
This commit is contained in:
parent
da5b5b1e12
commit
bb02824c91
8 changed files with 208 additions and 0 deletions
|
@ -98,5 +98,10 @@ namespace Common {
|
|||
{
|
||||
DelayedPatches::Func = std::move(func);
|
||||
}
|
||||
|
||||
void III_VC_DelayedCommon( bool /*hasDebugMenu*/, const wchar_t* /*iniPath*/ )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace Common
|
|||
{
|
||||
namespace Patches
|
||||
{
|
||||
void III_VC_DelayedCommon( bool hasDebugMenu, const wchar_t* iniPath );
|
||||
void III_VC_Common();
|
||||
void III_VC_SetDelayedPatchesFunc( void(*func)() );
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
#include "Common_ddraw.h"
|
||||
|
||||
#include <memory>
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#include "debugmenu_public.h"
|
||||
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
|
||||
struct PsGlobalType
|
||||
{
|
||||
|
@ -44,6 +49,10 @@ struct RwV2d
|
|||
float y; /**< Y value */
|
||||
};
|
||||
|
||||
DebugMenuAPI gDebugMenuAPI;
|
||||
|
||||
static HMODULE hDLLModule;
|
||||
|
||||
|
||||
static void (*DrawRect)(const CRect&,const CRGBA&);
|
||||
static void (*SetScale)(float,float);
|
||||
|
@ -426,6 +435,68 @@ namespace KeyboardInputFix
|
|||
}
|
||||
}
|
||||
|
||||
namespace Localization
|
||||
{
|
||||
static int8_t forcedUnits = -1; // 0 - metric, 1 - imperial
|
||||
|
||||
bool IsMetric_LocaleBased()
|
||||
{
|
||||
if ( forcedUnits != -1 ) return forcedUnits == 0;
|
||||
|
||||
unsigned int LCData;
|
||||
if ( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER, reinterpret_cast<LPTSTR>(&LCData), sizeof(LCData) / sizeof(TCHAR) ) != 0 )
|
||||
{
|
||||
return LCData == 0;
|
||||
}
|
||||
|
||||
// If fails, default to metric. Hopefully never fails though
|
||||
return true;
|
||||
}
|
||||
|
||||
static void (__thiscall* orgUpdateCompareFlag_IsMetric)(void* pThis, uint8_t flag);
|
||||
void __fastcall UpdateCompareFlag_IsMetric(void* pThis, void*, uint8_t)
|
||||
{
|
||||
std::invoke( orgUpdateCompareFlag_IsMetric, pThis, IsMetric_LocaleBased() );
|
||||
}
|
||||
|
||||
uint32_t PrefsLanguage_IsMetric()
|
||||
{
|
||||
return IsMetric_LocaleBased();
|
||||
}
|
||||
}
|
||||
|
||||
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||
{
|
||||
// Locale based metric/imperial system INI/debug menu
|
||||
{
|
||||
using namespace Localization;
|
||||
|
||||
forcedUnits = static_cast<int8_t>(GetPrivateProfileIntW(L"SilentPatch", L"Units", -1, wcModulePath));
|
||||
if ( bHasDebugMenu )
|
||||
{
|
||||
static const char * const str[] = { "Default", "Metric", "Imperial" };
|
||||
DebugMenuEntry *e = DebugMenuAddVar( "SilentPatch", "Forced units", &forcedUnits, nullptr, 1, -1, 1, str );
|
||||
DebugMenuEntrySetWrap(e, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InjectDelayedPatches_III_Common()
|
||||
{
|
||||
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( GetModuleHandle( nullptr ), ".text" );
|
||||
|
||||
// Obtain a path to the ASI
|
||||
wchar_t wcModulePath[MAX_PATH];
|
||||
GetModuleFileNameW(hDLLModule, wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension
|
||||
PathRenameExtensionW(wcModulePath, L".ini");
|
||||
|
||||
const bool hasDebugMenu = DebugMenuLoad();
|
||||
|
||||
InjectDelayedPatches_III_Common( hasDebugMenu, wcModulePath );
|
||||
|
||||
Common::Patches::III_VC_DelayedCommon( hasDebugMenu, wcModulePath );
|
||||
}
|
||||
|
||||
|
||||
void Patch_III_10(const RECT& desktop)
|
||||
{
|
||||
|
@ -953,6 +1024,32 @@ void Patch_III_Common()
|
|||
InjectHook( simButtonCheckers, ClearSimButtonPressCheckers );
|
||||
InjectHook( updatePads.get<void>( 10 ), jmpDest, PATCH_JUMP );
|
||||
}
|
||||
|
||||
|
||||
// Locale based metric/imperial system
|
||||
{
|
||||
using namespace Localization;
|
||||
|
||||
void* updateCompareFlag = get_pattern( "89 E9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5E 5B C2 04 00", 4 );
|
||||
|
||||
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
||||
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
||||
|
||||
// Stats
|
||||
auto constructStatLine = pattern( "FF 24 9D ? ? ? ? 39 D0" ).get_one();
|
||||
|
||||
// push eax
|
||||
// push edx
|
||||
// call IsMetric_LocaleBased
|
||||
// movzx ebx, al
|
||||
// pop edx
|
||||
// pop eax
|
||||
// nop...
|
||||
Patch( constructStatLine.get<void>( -0xF ), { 0x50, 0x52 } );
|
||||
InjectHook( constructStatLine.get<void>( -0xF + 2 ), PrefsLanguage_IsMetric, PATCH_CALL );
|
||||
Patch( constructStatLine.get<void>( -0xF + 7 ), { 0x0F, 0xB6, 0xD8, 0x5A, 0x58 } );
|
||||
Nop( constructStatLine.get<void>( -0xF + 12 ), 3 );
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
|
@ -962,6 +1059,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
|
||||
if ( fdwReason == DLL_PROCESS_ATTACH )
|
||||
{
|
||||
hDLLModule = hinstDLL;
|
||||
|
||||
RECT desktop;
|
||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
||||
|
@ -978,6 +1077,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
Patch_III_Common();
|
||||
Common::Patches::III_VC_Common();
|
||||
Common::Patches::DDraw_Common();
|
||||
|
||||
Common::Patches::III_VC_SetDelayedPatchesFunc( InjectDelayedPatches_III_Common );
|
||||
}
|
||||
|
||||
Common::Patches::FixRwcseg_Patterns();
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="..\SilentPatch\Common.h" />
|
||||
<ClInclude Include="..\SilentPatch\Common_ddraw.h" />
|
||||
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
|
||||
<ClInclude Include="..\SilentPatch\General.h" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
<ClInclude Include="..\SilentPatch\StoredCar.h" />
|
||||
|
|
|
@ -74,6 +74,9 @@
|
|||
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
|
||||
<Filter>Header Files\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\debugmenu_public.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
#include "ModelInfoVC.h"
|
||||
|
||||
#include <memory>
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#include "debugmenu_public.h"
|
||||
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
|
||||
struct RsGlobalType
|
||||
{
|
||||
|
@ -23,6 +28,10 @@ struct RsGlobalType
|
|||
void* pad;
|
||||
};
|
||||
|
||||
DebugMenuAPI gDebugMenuAPI;
|
||||
|
||||
static HMODULE hDLLModule;
|
||||
|
||||
static const void* RosieAudioFix_JumpBack;
|
||||
|
||||
static void (*PrintString)(float,float,const wchar_t*);
|
||||
|
@ -298,6 +307,68 @@ namespace KeyboardInputFix
|
|||
}
|
||||
}
|
||||
|
||||
namespace Localization
|
||||
{
|
||||
static int8_t forcedUnits = -1; // 0 - metric, 1 - imperial
|
||||
|
||||
bool IsMetric_LocaleBased()
|
||||
{
|
||||
if ( forcedUnits != -1 ) return forcedUnits == 0;
|
||||
|
||||
unsigned int LCData;
|
||||
if ( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER, reinterpret_cast<LPTSTR>(&LCData), sizeof(LCData) / sizeof(TCHAR) ) != 0 )
|
||||
{
|
||||
return LCData == 0;
|
||||
}
|
||||
|
||||
// If fails, default to metric. Hopefully never fails though
|
||||
return true;
|
||||
}
|
||||
|
||||
static void (__thiscall* orgUpdateCompareFlag_IsMetric)(void* pThis, uint8_t flag);
|
||||
void __fastcall UpdateCompareFlag_IsMetric(void* pThis, void*, uint8_t)
|
||||
{
|
||||
std::invoke( orgUpdateCompareFlag_IsMetric, pThis, IsMetric_LocaleBased() );
|
||||
}
|
||||
|
||||
uint32_t PrefsLanguage_IsMetric()
|
||||
{
|
||||
return IsMetric_LocaleBased();
|
||||
}
|
||||
}
|
||||
|
||||
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||
{
|
||||
// Locale based metric/imperial system INI/debug menu
|
||||
{
|
||||
using namespace Localization;
|
||||
|
||||
forcedUnits = static_cast<int8_t>(GetPrivateProfileIntW(L"SilentPatch", L"Units", -1, wcModulePath));
|
||||
if ( bHasDebugMenu )
|
||||
{
|
||||
static const char * const str[] = { "Default", "Metric", "Imperial" };
|
||||
DebugMenuEntry *e = DebugMenuAddVar( "SilentPatch", "Forced units", &forcedUnits, nullptr, 1, -1, 1, str );
|
||||
DebugMenuEntrySetWrap(e, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InjectDelayedPatches_VC_Common()
|
||||
{
|
||||
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( GetModuleHandle( nullptr ), ".text" );
|
||||
|
||||
// Obtain a path to the ASI
|
||||
wchar_t wcModulePath[MAX_PATH];
|
||||
GetModuleFileNameW(hDLLModule, wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension
|
||||
PathRenameExtensionW(wcModulePath, L".ini");
|
||||
|
||||
const bool hasDebugMenu = DebugMenuLoad();
|
||||
|
||||
InjectDelayedPatches_VC_Common( hasDebugMenu, wcModulePath );
|
||||
|
||||
Common::Patches::III_VC_DelayedCommon( hasDebugMenu, wcModulePath );
|
||||
}
|
||||
|
||||
void Patch_VC_10(const RECT& desktop)
|
||||
{
|
||||
using namespace Memory;
|
||||
|
@ -779,6 +850,24 @@ void Patch_VC_Common()
|
|||
InjectHook( updatePads.get<void>( 9 ), jmpDest, PATCH_JUMP );
|
||||
}
|
||||
|
||||
|
||||
// Locale based metric/imperial system
|
||||
{
|
||||
using namespace Localization;
|
||||
|
||||
void* updateCompareFlag = get_pattern( "89 D9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5F 5E 5B C2 04 00", 4 );
|
||||
|
||||
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
||||
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
||||
|
||||
// Stats
|
||||
auto constructStatLine = pattern( "85 C0 74 11 83 E8 01 83 F8 03" ).get_one();
|
||||
|
||||
Nop( constructStatLine.get<void>( -11 ), 1 );
|
||||
InjectHook( constructStatLine.get<void>( -11 + 1 ), PrefsLanguage_IsMetric, PATCH_CALL );
|
||||
Nop( constructStatLine.get<void>( -2 ), 2 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
|
@ -788,6 +877,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
|
||||
if ( fdwReason == DLL_PROCESS_ATTACH )
|
||||
{
|
||||
hDLLModule = hinstDLL;
|
||||
|
||||
RECT desktop;
|
||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
||||
|
@ -807,6 +898,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
Patch_VC_Common();
|
||||
Common::Patches::III_VC_Common();
|
||||
Common::Patches::DDraw_Common();
|
||||
|
||||
Common::Patches::III_VC_SetDelayedPatchesFunc( InjectDelayedPatches_VC_Common );
|
||||
}
|
||||
|
||||
Common::Patches::FixRwcseg_Patterns();
|
||||
|
|
|
@ -172,6 +172,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\SilentPatch\Common_ddraw.h" />
|
||||
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
|
||||
<ClInclude Include="..\SilentPatch\General.h" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
<ClInclude Include="..\SilentPatch\StoredCar.h" />
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
|
||||
<Filter>Header Files\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\debugmenu_public.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\SilentPatch\Timer.cpp">
|
||||
|
|
Loading…
Reference in a new issue