From 0b8cfdd7db9bdc7e15b5d3e307fee599013b8a40 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 12 Aug 2014 22:30:37 +0200 Subject: [PATCH] A better fix for CAutomobile::Fix wrongly rotated components - now matrix is obtained from cclumpmodelinfo clump --- SAFix/ModelInfoSA.cpp | 2 ++ SAFix/ModelInfoSA.h | 2 ++ SAFix/SilentPatchSA.cpp | 14 +++++++++++--- SAFix/StdAfxSA.h | 1 + SAFix/VehicleSA.cpp | 43 +++++++++++++++++++++++++++++++++++++++++ SAFix/VehicleSA.h | 2 ++ 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/SAFix/ModelInfoSA.cpp b/SAFix/ModelInfoSA.cpp index 7d22cb0..3df38a7 100644 --- a/SAFix/ModelInfoSA.cpp +++ b/SAFix/ModelInfoSA.cpp @@ -9,6 +9,8 @@ bool (*CCustomCarPlateMgr::GeneratePlateText)(char* pBuf, int nLen) = AddressByV signed char (*CCustomCarPlateMgr::GetMapRegionPlateDesign)() = AddressByVersion(0x6FD7A0, 0, 0); void (*CCustomCarPlateMgr::SetupMaterialPlatebackTexture)(RpMaterial* pMaterial, signed char nDesign) = AddressByVersion(0x6FDE50, 0, 0); +CBaseModelInfo** const ms_modelInfoPtrs = *AddressByVersion(0x509CB1, 0, 0); + void CVehicleModelInfo::Shutdown() { CBaseModelInfo::Shutdown(); diff --git a/SAFix/ModelInfoSA.h b/SAFix/ModelInfoSA.h index 403ca94..827aa28 100644 --- a/SAFix/ModelInfoSA.h +++ b/SAFix/ModelInfoSA.h @@ -281,6 +281,8 @@ public: static RpMaterial* GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData); }; +extern CBaseModelInfo** const ms_modelInfoPtrs; + #define NUM_MAX_PLATES 12 class CCustomCarPlateMgr diff --git a/SAFix/SilentPatchSA.cpp b/SAFix/SilentPatchSA.cpp index 44a999a..87f0406 100644 --- a/SAFix/SilentPatchSA.cpp +++ b/SAFix/SilentPatchSA.cpp @@ -9,6 +9,8 @@ #include "PNGFile.h" // RW wrappers +static void* varRwFrameForAllChildren = AddressByVersion(0x7F0DC0, 0, 0); +WRAPPER RwFrame* RwFrameForAllChildren(RwFrame* frame, RwFrameCallBack callBack, void* data) { WRAPARG(frame); WRAPARG(callBack); WRAPARG(data); VARJMP(varRwFrameForAllChildren); } static void* varRwFrameForAllObjects = AddressByVersion(0x7F1200, 0, 0); WRAPPER RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, void* data) { WRAPARG(frame); WRAPARG(callBack); WRAPARG(data); VARJMP(varRwFrameForAllObjects); } static void* varRpClumpForAllAtomics = AddressByVersion(0x749B70, 0, 0); @@ -55,14 +57,20 @@ WRAPPER RwBool _rpD3D9VertexDeclarationInstColor(RwUInt8 *mem, RwInt32 numVerts, RwUInt32 stride) { VARJMP(var_rpD3D9VertexDeclarationInstColor); } +RwMatrix* RwMatrixUpdate(RwMatrix* matrix) +{ + matrix->flags &= ~(rwMATRIXTYPEMASK|rwMATRIXINTERNALIDENTITY); + return matrix; +} + // Other wrappers void (*GTAdelete)(void*) = AddressByVersion(0x82413F, 0, 0); +const char* (*GetFrameNodeName)(RwFrame*) = AddressByVersion(0x72FB30, 0, 0); auto SetVolume = AddressByVersion(0x4D7C60, 0, 0); auto InitializeUtrax = AddressByVersion(0x4F35B0, 0, 0); auto CanSeeOutSideFromCurrArea = AddressByVersion(0x53C4A0, 0, 0); auto __rwD3D9TextureHasAlpha = AddressByVersion(0x4C9EA0, 0, 0); -auto GetFrameNodeName = AddressByVersion(0x72FB30, 0, 0); auto RenderOneXLUSprite = AddressByVersion(0x70D000, 0, 0); // That function is fake @@ -1408,8 +1416,8 @@ __forceinline void Patch_SA_10() // Patched CAutomobile::Fix // misc_x parts don't get reset (Bandito fix), Towtruck's bouncing panel is not reset - //Patch(0x6A34C9, 0x5EEB); - Patch(0x6A34D0, 10); + Patch(0x6A34C9, 0x5EEB); + //Patch(0x6A34D0, 10); Patch(0x6A3555, 0x5E5FCF8B); Patch(0x6A3559, 0x448B5B5D); Patch(0x6A355D, 0x89644824); diff --git a/SAFix/StdAfxSA.h b/SAFix/StdAfxSA.h index 14422d5..c932a39 100644 --- a/SAFix/StdAfxSA.h +++ b/SAFix/StdAfxSA.h @@ -49,6 +49,7 @@ struct AlphaObjectInfo // SA operator delete extern void (*GTAdelete)(void* data); +extern const char* (*GetFrameNodeName)(RwFrame*); extern unsigned char& nGameClockDays; extern unsigned char& nGameClockMonths; diff --git a/SAFix/VehicleSA.cpp b/SAFix/VehicleSA.cpp index 21cb2a9..61713bf 100644 --- a/SAFix/VehicleSA.cpp +++ b/SAFix/VehicleSA.cpp @@ -20,6 +20,21 @@ static RwObject* GetCurrentAtomicObjectCB(RwObject* pObject, void* data) return pObject; } +static RwFrame* GetFrameFromNameCB(RwFrame* pFrame, void* pData) +{ + // Is this a frame we want? + std::pair* pFindData = static_cast*>(pData); + if ( !strncmp(pFindData->first, GetFrameNodeName(pFrame), 24) ) + { + pFindData->second = pFrame; + return nullptr; + } + + // Try children + RwFrameForAllChildren(pFrame, GetFrameFromNameCB, pData); + return !pFindData->second ? pFrame : nullptr; +} + bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo) { char PlateText[8]; @@ -207,6 +222,8 @@ void CPlane::Render() void CAutomobile::Fix_SilentPatch() { + ResetFrames(); + // Reset bouncing panels for ( int i = 0; i < 3; i++ ) { @@ -216,4 +233,30 @@ void CAutomobile::Fix_SilentPatch() continue; m_aBouncingPanel[i].m_nNodeIndex = -1; } +} + +void CAutomobile::ResetFrames() +{ + RpClump* pOrigClump = reinterpret_cast(ms_modelInfoPtrs[m_nModelIndex]->pRwObject); + if ( pOrigClump ) + { + // Instead of setting frame rotation to (0,0,0) like R* did, obtain the original frame matrix from CBaseNodelInfo clump + for ( int i = 8; i < 25; i++ ) + { + if ( m_pCarNode[i] ) + { + // Find a frame in CBaseModelInfo object + std::pair FindData = std::make_pair(GetFrameNodeName(m_pCarNode[i]), nullptr); + + RwFrameForAllChildren(RpClumpGetFrame(pOrigClump), GetFrameFromNameCB, &FindData); + + if ( FindData.second ) + { + // Found a frame, reset it + *RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(FindData.second); + RwMatrixUpdate(RwFrameGetMatrix(m_pCarNode[i])); + } + } + } + } } \ No newline at end of file diff --git a/SAFix/VehicleSA.h b/SAFix/VehicleSA.h index 01da4b3..dea07a7 100644 --- a/SAFix/VehicleSA.h +++ b/SAFix/VehicleSA.h @@ -140,6 +140,8 @@ public: public: void Fix_SilentPatch(); + + void ResetFrames(); }; class NOVMT CHeli : public CAutomobile