From 135ceed86c2651625ad548efa4200ad93403c264 Mon Sep 17 00:00:00 2001 From: Echo J Date: Mon, 4 Nov 2024 17:14:10 +0200 Subject: [PATCH] SilentPatchIII: Add GCC/Clang-specific inline assembly statements This also matches the MSVC statements more closely to the GCC/Clang ones --- SilentPatchIII/SilentPatchIII.cpp | 289 ++++++++++++++++++++++++++---- 1 file changed, 258 insertions(+), 31 deletions(-) diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 97b303d..acdbac6 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -196,36 +196,70 @@ void ResetMousePos() void __declspec(naked) M16StatsFix() { +#ifdef _MSC_VER _asm { - add eax, 34h - add ebx, 34h + add eax, 0x34 + add ebx, 0x34 mov ecx, [InstantHitsFiredByPlayer] - inc [ecx] - retn + inc dword ptr [ecx] + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "add eax, 0x34\n" + "add ebx, 0x34\n" + "mov ecx, [%[InstantHitsFiredByPlayer]]\n" + "inc dword ptr [ecx]\n" + "ret\n" + :: [InstantHitsFiredByPlayer] "m" (InstantHitsFiredByPlayer) + ); +#endif } void __declspec(naked) HeadlightsFix() { static const float fMinusOne = -1.0f; +#ifdef _MSC_VER _asm { - fld [esp+708h-690h] + fld dword ptr [esp+0x708-0x690] fcomp fMinusOne fnstsw ax and ah, 5 cmp ah, 1 jnz HeadlightsFix_DontLimit fld fMinusOne - fstp [esp+708h-690h] + fstp dword ptr [esp+0x708-0x690] HeadlightsFix_DontLimit: - fld [esp+708h-690h] + fld dword ptr [esp+0x708-0x690] fabs fld st jmp [HeadlightsFix_JumpBack] } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "fld dword ptr [esp+0x708-0x690]\n" + "fcomp %[fMinusOne]\n" + "fnstsw ax\n" + "and ah, 5\n" + "cmp ah, 1\n" + "jnz HeadlightsFix_DontLimit\n" + "fld %0\n" + "fstp dword ptr [esp+0x708-0x690]\n" + +"HeadlightsFix_DontLimit:\n" + "fld dword ptr [esp+0x708-0x690]\n" + "fabs\n" + "fld st\n" + "jmp [%[HeadlightsFix_JumpBack]]\n" + :: [fMinusOne] "m" (fMinusOne), + [HeadlightsFix_JumpBack] "m" (HeadlightsFix_JumpBack) + ); +#endif } static float fShadowXSize, fShadowYSize; @@ -314,35 +348,64 @@ float FixedRefValue() void __declspec(naked) SubtitlesShadowFix() { +#ifdef _MSC_VER _asm { push eax call Recalculate - fadd [esp+50h+8] + fadd dword ptr [esp+0x50+8] fadd [fShadowYSize] jmp SubtitlesShadowFix_JumpBack } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "push eax\n" + "call %[Recalculate]\n" + "fadd dword ptr [esp+0x50+8]\n" + "fadd [%[fShadowYSize]]\n" + "jmp %[SubtitlesShadowFix_JumpBack]\n" + :: [Recalculate] "i" (Recalculate), + [fShadowYSize] "m" (fShadowYSize), + [SubtitlesShadowFix_JumpBack] "m" (SubtitlesShadowFix_JumpBack) + ); +#endif } void __declspec(naked) III_SensResetFix() { +#ifdef _MSC_VER _asm { - mov ecx, 3A76h + mov ecx, 0x3A76 mov edi, ebp - fld dword ptr [ebp+194h] - fld dword ptr [ebp+198h] + fld dword ptr [ebp+0x194] + fld dword ptr [ebp+0x198] rep stosd - fstp dword ptr [ebp+198h] - fstp dword ptr [ebp+194h] - retn + fstp dword ptr [ebp+0x198] + fstp dword ptr [ebp+0x194] + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov ecx, 0x3A76\n" + "mov edi, ebp\n" + "fld dword ptr [ebp+0x194]\n" + "fld dword ptr [ebp+0x198]\n" + "rep stosd\n" + "fstp dword ptr [ebp+0x198]\n" + "fstp dword ptr [ebp+0x194]\n" + "ret\n" + ); +#endif } static void* RadarBoundsCheckCoordBlip_JumpBack = AddressByVersion(0x4A55B8, 0x4A56A8, 0x4A5638); static void* RadarBoundsCheckCoordBlip_Count = AddressByVersion(0x4A55AF, 0x4A569F, 0x4A562F); void __declspec(naked) RadarBoundsCheckCoordBlip() { +#ifdef _MSC_VER _asm { mov edx, dword ptr [RadarBoundsCheckCoordBlip_Count] @@ -355,13 +418,32 @@ void __declspec(naked) RadarBoundsCheckCoordBlip() OutOfBounds: or eax, -1 fcompp - retn + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov edx, dword ptr [%[RadarBoundsCheckCoordBlip_Count]]\n" + "cmp cl, byte ptr [edx]\n" + "jnb OutOfBounds\n" + "mov edx, ecx\n" + "mov eax, [esp+4]\n" + "jmp %[RadarBoundsCheckCoordBlip_JumpBack]\n" + +"OutOfBounds:\n" + "or eax, -1\n" + "fcompp\n" + "ret\n" + :: [RadarBoundsCheckCoordBlip_Count] "m" (RadarBoundsCheckCoordBlip_Count), + [RadarBoundsCheckCoordBlip_JumpBack] "m" (RadarBoundsCheckCoordBlip_JumpBack) + ); +#endif } static void* RadarBoundsCheckEntityBlip_JumpBack = AddressByVersion(0x4A565E, 0x4A574E, 0x4A56DE); void __declspec(naked) RadarBoundsCheckEntityBlip() { +#ifdef _MSC_VER _asm { mov edx, dword ptr [RadarBoundsCheckCoordBlip_Count] @@ -373,8 +455,25 @@ void __declspec(naked) RadarBoundsCheckEntityBlip() OutOfBounds: or eax, -1 - retn + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov edx, dword ptr [%[RadarBoundsCheckCoordBlip_Count]]\n" + "cmp cl, byte ptr [edx]\n" + "jnb OutOfBounds2\n" + "mov edx, ecx\n" + "mov eax, [esp+4]\n" + "jmp %[RadarBoundsCheckEntityBlip_JumpBack]\n" + + "OutOfBounds2:\n" + "or eax, -1\n" + "ret\n" + :: [RadarBoundsCheckCoordBlip_Count] "m" (RadarBoundsCheckCoordBlip_Count), + [RadarBoundsCheckEntityBlip_JumpBack] "m" (RadarBoundsCheckEntityBlip_JumpBack) + ); +#endif } char** ppUserFilesDir = AddressByVersion(0x580C16, 0x580F66, 0x580E66); @@ -413,9 +512,10 @@ unsigned int __cdecl AutoPilotTimerCalculation_III(unsigned int nTimer, int nSca void __declspec(naked) AutoPilotTimerFix_III() { +#ifdef _MSC_VER _asm { - push dword ptr[esp + 0x4] - push dword ptr[ebx + 0x10] + push dword ptr [esp + 0x4] + push dword ptr [ebx + 0x10] push eax call AutoPilotTimerCalculation_III add esp, 0xC @@ -424,8 +524,25 @@ void __declspec(naked) AutoPilotTimerFix_III() pop ebp pop esi pop ebx - retn 4 + ret 4 } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "push dword ptr [esp + 0x4]\n" + "push dword ptr [ebx + 0x10]\n" + "push eax\n" + "call %[AutoPilotTimerCalculation_III]\n" + "add esp, 0xC\n" + "mov [ebx + 0xC], eax\n" + "add esp, 0x28\n" + "pop ebp\n" + "pop esi\n" + "pop ebx\n" + "ret 4\n" + :: [AutoPilotTimerCalculation_III] "i" (AutoPilotTimerCalculation_III) + ); +#endif } namespace ZeroAmmoFix @@ -580,19 +697,35 @@ namespace RemoveDriverStatusFix { // if (m_nStatus != STATUS_WRECKED) // m_nStatus = STATUS_ABANDONED; +#ifdef _MSC_VER _asm { - mov ah, [ecx+50h] + mov ah, [ecx+0x50] mov al, ah - and ah, 0F8h - cmp ah, 28h + and ah, 0xF8 + cmp ah, 0x28 je DontSetStatus and al, 7 - or al, 20h + or al, 0x20 DontSetStatus: - retn + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov ah, [ecx+0x50]\n" + "mov al, ah\n" + "and ah, 0xF8\n" + "cmp ah, 0x28\n" + "je DontSetStatus\n" + "and al, 7\n" + "or al, 0x20\n" + + "DontSetStatus:\n" + "ret\n" + ); +#endif } } @@ -625,16 +758,30 @@ namespace EvasiveDiveFix __declspec(naked) void CalculateAngle_Hook() { +#ifdef _MSC_VER _asm { - push dword ptr [esi+7Ch] - push dword ptr [esi+78h] + push dword ptr [esi+0x7C] + push dword ptr [esi+0x78] call CalculateAngle add esp, 8 mov ecx, ebp - retn + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "push dword ptr [esi+0x7C]\n" + "push dword ptr [esi+0x78]\n" + "call %[CalculateAngle]\n" + "add esp, 8\n" + + "mov ecx, ebp\n" + "ret\n" + :: [CalculateAngle] "i" (CalculateAngle) + ); +#endif } } @@ -647,36 +794,69 @@ namespace NullTerminatedLines static void* orgSscanf_LoadPath; __declspec(naked) static void sscanf1_LoadPath_Terminate() { +#ifdef _MSC_VER _asm { mov eax, [esp+4] mov byte ptr [eax+ecx], 0 jmp [orgSscanf_LoadPath] } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov eax, [esp+4]\n" + "mov byte ptr [eax+ecx], 0\n" + "jmp [%[orgSscanf_LoadPath]]\n" + :: [orgSscanf_LoadPath] "m" (orgSscanf_LoadPath) + ); +#endif } static void* orgSscanf1; __declspec(naked) static void sscanf1_Terminate() { +#ifdef _MSC_VER _asm { mov eax, [esp+4] mov byte ptr [eax+ecx], 0 jmp [orgSscanf1] } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov eax, [esp+4]\n" + "mov byte ptr [eax+ecx], 0\n" + "jmp [%[orgSscanf1]]\n" + :: [orgSscanf1] "m" (orgSscanf1) + ); +#endif } __declspec(naked) static void ReadTrackFile_Terminate() { +#ifdef _MSC_VER _asm { mov ecx, [gString] mov byte ptr [ecx+edx], 0 mov ecx, [esi] inc ebp - add ecx, [esp+0ACh-98h] - retn + add ecx, [esp+0xAC-0x98] + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov ecx, [%[gString]]\n" + "mov byte ptr [ecx+edx], 0\n" + "mov ecx, [esi]\n" + "inc ebp\n" + "add ecx, [esp+0xAC-0x98]\n" + "ret\n" + :: [gString] "m" (gString) + ); +#endif } } @@ -703,17 +883,33 @@ namespace DodoKeyboardControls static void* (*orgFindPlayerVehicle)(); __declspec(naked) static void FindPlayerVehicle_DodoCheck() { +#ifdef _MSC_VER _asm { call [orgFindPlayerVehicle] mov ecx, [bAllDodosCheat] cmp byte ptr [ecx], 0 je CheatDisabled - mov byte ptr [esp+1Ch-14h], 1 + mov byte ptr [esp+0x1C-0x14], 1 CheatDisabled: - retn + ret } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "call [%[orgFindPlayerVehicle]]\n" + "mov ecx, [%[bAllDodosCheat]]\n" + "cmp byte ptr [ecx], 0\n" + "je CheatDisabled\n" + "mov byte ptr [esp+0x1C-0x14], 1\n" + + "CheatDisabled:\n" + "ret\n" + :: [orgFindPlayerVehicle] "m" (orgFindPlayerVehicle), + [bAllDodosCheat] "m" (bAllDodosCheat) + ); +#endif } } @@ -770,6 +966,7 @@ namespace GenerateNewPickup_ReuseObjectFix __declspec(naked) void GiveUsAPickUpObject_CleanUpObject() { +#ifdef _MSC_VER _asm { mov eax, [pPickupObject] @@ -795,6 +992,36 @@ namespace GenerateNewPickup_ReuseObjectFix NoPickup: jmp [orgGiveUsAPickUpObject] } +#elif defined(__GNUC__) || defined(__clang__) + __asm__ volatile + ( + "mov eax, [%[pPickupObject]]\n" + "add eax, ebp\n" + "mov eax, [eax]\n" + "test eax, eax\n" + "jz NoPickup\n" + "push edi\n" + "mov edi, eax\n" + + "push edi\n" + "call [%[WorldRemove]]\n" + "add esp, 4\n" + + // Call dtor + "mov ecx, edi\n" + "mov eax, [edi]\n" + "push 1\n" + "call dword ptr [eax]\n" + + "pop edi\n" + + "NoPickup:\n" + "jmp [%[orgGiveUsAPickUpObject]]\n" + :: [pPickupObject] "m" (pPickupObject), + [WorldRemove] "m" (WorldRemove), + [orgGiveUsAPickUpObject] "m" (orgGiveUsAPickUpObject) + ); +#endif } }