diff --git a/LEGO1/tgl/d3drm/device.cpp b/LEGO1/tgl/d3drm/device.cpp index 82e96730..2d17a5c9 100644 --- a/LEGO1/tgl/d3drm/device.cpp +++ b/LEGO1/tgl/d3drm/device.cpp @@ -1,5 +1,6 @@ #include "impl.h" +#include #include using namespace TglImpl; @@ -29,13 +30,20 @@ Result DeviceImpl::SetColorModel(ColorModel) return Success; } +// FUNCTION: BETA10 0x1016e020 +inline Result DeviceSetShadingModel(IDirect3DRMDevice2* pDevice, ShadingModel model) +{ + D3DRMRENDERQUALITY renderQuality = Translate(model); + return ResultVal(pDevice->SetQuality(renderQuality)); +} + // FUNCTION: LEGO1 0x100a2c30 +// FUNCTION: BETA10 0x1016dfc0 Result DeviceImpl::SetShadingModel(ShadingModel model) { - // Doesn't match well even though we know this is exactly - // the original code thanks to the jump table. - D3DRMRENDERQUALITY renderQuality = Translate(model); - return ResultVal(m_data->SetQuality(renderQuality)); + assert(m_data); + + return DeviceSetShadingModel(m_data, model); } // FUNCTION: LEGO1 0x100a2ca0 diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index 1e22f09e..b7ab827e 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -100,6 +100,7 @@ public: public: inline Result Create(); inline void Destroy(); + inline Result CreateLight(LightType type, float r, float g, float b, LightImpl& rLight); private: IDirect3DRM2* m_data; @@ -300,13 +301,13 @@ void CameraImpl::Destroy() } // VTABLE: LEGO1 0x100dbaf8 -// VTABLE: BETA10 0x101c31e0 +// VTABLE: BETA10 0x101c3270 class LightImpl : public Light { public: - // FUNCTION: BETA10 0x1016b260 + // FUNCTION: BETA10 0x1016b460 LightImpl() : m_data(0) {} - // FUNCTION: BETA10 0x1016c7e0 + // FUNCTION: BETA10 0x1016f5c0 ~LightImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -315,23 +316,26 @@ public: Result SetTransformation(FloatMatrix4&) override; Result SetColor(float r, float g, float b) override; - IDirect3DRMFrame2* ImplementationData() const { return m_data; } + typedef IDirect3DRMFrame2* LightDataType; + + const LightDataType& ImplementationData() const { return m_data; } + LightDataType& ImplementationData() { return m_data; } inline void Destroy(); friend class RendererImpl; private: - IDirect3DRMFrame2* m_data; + LightDataType m_data; }; -// FUNCTION: BETA10 0x10170390 +// FUNCTION: BETA10 0x10171220 inline void LightDestroy(IDirect3DRMFrame2* pLight) { pLight->Release(); } -// FUNCTION: BETA10 0x10170350 +// FUNCTION: BETA10 0x101711e0 void LightImpl::Destroy() { if (m_data) { @@ -455,13 +459,13 @@ void GroupImpl::Destroy() } // VTABLE: LEGO1 0x100dbb18 -// VTABLE: BETA10 0x101c3270 +// VTABLE: BETA10 0x101c31e0 class MeshBuilderImpl : public MeshBuilder { public: - // FUNCTION: BETA10 0x1016b460 + // FUNCTION: BETA10 0x1016b260 MeshBuilderImpl() : m_data(0) {} - // FUNCTION: BETA10 0x1016f5c0 + // FUNCTION: BETA10 0x1016c7e0 ~MeshBuilderImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -504,13 +508,13 @@ private: IDirect3DRMMesh* m_data; }; -// FUNCTION: BETA10 0x10171220 +// FUNCTION: BETA10 0x10170390 inline void MeshBuilderDestroy(IDirect3DRMMesh* pMeshBuilder) { pMeshBuilder->Release(); } -// FUNCTION: BETA10 0x101711e0 +// FUNCTION: BETA10 0x10170350 void MeshBuilderImpl::Destroy() { if (m_data) { @@ -599,6 +603,7 @@ void TextureImpl::Destroy() } // Translation helpers +// FUNCTION: BETA10 0x1016fc40 inline D3DRMRENDERQUALITY Translate(ShadingModel tglShadingModel) { D3DRMRENDERQUALITY renderQuality; @@ -668,6 +673,36 @@ inline D3DVECTOR* Translate(const float tglVector[3], D3DVECTOR& rD3DVector) return &rD3DVector; } +// FUNCTION: BETA10 0x1016fd80 +inline D3DRMLIGHTTYPE Translate(LightType tglLightType) +{ + D3DRMLIGHTTYPE lightType; + + // ??? use lookup table + switch (tglLightType) { + case Ambient: + lightType = D3DRMLIGHT_AMBIENT; + break; + case Point: + lightType = D3DRMLIGHT_POINT; + break; + case Spot: + lightType = D3DRMLIGHT_SPOT; + break; + case Directional: + lightType = D3DRMLIGHT_DIRECTIONAL; + break; + case ParallelPoint: + lightType = D3DRMLIGHT_PARALLELPOINT; + break; + default: + lightType = D3DRMLIGHT_AMBIENT; + break; + } + + return lightType; +} + // SYNTHETIC: LEGO1 0x100a16d0 // SYNTHETIC: BETA10 0x10169aa0 // TglImpl::RendererImpl::`scalar deleting destructor' @@ -689,11 +724,11 @@ inline D3DVECTOR* Translate(const float tglVector[3], D3DVECTOR& rD3DVector) // TglImpl::CameraImpl::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100a2640 -// SYNTHETIC: BETA10 0x1016b5f0 +// SYNTHETIC: BETA10 0x1016ba30 // TglImpl::LightImpl::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100a2720 -// SYNTHETIC: BETA10 0x1016ba30 +// SYNTHETIC: BETA10 0x1016b5f0 // TglImpl::MeshBuilderImpl::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100a2800 diff --git a/LEGO1/tgl/d3drm/light.cpp b/LEGO1/tgl/d3drm/light.cpp index 3452fbc2..50d8271e 100644 --- a/LEGO1/tgl/d3drm/light.cpp +++ b/LEGO1/tgl/d3drm/light.cpp @@ -6,7 +6,7 @@ DECOMP_SIZE_ASSERT(Light, 0x04); DECOMP_SIZE_ASSERT(LightImpl, 0x08); // FUNCTION: LEGO1 0x100a3770 -// FUNCTION: BETA10 0x1016c9f0 +// FUNCTION: BETA10 0x1016f630 void* LightImpl::ImplementationDataPtr() { return reinterpret_cast(&m_data); diff --git a/LEGO1/tgl/d3drm/mesh.cpp b/LEGO1/tgl/d3drm/mesh.cpp index b5e66922..518ac921 100644 --- a/LEGO1/tgl/d3drm/mesh.cpp +++ b/LEGO1/tgl/d3drm/mesh.cpp @@ -1,5 +1,7 @@ #include "impl.h" +#include + using namespace TglImpl; DECOMP_SIZE_ASSERT(D3DRMVERTEX, 0x24); @@ -49,28 +51,19 @@ Result MeshImpl::SetTextureMappingMode(TextureMappingMode mode) } } +// FUNCTION: BETA10 0x10170750 +inline Result MeshSetShadingModel(MeshImpl::MeshData* pMesh, ShadingModel model) +{ + D3DRMRENDERQUALITY mode = Translate(model); + return ResultVal(pMesh->groupMesh->SetGroupQuality(pMesh->groupIndex, mode)); +} + // FUNCTION: LEGO1 0x100a3fc0 +// FUNCTION: BETA10 0x101706f0 Result MeshImpl::SetShadingModel(ShadingModel model) { - D3DRMRENDERQUALITY mode; - switch (model) { - case Wireframe: - mode = D3DRMRENDER_WIREFRAME; - break; - case UnlitFlat: - mode = D3DRMRENDER_UNLITFLAT; - break; - case Flat: - mode = D3DRMRENDER_FLAT; - break; - case Gouraud: - mode = D3DRMRENDER_GOURAUD; - break; - case Phong: - mode = D3DRMRENDER_PHONG; - break; - } - return ResultVal(m_data->groupMesh->SetGroupQuality(m_data->groupIndex, mode)); + assert(m_data); + return MeshSetShadingModel(m_data, model); } // FUNCTION: LEGO1 0x100a4030 diff --git a/LEGO1/tgl/d3drm/meshbuilder.cpp b/LEGO1/tgl/d3drm/meshbuilder.cpp index 6b8b8113..be7119f3 100644 --- a/LEGO1/tgl/d3drm/meshbuilder.cpp +++ b/LEGO1/tgl/d3drm/meshbuilder.cpp @@ -1,12 +1,14 @@ #include "impl.h" +#include + using namespace TglImpl; DECOMP_SIZE_ASSERT(MeshBuilder, 0x04); DECOMP_SIZE_ASSERT(MeshBuilderImpl, 0x08); // FUNCTION: LEGO1 0x100a3830 -// FUNCTION: BETA10 0x1016f630 +// FUNCTION: BETA10 0x1016c9f0 void* MeshBuilderImpl::ImplementationDataPtr() { return reinterpret_cast(&m_data); @@ -159,12 +161,12 @@ inline Result MeshBuilderImpl::CreateMeshImpl( ); } -// FUNCTION: LEGO1 0x100a3ae0 -Result MeshBuilderImpl::GetBoundingBox(float min[3], float max[3]) const +// FUNCTION: BETA10 0x1016e060 +inline Result MeshBuilderGetBoundingBox(IDirect3DRMMesh* pMesh, float min[3], float max[3]) { D3DRMBOX box; - Result result = ResultVal(m_data->GetBox(&box)); - if (result == Success) { + Result result = ResultVal(pMesh->GetBox(&box)); + if (Succeeded(result)) { min[0] = box.min.x; min[1] = box.min.y; min[2] = box.min.z; @@ -175,6 +177,15 @@ Result MeshBuilderImpl::GetBoundingBox(float min[3], float max[3]) const return result; } +// FUNCTION: LEGO1 0x100a3ae0 +// FUNCTION: BETA10 0x1016ce00 +Result MeshBuilderImpl::GetBoundingBox(float min[3], float max[3]) const +{ + assert(m_data); + + return MeshBuilderGetBoundingBox(m_data, min, max); +} + // FUNCTION: LEGO1 0x100a3b40 MeshBuilder* MeshBuilderImpl::Clone() { diff --git a/LEGO1/tgl/d3drm/renderer.cpp b/LEGO1/tgl/d3drm/renderer.cpp index e18b646f..f0ab4fbb 100644 --- a/LEGO1/tgl/d3drm/renderer.cpp +++ b/LEGO1/tgl/d3drm/renderer.cpp @@ -1,5 +1,7 @@ #include "impl.h" +#include + using namespace TglImpl; // FUNCTION: LEGO1 0x100a15e0 @@ -156,56 +158,82 @@ Camera* RendererImpl::CreateCamera() return camera; } +// FUNCTION: BETA10 0x1016d580 +inline Result RendererCreateLight( + IDirect3DRM2* pD3DRM, + LightType type, + float r, + float g, + float b, + IDirect3DRMFrame2*& rpLight +) +{ + D3DRMLIGHTTYPE lightType = Translate(type); + IDirect3DRMFrame2* pLightFrame; + IDirect3DRMLight* pLight; + Result result; + + result = ResultVal(pD3DRM->CreateFrame(NULL, &pLightFrame)); + assert(Succeeded(result)); + if (!Succeeded(result)) { + return result; + } + // pLightFrame ref count is now 1 + assert((pLightFrame->AddRef(), pLightFrame->Release()) == 1); + + result = ResultVal(pD3DRM->CreateLightRGB(lightType, D3DVAL(r), D3DVAL(g), D3DVAL(b), &pLight)); + assert(Succeeded(result)); + if (!Succeeded(result)) { + pLightFrame->Release(); + return result; + } + // pLight ref count is now 1 + assert((pLight->AddRef(), pLight->Release()) == 1); + + result = ResultVal(pLightFrame->AddLight(pLight)); + assert(Succeeded(result)); + if (!Succeeded(result)) { + pLightFrame->Release(); + pLight->Release(); + return result; + } + // pLightFrame ref count is still 1 + assert((pLightFrame->AddRef(), pLightFrame->Release()) == 1); + + // pLight ref count is now 2 + assert((pLight->AddRef(), pLight->Release()) == 2); + + // Release() pLight so it gets deleted when pLightFrame is Release() + pLight->Release(); + + rpLight = pLightFrame; + + return result; +} + +// FUNCTION: BETA10 0x1016d4e0 +inline Result RendererImpl::CreateLight(LightType type, float r, float g, float b, LightImpl& rLight) +{ + assert(m_data); + assert(!rLight.ImplementationData()); + + return RendererCreateLight(m_data, type, r, g, b, rLight.ImplementationData()); +} + // FUNCTION: LEGO1 0x100a1cf0 +// FUNCTION: BETA10 0x1016aa90 Light* RendererImpl::CreateLight(LightType type, float r, float g, float b) { - LightImpl* newLight = new LightImpl(); - D3DRMLIGHTTYPE translatedType; - switch (type) { - case Ambient: - translatedType = D3DRMLIGHT_AMBIENT; - break; - case Point: - translatedType = D3DRMLIGHT_POINT; - break; - case Spot: - translatedType = D3DRMLIGHT_SPOT; - break; - case Directional: - translatedType = D3DRMLIGHT_DIRECTIONAL; - break; - case ParallelPoint: - translatedType = D3DRMLIGHT_PARALLELPOINT; - break; - default: - translatedType = D3DRMLIGHT_AMBIENT; + assert(m_data); + + LightImpl* pLightImpl = new LightImpl; + + if (!CreateLight(type, r, g, b, *pLightImpl)) { + delete pLightImpl; + pLightImpl = 0; } - LPDIRECT3DRMFRAME2 frame; - Result result = ResultVal(m_data->CreateFrame(NULL, &frame)); - if (Succeeded(result)) { - LPDIRECT3DRMLIGHT d3dLight; - result = ResultVal(m_data->CreateLightRGB(translatedType, r, g, b, &d3dLight)); - if (!Succeeded(result)) { - frame->Release(); - } - else { - result = ResultVal(frame->AddLight(d3dLight)); - if (!Succeeded(result)) { - d3dLight->Release(); - frame->Release(); - } - else { - d3dLight->Release(); - newLight->m_data = frame; - } - } - } - if (!Succeeded(result)) { - delete newLight; - newLight = NULL; - } - return newLight; + return pLightImpl; } // FUNCTION: LEGO1 0x100a1e90 diff --git a/LEGO1/tgl/tgl.h b/LEGO1/tgl/tgl.h index 8ba3493b..c519cf05 100644 --- a/LEGO1/tgl/tgl.h +++ b/LEGO1/tgl/tgl.h @@ -285,21 +285,21 @@ public: }; // VTABLE: LEGO1 0x100dbb08 -// VTABLE: BETA10 0x101c32a0 +// VTABLE: BETA10 0x101c3330 class Light : public Object { public: virtual Result SetTransformation(FloatMatrix4&) = 0; virtual Result SetColor(float r, float g, float b) = 0; - // SYNTHETIC: BETA10 0x1016b630 + // SYNTHETIC: BETA10 0x1016ba70 // Tgl::Light::Light // SYNTHETIC: LEGO1 0x100a26d0 - // SYNTHETIC: BETA10 0x1016b6a0 + // SYNTHETIC: BETA10 0x1016bae0 // Tgl::Light::~Light // SYNTHETIC: LEGO1 0x100a2aa0 - // SYNTHETIC: BETA10 0x1016bb80 + // SYNTHETIC: BETA10 0x1016bc80 // Tgl::Light::`scalar deleting destructor' }; @@ -367,7 +367,7 @@ public: // was not in the leaked Tgl code. My suspicion is that it's // some kind of builder class for creating meshes. // VTABLE: LEGO1 0x100dbb30 -// VTABLE: BETA10 0x101c3330 +// VTABLE: BETA10 0x101c32a0 class MeshBuilder : public Object { public: virtual Mesh* CreateMesh( @@ -383,15 +383,15 @@ public: virtual Result GetBoundingBox(float min[3], float max[3]) const = 0; virtual MeshBuilder* Clone() = 0; - // SYNTHETIC: BETA10 0x1016ba70 + // SYNTHETIC: BETA10 0x1016b630 // Tgl::MeshBuilder::MeshBuilder // SYNTHETIC: LEGO1 0x100a27b0 - // SYNTHETIC: BETA10 0x1016bae0 + // SYNTHETIC: BETA10 0x1016b6a0 // Tgl::MeshBuilder::~MeshBuilder // SYNTHETIC: LEGO1 0x100a2b10 - // SYNTHETIC: BETA10 0x1016bc80 + // SYNTHETIC: BETA10 0x1016bb80 // Tgl::MeshBuilder::`scalar deleting destructor' };