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

View file

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

View file

@ -1,5 +1,6 @@
#include "legomodelpresenter.h"
#include "anim/legoanim.h"
#include "define.h"
#include "legoentity.h"
#include "legoentitypresenter.h"
@ -7,6 +8,9 @@
#include "legounksavedatawriter.h"
#include "legovideomanager.h"
#include "legoworld.h"
#include "misc/legocontainer.h"
#include "misc/legotexture.h"
#include "misc/version.h"
#include "mxcompositepresenter.h"
#include "mxutil.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)
{
// TODO
return FAILURE;
MxResult result = 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

View file

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

View file

@ -13,7 +13,7 @@
#pragma warning(disable : 4237)
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
@ -44,16 +44,45 @@ class LegoContainer {
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
typename LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#else
LegoContainerInfo<T>::iterator it = m_map.find(p_name);
#endif
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; }
@ -76,8 +105,8 @@ class LegoTextureContainer : public LegoContainer<LegoTextureInfo> {
LegoTextureContainer() { m_ownership = TRUE; }
~LegoTextureContainer() override;
LegoTextureInfo* Insert(LegoTextureInfo* p_textureInfo);
void Erase(LegoTextureInfo* p_textureInfo);
LegoTextureInfo* AddToList(LegoTextureInfo* p_textureInfo);
void EraseFromList(LegoTextureInfo* p_textureInfo);
protected:
LegoTextureList m_list; // 0x18
@ -90,6 +119,9 @@ class LegoTextureContainer : public LegoContainer<LegoTextureInfo> {
// TEMPLATE: LEGO1 0x10001cc0
// _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
// _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;
}
// 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 @@ class LegoMemory : public LegoStorage {
LegoMemory(void* p_buffer);
LegoResult Read(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
// LegoMemory::~LegoMemory

View file

@ -1,6 +1,6 @@
#ifndef __VERSION_H
#define __VERSION_H
#define MODEL_VERSION 3
#define MODEL_VERSION 19
#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
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);
class LegoEntity;
class LegoTextureContainer;
class LegoStorage;
class LegoAnim;
// VTABLE: LEGO1 0x100dbe38
// SIZE 0x108
@ -16,6 +19,15 @@ class LegoROI : public ViewROI {
LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList);
~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
void UpdateWorldBoundingVolumes() override; // vtable+0x18

View file

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

View file

@ -15,6 +15,10 @@ class Mx3DPointFloat : public Vector3 {
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
inline Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }