From 00a4861914f409b195623bf7c113882e2da68997 Mon Sep 17 00:00:00 2001 From: MS Date: Sat, 12 Jul 2025 12:39:16 -0400 Subject: [PATCH] Beta matching `CConfigApp` (#1620) * Beta matching CConfigApp * Docs --- CONFIG/config.cpp | 134 ++++++++++++++++++++++++++++++--------------- CONFIG/config.h | 6 ++ reccmp-project.yml | 5 ++ tools/README.md | 3 + 4 files changed, 105 insertions(+), 43 deletions(-) diff --git a/CONFIG/config.cpp b/CONFIG/config.cpp index 13a80e7f..54b16ee9 100644 --- a/CONFIG/config.cpp +++ b/CONFIG/config.cpp @@ -4,6 +4,7 @@ #include "MainDlg.h" #include "detectdx5.h" +#include #include // _chdir #include #include @@ -19,6 +20,7 @@ ON_COMMAND(ID_HELP, OnHelp) END_MESSAGE_MAP() // FUNCTION: CONFIG 0x00402c40 +// FUNCTION: CONFIGD 0x00406900 CConfigApp::CConfigApp() { } @@ -26,11 +28,13 @@ CConfigApp::CConfigApp() #define MiB (1024 * 1024) // FUNCTION: CONFIG 0x00402dc0 +// FUNCTION: CONFIGD 0x004069dc BOOL CConfigApp::InitInstance() { if (!IsLegoNotRunning()) { return FALSE; } + if (!DetectDirectX5()) { AfxMessageBox( "\"LEGO\xae Island\" is not detecting DirectX 5 or later. Please quit all other applications and try " @@ -38,20 +42,25 @@ BOOL CConfigApp::InitInstance() ); return FALSE; } + #ifdef _AFXDLL Enable3dControls(); #else Enable3dControlsStatic(); #endif + CConfigCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); if (_stricmp(afxCurrentAppName, "config") == 0) { m_run_config_dialog = TRUE; } + m_device_enumerator = new LegoDeviceEnumerate; if (m_device_enumerator->DoEnumerate()) { + assert("Could not build device list." == NULL); return FALSE; } + m_driver = NULL; m_device = NULL; m_full_screen = TRUE; @@ -76,11 +85,17 @@ BOOL CConfigApp::InitInstance() m_texture_quality = 1; } else { - m_model_quality = 2; m_3d_sound = TRUE; + m_model_quality = 2; m_texture_quality = 1; } - if (!m_run_config_dialog) { + + if (m_run_config_dialog) { + CMainDialog main_dialog(NULL); + m_pMainWnd = &main_dialog; + main_dialog.DoModal(); + } + else { ReadRegisterSettings(); ValidateSettings(); WriteRegisterSettings(); @@ -89,17 +104,17 @@ BOOL CConfigApp::InitInstance() m_driver = NULL; m_device = NULL; char password[256]; - ReadReg("password", password, sizeof(password)); + BOOL read = ReadReg("password", password, sizeof(password)); const char* exe = _stricmp("ogel", password) == 0 ? "isled.exe" : "isle.exe"; char diskpath[1024]; - if (ReadReg("diskpath", diskpath, sizeof(diskpath))) { + read = ReadReg("diskpath", diskpath, sizeof(diskpath)); + if (read) { _chdir(diskpath); } + _spawnl(_P_NOWAIT, exe, exe, "/diskstream", "/script", "\\lego\\scripts\\isle\\isle.si", NULL); - return FALSE; } - CMainDialog main_dialog(NULL); - main_dialog.DoModal(); + return FALSE; } @@ -117,35 +132,40 @@ BOOL CConfigApp::IsLegoNotRunning() } // FUNCTION: CONFIG 0x004031b0 +// FUNCTION: CONFIGD 0x00406dc3 BOOL CConfigApp::WriteReg(const char* p_key, const char* p_value) const { HKEY hKey; DWORD pos; + BOOL success = FALSE; + BOOL created = RegCreateKeyEx( + HKEY_LOCAL_MACHINE, + "SOFTWARE\\Mindscape\\LEGO Island", + 0, + "string", + 0, + KEY_READ | KEY_WRITE, + NULL, + &hKey, + &pos + ); - if (RegCreateKeyEx( - HKEY_LOCAL_MACHINE, - "SOFTWARE\\Mindscape\\LEGO Island", - 0, - "string", - 0, - KEY_READ | KEY_WRITE, - NULL, - &hKey, - &pos - ) == ERROR_SUCCESS) { - if (RegSetValueEx(hKey, p_key, 0, REG_SZ, (LPBYTE) p_value, strlen(p_value)) == ERROR_SUCCESS) { + if (created == ERROR_SUCCESS) { + if (RegSetValueEx(hKey, p_key, 0, REG_SZ, (LPBYTE) p_value, strlen(p_value) + 1) == ERROR_SUCCESS) { if (RegCloseKey(hKey) == ERROR_SUCCESS) { - return TRUE; + success = TRUE; } } else { RegCloseKey(hKey); } } - return FALSE; + + return success; } // FUNCTION: CONFIG 0x00403240 +// FUNCTION: CONFIGD 0x00406e6e BOOL CConfigApp::ReadReg(LPCSTR p_key, LPCSTR p_value, DWORD p_size) const { HKEY hKey; @@ -164,28 +184,30 @@ BOOL CConfigApp::ReadReg(LPCSTR p_key, LPCSTR p_value, DWORD p_size) const } // FUNCTION: CONFIG 0x004032b0 +// FUNCTION: CONFIGD 0x00406ef6 BOOL CConfigApp::ReadRegBool(LPCSTR p_key, BOOL* p_bool) const { char buffer[256]; + BOOL read = TRUE; - BOOL read = ReadReg(p_key, buffer, sizeof(buffer)); + read = ReadReg(p_key, buffer, sizeof(buffer)); if (read) { if (strcmp("YES", buffer) == 0) { *p_bool = TRUE; - return read; } - - if (strcmp("NO", buffer) == 0) { + else if (strcmp("NO", buffer) == 0) { *p_bool = FALSE; - return read; } - - read = FALSE; + else { + read = FALSE; + } } + return read; } // FUNCTION: CONFIG 0x00403380 +// FUNCTION: CONFIGD 0x00406fa1 BOOL CConfigApp::ReadRegInt(LPCSTR p_key, int* p_value) const { char buffer[256]; @@ -199,46 +221,63 @@ BOOL CConfigApp::ReadRegInt(LPCSTR p_key, int* p_value) const } // FUNCTION: CONFIG 0x004033d0 +// FUNCTION: CONFIGD 0x00407080 BOOL CConfigApp::IsDeviceInBasicRGBMode() const { /* * BUG: should be: * return !GetHardwareDeviceColorModel() && (m_device->m_HELDesc.dcmColorModel & D3DCOLOR_RGB); */ + assert(m_device); return !GetHardwareDeviceColorModel() && m_device->m_HELDesc.dcmColorModel == D3DCOLOR_RGB; } // FUNCTION: CONFIG 0x00403400 +// FUNCTION: CONFIGD 0x004070fa D3DCOLORMODEL CConfigApp::GetHardwareDeviceColorModel() const { + assert(m_device); return m_device->m_HWDesc.dcmColorModel; } // FUNCTION: CONFIG 0x00403410 +// FUNCTION: CONFIGD 0x0040714e BOOL CConfigApp::IsPrimaryDriver() const { + assert(m_driver && m_device_enumerator); return m_driver == &m_device_enumerator->GetDriverList().front(); } // FUNCTION: CONFIG 0x00403430 +// FUNCTION: CONFIGD 0x004071d2 BOOL CConfigApp::ReadRegisterSettings() { char buffer[256]; BOOL is_modified = FALSE; - int tmp = -1; - if (ReadReg("3D Device ID", buffer, sizeof(buffer))) { - tmp = m_device_enumerator->ParseDeviceName(buffer); - if (tmp >= 0) { - tmp = m_device_enumerator->GetDevice(tmp, m_driver, m_device); + BOOL read = ReadReg("3D Device ID", buffer, sizeof(buffer)); + int r = -1; + + if (read) { + r = m_device_enumerator->ParseDeviceName(buffer); + if (r >= 0) { + r = m_device_enumerator->GetDevice(r, m_driver, m_device); + if (r) { + r = -1; + } } } - if (tmp != 0) { - is_modified = TRUE; + + if (r < 0) { m_device_enumerator->FUN_1009d210(); - tmp = m_device_enumerator->GetBestDevice(); - m_device_enumerator->GetDevice(tmp, m_driver, m_device); + r = m_device_enumerator->GetBestDevice(); + is_modified = TRUE; + assert(r >= 0); + r = m_device_enumerator->GetDevice(r, m_driver, m_device); } + + assert(r == 0 && m_driver && m_device); + if (!ReadRegInt("Display Bit Depth", &m_display_bit_depth)) { is_modified = TRUE; } @@ -279,6 +318,7 @@ BOOL CConfigApp::ReadRegisterSettings() } // FUNCTION: CONFIG 0x00403630 +// FUNCTION: CONFIGD 0x00407547 BOOL CConfigApp::ValidateSettings() { BOOL is_modified = FALSE; @@ -301,11 +341,7 @@ BOOL CConfigApp::ValidateSettings() is_modified = TRUE; } } - if (!GetHardwareDeviceColorModel()) { - m_draw_cursor = FALSE; - is_modified = TRUE; - } - else { + if (GetHardwareDeviceColorModel()) { if (!m_3d_video_ram) { m_3d_video_ram = TRUE; is_modified = TRUE; @@ -315,6 +351,10 @@ BOOL CConfigApp::ValidateSettings() is_modified = TRUE; } } + else { + m_draw_cursor = FALSE; + is_modified = TRUE; + } if (m_flip_surfaces) { if (!m_3d_video_ram) { m_3d_video_ram = TRUE; @@ -341,8 +381,10 @@ BOOL CConfigApp::ValidateSettings() } // FUNCTION: CONFIG 0x004037a0 +// FUNCTION: CONFIGD 0x00407793 DWORD CConfigApp::GetConditionalDeviceRenderBitDepth() const { + assert(m_device); if (IsDeviceInBasicRGBMode()) { return 0; } @@ -353,8 +395,10 @@ DWORD CConfigApp::GetConditionalDeviceRenderBitDepth() const } // FUNCTION: CONFIG 0x004037e0 +// FUNCTION: CONFIGD 0x00407822 DWORD CConfigApp::GetDeviceRenderBitStatus() const { + assert(m_device); if (GetHardwareDeviceColorModel()) { return m_device->m_HWDesc.dwDeviceRenderBitDepth & DDBD_16; } @@ -364,6 +408,7 @@ DWORD CConfigApp::GetDeviceRenderBitStatus() const } // FUNCTION: CONFIG 0x00403810 +// FUNCTION: CONFIGD 0x004078ac BOOL CConfigApp::AdjustDisplayBitDepthBasedOnRenderStatus() { if (m_display_bit_depth == 8) { @@ -388,7 +433,8 @@ BOOL CConfigApp::AdjustDisplayBitDepthBasedOnRenderStatus() return TRUE; } -// FUNCTION: CONFIG 00403890 +// FUNCTION: CONFIG 0x00403890 +// FUNCTION: CONFIGD 0x00407966 void CConfigApp::WriteRegisterSettings() const { @@ -401,6 +447,7 @@ void CConfigApp::WriteRegisterSettings() const WriteReg(NAME, buffer); \ } while (0) + assert(m_device_enumerator && m_driver && m_device); m_device_enumerator->FormatDeviceName(buffer, m_driver, m_device); WriteReg("3D Device ID", buffer); WriteReg("3D Device Name", m_device->m_deviceName); @@ -422,6 +469,7 @@ void CConfigApp::WriteRegisterSettings() const } // FUNCTION: CONFIG 0x00403a90 +// FUNCTION: CONFIGD 0x00407c44 int CConfigApp::ExitInstance() { if (m_device_enumerator) { diff --git a/CONFIG/config.h b/CONFIG/config.h index c3282769..02366100 100644 --- a/CONFIG/config.h +++ b/CONFIG/config.h @@ -14,6 +14,7 @@ struct MxDriver; #define currentConfigApp ((CConfigApp*) afxCurrentWinApp) // VTABLE: CONFIG 0x00406040 +// VTABLE: CONFIGD 0x0040c0a0 // SIZE 0x108 class CConfigApp : public CWinApp { public: @@ -74,18 +75,23 @@ public: }; // SYNTHETIC: CONFIG 0x00402cd0 +// SYNTHETIC: CONFIGD 0x00408330 // CConfigApp::`scalar deleting destructor' // FUNCTION: CONFIG 0x402c20 +// FUNCTION: CONFIGD 0x4068d0 // CConfigApp::_GetBaseMessageMap // FUNCTION: CONFIG 0x402c30 +// FUNCTION: CONFIGD 0x4068e5 // CConfigApp::GetMessageMap // GLOBAL: CONFIG 0x406008 +// GLOBAL: CONFIGD 0x40c058 // CConfigApp::messageMap // GLOBAL: CONFIG 0x406010 +// GLOBAL: CONFIGD 0x40c060 // CConfigApp::_messageEntries #endif // !defined(AFX_CONFIG_H) diff --git a/reccmp-project.yml b/reccmp-project.yml index fd9a2ef1..c0a1c907 100644 --- a/reccmp-project.yml +++ b/reccmp-project.yml @@ -43,3 +43,8 @@ targets: source-root: LEGO1 hash: sha256: dc7e5ed8ec9d96851126a40c4d23755f1783a8df61def44c667dfaa992ac509e + CONFIGD: + filename: CONFIGD.EXE + source-root: . + hash: + sha256: 9d2b7de2e53eee99cce24a64777a08a7f919a0401a393d9494bce27ef2e24c39 diff --git a/tools/README.md b/tools/README.md index 0d75e48e..0d443780 100644 --- a/tools/README.md +++ b/tools/README.md @@ -22,6 +22,7 @@ These modules are the most important ones and refer to the English retail versio ## BETA v1.0 * `BETA10` -> `LEGO1D.DLL` +* `CONFIGD` -> `CONFIG.EXE` The Beta 1.0 version contains a debug build of the game. While it does not have debug symbols, it still has a number of benefits: * It is built with less or no optimisation, leading to better decompilations in Ghidra @@ -32,6 +33,8 @@ It is therefore advisable to search for the corresponding function in `BETA10` w Unfortunately, some code has been changed after this beta version was created. Therefore, we are not aiming for a perfect binary match of `BETA10`. In case of discrepancies, `LEGO1` (as defined above) is our "gold standard" for matching. +The beta version of the `CONFIG` application has provided some help with matching [MFC handler functions](https://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library) that are similar to the final version. + ## Pre-Alpha * `ALPHA` -> `LEGO1D.DLL`