From 544372759ee0c74ab0f00a8f2de63f4c5bb2b073 Mon Sep 17 00:00:00 2001 From: MS Date: Tue, 15 Apr 2025 16:30:56 -0400 Subject: [PATCH] Add abstraction functions to `TglImpl::ViewImpl` (#1434) * Add Destroy methods to TglImpl * Test one abstraction * More ViewImpl abstractions * Finish ViewImpl --- LEGO1/tgl/d3drm/impl.h | 224 ++++++++++++++++++++------- LEGO1/tgl/d3drm/view.cpp | 322 ++++++++++++++++++++++++++++++++------- 2 files changed, 433 insertions(+), 113 deletions(-) diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index c5c74f82..1e22f09e 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -26,6 +26,7 @@ namespace TglImpl using namespace Tgl; // Utility function used by implementations +// FUNCTION: BETA10 0x10169cf0 inline Result ResultVal(HRESULT result) { return SUCCEEDED(result) ? Success : Error; @@ -133,13 +134,7 @@ public: DeviceImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016dd80 - ~DeviceImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~DeviceImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -161,12 +156,29 @@ public: IDirect3DRMDevice2* ImplementationData() const { return m_data; } void SetImplementationData(IDirect3DRMDevice2* device) { m_data = device; } + inline void Destroy(); + friend class RendererImpl; private: IDirect3DRMDevice2* m_data; }; +// FUNCTION: BETA10 0x101708c0 +inline void DeviceDestroy(IDirect3DRMDevice2* pDevice) +{ + pDevice->Release(); +} + +// FUNCTION: BETA10 0x10170880 +void DeviceImpl::Destroy() +{ + if (m_data) { + DeviceDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100db9e8 // VTABLE: BETA10 0x101c3220 class ViewImpl : public View { @@ -175,13 +187,7 @@ public: ViewImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016e5d0 - ~ViewImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~ViewImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -218,12 +224,41 @@ public: static Result ViewportCreateAppData(IDirect3DRM2*, IDirect3DRMViewport*, IDirect3DRMFrame2*); + inline void Destroy(); + Result Add(const LightImpl& rLight); + Result Remove(const LightImpl& rLight); + Result SetCamera(const CameraImpl& rCamera); + Result Render(const GroupImpl& rScene); + Result Pick( + unsigned long x, + unsigned long y, + const GroupImpl** ppGroupsToPickFrom, + int groupsToPickFromCount, + const Group**& rppPickedGroups, + int& rPickedGroupCount + ); + friend class RendererImpl; private: IDirect3DRMViewport* m_data; }; +// FUNCTION: BETA10 0x101711a0 +inline void ViewDestroy(IDirect3DRMViewport* pView) +{ + pView->Release(); +} + +// FUNCTION: BETA10 0x10171160 +void ViewImpl::Destroy() +{ + if (m_data) { + ViewDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100dbad8 // VTABLE: BETA10 0x101c3260 class CameraImpl : public Camera { @@ -232,13 +267,7 @@ public: CameraImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016f200 - ~CameraImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~CameraImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -247,12 +276,29 @@ public: IDirect3DRMFrame2* ImplementationData() const { return m_data; } + inline void Destroy(); + friend class RendererImpl; private: IDirect3DRMFrame2* m_data; }; +// FUNCTION: BETA10 0x10170940 +inline void CameraDestroy(IDirect3DRMFrame2* pFrame) +{ + pFrame->Release(); +} + +// FUNCTION: BETA10 0x10170900 +void CameraImpl::Destroy() +{ + if (m_data) { + CameraDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100dbaf8 // VTABLE: BETA10 0x101c31e0 class LightImpl : public Light { @@ -261,13 +307,7 @@ public: LightImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016c7e0 - ~LightImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~LightImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -277,12 +317,29 @@ public: IDirect3DRMFrame2* ImplementationData() const { return m_data; } + inline void Destroy(); + friend class RendererImpl; private: IDirect3DRMFrame2* m_data; }; +// FUNCTION: BETA10 0x10170390 +inline void LightDestroy(IDirect3DRMFrame2* pLight) +{ + pLight->Release(); +} + +// FUNCTION: BETA10 0x10170350 +void LightImpl::Destroy() +{ + if (m_data) { + LightDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100dbb88 // VTABLE: BETA10 0x101c3340 class MeshImpl : public Mesh { @@ -291,13 +348,7 @@ public: MeshImpl() : m_data(0) {} // FUNCTION: BETA10 0x10170460 - ~MeshImpl() override - { - if (m_data) { - delete m_data; - m_data = NULL; - } - } + ~MeshImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -324,12 +375,29 @@ public: const MeshDataType& ImplementationData() const { return m_data; } MeshDataType& ImplementationData() { return m_data; } + inline void Destroy(); + friend class RendererImpl; private: MeshDataType m_data; }; +// FUNCTION: BETA10 0x10171b40 +inline void MeshDestroy(MeshImpl::MeshDataType pMesh) +{ + delete pMesh; +} + +// FUNCTION: BETA10 0x10171b00 +void MeshImpl::Destroy() +{ + if (m_data) { + MeshDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100dba68 // VTABLE: BETA10 0x101c3150 class GroupImpl : public Group { @@ -338,13 +406,7 @@ public: GroupImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016a410 - ~GroupImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~GroupImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -369,12 +431,29 @@ public: IDirect3DRMFrame2* ImplementationData() const { return m_data; } + inline void Destroy(); + friend class RendererImpl; private: IDirect3DRMFrame2* m_data; }; +// FUNCTION: BETA10 0x1016c2b0 +inline void GroupDestroy(IDirect3DRMFrame2* pGroup) +{ + pGroup->Release(); +} + +// FUNCTION: BETA10 0x1016c270 +void GroupImpl::Destroy() +{ + if (m_data) { + GroupDestroy(m_data); + m_data = NULL; + } +} + // VTABLE: LEGO1 0x100dbb18 // VTABLE: BETA10 0x101c3270 class MeshBuilderImpl : public MeshBuilder { @@ -383,13 +462,7 @@ public: MeshBuilderImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016f5c0 - ~MeshBuilderImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~MeshBuilderImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -411,6 +484,8 @@ public: IDirect3DRMMesh* ImplementationData() const { return m_data; } + inline void Destroy(); + friend class RendererImpl; private: @@ -429,6 +504,21 @@ private: IDirect3DRMMesh* m_data; }; +// FUNCTION: BETA10 0x10171220 +inline void MeshBuilderDestroy(IDirect3DRMMesh* pMeshBuilder) +{ + pMeshBuilder->Release(); +} + +// FUNCTION: BETA10 0x101711e0 +void MeshBuilderImpl::Destroy() +{ + if (m_data) { + MeshBuilderDestroy(m_data); + m_data = NULL; + } +} + // No vtable, this is just a simple wrapper around D3DRMIMAGE class TglD3DRMIMAGE { public: @@ -460,13 +550,7 @@ public: TextureImpl() : m_data(0) {} // FUNCTION: BETA10 0x1016c2d0 - ~TextureImpl() override - { - if (m_data) { - m_data->Release(); - m_data = NULL; - } - } + ~TextureImpl() override { Destroy(); } void* ImplementationDataPtr() override; @@ -489,6 +573,8 @@ public: IDirect3DRMTexture* ImplementationData() const { return m_data; } void SetImplementation(IDirect3DRMTexture* pData) { m_data = pData; } + inline void Destroy(); + friend class RendererImpl; static Result SetImage(IDirect3DRMTexture* pSelf, TglD3DRMIMAGE* pImage); @@ -497,6 +583,21 @@ private: IDirect3DRMTexture* m_data; }; +// FUNCTION: BETA10 0x1016fd40 +inline void TextureDestroy(IDirect3DRMTexture* pTexture) +{ + pTexture->Release(); +} + +// FUNCTION: BETA10 0x1016fd00 +void TextureImpl::Destroy() +{ + if (m_data) { + TextureDestroy(m_data); + m_data = NULL; + } +} + // Translation helpers inline D3DRMRENDERQUALITY Translate(ShadingModel tglShadingModel) { @@ -526,6 +627,7 @@ inline D3DRMRENDERQUALITY Translate(ShadingModel tglShadingModel) return renderQuality; } +// FUNCTION: BETA10 0x101703b0 inline D3DRMPROJECTIONTYPE Translate(ProjectionType tglProjectionType) { D3DRMPROJECTIONTYPE projectionType; @@ -556,6 +658,16 @@ inline D3DRMMATRIX4D* Translate(FloatMatrix4& tglMatrix4x4, D3DRMMATRIX4D& rD3DR return &rD3DRMMatrix4x4; } +// FUNCTION: BETA10 0x1016fba0 +inline D3DVECTOR* Translate(const float tglVector[3], D3DVECTOR& rD3DVector) +{ + rD3DVector.x = D3DVAL(tglVector[0]); + rD3DVector.y = D3DVAL(tglVector[1]); + rD3DVector.z = D3DVAL(tglVector[2]); + + return &rD3DVector; +} + // SYNTHETIC: LEGO1 0x100a16d0 // SYNTHETIC: BETA10 0x10169aa0 // TglImpl::RendererImpl::`scalar deleting destructor' diff --git a/LEGO1/tgl/d3drm/view.cpp b/LEGO1/tgl/d3drm/view.cpp index 3ac84021..30970214 100644 --- a/LEGO1/tgl/d3drm/view.cpp +++ b/LEGO1/tgl/d3drm/view.cpp @@ -1,5 +1,7 @@ #include "impl.h" +#include + using namespace TglImpl; struct ViewportAppData { @@ -61,6 +63,7 @@ Result ViewImpl::ViewportCreateAppData(IDirect3DRM2* pDevice, IDirect3DRMViewpor return result; } +// FUNCTION: BETA10 0x1016bd80 inline Result ViewRestoreFrameAfterRender( IDirect3DRMFrame* pFrame, IDirect3DRMFrame* pCamera, @@ -72,7 +75,11 @@ inline Result ViewRestoreFrameAfterRender( // remove camera and light frame from frame that was rendered // this doesn't destroy the camera as it is still the camera of the viewport... result = ResultVal(pFrame->DeleteChild(pCamera)); + assert(Succeeded(result)); + assert((pCamera->AddRef(), pCamera->Release()) > 0); + result = ResultVal(pFrame->DeleteChild(pLightFrame)); + assert(Succeeded(result)); // decrease frame's ref count (it was increased in ViewPrepareFrameForRender()) pFrame->Release(); @@ -97,11 +104,12 @@ void ViewportDestroyCallback(IDirect3DRMObject* pObject, void* pArg) } // FUNCTION: LEGO1 0x100a1290 +// FUNCTION: BETA10 0x10168eab Result ViewportPickImpl( IDirect3DRMViewport* pViewport, int x, int y, - const Group** ppGroupsToPickFrom, + const GroupImpl** ppGroupsToPickFrom, int groupsToPickFromCount, const Group**& rppPickedGroups, int& rPickedGroupCount @@ -116,9 +124,11 @@ inline ViewportAppData* ViewportGetData(IDirect3DRMViewport* pViewport) return reinterpret_cast(pViewport->GetAppData()); } +// FUNCTION: BETA10 0x10170ab0 inline IDirect3DRMFrame* ViewportGetLightFrame(IDirect3DRMViewport* pViewport) { - return ViewportGetData(pViewport)->m_pLightFrame; + assert(pViewport->GetAppData()); + return reinterpret_cast(pViewport->GetAppData())->m_pLightFrame; } // FUNCTION: LEGO1 0x100a2d80 @@ -128,97 +138,216 @@ void* ViewImpl::ImplementationDataPtr() return reinterpret_cast(&m_data); } +// FUNCTION: BETA10 0x10170a40 +inline Result ViewAddLight(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame* pLight) +{ + IDirect3DRMFrame* pLightFrame = ViewportGetLightFrame(pViewport); + + assert(pLightFrame); + return ResultVal(pLightFrame->AddChild(const_cast(pLight))); +} + +// FUNCTION: BETA10 0x101709a0 +inline Result ViewImpl::Add(const LightImpl& rLight) +{ + assert(m_data); + assert(rLight.ImplementationData()); + + return ViewAddLight(m_data, rLight.ImplementationData()); +} + // FUNCTION: LEGO1 0x100a2d90 +// FUNCTION: BETA10 0x1016e690 Result ViewImpl::Add(const Light* pLight) { - const LightImpl* light = static_cast(pLight); - IDirect3DRMFrame* frame = light->ImplementationData(); - return ResultVal(ViewportGetLightFrame(m_data)->AddChild(frame)); + assert(m_data); + assert(pLight); + + return Add(*static_cast(pLight)); +} + +// FUNCTION: BETA10 0x10170bb0 +inline Result ViewRemoveLight(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame* pLight) +{ + IDirect3DRMFrame* pLightFrame = ViewportGetLightFrame(pViewport); + + assert(pLightFrame); + return ResultVal(pLightFrame->DeleteChild(const_cast(pLight))); +} + +// FUNCTION: BETA10 0x10170b10 +inline Result ViewImpl::Remove(const LightImpl& rLight) +{ + assert(m_data); + assert(rLight.ImplementationData()); + + return ViewRemoveLight(m_data, rLight.ImplementationData()); } // FUNCTION: LEGO1 0x100a2dc0 +// FUNCTION: BETA10 0x1016e710 Result ViewImpl::Remove(const Light* pLight) { - const LightImpl* light = static_cast(pLight); - IDirect3DRMFrame* frame = light->ImplementationData(); - return ResultVal(ViewportGetLightFrame(m_data)->DeleteChild(frame)); + assert(m_data); + assert(pLight); + + return Remove(*static_cast(pLight)); } -// FUNCTION: LEGO1 0x100a2df0 -Result ViewImpl::SetCamera(const Camera* pCamera) +// FUNCTION: BETA10 0x10170cc0 +inline Result ViewSetCamera(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame2* pCamera) { - const CameraImpl* camera = static_cast(pCamera); - IDirect3DRMFrame2* frame = camera->ImplementationData(); - ViewportAppData* pViewportAppData; Result result; - pViewportAppData = reinterpret_cast(m_data->GetAppData()); + pViewportAppData = reinterpret_cast(pViewport->GetAppData()); + assert(pViewportAppData); + result = ViewRestoreFrameAfterRender( pViewportAppData->m_pLastRenderedFrame, pViewportAppData->m_pCamera, pViewportAppData->m_pLightFrame ); - pViewportAppData->m_pCamera = frame; + assert(Succeeded(result)); + pViewportAppData->m_pCamera = const_cast(pCamera); pViewportAppData->m_pLastRenderedFrame = 0; - return ResultVal(m_data->SetCamera(frame)); + return ResultVal(pViewport->SetCamera(const_cast(pCamera))); +} + +// FUNCTION: BETA10 0x10170c20 +inline Result ViewImpl::SetCamera(const CameraImpl& rCamera) +{ + assert(m_data); + assert(rCamera.ImplementationData()); + + return ViewSetCamera(m_data, rCamera.ImplementationData()); +} + +// FUNCTION: LEGO1 0x100a2df0 +// FUNCTION: BETA10 0x1016e790 +Result ViewImpl::SetCamera(const Camera* pCamera) +{ + assert(m_data); + assert(pCamera); + + return SetCamera(*static_cast(pCamera)); +} + +// FUNCTION: BETA10 0x1016e870 +inline Result ViewSetProjection(IDirect3DRMViewport* pViewport, ProjectionType type) +{ + D3DRMPROJECTIONTYPE projectionType = Translate(type); + + return ResultVal(pViewport->SetProjection(projectionType)); } // FUNCTION: LEGO1 0x100a2e70 +// FUNCTION: BETA10 0x1016e810 Result ViewImpl::SetProjection(ProjectionType type) { - return ResultVal(m_data->SetProjection(Translate(type))); + assert(m_data); + + return ViewSetProjection(m_data, type); } -// FUNCTION: LEGO1 0x100a2eb0 -Result ViewImpl::SetFrustrum(float frontClippingDistance, float backClippingDistance, float degrees) +// FUNCTION: BETA10 0x1016e920 +inline Result ViewSetFrustrum( + IDirect3DRMViewport* pViewport, + float frontClippingDistance, + float backClippingDistance, + float degrees +) { float field = frontClippingDistance * tan(DegreesToRadians(degrees / 2)); Result result; - result = ResultVal(m_data->SetFront(frontClippingDistance)); + result = ResultVal(pViewport->SetFront(frontClippingDistance)); if (Succeeded(result)) { - result = ResultVal(m_data->SetBack(backClippingDistance)); + result = ResultVal(pViewport->SetBack(backClippingDistance)); } if (Succeeded(result)) { - result = ResultVal(m_data->SetField(field)); + result = ResultVal(pViewport->SetField(field)); + } + + return result; +} + +// FUNCTION: LEGO1 0x100a2eb0 +// FUNCTION: BETA10 0x1016e8b0 +Result ViewImpl::SetFrustrum(float frontClippingDistance, float backClippingDistance, float degrees) +{ + assert(m_data); + + return ViewSetFrustrum(m_data, frontClippingDistance, backClippingDistance, degrees); +} + +// FUNCTION: BETA10 0x1016ea70 +inline Result ViewSetBackgroundColor(IDirect3DRMViewport* pViewport, float r, float g, float b) +{ + Result result = Success; + + ViewportAppData* pViewportAppData = reinterpret_cast(pViewport->GetAppData()); + assert(pViewportAppData); + + pViewportAppData->m_backgroundColorRed = r; + pViewportAppData->m_backgroundColorGreen = g; + pViewportAppData->m_backgroundColorBlue = b; + + if (pViewportAppData->m_pLastRenderedFrame) { + result = ResultVal(pViewportAppData->m_pLastRenderedFrame->SetSceneBackgroundRGB(r, g, b)); + assert(Succeeded(result)); } return result; } // FUNCTION: LEGO1 0x100a2f30 +// FUNCTION: BETA10 0x1016ea00 Result ViewImpl::SetBackgroundColor(float r, float g, float b) { - Result ret = Success; - // Note, this method in the shipped game is very diverged from - // the Tgl leak code. - ViewportAppData* data = ViewportGetData(m_data); - data->m_backgroundColorRed = r; - data->m_backgroundColorGreen = g; - data->m_backgroundColorBlue = b; - if (data->m_pLastRenderedFrame) { - ret = ResultVal(data->m_pLastRenderedFrame->SetSceneBackgroundRGB(r, g, b)); - } - return ret; + assert(m_data); + + return ViewSetBackgroundColor(m_data, r, g, b); } -// FUNCTION: LEGO1 0x100a2f80 -Result ViewImpl::GetBackgroundColor(float* r, float* g, float* b) +// FUNCTION: BETA10 0x1016ebd0 +inline Result ViewGetBackgroundColor(IDirect3DRMViewport* pViewport, float* r, float* g, float* b) { - ViewportAppData* data = ViewportGetData(m_data); - *r = data->m_backgroundColorRed; - *g = data->m_backgroundColorGreen; - *b = data->m_backgroundColorBlue; + ViewportAppData* pViewportAppData = reinterpret_cast(pViewport->GetAppData()); + assert(pViewportAppData); + + *r = pViewportAppData->m_backgroundColorRed; + *g = pViewportAppData->m_backgroundColorGreen; + *b = pViewportAppData->m_backgroundColorBlue; + return Success; } -// FUNCTION: LEGO1 0x100a2fb0 -Result ViewImpl::Clear() +// FUNCTION: LEGO1 0x100a2f80 +// FUNCTION: BETA10 0x1016eb60 +Result ViewImpl::GetBackgroundColor(float* r, float* g, float* b) { - return ResultVal(m_data->Clear()); + assert(m_data); + + return ViewGetBackgroundColor(m_data, r, g, b); } +// FUNCTION: BETA10 0x1016ecb0 +inline Result ViewClear(IDirect3DRMViewport* pViewport) +{ + return ResultVal(pViewport->Clear()); +} + +// FUNCTION: LEGO1 0x100a2fb0 +// FUNCTION: BETA10 0x1016ec50 +Result ViewImpl::Clear() +{ + assert(m_data); + + return ViewClear(m_data); +} + +// FUNCTION: BETA10 0x10170fb0 inline Result ViewPrepareFrameForRender( IDirect3DRMFrame* pFrame, IDirect3DRMFrame* pCamera, @@ -233,12 +362,15 @@ inline Result ViewPrepareFrameForRender( if (pFrame) { // set background color result = ResultVal(pFrame->SetSceneBackgroundRGB(backgroundRed, backgroundGreen, backgroundBlue)); + assert(Succeeded(result)); // add camera to frame to be rendered result = ResultVal(pFrame->AddChild(pCamera)); + assert(Succeeded(result)); // add light frame to frame to be rendered result = ResultVal(pFrame->AddChild(pLightFrame)); + assert(Succeeded(result)); // increase ref count of frame to ensure it does not get deleted underneath us pFrame->AddRef(); @@ -247,12 +379,14 @@ inline Result ViewPrepareFrameForRender( return result; } +// FUNCTION: BETA10 0x10170e30 inline Result ViewRender(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame2* pGroup) { ViewportAppData* pViewportAppData; Result result; pViewportAppData = reinterpret_cast(pViewport->GetAppData()); + assert(pViewportAppData); if (pViewportAppData->m_pLastRenderedFrame != pGroup) { result = ViewRestoreFrameAfterRender( @@ -261,6 +395,8 @@ inline Result ViewRender(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame2 pViewportAppData->m_pLightFrame ); + assert(Succeeded(result)); + pViewportAppData->m_pLastRenderedFrame = const_cast(pGroup); result = ViewPrepareFrameForRender( @@ -273,32 +409,66 @@ inline Result ViewRender(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame2 ); } + assert(Succeeded(result)); + result = ResultVal(pViewport->Render(const_cast(pGroup))); + assert(Succeeded(result)); + return result; } +// FUNCTION: BETA10 0x10170d90 +inline Result ViewImpl::Render(const GroupImpl& rScene) +{ + assert(m_data); + assert(rScene.ImplementationData()); + + return ViewRender(m_data, rScene.ImplementationData()); +} + // FUNCTION: LEGO1 0x100a2fd0 +// FUNCTION: BETA10 0x1016ece0 Result ViewImpl::Render(const Group* pGroup) { - return ViewRender(m_data, static_cast(pGroup)->ImplementationData()); + assert(m_data); + assert(pGroup); + + return Render(*static_cast(pGroup)); +} + +// FUNCTION: BETA10 0x1016edd0 +inline Result ViewForceUpdate( + IDirect3DRMViewport* pViewport, + unsigned long x, + unsigned long y, + unsigned long width, + unsigned long height +) +{ + return ResultVal(pViewport->ForceUpdate(x, y, x + width - 1, y + height - 1)); } // FUNCTION: LEGO1 0x100a3080 +// FUNCTION: BETA10 0x1016ed60 Result ViewImpl::ForceUpdate(unsigned long x, unsigned long y, unsigned long width, unsigned long height) { - return ResultVal(m_data->ForceUpdate(x, y, x + width - 1, y + height - 1)); + assert(m_data); + + return ViewForceUpdate(m_data, x, y, width, height); } -// FUNCTION: LEGO1 0x100a30c0 -Result ViewImpl::Pick( +// FUNCTION: BETA10 0x101710f0 +inline Result ViewImpl::Pick( unsigned long x, unsigned long y, - const Group** ppGroupsToPickFrom, + const GroupImpl** ppGroupsToPickFrom, int groupsToPickFromCount, const Group**& rppPickedGroups, int& rPickedGroupCount ) { + assert(m_data); + return ViewportPickImpl( m_data, x, @@ -310,17 +480,38 @@ Result ViewImpl::Pick( ); } -// FUNCTION: LEGO1 0x100a30f0 -Result ViewImpl::TransformWorldToScreen(const float world[3], float screen[4]) +// FUNCTION: LEGO1 0x100a30c0 +// FUNCTION: BETA10 0x1016ee10 +Result ViewImpl::Pick( + unsigned long x, + unsigned long y, + const Group** ppGroupsToPickFrom, + int groupsToPickFromCount, + const Group**& rppPickedGroups, + int& rPickedGroupCount +) +{ + assert(m_data); + + return Pick( + x, + y, + reinterpret_cast(ppGroupsToPickFrom), + groupsToPickFromCount, + rppPickedGroups, + rPickedGroupCount + ); +} + +// FUNCTION: BETA10 0x1016eff0 +inline Result ViewTransformWorldToScreen(IDirect3DRMViewport* pViewport, const float world[3], float screen[4]) { D3DRMVECTOR4D d3dRMScreen; D3DVECTOR d3dRMWorld; - d3dRMWorld.x = world[0]; - d3dRMWorld.y = world[1]; - d3dRMWorld.z = world[2]; + D3DVECTOR* pD3DRMWorld = Translate(world, d3dRMWorld); Result result; - result = ResultVal(m_data->Transform(&d3dRMScreen, &d3dRMWorld)); + result = ResultVal(pViewport->Transform(&d3dRMScreen, pD3DRMWorld)); if (Succeeded(result)) { screen[0] = d3dRMScreen.x; @@ -332,10 +523,18 @@ Result ViewImpl::TransformWorldToScreen(const float world[3], float screen[4]) return result; } -// FUNCTION: LEGO1 0x100a3160 -Result ViewImpl::TransformScreenToWorld(const float screen[4], float world[3]) +// FUNCTION: LEGO1 0x100a30f0 +// FUNCTION: BETA10 0x1016ef90 +Result ViewImpl::TransformWorldToScreen(const float world[3], float screen[4]) +{ + assert(m_data); + + return ViewTransformWorldToScreen(m_data, world, screen); +} + +// FUNCTION: BETA10 0x1016f0d0 +inline Result ViewTransformScreenToWorld(IDirect3DRMViewport* pViewport, const float screen[4], float world[3]) { - // 100% match minus instruction reordering. D3DVECTOR d3dRMWorld; D3DRMVECTOR4D d3dScreen; d3dScreen.x = screen[0]; @@ -344,7 +543,7 @@ Result ViewImpl::TransformScreenToWorld(const float screen[4], float world[3]) d3dScreen.w = screen[3]; Result result; - result = ResultVal(m_data->InverseTransform(&d3dRMWorld, &d3dScreen)); + result = ResultVal(pViewport->InverseTransform(&d3dRMWorld, &d3dScreen)); if (Succeeded(result)) { world[0] = d3dRMWorld.x; @@ -354,3 +553,12 @@ Result ViewImpl::TransformScreenToWorld(const float screen[4], float world[3]) return result; } + +// FUNCTION: LEGO1 0x100a3160 +// FUNCTION: BETA10 0x1016f070 +Result ViewImpl::TransformScreenToWorld(const float screen[4], float world[3]) +{ + assert(m_data); + + return ViewTransformScreenToWorld(m_data, screen, world); +}