Compare commits

...

4 commits

Author SHA1 Message Date
Silent
7d055f9264
III/VC: Two more minor scaling fixes
III: The position of the dialog question text in the main menu now
scales to resolution correctly.
VC: The vertical offset of the weapon name text in Ammu-Nation
now scales to resolution correctly.
2024-11-01 19:44:40 +01:00
Silent
fd67cb4064
III/VC: Port the inner text box background padding fix from San Andreas
Fixes #48
2024-11-01 19:00:01 +01:00
Silent
7d1bd8a9ac
Fix warnings 2024-11-01 17:53:46 +01:00
Silent
75a3f16ffb
III/VC: Improve the way RwD3D8Get/SetRenderState is located
Improves compatibility with other mods and provides a safe fallback.

Fixes #65
2024-11-01 17:33:33 +01:00
14 changed files with 363 additions and 9 deletions

View file

@ -48,6 +48,8 @@ All the remaining, non-critical fixes.
* The radar's horizontal position and its disc texture now scale to resolution correctly, resolving color bleed issues at high resolutions.
* Credits now scale to resolution correctly, and they don't cut to an empty screen at the very end anymore.
* Mission title and 'Mission Passed' texts now stay on screen for the same duration, regardless of screen resolution.
* The inner padding of the text boxes with a background now scales to resolution correctly.
* The position of the dialog question text in the main menu now scales to resolution correctly.
* `FILE_FLAG_NO_BUFFERING` flag has been removed from IMG reading functions - speeding up streaming.
* Free resprays will not carry on a New Game now.
* Fixed ambulance and firetruck dispatch timers - they reset on New Game now.

View file

@ -44,6 +44,8 @@ All the remaining, non-critical fixes.
* The radar's horizontal position, the disc texture, and the shadow now scale to resolution correctly. The radar disc was also shrunk slightly to fix gaps and make the icons sit better on the edge.
* Credits now scale to resolution correctly.
* Mission title and 'Mission Passed' texts now stay on screen for the same duration, regardless of screen resolution.
* The inner padding of the text boxes with a background now scales to resolution correctly.
* The vertical offset of the weapon name text in Ammu-Nation now scales to resolution correctly.
* `FILE_FLAG_NO_BUFFERING` flag has been removed from IMG reading functions - speeding up streaming.
* Free resprays will not carry on a New Game now.
* Fixed ambulance and firetruck dispatch timers - they reset on New Game now.

View file

@ -36,6 +36,7 @@ for both first-time players and the old guard returning for yet another playthro
SilentPatch includes code contributions from:
* aap
* B1ack_Wh1te
* DK22Pac
* Fire_Head
* Nick007J

View file

@ -7,6 +7,7 @@
#include "SVF.h"
#include "ParseUtils.hpp"
#include "Random.h"
#include "RWGTA.h"
#include "Utils/DelimStringReader.h"
@ -195,6 +196,8 @@ namespace Common {
using namespace Memory;
using namespace hook::txn;
const bool HasRwD3D8 = RWGTA::Patches::TryLocateRwD3D8();
// Delayed patching
try
{
@ -249,7 +252,7 @@ namespace Common {
// Fixed static shadows not rendering under fire and pickups
try
if (HasRwD3D8) try
{
using namespace StaticShadowAlphaFix;

View file

@ -4,6 +4,7 @@
#define RwEngineInstance (*rwengine)
#include <rwcore.h>
#include "RWGTA.h"
// GTA versions of RenderWare functions/macros for GTA III/Vice City
// since we cannot use RwEngineInstance directly
@ -39,14 +40,16 @@ void** rwengine = []() -> void** {
return nullptr;
}();
static void* varRwD3D8SetRenderState = Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ) );
WRAPPER RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) { VARJMP(varRwD3D8SetRenderState); }
static decltype(::RwD3D8SetRenderState)* fnRwD3D8SetRenderState;
RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value)
{
return fnRwD3D8SetRenderState(state, value);
}
static RwUInt32* _rwD3D8RenderStates = *static_cast<RwUInt32**>(Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ), 8 + 3 ));
static decltype(::RwD3D8GetRenderState)* fnRwD3D8GetRenderState;
void RwD3D8GetRenderState(RwUInt32 state, void* value)
{
RwUInt32* valuePtr = static_cast<RwUInt32*>(value);
*valuePtr = _rwD3D8RenderStates[ 2 * state ];
fnRwD3D8GetRenderState(state, value);
}
RwReal RwIm2DGetNearScreenZ()
@ -65,4 +68,37 @@ RwBool RwRenderStateSet(RwRenderState state, void *value)
}
// Unreachable stub
RwBool RwMatrixDestroy(RwMatrix* mpMat) { assert(!"Unreachable!"); return TRUE; }
RwBool RwMatrixDestroy(RwMatrix* /*mpMat*/) { assert(!"Unreachable!"); return TRUE; }
bool RWGTA::Patches::TryLocateRwD3D8() try
{
using namespace Memory;
using namespace hook::txn;
auto pfnRwD3D8SetRenderState = [] {
try {
// Everything except for III Steam
return static_cast<decltype(RwD3D8SetRenderState)*>(get_pattern("39 0C C5 ? ? ? ? 74 31", -8));
} catch (const hook::txn_exception&) {
// III Steam
return static_cast<decltype(RwD3D8SetRenderState)*>(get_pattern("8B 0C C5 ? ? ? ? 3B CA", -8));
}
}();
auto pfnRwD3D8GetRenderState = [] {
try {
// Everything except for III Steam
return static_cast<decltype(RwD3D8GetRenderState)*>(get_pattern("8B 0C C5 ? ? ? ? 89 0A C3", -8));
} catch (const hook::txn_exception&) {
// III Steam
return static_cast<decltype(RwD3D8GetRenderState)*>(get_pattern("8B 04 C5 ? ? ? ? 89 02 C3", -8));
}
}();
fnRwD3D8SetRenderState = pfnRwD3D8SetRenderState;
fnRwD3D8GetRenderState = pfnRwD3D8GetRenderState;
return true;
}
catch (const hook::txn_exception&)
{
return false;
}

6
SilentPatch/RWGTA.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
namespace RWGTA::Patches
{
bool TryLocateRwD3D8();
}

View file

@ -1099,6 +1099,84 @@ namespace BrakelightsDummy
}
}
// ============= Fix text background padding not scaling to resolution =============
namespace TextRectPaddingScalingFixes
{
template<std::size_t Index>
static const float* orgPaddingXSize;
template<std::size_t Index>
static float PaddingXSize_Recalculated;
template<std::size_t... I>
static void RecalculateXSize(std::index_sequence<I...>)
{
const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth;
((PaddingXSize_Recalculated<I> = *orgPaddingXSize<I> * multiplier), ...);
}
template<std::size_t Index>
static const float* orgPaddingYSize;
template<std::size_t Index>
static float PaddingYSize_Recalculated;
template<std::size_t... I>
static void RecalculateYSize(std::index_sequence<I...>)
{
const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight;
((PaddingYSize_Recalculated<I> = *orgPaddingYSize<I> * multiplier), ...);
}
static void (*orgGetTextRect)(CRect*, float, float, void*);
template<std::size_t NumXPadding, std::size_t NumYPadding>
static void GetTextRect_Recalculate(CRect* a1, float a2, float a3, void* a4)
{
RecalculateXSize(std::make_index_sequence<NumXPadding>{});
RecalculateYSize(std::make_index_sequence<NumYPadding>{});
orgGetTextRect(a1, a2, a3, a4);
}
HOOK_EACH_INIT(PaddingXSize, orgPaddingXSize, PaddingXSize_Recalculated);
HOOK_EACH_INIT(PaddingYSize, orgPaddingYSize, PaddingYSize_Recalculated);
template<std::size_t Index>
static const float* orgWrapX;
template<std::size_t Index>
static float WrapX_Recalculated;
template<std::size_t... I>
static void RecalculateWrapX(std::index_sequence<I...>)
{
const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth;
((WrapX_Recalculated<I> = *orgWrapX<I> * multiplier), ...);
}
static void (*orgSetJustifyOff)();
template<std::size_t NumXWrap>
static void SetJustifyOff_Recalculate()
{
RecalculateWrapX(std::make_index_sequence<NumXWrap>{});
orgSetJustifyOff();
}
HOOK_EACH_INIT(WrapX, orgWrapX, WrapX_Recalculated);
}
// ============= Fix menu texts not scaling to resolution =============
namespace MenuManagerScalingFixes
{
static void (*orgPrintString)(float,float,const wchar_t*);
static void PrintString_Scale(float fX, float fY, const wchar_t* pText)
{
orgPrintString(fX * GetWidthMult() * RsGlobal->MaximumWidth, fY * GetHeightMult() * RsGlobal->MaximumHeight, pText);
}
}
namespace ModelIndicesReadyHook
{
static void (*orgInitialiseObjectData)(const char*);
@ -1493,6 +1571,65 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
}
TXN_CATCH();
// Fix text background padding not scaling to resolution
try
{
using namespace TextRectPaddingScalingFixes;
auto getTextRect = get_pattern("FF 74 24 54 FF 74 24 54 50 E8 ? ? ? ? 83 C4 10", 9);
auto rectWidth1 = pattern("D8 25 ? ? ? ? D9 18 89 54 24 18 8B 44 24 34 DB 44 24 18 D8 44 24 38 D8 05").get_one();
auto rectWidth2 = pattern("D8 25 ? ? ? ? D9 18 D9 05 ? ? ? ? D8 0D ? ? ? ? 8B 44 24 34 D8 44 24 38 D8 05").get_one();
auto rectWidth3 = get_pattern<float*>("D8 25 ? ? ? ? 8B 44 24 34 D9 18", 2);
auto rectHeight1 = pattern("D8 05 ? ? ? ? D9 58 04 D9 44 24 3C D8 25").count(2);
auto rectHeight2 = pattern("D9 05 ? ? ? ? D8 44 24 3C DE C1 D8 05").get_one();
// SetWrapx on the help boxes includes an unscaled -4.0f probably to work together with this padding,
// so treat it as part of the same fix
auto setJustifyOff_helpBox = get_pattern("59 E8 ? ? ? ? D9 EE", 1);
std::array<float**, 5> paddingXSizes = {
rectWidth1.get<float*>(2),
rectWidth1.get<float*>(0x18 + 2),
rectWidth2.get<float*>(2),
rectWidth2.get<float*>(0x1C + 2),
rectWidth3
};
std::array<float**, 6> paddingYSizes = {
rectHeight1.get(0).get<float*>(2),
rectHeight1.get(0).get<float*>(0xD + 2),
rectHeight1.get(1).get<float*>(2),
rectHeight1.get(1).get<float*>(0xD + 2),
rectHeight2.get<float*>(2),
rectHeight2.get<float*>(0xC + 2),
};
std::array<float**, 1> wrapxWidth = {
get_pattern<float*>("D8 25 ? ? ? ? D9 1C 24 DD D8", 2),
};
HookEach_PaddingXSize(paddingXSizes, PatchFloat);
HookEach_PaddingYSize(paddingYSizes, PatchFloat);
InterceptCall(getTextRect, orgGetTextRect, GetTextRect_Recalculate<paddingXSizes.size(), paddingYSizes.size()>);
HookEach_WrapX(wrapxWidth, PatchFloat);
InterceptCall(setJustifyOff_helpBox, orgSetJustifyOff, SetJustifyOff_Recalculate<wrapxWidth.size()>);
}
TXN_CATCH();
// ============= Fix menu texts not scaling to resolution =============
try
{
using namespace MenuManagerScalingFixes;
auto printStringMenuText = get_pattern("E8 ? ? ? ? 83 C4 0C DB 05 ? ? ? ? 50");
InterceptCall(printStringMenuText, orgPrintString, PrintString_Scale);
}
TXN_CATCH();
FLAUtils::Init(moduleList);
}

View file

@ -73,6 +73,7 @@
<ClInclude Include="..\SilentPatch\Maths.h" />
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
<ClInclude Include="..\SilentPatch\Random.h" />
<ClInclude Include="..\SilentPatch\RWGTA.h" />
<ClInclude Include="..\SilentPatch\StdAfx.h" />
<ClInclude Include="..\SilentPatch\StoredCar.h" />
<ClInclude Include="..\SilentPatch\SVF.h" />

View file

@ -113,6 +113,9 @@
<ClInclude Include="..\SilentPatch\Random.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\RWGTA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">

View file

@ -6,7 +6,7 @@
<SILENTPATCH_EXT>.asi</SILENTPATCH_EXT>
<SILENTPATCH_FULL_NAME>SilentPatch for GTA III</SILENTPATCH_FULL_NAME>
<SILENTPATCH_REVISION_ID>9</SILENTPATCH_REVISION_ID>
<SILENTPATCH_BUILD_ID>0</SILENTPATCH_BUILD_ID>
<SILENTPATCH_BUILD_ID>1</SILENTPATCH_BUILD_ID>
<SILENTPATCH_COPYRIGHT>2013-2024</SILENTPATCH_COPYRIGHT>
</PropertyGroup>
<PropertyGroup />

View file

@ -553,6 +553,101 @@ namespace MinimalHUD
}
// ============= Fix text background padding not scaling to resolution =============
namespace TextRectPaddingScalingFixes
{
template<std::size_t Index>
static const float* orgPaddingXSize;
template<std::size_t Index>
static float PaddingXSize_Recalculated;
template<std::size_t... I>
static void RecalculateXSize(std::index_sequence<I...>)
{
const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth;
((PaddingXSize_Recalculated<I> = *orgPaddingXSize<I> * multiplier), ...);
}
template<std::size_t Index>
static const float* orgPaddingYSize;
template<std::size_t Index>
static float PaddingYSize_Recalculated;
template<std::size_t... I>
static void RecalculateYSize(std::index_sequence<I...>)
{
const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight;
((PaddingYSize_Recalculated<I> = *orgPaddingYSize<I> * multiplier), ...);
}
static void (*orgGetTextRect)(CRect*, float, float, void*);
template<std::size_t NumXPadding, std::size_t NumYPadding>
static void GetTextRect_Recalculate(CRect* a1, float a2, float a3, void* a4)
{
RecalculateXSize(std::make_index_sequence<NumXPadding>{});
RecalculateYSize(std::make_index_sequence<NumYPadding>{});
orgGetTextRect(a1, a2, a3, a4);
}
HOOK_EACH_INIT(PaddingXSize, orgPaddingXSize, PaddingXSize_Recalculated);
HOOK_EACH_INIT(PaddingYSize, orgPaddingYSize, PaddingYSize_Recalculated);
template<std::size_t Index>
static const float* orgWrapX;
template<std::size_t Index>
static float WrapX_Recalculated;
template<std::size_t... I>
static void RecalculateWrapX(std::index_sequence<I...>)
{
const float multiplier = GetWidthMult() * RsGlobal->MaximumWidth;
((WrapX_Recalculated<I> = *orgWrapX<I> * multiplier), ...);
}
static void (*orgSetJustifyOff)();
template<std::size_t NumXWrap>
static void SetJustifyOff_Recalculate()
{
RecalculateWrapX(std::make_index_sequence<NumXWrap>{});
orgSetJustifyOff();
}
HOOK_EACH_INIT(WrapX, orgWrapX, WrapX_Recalculated);
}
// ============= Fix ammunation text (big message type 3) Y position offset not scaling to resolution =============
namespace BigMessage3ScalingFixes
{
template<std::size_t Index>
static const float* orgOffsetY;
template<std::size_t Index>
static float OffsetY_Recalculated;
template<std::size_t... I>
static void RecalculateYOffset(std::index_sequence<I...>)
{
const float multiplier = GetHeightMult() * RsGlobal->MaximumHeight;
((OffsetY_Recalculated<I> = *orgOffsetY<I> * multiplier), ...);
}
static void (*orgSetDropColor)(const CRGBA&);
template<std::size_t NumXOffsets>
static void SetDropColor_Scale(const CRGBA& color)
{
RecalculateYOffset(std::make_index_sequence<NumXOffsets>{});
orgSetDropColor(color);
}
HOOK_EACH_INIT(MessageYOffset, orgOffsetY, OffsetY_Recalculated);
}
float FixedRefValue()
{
return 1.0f;
@ -1908,6 +2003,70 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
}
TXN_CATCH();
// Fix text background padding not scaling to resolution
try
{
using namespace TextRectPaddingScalingFixes;
auto getTextRect = get_pattern("FF 74 24 54 FF 74 24 54 50 E8 ? ? ? ? 83 C4 10", 9);
auto rectWidth1 = pattern("D8 25 ? ? ? ? D9 1E D9 44 24 38 D8 05 ? ? ? ? D8 05").get_one();
auto rectWidth2 = pattern("D8 25 ? ? ? ? D9 1E D9 05 ? ? ? ? D8 0D ? ? ? ? D8 44 24 38 D8 05").get_one();
auto rectWidth3 = get_pattern<float*>("D8 25 ? ? ? ? 0F BF C5 D9 1E", 2);
auto rectHeight1 = pattern("D8 05 ? ? ? ? D9 5E 04 D9 44 24 3C D8 25").count(2);
auto rectHeight2 = pattern("D9 05 ? ? ? ? D8 44 24 3C DE C1 D8 05").get_one();
// SetWrapx on the help boxes includes an unscaled -4.0f probably to work together with this padding,
// so treat it as part of the same fix
auto setJustifyOff_helpBox = get_pattern("59 E8 ? ? ? ? D9 EE", 1);
std::array<float**, 5> paddingXSizes = {
rectWidth1.get<float*>(2),
rectWidth1.get<float*>(0x12 + 2),
rectWidth2.get<float*>(2),
rectWidth2.get<float*>(0x18 + 2),
rectWidth3
};
std::array<float**, 6> paddingYSizes = {
rectHeight1.get(0).get<float*>(2),
rectHeight1.get(0).get<float*>(0xD + 2),
rectHeight1.get(1).get<float*>(2),
rectHeight1.get(1).get<float*>(0xD + 2),
rectHeight2.get<float*>(2),
rectHeight2.get<float*>(0xC + 2),
};
std::array<float**, 1> wrapxWidth = {
get_pattern<float*>("D8 25 ? ? ? ? D9 1C 24 DD D8", 2),
};
HookEach_PaddingXSize(paddingXSizes, PatchFloat);
HookEach_PaddingYSize(paddingYSizes, PatchFloat);
InterceptCall(getTextRect, orgGetTextRect, GetTextRect_Recalculate<paddingXSizes.size(), paddingYSizes.size()>);
HookEach_WrapX(wrapxWidth, PatchFloat);
InterceptCall(setJustifyOff_helpBox, orgSetJustifyOff, SetJustifyOff_Recalculate<wrapxWidth.size()>);
}
TXN_CATCH();
// Fix ammunation text (big message type 3) Y position offset not scaling to resolution
try
{
using namespace BigMessage3ScalingFixes;
auto setDropColor = get_pattern("E8 ? ? ? ? 59 8D 4C 24 40");
std::array<float**, 1> YOffset = {
get_pattern<float*>("D8 25 ? ? ? ? D9 1C 24 A1", 2),
};
HookEach_MessageYOffset(YOffset, PatchFloat);
InterceptCall(setDropColor, orgSetDropColor, SetDropColor_Scale<YOffset.size()>);
}
TXN_CATCH();
FLAUtils::Init(moduleList);
}

View file

@ -166,6 +166,7 @@
<ClInclude Include="..\SilentPatch\Maths.h" />
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
<ClInclude Include="..\SilentPatch\Random.h" />
<ClInclude Include="..\SilentPatch\RWGTA.h" />
<ClInclude Include="..\SilentPatch\RWUtils.hpp" />
<ClInclude Include="..\SilentPatch\StdAfx.h" />
<ClInclude Include="..\SilentPatch\StoredCar.h" />

View file

@ -75,6 +75,9 @@
<ClInclude Include="EntityVC.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\RWGTA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\SilentPatch\Timer.cpp">

View file

@ -6,7 +6,7 @@
<SILENTPATCH_EXT>.asi</SILENTPATCH_EXT>
<SILENTPATCH_FULL_NAME>SilentPatch for Vice City</SILENTPATCH_FULL_NAME>
<SILENTPATCH_REVISION_ID>11</SILENTPATCH_REVISION_ID>
<SILENTPATCH_BUILD_ID>0</SILENTPATCH_BUILD_ID>
<SILENTPATCH_BUILD_ID>1</SILENTPATCH_BUILD_ID>
<SILENTPATCH_COPYRIGHT>2013-2024</SILENTPATCH_COPYRIGHT>
</PropertyGroup>
<PropertyGroup />