SilentPatchIII: Add GCC/Clang-specific inline assembly statements

This also matches the MSVC statements more closely to the GCC/Clang
ones
This commit is contained in:
Echo J 2024-11-04 17:14:10 +02:00
parent 75004322ab
commit 135ceed86c

View file

@ -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<void*>(0x4A55B8, 0x4A56A8, 0x4A5638);
static void* RadarBoundsCheckCoordBlip_Count = AddressByVersion<void*>(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<void*>(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<char**>(0x580C16, 0x580F66, 0x580E66);
@ -413,6 +512,7 @@ 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]
@ -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
}
}