diff --git a/SilentPatch/Common.cpp b/SilentPatch/Common.cpp index 836f356..8baeaa5 100644 --- a/SilentPatch/Common.cpp +++ b/SilentPatch/Common.cpp @@ -84,8 +84,8 @@ namespace StaticShadowAlphaFix return result; } - HOOK_EACH_FUNC(StoreAlphaTest, orgRenderStateSet_StoreAlphaTest, RenderStateSet_StoreAlphaTest); - HOOK_EACH_FUNC(RestoreAlphaTest, orgRenderStateSet_RestoreAlphaTest, RenderStateSet_RestoreAlphaTest); + HOOK_EACH_INIT(StoreAlphaTest, orgRenderStateSet_StoreAlphaTest, RenderStateSet_StoreAlphaTest); + HOOK_EACH_INIT(RestoreAlphaTest, orgRenderStateSet_RestoreAlphaTest, RenderStateSet_RestoreAlphaTest); }; // ============= Corrected corona placement for taxi ============= diff --git a/SilentPatch/Maths.h b/SilentPatch/Maths.h index 36245eb..c25c5ee 100644 --- a/SilentPatch/Maths.h +++ b/SilentPatch/Maths.h @@ -2,6 +2,7 @@ #define _USE_MATH_DEFINES #include +#include #include diff --git a/SilentPatch/Utils b/SilentPatch/Utils index 58f3f47..cc5c9df 160000 --- a/SilentPatch/Utils +++ b/SilentPatch/Utils @@ -1 +1 @@ -Subproject commit 58f3f475e6e84dc97f5e2c171e21b928c2c366ab +Subproject commit cc5c9df5895e7c0ca0dc087a716f4782635ddcfe diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 97de0c4..3a8bca2 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -132,7 +132,7 @@ namespace ScalingFixes orgSetScale(fX * GetWidthMult() * RsGlobal->MaximumWidth, fY * GetHeightMult() * RsGlobal->MaximumHeight); } - HOOK_EACH_FUNC(SetScale, orgSetScale, SetScale_Fix); + HOOK_EACH_INIT(SetScale, orgSetScale, SetScale_Fix); } class CGang @@ -428,7 +428,7 @@ static void __fastcall GiveWeapon_SP(void* ped, void*, unsigned int weapon, unsi { orgGiveWeapon(ped, nullptr, weapon, std::max(1u, ammo)); } -HOOK_EACH_FUNC(GiveWeapon, orgGiveWeapon, GiveWeapon_SP); +HOOK_EACH_INIT(GiveWeapon, orgGiveWeapon, GiveWeapon_SP); } @@ -739,7 +739,7 @@ namespace VariableResets ReInitOurVariables(); orgReInitGameObjectVariables(); } - HOOK_EACH_FUNC(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); + HOOK_EACH_INIT(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); static void (*orgGameInitialise)(const char*); void GameInitialise(const char* path) @@ -813,7 +813,7 @@ namespace SitInBoat orgRegisterReference(pThis, nullptr, pReference); } - HOOK_EACH_FUNC(CheckSitInBoat, orgRegisterReference, RegisterReference_CheckSitInBoat); + HOOK_EACH_INIT(CheckSitInBoat, orgRegisterReference, RegisterReference_CheckSitInBoat); template static void* (*orgBlendAnimation)(void*, unsigned int, unsigned int, float); @@ -828,7 +828,7 @@ namespace SitInBoat return orgBlendAnimation(clump, groupId, animationId, factor); } - HOOK_EACH_FUNC(BlendAnimation, orgBlendAnimation, BlendAnimation_SitInBoat); + HOOK_EACH_INIT(BlendAnimation, orgBlendAnimation, BlendAnimation_SitInBoat); using FinishCB = void(*)(void*, void*); static void __fastcall FinishCallback_CallImmediately(void*, void*, FinishCB cb, Ped* ped) diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 8a00d3a..ed8aa13 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -770,7 +770,7 @@ static void WipeLocalVariableMemoryForMissionScript_ApplyFixes() StartNewMission_SCMFixes(); } -HOOK_EACH_FUNC(SCMFixes, orgWipeLocalVariableMemoryForMissionScript, WipeLocalVariableMemoryForMissionScript_ApplyFixes) +HOOK_EACH_INIT(SCMFixes, orgWipeLocalVariableMemoryForMissionScript, WipeLocalVariableMemoryForMissionScript_ApplyFixes) } @@ -979,7 +979,7 @@ static RwUInt32 GetMaxMultiSamplingLevels() { return GetMaxMultiSamplingLevels_BitScan(orgGetMaxMultiSamplingLevels()); } -HOOK_EACH_FUNC(GetMaxMultiSamplingLevels, orgGetMaxMultiSamplingLevels, GetMaxMultiSamplingLevels); +HOOK_EACH_INIT(GetMaxMultiSamplingLevels, orgGetMaxMultiSamplingLevels, GetMaxMultiSamplingLevels); template static void (*orgSetOrChangeMultiSamplingLevels)(RwUInt32); @@ -989,7 +989,7 @@ static void SetOrChangeMultiSamplingLevels(RwUInt32 level) { orgSetOrChangeMultiSamplingLevels( 1 << (level - 1) ); } -HOOK_EACH_FUNC(SetOrChangeMultiSamplingLevels, orgSetOrChangeMultiSamplingLevels, SetOrChangeMultiSamplingLevels); +HOOK_EACH_INIT(SetOrChangeMultiSamplingLevels, orgSetOrChangeMultiSamplingLevels, SetOrChangeMultiSamplingLevels); void MSAAText( char* buffer, const char*, DWORD level ) { @@ -1038,7 +1038,7 @@ static void* CollisionData_NewAndInit(size_t size) return mem; } -HOOK_EACH_FUNC(CollisionDataNew, orgNewAlloc, CollisionData_NewAndInit); +HOOK_EACH_INIT(CollisionDataNew, orgNewAlloc, CollisionData_NewAndInit); } @@ -1722,7 +1722,7 @@ namespace VariableResets // Then after the normal restart, re-instate pickups, car generators and stunt jumps from text IPLs as they have been ReloadObjectDefinitionsAfterReinit(); } - HOOK_EACH_FUNC(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); + HOOK_EACH_INIT(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); } namespace LightbeamFix @@ -2279,7 +2279,7 @@ namespace RestrictImpoundVehicleTypes return vehicle->CanThisVehicleBeImpounded() && orgIsThisVehicleInteresting(vehicle); } - HOOK_EACH_FUNC(ShouldImpound, orgIsThisVehicleInteresting, IsThisVehicleInteresting_AndCanBeImpounded) + HOOK_EACH_INIT(ShouldImpound, orgIsThisVehicleInteresting, IsThisVehicleInteresting_AndCanBeImpounded) } @@ -2536,7 +2536,7 @@ namespace Rand16bit return bottomBits | topBit; } - HOOK_EACH_FUNC(Rand, orgRand, rand16bit); + HOOK_EACH_INIT(Rand, orgRand, rand16bit); } diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index dfff1fe..eeda440 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -313,7 +313,7 @@ private: } public: - HOOK_EACH_FUNC(DoHeadLightBeam, orgDoHeadLightBeam, &DoHeadLightBeam_LightBeamFixSaveObj); + HOOK_EACH_INIT(DoHeadLightBeam, orgDoHeadLightBeam, &DoHeadLightBeam_LightBeamFixSaveObj); }; class NOVMT CAutomobile : public CVehicle @@ -347,7 +347,7 @@ public: AfterPreRender(); } - HOOK_EACH_FUNC(PreRender, orgAutomobilePreRender, &PreRender_SilentPatch); + HOOK_EACH_INIT(PreRender, orgAutomobilePreRender, &PreRender_SilentPatch); void HideDestroyedWheels_SilentPatch(void (CAutomobile::*spawnFlyingComponentCB)(int, unsigned int), int nodeID, unsigned int modelID); @@ -360,7 +360,7 @@ public: HideDestroyedWheels_SilentPatch(orgSpawnFlyingComponent, nodeID, modelID); } - HOOK_EACH_FUNC(SpawnFlyingComponent, orgSpawnFlyingComponent, &SpawnFlyingComponent_HideWheels); + HOOK_EACH_INIT(SpawnFlyingComponent, orgSpawnFlyingComponent, &SpawnFlyingComponent_HideWheels); void Fix_SilentPatch(); RwFrame* GetTowBarFrame() const; @@ -457,7 +457,7 @@ private: } public: - HOOK_EACH_FUNC(RestoreCar, orgRestoreCar, &RestoreCar_SilentPatch); + HOOK_EACH_INIT(RestoreCar, orgRestoreCar, &RestoreCar_SilentPatch); private: CVehicle* RestoreCar_LoadBombOwnership(CVehicle* vehicle); diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 5a8d73e..01b00f9 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -190,6 +190,96 @@ namespace PrintStringShadows Memory::DynBase::InterceptCall(addr, orgPrintString, PrintString); } }; + + // Radar position and radardisc shadow + + static const float RADARDISC_SHRINK = 2.0f; // We are shrinking the radardisc by that + + 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), ...); + } + + template + static const float* orgRadarXPos_RadardiscShrink; + + template + static float RadarXPos_Recalculated_RadardiscShrink; + + template + static void RecalculateXPositions_RadardiscShrink(std::index_sequence) + { + const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth; + ((RadarXPos_Recalculated_RadardiscShrink = (*orgRadarXPos_RadardiscShrink - RADARDISC_SHRINK) * multiplier), ...); + } + + template + static const float* orgRadarYPos_RadardiscShrink; + + template + static float RadarYPos_Recalculated_RadardiscShrink; + + template + static void RecalculateYPositions_RadardiscShrink(std::index_sequence) + { + const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight; + ((RadarYPos_Recalculated_RadardiscShrink = (*orgRadarYPos_RadardiscShrink - RADARDISC_SHRINK) * multiplier), ...); + } + + static void (*orgDrawMap)(); + template + static void DrawMap_RecalculatePositions() + { + RecalculateXPositions(std::make_index_sequence{}); + RecalculateYPositions(std::make_index_sequence{}); + RecalculateXPositions_RadardiscShrink(std::make_index_sequence{}); + RecalculateYPositions_RadardiscShrink(std::make_index_sequence{}); + orgDrawMap(); + } + + HOOK_EACH_INIT(CalculateRadarXPos, orgRadarXPos, RadarXPos_Recalculated); + HOOK_EACH_INIT(CalculateRadarYPos, orgRadarYPos, RadarYPos_Recalculated); + HOOK_EACH_INIT(CalculateRadarXPos_RadardiscShrink, orgRadarXPos_RadardiscShrink, RadarXPos_Recalculated_RadardiscShrink); + HOOK_EACH_INIT(CalculateRadarYPos_RadardiscShrink, orgRadarYPos_RadardiscShrink, RadarYPos_Recalculated_RadardiscShrink); + + static CRect ScaleWidthRect(CRect rect) + { + // Also account for a smaller radardisc + rect.x1 = (rect.x1 + RADARDISC_SHRINK) * GetWidthMult() * RsGlobal->MaximumWidth; + return rect; + } + + template + static void (__fastcall* orgDrawSprite)(void* obj, void*, const CRect& rect, const CRGBA& col1, const CRGBA& col2, const CRGBA& col3, const CRGBA& col4); + + template + static void __fastcall DrawSprite_Scale(void* obj, void*, const CRect& rect, const CRGBA& col1, const CRGBA& col2, const CRGBA& col3, const CRGBA& col4) + { + orgDrawSprite(obj, nullptr, ScaleWidthRect(rect), col1, col2, col3, col4); + } + + HOOK_EACH_INIT(DrawRadarDisc, orgDrawSprite, DrawSprite_Scale); } float FixedRefValue() @@ -287,7 +377,7 @@ static void __fastcall GiveWeapon_SP(void* ped, void*, unsigned int weapon, unsi { orgGiveWeapon(ped, nullptr, weapon, std::max(1u, ammo), flag); } -HOOK_EACH_FUNC(GiveWeapon, orgGiveWeapon, GiveWeapon_SP); +HOOK_EACH_INIT(GiveWeapon, orgGiveWeapon, GiveWeapon_SP); } @@ -681,7 +771,7 @@ namespace VariableResets ReInitOurVariables(); orgReInitGameObjectVariables(); } - HOOK_EACH_FUNC(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); + HOOK_EACH_INIT(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); static void (*orgGameInitialise)(const char*); void GameInitialise(const char* path) @@ -845,7 +935,7 @@ namespace ConstructionSiteLODFix FixConstructionSiteModel(oldModelID, newModelID); } - HOOK_EACH_FUNC(ReplaceWithNewModel, orgReplaceWithNewModel, ReplaceWithNewModel_ConstructionSiteFix); + HOOK_EACH_INIT(ReplaceWithNewModel, orgReplaceWithNewModel, ReplaceWithNewModel_ConstructionSiteFix); } @@ -936,7 +1026,7 @@ namespace TommyFistShakeWithWeapons return orgGetWeaponInfo(weaponID); } - HOOK_EACH_FUNC(ExcludeChainsaw, orgGetWeaponInfo, gGetWeaponInfo_ExcludeChainsaw); + HOOK_EACH_INIT(ExcludeChainsaw, orgGetWeaponInfo, gGetWeaponInfo_ExcludeChainsaw); } @@ -947,6 +1037,8 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule const ModuleList moduleList; + const HMODULE hGameModule = GetModuleHandle(nullptr); + const HMODULE skygfxModule = moduleList.Get(L"skygfx"); if (skygfxModule != nullptr) { @@ -1130,6 +1222,94 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule TXN_CATCH(); + // Fix the radar disc shadow scaling and radar X position + try + { + // Legacy namespace name, it's OK + using namespace PrintStringShadows; + + auto draw_entity_coord_blip = pattern("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 D9 5C 24 18").count(2); + auto draw_radar_disc1 = pattern("D8 25 ? ? ? ? DD DB D9 C2 D9 9C 24 ? ? ? ? DB 05 ? ? ? ? D8 0D ? ? ? ? D8 0D ? ? ? ? D8 05 ? ? ? ? D8 05").count(2); + auto draw_radar_disc2 = pattern("D8 C1 D8 05 ? ? ? ? D9 9C 24 ? ? ? ? DE D9 DD D8").count(2); + + std::array radarXPos = { + get_pattern("D8 05 ? ? ? ? DE C1 D9 5C 24 28", 2), + get_pattern("D8 05 ? ? ? ? DE C1 D9 5C EC 30", 2), + get_pattern("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 D9 9C C4", 6 + 2), + get_pattern("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 D9 5C 24 08", 6 + 2), + get_pattern("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 DD D9 DB 44 24 18", 6 + 2), + get_pattern("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 DD DB DB 44 24 18", 6 + 2), + draw_entity_coord_blip.get(0).get(6 + 2), + draw_entity_coord_blip.get(1).get(6 + 2), + }; + + std::array radarXPos_RadardiscShrink = { + draw_radar_disc1.get(0).get(35 + 2), + draw_radar_disc1.get(0).get(35 + 6 + 2), + draw_radar_disc1.get(1).get(35 + 2), + draw_radar_disc1.get(1).get(35 + 6 + 2), + }; + + std::array radarYPos_RadardiscShrink = { + draw_radar_disc1.get(0).get(2), + draw_radar_disc1.get(1).get(2), + draw_radar_disc2.get(0).get(2 + 2), + draw_radar_disc2.get(1).get(2 + 2), + }; + + auto drawMap = get_pattern("59 E8 ? ? ? ? 83 3D ? ? ? ? ? 0F 84", 1); + + auto drawRadarDiscSprite = pattern("D8 05 ? ? ? ? D9 9C 24 ? ? ? ? DE D9 DD D8 E8").count(2); + std::array spriteDraw = { + drawRadarDiscSprite.get(0).get(17), + drawRadarDiscSprite.get(1).get(17), + }; + + // 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! + try + { + // Use exactly the same patterns as widescreen fix + float* radarPos = *get_pattern("D8 05 ? ? ? ? DE C1 D9 5C 24 28", 2); + // No need to undo CRadar::DrawYouAreHereSprite, as wsfix keeps it as 40.0f + + // This hardcodes a patched constant inside so the pattern will fail to match without IV radar scaling + auto radarRing1 = pattern("C7 84 24 ? ? ? ? 00 00 82 42").count(2); + auto radarRing2 = pattern("D8 05 ? ? ? ? D8 05 ? ? ? ? D9 9C 24").count(2); + + // This + radarRing1 succeeding is enough proof that IVRadarScaling is in use + if (hGameModule == ModCompat::Utils::GetModuleHandleFromAddress(radarPos) && *radarPos == (40.0f + 31.0f)) + { + *radarPos = 40.0f; + radarRing1.for_each_result([](pattern_match match) + { + Patch(match.get(7), 34.0f); + }); + radarRing2.for_each_result([](pattern_match match) + { + static float STOCK_RADAR_POS = 40.0f; + Patch(match.get(2), &STOCK_RADAR_POS); + }); + } + } + TXN_CATCH(); + + + auto PatchFloat = [](float** address, const float*& org, float& replaced) + { + org = *address; + Patch(address, &replaced); + }; + + HookEach_CalculateRadarXPos(radarXPos, PatchFloat); + HookEach_CalculateRadarXPos_RadardiscShrink(radarXPos_RadardiscShrink, PatchFloat); + HookEach_CalculateRadarYPos_RadardiscShrink(radarYPos_RadardiscShrink, PatchFloat); + HookEach_DrawRadarDisc(spriteDraw, InterceptCall); + InterceptCall(drawMap, orgDrawMap, DrawMap_RecalculatePositions); + } + TXN_CATCH(); + + FLAUtils::Init(moduleList); }