mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05:00
VC: Improve compatibility between the radar placement fix and plugin-sdk
plugin-sdk had to reimplement an inlined CRadar::TransformRadarPointToScreenSpace, so we need to patch a stock global variable so this reimplementation can be aware of our fixes. Fixes #43
This commit is contained in:
parent
5aaec719ed
commit
9f705a3dc3
1 changed files with 38 additions and 49 deletions
|
@ -211,32 +211,9 @@ namespace PrintStringShadows
|
||||||
namespace RadardiscFixes
|
namespace RadardiscFixes
|
||||||
{
|
{
|
||||||
static const float RADARDISC_SHRINK = 2.0f; // We are shrinking the radardisc by that
|
static const float RADARDISC_SHRINK = 2.0f; // We are shrinking the radardisc by that
|
||||||
|
|
||||||
template<std::size_t Index>
|
|
||||||
static const float* orgRadarXPos;
|
|
||||||
|
|
||||||
template<std::size_t Index>
|
static float orgRadarXPosVal;
|
||||||
static float RadarXPos_Recalculated;
|
static float* orgRadarXPosPtr;
|
||||||
|
|
||||||
template<std::size_t... I>
|
|
||||||
static void RecalculateXPositions(std::index_sequence<I...>)
|
|
||||||
{
|
|
||||||
const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth;
|
|
||||||
((RadarXPos_Recalculated<I> = *orgRadarXPos<I> * multiplier), ...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t Index>
|
|
||||||
static const float* orgRadarYPos;
|
|
||||||
|
|
||||||
template<std::size_t Index>
|
|
||||||
static float RadarYPos_Recalculated;
|
|
||||||
|
|
||||||
template<std::size_t... I>
|
|
||||||
static void RecalculateYPositions(std::index_sequence<I...>)
|
|
||||||
{
|
|
||||||
const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight;
|
|
||||||
((RadarYPos_Recalculated<I> = *orgRadarYPos<I> * multiplier), ...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t Index>
|
template<std::size_t Index>
|
||||||
static const float* orgRadarXPos_RadardiscShrink;
|
static const float* orgRadarXPos_RadardiscShrink;
|
||||||
|
@ -265,18 +242,15 @@ namespace RadardiscFixes
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*orgDrawMap)();
|
static void (*orgDrawMap)();
|
||||||
template<std::size_t NumXPos, std::size_t NumYPos, std::size_t NumXPosRadardisc, std::size_t NumYPosRadardisc>
|
template<std::size_t NumXPosRadardisc, std::size_t NumYPosRadardisc>
|
||||||
static void DrawMap_RecalculatePositions()
|
static void DrawMap_RecalculatePositions()
|
||||||
{
|
{
|
||||||
RecalculateXPositions(std::make_index_sequence<NumXPos>{});
|
*orgRadarXPosPtr = orgRadarXPosVal * GetWidthMult() * RsGlobal->MaximumWidth;
|
||||||
RecalculateYPositions(std::make_index_sequence<NumYPos>{});
|
|
||||||
RecalculateXPositions_RadardiscShrink(std::make_index_sequence<NumXPosRadardisc>{});
|
RecalculateXPositions_RadardiscShrink(std::make_index_sequence<NumXPosRadardisc>{});
|
||||||
RecalculateYPositions_RadardiscShrink(std::make_index_sequence<NumYPosRadardisc>{});
|
RecalculateYPositions_RadardiscShrink(std::make_index_sequence<NumYPosRadardisc>{});
|
||||||
orgDrawMap();
|
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(CalculateRadarXPos_RadardiscShrink, orgRadarXPos_RadardiscShrink, RadarXPos_Recalculated_RadardiscShrink);
|
||||||
HOOK_EACH_INIT(CalculateRadarYPos_RadardiscShrink, orgRadarYPos_RadardiscShrink, RadarYPos_Recalculated_RadardiscShrink);
|
HOOK_EACH_INIT(CalculateRadarYPos_RadardiscShrink, orgRadarYPos_RadardiscShrink, RadarYPos_Recalculated_RadardiscShrink);
|
||||||
|
|
||||||
|
@ -1537,21 +1511,9 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
{
|
{
|
||||||
using namespace RadardiscFixes;
|
using namespace RadardiscFixes;
|
||||||
|
|
||||||
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_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);
|
auto draw_radar_disc2 = pattern("D8 C1 D8 05 ? ? ? ? D9 9C 24 ? ? ? ? DE D9 DD D8").count(2);
|
||||||
|
|
||||||
std::array<float**, 8> radarXPos = {
|
|
||||||
get_pattern<float*>("D8 05 ? ? ? ? DE C1 D9 5C 24 28", 2),
|
|
||||||
get_pattern<float*>("D8 05 ? ? ? ? DE C1 D9 5C EC 30", 2),
|
|
||||||
get_pattern<float*>("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 D9 9C C4", 6 + 2),
|
|
||||||
get_pattern<float*>("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 D9 5C 24 08", 6 + 2),
|
|
||||||
get_pattern<float*>("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 DD D9 DB 44 24 18", 6 + 2),
|
|
||||||
get_pattern<float*>("D8 0D ? ? ? ? D8 05 ? ? ? ? DE C1 DD DB DB 44 24 18", 6 + 2),
|
|
||||||
draw_entity_coord_blip.get(0).get<float*>(6 + 2),
|
|
||||||
draw_entity_coord_blip.get(1).get<float*>(6 + 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<float**, 4> radarXPos_RadardiscShrink = {
|
std::array<float**, 4> radarXPos_RadardiscShrink = {
|
||||||
draw_radar_disc1.get(0).get<float*>(35 + 2),
|
draw_radar_disc1.get(0).get<float*>(35 + 2),
|
||||||
draw_radar_disc1.get(0).get<float*>(35 + 6 + 2),
|
draw_radar_disc1.get(0).get<float*>(35 + 6 + 2),
|
||||||
|
@ -1574,13 +1536,18 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
drawRadarDiscSprite.get(1).get<void>(17),
|
drawRadarDiscSprite.get(1).get<void>(17),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use exactly the same patterns as widescreen fix
|
||||||
|
float* radarPos = *get_pattern<float*>("D8 05 ? ? ? ? DE C1 D9 5C 24 28", 2);
|
||||||
|
std::array<float**, 2> youAreHereSize = {
|
||||||
|
get_pattern<float*>("DD D9 D9 05 ? ? ? ? D8 C9 D9 7C 24 04", 2 + 2),
|
||||||
|
get_pattern<float*>("8B 5C 24 18 D8 0D ? ? ? ? D8 0D ? ? ? ? D9 7C 24 04", 10 + 2),
|
||||||
|
};
|
||||||
|
|
||||||
// Undo the damage caused by IVRadarScaling from the widescreen fix moving the radar way too far to the right
|
// 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!
|
// 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.
|
// This is removed from the most up-to-date widescreen fix, but keep it so we don't break with older builds.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Use exactly the same patterns as widescreen fix
|
|
||||||
float* radarPos = *get_pattern<float*>("D8 05 ? ? ? ? DE C1 D9 5C 24 28", 2);
|
|
||||||
// No need to undo CRadar::DrawYouAreHereSprite, as wsfix keeps it as 40.0f
|
// 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
|
// This hardcodes a patched constant inside so the pattern will fail to match without IV radar scaling
|
||||||
|
@ -1604,11 +1571,33 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
|
|
||||||
HookEach_CalculateRadarXPos(radarXPos, PatchFloat);
|
// Normally we would "wrap" the global variable 40.0f used as a X radar position, but that causes issues with plugin-sdk.
|
||||||
HookEach_CalculateRadarXPos_RadardiscShrink(radarXPos_RadardiscShrink, PatchFloat);
|
// Vice City inlined CRadar::TransformRadarPointToScreenSpace and plugin-sdk reimplements it using this global directly, so we need to patch it.
|
||||||
HookEach_CalculateRadarYPos_RadardiscShrink(radarYPos_RadardiscShrink, PatchFloat);
|
// Therefore, we instead do the following:
|
||||||
HookEach_DrawRadarDisc(spriteDraw, InterceptCall);
|
// 1. Patch the float directly, reading the original value once and rescaling as usual in-place.
|
||||||
InterceptCall(drawMap, orgDrawMap, DrawMap_RecalculatePositions<radarXPos.size(), 0, radarXPos_RadardiscShrink.size(), radarYPos_RadardiscShrink.size()>);
|
// 2. If CRadar::DrawYouAreHereSprite still points at the same global variable, give it a dedicated one.
|
||||||
|
// Otherwise do nothing, as some other mod (like the wsfix above) may have already done it.
|
||||||
|
// 3. If we can't safely change the radar position because it was relocated, bail out of the fix entirely, just to be safe.
|
||||||
|
// Missing out on a fix is better than breaking something.
|
||||||
|
if (hGameModule == ModCompat::Utils::GetModuleHandleFromAddress(radarPos))
|
||||||
|
{
|
||||||
|
static float fYouAreHereSize;
|
||||||
|
orgRadarXPosVal = fYouAreHereSize = *radarPos;
|
||||||
|
orgRadarXPosPtr = radarPos;
|
||||||
|
|
||||||
|
for (float** val : youAreHereSize)
|
||||||
|
{
|
||||||
|
if (*val == radarPos)
|
||||||
|
{
|
||||||
|
Patch(val, &fYouAreHereSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HookEach_CalculateRadarXPos_RadardiscShrink(radarXPos_RadardiscShrink, PatchFloat);
|
||||||
|
HookEach_CalculateRadarYPos_RadardiscShrink(radarYPos_RadardiscShrink, PatchFloat);
|
||||||
|
HookEach_DrawRadarDisc(spriteDraw, InterceptCall);
|
||||||
|
InterceptCall(drawMap, orgDrawMap, DrawMap_RecalculatePositions<radarXPos_RadardiscShrink.size(), radarYPos_RadardiscShrink.size()>);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue