diff --git a/Client/game_sa/CAESoundManagerSA.cpp b/Client/game_sa/CAESoundManagerSA.cpp index f77bf2941b..d0bc3a3fa0 100644 --- a/Client/game_sa/CAESoundManagerSA.cpp +++ b/Client/game_sa/CAESoundManagerSA.cpp @@ -23,7 +23,6 @@ CAESoundManagerSA::CAESoundManagerSA(CAESoundManagerSAInterface* pInterface) : m void CAESoundManagerSA::CancelSoundsInBankSlot(uint uiGroup, uint uiIndex) { - using CAESoundManager__CancelSoundsInBankSlot = CAESound*(__thiscall*)(CAESoundManagerSAInterface*, uint, uint); - static auto pCancelSoundsInBankSlot = reinterpret_cast(FUNC_CAESoundManager__CancelSoundsInBankSlot); - pCancelSoundsInBankSlot(m_pInterface, uiGroup, uiIndex); + auto args = PrepareSignature(m_pInterface, uiGroup, uiIndex); + CallGTAFunction(FUNC_CAESoundManager__CancelSoundsInBankSlot, args); } diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 50ae14bb3c..24852ab3a4 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -108,7 +108,8 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding) pGame->GetWorld()->Remove(pInterface, CBuildingPool_Destructor); // Call virtual destructor - ((void*(__thiscall*)(void*, char))pInterface->vtbl->SCALAR_DELETING_DESTRUCTOR)(pInterface, 0); + auto args = PrepareSignature(pInterface, 0); + CallGTAFunction(pInterface->vtbl->SCALAR_DELETING_DESTRUCTOR, args); // Remove col reference auto modelInfo = pGame->GetModelInfo(pBuilding->GetModelIndex()); @@ -137,8 +138,7 @@ void CBuildingsPoolSA::RemoveAllBuildings() pGame->GetPlantManager()->RemoveAllPlants(); // Remove all shadows - using CStencilShadowObjects_dtorAll = void* (*)(); - ((CStencilShadowObjects_dtorAll)0x711390)(); + CallGTAFunction(0x711390, PrepareSignature()); m_pOriginalBuildingsBackup = std::make_unique, MAX_BUILDINGS>>(); diff --git a/Client/game_sa/CCameraSA.cpp b/Client/game_sa/CCameraSA.cpp index 2e8f6b6eb8..6b0260660e 100644 --- a/Client/game_sa/CCameraSA.cpp +++ b/Client/game_sa/CCameraSA.cpp @@ -358,7 +358,8 @@ float CCameraSA::GetCameraRotation() RwMatrix* CCameraSA::GetLTM() { // RwFrameGetLTM - return ((RwMatrix*(_cdecl*)(void*))0x7F0990)(GetInterface()->m_pRwCamera->object.object.parent); + auto args = PrepareSignature(GetInterface()->m_pRwCamera->object.object.parent); + return CallGTAFunction(0x7F0990, args); } CEntity* CCameraSA::GetTargetEntity() @@ -450,8 +451,8 @@ void CCameraSA::ShakeCamera(float radius, float x, float y, float z) noexcept if (radius <= 0.0f) return ResetShakeCamera(); - using ShakeCamera_t = void(__thiscall*)(CCameraSAInterface*, float radius, float x, float y, float z); - ((ShakeCamera_t)FUNC_ShakeCam)(cameraInterface, radius, x, y, z); + auto args = PrepareSignature(cameraInterface, radius, x, y, z); + CallGTAFunction(FUNC_ShakeCam, args); } void CCameraSA::ResetShakeCamera() noexcept diff --git a/Client/game_sa/CEntitySA.cpp b/Client/game_sa/CEntitySA.cpp index 02a9f00380..66d7e8221b 100644 --- a/Client/game_sa/CEntitySA.cpp +++ b/Client/game_sa/CEntitySA.cpp @@ -25,22 +25,24 @@ extern CGameSA* pGame; void CEntitySAInterface::TransformFromObjectSpace(CVector& outPosn, CVector const& offset) { - ((void(__thiscall*)(CEntitySAInterface*, CVector&, CVector const&))0x533560)(this, outPosn, offset); + auto args = PrepareSignature(this, &outPosn, &offset); + CallGTAFunction(0x533560, args); } CVector* CEntitySAInterface::GetBoundCentre(CVector* pOutCentre) { - return ((CVector * (__thiscall*)(CEntitySAInterface*, CVector*))0x534250)(this, pOutCentre); + auto args = PrepareSignature(this, pOutCentre); + return CallGTAFunction(0x534250, args); } void CEntitySAInterface::UpdateRW() { - ((void(__thiscall*)(CEntitySAInterface*))0x446F90)(this); + CallGTAFunction(0x446F90, PrepareSignature(this)); } void CEntitySAInterface::UpdateRpHAnim() { - ((void(__thiscall*)(CEntitySAInterface*))0x532B20)(this); + CallGTAFunction(0x532B20, PrepareSignature(this)); } CRect* CEntitySAInterface::GetBoundRect_(CRect* pRect) @@ -71,6 +73,26 @@ void CEntitySAInterface::StaticSetHooks() HookInstall(0x534120, &CEntitySAInterface::GetBoundRect_); } +void CEntitySAInterface::ResolveReferences() +{ + CallGTAFunction(0x571A40, PrepareSignature(this)); +} + +void CEntitySAInterface::RemoveShadows() +{ + CallGTAFunction(0x711730, PrepareSignature(this)); +} + +void CEntitySAInterface::DeleteRwObject() +{ + CallGTAFunction(this->vtbl->DeleteRwObject, PrepareSignature(this)); +} + +void CEntitySAInterface::RemoveMatrix() +{ + CallGTAFunction(0x54F3B0, PrepareSignature(this)); +} + CEntitySA::CEntitySA() { // Set these variables to a constant state @@ -437,7 +459,8 @@ eEntityStatus CEntitySA::GetEntityStatus() RwFrame* CEntitySA::GetFrameFromId(int id) { // CClumpModelInfo::GetFrameFromId - return ((RwFrame*(_cdecl*)(RpClump*, int))0x4C53C0)(m_pInterface->m_pRwObject, id); + auto args = PrepareSignature(m_pInterface->m_pRwObject, id); + return CallGTAFunction(0x4C53C0, args); } RpClump* CEntitySA::GetRpClump() @@ -448,7 +471,7 @@ RpClump* CEntitySA::GetRpClump() RwMatrix* CEntitySA::GetLTMFromId(int id) { // RwFrameGetLTM - return ((RwMatrix*(_cdecl*)(RwFrame*))0x7F0990)(GetFrameFromId(id)); + return CallGTAFunction(0x7F0990, PrepareSignature(GetFrameFromId(id))); } void CEntitySA::SetAlpha(DWORD dwAlpha) diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index 205d5415f7..9b2498d235 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -225,27 +225,15 @@ class CEntitySAInterface return -1; } - void ResolveReferences() - { - using CEntity_ResolveReferences = void*(__thiscall*)(CEntitySAInterface*); - ((CEntity_ResolveReferences)0x571A40)(this); - }; + void ResolveReferences(); - void RemoveShadows() - { - using CStencilShadow_dtorByOwner = void*(__cdecl*)(CEntitySAInterface * pEntity); - ((CStencilShadow_dtorByOwner)0x711730)(this); - }; + void RemoveShadows(); - void DeleteRwObject() - { - using vtbl_DeleteRwObject = void(__thiscall*)(CEntitySAInterface * pEntity); - ((vtbl_DeleteRwObject)this->vtbl->DeleteRwObject)(this); - }; + void DeleteRwObject(); bool HasMatrix() const noexcept { return Placeable.matrix != nullptr; } - void RemoveMatrix() { ((void(__thiscall*)(void*))0x54F3B0)(this); } + void RemoveMatrix(); }; static_assert(sizeof(CEntitySAInterface) == 0x38, "Invalid size for CEntitySAInterface"); diff --git a/Client/game_sa/CFileLoaderSA.cpp b/Client/game_sa/CFileLoaderSA.cpp index 67cb476cf5..d0a3f9f6ec 100644 --- a/Client/game_sa/CFileLoaderSA.cpp +++ b/Client/game_sa/CFileLoaderSA.cpp @@ -31,26 +31,26 @@ void CFileLoaderSA::StaticSetHooks() CEntitySAInterface* CFileLoaderSA::LoadObjectInstance(SFileObjectInstance* obj) { // Second argument is model name. It's unused in the function - return ((CEntitySAInterface * (__cdecl*)(SFileObjectInstance*, const char*))0x538090)(obj, nullptr); + return CallGTAFunction(0x538090, PrepareSignature(obj, static_cast(nullptr))); } class CAtomicModelInfo { public: - void CAtomicModelInfo::DeleteRwObject() { ((void(__thiscall*)(CAtomicModelInfo*))(*(void***)this)[8])(this); } + void CAtomicModelInfo::DeleteRwObject() { CallGTAFunction((*(void***)this)[8], PrepareSignature(this)); } - void CAtomicModelInfo::SetAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CAtomicModelInfo*, RpAtomic*))(*(void***)this)[15])(this, atomic); } + void CAtomicModelInfo::SetAtomic(RpAtomic* atomic) { CallGTAFunction((*(void***)this)[15], PrepareSignature(this, atomic)); } }; class CDamagableModelInfo { public: - void CDamagableModelInfo::SetDamagedAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CDamagableModelInfo*, RpAtomic*))0x4C48D0)(this, atomic); } + void CDamagableModelInfo::SetDamagedAtomic(RpAtomic* atomic) { CallGTAFunction(0x4C48D0, PrepareSignature(this, atomic)); } }; static char* GetFrameNodeName(RwFrame* frame) { - return ((char*(__cdecl*)(RwFrame*))0x72FB30)(frame); + return CallGTAFunction(0x72FB30, PrepareSignature(frame)); } // Originally there was a possibility for this function to cause buffer overflow @@ -97,22 +97,22 @@ void GetNameAndDamage(const char* nodeName, char (&outName)[OutBuffSize], bool& static void CVisibilityPlugins_SetAtomicRenderCallback(RpAtomic* pRpAtomic, RpAtomic* (*renderCB)(RpAtomic*)) { - return ((void(__cdecl*)(RpAtomic*, RpAtomic * (*renderCB)(RpAtomic*)))0x7328A0)(pRpAtomic, renderCB); + CallGTAFunction(0x7328A0, PrepareSignature(pRpAtomic, renderCB)); } static void CVisibilityPlugins_SetAtomicId(RpAtomic* pRpAtomic, int id) { - return ((void(__cdecl*)(RpAtomic*, int))0x732230)(pRpAtomic, id); + CallGTAFunction(0x732230, PrepareSignature(pRpAtomic, id)); } static void CVehicleModelInfo_UseCommonVehicleTexDicationary() { - ((void(__cdecl*)())0x4C75A0)(); + CallGTAFunction(0x4C75A0, PrepareSignature()); } static void CVehicleModelInfo_StopUsingCommonVehicleTexDicationary() { - ((void(__cdecl*)())0x4C75C0)(); + CallGTAFunction(0x4C75C0, PrepareSignature()); } static auto CModelInfo_ms_modelInfoPtrs = (CBaseModelInfoSAInterface**)ARRAY_ModelInfo; @@ -223,5 +223,5 @@ CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine) if (fLenSq > 0.0f && std::fabs(fLenSq - 1.0f) > std::numeric_limits::epsilon()) inst.rotation /= std::sqrt(fLenSq); - return ((CEntitySAInterface * (__cdecl*)(SFileObjectInstance*))0x538090)(&inst); + return CallGTAFunction(0x538090, PrepareSignature(&inst)); } diff --git a/Client/game_sa/CFxManagerSA.cpp b/Client/game_sa/CFxManagerSA.cpp index fe2f03b89e..c60410534b 100644 --- a/Client/game_sa/CFxManagerSA.cpp +++ b/Client/game_sa/CFxManagerSA.cpp @@ -71,9 +71,8 @@ void CFxManagerSA::OnFxSystemSAInterfaceDestroyed(CFxSystemSAInterface* pFxSyste CFxSystemBPSAInterface* CFxManagerSA::GetFxSystemBlueprintByName(SString sName) { - using func_t = CFxSystemBPSAInterface*(__thiscall*)(CFxManagerSAInterface * pInterface, const char* pChars); - auto func = reinterpret_cast(FUNC_FxManager_c__GetSystemByName); - return func(m_pInterface, sName); + auto args = PrepareSignature(m_pInterface, static_cast(sName)); + return CallGTAFunction(FUNC_FxManager_c__GetSystemByName, args); } bool CFxManagerSA::IsValidFxSystemBlueprintName(SString sName) diff --git a/Client/game_sa/CFxSA.cpp b/Client/game_sa/CFxSA.cpp index b063cb927d..3102e0f2e8 100644 --- a/Client/game_sa/CFxSA.cpp +++ b/Client/game_sa/CFxSA.cpp @@ -326,6 +326,7 @@ void CFxSA::AddParticle(eFxParticleSystems eFxParticle, const CVector& vecPositi newDirection.fZ = (rand() % 10000) * 0.0001f * 4 - 2 + newDirection.fZ; // Call FxSystem_c::AddParticle - ((int(__thiscall*)(FxSystem_c*, const CVector*, const CVector*, float, FxPrtMult_c*, float, float, float, int))FUNC_FXSystem_c_AddParticle)(fxParticleSystem, &vecPosition, &newDirection, 0, &fxPrt, -1.0f, fBrightness, 0, 0); + auto args = PrepareSignature(fxParticleSystem, &vecPosition, &newDirection, 0.0f, &fxPrt, -1.0f, fBrightness, 0.0f, 0); + CallGTAFunction(FUNC_FXSystem_c_AddParticle, args); } } diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 07ac611c09..6ca36ebe58 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -675,15 +675,9 @@ void CGameSA::SetWaterCreaturesEnabled(bool isEnabled) const auto manager = reinterpret_cast(0xC1DF30); if (isEnabled) - { - unsigned char(__thiscall * Init)(WaterCreatureManager_c*) = reinterpret_cast(0x6E3F90); - Init(manager); - } + CallGTAFunction(0x6E3F90, PrepareSignature(manager)); else - { - void(__thiscall * Exit)(WaterCreatureManager_c*) = reinterpret_cast(0x6E3FD0); - Exit(manager); - } + CallGTAFunction(0x6E3FD0, PrepareSignature(manager)); m_areWaterCreaturesEnabled = isEnabled; } @@ -785,17 +779,17 @@ void CGameSA::SetExtendedWaterCannonsEnabled(bool isEnabled) { char* currentCannon = (char*)currentACannons + i * SIZE_CWaterCannon; - ((void(__thiscall*)(int, void*, bool))FUNC_CAESoundManager_CancelSoundsOwnedByAudioEntity)(STRUCT_CAESoundManager, currentCannon + NUM_CWaterCannon_Audio_Offset, true); // CAESoundManager::CancelSoundsOwnedByAudioEntity to prevent random crashes from CAESound::UpdateParameters - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Destructor)(currentCannon); // CWaterCannon::~CWaterCannon + CallGTAFunction(FUNC_CAESoundManager_CancelSoundsOwnedByAudioEntity, PrepareSignature(STRUCT_CAESoundManager, static_cast(currentCannon + NUM_CWaterCannon_Audio_Offset), true)); // CAESoundManager::CancelSoundsOwnedByAudioEntity to prevent random crashes from CAESound::UpdateParameters + CallGTAFunction(FUNC_CWaterCannon_Destructor, PrepareSignature(static_cast(currentCannon))); // CWaterCannon::~CWaterCannon } // Call CWaterCannon constructor & CWaterCannon::Init for (int i = 0; i < newLimit; ++i) { - char* currentCannon = (char*)aCannons + i * SIZE_CWaterCannon; + void* currentCannon = (char*)aCannons + i * SIZE_CWaterCannon; - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Constructor)(currentCannon); // CWaterCannon::CWaterCannon - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Init)(currentCannon); // CWaterCannon::Init + CallGTAFunction(FUNC_CWaterCannon_Constructor, PrepareSignature(currentCannon)); // CWaterCannon::CWaterCannon + CallGTAFunction(FUNC_CWaterCannon_Init, PrepareSignature(currentCannon)); // CWaterCannon::Init } // Patch references to array @@ -831,7 +825,7 @@ void CGameSA::SetExtendedWaterCannonsEnabled(bool isEnabled) MemPut(0x856BF6, newLimit); // Free previous allocated memory - if (!isEnabled && currentACannons != nullptr) + if (!isEnabled && currentACannons) free(currentACannons); m_isExtendedWaterCannonsEnabled = isEnabled; diff --git a/Client/game_sa/CMatrixSA.cpp b/Client/game_sa/CMatrixSA.cpp index 3db83a7fc4..a6c2ed3cdf 100644 --- a/Client/game_sa/CMatrixSA.cpp +++ b/Client/game_sa/CMatrixSA.cpp @@ -3,30 +3,34 @@ CMatrixSAInterface::CMatrixSAInterface(CMatrixSAInterface const& matrix) { - ((void(__thiscall*)(CMatrixSAInterface*, CMatrixSAInterface const&))0x59BCF0)(this, matrix); + auto args = PrepareSignature(this, &matrix); + CallGTAFunction(CMatrix_Constructor, args); } CMatrixSAInterface::CMatrixSAInterface(RwMatrix* matrix, bool temporary) { - ((void(__thiscall*)(CMatrixSAInterface*, RwMatrix*, bool))0x59C050)(this, matrix, temporary); + auto args = PrepareSignature(this, matrix, temporary); + CallGTAFunction(CMatrix_Constructor2, args); } // destructor detaches matrix if attached CMatrixSAInterface::~CMatrixSAInterface() { - ((void(__thiscall*)(CMatrixSAInterface*))0x59ACD0)(this); + CallGTAFunction(CMatrix_Destructor, PrepareSignature(this)); } void CMatrixSAInterface::ConvertToEulerAngles(float& x, float& y, float& z, std::int32_t flags) { - ((void(__thiscall*)(CMatrixSAInterface*, float&, float&, float&, std::int32_t))0x59A840)(this, x, y, z, flags); + auto args = PrepareSignature(this, &x, &y, &z, flags); + CallGTAFunction(FUNC_CMatrix_ConvertToEulerAngles, args); } void CMatrixSAInterface::ConvertFromEulerAngles(float x, float y, float z, std::int32_t flags) { - ((void(__thiscall*)(CMatrixSAInterface*, float, float, float, std::int32_t))0x59AA40)(this, x, y, z, flags); + auto args = PrepareSignature(this, x, y, z, flags); + CallGTAFunction(FUNC_CMatrix_ConvertFromEulerAngles, args); } void CMatrixSAInterface::UpdateRW() { - ((void(__thiscall*)(CMatrixSAInterface*))0x59BBB0)(this); + CallGTAFunction(FUNC_CMatrix_UpdateRW, PrepareSignature(this)); } diff --git a/Client/game_sa/CMatrixSA.h b/Client/game_sa/CMatrixSA.h index 37173aea7f..d21354abb7 100644 --- a/Client/game_sa/CMatrixSA.h +++ b/Client/game_sa/CMatrixSA.h @@ -2,6 +2,13 @@ #include "CVector.h" #include "CRenderWareSA.h" +#define CMatrix_Constructor 0x59BCF0 +#define CMatrix_Constructor2 0x59C050 +#define CMatrix_Destructor 0x59ACD0 +#define FUNC_CMatrix_ConvertToEulerAngles 0x59A840 +#define FUNC_CMatrix_ConvertFromEulerAngles 0x59AA40 +#define FUNC_CMatrix_UpdateRW 0x59BBB0 + class CMatrixSAInterface { private: diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 2db97a5245..4c02bdf16b 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -77,16 +77,14 @@ static constexpr size_t RESOURCE_ID_COL = 25000; static void CBaseModelInfo_SetColModel(CBaseModelInfoSAInterface* self, CColModelSAInterface* colModel, bool applyToPairedModel) { - using Signature = void(__thiscall*)(CBaseModelInfoSAInterface*, CColModelSAInterface*, bool); - auto function = reinterpret_cast(0x4C4BC0); - function(self, colModel, applyToPairedModel); + auto args = PrepareSignature(self, colModel, applyToPairedModel); + CallGTAFunction(0x4C4BC0, args); } static void CColAccel_addCacheCol(int idx, const CColModelSAInterface* colModel) { - using Signature = void(__cdecl*)(int, const CColModelSAInterface*); - auto function = reinterpret_cast(0x5B2C20); - function(idx, colModel); + auto args = PrepareSignature(idx, colModel); + CallGTAFunction(0x5B2C20, args); } CModelInfoSA::CModelInfoSA() @@ -1566,7 +1564,7 @@ void CModelInfoSA::SetColModel(CColModel* pColModel) m_pInterface->bIsColLoaded = false; // Fix random foliage on custom collisions by calling CPlantMgr::SetPlantFriendlyFlagInAtomicMI - (reinterpret_cast(0x5DB650))(m_pInterface); + CallGTAFunction(0x5DB650, PrepareSignature(m_pInterface)); // Set some lighting for this collision if not already present CColDataSA* pColData = pColModelInterface->m_data; diff --git a/Client/game_sa/CPedIKSA.cpp b/Client/game_sa/CPedIKSA.cpp index 1efccf4b41..677bbe03e4 100644 --- a/Client/game_sa/CPedIKSA.cpp +++ b/Client/game_sa/CPedIKSA.cpp @@ -18,6 +18,5 @@ RwV3d& CPedIKSAInterface::ZaxisIK = *(RwV3d*)0x8D2344; void CPedIKSA::RotateTorso(void* bone, LimbOrientation* orientation, bool flag) { - auto CPedIKSA_RotateTorso = (void(__thiscall*)(CPedIKSAInterface*, void*, LimbOrientation*, bool))0x5FDDB0; - CPedIKSA_RotateTorso(internalInterface, bone, orientation, flag); + CallGTAFunction(CPedIK__RotateTorso, PrepareSignature(internalInterface, bone, orientation, flag)); } diff --git a/Client/game_sa/CPedIKSA.h b/Client/game_sa/CPedIKSA.h index 26a2a4525b..f218c07a2f 100644 --- a/Client/game_sa/CPedIKSA.h +++ b/Client/game_sa/CPedIKSA.h @@ -13,6 +13,8 @@ #include +#define CPedIK__RotateTorso 0x5FDDB0 + class CPedSAInterface; struct RwV3d; diff --git a/Client/game_sa/CPedIntelligenceSA.cpp b/Client/game_sa/CPedIntelligenceSA.cpp index e6752a96da..f53eb576e6 100644 --- a/Client/game_sa/CPedIntelligenceSA.cpp +++ b/Client/game_sa/CPedIntelligenceSA.cpp @@ -53,8 +53,8 @@ bool CPedIntelligenceSA::TestForStealthKill(CPed* pPed, bool bUnk) CTaskSAInterface* CPedIntelligenceSA::SetTaskDuckSecondary(unsigned short nLengthOfDuck) { - auto SetTaskDuckSecondary = (CTaskSAInterface * (__thiscall*)(CPedIntelligenceSAInterface*, unsigned short))0x601230; - return SetTaskDuckSecondary(internalInterface, nLengthOfDuck); + auto args = PrepareSignature(internalInterface, nLengthOfDuck); + return CallGTAFunction(0x601230, args); } CTaskSimpleUseGun* CPedIntelligenceSA::GetTaskUseGun() diff --git a/Client/game_sa/CPedSA.cpp b/Client/game_sa/CPedSA.cpp index 1ae9f942f8..54d0340515 100644 --- a/Client/game_sa/CPedSA.cpp +++ b/Client/game_sa/CPedSA.cpp @@ -513,9 +513,8 @@ CVector* CPedSA::GetBonePosition(eBone bone, CVector* vecPosition) if (entity->m_pRwObject != nullptr) { // void __thiscall CPed::GetBonePosition(struct RwV3d &, unsigned int, bool) - using Signature = void(__thiscall*)(CEntitySAInterface*, CVector*, unsigned int, bool); - const auto GameFunction = reinterpret_cast(FUNC_GetBonePosition); - GameFunction(entity, vecPosition, bone, true); + auto args = PrepareSignature(entity, vecPosition, bone, true); + CallGTAFunction(FUNC_GetBonePosition, args); } // Clamp to a sane range as this function can occasionally return massive values, @@ -538,9 +537,8 @@ CVector* CPedSA::GetTransformedBonePosition(eBone bone, CVector* vecPosition) if (entity->m_pRwObject != nullptr) { // void __thiscall CPed::GetTransformedBonePosition(struct RwV3d &, unsigned int, bool) - using Signature = void(__thiscall*)(CEntitySAInterface*, CVector*, unsigned int, bool); - const auto GameFunction = reinterpret_cast(FUNC_GetTransformedBonePosition); - GameFunction(entity, vecPosition, bone, true); + auto args = PrepareSignature(entity, vecPosition, bone, true); + CallGTAFunction(FUNC_GetTransformedBonePosition, args); } // Clamp to a sane range as this function can occasionally return massive values, diff --git a/Client/game_sa/CPlantManagerSA.cpp b/Client/game_sa/CPlantManagerSA.cpp index aef1849aae..34d1bfd610 100644 --- a/Client/game_sa/CPlantManagerSA.cpp +++ b/Client/game_sa/CPlantManagerSA.cpp @@ -16,11 +16,15 @@ class CPlantColEntEntry public: void ReleaseEntry() { - using CPlantColEntEntry_ReleaseEntry = void* ( __thiscall *)(CPlantColEntEntry*); - ((CPlantColEntEntry_ReleaseEntry)0x5DB8A0)(this); + CallGTAFunction(FUNC_CPlantColEntEntry_ReleaseEntry, PrepareSignature(this)); }; }; +void CPlantManagerSA::RemovePlant(CEntitySAInterface* enity) +{ + CallGTAFunction(FUNC_CPlantColEntEntry_Remove, PrepareSignature(enity)); +} + void CPlantManagerSA::RemoveAllPlants() { while (true) diff --git a/Client/game_sa/CPlantManagerSA.h b/Client/game_sa/CPlantManagerSA.h index 4ade022684..52c9d65132 100644 --- a/Client/game_sa/CPlantManagerSA.h +++ b/Client/game_sa/CPlantManagerSA.h @@ -2,17 +2,16 @@ #include "CEntitySA.h" +#define FUNC_CPlantColEntEntry_ReleaseEntry 0x5DB8A0 +#define FUNC_CPlantColEntEntry_Remove 0x5DBEF0 + class CPlantManagerSA { public: CPlantManagerSA() = default; ~CPlantManagerSA() = default; - void RemovePlant(CEntitySAInterface* enity) - { - using CPlantColEntry_Remove = CEntitySAInterface* (*)(CEntitySAInterface*); - ((CPlantColEntry_Remove)0x5DBEF0)(enity); - }; + void RemovePlant(CEntitySAInterface* enity); void RemoveAllPlants(); }; diff --git a/Client/game_sa/CPtrNodeDoubleListSA.h b/Client/game_sa/CPtrNodeDoubleListSA.h index fb6f6c9978..8b635a4620 100644 --- a/Client/game_sa/CPtrNodeDoubleListSA.h +++ b/Client/game_sa/CPtrNodeDoubleListSA.h @@ -27,8 +27,8 @@ class CPtrNodeDoubleListSAInterface void RemoveItem(T* pItem) { - using CPtrListDoubleLinkSAInterface_RemoveItem = void(__thiscall*)(CPtrNodeDoubleListSAInterface * pLinkList, void* item); - ((CPtrListDoubleLinkSAInterface_RemoveItem)0x5336B0)(this, pItem); + auto args = PrepareSignature(this, pItem); + CallGTAFunction(0x5336B0, args); }; void RemoveAllItems() diff --git a/Client/game_sa/CPtrNodeSingleListSA.h b/Client/game_sa/CPtrNodeSingleListSA.h index f083614421..fefabd4e3f 100644 --- a/Client/game_sa/CPtrNodeSingleListSA.h +++ b/Client/game_sa/CPtrNodeSingleListSA.h @@ -31,8 +31,8 @@ class CPtrNodeSingleListSAInterface template void CPtrNodeSingleListSAInterface::RemoveItem(T* item) { - using CPtrNodeSingleList_RemoveItem_t = void(__thiscall*)(CPtrNodeSingleListSAInterface * pLinkList, void* item); - ((CPtrNodeSingleList_RemoveItem_t)0x533610)(this, item); + auto args = PrepareSignature(this, item); + CallGTAFunction(0x533610, args); } template diff --git a/Client/game_sa/CQuadTreeNodeSA.h b/Client/game_sa/CQuadTreeNodeSA.h index dabb9bdfe5..00abd52530 100644 --- a/Client/game_sa/CQuadTreeNodeSA.h +++ b/Client/game_sa/CQuadTreeNodeSA.h @@ -51,6 +51,6 @@ void CQuadTreeNodesSAInterface::RemoveAllItems() template char CQuadTreeNodesSAInterface::AddItem(T* item, CRect* boudingBox) { - typedef char(__thiscall * CQuadTreeNode_AddItem_t)(CQuadTreeNodesSAInterface*, void*, CRect*); - return ((CQuadTreeNode_AddItem_t)(0x552CD0))(this, item, boudingBox); + auto args = PrepareSignature(this, item, boudingBox); + return CallGTAFunction(0x552CD0, args); }; diff --git a/Client/game_sa/CRenderWareSA.cpp b/Client/game_sa/CRenderWareSA.cpp index 56f5ce34e4..f284077cde 100644 --- a/Client/game_sa/CRenderWareSA.cpp +++ b/Client/game_sa/CRenderWareSA.cpp @@ -358,10 +358,6 @@ bool CRenderWareSA::DoContainTheSameGeometry(RpClump* pClumpA, RpClump* pClumpB, // Replaces a vehicle/weapon/ped model bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD dwSetClumpFunction) { - auto CVehicleModelInfo_CVehicleStructure_Destructor = (void(__thiscall*)(CVehicleModelVisualInfoSAInterface * pThis))0x4C7410; - auto CVehicleModelInfo_CVehicleStructure_release = (void(__cdecl*)(CVehicleModelVisualInfoSAInterface * pThis))0x4C9580; - auto CBaseModelInfo_SetClump = (void(__thiscall*)(CBaseModelInfoSAInterface * pThis, RpClump * clump)) dwSetClumpFunction; - CModelInfo* pModelInfo = pGame->GetModelInfo(usModelID); if (pModelInfo) { @@ -387,14 +383,22 @@ bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD if (pVehicleModelInfoInterface->pVisualInfo) { auto pVisualInfo = pVehicleModelInfoInterface->pVisualInfo; - CVehicleModelInfo_CVehicleStructure_Destructor(pVisualInfo); - CVehicleModelInfo_CVehicleStructure_release(pVisualInfo); + + auto args = PrepareSignature(pVisualInfo); + // Call CVehicleModelInfo_CVehicleStructure_Destructor + CallGTAFunction(0x4C7410, args); + + // Call CVehicleModelInfo_CVehicleStructure_release + CallGTAFunction(0x4C9580, args); + pVehicleModelInfoInterface->pVisualInfo = nullptr; } } CBaseModelInfoSAInterface* pModelInfoInterface = pModelInfo->GetInterface(); - CBaseModelInfo_SetClump(pModelInfoInterface, pNewClone); + + // Call CBaseModelInfo_SetClump + CallGTAFunction(dwSetClumpFunction, PrepareSignature(pModelInfoInterface, pNewClone)); RpClumpDestroy(pOldClump); } } @@ -769,7 +773,7 @@ void CRenderWareSA::GetModelTextureNames(std::vector& outNameList, usho } if (bLoadedModel) - ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); + CallGTAFunction(FUNC_RemoveModel, PrepareSignature(usModelId)); } //////////////////////////////////////////////////////////////// @@ -838,7 +842,7 @@ bool CRenderWareSA::GetModelTextures(std::vector(FUNC_RemoveModel, PrepareSignature(usModelId)); return true; } diff --git a/Client/game_sa/CRopesSA.cpp b/Client/game_sa/CRopesSA.cpp index 0a678ca815..e883990e2a 100644 --- a/Client/game_sa/CRopesSA.cpp +++ b/Client/game_sa/CRopesSA.cpp @@ -49,8 +49,5 @@ void CRopesSA::RemoveEntityRope(CEntitySAInterface* pEntity) } if (pRope) - { - auto CRope_Remove = (void(__thiscall*)(CRopesSAInterface*))0x556780; - CRope_Remove(pRope); - } + CallGTAFunction(FUNC_CRope_Remove, PrepareSignature(pRope)); } diff --git a/Client/game_sa/CRopesSA.h b/Client/game_sa/CRopesSA.h index 6671ee0502..beebf30541 100644 --- a/Client/game_sa/CRopesSA.h +++ b/Client/game_sa/CRopesSA.h @@ -17,6 +17,7 @@ #define ROPES_COUNT 8 #define FUNC_CRopes_CreateRopeForSwatPed 0x558d10 +#define FUNC_CRope_Remove 0x556780 class CRopesSAInterface { diff --git a/Client/game_sa/D3DResourceSystemSA.cpp b/Client/game_sa/D3DResourceSystemSA.cpp index f0ce9c88a7..835ed32472 100644 --- a/Client/game_sa/D3DResourceSystemSA.cpp +++ b/Client/game_sa/D3DResourceSystemSA.cpp @@ -30,13 +30,14 @@ void D3DResourceSystemSA::StaticSetHooks() void D3DResourceSystem_Init() { - auto D3DTextureBuffer_Setup = (void(__thiscall*)(D3DTextureBuffer * pThis, int format, int width, int bOneLevel, int capacity))0x72FE80; - auto D3DIndexDataBuffer_Setup = (void(__thiscall*)(D3DIndexDataBuffer * pThis, int format, int a3, int capacity))0x730190; + auto args_textureBufferSetup = PrepareSignature(&D3DResourceSystem_TextureBuffer, 0, 0, -1, 16); + auto args_dataBufferSetup = PrepareSignature(&D3DResourceSystem_IndexDataBuffer, D3DFMT_INDEX16, 0, 16); D3DResourceSystem_UseD3DResourceBuffering = false; D3DResourceSystem_FreeTextureBufferIndex = 0; - D3DTextureBuffer_Setup(&D3DResourceSystem_TextureBuffer, 0, 0, -1, 16); - D3DIndexDataBuffer_Setup(&D3DResourceSystem_IndexDataBuffer, D3DFMT_INDEX16, 0, 16); + + CallGTAFunction(0x72FE80, args_textureBufferSetup); + CallGTAFunction(0x730190, args_dataBufferSetup); } void D3DResourceSystem_SetUseD3DResourceBuffering(char bUse) diff --git a/Client/game_sa/gamesa_init.h b/Client/game_sa/gamesa_init.h index 95d3bbd1da..b73e15dca5 100644 --- a/Client/game_sa/gamesa_init.h +++ b/Client/game_sa/gamesa_init.h @@ -104,3 +104,62 @@ void MemOrFast(U ptr, const T value) bool GetDebugIdEnabled(uint uiDebugId); void LogEvent(uint uiDebugId, const char* szType, const char* szContext, const char* szBody, uint uiAddReportLogId = 0); + +struct __THISCALL{}; +struct __CDECL{}; +struct __STDCALL{}; +struct __FASTCALL{}; +struct __VECTORCALL{}; + +template +struct GTAFuncSignature +{ + std::tuple args; + GTAFuncSignature(Args... a) : args(std::forward(a)...) {} +}; + +template +GTAFuncSignature PrepareSignature(Args... args) +{ + return GTAFuncSignature(std::forward(args)...); +} + +template +ReturnType apply_helper(Func&& f, Tuple&& t, std::index_sequence) +{ + return f(std::get(std::forward(t))...); +} + +template +ReturnType CallGTAFunction(Func function, GTAFuncSignature& sig) +{ + if constexpr (std::is_same_v) + { + return apply_helper(reinterpret_cast(function), sig.args, std::index_sequence_for{}); + } + else if constexpr (std::is_same_v) + { + return apply_helper(reinterpret_cast(function), sig.args, std::index_sequence_for{}); + } + else if constexpr (std::is_same_v) + { + return apply_helper(reinterpret_cast(function), sig.args, std::index_sequence_for{}); + } + else if constexpr (std::is_same_v) + { + return apply_helper(reinterpret_cast(function), sig.args, std::index_sequence_for{}); + } + else if constexpr (std::is_same_v) + { + return apply_helper(reinterpret_cast(function), sig.args, std::index_sequence_for{}); + } + + static_assert( + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v, + "Invalid calling onvention specified in CallGTAFunction" + ); +}