From efdffd8adffe79280a92b584b1136c4026822450 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 5 Oct 2024 14:54:03 +0200 Subject: [PATCH] III: Scale radardisc to resolution --- SilentPatchIII/SilentPatchIII.cpp | 116 ++++++++++++++++++++++++++++++ SilentPatchVC/SilentPatchVC.cpp | 1 + 2 files changed, 117 insertions(+) diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 3a8bca2..e2e9228 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -45,6 +45,17 @@ namespace ModCompat } return bOldModVersion; } + + namespace Utils + { + template + HMODULE GetModuleHandleFromAddress( AT address ) + { + HMODULE result = nullptr; + GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT|GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, LPCTSTR(address), &result ); + return result; + } + } } struct PsGlobalType @@ -889,6 +900,49 @@ namespace FixedBrightnessSaving } } + +// ============= Radar position and radardisc scaling ============= +namespace RadardiscFixes +{ + template + static const float* orgRadarXPos; + + template + static float RadarXPos_Recalculated; + + template + static void RecalculateXPositions(std::index_sequence) + { + const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth; + ((RadarXPos_Recalculated = *orgRadarXPos * multiplier), ...); + } + + template + static const float* orgRadarYPos; + + template + static float RadarYPos_Recalculated; + + template + static void RecalculateYPositions(std::index_sequence) + { + const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight; + ((RadarYPos_Recalculated = *orgRadarYPos * multiplier), ...); + } + + static void (*orgDrawMap)(); + template + static void DrawMap_RecalculatePositions() + { + RecalculateXPositions(std::make_index_sequence{}); + RecalculateYPositions(std::make_index_sequence{}); + orgDrawMap(); + } + + HOOK_EACH_INIT(CalculateRadarXPos, orgRadarXPos, RadarXPos_Recalculated); + HOOK_EACH_INIT(CalculateRadarYPos, orgRadarYPos, RadarYPos_Recalculated); +} + namespace ModelIndicesReadyHook { static void (*orgInitialiseObjectData)(const char*); @@ -907,6 +961,8 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul const ModuleList moduleList; + const HMODULE hGameModule = GetModuleHandle(nullptr); + const HMODULE skygfxModule = moduleList.Get(L"skygfx"); const HMODULE iiiAircraftModule = moduleList.Get(L"IIIAircraft"); if (skygfxModule != nullptr) @@ -923,6 +979,12 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul SVF::RegisterFeature(156, SVF::Feature::SIT_IN_BOAT); } + auto PatchFloat = [](float** address, const float*& org, float& replaced) + { + org = *address; + Patch(address, &replaced); + }; + // Locale based metric/imperial system INI/debug menu { using namespace Localization; @@ -1071,6 +1133,60 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul TXN_CATCH(); + // Fix the radar disc shadow scaling and radar X position + try + { + using namespace RadardiscFixes; + // We use this overkill pattern so we can get all those constants safely in one sweep. One big scan is better than several smaller ones. + auto drawRadardisc = pattern("D8 05 ? ? ? ? D9 1C 24 DB 05 ? ? ? ? 50 D8 0D ? ? ? ? D8 0D ? ? ? ? D8 05 ? ? ? ? D8 05 ? ? ? ? D9 1C 24 D9 C0 D8 25 ? ? ? ? 50 D9 1C 24 8D 8C 24 ? ? ? ? FF 35") + .get_one(); + auto drawRadarMap = pattern("D8 05 ? ? ? ? D9 1C 24 50 D9 14 24 8D 4C 24 24 FF 35").get_one(); + + std::array radarXPos = { + drawRadardisc.get(28 + 2), + drawRadardisc.get(34 + 2), + drawRadardisc.get(62 + 2), + + get_pattern("D8 05 ? ? ? ? DE C1 D9 19", 2), + drawRadarMap.get(2), + drawRadarMap.get(17 + 2), + }; + + std::array radarYPos = { + drawRadardisc.get(2), + drawRadardisc.get(45 + 2), + }; + + auto drawMap = get_pattern("0F 84 ? ? ? ? E8 ? ? ? ? 8D 8C 24", 6); + + // Undo the damage caused by IVRadarScaling from the widescreen fix moving the radar way too far to the right + // It's moved from 40.0f to 71.0f, which is way too much now that we're scaling the horizontal placement correctly! + // This is removed from the most up-to-date widescreen fix, but keep it so we don't break with older builds. + try + { + // Use exactly the same patterns as widescreen fix + float* radarPos = *get_pattern("D8 05 ? ? ? ? DE C1 D9 19 8B 15 ? ? ? ? 89 14 24", 2); + auto radarDisc1 = get_pattern("FF 35 ? ? ? ? DD D8 E8 ? ? ? ? B9 ? ? ? ? 50", 2); + auto radarDisc2 = get_pattern("D8 05 ? ? ? ? D8 05 ? ? ? ? D9 1C 24 D9 C0 D8 25 ? ? ? ? 50", 2); + + if (hGameModule == ModCompat::Utils::GetModuleHandleFromAddress(radarPos) && *radarPos == (40.0f + 31.0f)) + { + *radarPos = 40.0f; + + static float STOCK_RADAR_POS = 40.0f; + static float STOCK_RADARDISC_POS = STOCK_RADAR_POS - 4.0f; + Patch(radarDisc1, &STOCK_RADARDISC_POS); + Patch(radarDisc2, &STOCK_RADAR_POS); + } + } + TXN_CATCH(); + + HookEach_CalculateRadarXPos(radarXPos, PatchFloat); + HookEach_CalculateRadarYPos(radarYPos, PatchFloat); + InterceptCall(drawMap, orgDrawMap, DrawMap_RecalculatePositions); + } + TXN_CATCH(); + FLAUtils::Init(moduleList); } diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 4d31843..403da1d 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -1420,6 +1420,7 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule // Undo the damage caused by IVRadarScaling from the widescreen fix moving the radar way too far to the right // It's moved from 40.0f to 71.0f, which is way too much now that we're scaling the horizontal placement correctly! + // This is removed from the most up-to-date widescreen fix, but keep it so we don't break with older builds. try { // Use exactly the same patterns as widescreen fix