diff --git a/CMakeLists.txt b/CMakeLists.txt index 2073555c..7371bb69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ target_include_directories(mxdirectx PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAK target_link_libraries(mxdirectx PRIVATE ddraw) add_library(roi STATIC + LEGO1/lego/sources/roi/legolod.cpp LEGO1/lego/sources/roi/legoroi.cpp ) register_lego1_target(roi) @@ -146,6 +147,7 @@ target_link_libraries(roi PRIVATE viewmanager Vec::Vec) add_library(geom STATIC LEGO1/lego/sources/geom/legobox.cpp + LEGO1/lego/sources/geom/legomesh.cpp LEGO1/lego/sources/geom/legosphere.cpp LEGO1/lego/sources/geom/legovertex.cpp ) @@ -163,6 +165,7 @@ target_include_directories(anim PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" target_link_libraries(anim PRIVATE) add_library(misc STATIC + LEGO1/lego/sources/misc/legocolor.cpp LEGO1/lego/sources/misc/legocontainer.cpp LEGO1/lego/sources/misc/legoimage.cpp LEGO1/lego/sources/misc/legostorage.cpp diff --git a/LEGO1/lego/sources/geom/legomesh.cpp b/LEGO1/lego/sources/geom/legomesh.cpp new file mode 100644 index 00000000..51b61fb0 --- /dev/null +++ b/LEGO1/lego/sources/geom/legomesh.cpp @@ -0,0 +1,91 @@ +#include "legomesh.h" + +#include "misc/legostorage.h" + +DECOMP_SIZE_ASSERT(LegoMeshUnkComponent, 0x1c) +DECOMP_SIZE_ASSERT(LegoMesh, 0x24) + +// FUNCTION: LEGO1 0x100d3810 +LegoMesh::LegoMesh() +{ + m_alpha = 0.0F; + m_shading = e_flat; + m_unk0x14 = 0; + m_textureName = NULL; + m_unk0x0d = 0; + m_unk0x10 = NULL; + m_unk0x20 = 0; + m_unk0x21 = FALSE; + m_materialName = NULL; +} + +// FUNCTION: LEGO1 0x100d3860 +LegoMesh::~LegoMesh() +{ + if (m_textureName != NULL) { + delete[] m_textureName; + } + + if (m_materialName != NULL) { + delete[] m_materialName; + } + + if (m_unk0x10 != NULL) { + delete m_unk0x10; + } +} + +// FUNCTION: LEGO1 0x100d38f0 +LegoResult LegoMesh::Read(LegoStorage* p_storage) +{ + LegoResult result; + LegoU32 textureLength, materialLength; + if ((result = m_color.Read(p_storage)) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_alpha, sizeof(m_alpha))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_shading, sizeof(m_shading))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_unk0x0d, sizeof(m_unk0x0d))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_unk0x20, sizeof(m_unk0x20))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_unk0x21, sizeof(m_unk0x21))) != SUCCESS) { + return result; + } + + if ((result = p_storage->Read(&textureLength, sizeof(textureLength))) != SUCCESS) { + return result; + } + if (textureLength) { + m_textureName = new LegoChar[textureLength + 1]; + + if ((result = p_storage->Read(m_textureName, textureLength)) != SUCCESS) { + return result; + } + + m_textureName[textureLength] = '\0'; + strlwr(m_textureName); + } + + if ((result = p_storage->Read(&materialLength, sizeof(materialLength))) != SUCCESS) { + return result; + } + if (materialLength) { + m_materialName = new LegoChar[materialLength + 1]; + + if ((result = p_storage->Read(m_materialName, materialLength)) != SUCCESS) { + return result; + } + + m_materialName[materialLength] = '\0'; + strlwr(m_materialName); + } + + return SUCCESS; +} diff --git a/LEGO1/lego/sources/geom/legomesh.h b/LEGO1/lego/sources/geom/legomesh.h new file mode 100644 index 00000000..1832ae7b --- /dev/null +++ b/LEGO1/lego/sources/geom/legomesh.h @@ -0,0 +1,78 @@ +#ifndef __LEGOMESH_H +#define __LEGOMESH_H + +#include "decomp.h" +#include "misc/legocolor.h" +#include "misc/legotypes.h" + +class LegoStorage; + +// SIZE 0x1c +struct LegoMeshUnkComponent { + ~LegoMeshUnkComponent() + { + if (m_unk0x08) { + delete m_unk0x08; + } + if (m_unk0x0c) { + delete m_unk0x0c; + } + if (m_unk0x10) { + delete m_unk0x10; + } + if (m_unk0x14) { + delete m_unk0x14; + } + if (m_unk0x18) { + delete m_unk0x18; + } + } + + undefined m_unk0x00[8]; // 0x00 + undefined* m_unk0x08; // 0x08 + undefined* m_unk0x0c; // 0x0c + undefined* m_unk0x10; // 0x10 + undefined* m_unk0x14; // 0x14 + undefined* m_unk0x18; // 0x18 +}; + +// VTABLE: LEGO1 0x100dd228 +// SIZE 0x24 +class LegoMesh { +public: + enum { + e_flat, + e_gouraud, + e_wireframe + }; + + LegoMesh(); + virtual ~LegoMesh(); + LegoColor GetColor() { return m_color; } + void SetColor(LegoColor p_color) { m_color = p_color; } + LegoFloat GetAlpha() { return m_alpha; } + LegoU8 GetShading() { return m_shading; } + void SetShading(LegoU8 p_shading) { m_shading = p_shading; } + LegoU8 GetUnknown0x0d() { return m_unk0x0d; } + const LegoChar* GetTextureName() { return m_textureName; } + const LegoChar* GetMaterialName() { return m_materialName; } + LegoBool GetUnknown0x21() { return m_unk0x21; } + LegoResult Read(LegoStorage* p_storage); + + // SYNTHETIC: LEGO1 0x100d3840 + // LegoMesh::`scalar deleting destructor' + +protected: + LegoColor m_color; // 0x04 + LegoFloat m_alpha; // 0x08 + LegoU8 m_shading; // 0x0c + LegoU8 m_unk0x0d; // 0x0d + LegoMeshUnkComponent* m_unk0x10; // 0x10 - unused, except in destructor + undefined4 m_unk0x14; // 0x14 - unused + LegoChar* m_textureName; // 0x18 + LegoChar* m_materialName; // 0x1c + undefined m_unk0x20; // 0x20 - unused + LegoBool m_unk0x21; // 0x21 +}; + +#endif // __LEGOMESH_H diff --git a/LEGO1/lego/sources/misc/legocolor.cpp b/LEGO1/lego/sources/misc/legocolor.cpp new file mode 100644 index 00000000..1dc1dce4 --- /dev/null +++ b/LEGO1/lego/sources/misc/legocolor.cpp @@ -0,0 +1,22 @@ +#include "legocolor.h" + +#include "decomp.h" +#include "legostorage.h" + +DECOMP_SIZE_ASSERT(LegoColor, 0x03) + +// FUNCTION: LEGO1 0x100d3a20 +LegoResult LegoColor::Read(LegoStorage* p_storage) +{ + LegoResult result; + if ((result = p_storage->Read(&m_red, sizeof(m_red))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_green, sizeof(m_green))) != SUCCESS) { + return result; + } + if ((result = p_storage->Read(&m_blue, sizeof(m_blue))) != SUCCESS) { + return result; + } + return SUCCESS; +} diff --git a/LEGO1/lego/sources/misc/legocolor.h b/LEGO1/lego/sources/misc/legocolor.h new file mode 100644 index 00000000..027362ce --- /dev/null +++ b/LEGO1/lego/sources/misc/legocolor.h @@ -0,0 +1,26 @@ +#ifndef __LEGOCOLOR_H +#define __LEGOCOLOR_H + +#include "legotypes.h" + +class LegoStorage; + +// SIZE 0x03 +class LegoColor { +public: + LegoColor() { m_red = m_green = m_blue = 0; } + LegoU8 GetRed() { return m_red; } + void SetRed(LegoU8 p_red) { m_red = p_red; } + LegoU8 GetGreen() { return m_green; } + void SetGreen(LegoU8 p_green) { m_green = p_green; } + LegoU8 GetBlue() { return m_blue; } + void SetBlue(LegoU8 p_blue) { m_blue = p_blue; } + LegoResult Read(LegoStorage* p_storage); + +protected: + LegoU8 m_red; // 0x00 + LegoU8 m_green; // 0x01 + LegoU8 m_blue; // 0x02 +}; + +#endif // __LEGOCOLOR_H diff --git a/LEGO1/lego/sources/roi/legolod.cpp b/LEGO1/lego/sources/roi/legolod.cpp new file mode 100644 index 00000000..f14e206a --- /dev/null +++ b/LEGO1/lego/sources/roi/legolod.cpp @@ -0,0 +1,317 @@ + +#include "legolod.h" + +#include "geom/legomesh.h" +#include "legoroi.h" +#include "misc/legocontainer.h" +#include "misc/legostorage.h" +#include "tgl/d3drm/impl.h" + +DECOMP_SIZE_ASSERT(LODObject, 0x04) +DECOMP_SIZE_ASSERT(ViewLOD, 0x0c) +DECOMP_SIZE_ASSERT(LegoLOD, 0x20) +DECOMP_SIZE_ASSERT(LegoLOD::Mesh, 0x08) + +// GLOBAL: LEGO1 0x101013d4 +LPDIRECT3DRMMATERIAL g_unk0x101013d4 = NULL; + +inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer); +inline BOOL GetMeshData(IDirect3DRMMesh*& mesh, D3DRMGROUPINDEX& index, Tgl::Mesh* pMesh); + +// TODO: Find out which unit this belongs to +// STUB: LEGO1 0x10065f60 +BOOL SetGroupTexture(Tgl::Mesh* pMesh, LegoTextureInfo* p_textureInfo) +{ + TglImpl::MeshImpl::MeshData* data = ((TglImpl::MeshImpl*) pMesh)->ImplementationData(); + data->groupMesh->SetGroupTexture(data->groupIndex, p_textureInfo->m_texture); + return TRUE; +} + +// FUNCTION: LEGO1 0x100aa380 +LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer) +{ + if (g_unk0x101013d4 == NULL) { + GetD3DRM(p_renderer)->CreateMaterial(10.0, &g_unk0x101013d4); + } + + m_meshes = NULL; + m_numMeshes = 0; + m_numVertices = 0; + m_numPolys = 0; + m_unk0x1c = 0; +} + +// STUB: LEGO1 0x100aa450 +LegoLOD::~LegoLOD() +{ + // TODO +} + +// FUNCTION: LEGO1 0x100aa510 +LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage) +{ + float(*normals)[3] = NULL; + float(*vertices)[3] = NULL; + float(*textureVertices)[2] = NULL; + LegoS32 numVerts = 0; + LegoS32 numNormals = 0; + LegoS32 numTextureVertices = 0; + LegoMesh* mesh = NULL; + LegoU32(*polyIndices)[3] = NULL; + LegoU32(*textureIndices)[3] = NULL; + LegoTextureInfo* textureInfo = NULL; + + LegoU32 i, meshUnd1, meshUnd2, tempNumVertsAndNormals; + unsigned char paletteEntries[256]; + + if (p_storage->Read(&m_unk0x08, sizeof(m_unk0x08)) != SUCCESS) { + goto done; + } + + if (GetUnknown0x08Test4()) { + return SUCCESS; + } + + m_unk0x04 = p_renderer->CreateUnk(); + + if (p_storage->Read(&m_numMeshes, sizeof(m_numMeshes)) != SUCCESS) { + goto done; + } + + if (m_numMeshes == 0) { + ClearFlag(c_bit4); + return SUCCESS; + } + + SetFlag(c_bit4); + + m_meshes = new Mesh[m_numMeshes]; + memset(m_meshes, 0, sizeof(*m_meshes) * m_numMeshes); + + meshUnd1 = m_numMeshes - 1; + meshUnd2 = 0; + + if (p_storage->Read(&tempNumVertsAndNormals, sizeof(tempNumVertsAndNormals)) != SUCCESS) { + goto done; + } + + numVerts = *((LegoU16*) &tempNumVertsAndNormals) & MAXSHORT; + numNormals = (*((LegoU16*) &tempNumVertsAndNormals + 1) >> 1) & MAXSHORT; + + if (p_storage->Read(&numTextureVertices, sizeof(numTextureVertices)) != SUCCESS) { + goto done; + } + + if (numVerts > 0) { + vertices = new float[numVerts][_countof(*vertices)]; + if (p_storage->Read(vertices, numVerts * sizeof(*vertices)) != SUCCESS) { + goto done; + } + } + + if (numNormals > 0) { + normals = new float[numNormals][_countof(*normals)]; + if (p_storage->Read(normals, numNormals * sizeof(*normals)) != SUCCESS) { + goto done; + } + } + + if (numTextureVertices > 0) { + textureVertices = new float[numTextureVertices][_countof(*textureVertices)]; + if (p_storage->Read(textureVertices, numTextureVertices * sizeof(*textureVertices)) != SUCCESS) { + goto done; + } + } + + for (i = 0; i < m_numMeshes; i++) { + LegoU32 numPolys, numVertices, numTextureIndices, meshIndex; + const LegoChar *textureName, *materialName; + Tgl::ShadingModel shadingModel; + + if (p_storage->Read(&numPolys, 2) != SUCCESS) { + goto done; + } + + m_numPolys += numPolys & MAXWORD; + + if (p_storage->Read(&numVertices, 2) != SUCCESS) { + goto done; + } + + polyIndices = new LegoU32[numPolys & MAXWORD][_countof(*polyIndices)]; + if (p_storage->Read(polyIndices, (numPolys & MAXWORD) * sizeof(*polyIndices)) != SUCCESS) { + goto done; + } + + if (p_storage->Read(&numTextureIndices, sizeof(numTextureIndices)) != SUCCESS) { + goto done; + } + + if (numTextureIndices > 0) { + textureIndices = new LegoU32[numPolys & MAXWORD][_countof(*textureIndices)]; + if (p_storage->Read(textureIndices, (numPolys & MAXWORD) * sizeof(*textureIndices)) != SUCCESS) { + goto done; + } + } + else { + textureIndices = NULL; + } + + mesh = new LegoMesh(); + + if (mesh->Read(p_storage) != SUCCESS) { + goto done; + } + + switch (mesh->GetShading()) { + case LegoMesh::e_flat: + shadingModel = Tgl::Flat; + break; + case LegoMesh::e_wireframe: + shadingModel = Tgl::Wireframe; + break; + default: + shadingModel = Tgl::Gouraud; + } + + m_numVertices += numVertices & MAXWORD; + + textureName = mesh->GetTextureName(); + materialName = mesh->GetMaterialName(); + + if (FUN_100aae20(textureName) || FUN_100aae20(materialName)) { + meshIndex = meshUnd1; + meshUnd1--; + } + else { + meshIndex = meshUnd2; + meshUnd2++; + } + + m_meshes[meshIndex].m_tglMesh = m_unk0x04->CreateMesh( + numPolys & MAXWORD, + numVertices & MAXWORD, + vertices, + normals, + textureVertices, + polyIndices, + textureIndices, + shadingModel + ); + + if (m_meshes[meshIndex].m_tglMesh == NULL) { + goto done; + } + + m_meshes[meshIndex].m_tglMesh->SetShadingModel(shadingModel); + + if (textureName != NULL) { + if (mesh->GetUnknown0x21()) { + LegoROI::FUN_100a9cf0(textureName, paletteEntries, _countof(paletteEntries)); + } + + textureInfo = p_textureContainer->Get(mesh->GetTextureName()); + + if (textureInfo == NULL) { + goto done; + } + + m_meshes[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); + SetGroupTexture(m_meshes[meshIndex].m_tglMesh, textureInfo); + m_meshes[meshIndex].m_unk0x04 = TRUE; + } + else { + LegoFloat red = 1.0F; + LegoFloat green = 0.0F; + LegoFloat blue = 1.0F; + LegoFloat alpha = 0.0F; + + if (mesh->GetUnknown0x21()) { + LegoROI::FUN_100a9bf0(materialName, red, green, blue, alpha); + } + else { + red = mesh->GetColor().GetRed() / 255.0; + green = mesh->GetColor().GetGreen() / 255.0; + blue = mesh->GetColor().GetBlue() / 255.0; + alpha = mesh->GetAlpha(); + } + + m_meshes[meshIndex].m_tglMesh->SetColor(red, green, blue, alpha); + } + + if (mesh->GetUnknown0x0d() > 0) { + IDirect3DRMMesh* mesh; + D3DRMGROUPINDEX index; + GetMeshData(mesh, index, m_meshes[meshIndex].m_tglMesh); + mesh->SetGroupMaterial(index, g_unk0x101013d4); + } + + if (mesh != NULL) { + delete mesh; + mesh = NULL; + } + if (polyIndices != NULL) { + delete[] polyIndices; + polyIndices = NULL; + } + if (textureIndices != NULL) { + delete[] textureIndices; + textureIndices = NULL; + } + } + + m_unk0x1c = meshUnd2; + + if (textureVertices != NULL) { + delete[] textureVertices; + } + if (normals != NULL) { + delete[] normals; + } + if (vertices != NULL) { + delete[] vertices; + } + + return SUCCESS; + +done: + if (normals != NULL) { + delete[] normals; + } + if (vertices != NULL) { + delete[] vertices; + } + if (textureVertices != NULL) { + delete[] textureVertices; + } + if (mesh != NULL) { + delete mesh; + } + if (polyIndices != NULL) { + delete[] polyIndices; + } + if (textureIndices != NULL) { + delete[] textureIndices; + } + + return FAILURE; +} + +// STUB: LEGO1 0x100aae20 +LegoBool LegoLOD::FUN_100aae20(const LegoChar*) +{ + // TODO + return FALSE; +} + +inline BOOL GetMeshData(IDirect3DRMMesh*& mesh, D3DRMGROUPINDEX& index, Tgl::Mesh* pMesh) +{ + mesh = ((TglImpl::MeshImpl*) pMesh)->ImplementationData()->groupMesh; + index = ((TglImpl::MeshImpl*) pMesh)->ImplementationData()->groupIndex; + return FALSE; +} + +inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer) +{ + return ((TglImpl::RendererImpl*) pRenderer)->ImplementationData(); +} diff --git a/LEGO1/lego/sources/roi/legolod.h b/LEGO1/lego/sources/roi/legolod.h new file mode 100644 index 00000000..34f4c124 --- /dev/null +++ b/LEGO1/lego/sources/roi/legolod.h @@ -0,0 +1,45 @@ +#ifndef LEGOLOD_H +#define LEGOLOD_H + +#include "misc/legotypes.h" +#include "viewmanager/viewlod.h" + +class LegoTextureContainer; +struct LegoTextureInfo; +class LegoStorage; + +// VTABLE: LEGO1 0x100dbf10 +// SIZE 0x20 +class LegoLOD : public ViewLOD { +public: + // SIZE 0x08 + struct Mesh { + Tgl::Mesh* m_tglMesh; // 0x00 + BOOL m_unk0x04; // 0x04 + }; + + LegoLOD(Tgl::Renderer*); + ~LegoLOD() override; + + // FUNCTION: LEGO1 0x100aae70 + int NumPolys() const override { return m_numPolys; } // vtable+0x0c + + // FUNCTION: LEGO1 0x100aae80 + float VTable0x10() override { return 0.0; } // vtable+0x10 + + LegoResult Read(Tgl::Renderer*, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage); + + static LegoBool FUN_100aae20(const LegoChar*); + + // SYNTHETIC: LEGO1 0x100aa430 + // LegoLOD::`scalar deleting destructor' + +protected: + Mesh* m_meshes; // 0x0c + LegoU32 m_numMeshes; // 0x10 + LegoU32 m_numVertices; // 0x14 + LegoU32 m_numPolys; // 0x18 + undefined4 m_unk0x1c; // 0x1c +}; + +#endif // LEGOLOD_H diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 0c8c31cd..70f899aa 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -2,20 +2,15 @@ #include "geom/legobox.h" #include "geom/legosphere.h" +#include "legolod.h" #include "misc/legocontainer.h" #include "misc/legostorage.h" -#include "tgl/d3drm/impl.h" #include #include DECOMP_SIZE_ASSERT(LegoROI, 0x108) DECOMP_SIZE_ASSERT(TimeROI, 0x10c) -DECOMP_SIZE_ASSERT(LODObject, 0x04) -DECOMP_SIZE_ASSERT(ViewLOD, 0x0c) -DECOMP_SIZE_ASSERT(LegoLOD, 0x20) - -inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer); // SIZE 0x14 typedef struct { @@ -23,7 +18,7 @@ typedef struct { int m_red; int m_green; int m_blue; - int m_unk0x10; + int m_alpha; } ROIColorAlias; // GLOBAL: LEGO1 0x100dbe28 @@ -59,9 +54,6 @@ const char* g_unk0x10101390[] = {"rcuser", "jsuser", "dunebugy", "chtrblad", "ch // GLOBAL: LEGO1 0x101013ac ROIHandler g_unk0x101013ac = NULL; -// GLOBAL: LEGO1 0x101013d4 -LPDIRECT3DRMMATERIAL g_unk0x101013d4 = NULL; - // FUNCTION: LEGO1 0x100a81c0 void LegoROI::configureLegoROI(int p_roiConfig) { @@ -251,7 +243,7 @@ LegoResult LegoROI::Read( } if (j == 0) { - if (surplusLODs != 0 && lod->GetUnknown0x08Test()) { + if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) { numLODs++; } } @@ -268,7 +260,7 @@ LegoResult LegoROI::Read( } if (i == 0) { - if (surplusLODs != 0 && lod->GetUnknown0x08Test()) { + if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) { numLODs++; } } @@ -306,9 +298,9 @@ LegoResult LegoROI::Read( LegoFloat red = 1.0F; LegoFloat green = 0.0F; LegoFloat blue = 1.0F; - LegoFloat other = 0.0F; - FUN_100a9bf0(textureName, red, green, blue, other); - FUN_100a9170(red, green, blue, other); + LegoFloat alpha = 0.0F; + FUN_100a9bf0(textureName, red, green, blue, alpha); + FUN_100a9170(red, green, blue, alpha); } } @@ -364,7 +356,7 @@ TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_t } // FUNCTION: LEGO1 0x100a9bf0 -unsigned char LegoROI::FUN_100a9bf0(const char* p_param, float& p_red, float& p_green, float& p_blue, float& p_other) +LegoBool LegoROI::FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha) { // TODO if (p_param == NULL) { @@ -378,17 +370,11 @@ unsigned char LegoROI::FUN_100a9bf0(const char* p_param, float& p_red, float& p_ } } - return ColorAliasLookup(p_param, p_red, p_green, p_blue, p_other); + return ColorAliasLookup(p_param, p_red, p_green, p_blue, p_alpha); } // FUNCTION: LEGO1 0x100a9c50 -unsigned char LegoROI::ColorAliasLookup( - const char* p_param, - float& p_red, - float& p_green, - float& p_blue, - float& p_other -) +LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha) { // TODO: this seems awfully hacky for these devs. is there a dynamic way // to represent `the end of this array` that would improve this? @@ -398,7 +384,7 @@ unsigned char LegoROI::ColorAliasLookup( p_red = g_roiColorAliases[i].m_red * g_normalizeByteToFloat; p_green = g_roiColorAliases[i].m_green * g_normalizeByteToFloat; p_blue = g_roiColorAliases[i].m_blue * g_normalizeByteToFloat; - p_other = g_roiColorAliases[i].m_unk0x10 * g_normalizeByteToFloat; + p_alpha = g_roiColorAliases[i].m_alpha * g_normalizeByteToFloat; return TRUE; } i++; @@ -407,6 +393,13 @@ unsigned char LegoROI::ColorAliasLookup( return FALSE; } +// STUB: LEGO1 0x100a9cf0 +LegoBool LegoROI::FUN_100a9cf0(const LegoChar* p_param, unsigned char* paletteEntries, LegoU32 p_numEntries) +{ + // TODO + return FALSE; +} + // FUNCTION: LEGO1 0x100a9d30 void LegoROI::FUN_100a9d30(ROIHandler p_func) { @@ -430,35 +423,3 @@ void LegoROI::UpdateWorldBoundingVolumes() { // TODO } - -// FUNCTION: LEGO1 0x100aa380 -LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer) -{ - if (g_unk0x101013d4 == NULL) { - GetD3DRM(p_renderer)->CreateMaterial(10.0, &g_unk0x101013d4); - } - - m_unk0x0c = 0; - m_unk0x10 = 0; - m_unk0x14 = 0; - m_numPolys = 0; - m_unk0x1c = 0; -} - -// STUB: LEGO1 0x100aa450 -LegoLOD::~LegoLOD() -{ - // TODO -} - -// STUB: LEGO1 0x100aa510 -LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage) -{ - // TODO - return SUCCESS; -} - -inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer) -{ - return ((TglImpl::RendererImpl*) pRenderer)->ImplementationData(); -} diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index e12cdb88..2b303944 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -2,7 +2,6 @@ #define LEGOROI_H #include "misc/legotypes.h" -#include "viewmanager/viewlod.h" #include "viewmanager/viewroi.h" typedef unsigned char (*ROIHandler)(const char*, char*, unsigned int); @@ -13,33 +12,6 @@ struct LegoTextureInfo; class LegoStorage; class LegoAnim; -// VTABLE: LEGO1 0x100dbf10 -// SIZE 0x20 -class LegoLOD : public ViewLOD { -public: - LegoLOD(Tgl::Renderer*); - ~LegoLOD() override; - - // FUNCTION: LEGO1 0x100aae70 - int NumPolys() const override { return m_numPolys; } // vtable+0x0c - - // FUNCTION: LEGO1 0x100aae80 - float VTable0x10() override { return 0.0; } // vtable+0x10 - - LegoResult Read(Tgl::Renderer*, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage); - - // SYNTHETIC: LEGO1 0x100aa430 - // LegoLOD::`scalar deleting destructor' - -protected: - // TODO: Review 1996 version - undefined4 m_unk0x0c; // 0x0c - undefined4 m_unk0x10; // 0x10 - undefined4 m_unk0x14; // 0x14 - LegoU32 m_numPolys; // 0x18 - undefined4 m_unk0x1c; // 0x1c -}; - // VTABLE: LEGO1 0x100dbe38 // SIZE 0x108 class LegoROI : public ViewROI { @@ -66,14 +38,15 @@ class LegoROI : public ViewROI { static void configureLegoROI(int p_roi); static void FUN_100a9d30(ROIHandler p_func); - static unsigned char FUN_100a9bf0(const char* p_param, float& p_red, float& p_green, float& p_blue, float& p_other); - static unsigned char ColorAliasLookup( - const char* p_param, + static LegoBool FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha); + static LegoBool ColorAliasLookup( + const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, - float& p_other + float& p_alpha ); + static LegoBool FUN_100a9cf0(const LegoChar* p_param, unsigned char* paletteEntries, LegoU32 p_numEntries); inline const LegoChar* GetName() const { return m_name; } inline LegoEntity* GetEntity() { return m_entity; } diff --git a/LEGO1/tgl/d3drm/group.cpp b/LEGO1/tgl/d3drm/group.cpp index af9ba1b7..f676dd7c 100644 --- a/LEGO1/tgl/d3drm/group.cpp +++ b/LEGO1/tgl/d3drm/group.cpp @@ -94,11 +94,11 @@ Result GroupImpl::Add(const Mesh* pMesh) } // FUNCTION: LEGO1 0x100a3450 -Result GroupImpl::Remove(const Mesh* pMesh) +Result GroupImpl::Remove(const Unk* pUnk) { - const MeshImpl* pMeshImpl = static_cast(pMesh); + const UnkImpl* pUnkImpl = static_cast(pUnk); // TODO: Incorrect structure - return ResultVal(m_data->DeleteVisual((IDirect3DRMMesh*) pMeshImpl->ImplementationData())); + return ResultVal(m_data->DeleteVisual((IDirect3DRMMesh*) pUnkImpl->ImplementationData())); } // FUNCTION: LEGO1 0x100a3480 diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index 8b1fe39e..e66aca74 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -282,7 +282,7 @@ class MeshImpl : public Mesh { struct MeshData { IDirect3DRMMesh* groupMesh; - int groupIndex; + D3DRMGROUPINDEX groupIndex; }; inline MeshData* ImplementationData() const { return m_data; } @@ -320,7 +320,7 @@ class GroupImpl : public Group { // vtable+0x20 Result Add(const Mesh*) override; Result Remove(const Group*) override; - Result Remove(const Mesh*) override; + Result Remove(const Unk*) override; Result RemoveAll() override; // vtable+0x30 @@ -349,14 +349,15 @@ class UnkImpl : public Unk { void* ImplementationDataPtr() override; // vtable+0x08 - Result SetMeshData( + Tgl::Mesh* CreateMesh( unsigned long faceCount, unsigned long vertexCount, - const float (*pPositions)[3], - const float (*pNormals)[3], - const float (*pTextureCoordinates)[2], - unsigned long vertexPerFaceCount, - unsigned long* pFaceData + float (*pPositions)[3], + float (*pNormals)[3], + float (*pTextureCoordinates)[2], + unsigned long (*pFaceIndices)[3], + unsigned long (*pTextureIndices)[3], + Tgl::ShadingModel shadingModel ) override; Result GetBoundingBox(float min[3], float max[3]) override; diff --git a/LEGO1/tgl/d3drm/unk.cpp b/LEGO1/tgl/d3drm/unk.cpp index 038b0e9d..eb73eb00 100644 --- a/LEGO1/tgl/d3drm/unk.cpp +++ b/LEGO1/tgl/d3drm/unk.cpp @@ -12,17 +12,18 @@ void* UnkImpl::ImplementationDataPtr() } // STUB: LEGO1 0x100a3840 -Result UnkImpl::SetMeshData( +Tgl::Mesh* UnkImpl::CreateMesh( unsigned long faceCount, unsigned long vertexCount, - const float (*pPositions)[3], - const float (*pNormals)[3], - const float (*pTextureCoordinates)[2], - unsigned long vertexPerFaceCount, - unsigned long* pFaceData + float (*pPositions)[3], + float (*pNormals)[3], + float (*pTextureCoordinates)[2], + unsigned long (*pFaceIndices)[3], + unsigned long (*pTextureIndices)[3], + Tgl::ShadingModel shadingModel ) { - return Error; + return NULL; } // FUNCTION: LEGO1 0x100a3ae0 diff --git a/LEGO1/tgl/tgl.h b/LEGO1/tgl/tgl.h index a8d89fb5..2cd4d6f7 100644 --- a/LEGO1/tgl/tgl.h +++ b/LEGO1/tgl/tgl.h @@ -297,7 +297,7 @@ class Group : public Object { virtual Result Add(const Group*) = 0; virtual Result Add(const Mesh*) = 0; virtual Result Remove(const Group*) = 0; - virtual Result Remove(const Mesh*) = 0; + virtual Result Remove(const Unk*) = 0; virtual Result RemoveAll() = 0; // This is TransformLocalToWorld in the leak, however it seems @@ -317,14 +317,15 @@ class Group : public Object { // VTABLE: LEGO1 0x100dbb30 class Unk : public Object { public: - virtual Result SetMeshData( + virtual Tgl::Mesh* CreateMesh( unsigned long faceCount, unsigned long vertexCount, - const float (*pPositions)[3], - const float (*pNormals)[3], - const float (*pTextureCoordinates)[2], - unsigned long vertexPerFaceCount, - unsigned long* pFaceData + float (*pPositions)[3], + float (*pNormals)[3], + float (*pTextureCoordinates)[2], + unsigned long (*pFaceIndices)[3], + unsigned long (*pTextureIndices)[3], + Tgl::ShadingModel shadingModel ) = 0; virtual Result GetBoundingBox(float min[3], float max[3]) = 0; virtual Unk* Clone() = 0; diff --git a/LEGO1/viewmanager/viewlod.cpp b/LEGO1/viewmanager/viewlod.cpp index 199e4c3a..afafe61a 100644 --- a/LEGO1/viewmanager/viewlod.cpp +++ b/LEGO1/viewmanager/viewlod.cpp @@ -3,5 +3,5 @@ // FUNCTION: LEGO1 0x100a5e40 ViewLOD::~ViewLOD() { - delete m_meshGroup; + delete m_unk0x04; } diff --git a/LEGO1/viewmanager/viewlod.h b/LEGO1/viewmanager/viewlod.h index 1b99b3f2..a92b52f9 100644 --- a/LEGO1/viewmanager/viewlod.h +++ b/LEGO1/viewmanager/viewlod.h @@ -13,7 +13,11 @@ // SIZE 0x0c class ViewLOD : public LODObject { public: - ViewLOD(Tgl::Renderer* pRenderer) : m_meshGroup(NULL), m_unk0x08(3) {} + enum { + c_bit4 = 0x10 + }; + + ViewLOD(Tgl::Renderer* pRenderer) : m_unk0x04(NULL), m_unk0x08(3) {} ~ViewLOD() override; // FUNCTION: LEGO1 0x100a6f30 @@ -22,17 +26,20 @@ class ViewLOD : public LODObject { // FUNCTION: LEGO1 0x100a6f50 int NVerts() const override { return NumPolys() * 2; } // vtable+0x08 - Tgl::Group* GetGeometry() { return m_meshGroup; } - const Tgl::Group* GetGeometry() const { return m_meshGroup; } - unsigned char GetUnknown0x08Test() { return m_unk0x08 & 0xffffff08; } + Tgl::Unk* GetUnknown0x04() { return m_unk0x04; } + const Tgl::Unk* GetUnknown0x04() const { return m_unk0x04; } + unsigned char GetUnknown0x08Test4() { return m_unk0x08 & 0xffffff04; } + unsigned char GetUnknown0x08Test8() { return m_unk0x08 & 0xffffff08; } + + void SetFlag(unsigned char p_flag) { m_unk0x08 |= p_flag; } + void ClearFlag(unsigned char p_flag) { m_unk0x08 &= ~p_flag; } // SYNTHETIC: LEGO1 0x100a6f60 // ViewLOD::`scalar deleting destructor' protected: - // TODO: m_meshGroup unconfirmed (based on 1996) - Tgl::Group* m_meshGroup; // 0x04 - undefined4 m_unk0x08; // 0x08 + Tgl::Unk* m_unk0x04; // 0x04 + undefined4 m_unk0x08; // 0x08 }; #endif // VIEWLOD_H diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index 0d8473e8..aa2f4fb4 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -93,13 +93,13 @@ void ViewManager::FUN_100a66a0(ViewROI* p_roi) const ViewLOD* lod = (const ViewLOD*) p_roi->GetLOD(p_roi->GetUnknown0xe0()); if (lod != NULL) { - const Tgl::Mesh* meshGroup = NULL; + const Tgl::Unk* unk = NULL; Tgl::Group* roiGeometry = p_roi->GetGeometry(); - meshGroup = (const Tgl::Mesh*) lod->GetGeometry(); + unk = lod->GetUnknown0x04(); - if (meshGroup != NULL) { - roiGeometry->Remove(meshGroup); + if (unk != NULL) { + roiGeometry->Remove(unk); } scene->Remove(roiGeometry);