Implement/match LegoModelPresenter::CreateROI (#591)

* Implement/match LegoModelPresenter::CreateROI

* Match

* Use inline function

* Note about Get()
This commit is contained in:
Christian Semmler 2024-02-24 11:48:16 -05:00 committed by GitHub
parent 13fc4e3285
commit b281866ea6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 248 additions and 27 deletions

View file

@ -213,6 +213,7 @@ public:
LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; } LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; }
LegoInputManager* GetInputManager() { return m_inputManager; } LegoInputManager* GetInputManager() { return m_inputManager; }
LegoTextureContainer* GetTextureContainer() { return m_textureContainer; } LegoTextureContainer* GetTextureContainer() { return m_textureContainer; }
ViewLODListManager* GetViewLODListManager() { return m_viewLODListManager; }
LegoWorld* GetCurrentWorld() { return m_currentWorld; } LegoWorld* GetCurrentWorld() { return m_currentWorld; }
LegoNavController* GetNavController() { return m_navController; } LegoNavController* GetNavController() { return m_navController; }
IslePathActor* GetCurrentVehicle() { return m_currentVehicle; } IslePathActor* GetCurrentVehicle() { return m_currentVehicle; }
@ -276,6 +277,7 @@ LegoPlantManager* PlantManager();
LegoWorld* CurrentWorld(); LegoWorld* CurrentWorld();
LegoUnkSaveDataWriter* UnkSaveDataWriter(); LegoUnkSaveDataWriter* UnkSaveDataWriter();
LegoTextureContainer* TextureContainer(); LegoTextureContainer* TextureContainer();
ViewLODListManager* GetViewLODListManager();
void FUN_10015820(MxBool p_disable, MxU16 p_flags); void FUN_10015820(MxBool p_disable, MxU16 p_flags);
void SetROIUnknown0x0c(const char* p_name, undefined p_unk0x0c); void SetROIUnknown0x0c(const char* p_name, undefined p_unk0x0c);
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);

View file

@ -220,6 +220,12 @@ LegoTextureContainer* TextureContainer()
return LegoOmni::GetInstance()->GetTextureContainer(); return LegoOmni::GetInstance()->GetTextureContainer();
} }
// FUNCTION: LEGO1 0x10015810
ViewLODListManager* GetViewLODListManager()
{
return LegoOmni::GetInstance()->GetViewLODListManager();
}
// FUNCTION: LEGO1 0x10015820 // FUNCTION: LEGO1 0x10015820
void FUN_10015820(MxBool p_disable, MxU16 p_flags) void FUN_10015820(MxBool p_disable, MxU16 p_flags)
{ {

View file

@ -1,5 +1,6 @@
#include "legomodelpresenter.h" #include "legomodelpresenter.h"
#include "anim/legoanim.h"
#include "define.h" #include "define.h"
#include "legoentity.h" #include "legoentity.h"
#include "legoentitypresenter.h" #include "legoentitypresenter.h"
@ -7,6 +8,9 @@
#include "legounksavedatawriter.h" #include "legounksavedatawriter.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc/legocontainer.h"
#include "misc/legotexture.h"
#include "misc/version.h"
#include "mxcompositepresenter.h" #include "mxcompositepresenter.h"
#include "mxutil.h" #include "mxutil.h"
#include "roi/legoroi.h" #include "roi/legoroi.h"
@ -47,11 +51,155 @@ void LegoModelPresenter::Destroy(MxBool p_fromDestructor)
} }
} }
// STUB: LEGO1 0x1007f6b0 // FUNCTION: LEGO1 0x1007f6b0
MxResult LegoModelPresenter::CreateROI(MxStreamChunk* p_chunk) MxResult LegoModelPresenter::CreateROI(MxStreamChunk* p_chunk)
{ {
// TODO MxResult result = FAILURE;
return FAILURE; LegoU32 numROIs;
Mx3DPointFloat vect;
LegoMemory storage(p_chunk->GetData());
LegoAnim anim;
LegoU32 version, textureInfoOffset, i, numTextures, skipTextures;
MxMatrix mat;
LegoChar* textureName = NULL;
LegoTexture* texture = NULL;
LegoS32 hardwareMode = VideoManager()->GetDirect3D()->AssignedDevice()->GetHardwareMode();
if (m_roi) {
delete m_roi;
}
if (!(m_roi = new LegoROI(VideoManager()->GetRenderer()))) {
goto done;
}
if (storage.Read(&version, sizeof(version)) != SUCCESS) {
goto done;
}
if (version != MODEL_VERSION) {
goto done;
}
if (storage.Read(&textureInfoOffset, sizeof(textureInfoOffset)) != SUCCESS) {
goto done;
}
storage.SetPosition(textureInfoOffset);
if (storage.Read(&numTextures, sizeof(numTextures)) != SUCCESS) {
goto done;
}
if (storage.Read(&skipTextures, sizeof(skipTextures)) != 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_modelPresenterConfig) {
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 (!skipTextures) {
if (TextureContainer()->Get(textureName) == NULL) {
LegoTextureInfo* textureInfo = LegoTextureInfo::Create(textureName, texture);
if (textureInfo == NULL) {
goto done;
}
TextureContainer()->Add(textureName, textureInfo);
}
delete[] textureName;
textureName = NULL;
delete texture;
texture = NULL;
}
}
storage.SetPosition(8);
if (storage.Read(&numROIs, sizeof(numROIs)) != SUCCESS) {
goto done;
}
if (anim.Read(&storage, FALSE) != SUCCESS) {
goto done;
}
if (m_roi->Read(NULL, VideoManager()->GetRenderer(), GetViewLODListManager(), TextureContainer(), &storage) !=
SUCCESS) {
goto done;
}
if (m_roi->SetFrame(&anim, 0) != SUCCESS) {
goto done;
}
// Get scripted location, direction and up vectors
CalcLocalTransform(
Mx3DPointFloat(m_action->GetLocation().GetX(), m_action->GetLocation().GetY(), m_action->GetLocation().GetZ()),
Mx3DPointFloat(
m_action->GetDirection().GetX(),
m_action->GetDirection().GetY(),
m_action->GetDirection().GetZ()
),
Mx3DPointFloat(m_action->GetUp().GetX(), m_action->GetUp().GetY(), m_action->GetUp().GetZ()),
mat
);
m_roi->FUN_100a46b0(mat);
result = SUCCESS;
done:
if (textureName != NULL) {
delete[] textureName;
}
if (texture != NULL) {
delete texture;
}
if (result != SUCCESS) {
if (m_roi) {
delete m_roi;
m_roi = NULL;
}
}
return result;
} }
// FUNCTION: LEGO1 0x10080050 // FUNCTION: LEGO1 0x10080050

View file

@ -14,7 +14,7 @@ LegoTextureContainer::~LegoTextureContainer()
} }
// FUNCTION: LEGO1 0x100998e0 // FUNCTION: LEGO1 0x100998e0
LegoTextureInfo* LegoTextureContainer::Insert(LegoTextureInfo* p_textureInfo) LegoTextureInfo* LegoTextureContainer::AddToList(LegoTextureInfo* p_textureInfo)
{ {
DDSURFACEDESC desc, newDesc; DDSURFACEDESC desc, newDesc;
DWORD width, height; DWORD width, height;
@ -110,7 +110,7 @@ LegoTextureInfo* LegoTextureContainer::Insert(LegoTextureInfo* p_textureInfo)
} }
// FUNCTION: LEGO1 0x10099cc0 // FUNCTION: LEGO1 0x10099cc0
void LegoTextureContainer::Erase(LegoTextureInfo* p_textureInfo) void LegoTextureContainer::EraseFromList(LegoTextureInfo* p_textureInfo)
{ {
if (p_textureInfo == NULL) { if (p_textureInfo == NULL) {
return; return;

View file

@ -13,7 +13,7 @@
#pragma warning(disable : 4237) #pragma warning(disable : 4237)
struct LegoContainerInfoComparator { struct LegoContainerInfoComparator {
bool operator()(const char* const& p_key0, const char* const& p_key1) const { return strcmp(p_key0, p_key1) > 0; } LegoU8 operator()(const char* const& p_key0, const char* const& p_key1) const { return strcmp(p_key0, p_key1) > 0; }
}; };
// SIZE 0x10 // SIZE 0x10
@ -44,16 +44,45 @@ public:
inline T* Get(const char* p_name) inline T* Get(const char* p_name)
{ {
// TODO: Score::Paint matches better with no `value` on the stack,
// while LegoModelPresenter::CreateROI only matches with `value`
T* value = NULL;
#ifdef COMPAT_MODE #ifdef COMPAT_MODE
typename LegoContainerInfo<T>::iterator it = m_map.find(p_name); typename LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#else #else
LegoContainerInfo<T>::iterator it = m_map.find(p_name); LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#endif #endif
if (it != m_map.end()) { if (it != m_map.end()) {
return (*it).second; value = (*it).second;
} }
return NULL; return value;
}
inline void Add(const char* p_name, T* p_value)
{
#ifdef COMPAT_MODE
typename LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#else
LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#endif
char* name;
if (it != m_map.end()) {
name = const_cast<char*>((*it).first);
if (m_ownership) {
delete (*it).second;
}
}
else {
name = new char[strlen(p_name) + 1];
strcpy(name, p_name);
}
m_map[name] = p_value;
} }
inline void SetOwnership(LegoBool p_ownership) { m_ownership = p_ownership; } inline void SetOwnership(LegoBool p_ownership) { m_ownership = p_ownership; }
@ -76,8 +105,8 @@ public:
LegoTextureContainer() { m_ownership = TRUE; } LegoTextureContainer() { m_ownership = TRUE; }
~LegoTextureContainer() override; ~LegoTextureContainer() override;
LegoTextureInfo* Insert(LegoTextureInfo* p_textureInfo); LegoTextureInfo* AddToList(LegoTextureInfo* p_textureInfo);
void Erase(LegoTextureInfo* p_textureInfo); void EraseFromList(LegoTextureInfo* p_textureInfo);
protected: protected:
LegoTextureList m_list; // 0x18 LegoTextureList m_list; // 0x18
@ -90,6 +119,9 @@ protected:
// TEMPLATE: LEGO1 0x10001cc0 // TEMPLATE: LEGO1 0x10001cc0
// _Tree<char const *,pair<char const * const,LegoTextureInfo *>,map<char const *,LegoTextureInfo *,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Kfn,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Lbound // _Tree<char const *,pair<char const * const,LegoTextureInfo *>,map<char const *,LegoTextureInfo *,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Kfn,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Lbound
// TEMPLATE: LEGO1 0x1004f960
// _Tree<char const *,pair<char const * const,LegoTextureInfo *>,map<char const *,LegoTextureInfo *,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Kfn,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::iterator::_Dec
// TEMPLATE: LEGO1 0x1004f9b0 // TEMPLATE: LEGO1 0x1004f9b0
// _Tree<char const *,pair<char const * const,LegoTextureInfo *>,map<char const *,LegoTextureInfo *,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Kfn,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Insert // _Tree<char const *,pair<char const * const,LegoTextureInfo *>,map<char const *,LegoTextureInfo *,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Kfn,LegoContainerInfoComparator,allocator<LegoTextureInfo *> >::_Insert

View file

@ -126,17 +126,3 @@ LegoResult LegoFile::Open(const char* p_name, LegoU32 p_mode)
} }
return SUCCESS; return SUCCESS;
} }
// FUNCTION: LEGO1 0x100994a0
LegoResult LegoMemory::GetPosition(LegoU32& p_position)
{
p_position = m_position;
return SUCCESS;
}
// FUNCTION: LEGO1 0x100994b0
LegoResult LegoMemory::SetPosition(LegoU32 p_position)
{
m_position = p_position;
return SUCCESS;
}

View file

@ -47,8 +47,20 @@ public:
LegoMemory(void* p_buffer); LegoMemory(void* p_buffer);
LegoResult Read(void* p_buffer, LegoU32 p_size) override; LegoResult Read(void* p_buffer, LegoU32 p_size) override;
LegoResult Write(const void* p_buffer, LegoU32 p_size) override; LegoResult Write(const void* p_buffer, LegoU32 p_size) override;
LegoResult GetPosition(LegoU32& p_position) override;
LegoResult SetPosition(LegoU32 p_position) override; // FUNCTION: LEGO1 0x100994a0
LegoResult GetPosition(LegoU32& p_position) override
{
p_position = m_position;
return SUCCESS;
}
// FUNCTION: LEGO1 0x100994b0
LegoResult SetPosition(LegoU32 p_position) override
{
m_position = p_position;
return SUCCESS;
}
// SYNTHETIC: LEGO1 0x10045a80 // SYNTHETIC: LEGO1 0x10045a80
// LegoMemory::~LegoMemory // LegoMemory::~LegoMemory

View file

@ -1,6 +1,6 @@
#ifndef __VERSION_H #ifndef __VERSION_H
#define __VERSION_H #define __VERSION_H
#define MODEL_VERSION 3 #define MODEL_VERSION 19
#endif // __VERSION_H #endif // __VERSION_H

View file

@ -96,6 +96,24 @@ LegoROI::~LegoROI()
} }
} }
// STUB: LEGO1 0x100a84a0
LegoResult LegoROI::Read(
OrientableROI* p_unk0xd4,
Tgl::Renderer* p_renderer,
ViewLODListManager* p_viewLODListManager,
LegoTextureContainer* p_textureContainer,
LegoStorage* p_storage
)
{
return SUCCESS;
}
// STUB: LEGO1 0x100a90f0
LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time)
{
return SUCCESS;
}
// FUNCTION: LEGO1 0x100a9a50 // FUNCTION: LEGO1 0x100a9a50
TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, int p_time) : LegoROI(p_renderer, p_lodList) TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, int p_time) : LegoROI(p_renderer, p_lodList)
{ {

View file

@ -7,6 +7,9 @@
typedef unsigned char (*ROIHandler)(char*, char*, unsigned int); typedef unsigned char (*ROIHandler)(char*, char*, unsigned int);
class LegoEntity; class LegoEntity;
class LegoTextureContainer;
class LegoStorage;
class LegoAnim;
// VTABLE: LEGO1 0x100dbe38 // VTABLE: LEGO1 0x100dbe38
// SIZE 0x108 // SIZE 0x108
@ -16,6 +19,15 @@ public:
LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList); LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList);
~LegoROI() override; ~LegoROI() override;
LegoResult Read(
OrientableROI* p_unk0xd4,
Tgl::Renderer* p_renderer,
ViewLODListManager* p_viewLODListManager,
LegoTextureContainer* p_textureContainer,
LegoStorage* p_storage
);
LegoResult SetFrame(LegoAnim* p_anim, LegoTime p_time);
float IntrinsicImportance() const override; // vtable+0x04 float IntrinsicImportance() const override; // vtable+0x04
void UpdateWorldBoundingVolumes() override; // vtable+0x18 void UpdateWorldBoundingVolumes() override; // vtable+0x18

View file

@ -22,6 +22,7 @@ public:
~MxAssignedDevice(); ~MxAssignedDevice();
inline unsigned int GetFlags() { return m_flags; } inline unsigned int GetFlags() { return m_flags; }
inline BOOL GetHardwareMode() { return ((int) m_flags << 31) >> 31; }
inline D3DDEVICEDESC& GetDesc() { return m_desc; } inline D3DDEVICEDESC& GetDesc() { return m_desc; }
friend class MxDirect3D; friend class MxDirect3D;

View file

@ -15,6 +15,10 @@ public:
m_elements[2] = p_z; m_elements[2] = p_z;
} }
inline float GetX() { return m_data[0]; }
inline float GetY() { return m_data[1]; }
inline float GetZ() { return m_data[2]; }
// FUNCTION: LEGO1 0x100343a0 // FUNCTION: LEGO1 0x100343a0
inline Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } inline Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }