From dc18b5d9c11386cfca27799bed52826959f3c73c Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 10 Sep 2023 08:56:16 -0400 Subject: [PATCH] MxDirect3D (#114) * MxDirect3D Constructor * Implement MxDirect3D::Clear (not yet matching) * Match MxDirect3D::Clear * Building out MxDirect3D, link dxguid, add size asserts * Move a few things around on the Enumerate context obj * remove dupe mxdirect3d * Match BuildErrorString and _DoEnumerate * Fix style --------- Co-authored-by: Christian Semmler Co-authored-by: disinvite --- CMakeLists.txt | 7 +- LEGO1/mxdirect3d.cpp | 191 +++++++++++++++++++++++++++++++++++++++++ LEGO1/mxdirect3d.h | 59 ++++++++++++- LEGO1/mxdirectdraw.cpp | 8 +- LEGO1/mxdirectdraw.h | 7 +- 5 files changed, 262 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eb41a6d..f72f83e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,9 +46,9 @@ add_library(lego1 SHARED LEGO1/jukeboxentity.cpp LEGO1/jukeboxstate.cpp LEGO1/legoact2state.cpp - LEGO1/legoactor.cpp LEGO1/legoactioncontrolpresenter.cpp LEGO1/legoactor.cpp + LEGO1/legoactor.cpp LEGO1/legoanimactor.cpp LEGO1/legoanimationmanager.cpp LEGO1/legoanimmmpresenter.cpp @@ -102,6 +102,7 @@ add_library(lego1 SHARED LEGO1/mxcontrolpresenter.cpp LEGO1/mxcore.cpp LEGO1/mxcriticalsection.cpp + LEGO1/mxdirect3d.cpp LEGO1/mxdirectdraw.cpp LEGO1/mxdiskstreamcontroller.cpp LEGO1/mxdiskstreamprovider.cpp @@ -118,10 +119,10 @@ add_library(lego1 SHARED LEGO1/mxdsparallelaction.cpp LEGO1/mxdsselectaction.cpp LEGO1/mxdsserialaction.cpp - LEGO1/mxdsstreamingaction.cpp LEGO1/mxdssound.cpp LEGO1/mxdssource.cpp LEGO1/mxdsstill.cpp + LEGO1/mxdsstreamingaction.cpp LEGO1/mxdssubscriber.cpp LEGO1/mxentity.cpp LEGO1/mxeventmanager.cpp @@ -205,7 +206,7 @@ if (ISLE_USE_DX5) endif() # Link libraries -target_link_libraries(lego1 PRIVATE ddraw dsound winmm) +target_link_libraries(lego1 PRIVATE ddraw dsound dxguid winmm) # Make sure filenames are ALL CAPS set_property(TARGET lego1 PROPERTY OUTPUT_NAME LEGO1) diff --git a/LEGO1/mxdirect3d.cpp b/LEGO1/mxdirect3d.cpp index e69de29b..6d6a43e3 100644 --- a/LEGO1/mxdirect3d.cpp +++ b/LEGO1/mxdirect3d.cpp @@ -0,0 +1,191 @@ +#include "mxdirect3d.h" +#include // for vsprintf + +DECOMP_SIZE_ASSERT(MxDirect3D, 0x894); +DECOMP_SIZE_ASSERT(MxDeviceModeFinder, 0xe4); +DECOMP_SIZE_ASSERT(MxDeviceEnumerate, 0x198); + +// OFFSET: LEGO1 0x1009b0a0 +MxDirect3D::MxDirect3D() +{ + this->m_pDirect3d = NULL; + this->m_pDirect3dDevice = NULL; + this->m_unk88c = NULL; + this->m_pDeviceModeFinder = NULL; +} + +// OFFSET: LEGO1 0x1009b140 +MxDirect3D::~MxDirect3D() +{ + Destroy(); +} + +// OFFSET: LEGO1 0x1009b1a0 +BOOL MxDirect3D::Create( + HWND hWnd, + BOOL fullscreen_1, + BOOL surface_fullscreen, + BOOL onlySystemMemory, + int width, + int height, + int bpp, + const PALETTEENTRY* pPaletteEntries, + int paletteEntryCount) +{ + BOOL success = FALSE; + + BOOL ret = MxDirectDraw::Create(hWnd, fullscreen_1, surface_fullscreen, + onlySystemMemory, width, height, bpp, + pPaletteEntries, paletteEntryCount); + + if (ret && CreateIDirect3D() && D3DSetMode()) + success = TRUE; + + if (!success) + FUN_1009D920(); + + return success; +} + +// OFFSET: LEGO1 0x1009b210 +void MxDirect3D::Destroy() +{ + if (this->m_pDirect3dDevice) { + this->m_pDirect3dDevice->Release(); + this->m_pDirect3dDevice = NULL; + } + + if (this->m_pDirect3d) { + this->m_pDirect3d->Release(); + this->m_pDirect3d = NULL; + } + + if (this->m_pDeviceModeFinder) { + delete m_pDeviceModeFinder; + this->m_pDeviceModeFinder = NULL; + } + + // This should get deleted by MxDirectDraw::Destroy + if (m_pCurrentDeviceModesList) { + // delete m_pCurrentDeviceModesList; // missing? + m_pCurrentDeviceModesList = NULL; + } + + MxDirectDraw::Destroy(); +} + +// OFFSET: LEGO1 0x1009b290 +void MxDirect3D::Clear() +{ + if(this->m_pDirect3dDevice) { + this->m_pDirect3dDevice->Release(); + this->m_pDirect3dDevice = NULL; + } + if(this->m_pDirect3d) { + this->m_pDirect3d->Release(); + this->m_pDirect3d = NULL; + } + MxDirectDraw::DestroyButNotDirectDraw(); +} + +// OFFSET: LEGO1 0x1009b2d0 +BOOL MxDirect3D::CreateIDirect3D() +{ + MxResult ret = IDirect3D_QueryInterface(m_pDirectDraw, + IID_IDirect3D2, + (LPVOID*)&m_pDirect3d); + + if (ret) { + Error("Creation of IDirect3D failed", ret); + return FALSE; + } + + return TRUE; +} + +// OFFSET: LEGO1 0x1009b310 STUB +BOOL MxDirect3D::D3DSetMode() +{ + // TODO + //if (m_pDeviceModeFinder) + Error("This device cannot support the current display mode", 0); + OutputDebugString("MxDirect3D::D3DSetMode() front lock failed\n"); + OutputDebugString("MxDirect3D::D3DSetMode() back lock failed\n"); + return TRUE; +} + +// OFFSET: LEGO1 0x1009b8b0 +MxDeviceModeFinder::MxDeviceModeFinder() +{ + memset(this, 0, sizeof(*this)); +} + +// OFFSET: LEGO1 0x1009b8d0 +MxDeviceModeFinder::~MxDeviceModeFinder() +{ + if (m_deviceInfo) { + delete m_deviceInfo; + m_deviceInfo = NULL; + } +} + +// OFFSET: LEGO1 0x1009c070 STUB +BOOL MxDeviceEnumerate::FUN_1009c070() +{ + // TODO + // HRESULT ret = DirectDrawCreate(); + HRESULT ret = 0; + if (ret) { + MxDirect3D::BuildErrorString("GetCaps failed: %s\n", + EnumerateErrorToString(ret)); + } + //IDirect3D2_EnumDevices + return TRUE; +} + +// OFFSET: LEGO1 0x1009c4c0 +void MxDirect3D::BuildErrorString(const char *p_format, ...) +{ + va_list args; + char buf[512]; + + va_start(args, p_format); + vsprintf(buf, p_format, args); + va_end(args); + + OutputDebugString(buf); +} + +// OFFSET: LEGO1 0x1009c6c0 +MxResult MxDeviceEnumerate::_DoEnumerate() +{ + // TODO: what does ECX refer to in this context? + if (m_unk010_flag) + return FAILURE; + + HRESULT ret = DirectDrawEnumerate(EnumerateCallback, this); + if (ret) { + MxDirect3D::BuildErrorString("DirectDrawEnumerate returned error %s\n", + EnumerateErrorToString(ret)); + return FAILURE; + } + + m_unk010_flag = TRUE; + return SUCCESS; +} + +// OFFSET: LEGO1 0x1009c710 STUB +BOOL FAR PASCAL EnumerateCallback(GUID FAR *, LPSTR, LPSTR, LPVOID) +{ + // TODO + return FALSE; +} + +// OFFSET: LEGO1 0x1009c730 STUB +char *MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) +{ + // TODO: This is a list of error messages, similar to the function in + // MxDirectDraw, except that this one now contains the Direct3D errors. + // Probably just copied from a sample file in the dx5 sdk. + return ""; +} diff --git a/LEGO1/mxdirect3d.h b/LEGO1/mxdirect3d.h index ecc1f0aa..03e9f1ac 100644 --- a/LEGO1/mxdirect3d.h +++ b/LEGO1/mxdirect3d.h @@ -2,24 +2,77 @@ #define MXDIRECT3D_H #include "mxdirectdraw.h" +#include "mxtypes.h" #include "decomp.h" #include -class MxDeviceModeFinder; +// SIZE 0xe4 +class MxDeviceModeFinder +{ +public: + MxDeviceModeFinder(); + ~MxDeviceModeFinder(); + undefined4 m_unknown[56]; + MxDirectDraw::DeviceModesInfo *m_deviceInfo; // +0xe0 +}; + +// VTABLE 0x100db814 (or 0x100d9cc8?) +// SIZE 0x198 +class MxDeviceEnumerate +{ +public: + MxDeviceEnumerate(); + virtual MxResult _DoEnumerate(); + BOOL FUN_1009c070(); + + char *EnumerateErrorToString(HRESULT p_error); + + undefined4 m_unk004; + undefined4 m_unk008; + undefined4 m_unk00c; + MxBool m_unk010_flag; // +0x10 + + undefined4 m_unknown[97]; +}; + +// VTABLE 0x100db800 // SIZE 0x894 class MxDirect3D : public MxDirectDraw { public: + MxDirect3D(); + + void Clear(); inline MxDeviceModeFinder *GetDeviceModeFinder() { return this->m_pDeviceModeFinder; }; + virtual ~MxDirect3D(); + virtual BOOL Create( + HWND hWnd, + BOOL fullscreen_1, + BOOL surface_fullscreen, + BOOL onlySystemMemory, + int width, + int height, + int bpp, + const PALETTEENTRY* pPaletteEntries, + int paletteEntryCount); + virtual void Destroy(); + + BOOL CreateIDirect3D(); + BOOL D3DSetMode(); + + static void BuildErrorString(const char *, ...); + private: - MxDeviceModeFinder *m_pDeviceModeFinder; - IDirect3D *m_pDirect3d; + MxDeviceModeFinder *m_pDeviceModeFinder; // +0x880 + IDirect3D *m_pDirect3d; // +0x884 IDirect3DDevice *m_pDirect3dDevice; undefined4 m_unk88c; undefined4 m_unk890; }; +BOOL FAR PASCAL EnumerateCallback(GUID FAR *, LPSTR, LPSTR, LPVOID); + #endif // MXDIRECT3D_H \ No newline at end of file diff --git a/LEGO1/mxdirectdraw.cpp b/LEGO1/mxdirectdraw.cpp index 625a6fae..099e9bc6 100644 --- a/LEGO1/mxdirectdraw.cpp +++ b/LEGO1/mxdirectdraw.cpp @@ -1,8 +1,8 @@ - #include "mxdirectdraw.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxDirectDraw, 0x880); +DECOMP_SIZE_ASSERT(MxDirectDraw::DeviceModesInfo, 0x17c); #ifndef DDSCAPS_3DDEVICE #define DDSCAPS_3DDEVICE 0x00002000l @@ -30,6 +30,12 @@ void EnableResizing(HWND hwnd, BOOL flag) } } +// OFFSET: LEGO1 0x1009efb0 +MxDirectDraw::DeviceModesInfo::DeviceModesInfo() +{ + memset(this, 0, sizeof(*this)); +} + // OFFSET: LEGO1 0x1009EFD0 MxDirectDraw::DeviceModesInfo::~DeviceModesInfo() { diff --git a/LEGO1/mxdirectdraw.h b/LEGO1/mxdirectdraw.h index 3e2c710a..8cee9477 100644 --- a/LEGO1/mxdirectdraw.h +++ b/LEGO1/mxdirectdraw.h @@ -1,4 +1,3 @@ - #ifndef MXDIRECTDRAW_H #define MXDIRECTDRAW_H @@ -7,6 +6,7 @@ extern BOOL g_is_PALETTEINDEXED8; +// VTABLE 0x100db818 // SIZE 0x880 class MxDirectDraw { @@ -37,11 +37,12 @@ class MxDirectDraw DDCAPS m_ddcaps; void* a_178; + DeviceModesInfo(); ~DeviceModesInfo(); }; -private: +protected: BOOL m_bOnlySoftRender; BOOL m_bFlipSurfaces; IDirectDraw* m_pDirectDraw; @@ -94,7 +95,7 @@ class MxDirectDraw virtual void DestroyButNotDirectDraw(); virtual const char* ErrorToString(HRESULT error); -private: +protected: BOOL CacheOriginalPaletteEntries(); HRESULT CreateDDSurface( LPDDSURFACEDESC a2,