From d4e7bb11326a73f74715a4097566e9af3cdcaa01 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 4 Jan 2024 14:37:15 -0500 Subject: [PATCH] Implement/match MxDirect3D::SetDevice (#401) * WIP * WIP * WIP * Rename class * Rename vars * Rename function * Rename * Rename flag * Fix deletion of modeArray * Remove obsolete comment --- ISLE/isleapp.cpp | 2 +- LEGO1/legovideomanager.cpp | 16 +++--- LEGO1/mxdirect3d.cpp | 101 ++++++++++++++++++++++++++++++++----- LEGO1/mxdirect3d.h | 40 ++++++++++----- LEGO1/mxdirectdraw.cpp | 2 +- LEGO1/mxdirectdraw.h | 80 ++++++++++++++--------------- 6 files changed, 164 insertions(+), 77 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index ab0d2290..c402098d 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -388,7 +388,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DefWindowProcA(hWnd, uMsg, wParam, lParam); case WM_DISPLAYCHANGE: if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->GetDirect3D()) { - if (VideoManager()->GetDirect3D()->GetDeviceModeFinder()) { + if (VideoManager()->GetDirect3D()->GetAssignedDevice()) { int targetDepth = wParam; int targetWidth = LOWORD(lParam); int targetHeight = HIWORD(lParam); diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index a17714fc..1572423f 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -61,7 +61,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM MxDevice* device = NULL; MxResult result = FAILURE; - MxDeviceEnumerate100d9cc8 deviceEnumerator; + MxDeviceEnumerate100d9cc8 deviceEnumerate; Vector3Data posVec(0.0, 1.25, -50.0); Vector3Data dirVec(0.0, 0.0, 1.0); Vector3Data upVec(0.0, 1.0, 0.0); @@ -85,24 +85,24 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM if (CreateDirect3D() != SUCCESS) goto done; - if (deviceEnumerator.DoEnumerate() != SUCCESS) + if (deviceEnumerate.DoEnumerate() != SUCCESS) goto done; if (p_videoParam.GetDeviceName()) { - deviceNum = deviceEnumerator.ParseDeviceName(p_videoParam.GetDeviceName()); + deviceNum = deviceEnumerate.ParseDeviceName(p_videoParam.GetDeviceName()); if (deviceNum >= 0) { - if ((deviceNum = deviceEnumerator.GetDevice(deviceNum, driver, device)) != SUCCESS) + if ((deviceNum = deviceEnumerate.GetDevice(deviceNum, driver, device)) != SUCCESS) deviceNum = -1; } } if (deviceNum < 0) { - deviceEnumerator.FUN_1009d210(); - deviceNum = deviceEnumerator.FUN_1009d0d0(); - deviceEnumerator.GetDevice(deviceNum, driver, device); + deviceEnumerate.FUN_1009d210(); + deviceNum = deviceEnumerate.FUN_1009d0d0(); + deviceEnumerate.GetDevice(deviceNum, driver, device); } - m_direct3d->FUN_1009b5f0(deviceEnumerator, driver, device); + m_direct3d->SetDevice(deviceEnumerate, driver, device); if (!driver->m_ddCaps.dwCaps2 && driver->m_ddCaps.dwSVBRops[7] != 2) p_videoParam.Flags().SetF2bit0(TRUE); diff --git a/LEGO1/mxdirect3d.cpp b/LEGO1/mxdirect3d.cpp index 5ea3202c..544252aa 100644 --- a/LEGO1/mxdirect3d.cpp +++ b/LEGO1/mxdirect3d.cpp @@ -2,7 +2,7 @@ #include // for vsprintf -DECOMP_SIZE_ASSERT(MxDeviceModeFinder, 0xe4); +DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4); DECOMP_SIZE_ASSERT(MxDirect3D, 0x894); DECOMP_SIZE_ASSERT(MxDevice, 0x1a4); DECOMP_SIZE_ASSERT(MxDisplayMode, 0x0c); @@ -15,7 +15,7 @@ MxDirect3D::MxDirect3D() this->m_pDirect3d = NULL; this->m_pDirect3dDevice = NULL; this->m_unk0x88c = NULL; - this->m_pDeviceModeFinder = NULL; + this->m_assignedDevice = NULL; } // FUNCTION: LEGO1 0x1009b140 @@ -73,16 +73,13 @@ void MxDirect3D::Destroy() this->m_pDirect3d = NULL; } - if (this->m_pDeviceModeFinder) { - delete m_pDeviceModeFinder; - this->m_pDeviceModeFinder = NULL; + if (this->m_assignedDevice) { + delete m_assignedDevice; + this->m_assignedDevice = NULL; } - // This should get deleted by MxDirectDraw::Destroy - if (m_pCurrentDeviceModesList) { - // delete m_pCurrentDeviceModesList; // missing? + if (m_pCurrentDeviceModesList) m_pCurrentDeviceModesList = NULL; - } MxDirectDraw::Destroy(); } @@ -118,27 +115,103 @@ BOOL MxDirect3D::CreateIDirect3D() BOOL MxDirect3D::D3DSetMode() { // TODO - // if (m_pDeviceModeFinder) + // if (m_assignedDevice) 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; } -// STUB: LEGO1 0x1009b5f0 -BOOL MxDirect3D::FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerator, MxDriver* p_driver, MxDevice* p_device) +// FUNCTION: LEGO1 0x1009b5f0 +BOOL MxDirect3D::SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_driver, MxDevice* p_device) { + if (m_assignedDevice) { + delete m_assignedDevice; + m_assignedDevice = NULL; + m_pCurrentDeviceModesList = NULL; + } + + MxAssignedDevice* assignedDevice = new MxAssignedDevice; + MxS32 i = 0; + + for (list::iterator it = p_deviceEnumerate.m_list.begin(); it != p_deviceEnumerate.m_list.end(); it++) { + MxDriver& driver = *it; + + if (&driver == p_driver) { + assignedDevice->m_deviceInfo = new MxDirectDraw::DeviceModesInfo; + + if (driver.m_guid) { + assignedDevice->m_deviceInfo->m_guid = new GUID; + memcpy(assignedDevice->m_deviceInfo->m_guid, driver.m_guid, sizeof(GUID)); + } + + assignedDevice->m_deviceInfo->m_count = driver.m_displayModes.size(); + + if (assignedDevice->m_deviceInfo->m_count > 0) { + assignedDevice->m_deviceInfo->m_modeArray = + new MxDirectDraw::Mode[assignedDevice->m_deviceInfo->m_count]; + + MxS32 j = 0; + for (list::iterator it2 = driver.m_displayModes.begin(); + it2 != driver.m_displayModes.end(); + it2++) { + assignedDevice->m_deviceInfo->m_modeArray[j].m_width = (*it2).m_width; + assignedDevice->m_deviceInfo->m_modeArray[j].m_height = (*it2).m_height; + assignedDevice->m_deviceInfo->m_modeArray[j].m_bitsPerPixel = (*it2).m_bitsPerPixel; + j++; + } + } + + memcpy( + &assignedDevice->m_deviceInfo->m_ddcaps, + &driver.m_ddCaps, + sizeof(assignedDevice->m_deviceInfo->m_ddcaps) + ); + + if (i == 0) + assignedDevice->m_flags |= MxAssignedDevice::Flag_PrimaryDevice; + + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { + MxDevice& device = *it2; + if (&device != p_device) + continue; + + memcpy(&assignedDevice->m_guid, device.m_guid, sizeof(assignedDevice->m_guid)); + + D3DDEVICEDESC* desc; + if (device.m_HWDesc.dcmColorModel) { + assignedDevice->m_flags |= MxAssignedDevice::Flag_HardwareMode; + desc = &device.m_HWDesc; + } + else + desc = &device.m_HELDesc; + + memcpy(&assignedDevice->m_desc, desc, sizeof(assignedDevice->m_desc)); + m_assignedDevice = assignedDevice; + m_pCurrentDeviceModesList = assignedDevice->m_deviceInfo; + break; + } + } + + i++; + } + + if (!m_assignedDevice) { + delete assignedDevice; + return FALSE; + } + return TRUE; } // FUNCTION: LEGO1 0x1009b8b0 -MxDeviceModeFinder::MxDeviceModeFinder() +MxAssignedDevice::MxAssignedDevice() { memset(this, 0, sizeof(*this)); } // FUNCTION: LEGO1 0x1009b8d0 -MxDeviceModeFinder::~MxDeviceModeFinder() +MxAssignedDevice::~MxAssignedDevice() { if (m_deviceInfo) { delete m_deviceInfo; diff --git a/LEGO1/mxdirect3d.h b/LEGO1/mxdirect3d.h index 8b792ac0..4877159b 100644 --- a/LEGO1/mxdirect3d.h +++ b/LEGO1/mxdirect3d.h @@ -8,13 +8,25 @@ #include -// SIZE 0xe4 -class MxDeviceModeFinder { -public: - MxDeviceModeFinder(); - ~MxDeviceModeFinder(); +class MxDirect3D; - undefined m_pad[0xe0]; // 0x00 +// SIZE 0xe4 +class MxAssignedDevice { +public: + enum { + Flag_HardwareMode = 0x01, + Flag_PrimaryDevice = 0x02 + }; + + MxAssignedDevice(); + ~MxAssignedDevice(); + + friend class MxDirect3D; + +private: + GUID m_guid; // 0x00 + MxU32 m_flags; // 0x10 + D3DDEVICEDESC m_desc; // 0x14 MxDirectDraw::DeviceModesInfo* m_deviceInfo; // 0xe0 }; @@ -45,18 +57,18 @@ class MxDirect3D : public MxDirectDraw { BOOL CreateIDirect3D(); BOOL D3DSetMode(); - BOOL FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerator, MxDriver* p_driver, MxDevice* p_device); + BOOL SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_driver, MxDevice* p_device); - inline MxDeviceModeFinder* GetDeviceModeFinder() { return this->m_pDeviceModeFinder; }; + inline MxAssignedDevice* GetAssignedDevice() { return this->m_assignedDevice; }; inline IDirect3D* GetDirect3D() { return this->m_pDirect3d; } inline IDirect3DDevice* GetDirect3DDevice() { return this->m_pDirect3dDevice; } private: - MxDeviceModeFinder* m_pDeviceModeFinder; // 0x880 - IDirect3D* m_pDirect3d; // 0x884 - IDirect3DDevice* m_pDirect3dDevice; // 0x888 - undefined4 m_unk0x88c; // 0x88c - undefined4 m_unk0x890; // 0x890 + MxAssignedDevice* m_assignedDevice; // 0x880 + IDirect3D* m_pDirect3d; // 0x884 + IDirect3DDevice* m_pDirect3dDevice; // 0x888 + undefined4 m_unk0x88c; // 0x88c + undefined4 m_unk0x890; // 0x890 }; // SIZE 0x1a4 @@ -197,6 +209,8 @@ class MxDeviceEnumerate { static undefined4 FUN_1009d1a0(); static undefined4 FUN_1009d1e0(); + friend class MxDirect3D; + private: list m_list; // 0x04 MxBool m_initialized; // 0x10 diff --git a/LEGO1/mxdirectdraw.cpp b/LEGO1/mxdirectdraw.cpp index 12a7cde0..fa030eb8 100644 --- a/LEGO1/mxdirectdraw.cpp +++ b/LEGO1/mxdirectdraw.cpp @@ -1127,6 +1127,6 @@ MxDirectDraw::DeviceModesInfo::~DeviceModesInfo() } if (m_modeArray != NULL) { - delete m_modeArray; + delete[] m_modeArray; } } diff --git a/LEGO1/mxdirectdraw.h b/LEGO1/mxdirectdraw.h index 6d3d190b..ce45a823 100644 --- a/LEGO1/mxdirectdraw.h +++ b/LEGO1/mxdirectdraw.h @@ -12,12 +12,8 @@ class MxDirectDraw { public: typedef void (*ErrorHandler)(const char*, HRESULT, void*); - // size 0x0c + // SIZE 0x0c struct Mode { - MxS32 m_width; - MxS32 m_height; - MxS32 m_bitsPerPixel; - MxS32 operator==(const Mode& p_mode) const { return ( @@ -25,50 +21,54 @@ class MxDirectDraw { (m_bitsPerPixel == p_mode.m_bitsPerPixel) ); } + + MxS32 m_width; // 0x00 + MxS32 m_height; // 0x04 + MxS32 m_bitsPerPixel; // 0x08 }; // SIZE 0x17c struct DeviceModesInfo { - GUID* m_guid; - Mode* m_modeArray; - MxS32 m_count; - DDCAPS m_ddcaps; - void* m_unk0x178; - DeviceModesInfo(); ~DeviceModesInfo(); + + GUID* m_guid; // 0x00 + Mode* m_modeArray; // 0x04 + MxS32 m_count; // 0x08 + DDCAPS m_ddcaps; // 0x0c + void* m_unk0x178; // 0x178 }; protected: - BOOL m_bOnlySoftRender; - BOOL m_bFlipSurfaces; - IDirectDraw* m_pDirectDraw; - IDirectDrawSurface* m_pFrontBuffer; - IDirectDrawSurface* m_pBackBuffer; - IDirectDrawSurface* m_pZBuffer; - IDirectDrawSurface* m_pText1Surface; - IDirectDrawSurface* m_pText2Surface; - IDirectDrawClipper* m_pClipper; - IDirectDrawPalette* m_pPalette; - PALETTEENTRY m_paletteEntries[256]; - PALETTEENTRY m_originalPaletteEntries[256]; - SIZE m_text1SizeOnSurface; - SIZE m_text2SizeOnSurface; - HWND m_hWndMain; - HFONT m_hFont; - BOOL m_bIgnoreWMSIZE; - BOOL m_bPrimaryPalettized; - BOOL m_bFullScreen; - void* m_unk0x850; - BOOL m_bOnlySystemMemory; - BOOL m_bIsOnPrimaryDevice; - ErrorHandler m_pErrorHandler; - ErrorHandler m_pFatalErrorHandler; - void* m_pErrorHandlerArg; - void* m_pFatalErrorHandlerArg; - int m_pauseCount; - DeviceModesInfo* m_pCurrentDeviceModesList; - Mode m_currentMode; + BOOL m_bOnlySoftRender; // 0x04 + BOOL m_bFlipSurfaces; // 0x08 + IDirectDraw* m_pDirectDraw; // 0x0c + IDirectDrawSurface* m_pFrontBuffer; // 0x10 + IDirectDrawSurface* m_pBackBuffer; // 0x14 + IDirectDrawSurface* m_pZBuffer; // 0x18 + IDirectDrawSurface* m_pText1Surface; // 0x1c + IDirectDrawSurface* m_pText2Surface; // 0x20 + IDirectDrawClipper* m_pClipper; // 0x24 + IDirectDrawPalette* m_pPalette; // 0x28 + PALETTEENTRY m_paletteEntries[256]; // 0x2c + PALETTEENTRY m_originalPaletteEntries[256]; // 0x42c + SIZE m_text1SizeOnSurface; // 0x82c + SIZE m_text2SizeOnSurface; // 0x834 + HWND m_hWndMain; // 0x83c + HFONT m_hFont; // 0x840 + BOOL m_bIgnoreWMSIZE; // 0x844 + BOOL m_bPrimaryPalettized; // 0x848 + BOOL m_bFullScreen; // 0x84c + void* m_unk0x850; // 0x850 + BOOL m_bOnlySystemMemory; // 0x854 + BOOL m_bIsOnPrimaryDevice; // 0x858 + ErrorHandler m_pErrorHandler; // 0x85c + ErrorHandler m_pFatalErrorHandler; // 0x860 + void* m_pErrorHandlerArg; // 0x864 + void* m_pFatalErrorHandlerArg; // 0x868 + int m_pauseCount; // 0x86c + DeviceModesInfo* m_pCurrentDeviceModesList; // 0x870 + Mode m_currentMode; // 0x87c public: __declspec(dllexport) int FlipToGDISurface();