Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
FileEX committed Sep 11, 2024
1 parent 25a207b commit 722576b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 32 deletions.
12 changes: 7 additions & 5 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1834,20 +1834,22 @@ bool CModelInfoSA::MakeClumpModel()
// Copy existing data to the new interface
CBaseModelInfoSAInterface* pBaseObjectInfo = ppModelInfo[m_dwModelID];
MemCpyFast(newInterface, pBaseObjectInfo, sizeof(CClumpModelInfoSAInterface));

newInterface->bHasComplexHierarchy = true;
newInterface->m_nAnimFileIndex = -1;

// Create new empty clump like CFileLoader::LoadClumpFile
RpClump* parentClump = RpClumpCreate();
RpClump* parentClump = RpClumpCreate();
RpSetFrame(parentClump, RwFrameCreate());

// Set temp atomic to avoid crash because of empty clump
//RpClumpAddAtomic(parentClump, reinterpret_cast<RpAtomic*>(pBaseObjectInfo->pRwObject));

// Call CClumpModelInfo::SetClump
((void(__thiscall*)(CClumpModelInfoSAInterface*, RpClump*))FUNC_CClumpModelInfo_SetClump)(newInterface, parentClump);

// Call CAtomicModelInfo::DeleteRwObject
((void(__thiscall*)(CAtomicModelInfoSAInterface*))FUNC_CAtomicModelInfo_DeleteRwObject)(static_cast<CAtomicModelInfoSAInterface*>(pBaseObjectInfo));

// Replace interface with new
delete reinterpret_cast<CBaseModelInfoSAInterface*>(ppModelInfo[m_dwModelID]);
delete ppModelInfo[m_dwModelID];
ppModelInfo[m_dwModelID] = newInterface;

m_dwParentID = -1;
Expand Down
4 changes: 4 additions & 0 deletions Client/game_sa/CModelInfoSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ static void* ARRAY_ModelInfo = *(void**)(0x403DA4 + 3);
#define VAR_CTempColModels_ModelPed1 0x968DF0

#define FUNC_CClumpModelInfo_SetClump 0x4C4F70
#define FUNC_CClumpModelInfo_DeleteRwObject 0x4C4E70

#define FUNC_CAtomicModelInfo_SetAtomic 0x4C4360
#define FUNC_CAtomicModelInfo_DeleteRwObject 0x4C4440

#define FUNC_CVisibilityPlugins_SetAtomicId 0x732230

class CBaseModelInfoSAInterface;
Expand Down
86 changes: 59 additions & 27 deletions Client/game_sa/CRenderWareSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,43 +504,69 @@ struct SAtomicsClone
RpClump* clump;
};

static bool CopyAllFramesCB(RwFrame* frame, void* data)
{
RwFrame* targetFrame = static_cast<RwFrame*>(data);

RwFrame* newFrame = RwFrameCreate();
RwFrameCopyMatrix(newFrame, frame);
std::strncpy(newFrame->szName, frame->szName, 24);

RwFrameAddChild(targetFrame, newFrame);
RwFrameForAllChildren(frame, CopyAllFramesCB, newFrame);
return true;
}

static bool CloneAtomicsToClumpCB(RpAtomic* atomic, void* data)
{
auto* cbData = reinterpret_cast<SAtomicsClone*>(data);

// Clone atomic
// Clone the atomic
RpAtomic* clone = RpAtomicClone(atomic);
RwFrame* frame = RpGetFrame(atomic);

// Set frames
RpAtomicSetFrame(clone, frame);

// Add atomic to new clump
RpClumpAddAtomic(cbData->clump, clone);

RwFrame* oldFrame = RpGetFrame(atomic);
RwFrame* originalFrame = RpGetFrame(atomic);
RwFrame* newFrame = RwFrameCreate();
RwFrameCopyMatrix(newFrame, originalFrame);
std::strncpy(newFrame->szName, originalFrame->szName, 24);
RpAtomicSetFrame(clone, newFrame);
RwFrameCopyMatrix(RpGetFrame(clone), oldFrame);

RwFrame* rootFrame = RpGetFrame(cbData->clump);
RwFrameAddChild(rootFrame, newFrame);

// Update atomic ID like in the CFileLoader::SetRelatedModelInfoCB
// Call CVisibilityPlugins::SetAtomicId
RwFrameForAllChildren(originalFrame, CopyAllFramesCB, newFrame);

// Copy geometry
RpGeometry originalGeometry = *atomic->geometry;
clone->geometry = &originalGeometry;

// Add the atomic to the new clump
RpClumpAddAtomic(cbData->clump, clone);

// Update atomic ID
((int(__cdecl*)(RpAtomic*, std::uint16_t))FUNC_CVisibilityPlugins_SetAtomicId)(clone, cbData->modelID);

return true;
}

static bool GetFirstAtomicCB(RpAtomic* atomic, void* data)
static bool testCB(RpAtomic* atomic, void* data)
{
RpAtomic** firstAtomic = reinterpret_cast<RpAtomic**>(data);
if (!*firstAtomic)
*firstAtomic = atomic;
RpAtomic* currentAtomic = atomic;
RwFrame* currentFrame = RpGetFrame(atomic);

CModelInfo* modelInfo = pGame->GetModelInfo((DWORD)3425);
if (!modelInfo)
return false;

RpAtomic* originalAtomic = reinterpret_cast<RpAtomic*>(modelInfo->GetInterface()->pRwObject);
if (!originalAtomic)
return false;

RwFrame* originalFrame = RpGetFrame(originalAtomic);

return true;
}

static bool clumpReplaced = false;
bool CRenderWareSA::ReplaceAllAtomicsInModel(RpClump* newClump, std::uint16_t modelID, bool isClump)
{
CModelInfo* modelInfo = pGame->GetModelInfo(modelID);
Expand All @@ -551,37 +577,43 @@ bool CRenderWareSA::ReplaceAllAtomicsInModel(RpClump* newClump, std::uint16_t mo
if (reinterpret_cast<RpClump*>(oldAtomic) == newClump || DoContainTheSameGeometry(newClump, nullptr, oldAtomic))
return true;

// Clone the clump that's to be replaced (CFileLoader_SetRelatedModelInfoCB removes the atomics from the source clump)
RpClump* copy = RpClumpClone(newClump);

// Check if new model is clump or atomic
if (isClump)
{
// Clump already created for this model?
if (clumpReplaced)
return true;

SAtomicsClone data = {};
data.modelID = modelID;

// Get our new clump created in MakeClumpModel
data.clump = reinterpret_cast<RpClump*>(modelInfo->GetInterface()->pRwObject);

//RpAtomic* firstAtomic = nullptr;
//RpClumpForAllAtomics(data.clump, GetFirstAtomicCB, &firstAtomic);
//RpClumpRemoveAtomic(data.clump, firstAtomic);

// Clone atomics from new model to our empty clump
RpClumpForAllAtomics(copy, CloneAtomicsToClumpCB, &data);
RpClumpForAllAtomics(newClump, CloneAtomicsToClumpCB, &data);

clumpReplaced = true;

int num = RpClumpGetNumAtomics(data.clump);
RpClumpForAllAtomics(data.clump, testCB, data.clump);
}
else
{
// Clone the clump that's to be replaced (CFileLoader_SetRelatedModelInfoCB removes the atomics from the source clump)
RpClump* copy = RpClumpClone(newClump);

// Replace the atomics
SAtomicsReplace data = {};
data.txdID = static_cast<CBaseModelInfoSAInterface**>(ARRAY_ModelInfo)[modelID]->usTextureDictionary;
data.clump = copy;

MemPutFast<DWORD>(reinterpret_cast<DWORD*>(DWORD_AtomicsReplacerModelID), modelID);
RpClumpForAllAtomics(copy, ReplaceAtomicsInModelCB, &data);
}

// Destroy empty clump
RpClumpDestroy(copy);
// Destroy empty clump
RpClumpDestroy(copy);
}

return true;
}
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/gamesa_renderware.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ 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 RpClump*(__cdecl* RpClumpCreate_t)();
typedef RwFrame*(__cdecl* RwFrameForAllChildren_t)(RwFrame* frame, void* callback, void* data);

/*****************************************************************************/
/** Renderware function mappings **/
Expand Down Expand Up @@ -197,6 +198,7 @@ RWFUNC(RpHAnimIDGetIndex_t RpHAnimIDGetIndex, (RpHAnimIDGetIndex_t)0xDEAD)
RWFUNC(RpHAnimHierarchyGetMatrixArray_t RpHAnimHierarchyGetMatrixArray, (RpHAnimHierarchyGetMatrixArray_t)0xDEAD)
RWFUNC(RtQuatRotate_t RtQuatRotate, (RtQuatRotate_t)0xDEAD)
RWFUNC(RpClumpCreate_t RpClumpCreate, reinterpret_cast<RpClumpCreate_t>(0xDEAD))
RWFUNC(RwFrameForAllChildren_t RwFrameForAllChildren, reinterpret_cast<RwFrameForAllChildren_t>(0xDEAD));

/*****************************************************************************/
/** GTA function definitions and mappings **/
Expand Down
1 change: 1 addition & 0 deletions Client/game_sa/gamesa_renderware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void InitRwFunctions()
RpHAnimHierarchyGetMatrixArray = (RpHAnimHierarchyGetMatrixArray_t)0x7C5120;
RtQuatRotate = (RtQuatRotate_t)0x7EB7C0;
RpClumpCreate = reinterpret_cast<RpClumpCreate_t>(0x74A290);
RwFrameForAllChildren = reinterpret_cast<RwFrameForAllChildren_t>(0x7F0DC0);

SetTextureDict = (SetTextureDict_t)0x007319C0;
LoadClumpFile = (LoadClumpFile_t)0x005371F0;
Expand Down

0 comments on commit 722576b

Please sign in to comment.