diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e9a675c..8ed6f3a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,7 @@ add_library(mxdirectx STATIC LEGO1/mxdirectx/mxdirect3d.cpp LEGO1/mxdirectx/mxdirectdraw.cpp LEGO1/mxdirectx/mxdirectxinfo.cpp + LEGO1/mxdirectx/legodxinfo.cpp ) register_lego1_target(mxdirectx) set_property(TARGET mxdirectx PROPERTY ARCHIVE_OUTPUT_NAME "MxDirectX$<$:d>") @@ -288,7 +289,7 @@ add_library(lego1 SHARED LEGO1/define.cpp LEGO1/lego/legoomni/src/actors/act2actor.cpp LEGO1/lego/legoomni/src/actors/act2genactor.cpp - LEGO1/lego/legoomni/src/actors/act3actor.cpp + LEGO1/lego/legoomni/src/actors/act3actors.cpp LEGO1/lego/legoomni/src/actors/act3brickster.cpp LEGO1/lego/legoomni/src/actors/act3cop.cpp LEGO1/lego/legoomni/src/actors/act3shark.cpp @@ -466,6 +467,7 @@ endif() if (ISLE_BUILD_CONFIG) add_executable(config WIN32 LEGO1/mxdirectx/mxdirectxinfo.cpp + LEGO1/mxdirectx/legodxinfo.cpp CONFIG/config.cpp CONFIG/ConfigCommandLineInfo.cpp CONFIG/AboutDlg.cpp diff --git a/CONFIG/MainDlg.cpp b/CONFIG/MainDlg.cpp index da0b5d17..7ae5393e 100644 --- a/CONFIG/MainDlg.cpp +++ b/CONFIG/MainDlg.cpp @@ -4,7 +4,7 @@ #include "config.h" #include "res/resource.h" -#include +#include DECOMP_SIZE_ASSERT(CDialog, 0x60) DECOMP_SIZE_ASSERT(CMainDialog, 0x70) @@ -57,7 +57,7 @@ BOOL CMainDialog::OnInitDialog() } SendMessage(WM_SETICON, ICON_BIG, (LPARAM) m_icon); SendMessage(WM_SETICON, ICON_SMALL, (LPARAM) m_icon); - MxDeviceEnumerate* enumerator = currentConfigApp->m_device_enumerator; + LegoDeviceEnumerate* enumerator = currentConfigApp->m_device_enumerator; enumerator->FUN_1009d210(); m_modified = currentConfigApp->ReadRegisterSettings(); CWnd* list_3d_devices = GetDlgItem(IDC_LIST_3DDEVICES); @@ -131,7 +131,7 @@ HCURSOR CMainDialog::OnQueryDragIcon() // FUNCTION: CONFIG 0x00404240 void CMainDialog::OnList3DevicesSelectionChanged() { - MxDeviceEnumerate* device_enumerator = currentConfigApp->m_device_enumerator; + LegoDeviceEnumerate* device_enumerator = currentConfigApp->m_device_enumerator; int selected = ::SendMessage(GetDlgItem(IDC_LIST_3DDEVICES)->m_hWnd, LB_GETCURSEL, 0, 0); device_enumerator->GetDevice(selected, currentConfigApp->m_driver, currentConfigApp->m_device); if (currentConfigApp->GetHardwareDeviceColorModel()) { diff --git a/CONFIG/config.cpp b/CONFIG/config.cpp index 59c03332..d4457b55 100644 --- a/CONFIG/config.cpp +++ b/CONFIG/config.cpp @@ -5,6 +5,7 @@ #include "detectdx5.h" #include // _chdir +#include #include #include // _spawnl diff --git a/LEGO1/lego/legoomni/include/act3actor.h b/LEGO1/lego/legoomni/include/act3actors.h similarity index 78% rename from LEGO1/lego/legoomni/include/act3actor.h rename to LEGO1/lego/legoomni/include/act3actors.h index b71939e0..ac955816 100644 --- a/LEGO1/lego/legoomni/include/act3actor.h +++ b/LEGO1/lego/legoomni/include/act3actors.h @@ -1,10 +1,13 @@ -#ifndef ACT3ACTOR_H -#define ACT3ACTOR_H +#ifndef ACT3ACTORS_H +#define ACT3ACTORS_H #include "legoanimactor.h" +// File name verified by multiple assertions, e.g. BETA10 0x10018391 + // VTABLE: LEGO1 0x100d7668 LegoPathActor // VTABLE: LEGO1 0x100d7738 LegoAnimActor +// VTABLE: BETA10 0x101b8a98 LegoPathActor // SIZE 0x178 class Act3Actor : public LegoAnimActor { public: @@ -30,4 +33,4 @@ class Act3Actor : public LegoAnimActor { undefined4 m_unk0x1c; // 0x1c }; -#endif // ACT3ACTOR_H +#endif // ACT3ACTORS_H diff --git a/LEGO1/lego/legoomni/include/act3brickster.h b/LEGO1/lego/legoomni/include/act3brickster.h index f9066d3c..c84b8dd7 100644 --- a/LEGO1/lego/legoomni/include/act3brickster.h +++ b/LEGO1/lego/legoomni/include/act3brickster.h @@ -1,7 +1,7 @@ #ifndef ACT3BRICKSTER_H #define ACT3BRICKSTER_H -#include "act3actor.h" +#include "act3actors.h" // VTABLE: LEGO1 0x100d7838 LegoPathActor // VTABLE: LEGO1 0x100d7908 LegoAnimActor diff --git a/LEGO1/lego/legoomni/include/act3cop.h b/LEGO1/lego/legoomni/include/act3cop.h index 29ac65b6..a720b84c 100644 --- a/LEGO1/lego/legoomni/include/act3cop.h +++ b/LEGO1/lego/legoomni/include/act3cop.h @@ -1,7 +1,7 @@ #ifndef ACT3COP_H #define ACT3COP_H -#include "act3actor.h" +#include "act3actors.h" // VTABLE: LEGO1 0x100d7750 LegoPathActor // VTABLE: LEGO1 0x100d7820 LegoAnimActor diff --git a/LEGO1/lego/legoomni/src/actors/act3actor.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp similarity index 92% rename from LEGO1/lego/legoomni/src/actors/act3actor.cpp rename to LEGO1/lego/legoomni/src/actors/act3actors.cpp index 5ae24f14..01359090 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -1,4 +1,4 @@ -#include "act3actor.h" +#include "act3actors.h" DECOMP_SIZE_ASSERT(Act3Actor, 0x178) diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 00f88397..6bbae1fa 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -5,7 +5,7 @@ #include "act2genactor.h" #include "act2policestation.h" #include "act3.h" -#include "act3actor.h" +#include "act3actors.h" #include "act3brickster.h" #include "act3cop.h" #include "act3shark.h" diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 0eae0878..21147b1f 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -4,6 +4,7 @@ #include "legoinputmanager.h" #include "legomain.h" #include "misc.h" +#include "mxdirectx/legodxinfo.h" #include "mxdirectx/mxdirect3d.h" #include "mxdirectx/mxstopwatch.h" #include "mxdisplaysurface.h" diff --git a/LEGO1/mxdirectx/legodxinfo.cpp b/LEGO1/mxdirectx/legodxinfo.cpp new file mode 100644 index 00000000..eb511f2b --- /dev/null +++ b/LEGO1/mxdirectx/legodxinfo.cpp @@ -0,0 +1,373 @@ +#include "legodxinfo.h" + +#include +#include // for vsprintf + +// File name validated by BETA10 0x1011cba3; directory unknown + +// FUNCTION: CONFIG 0x00402560 +// FUNCTION: LEGO1 0x1009ce60 +// FUNCTION: BETA10 0x1011c7e0 +int LegoDeviceEnumerate::ParseDeviceName(const char* p_deviceId) +{ + if (!IsInitialized()) { + return -1; + } + + int unknown = -1; + int num = -1; + int hex[4]; + + if (sscanf(p_deviceId, "%d 0x%x 0x%x 0x%x 0x%x", &num, &hex[0], &hex[1], &hex[2], &hex[3]) != 5) { + return -1; + } + + if (num < 0) { + return -1; + } + + GUID guid; + memcpy(&guid, hex, sizeof(guid)); + + int result = ProcessDeviceBytes(num, guid); + + if (result < 0) { + result = ProcessDeviceBytes(-1, guid); + } + + return result; +} + +// FUNCTION: CONFIG 0x00402620 +// FUNCTION: LEGO1 0x1009cf20 +// FUNCTION: BETA10 0x1011c8b3 +int LegoDeviceEnumerate::ProcessDeviceBytes(int p_deviceNum, GUID& p_guid) +{ + if (!IsInitialized()) { + return -1; + } + + int i = 0; + int j = 0; + + static_assert(sizeof(GUID4) == sizeof(GUID), "Equal size"); + + GUID4 deviceGuid; + memcpy(&deviceGuid, &p_guid, sizeof(GUID4)); + + for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { + if (p_deviceNum >= 0 && p_deviceNum < i) { + return -1; + } + + GUID4 compareGuid; + MxDriver& driver = *it; + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { + Direct3DDeviceInfo& md3d = *it2; + assert(md3d.m_guid); + + memcpy(&compareGuid, md3d.m_guid, sizeof(GUID4)); + + if (GUID4::Compare(compareGuid, deviceGuid) && i == p_deviceNum) { + return j; + } + + j++; + } + } + + return -1; +} + +// FUNCTION: CONFIG 0x00402730 +// FUNCTION: LEGO1 0x1009d030 +// FUNCTION: BETA10 0x1011ca54 +int LegoDeviceEnumerate::GetDevice(int p_deviceNum, MxDriver*& p_driver, Direct3DDeviceInfo*& p_device) +{ + if (p_deviceNum < 0 || !IsInitialized()) { + return -1; + } + + int 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 0; + } + i++; + } + } + + return -1; +} + +// FUNCTION: CONFIG 0x004027d0 +// FUNCTION: BETA10 0x1011cb70 +int LegoDeviceEnumerate::FormatDeviceName(char* p_buffer, const MxDriver* p_ddInfo, const Direct3DDeviceInfo* p_d3dInfo) + const +{ + int number = 0; + assert(p_ddInfo && p_d3dInfo); + + for (list::const_iterator it = m_list.begin(); it != m_list.end(); it++, number++) { + if (&(*it) == p_ddInfo) { + GUID4 guid; + memcpy(&guid, p_d3dInfo->m_guid, sizeof(GUID4)); + + sprintf(p_buffer, "%d 0x%x 0x%x 0x%x 0x%x", number, guid.m_data1, guid.m_data2, guid.m_data3, guid.m_data4); + return 0; + } + } + + return -1; +} + +// FUNCTION: BETA10 0x1011cc65 +int LegoDeviceEnumerate::BETA_1011cc65(int p_idx, char* p_buffer) +{ + if (p_idx < 0 || !IsInitialized()) { + return -1; + } + + int i = 0; + int j = 0; + + for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { + MxDriver& driver = *it; + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { + + if (j == p_idx) { + GUID4 guid; + memcpy(&guid, &((Direct3DDeviceInfo&) *it2).m_guid, sizeof(GUID4)); + sprintf(p_buffer, "%d 0x%x 0x%x 0x%x 0x%x", i, guid.m_data1, guid.m_data2, guid.m_data3, guid.m_data4); + return 0; + } + + j++; + } + } + + return -1; +} + +// FUNCTION: CONFIG 0x00402860 +// FUNCTION: LEGO1 0x1009d0d0 +// FUNCTION: BETA10 0x1011cdb4 +int LegoDeviceEnumerate::FUN_1009d0d0() +{ + if (!IsInitialized()) { + return -1; + } + + if (m_list.size() == 0) { + return -1; + } + + int i = 0; + int j = 0; + int k = -1; + int cpu_mmx = SupportsMMX(); + + for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { + + MxDriver& driver = *it; + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { + if ((*it2).m_HWDesc.dcmColorModel) { + return j; + } + else { + if (cpu_mmx && (*it2).m_HELDesc.dcmColorModel == D3DCOLOR_RGB && i == 0) { + k = j; + } + else if ((*it2).m_HELDesc.dcmColorModel == D3DCOLOR_MONO && i == 0 && k < 0) { + k = j; + } + } + + j++; + } + } + + return k; +} + +// FUNCTION: CONFIG 0x00402930 +// FUNCTION: LEGO1 0x1009d1a0 +// FUNCTION: BETA10 0x1011cf54 +int LegoDeviceEnumerate::SupportsMMX() +{ + if (!SupportsCPUID()) { + return 0; + } + int supports_mmx; +#ifdef _MSC_VER + __asm { + mov eax, 0x0 ; EAX=0: Highest Function Parameter and Manufacturer ID +#if _MSC_VER > 1100 + cpuid ; Run CPUID +#else + __emit 0x0f + __emit 0xa2 +#endif + mov eax, 0x1 ; EAX=1: Processor Info and Feature Bits (unused) +#if _MSC_VER > 1100 + cpuid ; Run CPUID +#else + __emit 0x0f + __emit 0xa2 +#endif + xor eax, eax ; Zero EAX register + bt edx, 0x17 ; Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF) + adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF + mov supports_mmx, eax ; Save eax into C variable + } +#else + __asm__("movl $0x0, %%eax\n\t" // EAX=0: Highest Function Parameter and Manufacturer ID + "cpuid\n\t" // Run CPUID\n" + "mov $0x1, %%eax\n\t" // EAX=1: Processor Info and Feature Bits (unused) + "cpuid\n\t" // Run CPUID + "xorl %%eax, %%eax\n\t" // Zero EAX register + "btl $0x15, %%edx\n\t" // Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF) + "adc %%eax, %%eax" // Add with carry: EAX = EAX + EAX + CF = CF + : "=a"(supports_mmx) // supports_mmx == EAX + ); +#endif + return supports_mmx; +} + +// FUNCTION: CONFIG 0x00402970 +// FUNCTION: LEGO1 0x1009d1e0 +// FUNCTION: BETA10 0x1011cf97 +int LegoDeviceEnumerate::SupportsCPUID() +{ + int has_cpuid; +#ifdef _MSC_VER +#if defined(_M_IX86) + __asm { + xor eax, eax ; Zero EAX register + pushfd ; Push EFLAGS register value on the stack + or dword ptr[esp], 0x200000 ; Set bit 0x200000: Able to use CPUID instruction (Pentium+) + popfd ; Write the updated value into the EFLAGS register + pushfd ; Push EFLAGS register value on the stack (again) + btr dword ptr[esp], 0x15 ; Test bit 0x15 (21) and reset (set CF) + adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF + popfd ; Push EFLAGS register value on the stack (again, and makes sure the stack remains the same) + mov has_cpuid, eax ; Save eax into C variable + } +#elif defined(_M_X64) + has_cpuid = 1; +#else + has_cpuid = 0; +#endif +#else +#if defined(__i386__) + __asm__("xorl %%eax, %%eax\n\t" // Zero EAX register + "pushfl\n\t" // Push EFLAGS register value on the stack + "orl $0x200000, (%%esp)\n\t" // Set bit 0x200000: Able to use CPUID instruction (Pentium+) + "popfl\n\t" // Write the updated value into the EFLAGS register + "pushfl\n\t" // Push EFLAGS register value on the stack (again) + "btrl $0x15, (%%esp)\n\t" // Test bit 0x15 (21) and reset (set CF) + "adc %%eax, %%eax\n\t" // Add with carry: EAX = EAX + EAX + CF = CF + "popfl" // Push EFLAGS register value on the stack (again, and makes sure the stack remains the same) + : "=a"(has_cpuid) // has_cpuid == EAX + ); +#elif defined(__x86_64__) || defined(__amd64__) + has_cpuid = 1; +#else + has_cpuid = 0; +#endif +#endif + return has_cpuid; +} + +// FUNCTION: CONFIG 0x004029a0 +// FUNCTION: LEGO1 0x1009d210 +// FUNCTION: BETA10 0x1011cfc4 +int LegoDeviceEnumerate::FUN_1009d210() +{ + if (!IsInitialized()) { + return -1; + } + + for (list::iterator it = m_list.begin(); it != m_list.end();) { + if (!DriverSupportsRequiredDisplayMode(*it)) { + m_list.erase(it++); + continue; + } + + MxDriver& driver = *it; + + for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end();) { + if (!FUN_1009d3d0(*it2)) { + driver.m_devices.erase(it2++); + } + else { + it2++; + } + } + + if (!driver.m_devices.size()) { + m_list.erase(it++); + } + else { + it++; + } + } + + if (!m_list.size()) { + return -1; + } + + return 0; +} + +// FUNCTION: CONFIG 0x00402b00 +// FUNCTION: LEGO1 0x1009d370 +// FUNCTION: BETA10 0x1011d176 +unsigned char LegoDeviceEnumerate::DriverSupportsRequiredDisplayMode(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: CONFIG 0x00402b60 +// FUNCTION: LEGO1 0x1009d3d0 +// FUNCTION: BETA10 0x1011d235 +unsigned char LegoDeviceEnumerate::FUN_1009d3d0(Direct3DDeviceInfo& p_device) +{ + if (m_list.size() <= 0) { + return FALSE; + } + + if (p_device.m_HWDesc.dcmColorModel) { + if (p_device.m_HWDesc.dwDeviceZBufferBitDepth & DDBD_16 && + p_device.m_HWDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) { + return TRUE; + } + else { + return FALSE; + } + } + + MxDriver& front = m_list.front(); + for (list::iterator it = front.m_devices.begin(); it != front.m_devices.end(); it++) { + if ((&*it) == &p_device) { + return TRUE; + } + } + + return FALSE; +} diff --git a/LEGO1/mxdirectx/legodxinfo.h b/LEGO1/mxdirectx/legodxinfo.h new file mode 100644 index 00000000..2888c02c --- /dev/null +++ b/LEGO1/mxdirectx/legodxinfo.h @@ -0,0 +1,32 @@ +#ifndef LEGODXINFO_H +#define LEGODXINFO_H + +#include "mxdirectxinfo.h" + +// VTABLE: CONFIG 0x4060e4 +// VTABLE: LEGO1 0x100d9cc8 +// VTABLE: BETA10 0x101befb4 +// SIZE 0x14 +class LegoDeviceEnumerate : public MxDeviceEnumerate { +public: + int ParseDeviceName(const char* p_deviceId); + int ProcessDeviceBytes(int p_deviceNum, GUID& p_guid); + int GetDevice(int p_deviceNum, MxDriver*& p_driver, Direct3DDeviceInfo*& p_device); + int FormatDeviceName(char* p_buffer, const MxDriver* p_ddInfo, const Direct3DDeviceInfo* p_d3dInfo) const; + int BETA_1011cc65(int p_idx, char* p_buffer); + int FUN_1009d0d0(); + static int SupportsMMX(); + static int SupportsCPUID(); + int FUN_1009d210(); + unsigned char DriverSupportsRequiredDisplayMode(MxDriver& p_driver); + unsigned char FUN_1009d3d0(Direct3DDeviceInfo& p_device); + + // SYNTHETIC: BETA10 0x100d8d10 + // LegoDeviceEnumerate::LegoDeviceEnumerate + + // SYNTHETIC: LEGO1 0x1007b590 + // SYNTHETIC: BETA10 0x100d8da0 + // LegoDeviceEnumerate::~LegoDeviceEnumerate +}; + +#endif // LEGODXINFO_H diff --git a/LEGO1/mxdirectx/mxdirectxinfo.cpp b/LEGO1/mxdirectx/mxdirectxinfo.cpp index dded6e04..4d2950e3 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.cpp +++ b/LEGO1/mxdirectx/mxdirectxinfo.cpp @@ -570,373 +570,6 @@ const char* MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) } } -// FUNCTION: CONFIG 0x00402560 -// FUNCTION: LEGO1 0x1009ce60 -// FUNCTION: BETA10 0x1011c7e0 -int MxDeviceEnumerate::ParseDeviceName(const char* p_deviceId) -{ - if (!IsInitialized()) { - return -1; - } - - int unknown = -1; - int num = -1; - int hex[4]; - - if (sscanf(p_deviceId, "%d 0x%x 0x%x 0x%x 0x%x", &num, &hex[0], &hex[1], &hex[2], &hex[3]) != 5) { - return -1; - } - - if (num < 0) { - return -1; - } - - GUID guid; - memcpy(&guid, hex, sizeof(guid)); - - int result = ProcessDeviceBytes(num, guid); - - if (result < 0) { - result = ProcessDeviceBytes(-1, guid); - } - - return result; -} - -// FUNCTION: CONFIG 0x00402620 -// FUNCTION: LEGO1 0x1009cf20 -// FUNCTION: BETA10 0x1011c8b3 -int MxDeviceEnumerate::ProcessDeviceBytes(int p_deviceNum, GUID& p_guid) -{ - if (!IsInitialized()) { - return -1; - } - - int i = 0; - int j = 0; - - static_assert(sizeof(GUID4) == sizeof(GUID), "Equal size"); - - GUID4 deviceGuid; - memcpy(&deviceGuid, &p_guid, sizeof(GUID4)); - - for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { - if (p_deviceNum >= 0 && p_deviceNum < i) { - return -1; - } - - GUID4 compareGuid; - MxDriver& driver = *it; - for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { - Direct3DDeviceInfo& md3d = *it2; - assert(md3d.m_guid); - - memcpy(&compareGuid, md3d.m_guid, sizeof(GUID4)); - - if (GUID4::Compare(compareGuid, deviceGuid) && i == p_deviceNum) { - return j; - } - - j++; - } - } - - return -1; -} - -// FUNCTION: CONFIG 0x00402730 -// FUNCTION: LEGO1 0x1009d030 -// FUNCTION: BETA10 0x1011ca54 -int MxDeviceEnumerate::GetDevice(int p_deviceNum, MxDriver*& p_driver, Direct3DDeviceInfo*& p_device) -{ - if (p_deviceNum < 0 || !IsInitialized()) { - return -1; - } - - int 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 0; - } - i++; - } - } - - return -1; -} - -// FUNCTION: CONFIG 0x004027d0 -// FUNCTION: BETA10 0x1011cb70 -int MxDeviceEnumerate::FormatDeviceName(char* p_buffer, const MxDriver* p_ddInfo, const Direct3DDeviceInfo* p_d3dInfo) - const -{ - int number = 0; - assert(p_ddInfo && p_d3dInfo); - - for (list::const_iterator it = m_list.begin(); it != m_list.end(); it++, number++) { - if (&(*it) == p_ddInfo) { - GUID4 guid; - memcpy(&guid, p_d3dInfo->m_guid, sizeof(GUID4)); - - sprintf(p_buffer, "%d 0x%x 0x%x 0x%x 0x%x", number, guid.m_data1, guid.m_data2, guid.m_data3, guid.m_data4); - return 0; - } - } - - return -1; -} - -// FUNCTION: BETA10 0x1011cc65 -int MxDeviceEnumerate::BETA_1011cc65(int p_idx, char* p_buffer) -{ - if (p_idx < 0 || !IsInitialized()) { - return -1; - } - - int i = 0; - int j = 0; - - for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { - MxDriver& driver = *it; - for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { - - if (j == p_idx) { - GUID4 guid; - memcpy(&guid, &((Direct3DDeviceInfo&) *it2).m_guid, sizeof(GUID4)); - sprintf(p_buffer, "%d 0x%x 0x%x 0x%x 0x%x", i, guid.m_data1, guid.m_data2, guid.m_data3, guid.m_data4); - return 0; - } - - j++; - } - } - - return -1; -} - -// FUNCTION: CONFIG 0x00402860 -// FUNCTION: LEGO1 0x1009d0d0 -// FUNCTION: BETA10 0x1011cdb4 -int MxDeviceEnumerate::FUN_1009d0d0() -{ - if (!IsInitialized()) { - return -1; - } - - if (m_list.size() == 0) { - return -1; - } - - int i = 0; - int j = 0; - int k = -1; - int cpu_mmx = SupportsMMX(); - - for (list::iterator it = m_list.begin(); it != m_list.end(); it++, i++) { - - MxDriver& driver = *it; - for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) { - if ((*it2).m_HWDesc.dcmColorModel) { - return j; - } - else { - if (cpu_mmx && (*it2).m_HELDesc.dcmColorModel == D3DCOLOR_RGB && i == 0) { - k = j; - } - else if ((*it2).m_HELDesc.dcmColorModel == D3DCOLOR_MONO && i == 0 && k < 0) { - k = j; - } - } - - j++; - } - } - - return k; -} - -// FUNCTION: CONFIG 0x00402930 -// FUNCTION: LEGO1 0x1009d1a0 -// FUNCTION: BETA10 0x1011cf54 -int MxDeviceEnumerate::SupportsMMX() -{ - if (!SupportsCPUID()) { - return 0; - } - int supports_mmx; -#ifdef _MSC_VER - __asm { - mov eax, 0x0 ; EAX=0: Highest Function Parameter and Manufacturer ID -#if _MSC_VER > 1100 - cpuid ; Run CPUID -#else - __emit 0x0f - __emit 0xa2 -#endif - mov eax, 0x1 ; EAX=1: Processor Info and Feature Bits (unused) -#if _MSC_VER > 1100 - cpuid ; Run CPUID -#else - __emit 0x0f - __emit 0xa2 -#endif - xor eax, eax ; Zero EAX register - bt edx, 0x17 ; Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF) - adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF - mov supports_mmx, eax ; Save eax into C variable - } -#else - __asm__("movl $0x0, %%eax\n\t" // EAX=0: Highest Function Parameter and Manufacturer ID - "cpuid\n\t" // Run CPUID\n" - "mov $0x1, %%eax\n\t" // EAX=1: Processor Info and Feature Bits (unused) - "cpuid\n\t" // Run CPUID - "xorl %%eax, %%eax\n\t" // Zero EAX register - "btl $0x15, %%edx\n\t" // Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF) - "adc %%eax, %%eax" // Add with carry: EAX = EAX + EAX + CF = CF - : "=a"(supports_mmx) // supports_mmx == EAX - ); -#endif - return supports_mmx; -} - -// FUNCTION: CONFIG 0x00402970 -// FUNCTION: LEGO1 0x1009d1e0 -// FUNCTION: BETA10 0x1011cf97 -int MxDeviceEnumerate::SupportsCPUID() -{ - int has_cpuid; -#ifdef _MSC_VER -#if defined(_M_IX86) - __asm { - xor eax, eax ; Zero EAX register - pushfd ; Push EFLAGS register value on the stack - or dword ptr[esp], 0x200000 ; Set bit 0x200000: Able to use CPUID instruction (Pentium+) - popfd ; Write the updated value into the EFLAGS register - pushfd ; Push EFLAGS register value on the stack (again) - btr dword ptr[esp], 0x15 ; Test bit 0x15 (21) and reset (set CF) - adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF - popfd ; Push EFLAGS register value on the stack (again, and makes sure the stack remains the same) - mov has_cpuid, eax ; Save eax into C variable - } -#elif defined(_M_X64) - has_cpuid = 1; -#else - has_cpuid = 0; -#endif -#else -#if defined(__i386__) - __asm__("xorl %%eax, %%eax\n\t" // Zero EAX register - "pushfl\n\t" // Push EFLAGS register value on the stack - "orl $0x200000, (%%esp)\n\t" // Set bit 0x200000: Able to use CPUID instruction (Pentium+) - "popfl\n\t" // Write the updated value into the EFLAGS register - "pushfl\n\t" // Push EFLAGS register value on the stack (again) - "btrl $0x15, (%%esp)\n\t" // Test bit 0x15 (21) and reset (set CF) - "adc %%eax, %%eax\n\t" // Add with carry: EAX = EAX + EAX + CF = CF - "popfl" // Push EFLAGS register value on the stack (again, and makes sure the stack remains the same) - : "=a"(has_cpuid) // has_cpuid == EAX - ); -#elif defined(__x86_64__) || defined(__amd64__) - has_cpuid = 1; -#else - has_cpuid = 0; -#endif -#endif - return has_cpuid; -} - -// FUNCTION: CONFIG 0x004029a0 -// FUNCTION: LEGO1 0x1009d210 -// FUNCTION: BETA10 0x1011cfc4 -int MxDeviceEnumerate::FUN_1009d210() -{ - if (!IsInitialized()) { - return -1; - } - - for (list::iterator it = m_list.begin(); it != m_list.end();) { - if (!DriverSupportsRequiredDisplayMode(*it)) { - m_list.erase(it++); - continue; - } - - MxDriver& driver = *it; - - for (list::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end();) { - if (!FUN_1009d3d0(*it2)) { - driver.m_devices.erase(it2++); - } - else { - it2++; - } - } - - if (!driver.m_devices.size()) { - m_list.erase(it++); - } - else { - it++; - } - } - - if (!m_list.size()) { - return -1; - } - - return 0; -} - -// FUNCTION: CONFIG 0x00402b00 -// FUNCTION: LEGO1 0x1009d370 -// FUNCTION: BETA10 0x1011d176 -unsigned char MxDeviceEnumerate::DriverSupportsRequiredDisplayMode(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: CONFIG 0x00402b60 -// FUNCTION: LEGO1 0x1009d3d0 -// FUNCTION: BETA10 0x1011d235 -unsigned char MxDeviceEnumerate::FUN_1009d3d0(Direct3DDeviceInfo& p_device) -{ - if (m_list.size() <= 0) { - return FALSE; - } - - if (p_device.m_HWDesc.dcmColorModel) { - if (p_device.m_HWDesc.dwDeviceZBufferBitDepth & DDBD_16 && - p_device.m_HWDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) { - return TRUE; - } - else { - return FALSE; - } - } - - MxDriver& front = m_list.front(); - for (list::iterator it = front.m_devices.begin(); it != front.m_devices.end(); it++) { - if ((&*it) == &p_device) { - return TRUE; - } - } - - return FALSE; -} - // FUNCTION: LEGO1 0x1009efb0 // FUNCTION: BETA10 0x10122ee2 DeviceModesInfo::DeviceModesInfo() diff --git a/LEGO1/mxdirectx/mxdirectxinfo.h b/LEGO1/mxdirectx/mxdirectxinfo.h index e585cd1e..0371b276 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.h +++ b/LEGO1/mxdirectx/mxdirectxinfo.h @@ -203,17 +203,6 @@ class MxDeviceEnumerate { LPD3DDEVICEDESC p_HELDesc ); const char* EnumerateErrorToString(HRESULT p_error); - int ParseDeviceName(const char* p_deviceId); - int ProcessDeviceBytes(int p_deviceNum, GUID& p_guid); - int GetDevice(int p_deviceNum, MxDriver*& p_driver, Direct3DDeviceInfo*& p_device); - int FormatDeviceName(char* p_buffer, const MxDriver* p_ddInfo, const Direct3DDeviceInfo* p_d3dInfo) const; - int BETA_1011cc65(int p_idx, char* p_buffer); - - int FUN_1009d0d0(); - int FUN_1009d210(); - unsigned char DriverSupportsRequiredDisplayMode(MxDriver& p_driver); - unsigned char FUN_1009d3d0(Direct3DDeviceInfo& p_device); - static void BuildErrorString(const char*, ...); static BOOL CALLBACK DirectDrawEnumerateCallback(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName, LPVOID p_context); @@ -226,8 +215,6 @@ class MxDeviceEnumerate { LPD3DDEVICEDESC p_HELDesc, LPVOID p_context ); - static int SupportsMMX(); - static int SupportsCPUID(); friend class MxDirect3D; @@ -251,24 +238,11 @@ class MxDeviceEnumerate { // FUNCTION: BETA10 0x1011d320 unsigned char IsInitialized() const { return m_initialized; } -private: +protected: list m_list; // 0x04 unsigned char m_initialized; // 0x10 }; -// VTABLE: CONFIG 0x4060e4 -// VTABLE: LEGO1 0x100d9cc8 -// VTABLE: BETA10 0x101befb4 -// SIZE 0x14 -class LegoDeviceEnumerate : public MxDeviceEnumerate {}; - -// SYNTHETIC: BETA10 0x100d8d10 -// LegoDeviceEnumerate::LegoDeviceEnumerate - -// SYNTHETIC: LEGO1 0x1007b590 -// SYNTHETIC: BETA10 0x100d8da0 -// LegoDeviceEnumerate::~LegoDeviceEnumerate - // TEMPLATE: BETA10 0x1011c1b0 // list >::iterator::operator*