Implement/match LegoPartPresenter::Read (#642)

* WIP

* Match

* Remove TODO

* Fix
This commit is contained in:
Christian Semmler 2024-03-09 12:27:53 -05:00 committed by GitHub
parent 9e2f37e7ca
commit 9f875d01e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 311 additions and 8 deletions

View file

@ -0,0 +1,52 @@
#ifndef LEGOLODLIST_H
#define LEGOLODLIST_H
#include "mxlist.h"
#include "roi/legolod.h"
#pragma warning(disable : 4786)
// VTABLE: LEGO1 0x100d9d30
// class MxCollection<LegoLOD *>
// VTABLE: LEGO1 0x100d9d48
// class MxList<LegoLOD *>
// VTABLE: LEGO1 0x100d9d60
// class MxPtrList<LegoLOD>
// VTABLE: LEGO1 0x100d9d78
// SIZE 0x18
class LegoLODList : public MxPtrList<LegoLOD> {
public:
LegoLODList() : MxPtrList<LegoLOD>(FALSE) {}
// SYNTHETIC: LEGO1 0x1007de40
// LegoLODList::`scalar deleting destructor'
};
// TEMPLATE: LEGO1 0x1007d480
// MxCollection<LegoLOD *>::Compare
// TEMPLATE: LEGO1 0x1007d490
// MxCollection<LegoLOD *>::~MxCollection<LegoLOD *>
// TEMPLATE: LEGO1 0x1007d4e0
// MxCollection<LegoLOD *>::Destroy
// TEMPLATE: LEGO1 0x1007d4f0
// MxList<LegoLOD *>::~MxList<LegoLOD *>
// SYNTHETIC: LEGO1 0x1007d580
// MxCollection<LegoLOD *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1007d5f0
// MxList<LegoLOD *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1007d6a0
// MxPtrList<LegoLOD>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1007d710
// MxPtrList<LegoLOD>::~MxPtrList<LegoLOD>
#endif // LEGOLODLIST_H

View file

@ -0,0 +1,26 @@
#ifndef LEGONAMEDPART_H
#define LEGONAMEDPART_H
#include "legolodlist.h"
#include "mxstring.h"
// SIZE 0x14
class LegoNamedPart {
public:
LegoNamedPart(const char* p_name, LegoLODList* p_list)
{
m_name = p_name;
m_list = p_list;
}
~LegoNamedPart() { delete m_list; }
const MxString* GetName() const { return &m_name; }
LegoLODList* GetList() { return m_list; }
private:
MxString m_name; // 0x00
LegoLODList* m_list; // 0x04
};
#endif // LEGONAMEDPART_H

View file

@ -0,0 +1,53 @@
#ifndef LEGONAMEDPARTLIST_H
#define LEGONAMEDPARTLIST_H
#include "legonamedpart.h"
#include "mxlist.h"
// VTABLE: LEGO1 0x100d9d90
// class MxCollection<LegoNamedPart *>
// VTABLE: LEGO1 0x100d9da8
// class MxList<LegoNamedPart *>
// VTABLE: LEGO1 0x100d9dc0
// class MxPtrList<LegoNamedPart>
// VTABLE: LEGO1 0x100d9dd8
// SIZE 0x18
class LegoNamedPartList : public MxPtrList<LegoNamedPart> {
public:
LegoNamedPartList() : MxPtrList<LegoNamedPart>(TRUE) {}
// SYNTHETIC: LEGO1 0x1007dbf0
// LegoNamedPartList::`scalar deleting destructor'
};
// TEMPLATE: LEGO1 0x1007d760
// MxCollection<LegoNamedPart *>::Compare
// TEMPLATE: LEGO1 0x1007d770
// MxCollection<LegoNamedPart *>::~MxCollection<LegoNamedPart *>
// TEMPLATE: LEGO1 0x1007d7c0
// MxCollection<LegoNamedPart *>::Destroy
// TEMPLATE: LEGO1 0x1007d7d0
// MxList<LegoNamedPart *>::~MxList<LegoNamedPart *>
// TEMPLATE: LEGO1 0x1007d860
// MxPtrList<LegoNamedPart>::Destroy
// TEMPLATE: LEGO1 0x1007dc60
// MxPtrList<LegoNamedPart>::~MxPtrList<LegoNamedPart>
// SYNTHETIC: LEGO1 0x1007dcb0
// MxCollection<LegoNamedPart *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1007dd20
// MxList<LegoNamedPart *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1007ddd0
// MxPtrList<LegoNamedPart>::`scalar deleting destructor'
#endif // LEGONAMEDPARTLIST_H

View file

@ -1,6 +1,7 @@
#ifndef LEGOPARTPRESENTER_H
#define LEGOPARTPRESENTER_H
#include "legonamedpartlist.h"
#include "mxmediapresenter.h"
// VTABLE: LEGO1 0x100d4df0
@ -34,7 +35,7 @@ class LegoPartPresenter : public MxMediaPresenter {
// SYNTHETIC: LEGO1 0x1000d060
// LegoPartPresenter::`scalar deleting destructor'
inline void Reset() { m_partData = NULL; }
inline void Reset() { m_parts = NULL; }
MxResult Read(MxDSChunk& p_chunk);
void FUN_1007df20();
@ -42,7 +43,7 @@ class LegoPartPresenter : public MxMediaPresenter {
private:
void Destroy(MxBool p_fromDestructor);
MxDSChunk* m_partData; // 0x54
LegoNamedPartList* m_parts; // 0x50
};
#endif // LEGOPARTPRESENTER_H

View file

@ -37,14 +37,15 @@ class LegoWorldPresenter : public LegoEntityPresenter {
MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c
void VTable0x60(MxPresenter* p_presenter) override; // vtable+0x60
MxResult FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile);
MxResult FUN_100674b0(ModelDbModel& p_model, FILE* p_wdbFile, LegoWorld* p_world);
MxResult LoadWorld(char* p_worldName, LegoWorld* p_world);
// SYNTHETIC: LEGO1 0x10066750
// LegoWorldPresenter::`scalar deleting destructor'
private:
MxResult FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile);
MxResult FUN_100674b0(ModelDbModel& p_model, FILE* p_wdbFile, LegoWorld* p_world);
undefined4 m_unk0x50;
};

View file

@ -63,6 +63,7 @@ MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk)
MxMatrix mat;
LegoChar* textureName = NULL;
LegoTexture* texture = NULL;
LegoTextureInfo* textureInfo = NULL;
LegoS32 hardwareMode = VideoManager()->GetDirect3D()->AssignedDevice()->GetHardwareMode();
if (m_roi) {
@ -137,7 +138,7 @@ MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk)
if (!skipTextures) {
if (TextureContainer()->Get(textureName) == NULL) {
LegoTextureInfo* textureInfo = LegoTextureInfo::Create(textureName, texture);
textureInfo = LegoTextureInfo::Create(textureName, texture);
if (textureInfo == NULL) {
goto done;

View file

@ -2,6 +2,13 @@
#include "legoomni.h"
#include "legovideomanager.h"
#include "misc/legocontainer.h"
#include "misc/legostorage.h"
#include "misc/legotexture.h"
DECOMP_SIZE_ASSERT(LegoLODList, 0x18)
DECOMP_SIZE_ASSERT(LegoNamedPart, 0x14)
DECOMP_SIZE_ASSERT(LegoNamedPartList, 0x18)
// GLOBAL: LEGO1 0x100f7aa0
MxS32 g_partPresenterConfig1 = 1;
@ -35,11 +42,172 @@ void LegoPartPresenter::Destroy(MxBool p_fromDestructor)
// TODO
}
// STUB: LEGO1 0x1007ca30
// FUNCTION: LEGO1 0x1007ca30
MxResult LegoPartPresenter::Read(MxDSChunk& p_chunk)
{
// TODO
return SUCCESS;
MxResult result = FAILURE;
LegoU32 numROIs, numLODs;
LegoMemory storage(p_chunk.GetData());
LegoU32 textureInfoOffset, i, j, numTextures;
LegoU32 roiNameLength, roiInfoOffset, surplusLODs;
LegoLODList* lods;
LegoNamedPart* namedPart;
LegoChar* roiName = NULL;
LegoChar* textureName = NULL;
LegoTexture* texture = NULL;
LegoTextureInfo* textureInfo = NULL;
LegoS32 hardwareMode = VideoManager()->GetDirect3D()->AssignedDevice()->GetHardwareMode();
if (storage.Read(&textureInfoOffset, sizeof(textureInfoOffset)) != SUCCESS) {
goto done;
}
if (storage.SetPosition(textureInfoOffset) != SUCCESS) {
goto done;
}
if (storage.Read(&numTextures, sizeof(numTextures)) != SUCCESS) {
goto done;
}
for (i = 0; i < numTextures; i++) {
LegoU32 textureNameLength;
storage.Read(&textureNameLength, sizeof(textureNameLength));
textureName = new LegoChar[textureNameLength + 1];
storage.Read(textureName, textureNameLength);
textureName[textureNameLength] = '\0';
strlwr(textureName);
if (textureName[0] == '^') {
strcpy(textureName, textureName + 1);
if (g_partPresenterConfig1) {
texture = new LegoTexture();
if (texture->Read(&storage, hardwareMode) != SUCCESS) {
goto done;
}
LegoTexture* discardTexture = new LegoTexture();
if (discardTexture->Read(&storage, FALSE) != SUCCESS) {
goto done;
}
delete discardTexture;
}
else {
LegoTexture* discardTexture = new LegoTexture();
if (discardTexture->Read(&storage, FALSE) != SUCCESS) {
goto done;
}
delete discardTexture;
texture = new LegoTexture();
if (texture->Read(&storage, hardwareMode) != SUCCESS) {
goto done;
}
}
}
else {
texture = new LegoTexture();
if (texture->Read(&storage, hardwareMode) != SUCCESS) {
goto done;
}
}
if (TextureContainer()->Get(textureName) == NULL) {
textureInfo = LegoTextureInfo::Create(textureName, texture);
if (textureInfo == NULL) {
goto done;
}
TextureContainer()->Add(textureName, textureInfo);
}
delete[] textureName;
textureName = NULL;
delete texture;
texture = NULL;
}
if (storage.SetPosition(4) != SUCCESS) {
goto done;
}
m_parts = new LegoNamedPartList();
if (storage.Read(&numROIs, sizeof(numROIs)) != SUCCESS) {
goto done;
}
for (i = 0; i < numROIs; i++) {
if (storage.Read(&roiNameLength, sizeof(roiNameLength)) != SUCCESS) {
goto done;
}
roiName = new LegoChar[roiNameLength + 1];
if (storage.Read(roiName, roiNameLength) != SUCCESS) {
goto done;
}
roiName[roiNameLength] = '\0';
strlwr(roiName);
if (storage.Read(&numLODs, sizeof(numLODs)) != SUCCESS) {
goto done;
}
if (storage.Read(&roiInfoOffset, sizeof(roiInfoOffset)) != SUCCESS) {
goto done;
}
if (numLODs > g_partPresenterConfig2) {
surplusLODs = numLODs - g_partPresenterConfig2;
numLODs = g_partPresenterConfig2;
}
else {
surplusLODs = 0;
}
lods = new LegoLODList();
for (j = 0; j < numLODs; j++) {
LegoLOD* lod = new LegoLOD(VideoManager()->GetRenderer());
if (lod->Read(VideoManager()->GetRenderer(), TextureContainer(), &storage) != SUCCESS) {
goto done;
}
if (j == 0) {
if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) {
numLODs++;
surplusLODs--;
}
}
lods->Append(lod);
}
storage.SetPosition(roiInfoOffset);
namedPart = new LegoNamedPart(roiName, lods);
m_parts->Append(namedPart);
delete[] roiName;
roiName = NULL;
}
result = SUCCESS;
done:
if (roiName != NULL) {
delete[] roiName;
}
if (result != SUCCESS && m_parts != NULL) {
delete m_parts;
m_parts = NULL;
}
return result;
}
// STUB: LEGO1 0x1007deb0

View file

@ -10,6 +10,7 @@
DECOMP_SIZE_ASSERT(LegoTexturePresenter, 0x54)
DECOMP_SIZE_ASSERT(LegoNamedTexture, 0x14)
DECOMP_SIZE_ASSERT(LegoNamedTextureList, 0x18)
DECOMP_SIZE_ASSERT(LegoNamedTextureListCursor, 0x10)
// FUNCTION: LEGO1 0x1004eb40
LegoTexturePresenter::~LegoTexturePresenter()