From 8362b0a1d0cd5ea4c6488e1260fceab7d4cebd75 Mon Sep 17 00:00:00 2001 From: Echo J Date: Mon, 4 Nov 2024 17:14:10 +0200 Subject: [PATCH] SilentPatchIII: Add GCC-style inline assembly statements These almost work on llvm-mingw too (but there's some stubborn call instructions) --- SilentPatchIII/SilentPatchIII.cpp | 227 ++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index dcb7c2f..da1730b 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -196,6 +196,7 @@ void ResetMousePos() __declspec(naked) void M16StatsFix() { +#ifdef _MSC_VER _asm { add eax, 0x34 @@ -204,11 +205,23 @@ __declspec(naked) void M16StatsFix() inc dword ptr [ecx] ret } +#else + __asm__ volatile + ( + "add eax, 0x34\n" + "add ebx, 0x34\n" + "mov ecx, %[InstantHitsFiredByPlayer]\n" + "inc dword ptr [ecx]\n" + "ret" + :: [InstantHitsFiredByPlayer] "m" (InstantHitsFiredByPlayer) + ); +#endif } static const float fMinusOne = -1.0f; __declspec(naked) void HeadlightsFix() { +#ifdef _MSC_VER _asm { fld dword ptr [esp+0x708-0x690] @@ -226,6 +239,27 @@ __declspec(naked) void HeadlightsFix() fld st jmp HeadlightsFix_JumpBack } +#else + __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 %[fMinusOne]\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]" + :: [fMinusOne] "f" (fMinusOne), + [HeadlightsFix_JumpBack] "m" (HeadlightsFix_JumpBack) + ); +#endif } static float fShadowXSize, fShadowYSize; @@ -314,6 +348,7 @@ float FixedRefValue() __declspec(naked) void SubtitlesShadowFix() { +#ifdef _MSC_VER _asm { push eax @@ -322,10 +357,24 @@ __declspec(naked) void SubtitlesShadowFix() fadd fShadowYSize jmp SubtitlesShadowFix_JumpBack } +#else + __asm__ volatile + ( + "push eax\n" + "call %[Recalculate]\n" + "fadd dword ptr [esp+0x50+8]\n" + "fadd %[fShadowYSize]\n" + "jmp %[SubtitlesShadowFix_JumpBack]" + :: [Recalculate] "i" (Recalculate), + [fShadowYSize] "m" (fShadowYSize), + [SubtitlesShadowFix_JumpBack] "m" (SubtitlesShadowFix_JumpBack) + ); +#endif } __declspec(naked) void III_SensResetFix() { +#ifdef _MSC_VER _asm { mov ecx, 0x3A76 @@ -337,12 +386,26 @@ __declspec(naked) void III_SensResetFix() fstp dword ptr [ebp+0x194] ret } +#else + __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" + ); +#endif } static void* RadarBoundsCheckCoordBlip_JumpBack = AddressByVersion(0x4A55B8, 0x4A56A8, 0x4A5638); static void* RadarBoundsCheckCoordBlip_Count = AddressByVersion(0x4A55AF, 0x4A569F, 0x4A562F); __declspec(naked) void RadarBoundsCheckCoordBlip() { +#ifdef _MSC_VER _asm { mov edx, RadarBoundsCheckCoordBlip_Count @@ -357,11 +420,30 @@ __declspec(naked) void RadarBoundsCheckCoordBlip() fcompp ret } +#else + __asm__ volatile + ( + "mov edx, %[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" + :: [RadarBoundsCheckCoordBlip_Count] "m" (RadarBoundsCheckCoordBlip_Count), + [RadarBoundsCheckCoordBlip_JumpBack] "m" (RadarBoundsCheckCoordBlip_JumpBack) + ); +#endif } static void* RadarBoundsCheckEntityBlip_JumpBack = AddressByVersion(0x4A565E, 0x4A574E, 0x4A56DE); __declspec(naked) void RadarBoundsCheckEntityBlip() { +#ifdef _MSC_VER _asm { mov edx, RadarBoundsCheckCoordBlip_Count @@ -375,6 +457,23 @@ __declspec(naked) void RadarBoundsCheckEntityBlip() or eax, -1 ret } +#else + __asm__ volatile + ( + "mov edx, %[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" + :: [RadarBoundsCheckCoordBlip_Count] "m" (RadarBoundsCheckCoordBlip_Count), + [RadarBoundsCheckEntityBlip_JumpBack] "m" (RadarBoundsCheckEntityBlip_JumpBack) + ); +#endif } char** ppUserFilesDir = AddressByVersion(0x580C16, 0x580F66, 0x580E66); @@ -413,6 +512,7 @@ unsigned int __cdecl AutoPilotTimerCalculation_III(unsigned int nTimer, int nSca __declspec(naked) void AutoPilotTimerFix_III() { +#ifdef _MSC_VER _asm { push dword ptr [esp + 0x4] @@ -427,6 +527,23 @@ __declspec(naked) void AutoPilotTimerFix_III() pop ebx ret 4 } +#else + __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" + :: [AutoPilotTimerCalculation_III] "i" (AutoPilotTimerCalculation_III) + ); +#endif } namespace ZeroAmmoFix @@ -581,6 +698,7 @@ namespace RemoveDriverStatusFix { // if (m_nStatus != STATUS_WRECKED) // m_nStatus = STATUS_ABANDONED; +#ifdef _MSC_VER _asm { mov ah, [ecx+0x50] @@ -594,6 +712,21 @@ namespace RemoveDriverStatusFix DontSetStatus: ret } +#else + __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" + ); +#endif } } @@ -626,6 +759,7 @@ namespace EvasiveDiveFix __declspec(naked) static void CalculateAngle_Hook() { +#ifdef _MSC_VER _asm { push dword ptr [esi+0x7C] @@ -636,6 +770,19 @@ namespace EvasiveDiveFix mov ecx, ebp ret } +#else + __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" + :: [CalculateAngle] "i" (CalculateAngle) + ); +#endif } } @@ -648,27 +795,48 @@ 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 } +#else + __asm__ volatile + ( + "mov eax, [esp+4]\n" + "mov byte ptr [eax+ecx], 0\n" + "jmp %[orgSscanf_LoadPath]" + :: [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 } +#else + __asm__ volatile + ( + "mov eax, [esp+4]\n" + "mov byte ptr [eax+ecx], 0\n" + "jmp %[orgSscanf1]" + :: [orgSscanf1] "m" (orgSscanf1) + ); +#endif } __declspec(naked) static void ReadTrackFile_Terminate() { +#ifdef _MSC_VER _asm { mov ecx, gString @@ -678,6 +846,18 @@ namespace NullTerminatedLines add ecx, [esp+0xAC-0x98] ret } +#else + __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" + :: [gString] "m" (gString) + ); +#endif } } @@ -704,6 +884,7 @@ namespace DodoKeyboardControls static void* (*orgFindPlayerVehicle)(); __declspec(naked) static void FindPlayerVehicle_DodoCheck() { +#ifdef _MSC_VER _asm { call orgFindPlayerVehicle @@ -715,6 +896,21 @@ namespace DodoKeyboardControls CheatDisabled: ret } +#else + __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" + :: [orgFindPlayerVehicle] "m" (orgFindPlayerVehicle), + [bAllDodosCheat] "m" (bAllDodosCheat) + ); +#endif } } @@ -771,6 +967,7 @@ namespace GenerateNewPickup_ReuseObjectFix __declspec(naked) static void GiveUsAPickUpObject_CleanUpObject() { +#ifdef _MSC_VER _asm { mov eax, pPickupObject @@ -796,6 +993,36 @@ namespace GenerateNewPickup_ReuseObjectFix NoPickup: jmp orgGiveUsAPickUpObject } +#else + __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 offset %[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]" + :: [pPickupObject] "m" (pPickupObject), + [WorldRemove] "m" (WorldRemove), + [orgGiveUsAPickUpObject] "m" (orgGiveUsAPickUpObject) + ); +#endif } }