Isle
Loading...
Searching...
No Matches
legodxinfo.cpp
Go to the documentation of this file.
1#include "legodxinfo.h"
2
3#include <assert.h>
4#include <stdio.h> // for vsprintf
5
6// File name validated by BETA10 0x1011cba3; directory unknown
7
8// FUNCTION: CONFIG 0x00402560
9// FUNCTION: LEGO1 0x1009ce60
10// FUNCTION: BETA10 0x1011c7e0
11int LegoDeviceEnumerate::ParseDeviceName(const char* p_deviceId)
12{
13 if (!IsInitialized()) {
14 return -1;
15 }
16
17 int unknown = -1;
18 int num = -1;
19 int hex[4];
20
21 if (sscanf(p_deviceId, "%d 0x%x 0x%x 0x%x 0x%x", &num, &hex[0], &hex[1], &hex[2], &hex[3]) != 5) {
22 return -1;
23 }
24
25 if (num < 0) {
26 return -1;
27 }
28
29 GUID guid;
30 memcpy(&guid, hex, sizeof(guid));
31
32 int result = ProcessDeviceBytes(num, guid);
33
34 if (result < 0) {
35 result = ProcessDeviceBytes(-1, guid);
36 }
37
38 return result;
39}
40
41// FUNCTION: CONFIG 0x00402620
42// FUNCTION: LEGO1 0x1009cf20
43// FUNCTION: BETA10 0x1011c8b3
44int LegoDeviceEnumerate::ProcessDeviceBytes(int p_deviceNum, GUID& p_guid)
45{
46 if (!IsInitialized()) {
47 return -1;
48 }
49
50 int i = 0;
51 int j = 0;
52
53 static_assert(sizeof(GUID4) == sizeof(GUID), "Equal size");
54
55 GUID4 deviceGuid;
56 memcpy(&deviceGuid, &p_guid, sizeof(GUID4));
57
58 for (list<MxDriver>::iterator it = m_list.begin(); it != m_list.end(); it++, i++) {
59 if (p_deviceNum >= 0 && p_deviceNum < i) {
60 return -1;
61 }
62
63 GUID4 compareGuid;
64 MxDriver& driver = *it;
65 for (list<Direct3DDeviceInfo>::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) {
66 Direct3DDeviceInfo& md3d = *it2;
67 assert(md3d.m_guid);
68
69 memcpy(&compareGuid, md3d.m_guid, sizeof(GUID4));
70
71 if (GUID4::Compare(compareGuid, deviceGuid) && i == p_deviceNum) {
72 return j;
73 }
74
75 j++;
76 }
77 }
78
79 return -1;
80}
81
82// FUNCTION: CONFIG 0x00402730
83// FUNCTION: LEGO1 0x1009d030
84// FUNCTION: BETA10 0x1011ca54
85int LegoDeviceEnumerate::GetDevice(int p_deviceNum, MxDriver*& p_driver, Direct3DDeviceInfo*& p_device)
86{
87 if (p_deviceNum < 0 || !IsInitialized()) {
88 return -1;
89 }
90
91 int i = 0;
92
93 for (list<MxDriver>::iterator it = m_list.begin(); it != m_list.end(); it++) {
94 p_driver = &*it;
95
96 for (list<Direct3DDeviceInfo>::iterator it2 = p_driver->m_devices.begin(); it2 != p_driver->m_devices.end();
97 it2++) {
98 if (i == p_deviceNum) {
99 p_device = &*it2;
100 return 0;
101 }
102 i++;
103 }
104 }
105
106 return -1;
107}
108
109// FUNCTION: CONFIG 0x004027d0
110// FUNCTION: BETA10 0x1011cb70
111int LegoDeviceEnumerate::FormatDeviceName(char* p_buffer, const MxDriver* p_ddInfo, const Direct3DDeviceInfo* p_d3dInfo)
112 const
113{
114 int number = 0;
115 assert(p_ddInfo && p_d3dInfo);
116
117 for (list<MxDriver>::const_iterator it = m_list.begin(); it != m_list.end(); it++, number++) {
118 if (&(*it) == p_ddInfo) {
119 GUID4 guid;
120 memcpy(&guid, p_d3dInfo->m_guid, sizeof(GUID4));
121
122 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);
123 return 0;
124 }
125 }
126
127 return -1;
128}
129
130// FUNCTION: BETA10 0x1011cc65
131int LegoDeviceEnumerate::BETA_1011cc65(int p_idx, char* p_buffer)
132{
133 if (p_idx < 0 || !IsInitialized()) {
134 return -1;
135 }
136
137 int i = 0;
138 int j = 0;
139
140 for (list<MxDriver>::iterator it = m_list.begin(); it != m_list.end(); it++, i++) {
141 MxDriver& driver = *it;
142 for (list<Direct3DDeviceInfo>::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) {
143
144 if (j == p_idx) {
145 GUID4 guid;
146 memcpy(&guid, &((Direct3DDeviceInfo&) *it2).m_guid, sizeof(GUID4));
147 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);
148 return 0;
149 }
150
151 j++;
152 }
153 }
154
155 return -1;
156}
157
158// FUNCTION: CONFIG 0x00402860
159// FUNCTION: LEGO1 0x1009d0d0
160// FUNCTION: BETA10 0x1011cdb4
162{
163 if (!IsInitialized()) {
164 return -1;
165 }
166
167 if (m_list.size() == 0) {
168 return -1;
169 }
170
171 int i = 0;
172 int j = 0;
173 int k = -1;
174 int cpu_mmx = SupportsMMX();
175
176 for (list<MxDriver>::iterator it = m_list.begin(); it != m_list.end(); it++, i++) {
177
178 MxDriver& driver = *it;
179 for (list<Direct3DDeviceInfo>::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end(); it2++) {
180 if ((*it2).m_HWDesc.dcmColorModel) {
181 return j;
182 }
183 else {
184 if (cpu_mmx && (*it2).m_HELDesc.dcmColorModel == D3DCOLOR_RGB && i == 0) {
185 k = j;
186 }
187 else if ((*it2).m_HELDesc.dcmColorModel == D3DCOLOR_MONO && i == 0 && k < 0) {
188 k = j;
189 }
190 }
191
192 j++;
193 }
194 }
195
196 return k;
197}
198
199// FUNCTION: CONFIG 0x00402930
200// FUNCTION: LEGO1 0x1009d1a0
201// FUNCTION: BETA10 0x1011cf54
203{
204 int supports_mmx = SupportsCPUID();
205
206 if (supports_mmx) {
207#ifdef _MSC_VER
208 __asm {
209 push ebx
210 mov eax, 0x0 ; EAX=0: Highest Function Parameter and Manufacturer ID
211#if _MSC_VER > 1100
212 cpuid ; Run CPUID
213#else
214 __emit 0x0f
215 __emit 0xa2
216#endif
217 mov eax, 0x1 ; EAX=1: Processor Info and Feature Bits (unused)
218#if _MSC_VER > 1100
219 cpuid ; Run CPUID
220#else
221 __emit 0x0f
222 __emit 0xa2
223#endif
224 xor eax, eax ; Zero EAX register
225 bt edx, 0x17 ; Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF)
226 adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF
227 pop ebx
228 mov supports_mmx, eax ; Save eax into C variable
229 }
230#else
231 __asm__("movl $0x0, %%eax\n\t" // EAX=0: Highest Function Parameter and Manufacturer ID
232 "cpuid\n\t" // Run CPUID\n"
233 "mov $0x1, %%eax\n\t" // EAX=1: Processor Info and Feature Bits (unused)
234 "cpuid\n\t" // Run CPUID
235 "xorl %%eax, %%eax\n\t" // Zero EAX register
236 "btl $0x15, %%edx\n\t" // Test bit 0x17 (23): MMX instructions (64-bit SIMD) (Store in CF)
237 "adc %%eax, %%eax" // Add with carry: EAX = EAX + EAX + CF = CF
238 : "=a"(supports_mmx) // supports_mmx == EAX
239 );
240#endif
241 }
242
243 return supports_mmx;
244}
245
246// FUNCTION: CONFIG 0x00402970
247// FUNCTION: LEGO1 0x1009d1e0
248// FUNCTION: BETA10 0x1011cf97
250{
251 int has_cpuid;
252#ifdef _MSC_VER
253#if defined(_M_IX86)
254 __asm {
255 xor eax, eax ; Zero EAX register
256 pushfd ; Push EFLAGS register value on the stack
257 or dword ptr[esp], 0x200000 ; Set bit 0x200000: Able to use CPUID instruction (Pentium+)
258 popfd ; Write the updated value into the EFLAGS register
259 pushfd ; Push EFLAGS register value on the stack (again)
260 btr dword ptr[esp], 0x15 ; Test bit 0x15 (21) and reset (set CF)
261 adc eax, eax ; Add with carry: EAX = EAX + EAX + CF = CF
262 popfd ; Push EFLAGS register value on the stack (again, and makes sure the stack remains the same)
263 mov has_cpuid, eax ; Save eax into C variable
264 }
265#elif defined(_M_X64)
266 has_cpuid = 1;
267#else
268 has_cpuid = 0;
269#endif
270#else
271#if defined(__i386__)
272 __asm__("xorl %%eax, %%eax\n\t" // Zero EAX register
273 "pushfl\n\t" // Push EFLAGS register value on the stack
274 "orl $0x200000, (%%esp)\n\t" // Set bit 0x200000: Able to use CPUID instruction (Pentium+)
275 "popfl\n\t" // Write the updated value into the EFLAGS register
276 "pushfl\n\t" // Push EFLAGS register value on the stack (again)
277 "btrl $0x15, (%%esp)\n\t" // Test bit 0x15 (21) and reset (set CF)
278 "adc %%eax, %%eax\n\t" // Add with carry: EAX = EAX + EAX + CF = CF
279 "popfl" // Push EFLAGS register value on the stack (again, and makes sure the stack remains the same)
280 : "=a"(has_cpuid) // has_cpuid == EAX
281 );
282#elif defined(__x86_64__) || defined(__amd64__)
283 has_cpuid = 1;
284#else
285 has_cpuid = 0;
286#endif
287#endif
288 return has_cpuid;
289}
290
291// FUNCTION: CONFIG 0x004029a0
292// FUNCTION: LEGO1 0x1009d210
293// FUNCTION: BETA10 0x1011cfc4
295{
296 if (!IsInitialized()) {
297 return -1;
298 }
299
300 for (list<MxDriver>::iterator it = m_list.begin(); it != m_list.end();) {
302 m_list.erase(it++);
303 continue;
304 }
305
306 MxDriver& driver = *it;
307
308 for (list<Direct3DDeviceInfo>::iterator it2 = driver.m_devices.begin(); it2 != driver.m_devices.end();) {
309 if (!FUN_1009d3d0(*it2)) {
310 driver.m_devices.erase(it2++);
311 }
312 else {
313 it2++;
314 }
315 }
316
317 if (!driver.m_devices.size()) {
318 m_list.erase(it++);
319 }
320 else {
321 it++;
322 }
323 }
324
325 if (!m_list.size()) {
326 return -1;
327 }
328
329 return 0;
330}
331
332// FUNCTION: CONFIG 0x00402b00
333// FUNCTION: LEGO1 0x1009d370
334// FUNCTION: BETA10 0x1011d176
336{
337 for (list<MxDisplayMode>::iterator it = p_driver.m_displayModes.begin(); it != p_driver.m_displayModes.end();
338 it++) {
339 if ((*it).m_width == 640 && (*it).m_height == 480) {
340 if ((*it).m_bitsPerPixel == 8 || (*it).m_bitsPerPixel == 16) {
341 return TRUE;
342 }
343 }
344 }
345
346 return FALSE;
347}
348
349// FUNCTION: CONFIG 0x00402b60
350// FUNCTION: LEGO1 0x1009d3d0
351// FUNCTION: BETA10 0x1011d235
353{
354 if (m_list.size() <= 0) {
355 return FALSE;
356 }
357
358 if (p_device.m_HWDesc.dcmColorModel) {
361 return TRUE;
362 }
363 else {
364 return FALSE;
365 }
366 }
367
368 MxDriver& front = m_list.front();
369 for (list<Direct3DDeviceInfo>::iterator it = front.m_devices.begin(); it != front.m_devices.end(); it++) {
370 if ((&*it) == &p_device) {
371 return TRUE;
372 }
373 }
374
375 return FALSE;
376}
static int SupportsCPUID()
[AI] Checks if the CPU supports CPUID instruction.
Definition: legodxinfo.cpp:249
unsigned char DriverSupportsRequiredDisplayMode(MxDriver &p_driver)
[AI] Checks if a driver supports a 640x480 display mode in 8bpp or 16bpp (needed by LEGO Island).
Definition: legodxinfo.cpp:335
int GetDevice(int p_deviceNum, MxDriver *&p_driver, Direct3DDeviceInfo *&p_device)
[AI] Outputs pointers to the MxDriver and Direct3DDeviceInfo for the given device index.
Definition: legodxinfo.cpp:85
static int SupportsMMX()
[AI] Checks if the CPU supports MMX instructions.
Definition: legodxinfo.cpp:202
unsigned char FUN_1009d3d0(Direct3DDeviceInfo &p_device)
[AI] Checks if a device supports required rendering features (Z-buffer, perspective,...
Definition: legodxinfo.cpp:352
int FUN_1009d0d0()
[AI] Finds and returns the preferred device index that supports required features.
Definition: legodxinfo.cpp:161
int ParseDeviceName(const char *p_deviceId)
[AI] Parses a device string identifier and locates the matching device entry.
Definition: legodxinfo.cpp:11
int FormatDeviceName(char *p_buffer, const MxDriver *p_ddInfo, const Direct3DDeviceInfo *p_d3dInfo) const
[AI] Formats and serializes a device identification string for a given driver/device.
Definition: legodxinfo.cpp:111
int ProcessDeviceBytes(int p_deviceNum, GUID &p_guid)
[AI] Returns the index of the device matching the given GUID and driver number.
Definition: legodxinfo.cpp:44
int FUN_1009d210()
[AI] Prunes the enumeration to only include devices/drivers that support the required display mode an...
Definition: legodxinfo.cpp:294
int BETA_1011cc65(int p_idx, char *p_buffer)
[AI] Formats device identification string for the device at a specific global index (Beta10-specific)...
Definition: legodxinfo.cpp:131
unsigned char IsInitialized() const
[AI] Checks if the enumeration has already been performed.
list< MxDriver > m_list
[AI] List of all discovered DirectDraw drivers and their device/mode info.
[AI] Set wrapper utilizing a custom allocator and comparator.
Definition: mxstl.h:209
#define D3DPTEXTURECAPS_PERSPECTIVE
Definition: d3dcaps.h:152
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define D3DCOLOR_MONO
Definition: d3dtypes.h:682
#define D3DCOLOR_RGB
Definition: d3dtypes.h:683
#define DDBD_16
Definition: ddraw.h:2197
#define stack
[AI] Macro alias for Stack<C>, replacing std::stack.
Definition: mxstl.h:418
#define set
[AI] Macro alias for Set<K, Pr>, replacing std::set<K>.
Definition: mxstl.h:413
[AI] Encapsulates Direct3D device enumeration information and capability structures.
D3DDEVICEDESC m_HWDesc
[AI] Hardware Direct3D device capability description.
LPGUID m_guid
[AI] GUID uniquely identifying this 3D device. [AI]
[AI] Utility structure for GUID comparison.
[AI] Holds data about a DirectDraw driver including devices and supported display modes.
list< MxDisplayMode > m_displayModes
[AI] List of all display modes reported by the driver.
list< Direct3DDeviceInfo > m_devices
[AI] List of all Direct3D devices provided by this driver.
D3DPRIMCAPS dpcTriCaps
Definition: d3dcaps.h:200
DWORD dwDeviceZBufferBitDepth
Definition: d3dcaps.h:202
D3DCOLORMODEL dcmColorModel
Definition: d3dcaps.h:194
DWORD dwTextureCaps
Definition: d3dcaps.h:57