Compare commits

..

20 commits

Author SHA1 Message Date
Echo J.
f53acc255b
Merge c6885c4d03 into 2a597da1bc 2024-11-29 11:27:52 +01:00
Echo J
c6885c4d03 SilentPatchVC: Add GCC-style inline assembly statements
This also includes a small wrapper to call a C++ function from GCC-style inline ASM

These statements almost work on llvm-mingw too (but there's some stubborn call instructions)
2024-11-29 12:20:52 +02:00
Echo J
c2e58d36e8 SilentPatchIII: Add GCC-style inline assembly statements
These almost work on llvm-mingw too (but there's some stubborn call instructions)
2024-11-29 12:20:52 +02:00
Echo J
d6f3ea8b0a SilentPatchIII: Add a missing functional header include
MinGW GCC doesn't implicitly include it either
2024-11-29 12:20:52 +02:00
Echo J
1b174a3724 SilentPatch: Add missing cmath header include
It's required for the modf() function (and it isn't implicitly
included on MinGW GCC)
2024-11-29 12:20:52 +02:00
Echo J
d3e5495666 SilentPatch: Move a header include in SVF
This makes sure the fixed-width integer types are included in SVF.h
2024-11-29 12:20:52 +02:00
Echo J
50b1c1353d SilentPatch: Define a replacement for _stricmp() on non-MSVC
MinGW GCC doesn't have this MSVC-specific function
2024-11-29 12:20:52 +02:00
Echo J
77f5e908c0 SilentPatch: Move RwEngineInstance definition to headers
MinGW GCC can't locate it in some files otherwise
2024-11-29 12:20:52 +02:00
Echo J
4ba23dbf75 SilentPatch: Simplify RwIm2DRenderLine function pointer declaration
MinGW GCC doesn't seem to unwind the layers of the macro define
properly (which causes it to not find the declaration type)
2024-11-29 12:20:52 +02:00
Echo J
80b4fa1ece SilentPatch: Don't define certain Rw* functions if not needed
Redefining them can cause strange compile errors with MinGW GCC
2024-11-29 12:20:52 +02:00
Echo J
acc4af21bd DDraw: Cast the memcpy() source argument
This works around the MinGW GCC type strictness
2024-11-29 12:20:49 +02:00
Echo J
940c68983d DDraw: Use a pragma for DirectDrawCreateEx export on MSVC
The .def file is either going to have issues on MSVC or MinGW GCC
(so replace it with a pragma on MSVC)
2024-11-29 12:19:33 +02:00
Echo J
1af97eef26 SilentPatchIII/VC/SA: Mark some function pointers as inline
MinGW GCC's linker can't find them otherwise
2024-11-29 12:19:27 +02:00
Echo J
04f74335c1 SilentPatchIII/VC: Remove extern from ppUserFilesDir variable definitions
This fixes compile warnings with MinGW GCC
2024-11-29 12:17:46 +02:00
Echo J
58905270bc SilentPatchIII/VC/SA: Add GCC/Clang-compatible safebuffers equivalent
And switch to a common define for this attribute (this fixes
compile warnings on MinGW GCC)
2024-11-29 12:17:46 +02:00
Echo J
b5483bbf59 Use reinterpret_cast for function pointer casts
MSVC (wrongly) allows those casts to succeed with static_cast:
https://stackoverflow.com/questions/74002657/why-cant-i-static-cast-a-void-to-a-pointer-to-function
(so adjust those casts for better compiler compatibility including MinGW GCC)
2024-11-29 12:17:46 +02:00
Echo J
fe6f98c314 Set Windows defines earlier
This avoids compile warnings on MinGW GCC (because standard C++
headers eventually import the Windows stuff)
2024-11-29 12:17:46 +02:00
Echo J
c15fbc549d Use lowercase names for Windows headers
This fixes missing header issues on a case-sensitive filesystem
with MinGW GCC
2024-11-29 12:17:46 +02:00
Echo J
f33f5c131b Remove unused dllmain.cpp file
It seems to be used in the early days of SilentPatch (but it's
no longer included since the III/VC/SA code split and serves no purpose)
2024-11-29 12:17:46 +02:00
Silent
2a597da1bc
III: Backport one more fix from VC to fix the timer initialize lingering the audio entities on New Game
Fixes #123
2024-11-28 20:41:17 +01:00
7 changed files with 44 additions and 16 deletions

View file

@ -197,9 +197,11 @@ static bool PatchIAT()
static bool PatchIAT_ByPointers() static bool PatchIAT_ByPointers()
{ {
using namespace Memory::VP;
pOrgSystemParametersInfoA = SystemParametersInfoA; pOrgSystemParametersInfoA = SystemParametersInfoA;
memcpy( orgCode, reinterpret_cast<void*>(pOrgSystemParametersInfoA), sizeof(orgCode) ); memcpy( orgCode, reinterpret_cast<void*>(pOrgSystemParametersInfoA), sizeof(orgCode) );
Memory::VP::InjectHook( pOrgSystemParametersInfoA, SystemParametersInfoA_OverwritingHook, Memory::HookType::Jump ); InjectHook( pOrgSystemParametersInfoA, SystemParametersInfoA_OverwritingHook, HookType::Jump );
return true; return true;
} }

View file

@ -6,7 +6,7 @@
<SILENTPATCH_EXT>.dll</SILENTPATCH_EXT> <SILENTPATCH_EXT>.dll</SILENTPATCH_EXT>
<SILENTPATCH_FULL_NAME>SilentPatch DDraw Component</SILENTPATCH_FULL_NAME> <SILENTPATCH_FULL_NAME>SilentPatch DDraw Component</SILENTPATCH_FULL_NAME>
<SILENTPATCH_REVISION_ID>6</SILENTPATCH_REVISION_ID> <SILENTPATCH_REVISION_ID>6</SILENTPATCH_REVISION_ID>
<SILENTPATCH_BUILD_ID>0</SILENTPATCH_BUILD_ID> <SILENTPATCH_BUILD_ID>1</SILENTPATCH_BUILD_ID>
<SILENTPATCH_COPYRIGHT>2014-2024</SILENTPATCH_COPYRIGHT> <SILENTPATCH_COPYRIGHT>2014-2024</SILENTPATCH_COPYRIGHT>
</PropertyGroup> </PropertyGroup>
<PropertyGroup /> <PropertyGroup />

@ -1 +1 @@
Subproject commit 95e523fa7494c0353b7ecfab408024a9d7b7e161 Subproject commit 70cab494523e76d56063b5044c34345c14803c96

View file

@ -918,7 +918,7 @@ namespace DodoKeyboardControls
// ============= Resetting stats and variables on New Game ============= // ============= Resetting stats and variables on New Game =============
namespace VariableResets namespace VariableResets
{ {
static auto TimerInitialise = reinterpret_cast<void(*)()>(hook::get_pattern("83 E4 F8 68 ? ? ? ? E8", -6)); static void (*TimerInitialise)();
using VarVariant = std::variant< bool*, int* >; using VarVariant = std::variant< bool*, int* >;
std::vector<VarVariant> GameVariablesToReset; std::vector<VarVariant> GameVariablesToReset;
@ -932,8 +932,6 @@ namespace VariableResets
}, var ); }, var );
} }
// Functions that should have been called by the game but aren't...
TimerInitialise();
PurpleNinesGlitchFix(); PurpleNinesGlitchFix();
} }
@ -953,8 +951,22 @@ namespace VariableResets
void GameInitialise(const char* path) void GameInitialise(const char* path)
{ {
ReInitOurVariables(); ReInitOurVariables();
TimerInitialise();
orgGameInitialise(path); orgGameInitialise(path);
} }
static void (__fastcall* DestroyAllGameCreatedEntities)(void* DMAudio);
template<std::size_t Index>
static void (__fastcall* orgService)(void* DMAudio);
template<std::size_t Index>
static void __fastcall Service_AndDestroyEntities(void* DMAudio)
{
DestroyAllGameCreatedEntities(DMAudio);
orgService<Index>(DMAudio);
}
HOOK_EACH_INIT(Service, orgService, Service_AndDestroyEntities);
} }
@ -2581,8 +2593,22 @@ void Patch_III_Common()
get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7) get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7)
}; };
TimerInitialise = reinterpret_cast<decltype(TimerInitialise)>(get_pattern("83 E4 F8 68 ? ? ? ? E8", -6));
// In GTA III, we also need to backport one more fix from VC to avoid issues with looping audio entities:
// CMenuManager::DoSettingsBeforeStartingAGame needs to call cDMAudio::DestroyAllGameCreatedEntities
DestroyAllGameCreatedEntities = reinterpret_cast<decltype(DestroyAllGameCreatedEntities)>(ReadCallFrom(
get_pattern("B9 ? ? ? ? E8 ? ? ? ? 31 DB BD ? ? ? ? 8D 40 00", 5)));
auto audio_service = pattern("B9 ? ? ? ? E8 ? ? ? ? B9 ? ? ? ? C6 05 ? ? ? ? ? E8").count(2);
std::array<void*, 2> audio_service_instances = {
audio_service.get(0).get<void>(5),
audio_service.get(1).get<void>(5),
};
InterceptCall(game_initialise, orgGameInitialise, GameInitialise); InterceptCall(game_initialise, orgGameInitialise, GameInitialise);
HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall); HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall);
HookEach_Service(audio_service_instances, InterceptCall);
// Variables to reset // Variables to reset
GameVariablesToReset.emplace_back(*get_pattern<bool*>("80 3D ? ? ? ? ? 74 2A", 2)); // Free resprays GameVariablesToReset.emplace_back(*get_pattern<bool*>("80 3D ? ? ? ? ? 74 2A", 2)); // Free resprays

View file

@ -302,7 +302,7 @@ public:
private: private:
template<std::size_t Index> template<std::size_t Index>
static void (CVehicle::*orgDoHeadLightBeam)(int type, CMatrix& m, bool right); STATIC_INLINE void (CVehicle::*orgDoHeadLightBeam)(int type, CMatrix& m, bool right);
template<std::size_t Index> template<std::size_t Index>
void DoHeadLightBeam_LightBeamFixSaveObj(int type, CMatrix& m, bool right) void DoHeadLightBeam_LightBeamFixSaveObj(int type, CMatrix& m, bool right)
@ -337,7 +337,7 @@ public:
public: public:
template<std::size_t Index> template<std::size_t Index>
static void (CAutomobile::*orgAutomobilePreRender)(); STATIC_INLINE void (CAutomobile::*orgAutomobilePreRender)();
template<std::size_t Index> template<std::size_t Index>
void PreRender_SilentPatch() void PreRender_SilentPatch()
@ -352,7 +352,7 @@ public:
void HideDestroyedWheels_SilentPatch(void (CAutomobile::*spawnFlyingComponentCB)(int, unsigned int), int nodeID, unsigned int modelID); void HideDestroyedWheels_SilentPatch(void (CAutomobile::*spawnFlyingComponentCB)(int, unsigned int), int nodeID, unsigned int modelID);
template<std::size_t Index> template<std::size_t Index>
static void (CAutomobile::*orgSpawnFlyingComponent)(int, unsigned int); STATIC_INLINE void (CAutomobile::*orgSpawnFlyingComponent)(int, unsigned int);
template<std::size_t Index> template<std::size_t Index>
void SpawnFlyingComponent_HideWheels(int nodeID, unsigned int modelID) void SpawnFlyingComponent_HideWheels(int nodeID, unsigned int modelID)
@ -448,7 +448,7 @@ private:
private: private:
template<std::size_t Index> template<std::size_t Index>
static CVehicle* (CStoredCar::*orgRestoreCar)(); STATIC_INLINE CVehicle* (CStoredCar::*orgRestoreCar)();
template<std::size_t Index> template<std::size_t Index>
CVehicle* RestoreCar_SilentPatch() CVehicle* RestoreCar_SilentPatch()
@ -477,4 +477,4 @@ static_assert(sizeof(CVehicle) == 0x5A0, "Wrong size: CVehicle");
static_assert(sizeof(CAutomobile) == 0x988, "Wrong size: CAutomobile"); static_assert(sizeof(CAutomobile) == 0x988, "Wrong size: CAutomobile");
static_assert(sizeof(CStoredCar) == 0x40, "Wrong size: CStoredCar"); static_assert(sizeof(CStoredCar) == 0x40, "Wrong size: CStoredCar");
#endif #endif

View file

@ -1282,7 +1282,7 @@ namespace IsPlayerTargettingCharFix
// ============= Resetting stats and variables on New Game ============= // ============= Resetting stats and variables on New Game =============
namespace VariableResets namespace VariableResets
{ {
static auto TimerInitialise = reinterpret_cast<void(*)()>(hook::get_pattern("83 E4 F8 68 ? ? ? ? E8", -6)); static void (*TimerInitialise)();
using VarVariant = std::variant< bool*, int* >; using VarVariant = std::variant< bool*, int* >;
std::vector<VarVariant> GameVariablesToReset; std::vector<VarVariant> GameVariablesToReset;
@ -1295,9 +1295,6 @@ namespace VariableResets
*v = {}; *v = {};
}, var ); }, var );
} }
// Functions that should have been called by the game but aren't...
TimerInitialise();
} }
template<std::size_t Index> template<std::size_t Index>
@ -1316,6 +1313,7 @@ namespace VariableResets
void GameInitialise(const char* path) void GameInitialise(const char* path)
{ {
ReInitOurVariables(); ReInitOurVariables();
TimerInitialise();
orgGameInitialise(path); orgGameInitialise(path);
} }
} }
@ -2970,6 +2968,8 @@ void Patch_VC_Common()
get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7) get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7)
}; };
TimerInitialise = reinterpret_cast<decltype(TimerInitialise)>(get_pattern("83 E4 F8 68 ? ? ? ? E8", -6));
InterceptCall(game_initialise, orgGameInitialise, GameInitialise); InterceptCall(game_initialise, orgGameInitialise, GameInitialise);
HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall); HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall);

View file

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