From 76c2a87c2372ed09a607f3cb9ab51c4e195230e6 Mon Sep 17 00:00:00 2001 From: FileEX Date: Sat, 2 Nov 2024 18:04:56 +0100 Subject: [PATCH 1/4] Fix setVehicleDirtLevel --- Client/game_sa/CModelInfoSA.h | 30 ++++- Client/game_sa/gamesa_renderware.h | 2 + Client/game_sa/gamesa_renderware.hpp | 3 +- .../CMultiplayerSA_Vehicles.cpp | 109 ++++++++++++++++++ 4 files changed, 140 insertions(+), 4 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index b261bcc04a1..e4387a42ae3 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -14,6 +14,7 @@ #include #include #include "CRenderWareSA.h" +#include "game/RenderWare.h" class CPedModelInfoSA; class CPedModelInfoSAInterface; @@ -259,11 +260,22 @@ class CTimeModelInfoSAInterface : public CBaseModelInfoSAInterface CTimeInfoSAInterface timeInfo; }; +class CVehicleModelUpgradePosnDesc +{ + CVector m_vPosition; + RtQuat m_vRotation; + int m_iParentId; +}; + class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change { public: - CVector vecDummies[15]; - char m_sUpgrade[18]; + CVector vecDummies[15]; + CVehicleModelUpgradePosnDesc m_sUpgrade[18]; + RpAtomic* m_pExtra[6]; + std::uint8_t m_numExtras; + std::uint8_t _pad[3]; + int m_maskComponentDamagable; }; class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface @@ -290,7 +302,19 @@ class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface float fSteeringAngle; CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92 char pad3[464]; - char pDirtMaterial[64]; // *RwMaterial + //RpMaterial* pDirtMaterial[32]; + + union + { + struct + { + RpMaterial** m_dirtMaterials; + size_t m_numDirtMaterials; + RpMaterial* m_staticDirtMaterials[30]; + }; + RpMaterial* pDirtMaterial[32]; + }; + char pad4[64]; char primColors[8]; char secondColors[8]; diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index 594c203b59e..4073f8f2b2b 100644 --- a/Client/game_sa/gamesa_renderware.h +++ b/Client/game_sa/gamesa_renderware.h @@ -105,6 +105,7 @@ typedef RpHAnimHierarchy*(__cdecl* GetAnimHierarchyFromSkinClump_t)(RpClump*); typedef int(__cdecl* RpHAnimIDGetIndex_t)(RpHAnimHierarchy*, int); typedef RwMatrix*(__cdecl* RpHAnimHierarchyGetMatrixArray_t)(RpHAnimHierarchy*); typedef RtQuat*(__cdecl* RtQuatRotate_t)(RtQuat* quat, const RwV3d* axis, float angle, RwOpCombineType combineOp); +typedef RpGeometry*(__cdecl* RpGeometryForAllMaterials_t)(RpGeometry* geom, void* callback, void* data); /*****************************************************************************/ /** Renderware function mappings **/ @@ -195,6 +196,7 @@ RWFUNC(GetAnimHierarchyFromSkinClump_t GetAnimHierarchyFromSkinClump, (GetAnimHi RWFUNC(RpHAnimIDGetIndex_t RpHAnimIDGetIndex, (RpHAnimIDGetIndex_t)0xDEAD) RWFUNC(RpHAnimHierarchyGetMatrixArray_t RpHAnimHierarchyGetMatrixArray, (RpHAnimHierarchyGetMatrixArray_t)0xDEAD) RWFUNC(RtQuatRotate_t RtQuatRotate, (RtQuatRotate_t)0xDEAD) +RWFUNC(RpGeometryForAllMaterials_t RpGeometryForAllMaterials, (RpGeometryForAllMaterials_t)0xDEAD) /*****************************************************************************/ /** GTA function definitions and mappings **/ diff --git a/Client/game_sa/gamesa_renderware.hpp b/Client/game_sa/gamesa_renderware.hpp index a638cfede04..f52d205ddab 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -89,7 +89,8 @@ void InitRwFunctions() RpHAnimIDGetIndex = (RpHAnimIDGetIndex_t)0x7C51A0; RpHAnimHierarchyGetMatrixArray = (RpHAnimHierarchyGetMatrixArray_t)0x7C5120; RtQuatRotate = (RtQuatRotate_t)0x7EB7C0; - + RpGeometryForAllMaterials = (RpGeometryForAllMaterials_t)0x74C790; + SetTextureDict = (SetTextureDict_t)0x007319C0; LoadClumpFile = (LoadClumpFile_t)0x005371F0; LoadModel = (LoadModel_t)0x0040C6B0; diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index 88b0b11eb8a..cd650d7d4f0 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -9,6 +9,10 @@ *****************************************************************************/ #include "StdInc.h" +#include "..\game_sa\gamesa_renderware.h" + +#define FUNC_CVehicleModelInfo_ResetColors 0x4C8490 +static RwTexture** ms_aDirtTextures = (RwTexture**)0xC02BD0; static bool __fastcall AreVehicleDoorsUndamageable(CVehicleSAInterface* vehicle) { @@ -107,6 +111,106 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() } } +static void CVehicleModelInfo_Shutdown() +{ + CVehicleModelInfoSAInterface* mi = nullptr; + _asm + { + mov mi, ecx + } + + if (!mi) + return; + + // Call CBaseModelInfo::Shutdown + ((void(__cdecl*)(void*))0x4C4D50)(mi); + + delete[] mi->m_dirtMaterials; + mi->m_dirtMaterials = nullptr; +} + +static void SetDirtTextures(CVehicleModelInfoSAInterface* mi, std::uint32_t level) +{ + RpMaterial** materials = mi->m_numDirtMaterials > 30 ? mi->m_dirtMaterials : mi->m_staticDirtMaterials; + for (std::uint32_t i = 0; i < mi->m_numDirtMaterials; i++) + RpMaterialSetTexture(materials[i], ms_aDirtTextures[level]); +} + +#define HOOKPOS_CVehicleModelInfo_SetDirtTextures 0x5D5DBB +#define HOOKSIZE_CVehicleModelInfo_SetDirtTextures 6 +static constexpr DWORD CONTINUE_CVehicleModelInfo_SetDirtTextures = 0x5D5DE3; +static void _declspec(naked) HOOK_CVehicleModelInfo_SetDirtTextures() +{ + _asm + { + pushad + push ebx + push esi + call SetDirtTextures + add esp, 8 + popad + + jmp CONTINUE_CVehicleModelInfo_SetDirtTextures + } +} + +static RpMaterial* GetAtomicGeometryMaterialsCB(RpMaterial* material, void* data) +{ + RwTexture* texture = material->texture; + if (!texture) + return nullptr; + + auto cbData = static_cast*>(data); + if (texture->name && std::strcmp(texture->name, "vehiclegrunge256") == 0) + cbData->push_back(material); + + return material; +} + +static bool GetEditableMaterialListCB(RpAtomic* atomic, void* data) +{ + RpGeometryForAllMaterials(atomic->geometry, &GetAtomicGeometryMaterialsCB, data); + return true; +} + +static void __fastcall FindEditableMaterialList(CVehicleModelInfoSAInterface* mi) +{ + std::vector list; + RpClumpForAllAtomics(reinterpret_cast(mi->pRwObject), &GetEditableMaterialListCB, &list); + + for (std::uint32_t i = 0; i < mi->pVisualInfo->m_numExtras; i++) + GetEditableMaterialListCB(mi->pVisualInfo->m_pExtra[i], &list); + + mi->m_numDirtMaterials = list.size(); + if (mi->m_numDirtMaterials > 30) + { + mi->m_dirtMaterials = new RpMaterial*[mi->m_numDirtMaterials]; + std::copy(list.begin(), list.end(), mi->m_dirtMaterials); + } + else + { + mi->m_dirtMaterials = nullptr; + std::copy(list.begin(), list.end(), mi->m_staticDirtMaterials); + } + + ((void(__thiscall*)(CVehicleModelInfoSAInterface*))FUNC_CVehicleModelInfo_ResetColors)(mi); +} + +#define HOOKPOS_CVehicleModelInfo_SetClump 0x4C9648 +#define HOOKSIZE_CVehicleModelInfo_SetClump 24 +static constexpr DWORD CONTINUE_CVehicleModelInfo_SetClump = 0x4C9660; +static void _declspec(naked) HOOK_CVehicleModelInfo_SetClump() +{ + _asm + { + pushad + call FindEditableMaterialList + popad + + jmp CONTINUE_CVehicleModelInfo_SetClump + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Vehicles @@ -118,4 +222,9 @@ void CMultiplayerSA::InitHooks_Vehicles() { EZHookInstall(CDamageManager__ProgressDoorDamage); EZHookInstall(CAEVehicleAudioEntity__Initialise); + + // Fix vehicle dirt level + EZHookInstall(CVehicleModelInfo_SetClump); + EZHookInstall(CVehicleModelInfo_SetDirtTextures); + MemCpy((void*)0x85C5E4, &CVehicleModelInfo_Shutdown, 4); } From 2ee6959d192f853aabbb7f51e3b1823f7f4b336b Mon Sep 17 00:00:00 2001 From: FileEX Date: Sat, 2 Nov 2024 18:16:17 +0100 Subject: [PATCH 2/4] Update --- Client/game_sa/CModelInfoSA.h | 1 - Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index e4387a42ae3..162c8dbb14b 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -302,7 +302,6 @@ class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface float fSteeringAngle; CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92 char pad3[464]; - //RpMaterial* pDirtMaterial[32]; union { diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index cd650d7d4f0..ff61c785068 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -12,7 +12,10 @@ #include "..\game_sa\gamesa_renderware.h" #define FUNC_CVehicleModelInfo_ResetColors 0x4C8490 -static RwTexture** ms_aDirtTextures = (RwTexture**)0xC02BD0; +#define FUNC_CBaseModelInfo_Shutdown 0x4C4D50 +#define IN_PLACE_BUFFER_DIRT_SIZE 30 + +static RwTexture** const ms_aDirtTextures = (RwTexture**)0xC02BD0; static bool __fastcall AreVehicleDoorsUndamageable(CVehicleSAInterface* vehicle) { @@ -122,8 +125,7 @@ static void CVehicleModelInfo_Shutdown() if (!mi) return; - // Call CBaseModelInfo::Shutdown - ((void(__cdecl*)(void*))0x4C4D50)(mi); + ((void(__cdecl*)(void*))FUNC_CBaseModelInfo_Shutdown)(mi); delete[] mi->m_dirtMaterials; mi->m_dirtMaterials = nullptr; @@ -131,7 +133,7 @@ static void CVehicleModelInfo_Shutdown() static void SetDirtTextures(CVehicleModelInfoSAInterface* mi, std::uint32_t level) { - RpMaterial** materials = mi->m_numDirtMaterials > 30 ? mi->m_dirtMaterials : mi->m_staticDirtMaterials; + RpMaterial** materials = mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE ? mi->m_dirtMaterials : mi->m_staticDirtMaterials; for (std::uint32_t i = 0; i < mi->m_numDirtMaterials; i++) RpMaterialSetTexture(materials[i], ms_aDirtTextures[level]); } @@ -182,7 +184,7 @@ static void __fastcall FindEditableMaterialList(CVehicleModelInfoSAInterface* mi GetEditableMaterialListCB(mi->pVisualInfo->m_pExtra[i], &list); mi->m_numDirtMaterials = list.size(); - if (mi->m_numDirtMaterials > 30) + if (mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE) { mi->m_dirtMaterials = new RpMaterial*[mi->m_numDirtMaterials]; std::copy(list.begin(), list.end(), mi->m_dirtMaterials); From 9d746c3b48780412dacd98857846e1c50ff2c8d3 Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 15 Nov 2024 16:52:36 +0100 Subject: [PATCH 3/4] Review --- Client/game_sa/CModelInfoSA.h | 72 ++++++++++--------- .../CMultiplayerSA_Vehicles.cpp | 22 +++--- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index 162c8dbb14b..76731e18085 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -232,6 +232,11 @@ class CBaseModelInfoSAInterface // +726 = Word array as referenced in CVehicleModelInfo::GetVehicleUpgrade(int) // +762 = Array of WORD containing something relative to paintjobs // +772 = Anim file index + + void Shutdown() + { + ((void(*)())VFTBL->Shutdown)(); + } }; static_assert(sizeof(CBaseModelInfoSAInterface) == 0x20, "Invalid size for CBaseModelInfoSAInterface"); @@ -278,30 +283,31 @@ class CVehicleModelVisualInfoSAInterface // Not sure about this name. int m_maskComponentDamagable; }; -class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface +class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface { public: - uint32 pad1; // +32 - RpMaterial* pPlateMaterial; // +36 + RpMaterial* pPlateMaterial; char plateText[8]; - char pad[2]; + std::uint8_t field_30; + std::uint8_t plateType; char gameName[8]; - char pad2[2]; - unsigned int uiVehicleType; + std::uint8_t field_3A[2]; + std::uint32_t vehicleType; float fWheelSizeFront; float fWheelSizeRear; - short sWheelModel; - short sHandlingID; - byte ucNumDoors; - byte ucVehicleList; - byte ucVehicleFlags; - byte ucWheelUpgradeClass; - byte ucTimesUsed; - short sVehFrequency; - unsigned int uiComponentRules; - float fSteeringAngle; - CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92 - char pad3[464]; + std::int16_t wheelModelID; + std::int16_t handlingID; + std::uint8_t numDoors; + std::uint8_t vehicleClass; + std::uint8_t vehicleFlags; + std::uint8_t wheelUpgradeClass; + std::uint8_t timesUsed; + std::uint8_t field_51; + std::int16_t vehFrequency; + std::uint32_t componentRules; + float bikeSteeringAngle; + CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct + std::uint8_t field_60[464]; union { @@ -311,24 +317,22 @@ class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface size_t m_numDirtMaterials; RpMaterial* m_staticDirtMaterials[30]; }; - RpMaterial* pDirtMaterial[32]; }; - char pad4[64]; - char primColors[8]; - char secondColors[8]; - char treeColors[8]; - char fourColors[8]; - unsigned char ucNumOfColorVariations; - unsigned char ucLastColorVariation; - unsigned char ucPrimColor; - unsigned char ucSecColor; - unsigned char ucTertColor; - unsigned char ucQuatColor; - char upgrades[36]; - char anRemapTXDs[8]; - char pad5[2]; - char pAnimBlock[4]; + std::uint8_t primColors[8]; + std::uint8_t secondColors[8]; + std::uint8_t treeColors[8]; + std::uint8_t fourColors[8]; + std::uint8_t numOfColorVariations; + std::uint8_t lastColorVariation; + std::uint8_t primColor; + std::uint8_t secColor; + std::uint8_t tertColor; + std::uint8_t quatColor; + std::uint8_t upgrades[36]; + std::uint8_t anRemapTXDs[8]; + std::uint8_t field_302[2]; + void* pAnimBlock; // CAnimBlock* }; class CModelInfoSA : public CModelInfo diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index ff61c785068..afaa8de6f1b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -11,7 +11,6 @@ #include "StdInc.h" #include "..\game_sa\gamesa_renderware.h" -#define FUNC_CVehicleModelInfo_ResetColors 0x4C8490 #define FUNC_CBaseModelInfo_Shutdown 0x4C4D50 #define IN_PLACE_BUFFER_DIRT_SIZE 30 @@ -114,18 +113,12 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() } } -static void CVehicleModelInfo_Shutdown() +static void __fastcall CVehicleModelInfo_Shutdown(CVehicleModelInfoSAInterface* mi) { - CVehicleModelInfoSAInterface* mi = nullptr; - _asm - { - mov mi, ecx - } - if (!mi) return; - ((void(__cdecl*)(void*))FUNC_CBaseModelInfo_Shutdown)(mi); + mi->Shutdown(); delete[] mi->m_dirtMaterials; mi->m_dirtMaterials = nullptr; @@ -145,12 +138,10 @@ static void _declspec(naked) HOOK_CVehicleModelInfo_SetDirtTextures() { _asm { - pushad push ebx push esi call SetDirtTextures add esp, 8 - popad jmp CONTINUE_CVehicleModelInfo_SetDirtTextures } @@ -195,7 +186,10 @@ static void __fastcall FindEditableMaterialList(CVehicleModelInfoSAInterface* mi std::copy(list.begin(), list.end(), mi->m_staticDirtMaterials); } - ((void(__thiscall*)(CVehicleModelInfoSAInterface*))FUNC_CVehicleModelInfo_ResetColors)(mi); + mi->primColor = 255; + mi->secColor = 255; + mi->tertColor = 255; + mi->quatColor = 255; } #define HOOKPOS_CVehicleModelInfo_SetClump 0x4C9648 @@ -205,9 +199,9 @@ static void _declspec(naked) HOOK_CVehicleModelInfo_SetClump() { _asm { - pushad + push ecx call FindEditableMaterialList - popad + pop ecx jmp CONTINUE_CVehicleModelInfo_SetClump } From be0fa468c3c905866194fb7d1aa85e1b5e1a74dc Mon Sep 17 00:00:00 2001 From: FileEX Date: Sat, 16 Nov 2024 16:30:01 +0100 Subject: [PATCH 4/4] Update Client/game_sa/CModelInfoSA.h Review Co-authored-by: Uladzislau Nikalayevich --- Client/game_sa/CModelInfoSA.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index 76731e18085..971bd6957cd 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -308,17 +308,9 @@ class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface float bikeSteeringAngle; CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct std::uint8_t field_60[464]; - - union - { - struct - { - RpMaterial** m_dirtMaterials; - size_t m_numDirtMaterials; - RpMaterial* m_staticDirtMaterials[30]; - }; - }; - + RpMaterial** m_dirtMaterials; + std::size_t m_numDirtMaterials; + RpMaterial* m_staticDirtMaterials[30]; std::uint8_t primColors[8]; std::uint8_t secondColors[8]; std::uint8_t treeColors[8];