From 49e3fa238fe473c76b4aaba1339e0bf90bfe3945 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 3 Jan 2024 22:03:02 -0500 Subject: [PATCH] Implement/match most remaining MxDirect3D device enumeration functions (#400) * WIP * WIP * Implement/match most remaining MxDirect3D device enumeration functions * Fix names --- LEGO1/legovideomanager.cpp | 30 +++---- LEGO1/mxdirect3d.cpp | 166 +++++++++++++++++++++++++++++++------ LEGO1/mxdirect3d.h | 42 ++++++---- 3 files changed, 183 insertions(+), 55 deletions(-) diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index 8d0a872a..a17714fc 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -57,18 +57,18 @@ MxResult LegoVideoManager::CreateDirect3D() MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread) { MxBool paletteCreated = FALSE; - undefined* und1 = NULL; - undefined* und2 = NULL; + MxDriver* driver = NULL; + MxDevice* device = NULL; MxResult result = FAILURE; - MxDeviceEnumerate100d9cc8 deviceEnumerate; + MxDeviceEnumerate100d9cc8 deviceEnumerator; Vector3Data posVec(0.0, 1.25, -50.0); Vector3Data dirVec(0.0, 0.0, 1.0); Vector3Data upVec(0.0, 1.0, 0.0); Matrix4Data outMatrix; HWND hwnd = MxOmni::GetInstance()->GetWindowHandle(); MxS32 bits = p_videoParam.Flags().Get16Bit() ? 16 : 8; - MxS32 und3 = -1; + MxS32 deviceNum = -1; if (!p_videoParam.GetPalette()) { MxPalette* palette = new MxPalette; @@ -85,26 +85,26 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM if (CreateDirect3D() != SUCCESS) goto done; - if (deviceEnumerate.DoEnumerate() != SUCCESS) + if (deviceEnumerator.DoEnumerate() != SUCCESS) goto done; if (p_videoParam.GetDeviceName()) { - und3 = deviceEnumerate.ParseDeviceName(p_videoParam.GetDeviceName()); - if (und3 >= 0) { - if ((und3 = deviceEnumerate.FUN_1009d030(und3, &und1, &und2)) != SUCCESS) - und3 = -1; + deviceNum = deviceEnumerator.ParseDeviceName(p_videoParam.GetDeviceName()); + if (deviceNum >= 0) { + if ((deviceNum = deviceEnumerator.GetDevice(deviceNum, driver, device)) != SUCCESS) + deviceNum = -1; } } - if (und3 < 0) { - deviceEnumerate.FUN_1009d210(); - und3 = deviceEnumerate.FUN_1009d0d0(); - deviceEnumerate.FUN_1009d030(und3, &und1, &und2); + if (deviceNum < 0) { + deviceEnumerator.FUN_1009d210(); + deviceNum = deviceEnumerator.FUN_1009d0d0(); + deviceEnumerator.GetDevice(deviceNum, driver, device); } - m_direct3d->FUN_1009b5f0(deviceEnumerate, und1, und2); + m_direct3d->FUN_1009b5f0(deviceEnumerator, driver, device); - if (!*((MxU32*) &und1[0x14]) && *((MxU32*) &und1[0xe0]) != 2) + if (!driver->m_ddCaps.dwCaps2 && driver->m_ddCaps.dwSVBRops[7] != 2) p_videoParam.Flags().SetF2bit0(TRUE); else p_videoParam.Flags().SetF2bit0(FALSE); diff --git a/LEGO1/mxdirect3d.cpp b/LEGO1/mxdirect3d.cpp index fae5e38e..5ea3202c 100644 --- a/LEGO1/mxdirect3d.cpp +++ b/LEGO1/mxdirect3d.cpp @@ -6,7 +6,7 @@ DECOMP_SIZE_ASSERT(MxDeviceModeFinder, 0xe4); DECOMP_SIZE_ASSERT(MxDirect3D, 0x894); DECOMP_SIZE_ASSERT(MxDevice, 0x1a4); DECOMP_SIZE_ASSERT(MxDisplayMode, 0x0c); -DECOMP_SIZE_ASSERT(MxDeviceEnumerateElement, 0x190); +DECOMP_SIZE_ASSERT(MxDriver, 0x190); DECOMP_SIZE_ASSERT(MxDeviceEnumerate, 0x14); // FUNCTION: LEGO1 0x1009b0a0 @@ -126,7 +126,7 @@ BOOL MxDirect3D::D3DSetMode() } // STUB: LEGO1 0x1009b5f0 -BOOL MxDirect3D::FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerate, undefined* p_und1, undefined* p_und2) +BOOL MxDirect3D::FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerator, MxDriver* p_driver, MxDevice* p_device) { return TRUE; } @@ -147,7 +147,7 @@ MxDeviceModeFinder::~MxDeviceModeFinder() } // FUNCTION: LEGO1 0x1009ba80 -MxDeviceEnumerateElement::MxDeviceEnumerateElement(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +MxDriver::MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { m_guid = NULL; m_driverDesc = NULL; @@ -158,7 +158,7 @@ MxDeviceEnumerateElement::MxDeviceEnumerateElement(LPGUID p_guid, LPSTR p_driver } // FUNCTION: LEGO1 0x1009bb80 -MxDeviceEnumerateElement::~MxDeviceEnumerateElement() +MxDriver::~MxDriver() { if (m_guid) delete m_guid; @@ -169,7 +169,7 @@ MxDeviceEnumerateElement::~MxDeviceEnumerateElement() } // FUNCTION: LEGO1 0x1009bc30 -void MxDeviceEnumerateElement::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { if (m_driverDesc) { delete[] m_driverDesc; @@ -272,19 +272,19 @@ MxDeviceEnumerate::MxDeviceEnumerate() // FUNCTION: LEGO1 0x1009c070 BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { - MxDeviceEnumerateElement device(p_guid, p_driverDesc, p_driverName); - m_list.push_back(device); + MxDriver driver(p_guid, p_driverDesc, p_driverName); + m_list.push_back(driver); // Must be zeroed because held resources are copied by pointer only // and should not be freed at the end of this function - device.m_guid = NULL; - device.m_driverDesc = NULL; - device.m_driverName = NULL; - memset(&device.m_ddCaps, 0, sizeof(device.m_ddCaps)); + driver.m_guid = NULL; + driver.m_driverDesc = NULL; + driver.m_driverName = NULL; + memset(&driver.m_ddCaps, 0, sizeof(driver.m_ddCaps)); LPDIRECT3D2 lpDirect3d2 = NULL; LPDIRECTDRAW lpDD = NULL; - MxDeviceEnumerateElement& newDevice = m_list.back(); + MxDriver& newDevice = m_list.back(); HRESULT result = DirectDrawCreate(newDevice.m_guid, &lpDD, NULL); if (result != DD_OK) @@ -444,7 +444,7 @@ MxS32 MxDeviceEnumerate::ParseDeviceName(const char* p_deviceId) } // FUNCTION: LEGO1 0x1009cf20 -MxS32 MxDeviceEnumerate::ProcessDeviceBytes(MxS32 p_num, GUID& p_guid) +MxS32 MxDeviceEnumerate::ProcessDeviceBytes(MxS32 p_deviceNum, GUID& p_guid) { if (!m_initialized) return -1; @@ -464,17 +464,18 @@ MxS32 MxDeviceEnumerate::ProcessDeviceBytes(MxS32 p_num, GUID& p_guid) GUID4 deviceGuid; memcpy(&deviceGuid, &p_guid, sizeof(GUID4)); - for (list::iterator it = m_list.begin(); it != m_list.end(); it++) { - if (p_num >= 0 && p_num < i) + for (list::iterator it = m_list.begin(); it != m_list.end(); it++) { + if (p_deviceNum >= 0 && p_deviceNum < i) return -1; GUID4 compareGuid; - MxDeviceEnumerateElement& elem = *it; - for (list::iterator it2 = elem.m_devices.begin(); it2 != elem.m_devices.end(); it2++) { + MxDriver& driver = *it; + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { memcpy(&compareGuid, (*it2).m_guid, sizeof(GUID4)); if (compareGuid.m_data1 == deviceGuid.m_data1 && compareGuid.m_data2 == deviceGuid.m_data2 && - compareGuid.m_data3 == deviceGuid.m_data3 && compareGuid.m_data4 == deviceGuid.m_data4 && i == p_num) + compareGuid.m_data3 == deviceGuid.m_data3 && compareGuid.m_data4 == deviceGuid.m_data4 && + i == p_deviceNum) return j; j++; @@ -486,20 +487,135 @@ MxS32 MxDeviceEnumerate::ProcessDeviceBytes(MxS32 p_num, GUID& p_guid) return -1; } -// STUB: LEGO1 0x1009d030 -MxResult MxDeviceEnumerate::FUN_1009d030(MxS32 p_und1, undefined** p_und2, undefined** p_und3) +// FUNCTION: LEGO1 0x1009d030 +MxResult MxDeviceEnumerate::GetDevice(MxS32 p_deviceNum, MxDriver*& p_driver, MxDevice*& p_device) { + if (p_deviceNum >= 0 && m_initialized) { + MxS32 i = 0; + + for (list::iterator it = m_list.begin(); it != m_list.end(); it++) { + p_driver = &*it; + + for (list::iterator it2 = p_driver->m_devices.begin(); it2 != p_driver->m_devices.end(); it2++) { + if (i == p_deviceNum) { + p_device = &*it2; + return SUCCESS; + } + i++; + } + } + + return FAILURE; + } + return FAILURE; } -// STUB: LEGO1 0x1009d0d0 -MxResult MxDeviceEnumerate::FUN_1009d0d0() +// FUNCTION: LEGO1 0x1009d0d0 +MxS32 MxDeviceEnumerate::FUN_1009d0d0() { - return FAILURE; + if (!m_initialized) + return -1; + + if (m_list.empty()) + return -1; + + MxS32 i = 0; + MxS32 j = 0; + MxS32 k = -1; + MxU32 und = FUN_1009d1a0(); + + for (list::iterator it = m_list.begin();; it++) { + if (it == m_list.end()) + return k; + + for (list::iterator it2 = (*it).m_devices.begin(); it2 != (*it).m_devices.end(); it2++) { + if ((*it2).m_HWDesc.dcmColorModel) + return j; + + if ((und && (*it2).m_HELDesc.dcmColorModel == D3DCOLOR_RGB && i == 0) || + (*it2).m_HELDesc.dcmColorModel == D3DCOLOR_MONO && i == 0 && k < 0) + k = j; + + j++; + } + + i++; + } + + return -1; } -// STUB: LEGO1 0x1009d210 +// STUB: LEGO1 0x1009d1a0 +undefined4 MxDeviceEnumerate::FUN_1009d1a0() +{ + return 1; +} + +// STUB: LEGO1 0x1009d1e0 +undefined4 MxDeviceEnumerate::FUN_1009d1e0() +{ + return 1; +} + +// FUNCTION: LEGO1 0x1009d210 MxResult MxDeviceEnumerate::FUN_1009d210() { - return FAILURE; + if (!m_initialized) + return FAILURE; + + for (list::iterator it = m_list.begin(); it != m_list.end();) { + MxDriver& driver = *it; + + if (!FUN_1009d370(driver)) + m_list.erase(it++); + else { + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end();) { + MxDevice& device = *it2; + + if (!FUN_1009d3d0(device)) + driver.m_devices.erase(it2++); + else + it2++; + } + + if (driver.m_devices.empty()) + m_list.erase(it++); + else + it++; + } + } + + return m_list.empty() ? FAILURE : SUCCESS; +} + +// FUNCTION: LEGO1 0x1009d370 +MxBool MxDeviceEnumerate::FUN_1009d370(MxDriver& p_driver) +{ + for (list::iterator it = p_driver.m_displayModes.begin(); it != p_driver.m_displayModes.end(); + it++) { + if ((*it).m_width == 640 && (*it).m_height == 480) { + if ((*it).m_bitsPerPixel == 8 || (*it).m_bitsPerPixel == 16) + return TRUE; + } + } + + return FALSE; +} + +// FUNCTION: LEGO1 0x1009d3d0 +MxBool MxDeviceEnumerate::FUN_1009d3d0(MxDevice& p_device) +{ + if (m_list.size() <= 0) + return FALSE; + + if (p_device.m_HWDesc.dcmColorModel) + return p_device.m_HWDesc.dwDeviceZBufferBitDepth & DDBD_16 && p_device.m_HWDesc.dpcTriCaps.dwTextureCaps & 1; + + for (list::iterator it = m_list.front().m_devices.begin(); it != m_list.front().m_devices.end(); it++) { + if ((&*it) == &p_device) + return TRUE; + } + + return FALSE; } diff --git a/LEGO1/mxdirect3d.h b/LEGO1/mxdirect3d.h index fb9d5618..8b792ac0 100644 --- a/LEGO1/mxdirect3d.h +++ b/LEGO1/mxdirect3d.h @@ -19,6 +19,8 @@ public: }; class MxDeviceEnumerate; +struct MxDriver; +struct MxDevice; // VTABLE: LEGO1 0x100db800 // SIZE 0x894 @@ -43,7 +45,7 @@ public: BOOL CreateIDirect3D(); BOOL D3DSetMode(); - BOOL FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerate, undefined* p_und1, undefined* p_und2); + BOOL FUN_1009b5f0(MxDeviceEnumerate& p_deviceEnumerator, MxDriver* p_driver, MxDevice* p_device); inline MxDeviceModeFinder* GetDeviceModeFinder() { return this->m_pDeviceModeFinder; }; inline IDirect3D* GetDirect3D() { return this->m_pDirect3d; } @@ -98,10 +100,10 @@ struct MxDisplayMode { }; // SIZE 0x190 -struct MxDeviceEnumerateElement { - MxDeviceEnumerateElement() {} - ~MxDeviceEnumerateElement(); - MxDeviceEnumerateElement(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); +struct MxDriver { + MxDriver() {} + ~MxDriver(); + MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); void Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); @@ -112,8 +114,8 @@ struct MxDeviceEnumerateElement { list m_devices; // 0x178 list m_displayModes; // 0x184 - MxBool operator==(MxDeviceEnumerateElement) const { return TRUE; } - MxBool operator<(MxDeviceEnumerateElement) const { return TRUE; } + MxBool operator==(MxDriver) const { return TRUE; } + MxBool operator<(MxDriver) const { return TRUE; } }; // clang-format off @@ -134,17 +136,23 @@ struct MxDeviceEnumerateElement { // clang-format off // TEMPLATE: LEGO1 0x1009bf50 -// list >::~list > +// list >::~list > // clang-format on // TEMPLATE: LEGO1 0x1009bfc0 -// List::~List +// List::~List // Compiler-generated copy ctor // Part of this function are two more synthetic sub-routines, // LEGO1 0x1009c400 and LEGO1 0x1009c460 // SYNTHETIC: LEGO1 0x1009c290 -// MxDeviceEnumerateElement::MxDeviceEnumerateElement +// MxDriver::MxDriver + +// SYNTHETIC: LEGO1 0x1009d450 +// MxDriver::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x1009d470 +// MxDevice::`scalar deleting destructor' // VTABLE: LEGO1 0x100db814 // SIZE 0x14 @@ -167,10 +175,12 @@ public: ); const char* EnumerateErrorToString(HRESULT p_error); MxS32 ParseDeviceName(const char* p_deviceId); - MxS32 ProcessDeviceBytes(MxS32 p_num, GUID& p_guid); - MxResult FUN_1009d030(MxS32 p_und1, undefined** p_und2, undefined** p_und3); - MxResult FUN_1009d0d0(); + MxS32 ProcessDeviceBytes(MxS32 p_deviceNum, GUID& p_guid); + MxResult GetDevice(MxS32 p_deviceNum, MxDriver*& p_driver, MxDevice*& p_device); + MxS32 FUN_1009d0d0(); MxResult FUN_1009d210(); + MxBool FUN_1009d370(MxDriver& p_driver); + MxBool FUN_1009d3d0(MxDevice& p_device); static void BuildErrorString(const char*, ...); static BOOL CALLBACK @@ -184,10 +194,12 @@ public: LPD3DDEVICEDESC p_HELDesc, LPVOID p_context ); + static undefined4 FUN_1009d1a0(); + static undefined4 FUN_1009d1e0(); private: - list m_list; // 0x04 - MxBool m_initialized; // 0x10 + list m_list; // 0x04 + MxBool m_initialized; // 0x10 }; // VTABLE: LEGO1 0x100d9cc8