A better fix for CAutomobile::Fix wrongly rotated components - now matrix is obtained from cclumpmodelinfo clump

This commit is contained in:
Silent 2014-08-12 22:30:37 +02:00
parent e4e9495cb0
commit 0b8cfdd7db
6 changed files with 61 additions and 3 deletions

View File

@ -9,6 +9,8 @@ bool (*CCustomCarPlateMgr::GeneratePlateText)(char* pBuf, int nLen) = AddressByV
signed char (*CCustomCarPlateMgr::GetMapRegionPlateDesign)() = AddressByVersion<signed char(*)()>(0x6FD7A0, 0, 0);
void (*CCustomCarPlateMgr::SetupMaterialPlatebackTexture)(RpMaterial* pMaterial, signed char nDesign) = AddressByVersion<void(*)(RpMaterial*,signed char)>(0x6FDE50, 0, 0);
CBaseModelInfo** const ms_modelInfoPtrs = *AddressByVersion<CBaseModelInfo***>(0x509CB1, 0, 0);
void CVehicleModelInfo::Shutdown()
{
CBaseModelInfo::Shutdown();

View File

@ -281,6 +281,8 @@ public:
static RpMaterial* GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData);
};
extern CBaseModelInfo** const ms_modelInfoPtrs;
#define NUM_MAX_PLATES 12
class CCustomCarPlateMgr

View File

@ -9,6 +9,8 @@
#include "PNGFile.h"
// RW wrappers
static void* varRwFrameForAllChildren = AddressByVersion<void*>(0x7F0DC0, 0, 0);
WRAPPER RwFrame* RwFrameForAllChildren(RwFrame* frame, RwFrameCallBack callBack, void* data) { WRAPARG(frame); WRAPARG(callBack); WRAPARG(data); VARJMP(varRwFrameForAllChildren); }
static void* varRwFrameForAllObjects = AddressByVersion<void*>(0x7F1200, 0, 0);
WRAPPER RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, void* data) { WRAPARG(frame); WRAPARG(callBack); WRAPARG(data); VARJMP(varRwFrameForAllObjects); }
static void* varRpClumpForAllAtomics = AddressByVersion<void*>(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<void(*)(void*)>(0x82413F, 0, 0);
const char* (*GetFrameNodeName)(RwFrame*) = AddressByVersion<const char*(*)(RwFrame*)>(0x72FB30, 0, 0);
auto SetVolume = AddressByVersion<void(__thiscall*)(void*,float)>(0x4D7C60, 0, 0);
auto InitializeUtrax = AddressByVersion<void(__thiscall*)(void*)>(0x4F35B0, 0, 0);
auto CanSeeOutSideFromCurrArea = AddressByVersion<bool(*)()>(0x53C4A0, 0, 0);
auto __rwD3D9TextureHasAlpha = AddressByVersion<BOOL(*)(RwTexture*)>(0x4C9EA0, 0, 0);
auto GetFrameNodeName = AddressByVersion<const char*(*)(RwFrame*)>(0x72FB30, 0, 0);
auto RenderOneXLUSprite = AddressByVersion<void(*)(float, float, float, float, float, int, int, int, int, float, char, char, char)>(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<WORD>(0x6A34C9, 0x5EEB);
Patch<DWORD>(0x6A34D0, 10);
Patch<WORD>(0x6A34C9, 0x5EEB);
//Patch<DWORD>(0x6A34D0, 10);
Patch<DWORD>(0x6A3555, 0x5E5FCF8B);
Patch<DWORD>(0x6A3559, 0x448B5B5D);
Patch<DWORD>(0x6A355D, 0x89644824);

View File

@ -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;

View File

@ -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<const char*,RwFrame*>* pFindData = static_cast<std::pair<const char*,RwFrame*>*>(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<RpClump*>(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<const char*,RwFrame*> 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]));
}
}
}
}
}

View File

@ -140,6 +140,8 @@ public:
public:
void Fix_SilentPatch();
void ResetFrames();
};
class NOVMT CHeli : public CAutomobile