diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index dec8b191..8e903cc1 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -4,31 +4,23 @@ on: [push, pull_request] jobs: decomplint-isle: - name: 'ISLE annotations' + name: '${{ matrix.who }} annotations' runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + who: + - CONFIG + - ISLE + - LEGO1 steps: - uses: actions/checkout@v4 - name: Install python libraries run: | - pip install -r tools/requirements.txt + python -m pip install -r tools/requirements.txt - name: Run decomplint.py run: | - python3 tools/decomplint/decomplint.py ISLE --module ISLE --warnfail - - decomplint-lego1: - name: 'LEGO1 annotations' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install python libraries - run: | - pip install -r tools/requirements.txt - - - name: Run decomplint.py - run: | - python3 tools/decomplint/decomplint.py LEGO1 --module LEGO1 --warnfail + tools/decomplint/decomplint.py ${{ matrix.who }} --module ${{ matrix.who }} --warnfail diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70b80c85..c7d7363f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,11 +71,11 @@ jobs: uses: jwlawson/actions-setup-cmake@v1.13 with: # Use minimum supported version - cmake-version: '3.13.x' + cmake-version: '3.15.x' - name: Patch MSVC 4.2 run: | - python tools/patch_c2.py msvc420/bin/C2.EXE + tools/patch_c2.py msvc420/bin/C2.EXE - name: Build shell: cmd @@ -89,6 +89,8 @@ jobs: with: name: Win32 path: | + build/CONFIG.EXE + build/CONFIG.PDB build/ISLE.EXE build/ISLE.PDB build/LEGO1.DLL @@ -117,6 +119,7 @@ jobs: - name: Download original island binares if: ${{ !steps.cache-original-binaries.outputs.cache-hit }} run: | + C:\msys64\usr\bin\wget.exe https://legoisland.org/download/CONFIG.EXE --directory-prefix=legobin C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE --directory-prefix=legobin C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL --directory-prefix=legobin @@ -136,6 +139,7 @@ jobs: - name: Summarize Accuracy shell: bash run: | + python3 tools/reccmp/reccmp.py -S CONFIGPROGRESS.SVG --svg-icon tools/reccmp/config.png -H CONFIGPROGRESS.HTML legobin/CONFIG.EXE build/CONFIG.EXE build/CONFIG.PDB . | tee CONFIGPROGRESS.TXT python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML legobin/ISLE.EXE build/ISLE.EXE build/ISLE.PDB . | tee ISLEPROGRESS.TXT python3 tools/reccmp/reccmp.py -S LEGO1PROGRESS.SVG -T 4252 --svg-icon tools/reccmp/lego1.png -H LEGO1PROGRESS.HTML legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB . | tee LEGO1PROGRESS.TXT @@ -143,20 +147,23 @@ jobs: shell: bash run: | # Compare with current master - curl -fLSs -o ISLEPROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/ISLEPROGRESS.TXT - curl -fLSs -o LEGO1PROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/LEGO1PROGRESS.TXT + curl -fLSs -o CONFIGPROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/CONFIGPROGRESS.TXT || echo "" >CONFIGPROGRESS-OLD.TXT + curl -fLSs -o ISLEPROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/ISLEPROGRESS.TXT || echo "" >ISLEPROGRESS-OLD.TXT + curl -fLSs -o LEGO1PROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/LEGO1PROGRESS.TXT || echo "" >LEGO1PROGRESS-OLD.TXT + diff -u0 CONFIGPROGRESS-OLD.TXT CONFIGPROGRESS.TXT || true diff -u0 ISLEPROGRESS-OLD.TXT ISLEPROGRESS.TXT || true diff -u0 LEGO1PROGRESS-OLD.TXT LEGO1PROGRESS.TXT || true - name: Test Exports shell: bash run: | - python3 tools/verexp/verexp.py legobin/LEGO1.DLL build/LEGO1.DLL + tools/verexp/verexp.py legobin/LEGO1.DLL build/LEGO1.DLL - name: Check Vtables shell: bash run: | + python3 tools/vtable/vtable.py legobin/CONFIG.EXE build/CONFIG.EXE build/CONFIG.PDB . python3 tools/vtable/vtable.py legobin/ISLE.EXE build/ISLE.EXE build/ISLE.PDB . python3 tools/vtable/vtable.py legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB . @@ -165,6 +172,7 @@ jobs: with: name: Accuracy Report path: | + CONFIGPROGRESS.* ISLEPROGRESS.* LEGO1PROGRESS.* @@ -193,10 +201,13 @@ jobs: UPLOAD_KEY: ${{ secrets.UPLOAD_KEY }} run: | ./upload.sh \ + build/CONFIG.EXE \ build/ISLE.EXE \ build/LEGO1.DLL \ + CONFIGPROGRESS.* \ ISLEPROGRESS.* \ LEGO1PROGRESS.* + curl -X POST -F key=$UPLOAD_KEY -F 'file=@CONFIGPROGRESS.SVG' https://legoisland.org/progress/ curl -X POST -F key=$UPLOAD_KEY -F 'file=@ISLEPROGRESS.SVG' https://legoisland.org/progress/ curl -X POST -F key=$UPLOAD_KEY -F 'file=@LEGO1PROGRESS.SVG' https://legoisland.org/progress/ diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 4cfb5d9e..9432beb0 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -12,7 +12,7 @@ jobs: - name: Run clang-format run: | - find LEGO1 ISLE -iname '*.h' -o -iname '*.cpp' | xargs \ + find CONFIG LEGO1 ISLE -iname '*.h' -o -iname '*.cpp' | xargs \ pipx run "clang-format>=17,<18" \ --style=file \ -i diff --git a/CMakeLists.txt b/CMakeLists.txt index 765cc68a..8ccd0188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,7 @@ -cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) + +# MSVC runtime library flags are selected by an abstraction +cmake_policy(SET CMP0091 NEW) project(isle CXX) @@ -60,6 +63,7 @@ message(STATUS "MSVC for decompilation: ${MSVC_FOR_DECOMP}") option(ISLE_WERROR "Treat warnings as errors" OFF) option(ISLE_BUILD_APP "Build ISLE.EXE application" ON) +cmake_dependent_option(ISLE_BUILD_CONFIG "Build CONFIG.EXE application" ON "NOT MINGW" OFF) option(ISLE_USE_SMARTHEAP "Build with SmartHeap" ${MSVC_FOR_DECOMP}) option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" ON) cmake_dependent_option(ISLE_USE_DX5_LIBS "Build with internal DirectX 5 SDK Libraries" ON ISLE_USE_DX5 OFF) @@ -435,14 +439,38 @@ if (ISLE_BUILD_APP) set_property(TARGET isle PROPERTY SUFFIX ".EXE") endif() +if (ISLE_BUILD_CONFIG) + add_executable(config WIN32 + LEGO1/mxdirectx/mxdirect3d.cpp + CONFIG/config.cpp + CONFIG/ConfigCommandLineInfo.cpp + CONFIG/common.cpp + CONFIG/AboutDlg.cpp + CONFIG/MainDlg.cpp + CONFIG/detectdx5.cpp + CONFIG/res/config.rc + ) + target_compile_definitions(config PRIVATE _AFXDLL MXDIRECTX_FOR_CONFIG) + target_include_directories(config PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/util" "${CMAKE_CURRENT_SOURCE_DIR}/LEGO1") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) + target_link_libraries(config PRIVATE DirectX5::DirectX5) + endif() + target_compile_definitions(config PRIVATE DIRECT3D_VERSION=0x500) + target_link_libraries(config PRIVATE ddraw dxguid) + set_property(TARGET config PROPERTY OUTPUT_NAME "CONFIG") + set_property(TARGET config PROPERTY SUFFIX ".EXE") + set_property(TARGET config PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>DLL) +endif() + if (MSVC) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15") - foreach(tgt IN LISTS lego1_targets) - target_compile_definitions(${tgt} PRIVATE _CRT_SECURE_NO_WARNINGS) - endforeach() + set_property(TARGET ${lego1_targets} APPEND PROPERTY COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS") if (TARGET isle) target_compile_definitions(isle PRIVATE "_CRT_SECURE_NO_WARNINGS") endif() + if (TARGET config) + target_compile_definitions(config PRIVATE "_CRT_SECURE_NO_WARNINGS") + endif() endif() # Visual Studio 2017 version 15.7 needs "/Zc:__cplusplus" for __cplusplus if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.14.26428") @@ -452,13 +480,19 @@ if (MSVC) if (TARGET isle) target_compile_options(isle PRIVATE "-Zc:__cplusplus") endif() + if (TARGET config) + target_compile_options(config PRIVATE "-Zc:__cplusplus") + endif() endif() endif() if (MSVC_FOR_DECOMP) target_compile_definitions(lego1 PRIVATE "ENABLE_DECOMP_ASSERTS") - if (ISLE_BUILD_APP) - target_compile_definitions(isle PRIVATE "ENABLE_DECOMP_ASSERTS") + if (TARGET isle) + target_compile_definitions(isle PRIVATE "ENABLE_DECOMP_ASSERTS") + endif() + if (TARGET config) + target_compile_definitions(config PRIVATE "ENABLE_DECOMP_ASSERTS") endif() endif() @@ -471,10 +505,8 @@ if (MSVC_FOR_DECOMP) target_link_options(isle PRIVATE "/OPT:REF") endif() - target_compile_options(lego1 PRIVATE "/MT$<$:d>") - foreach(tgt IN LISTS lego1_targets) - target_compile_options(${tgt} PRIVATE "/MT$<$:d>") - endforeach() + # Equivalent to target_compile_options(... PRIVATE "/MT$<$:d>") + set_property(TARGET lego1 ${lego1_targets} PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) set(CMAKE_CXX_FLAGS "/W3 /GX /D \"WIN32\" /D \"_WINDOWS\"") set(CMAKE_CXX_FLAGS_DEBUG "/Gm /Zi /Od /D \"_DEBUG\"") diff --git a/CONFIG/AboutDlg.cpp b/CONFIG/AboutDlg.cpp new file mode 100644 index 00000000..b14704f1 --- /dev/null +++ b/CONFIG/AboutDlg.cpp @@ -0,0 +1,19 @@ +#include "AboutDlg.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(CDialog, 0x60) +DECOMP_SIZE_ASSERT(CAboutDialog, 0x60) + +// FUNCTION: CONFIG 0x00403c20 +CAboutDialog::CAboutDialog() : CCommonDialog(IDD) +{ +} + +// FUNCTION: CONFIG 0x00403d20 +void CAboutDialog::DoDataExchange(CDataExchange* pDX) +{ +} + +BEGIN_MESSAGE_MAP(CAboutDialog, CDialog) +END_MESSAGE_MAP() diff --git a/CONFIG/AboutDlg.h b/CONFIG/AboutDlg.h new file mode 100644 index 00000000..725ac9e9 --- /dev/null +++ b/CONFIG/AboutDlg.h @@ -0,0 +1,49 @@ +#if !defined(AFX_ABOUTDLG_H) +#define AFX_ABOUTDLG_H + +#include "afxwin.h" +#include "common.h" +#include "compat.h" +#include "res/resource.h" + +// VTABLE: CONFIG 0x00406308 +// SIZE 0x60 +class CAboutDialog : public CCommonDialog { +public: + CAboutDialog(); + // Dialog Data + //{{AFX_DATA(CMainDialog) + enum { + IDD = IDD_ABOUT + }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainDialog) + +protected: + void DoDataExchange(CDataExchange* pDX) override; + //}}AFX_VIRTUAL + // void UpdateInterface(); + // void SwitchToAdvanced(BOOL p_advanced); + // Implementation + +protected: + //{{AFX_MSG(CMainDialog) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +// SYNTHETIC: CONFIG 0x00403cb0 +// CAboutDialog::`scalar deleting destructor' + +// FUNCTION: CONFIG 0x00403d40 +// CAboutDialog::GetMessageMap + +// GLOBAL: CONFIG 0x00406100 +// CAboutDialog::messageMap + +// GLOBAL: CONFIG 0x00406108 +// CAboutDialog::_messageEntries + +#endif // !defined(AFX_ABOUTDLG_H) diff --git a/CONFIG/ConfigCommandLineInfo.cpp b/CONFIG/ConfigCommandLineInfo.cpp new file mode 100644 index 00000000..0e376e6d --- /dev/null +++ b/CONFIG/ConfigCommandLineInfo.cpp @@ -0,0 +1,22 @@ +#include "ConfigCommandLineInfo.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(CCommandLineInfo, 0x24) +DECOMP_SIZE_ASSERT(CConfigCommandLineInfo, 0x24) + +// FUNCTION: CONFIG 0x00403b10 +CConfigCommandLineInfo::CConfigCommandLineInfo() +{ + currentConfigApp->m_run_config_dialog = FALSE; +} + +// FUNCTION: CONFIG 0x00403bf0 +void CConfigCommandLineInfo::ParseParam(LPCSTR pszParam, BOOL bFlag, BOOL bLast) +{ + if (bFlag) { + if (lstrcmpiA(pszParam, "config") == 0) { + currentConfigApp->m_run_config_dialog = TRUE; + } + } +} diff --git a/CONFIG/ConfigCommandLineInfo.h b/CONFIG/ConfigCommandLineInfo.h new file mode 100644 index 00000000..d7b88ac9 --- /dev/null +++ b/CONFIG/ConfigCommandLineInfo.h @@ -0,0 +1,22 @@ +#if !defined(AFX_CONFIGCOMMANDLINEINFO_H) +#define AFX_CONFIGCOMMANDLINEINFO_H + +#include "compat.h" +#include "config.h" +#include "decomp.h" + +#include + +// VTABLE: CONFIG 0x004060e8 +// SIZE 0x24 +class CConfigCommandLineInfo : public CCommandLineInfo { +public: + CConfigCommandLineInfo(); + + void ParseParam(LPCSTR pszParam, BOOL bFlag, BOOL bLast) override; +}; + +// SYNTHETIC: CONFIG 0x00403b80 +// CConfigCommandLineInfo::`scalar deleting destructor' + +#endif // !defined(AFX_CONFIGCOMMANDLINEINFO_H) diff --git a/CONFIG/MainDlg.cpp b/CONFIG/MainDlg.cpp new file mode 100644 index 00000000..52f55e58 --- /dev/null +++ b/CONFIG/MainDlg.cpp @@ -0,0 +1,344 @@ +#include "MainDlg.h" + +#include "AboutDlg.h" +#include "config.h" +#include "res/resource.h" + +#include + +DECOMP_SIZE_ASSERT(CDialog, 0x60) +DECOMP_SIZE_ASSERT(CMainDialog, 0x70) + +// FUNCTION: CONFIG 0x00403d50 +CMainDialog::CMainDialog(CWnd* pParent) : CCommonDialog(IDD, pParent) +{ + afxCurrentWinApp; + m_icon = LoadIconA(AfxFindResourceHandle(MAKEINTRESOURCE(IDI_CONFIG), RT_GROUP_ICON), MAKEINTRESOURCE(IDI_CONFIG)); +} + +// FUNCTION: CONFIG 0x00403e50 +void CMainDialog::DoDataExchange(CDataExchange* pDX) +{ +} + +BEGIN_MESSAGE_MAP(CMainDialog, CDialog) +ON_WM_SYSCOMMAND() +ON_WM_PAINT() +ON_WM_QUERYDRAGICON() +ON_COMMAND(IDC_CHK_FLIP_VIDEO_MEM_PAGES, OnCheckboxFlipVideoMemPages) +ON_LBN_SELCHANGE(IDC_LIST_3DDEVICES, OnList3DevicesSelectionChanged) +ON_COMMAND(IDC_RAD_PALETTE_16BIT, OnRadiobuttonPalette16bit) +ON_COMMAND(IDC_RAD_PALETTE_256, OnRadiobuttonPalette256) +ON_COMMAND(IDC_CHK_3D_VIDEO_MEMORY, OnCheckbox3DVideoMemory) +ON_WM_DESTROY() // FIXME: CONFIG.EXE calls Default +ON_COMMAND(IDABORT, OnButtonCancel) +ON_COMMAND(IDC_CHK_3DSOUND, OnCheckbox3DSound) +ON_COMMAND(IDC_RAD_MODEL_QUALITY_LOW, OnRadiobuttonModelLowQuality) +ON_COMMAND(IDC_RAD_MODEL_QUALITY_HIGH, OnRadiobuttonModelHighQuality) +ON_COMMAND(IDC_RAD_TEXTURE_QUALITY_LOW, OnRadiobuttonTextureLowQuality) +ON_COMMAND(IDC_RAD_TEXTURE_QUALITY_HIGH, OnRadiobuttonTextureHighQuality) +ON_COMMAND(IDC_CHK_JOYSTICK, OnCheckboxJoystick) +ON_COMMAND(IDC_BTN_ADVANCED, OnButtonAdvanced) +ON_COMMAND(IDC_CHK_DRAW_CURSOR, OnCheckboxDrawCursor) +ON_COMMAND(IDC_CHK_MUSIC, OnCheckboxMusic) +END_MESSAGE_MAP() + +// FUNCTION: CONFIG 0x00403e80 +BOOL CMainDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + SwitchToAdvanced(FALSE); + CMenu* system_menu = CMenu::FromHandle(::GetSystemMenu(m_hWnd, FALSE)); + CString about_text; + about_text.LoadString(IDS_ABOUT); + if (system_menu) { + AppendMenuA(system_menu->m_hMenu, MF_SEPARATOR, 0, NULL); + AppendMenuA(system_menu->m_hMenu, MF_STRING, 16, (LPCTSTR) about_text); + } + SendMessage(WM_SETICON, ICON_BIG, (LPARAM) m_icon); + SendMessage(WM_SETICON, ICON_SMALL, (LPARAM) m_icon); + MxDeviceEnumerate* enumerator = currentConfigApp->m_device_enumerator; + enumerator->FUN_1009d210(); + m_modified = currentConfigApp->ReadRegisterSettings(); + CWnd* list_3d_devices = GetDlgItem(IDC_LIST_3DDEVICES); + int driver_i = 0; + int device_i = 0; + int selected = 0; + char device_name[256]; + const list& driver_list = enumerator->GetDriverList(); + for (list::const_iterator it_driver = driver_list.begin(); it_driver != driver_list.end(); it_driver++) { + const MxDriver& driver = *it_driver; + for (list::const_iterator it_device = driver.m_devices.begin(); it_device != driver.m_devices.end(); + it_device++) { + const MxDevice& device = *it_device; + if (&device == currentConfigApp->m_device) { + selected = device_i; + } + device_i += 1; + sprintf( + device_name, + driver_i == 0 ? "%s ( Primary Device )" : "%s ( Secondary Device )", + device.m_deviceName + ); + ::SendMessage(list_3d_devices->m_hWnd, LB_ADDSTRING, 0, (LPARAM) device_name); + } + driver_i += 1; + } + ::SendMessage(list_3d_devices->m_hWnd, LB_SETCURSEL, selected, 0); + UpdateInterface(); + return TRUE; +} + +// FUNCTION: CONFIG 0x00404080 +void CMainDialog::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xfff0) == 0x10) { + CAboutDialog about_dialog; + about_dialog.DoModal(); + } + else { + Default(); + } +} + +// FUNCTION: CONFIG 0x00404150 +void CMainDialog::OnPaint() +{ + if (IsIconic()) { + CPaintDC painter(this); + ::SendMessage(m_hWnd, WM_ICONERASEBKGND, (WPARAM) painter.m_hDC, 0); + RECT dim; + GetClientRect(&dim); + DrawIcon( + painter.m_hDC, + (dim.right - dim.left - GetSystemMetrics(SM_CXICON) + 1) / 2, + (dim.bottom - dim.top - GetSystemMetrics(SM_CYICON) + 1) / 2, + m_icon + ); + } + else { + Default(); + } +} + +// FUNCTION: CONFIG 0x00404230 +HCURSOR CMainDialog::OnQueryDragIcon() +{ + return m_icon; +} + +// FUNCTION: CONFIG 0x00404240 +void CMainDialog::OnList3DevicesSelectionChanged() +{ + MxDeviceEnumerate* 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()) { + GetDlgItem(IDC_CHK_DRAW_CURSOR)->EnableWindow(TRUE); + } + else { + currentConfigApp->m_3d_video_ram = FALSE; + currentConfigApp->m_flip_surfaces = FALSE; + CheckDlgButton(IDC_CHK_3D_VIDEO_MEMORY, currentConfigApp->m_3d_video_ram); + CheckDlgButton(IDC_CHK_FLIP_VIDEO_MEM_PAGES, currentConfigApp->m_flip_surfaces); + } + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404320 +void CMainDialog::OnCancel() +{ + CDialog::OnCancel(); +} + +// FUNCTION: CONFIG 0x00404330 +void CMainDialog::OnDestroy() +{ + CDialog::Default(); +} + +// FUNCTION: CONFIG 0x00404340 +void CMainDialog::OnButtonCancel() +{ + if (m_modified) { + currentConfigApp->WriteRegisterSettings(); + } + OnCancel(); +} + +// FUNCTION: CONFIG 0x00404360 +void CMainDialog::UpdateInterface() +{ + currentConfigApp->ValidateSettings(); + GetDlgItem(IDC_CHK_3D_VIDEO_MEMORY) + ->EnableWindow(!currentConfigApp->m_flip_surfaces && !currentConfigApp->GetHardwareDeviceColorModel()); + CheckDlgButton(IDC_CHK_FLIP_VIDEO_MEM_PAGES, currentConfigApp->m_flip_surfaces); + CheckDlgButton(IDC_CHK_3D_VIDEO_MEMORY, currentConfigApp->m_3d_video_ram); + BOOL full_screen = currentConfigApp->m_full_screen; + currentConfigApp->FUN_00403810(); + if (currentConfigApp->GetHardwareDeviceColorModel()) { + CheckDlgButton(IDC_CHK_DRAW_CURSOR, TRUE); + } + else { + CheckDlgButton(IDC_CHK_DRAW_CURSOR, FALSE); + currentConfigApp->m_draw_cursor = FALSE; + GetDlgItem(IDC_CHK_DRAW_CURSOR)->EnableWindow(FALSE); + } + if (full_screen) { + CheckRadioButton( + IDC_RAD_PALETTE_256, + IDC_RAD_PALETTE_16BIT, + currentConfigApp->m_display_bit_depth == 8 ? IDC_RAD_PALETTE_256 : IDC_RAD_PALETTE_16BIT + ); + } + else { + CheckDlgButton(IDC_RAD_PALETTE_256, 0); + CheckDlgButton(IDC_RAD_PALETTE_16BIT, 0); + currentConfigApp->m_display_bit_depth = 0; + } + GetDlgItem(IDC_RAD_PALETTE_256)->EnableWindow(full_screen && currentConfigApp->FUN_004037a0()); + GetDlgItem(IDC_RAD_PALETTE_16BIT)->EnableWindow(full_screen && currentConfigApp->FUN_004037e0()); + CheckDlgButton(IDC_CHK_3DSOUND, currentConfigApp->m_3d_sound); + CheckDlgButton(IDC_CHK_DRAW_CURSOR, currentConfigApp->m_draw_cursor); + switch (currentConfigApp->m_model_quality) { + case 1: + CheckRadioButton(IDC_RAD_MODEL_QUALITY_LOW, IDC_RAD_MODEL_QUALITY_HIGH, IDC_RAD_MODEL_QUALITY_LOW); + break; + case 2: + CheckRadioButton(IDC_RAD_MODEL_QUALITY_LOW, IDC_RAD_MODEL_QUALITY_HIGH, IDC_RAD_MODEL_QUALITY_HIGH); + break; + } + CheckRadioButton( + IDC_RAD_TEXTURE_QUALITY_LOW, + IDC_RAD_TEXTURE_QUALITY_HIGH, + currentConfigApp->m_texture_quality == 0 ? IDC_RAD_TEXTURE_QUALITY_LOW : IDC_RAD_TEXTURE_QUALITY_HIGH + ); + CheckDlgButton(IDC_CHK_JOYSTICK, currentConfigApp->m_use_joystick); + CheckDlgButton(IDC_CHK_MUSIC, currentConfigApp->m_music); +} + +// FUNCTION: CONFIG 0x004045e0 +void CMainDialog::OnCheckbox3DSound() +{ + currentConfigApp->m_3d_sound = IsDlgButtonChecked(IDC_CHK_3DSOUND); + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404610 +void CMainDialog::OnCheckbox3DVideoMemory() +{ + currentConfigApp->m_3d_video_ram = IsDlgButtonChecked(IDC_CHK_3D_VIDEO_MEMORY); + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404640 +void CMainDialog::OnRadiobuttonPalette16bit() +{ + currentConfigApp->m_display_bit_depth = 16; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404670 +void CMainDialog::OnRadiobuttonPalette256() +{ + currentConfigApp->m_display_bit_depth = 8; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x004046a0 +void CMainDialog::OnCheckboxFlipVideoMemPages() +{ + currentConfigApp->m_flip_surfaces = IsDlgButtonChecked(IDC_CHK_FLIP_VIDEO_MEM_PAGES); + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x004046d0 +void CMainDialog::OnRadiobuttonModelLowQuality() +{ + currentConfigApp->m_model_quality = 1; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404700 +void CMainDialog::OnRadiobuttonModelHighQuality() +{ + currentConfigApp->m_model_quality = 2; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404730 +void CMainDialog::OnRadiobuttonTextureLowQuality() +{ + currentConfigApp->m_texture_quality = 0; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404760 +void CMainDialog::OnRadiobuttonTextureHighQuality() +{ + currentConfigApp->m_texture_quality = 1; + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x00404790 +void CMainDialog::OnCheckboxJoystick() +{ + currentConfigApp->m_use_joystick = IsDlgButtonChecked(IDC_CHK_JOYSTICK); + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x004047c0 +void CMainDialog::OnButtonAdvanced() +{ + SwitchToAdvanced(!m_advanced); +} + +// FUNCTION: CONFIG 0x004047d0 +void CMainDialog::SwitchToAdvanced(BOOL p_advanced) +{ + RECT dialog_rect; + RECT grp_advanced_rect; + ::GetWindowRect(m_hWnd, &dialog_rect); + ::GetWindowRect(GetDlgItem(IDC_GRP_ADVANCED)->m_hWnd, &grp_advanced_rect); + CWnd* button_advanced = GetDlgItem(IDC_BTN_ADVANCED); + m_advanced = p_advanced; + int height; + if (p_advanced) { + height = grp_advanced_rect.bottom - dialog_rect.top + 10; + GetDlgItem(IDC_BMP_SHARK)->EnableWindow(TRUE); + button_advanced->SetWindowText("Basic"); + } + else { + height = grp_advanced_rect.top - dialog_rect.top; + GetDlgItem(IDC_BMP_SHARK)->EnableWindow(FALSE); + button_advanced->SetWindowText("Advanced"); + } + SetWindowPos(&wndTop, 0, 0, dialog_rect.right - dialog_rect.left, height, SWP_NOMOVE); +} + +// FUNCTION: CONFIG 0x00404890 +void CMainDialog::OnCheckboxDrawCursor() +{ + currentConfigApp->m_draw_cursor = IsDlgButtonChecked(IDC_CHK_DRAW_CURSOR); + m_modified = TRUE; + UpdateInterface(); +} + +// FUNCTION: CONFIG 0x004048c0 +void CMainDialog::OnCheckboxMusic() +{ + currentConfigApp->m_music = IsDlgButtonChecked(IDC_CHK_MUSIC); + m_modified = TRUE; + UpdateInterface(); +} diff --git a/CONFIG/MainDlg.h b/CONFIG/MainDlg.h new file mode 100644 index 00000000..3f8da55a --- /dev/null +++ b/CONFIG/MainDlg.h @@ -0,0 +1,76 @@ +#if !defined(AFX_MAINDLG_H) +#define AFX_MAINDLG_H + +#include "afxwin.h" +#include "common.h" +#include "compat.h" +#include "decomp.h" +#include "res/resource.h" + +// VTABLE: CONFIG 0x004063e0 +// SIZE 0x70 +class CMainDialog : public CCommonDialog { +public: + CMainDialog(CWnd* pParent); + // Dialog Data + //{{AFX_DATA(CMainDialog) + enum { + IDD = IDD_MAIN + }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainDialog) + +protected: + void DoDataExchange(CDataExchange* pDX) override; + //}}AFX_VIRTUAL + void UpdateInterface(); + void SwitchToAdvanced(BOOL p_advanced); + + undefined m_unk0x60[4]; // 0x60 + HCURSOR m_icon; // 0x64 + BOOL m_modified; // 0x68 + BOOL m_advanced; // 0x6c + // Implementation + +protected: + //{{AFX_MSG(CMainDialog) + BOOL OnInitDialog() override; + void OnSysCommand(UINT nID, LPARAM lParam); + void OnPaint(); + HCURSOR OnQueryDragIcon(); + void OnList3DevicesSelectionChanged(); + void OnCancel(); + void OnDestroy(); + void OnButtonCancel(); + void OnCheckbox3DSound(); + void OnCheckbox3DVideoMemory(); + void OnRadiobuttonPalette16bit(); + void OnRadiobuttonPalette256(); + void OnCheckboxFlipVideoMemPages(); + void OnRadiobuttonModelLowQuality(); + void OnRadiobuttonModelHighQuality(); + void OnRadiobuttonTextureLowQuality(); + void OnRadiobuttonTextureHighQuality(); + void OnCheckboxJoystick(); + void OnButtonAdvanced(); + void OnCheckboxDrawCursor(); + void OnCheckboxMusic(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +// SYNTHETIC: CONFIG 0x00403de0 +// CMainDialog::`scalar deleting destructor' + +// FUNCTION: CONFIG 0x00403e70 +// CMainDialog::GetMessageMap + +// GLOBAL: CONFIG 0x00406120 +// CMainDialog::messageMap + +// GLOBAL: CONFIG 0x00406128 +// CMainDialog::_messageEntries + +#endif // !defined(AFX_MAINDLG_H) diff --git a/CONFIG/common.cpp b/CONFIG/common.cpp new file mode 100644 index 00000000..207d583d --- /dev/null +++ b/CONFIG/common.cpp @@ -0,0 +1,13 @@ +#include "common.h" + +// FUNCTION: CONFIG 0x00403c90 +void CCommonDialog::BeginModalState() +{ + ::EnableWindow(m_hWnd, FALSE); +} + +// FUNCTION: CONFIG 0x00403ca0 +void CCommonDialog::EndModalState() +{ + ::EnableWindow(m_hWnd, TRUE); +} diff --git a/CONFIG/common.h b/CONFIG/common.h new file mode 100644 index 00000000..f8c6299e --- /dev/null +++ b/CONFIG/common.h @@ -0,0 +1,16 @@ +#ifndef AFX_COMMON_H +#define AFX_COMMON_H + +#include "compat.h" + +#include + +class CCommonDialog : public CDialog { +public: + CCommonDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL) : CDialog(nIDTemplate, pParentWnd) {} + + void BeginModalState() override; + void EndModalState() override; +}; + +#endif diff --git a/CONFIG/config.cpp b/CONFIG/config.cpp new file mode 100644 index 00000000..78c6b6c2 --- /dev/null +++ b/CONFIG/config.cpp @@ -0,0 +1,434 @@ +#include "config.h" + +#include "ConfigCommandLineInfo.h" +#include "MainDlg.h" +#include "detectdx5.h" + +#include // _chdir +#include +#include // _spawnl + +DECOMP_SIZE_ASSERT(CWinApp, 0xc4) +DECOMP_SIZE_ASSERT(CConfigApp, 0x108) + +DECOMP_STATIC_ASSERT(offsetof(CConfigApp, m_display_bit_depth) == 0xd0) + +BEGIN_MESSAGE_MAP(CConfigApp, CWinApp) +ON_COMMAND(ID_HELP, OnHelp) +END_MESSAGE_MAP() + +// FUNCTION: CONFIG 0x00402c40 +CConfigApp::CConfigApp() +{ +} + +#define MiB (1024 * 1024) + +// FUNCTION: CONFIG 0x00402dc0 +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 " + "again." + ); + 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 MxDeviceEnumerate; + if (m_device_enumerator->DoEnumerate()) { + return FALSE; + } + m_driver = NULL; + m_device = NULL; + m_full_screen = TRUE; + m_wide_view_angle = TRUE; + m_use_joystick = FALSE; + m_music = TRUE; + m_flip_surfaces = FALSE; + m_3d_video_ram = FALSE; + m_joystick_index = -1; + m_display_bit_depth = 16; + MEMORYSTATUS memory_status; + memory_status.dwLength = sizeof(memory_status); + GlobalMemoryStatus(&memory_status); + if (memory_status.dwTotalPhys < 12 * MiB) { + m_3d_sound = FALSE; + m_model_quality = 0; + m_texture_quality = 1; + } + else if (memory_status.dwTotalPhys < 20 * MiB) { + m_3d_sound = FALSE; + m_model_quality = 1; + m_texture_quality = 1; + } + else { + m_model_quality = 2; + m_3d_sound = TRUE; + m_texture_quality = 1; + } + if (!m_run_config_dialog) { + ReadRegisterSettings(); + ValidateSettings(); + WriteRegisterSettings(); + delete m_device_enumerator; + m_device_enumerator = NULL; + m_driver = NULL; + m_device = NULL; + char password[256]; + 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))) { + _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; +} + +// FUNCTION: CONFIG 0x00403100 +BOOL CConfigApp::IsLegoNotRunning() +{ + HWND hWnd = FindWindowA("Lego Island MainNoM App", "LEGO\xae"); + if (_stricmp(afxCurrentAppName, "config") == 0 || !hWnd) { + return TRUE; + } + if (SetForegroundWindow(hWnd)) { + ShowWindow(hWnd, SW_RESTORE); + } + return FALSE; +} + +// FUNCTION: CONFIG 0x004031b0 +BOOL CConfigApp::WriteReg(const char* p_key, const char* p_value) const +{ + HKEY hKey; + DWORD pos; + + if (RegCreateKeyExA( + HKEY_LOCAL_MACHINE, + "SOFTWARE\\Mindscape\\LEGO Island", + 0, + "string", + 0, + KEY_READ | KEY_WRITE, + NULL, + &hKey, + &pos + ) == ERROR_SUCCESS) { + if (RegSetValueExA(hKey, p_key, 0, REG_SZ, (LPBYTE) p_value, strlen(p_value)) == ERROR_SUCCESS) { + if (RegCloseKey(hKey) == ERROR_SUCCESS) { + return TRUE; + } + } + else { + RegCloseKey(hKey); + } + } + return FALSE; +} + +// FUNCTION: CONFIG 0x00403240 +BOOL CConfigApp::ReadReg(LPCSTR p_key, LPCSTR p_value, DWORD p_size) const +{ + HKEY hKey; + DWORD valueType; + + BOOL out = FALSE; + DWORD size = p_size; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mindscape\\LEGO Island", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, p_key, NULL, &valueType, (LPBYTE) p_value, &size) == ERROR_SUCCESS) { + if (RegCloseKey(hKey) == ERROR_SUCCESS) { + out = TRUE; + } + } + } + return out; +} + +// FUNCTION: CONFIG 0x004032b0 +BOOL CConfigApp::ReadRegBool(LPCSTR p_key, BOOL* p_bool) const +{ + char buffer[256]; + + BOOL read = ReadReg(p_key, buffer, sizeof(buffer)); + if (read) { + if (strcmp("YES", buffer) == 0) { + *p_bool = TRUE; + return read; + } + + if (strcmp("NO", buffer) == 0) { + *p_bool = FALSE; + return read; + } + + read = FALSE; + } + return read; +} + +// FUNCTION: CONFIG 0x00403380 +BOOL CConfigApp::ReadRegInt(LPCSTR p_key, int* p_value) const +{ + char buffer[256]; + + BOOL read = ReadReg(p_key, buffer, sizeof(buffer)); + if (read) { + *p_value = atoi(buffer); + } + + return read; +} + +// FUNCTION: CONFIG 0x004033d0 +BOOL CConfigApp::FUN_004033d0() const +{ + /* + * BUG: should be: + * return !GetHardwareDeviceColorModel() && (m_device->m_HELDesc.dcmColorModel & D3DCOLOR_RGB); + */ + return !GetHardwareDeviceColorModel() && m_device->m_HELDesc.dcmColorModel == D3DCOLOR_RGB; +} + +// FUNCTION: CONFIG 0x00403400 +D3DCOLORMODEL CConfigApp::GetHardwareDeviceColorModel() const +{ + return m_device->m_HWDesc.dcmColorModel; +} + +// FUNCTION: CONFIG 0x00403410 +BOOL CConfigApp::IsPrimaryDriver() const +{ + return m_driver == &m_device_enumerator->GetDriverList().front(); +} + +// FUNCTION: CONFIG 0x00403430 +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); + } + } + if (tmp != 0) { + is_modified = TRUE; + m_device_enumerator->FUN_1009d210(); + tmp = m_device_enumerator->FUN_1009d0d0(); + m_device_enumerator->GetDevice(tmp, m_driver, m_device); + } + if (!ReadRegInt("Display Bit Depth", &m_display_bit_depth)) { + is_modified = TRUE; + } + if (!ReadRegBool("Flip Surfaces", &m_flip_surfaces)) { + is_modified = TRUE; + } + if (!ReadRegBool("Full Screen", &m_full_screen)) { + is_modified = TRUE; + } + if (!ReadRegBool("Back Buffers in Video RAM", &m_3d_video_ram)) { + is_modified = TRUE; + } + if (!ReadRegBool("Wide View Angle", &m_wide_view_angle)) { + is_modified = TRUE; + } + if (!ReadRegBool("3DSound", &m_3d_sound)) { + is_modified = TRUE; + } + if (!ReadRegBool("Draw Cursor", &m_draw_cursor)) { + is_modified = TRUE; + } + if (!ReadRegInt("Island Quality", &m_model_quality)) { + is_modified = TRUE; + } + if (!ReadRegInt("Island Texture", &m_texture_quality)) { + is_modified = TRUE; + } + if (!ReadRegBool("UseJoystick", &m_use_joystick)) { + is_modified = TRUE; + } + if (!ReadRegBool("Music", &m_music)) { + is_modified = TRUE; + } + if (!ReadRegInt("JoystickIndex", &m_joystick_index)) { + is_modified = TRUE; + } + return is_modified; +} + +// FUNCTION: CONFIG 0x00403630 +BOOL CConfigApp::ValidateSettings() +{ + BOOL is_modified = FALSE; + + if (!IsPrimaryDriver() && !m_full_screen) { + m_full_screen = TRUE; + is_modified = TRUE; + } + if (FUN_004033d0()) { + if (m_3d_video_ram) { + m_3d_video_ram = FALSE; + is_modified = TRUE; + } + if (m_flip_surfaces) { + m_flip_surfaces = FALSE; + is_modified = TRUE; + } + if (m_display_bit_depth != 16) { + m_display_bit_depth = 16; + is_modified = TRUE; + } + } + if (!GetHardwareDeviceColorModel()) { + m_draw_cursor = FALSE; + is_modified = TRUE; + } + else { + if (!m_3d_video_ram) { + m_3d_video_ram = TRUE; + is_modified = TRUE; + } + if (m_full_screen && !m_flip_surfaces) { + m_flip_surfaces = TRUE; + is_modified = TRUE; + } + } + if (m_flip_surfaces) { + if (!m_3d_video_ram) { + m_3d_video_ram = TRUE; + is_modified = TRUE; + } + if (!m_full_screen) { + m_full_screen = TRUE; + is_modified = TRUE; + } + } + if ((m_display_bit_depth != 8 && m_display_bit_depth != 16) && (m_display_bit_depth != 0 || m_full_screen)) { + m_display_bit_depth = 8; + is_modified = TRUE; + } + if (m_model_quality < 0 || m_model_quality > 2) { + m_model_quality = 1; + is_modified = TRUE; + } + if (m_texture_quality < 0 || m_texture_quality > 1) { + m_texture_quality = 0; + is_modified = TRUE; + } + return is_modified; +} + +// FUNCTION: CONFIG 0x004037a0 +DWORD CConfigApp::FUN_004037a0() const +{ + if (FUN_004033d0()) { + return 0; + } + if (GetHardwareDeviceColorModel()) { + return 0; + } + return m_device->m_HELDesc.dwDeviceRenderBitDepth & 0x800; +} + +// FUNCTION: CONFIG 0x004037e0 +DWORD CConfigApp::FUN_004037e0() const +{ + if (GetHardwareDeviceColorModel()) { + return m_device->m_HWDesc.dwDeviceRenderBitDepth & 0x400; + } + else { + return m_device->m_HELDesc.dwDeviceRenderBitDepth & 0x400; + } +} + +// FUNCTION: CONFIG 0x00403810 +BOOL CConfigApp::FUN_00403810() +{ + if (m_display_bit_depth == 8) { + if (FUN_004037a0()) { + return FALSE; + } + } + if (m_display_bit_depth == 16) { + if (FUN_004037e0()) { + return FALSE; + } + } + if (FUN_004037a0()) { + m_display_bit_depth = 8; + return TRUE; + } + if (FUN_004037e0()) { + m_display_bit_depth = 16; + return TRUE; + } + m_display_bit_depth = 8; + return TRUE; +} + +// FUNCTION: CONFIG 00403890 +void CConfigApp::WriteRegisterSettings() const + +{ + char buffer[128]; + +#define WriteRegBool(NAME, VALUE) WriteReg(NAME, VALUE ? "YES" : "NO") +#define WriteRegInt(NAME, VALUE) \ + do { \ + sprintf(buffer, "%d", VALUE); \ + WriteReg(NAME, buffer); \ + } while (0) + + m_device_enumerator->FormatDeviceName(buffer, m_driver, m_device); + WriteReg("3D Device ID", buffer); + WriteReg("3D Device Name", m_device->m_deviceName); + WriteRegInt("Display Bit Depth", m_display_bit_depth); + WriteRegBool("Flip Surfaces", m_flip_surfaces); + WriteRegBool("Full Screen", m_full_screen); + WriteRegBool("Back Buffers in Video RAM", m_3d_video_ram); + WriteRegBool("Wide View Angle", m_wide_view_angle); + WriteRegBool("3DSound", m_3d_sound); + WriteRegBool("Draw Cursor", m_draw_cursor); + WriteRegInt("Island Quality", m_model_quality); + WriteRegInt("Island Texture", m_texture_quality); + WriteRegBool("UseJoystick", m_use_joystick); + WriteRegBool("Music", m_music); + WriteRegInt("JoystickIndex", m_joystick_index); + +#undef WriteRegBool +#undef WriteRegInt +} + +// FUNCTION: CONFIG 0x00403a90 +int CConfigApp::ExitInstance() +{ + if (m_device_enumerator) { + delete m_device_enumerator; + m_device_enumerator = NULL; + } + return CWinApp::ExitInstance(); +} + +// GLOBAL: CONFIG 0x00408e50 +CConfigApp g_theApp; diff --git a/CONFIG/config.h b/CONFIG/config.h new file mode 100644 index 00000000..7112f8e4 --- /dev/null +++ b/CONFIG/config.h @@ -0,0 +1,88 @@ +#if !defined(AFX_CONFIG_H) +#define AFX_CONFIG_H + +#include "compat.h" +#include "decomp.h" + +#include +#include + +class MxDeviceEnumerate; +struct MxDevice; +struct MxDriver; + +#define currentConfigApp ((CConfigApp*) afxCurrentWinApp) + +// VTABLE: CONFIG 0x00406040 +// SIZE 0x108 +class CConfigApp : public CWinApp { +public: + CConfigApp(); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CConfigApp) + +public: + BOOL InitInstance() override; + int ExitInstance() override; + //}}AFX_VIRTUAL + + // Implementation + + BOOL WriteReg(const char* p_key, const char* p_value) const; + BOOL ReadReg(LPCSTR p_key, LPCSTR p_value, DWORD p_size) const; + BOOL ReadRegBool(LPCSTR p_key, BOOL* p_bool) const; + BOOL ReadRegInt(LPCSTR p_key, int* p_value) const; + BOOL FUN_004033d0() const; + D3DCOLORMODEL GetHardwareDeviceColorModel() const; + BOOL IsPrimaryDriver() const; + BOOL ReadRegisterSettings(); + BOOL ValidateSettings(); + DWORD FUN_004037a0() const; + DWORD FUN_004037e0() const; + BOOL FUN_00403810(); + void CConfigApp::WriteRegisterSettings() const; + + //{{AFX_MSG(CConfigApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +private: + BOOL IsLegoNotRunning(); + +public: + MxDeviceEnumerate* m_device_enumerator; // 0x0c4 + MxDriver* m_driver; // 0x0c8 + MxDevice* m_device; // 0x0cc + int m_display_bit_depth; // 0x0d0 + BOOL m_flip_surfaces; // 0x0d4 + BOOL m_full_screen; // 0x0d8 + BOOL m_3d_video_ram; // 0x0dc + BOOL m_wide_view_angle; // 0x0e0 + BOOL m_3d_sound; // 0x0e4 + BOOL m_draw_cursor; // 0x0e8 + BOOL m_use_joystick; // 0x0ec + int m_joystick_index; // 0x0f0 + BOOL m_run_config_dialog; // 0x0f4 + int m_model_quality; // 0x0f8 + int m_texture_quality; // 0x0fc + undefined m_unk0x100[4]; // 0x100 + BOOL m_music; // 0x104 +}; + +// SYNTHETIC: CONFIG 0x00402cd0 +// CConfigApp::`scalar deleting destructor' + +// FUNCTION: CONFIG 0x402c30 +// CConfigApp::GetMessageMap + +// GLOBAL: CONFIG 0x406008 +// CConfigApp::messageMap + +// GLOBAL: CONFIG 0x406010 +// CConfigApp::_messageEntries + +#endif // !defined(AFX_CONFIG_H) diff --git a/CONFIG/detectdx5.cpp b/CONFIG/detectdx5.cpp new file mode 100644 index 00000000..546f0dbd --- /dev/null +++ b/CONFIG/detectdx5.cpp @@ -0,0 +1,142 @@ +#include "detectdx5.h" + +#include +#include + +typedef HRESULT WINAPI DirectDrawCreate_fn(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter); +typedef HRESULT WINAPI +DirectInputCreateA_fn(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* ppDI, LPUNKNOWN punkOuter); + +// FUNCTION: CONFIG 0x004048f0 +BOOL DetectDirectX5() +{ + unsigned int version; + BOOL found; + DetectDirectX(&version, &found); + return version >= 0x500; +} + +// FUNCTION: CONFIG 0x00404920 +void DetectDirectX(unsigned int* p_version, BOOL* p_found) +{ + OSVERSIONINFOA os_version; + + os_version.dwOSVersionInfoSize = sizeof(os_version); + if (!GetVersionExA(&os_version)) { + *p_version = 0; + *p_found = 0; + return; + } + if (os_version.dwPlatformId == 2) { + *p_found = 2; + if (os_version.dwMajorVersion < 4) { + *p_found = 0; + return; + } + if (os_version.dwMajorVersion != 4) { + *p_version = 0x501; + return; + } + *p_version = 0x200; + HMODULE dinput_module = LoadLibraryA("DINPUT.DLL"); + if (!dinput_module) { + OutputDebugStringA("Couldn't LoadLibrary DInput\r\n"); + return; + } + DirectInputCreateA_fn* func_DirectInputCreateA = + (DirectInputCreateA_fn*) GetProcAddress(dinput_module, "DirectInputCreateA"); + FreeLibrary(dinput_module); + if (!func_DirectInputCreateA) { + OutputDebugStringA("Couldn't GetProcAddress DInputCreate\r\n"); + return; + } + *p_version = 0x300; + return; + } + *p_found = 1; + if (LOWORD(os_version.dwBuildNumber) >= 0x550) { + *p_version = 0x501; + return; + } + HMODULE ddraw_module = LoadLibraryA("DDRAW.DLL"); + if (!ddraw_module) { + *p_version = 0; + *p_found = 0; + FreeLibrary(ddraw_module); + return; + } + DirectDrawCreate_fn* func_DirectDrawCreate = + (DirectDrawCreate_fn*) GetProcAddress(ddraw_module, "DirectDrawCreate"); + if (!func_DirectDrawCreate) { + *p_version = 0; + *p_found = 0; + FreeLibrary(ddraw_module); + OutputDebugStringA("Couldn't LoadLibrary DDraw\r\n"); + return; + } + LPDIRECTDRAW ddraw; + if (FAILED(func_DirectDrawCreate(NULL, &ddraw, NULL))) { + *p_version = 0; + *p_found = 0; + FreeLibrary(ddraw_module); + OutputDebugStringA("Couldn't create DDraw\r\n"); + return; + } + *p_version = 0x100; + LPDIRECTDRAW2 ddraw2; + if (FAILED(ddraw->QueryInterface(IID_IDirectDraw2, (LPVOID*) &ddraw2))) { + ddraw->Release(); + FreeLibrary(ddraw_module); + OutputDebugStringA("Couldn't QI DDraw2\r\n"); + return; + } + ddraw->Release(); + *p_version = 0x200; + HMODULE dinput_module = LoadLibraryA("DINPUT.DLL"); + if (!dinput_module) { + OutputDebugStringA("Couldn't LoadLibrary DInput\r\n"); + ddraw2->Release(); + FreeLibrary(ddraw_module); + return; + } + DirectInputCreateA_fn* func_DirectInputCreateA = + (DirectInputCreateA_fn*) GetProcAddress(dinput_module, "DirectInputCreateA"); + FreeLibrary(dinput_module); + if (!func_DirectInputCreateA) { + FreeLibrary(ddraw_module); + ddraw2->Release(); + OutputDebugStringA("Couldn't GetProcAddress DInputCreate\r\n"); + return; + } + *p_version = 0x300; + DDSURFACEDESC surface_desc; + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS; + surface_desc.ddsCaps.dwCaps = DDCAPS2_NONLOCALVIDMEM; + if (FAILED(ddraw2->SetCooperativeLevel(NULL, DISCL_BACKGROUND))) { + ddraw2->Release(); + FreeLibrary(ddraw_module); + *p_version = 0; + OutputDebugStringA("Couldn't Set coop level\r\n"); + return; + } + LPDIRECTDRAWSURFACE surface; + if (FAILED(ddraw2->CreateSurface(&surface_desc, &surface, NULL))) { + ddraw2->Release(); + FreeLibrary(ddraw_module); + *p_version = 0; + OutputDebugStringA("Couldn't CreateSurface\r\n"); + return; + } + LPDIRECTDRAWSURFACE3 surface3; + if (FAILED(surface->QueryInterface(IID_IDirectDrawSurface3, (LPVOID*) &surface3))) { + ddraw2->Release(); + FreeLibrary(ddraw_module); + return; + } + *p_version = 0x500; + surface3->Release(); + ddraw2->Release(); + FreeLibrary(ddraw_module); +} diff --git a/CONFIG/detectdx5.h b/CONFIG/detectdx5.h new file mode 100644 index 00000000..6f45837c --- /dev/null +++ b/CONFIG/detectdx5.h @@ -0,0 +1,10 @@ +#if !defined(AFX_DETECTDX5_H) +#define AFX_DETECTDX5_H + +#include + +extern BOOL DetectDirectX5(); + +extern void DetectDirectX(unsigned int* p_version, BOOL* p_found); + +#endif // !defined(AFX_DETECTDX5_H) diff --git a/CONFIG/library_mfc.h b/CONFIG/library_mfc.h new file mode 100644 index 00000000..c6e1aa47 --- /dev/null +++ b/CONFIG/library_mfc.h @@ -0,0 +1,12 @@ +#ifdef 0 + +// FUNCTION: CONFIG 0x402ca0 +// CObject::Serialize + +// FUNCTION: CONFIG 0x402cb0 +// CObject::AssertValid + +// FUNCTION: CONFIG 0x402cc0 +// CObject::Dump + +#endif diff --git a/CONFIG/res/config.rc b/CONFIG/res/config.rc new file mode 100644 index 00000000..a6164bfa --- /dev/null +++ b/CONFIG/res/config.rc @@ -0,0 +1,82 @@ +#include "resource.h" +#include "afxres.h" + +IDI_CONFIG ICON "lego.ico" + +IDB_SHARK BITMAP "shark.bmp" + +IDD_ABOUT DIALOG 0, 0, 217, 55 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Configure LEGO\xAE Island" +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +FONT 8, "MS Sans Serif" +BEGIN + CONTROL IDI_CONFIG, -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 11, 17, 18, 20 + CONTROL "Configure LEGO Island Version 1.0", -1, "STATIC", SS_LEFT | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 10, 119, 8 + CONTROL "Copyright \xA9 1997 mindscape", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 25, 119, 8 + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 178, 7, 32, 14 +END + +STRINGTABLE +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +BEGIN + IDS_ABOUT, "&About Config..." +END + +IDD_MAIN DIALOGEX 0, 0, 289, 247 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "Configure LEGO Island" +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "OK", IDABORT, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 172, 125, 44, 14 + CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 238, 125, 44, 14 + CONTROL "Fast", IDC_RAD_MODEL_QUALITY_LOW, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 124, 18, 42, 10 + CONTROL "High", IDC_RAD_MODEL_QUALITY_HIGH, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 192, 18, 69, 10 + CONTROL "Fast", IDC_RAD_TEXTURE_QUALITY_LOW, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 124, 49, 43, 10 + CONTROL "High", IDC_RAD_TEXTURE_QUALITY_HIGH, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 192, 49, 69, 10 + CONTROL "256 Color", IDC_RAD_PALETTE_256, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 124, 80, 50, 10 + CONTROL "High Color(16 bit)", IDC_RAD_PALETTE_16BIT, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 192, 80, 76, 10 + CONTROL "Use Joystick", IDC_CHK_JOYSTICK, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 192, 104, 60, 10 + CONTROL "", IDC_LIST_3DDEVICES, "LISTBOX", LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 115, 168, 161, 36 , WS_EX_TRANSPARENT + CONTROL "Flip Video Memory Pages", IDC_CHK_FLIP_VIDEO_MEM_PAGES, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, 116, 224, 96, 15 + CONTROL "Draw 3D to Video Memory", IDC_CHK_3D_VIDEO_MEMORY, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, 116, 210, 99, 10 + CONTROL "Color Palette", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 107, 69, 175, 26 + CONTROL "Direct 3D Devices", -1, "STATIC", SS_CENTER | WS_CHILD | WS_VISIBLE | WS_GROUP, 123, 158, 143, 10 + CONTROL "3D Sound", IDC_CHK_3DSOUND, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, 220, 210, 45, 10 + CONTROL "Island Model Quality", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 107, 7, 175, 26 + CONTROL "Island Texture Quality", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 107, 38, 175, 26 + CONTROL "Advanced Settings", IDC_GRP_ADVANCED, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 107, 147, 175, 93 + CONTROL "Advanced", IDC_BTN_ADVANCED, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 109, 124, 44, 14 + CONTROL IDB_SHARK, IDC_BMP_SHARK, "STATIC", SS_BITMAP | WS_CHILD | WS_VISIBLE, 7, 7, 83, 249 + CONTROL "Draw Cursor", IDC_CHK_DRAW_CURSOR, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, 219, 227, 54, 10 + CONTROL "Music", IDC_CHK_MUSIC, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 124, 104, 35, 10 +END + +1 VERSIONINFO +FILEVERSION 1,1,0,0 +PRODUCTVERSION 1,1,0,0 +FILEOS 0x4 +FILETYPE 0x1 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Mindscape, Inc." + VALUE "FileDescription", "LEGOIsland & Configuration application" + VALUE "FileVersion", "1, 1, 0, 0" + VALUE "InternalName", "LEGOISLE.EXE" + VALUE "LegalCopyright", "Copyright \xA9 1997" + VALUE "OriginalFilename", "CONFIG.EXE" + VALUE "ProductName", "LEGO Island" + VALUE "ProductVersion", "1, 1, 0, 0" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 // U.S. English, Unicode + END +END diff --git a/CONFIG/res/lego.ico b/CONFIG/res/lego.ico new file mode 100644 index 00000000..7db1421d Binary files /dev/null and b/CONFIG/res/lego.ico differ diff --git a/CONFIG/res/resource.h b/CONFIG/res/resource.h new file mode 100644 index 00000000..4c72eaa1 --- /dev/null +++ b/CONFIG/res/resource.h @@ -0,0 +1,25 @@ +#define IDI_CONFIG 128 + +#define IDD_ABOUT 100 +#define IDS_ABOUT 101 + +#define IDD_MAIN 102 + +#define IDC_LIST_3DDEVICES 1000 +#define IDC_CHK_FLIP_VIDEO_MEM_PAGES 1001 +#define IDC_CHK_3D_VIDEO_MEMORY 1003 +#define IDC_RAD_PALETTE_256 1004 +#define IDC_RAD_PALETTE_16BIT 1005 +#define IDC_CHK_3DSOUND 1006 +#define IDC_CHK_DRAW_CURSOR 1008 +#define IDC_RAD_MODEL_QUALITY_LOW 1010 +#define IDC_RAD_MODEL_QUALITY_HIGH 1011 +#define IDC_RAD_TEXTURE_QUALITY_LOW 1013 +#define IDC_RAD_TEXTURE_QUALITY_HIGH 1014 +#define IDC_CHK_JOYSTICK 1015 +#define IDC_GRP_ADVANCED 1017 +#define IDC_BTN_ADVANCED 1020 +#define IDC_BMP_SHARK 1023 +#define IDC_CHK_MUSIC 1024 + +#define IDB_SHARK 135 diff --git a/CONFIG/res/shark.bmp b/CONFIG/res/shark.bmp new file mode 100644 index 00000000..0829a1d1 Binary files /dev/null and b/CONFIG/res/shark.bmp differ diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index be3f6bba..0fd02023 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -2,13 +2,16 @@ #include // for vsprintf +#if !defined(MXDIRECTX_FOR_CONFIG) DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4); DECOMP_SIZE_ASSERT(MxDirect3D, 0x894); +#endif DECOMP_SIZE_ASSERT(MxDevice, 0x1a4); DECOMP_SIZE_ASSERT(MxDisplayMode, 0x0c); DECOMP_SIZE_ASSERT(MxDriver, 0x190); DECOMP_SIZE_ASSERT(MxDeviceEnumerate, 0x14); +#if !defined(MXDIRECTX_FOR_CONFIG) // FUNCTION: LEGO1 0x1009b0a0 MxDirect3D::MxDirect3D() { @@ -332,7 +335,9 @@ MxAssignedDevice::~MxAssignedDevice() m_deviceInfo = NULL; } } +#endif +// FUNCTION: CONFIG 0x00401180 // FUNCTION: LEGO1 0x1009ba80 MxDriver::MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { @@ -344,6 +349,7 @@ MxDriver::MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) Init(p_guid, p_driverDesc, p_driverName); } +// FUNCTION: CONFIG 0x401280 // FUNCTION: LEGO1 0x1009bb80 MxDriver::~MxDriver() { @@ -358,6 +364,7 @@ MxDriver::~MxDriver() } } +// FUNCTION: CONFIG 0x00401330 // FUNCTION: LEGO1 0x1009bc30 void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { @@ -401,6 +408,7 @@ MxDevice::MxDevice( Init(p_guid, p_deviceDesc, p_deviceName, p_HWDesc, p_HELDesc); } +// FUNCTION: CONFIG 0x401460 // FUNCTION: LEGO1 0x1009bd60 MxDevice::~MxDevice() { @@ -458,12 +466,20 @@ void MxDevice::Init( } } +// FUNCTION: CONFIG 0x004015c0 // FUNCTION: LEGO1 0x1009bec0 MxDeviceEnumerate::MxDeviceEnumerate() { m_initialized = FALSE; } +// FUNCTION: CONFIG 0x401710 +// FUNCTION: LEGO1 0x1009c010 +MxDeviceEnumerate::~MxDeviceEnumerate() +{ +} + +// FUNCTION: CONFIG 0x00401770 // FUNCTION: LEGO1 0x1009c070 BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) { @@ -525,6 +541,7 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc return DDENUMRET_OK; } +// FUNCTION: CONFIG 0x00401bc0 // FUNCTION: LEGO1 0x1009c4c0 void MxDeviceEnumerate::BuildErrorString(const char* p_format, ...) { @@ -538,6 +555,7 @@ void MxDeviceEnumerate::BuildErrorString(const char* p_format, ...) OutputDebugString(buf); } +// FUNCTION: CONFIG 0x00401bf0 // FUNCTION: LEGO1 0x1009c4f0 HRESULT CALLBACK MxDeviceEnumerate::DisplayModesEnumerateCallback(LPDDSURFACEDESC p_ddsd, LPVOID p_context) { @@ -545,6 +563,7 @@ HRESULT CALLBACK MxDeviceEnumerate::DisplayModesEnumerateCallback(LPDDSURFACEDES return deviceEnumerate->EnumDisplayModesCallback(p_ddsd); } +// FUNCTION: CONFIG 0x00401c10 // FUNCTION: LEGO1 0x1009c510 HRESULT CALLBACK MxDeviceEnumerate::DevicesEnumerateCallback( LPGUID p_guid, @@ -559,6 +578,7 @@ HRESULT CALLBACK MxDeviceEnumerate::DevicesEnumerateCallback( return deviceEnumerate->EnumDevicesCallback(p_guid, p_deviceDesc, p_deviceName, p_HWDesc, p_HELDesc); } +// FUNCTION: CONFIG 0x00401c40 // FUNCTION: LEGO1 0x1009c540 HRESULT MxDeviceEnumerate::EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd) { @@ -571,6 +591,7 @@ HRESULT MxDeviceEnumerate::EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd) return DDENUMRET_OK; } +// FUNCTION: CONFIG 0x00401cd0 // FUNCTION: LEGO1 0x1009c5d0 HRESULT MxDeviceEnumerate::EnumDevicesCallback( LPGUID p_guid, @@ -586,6 +607,7 @@ HRESULT MxDeviceEnumerate::EnumDevicesCallback( return DDENUMRET_OK; } +// FUNCTION: CONFIG 0x00401dc0 // FUNCTION: LEGO1 0x1009c6c0 int MxDeviceEnumerate::DoEnumerate() { @@ -603,6 +625,7 @@ int MxDeviceEnumerate::DoEnumerate() return 0; } +// FUNCTION: CONFIG 0x00401e10 // FUNCTION: LEGO1 0x1009c710 BOOL CALLBACK MxDeviceEnumerate::DirectDrawEnumerateCallback(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName, LPVOID p_context) @@ -611,6 +634,7 @@ MxDeviceEnumerate::DirectDrawEnumerateCallback(LPGUID p_guid, LPSTR p_driverDesc return deviceEnumerate->EnumDirectDrawCallback(p_guid, p_driverDesc, p_driverName); } +// FUNCTION: CONFIG 0x00401e30 // FUNCTION: LEGO1 0x1009c730 const char* MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) { @@ -815,6 +839,7 @@ const char* MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) } } +// FUNCTION: CONFIG 0x00402560 // FUNCTION: LEGO1 0x1009ce60 int MxDeviceEnumerate::ParseDeviceName(const char* p_deviceId) { @@ -844,6 +869,7 @@ int MxDeviceEnumerate::ParseDeviceName(const char* p_deviceId) return result; } +// FUNCTION: CONFIG 0x00402620 // FUNCTION: LEGO1 0x1009cf20 int MxDeviceEnumerate::ProcessDeviceBytes(int p_deviceNum, GUID& p_guid) { @@ -891,6 +917,7 @@ int MxDeviceEnumerate::ProcessDeviceBytes(int p_deviceNum, GUID& p_guid) return -1; } +// FUNCTION: CONFIG 0x00402730 // FUNCTION: LEGO1 0x1009d030 int MxDeviceEnumerate::GetDevice(int p_deviceNum, MxDriver*& p_driver, MxDevice*& p_device) { @@ -915,6 +942,31 @@ int MxDeviceEnumerate::GetDevice(int p_deviceNum, MxDriver*& p_driver, MxDevice* return -1; } +#if defined(MXDIRECTX_FOR_CONFIG) +// FUNCTION: CONFIG 0x004027d0 +int MxDeviceEnumerate::FormatDeviceName(char* p_buffer, const MxDriver* p_driver, const MxDevice* p_device) const +{ + int number = 0; + for (list::const_iterator it = m_list.begin(); it != m_list.end(); it++) { + if (&(*it) == p_driver) { + sprintf( + p_buffer, + "%d 0x%x 0x%x 0x%x 0x%x", + number, + ((DWORD*) (p_device->m_guid))[0], + ((DWORD*) (p_device->m_guid))[1], + ((DWORD*) (p_device->m_guid))[2], + ((DWORD*) (p_device->m_guid))[3] + ); + return 0; + } + number++; + } + return -1; +} +#endif + +// FUNCTION: CONFIG 0x00402860 // FUNCTION: LEGO1 0x1009d0d0 int MxDeviceEnumerate::FUN_1009d0d0() { @@ -951,17 +1003,18 @@ int MxDeviceEnumerate::FUN_1009d0d0() i++; } - - return -1; } +// FUNCTION: CONFIG 0x00402930 // FUNCTION: LEGO1 0x1009d1a0 int MxDeviceEnumerate::SupportsMMX() { - int supports_mmx = SupportsCPUID(); - if (supports_mmx) { + if (!SupportsCPUID()) { + return 0; + } + int supports_mmx; #ifdef _MSC_VER - __asm { + __asm { mov eax, 0x0 ; EAX=0: Highest Function Parameter and Manufacturer ID #if _MSC_VER > 1100 cpuid ; Run CPUID @@ -980,22 +1033,22 @@ int MxDeviceEnumerate::SupportsMMX() 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 } +#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 int MxDeviceEnumerate::SupportsCPUID() { @@ -1027,6 +1080,7 @@ int MxDeviceEnumerate::SupportsCPUID() return has_cpuid; } +// FUNCTION: CONFIG 0x004029a0 // FUNCTION: LEGO1 0x1009d210 int MxDeviceEnumerate::FUN_1009d210() { @@ -1037,7 +1091,7 @@ int MxDeviceEnumerate::FUN_1009d210() for (list::iterator it = m_list.begin(); it != m_list.end();) { MxDriver& driver = *it; - if (!FUN_1009d370(driver)) { + if (!DriverSupportsRequiredDisplayMode(driver)) { m_list.erase(it++); } else { @@ -1064,8 +1118,9 @@ int MxDeviceEnumerate::FUN_1009d210() return m_list.empty() ? -1 : 0; } +// FUNCTION: CONFIG 0x00402b00 // FUNCTION: LEGO1 0x1009d370 -unsigned char MxDeviceEnumerate::FUN_1009d370(MxDriver& p_driver) +unsigned char MxDeviceEnumerate::DriverSupportsRequiredDisplayMode(MxDriver& p_driver) { for (list::iterator it = p_driver.m_displayModes.begin(); it != p_driver.m_displayModes.end(); it++) { @@ -1079,6 +1134,7 @@ unsigned char MxDeviceEnumerate::FUN_1009d370(MxDriver& p_driver) return FALSE; } +// FUNCTION: CONFIG 0x00402b60 // FUNCTION: LEGO1 0x1009d3d0 unsigned char MxDeviceEnumerate::FUN_1009d3d0(MxDevice& p_device) { @@ -1087,7 +1143,8 @@ unsigned char MxDeviceEnumerate::FUN_1009d3d0(MxDevice& p_device) } if (p_device.m_HWDesc.dcmColorModel) { - return p_device.m_HWDesc.dwDeviceZBufferBitDepth & DDBD_16 && p_device.m_HWDesc.dpcTriCaps.dwTextureCaps & 1; + return p_device.m_HWDesc.dwDeviceZBufferBitDepth & DDBD_16 && + p_device.m_HWDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE; } for (list::iterator it = m_list.front().m_devices.begin(); it != m_list.front().m_devices.end(); it++) { diff --git a/LEGO1/mxdirectx/mxdirect3d.h b/LEGO1/mxdirectx/mxdirect3d.h index e884c741..77d769b8 100644 --- a/LEGO1/mxdirectx/mxdirect3d.h +++ b/LEGO1/mxdirectx/mxdirect3d.h @@ -7,6 +7,7 @@ #include +#if !defined(MXDIRECTX_FOR_CONFIG) class MxDirect3D; // SIZE 0xe4 @@ -76,6 +77,7 @@ private: BOOL m_unk0x88c; // 0x88c undefined4 m_unk0x890; // 0x890 }; +#endif // SIZE 0x1a4 struct MxDevice { @@ -137,36 +139,45 @@ struct MxDriver { }; // clang-format off +// TEMPLATE: CONFIG 0x401000 // TEMPLATE: LEGO1 0x1009b900 // list >::~list > // clang-format on // clang-format off +// TEMPLATE: CONFIG 0x401070 // TEMPLATE: LEGO1 0x1009b970 // list >::~list > // clang-format on +// TEMPLATE: CONFIG 0x4010e0 // TEMPLATE: LEGO1 0x1009b9e0 // List::~List +// TEMPLATE: CONFIG 0x401130 // TEMPLATE: LEGO1 0x1009ba30 // List::~List // clang-format off +// TEMPLATE: CONFIG 0x401650 // TEMPLATE: LEGO1 0x1009bf50 // list >::~list > // clang-format on +// TEMPLATE: CONFIG 0x4016c0 // TEMPLATE: LEGO1 0x1009bfc0 // List::~List // Compiler-generated copy ctor +// SYNTHETIC: CONFIG 0x401990 // SYNTHETIC: LEGO1 0x1009c290 // MxDriver::MxDriver +// SYNTHETIC: CONFIG 0x401b00 // SYNTHETIC: LEGO1 0x1009c400 // list >::insert +// SYNTHETIC: CONFIG 0x401b60 // SYNTHETIC: LEGO1 0x1009c460 // list >::insert @@ -176,13 +187,13 @@ struct MxDriver { // SYNTHETIC: LEGO1 0x1009d470 // MxDevice::`scalar deleting destructor' +// VTABLE: CONFIG 0x00406000 // VTABLE: LEGO1 0x100db814 // SIZE 0x14 class MxDeviceEnumerate { public: MxDeviceEnumerate(); - // FUNCTION: LEGO1 0x1009c010 - ~MxDeviceEnumerate() {} + ~MxDeviceEnumerate(); virtual int DoEnumerate(); // vtable+0x00 @@ -199,9 +210,14 @@ public: int ParseDeviceName(const char* p_deviceId); int ProcessDeviceBytes(int p_deviceNum, GUID& p_guid); int GetDevice(int p_deviceNum, MxDriver*& p_driver, MxDevice*& p_device); + +#if defined(MXDIRECTX_FOR_CONFIG) + int FormatDeviceName(char* p_buffer, const MxDriver* p_driver, const MxDevice* p_device) const; +#endif + int FUN_1009d0d0(); int FUN_1009d210(); - unsigned char FUN_1009d370(MxDriver& p_driver); + unsigned char DriverSupportsRequiredDisplayMode(MxDriver& p_driver); unsigned char FUN_1009d3d0(MxDevice& p_device); static void BuildErrorString(const char*, ...); @@ -221,6 +237,8 @@ public: friend class MxDirect3D; + const list& GetDriverList() const { return m_list; } + private: list m_list; // 0x04 unsigned char m_initialized; // 0x10 diff --git a/LEGO1/mxdirectx/mxdirectdraw.cpp b/LEGO1/mxdirectx/mxdirectdraw.cpp index 7b64afe3..0e31e8d1 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.cpp +++ b/LEGO1/mxdirectx/mxdirectdraw.cpp @@ -911,208 +911,208 @@ const char* MxDirectDraw::ErrorToString(HRESULT p_error) { switch (p_error) { case DD_OK: - return "No error.\0"; + return "No error."; case DDERR_ALREADYINITIALIZED: - return "This object is already initialized.\0"; + return "This object is already initialized."; case DDERR_BLTFASTCANTCLIP: - return "Return if a clipper object is attached to the source surface passed into a BltFast call.\0"; + return "Return if a clipper object is attached to the source surface passed into a BltFast call."; case DDERR_CANNOTATTACHSURFACE: - return "This surface can not be attached to the requested surface.\0"; + return "This surface can not be attached to the requested surface."; case DDERR_CANNOTDETACHSURFACE: - return "This surface can not be detached from the requested surface.\0"; + return "This surface can not be detached from the requested surface."; case DDERR_CANTCREATEDC: - return "Windows can not create any more DCs.\0"; + return "Windows can not create any more DCs."; case DDERR_CANTDUPLICATE: - return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.\0"; + return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created."; case DDERR_CLIPPERISUSINGHWND: - return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.\0"; + return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd."; case DDERR_COLORKEYNOTSET: - return "No src color key specified for this operation.\0"; + return "No src color key specified for this operation."; case DDERR_CURRENTLYNOTAVAIL: - return "Support is currently not available.\0"; + return "Support is currently not available."; case DDERR_DIRECTDRAWALREADYCREATED: - return "A DirectDraw object representing this driver has already been created for this process.\0"; + return "A DirectDraw object representing this driver has already been created for this process."; case DDERR_EXCEPTION: - return "An exception was encountered while performing the requested operation.\0"; + return "An exception was encountered while performing the requested operation."; case DDERR_EXCLUSIVEMODEALREADYSET: - return "An attempt was made to set the cooperative level when it was already set to exclusive.\0"; + return "An attempt was made to set the cooperative level when it was already set to exclusive."; case DDERR_GENERIC: - return "Generic failure.\0"; + return "Generic failure."; case DDERR_HEIGHTALIGN: - return "Height of rectangle provided is not a multiple of reqd alignment.\0"; + return "Height of rectangle provided is not a multiple of reqd alignment."; case DDERR_HWNDALREADYSET: return "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or " - "palettes created.\0"; + "palettes created."; case DDERR_HWNDSUBCLASSED: return "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring " - "state.\0"; + "state."; case DDERR_IMPLICITLYCREATED: - return "This surface can not be restored because it is an implicitly created surface.\0"; + return "This surface can not be restored because it is an implicitly created surface."; case DDERR_INCOMPATIBLEPRIMARY: - return "Unable to match primary surface creation request with existing primary surface.\0"; + return "Unable to match primary surface creation request with existing primary surface."; case DDERR_INVALIDCAPS: - return "One or more of the caps bits passed to the callback are incorrect.\0"; + return "One or more of the caps bits passed to the callback are incorrect."; case DDERR_INVALIDCLIPLIST: - return "DirectDraw does not support the provided cliplist.\0"; + return "DirectDraw does not support the provided cliplist."; case DDERR_INVALIDDIRECTDRAWGUID: - return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.\0"; + return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier."; case DDERR_INVALIDMODE: - return "DirectDraw does not support the requested mode.\0"; + return "DirectDraw does not support the requested mode."; case DDERR_INVALIDOBJECT: - return "DirectDraw received a pointer that was an invalid DIRECTDRAW object.\0"; + return "DirectDraw received a pointer that was an invalid DIRECTDRAW object."; case DDERR_INVALIDPARAMS: - return "One or more of the parameters passed to the function are incorrect.\0"; + return "One or more of the parameters passed to the function are incorrect."; case DDERR_INVALIDPIXELFORMAT: - return "The pixel format was invalid as specified.\0"; + return "The pixel format was invalid as specified."; case DDERR_INVALIDPOSITION: return "Returned when the position of the overlay on the destination is no longer legal for that " - "destination.\0"; + "destination."; case DDERR_INVALIDRECT: - return "Rectangle provided was invalid.\0"; + return "Rectangle provided was invalid."; case DDERR_LOCKEDSURFACES: - return "Operation could not be carried out because one or more surfaces are locked.\0"; + return "Operation could not be carried out because one or more surfaces are locked."; case DDERR_NO3D: - return "There is no 3D present.\0"; + return "There is no 3D present."; case DDERR_NOALPHAHW: return "Operation could not be carried out because there is no alpha accleration hardware present or " - "available.\0"; + "available."; case DDERR_NOBLTHW: - return "No blitter hardware present.\0"; + return "No blitter hardware present."; case DDERR_NOCLIPLIST: - return "No cliplist available.\0"; + return "No cliplist available."; case DDERR_NOCLIPPERATTACHED: - return "No clipper object attached to surface object.\0"; + return "No clipper object attached to surface object."; case DDERR_NOCOLORCONVHW: return "Operation could not be carried out because there is no color conversion hardware present or " - "available.\0"; + "available."; case DDERR_NOCOLORKEY: - return "Surface doesn't currently have a color key\0"; + return "Surface doesn't currently have a color key"; case DDERR_NOCOLORKEYHW: return "Operation could not be carried out because there is no hardware support of the destination color " - "key.\0"; + "key."; case DDERR_NOCOOPERATIVELEVELSET: - return "Create function called without DirectDraw object method SetCooperativeLevel being called.\0"; + return "Create function called without DirectDraw object method SetCooperativeLevel being called."; case DDERR_NODC: - return "No DC was ever created for this surface.\0"; + return "No DC was ever created for this surface."; case DDERR_NODDROPSHW: - return "No DirectDraw ROP hardware.\0"; + return "No DirectDraw ROP hardware."; case DDERR_NODIRECTDRAWHW: return "A hardware-only DirectDraw object creation was attempted but the driver did not support any " - "hardware.\0"; + "hardware."; case DDERR_NOEMULATION: - return "Software emulation not available.\0"; + return "Software emulation not available."; case DDERR_NOEXCLUSIVEMODE: return "Operation requires the application to have exclusive mode but the application does not have exclusive " - "mode.\0"; + "mode."; case DDERR_NOFLIPHW: - return "Flipping visible surfaces is not supported.\0"; + return "Flipping visible surfaces is not supported."; case DDERR_NOGDI: - return "There is no GDI present.\0"; + return "There is no GDI present."; case DDERR_NOHWND: return "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel " - "HWND.\0"; + "HWND."; case DDERR_NOMIRRORHW: - return "Operation could not be carried out because there is no hardware present or available.\0"; + return "Operation could not be carried out because there is no hardware present or available."; case DDERR_NOOVERLAYDEST: return "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on " - "to establish a destination.\0"; + "to establish a destination."; case DDERR_NOOVERLAYHW: - return "Operation could not be carried out because there is no overlay hardware present or available.\0"; + return "Operation could not be carried out because there is no overlay hardware present or available."; case DDERR_NOPALETTEATTACHED: - return "No palette object attached to this surface.\0"; + return "No palette object attached to this surface."; case DDERR_NOPALETTEHW: - return "No hardware support for 16 or 256 color palettes.\0"; + return "No hardware support for 16 or 256 color palettes."; case DDERR_NORASTEROPHW: return "Operation could not be carried out because there is no appropriate raster op hardware present or " - "available.\0"; + "available."; case DDERR_NOROTATIONHW: - return "Operation could not be carried out because there is no rotation hardware present or available.\0"; + return "Operation could not be carried out because there is no rotation hardware present or available."; case DDERR_NOSTRETCHHW: - return "Operation could not be carried out because there is no hardware support for stretching.\0"; + return "Operation could not be carried out because there is no hardware support for stretching."; case DDERR_NOT4BITCOLOR: return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color " - "palette.\0"; + "palette."; case DDERR_NOT4BITCOLORINDEX: return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color " - "index palette.\0"; + "index palette."; case DDERR_NOT8BITCOLOR: - return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.\0"; + return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color."; case DDERR_NOTAOVERLAYSURFACE: - return "Returned when an overlay member is called for a non-overlay surface.\0"; + return "Returned when an overlay member is called for a non-overlay surface."; case DDERR_NOTEXTUREHW: return "Operation could not be carried out because there is no texture mapping hardware present or " - "available.\0"; + "available."; case DDERR_NOTFLIPPABLE: - return "An attempt has been made to flip a surface that is not flippable.\0"; + return "An attempt has been made to flip a surface that is not flippable."; case DDERR_NOTFOUND: - return "Requested item was not found.\0"; + return "Requested item was not found."; case DDERR_NOTLOCKED: return "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this " - "process, has been attempted.\0"; + "process, has been attempted."; case DDERR_NOTPALETTIZED: - return "The surface being used is not a palette-based surface.\0"; + return "The surface being used is not a palette-based surface."; case DDERR_NOVSYNCHW: return "Operation could not be carried out because there is no hardware support for vertical blank " - "synchronized operations.\0"; + "synchronized operations."; case DDERR_NOZBUFFERHW: - return "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0"; + return "Operation could not be carried out because there is no hardware support for zbuffer blitting."; case DDERR_NOZOVERLAYHW: return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support " - "z layering of overlays.\0"; + "z layering of overlays."; case DDERR_OUTOFCAPS: - return "The hardware needed for the requested operation has already been allocated.\0"; + return "The hardware needed for the requested operation has already been allocated."; case DDERR_OUTOFMEMORY: - return "DirectDraw does not have enough memory to perform the operation.\0"; + return "DirectDraw does not have enough memory to perform the operation."; case DDERR_OUTOFVIDEOMEMORY: - return "DirectDraw does not have enough memory to perform the operation.\0"; + return "DirectDraw does not have enough memory to perform the operation."; case DDERR_OVERLAYCANTCLIP: - return "The hardware does not support clipped overlays.\0"; + return "The hardware does not support clipped overlays."; case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: - return "Can only have ony color key active at one time for overlays.\0"; + return "Can only have ony color key active at one time for overlays."; case DDERR_OVERLAYNOTVISIBLE: - return "Returned when GetOverlayPosition is called on a hidden overlay.\0"; + return "Returned when GetOverlayPosition is called on a hidden overlay."; case DDERR_PALETTEBUSY: - return "Access to this palette is being refused because the palette is already locked by another thread.\0"; + return "Access to this palette is being refused because the palette is already locked by another thread."; case DDERR_PRIMARYSURFACEALREADYEXISTS: - return "This process already has created a primary surface.\0"; + return "This process already has created a primary surface."; case DDERR_REGIONTOOSMALL: - return "Region passed to Clipper::GetClipList is too small.\0"; + return "Region passed to Clipper::GetClipList is too small."; case DDERR_SURFACEALREADYATTACHED: - return "This surface is already attached to the surface it is being attached to.\0"; + return "This surface is already attached to the surface it is being attached to."; case DDERR_SURFACEALREADYDEPENDENT: - return "This surface is already a dependency of the surface it is being made a dependency of.\0"; + return "This surface is already a dependency of the surface it is being made a dependency of."; case DDERR_SURFACEBUSY: - return "Access to this surface is being refused because the surface is already locked by another thread.\0"; + return "Access to this surface is being refused because the surface is already locked by another thread."; case DDERR_SURFACEISOBSCURED: - return "Access to surface refused because the surface is obscured.\0"; + return "Access to surface refused because the surface is obscured."; case DDERR_SURFACELOST: return "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface " - "object representing this surface should have Restore called on it.\0"; + "object representing this surface should have Restore called on it."; case DDERR_SURFACENOTATTACHED: - return "The requested surface is not attached.\0"; + return "The requested surface is not attached."; case DDERR_TOOBIGHEIGHT: - return "Height requested by DirectDraw is too large.\0"; + return "Height requested by DirectDraw is too large."; case DDERR_TOOBIGSIZE: - return "Size requested by DirectDraw is too large, but the individual height and width are OK.\0"; + return "Size requested by DirectDraw is too large, but the individual height and width are OK."; case DDERR_TOOBIGWIDTH: - return "Width requested by DirectDraw is too large.\0"; + return "Width requested by DirectDraw is too large."; case DDERR_UNSUPPORTED: - return "Action not supported.\0"; + return "Action not supported."; case DDERR_UNSUPPORTEDFORMAT: - return "FOURCC format requested is unsupported by DirectDraw.\0"; + return "FOURCC format requested is unsupported by DirectDraw."; case DDERR_UNSUPPORTEDMASK: - return "Bitmask in the pixel format requested is unsupported by DirectDraw.\0"; + return "Bitmask in the pixel format requested is unsupported by DirectDraw."; case DDERR_VERTICALBLANKINPROGRESS: - return "Vertical blank is in progress.\0"; + return "Vertical blank is in progress."; case DDERR_WASSTILLDRAWING: return "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is " - "incomplete.\0"; + "incomplete."; case DDERR_WRONGMODE: - return "This surface can not be restored because it was created in a different mode.\0"; + return "This surface can not be restored because it was created in a different mode."; case DDERR_XALIGN: - return "Rectangle provided was not horizontally aligned on required boundary.\0"; + return "Rectangle provided was not horizontally aligned on required boundary."; default: - return "Unrecognized error value.\0"; + return "Unrecognized error value."; } } diff --git a/LEGO1/mxdirectx/mxstopwatch.h b/LEGO1/mxdirectx/mxstopwatch.h index 0630d2f6..5a86b283 100644 --- a/LEGO1/mxdirectx/mxstopwatch.h +++ b/LEGO1/mxdirectx/mxstopwatch.h @@ -3,6 +3,7 @@ #include "assert.h" +#include // ULONG_MAX #include #include diff --git a/tools/decomplint/decomplint.py b/tools/decomplint/decomplint.py old mode 100644 new mode 100755 index 2ceb42c2..cfe9155b --- a/tools/decomplint/decomplint.py +++ b/tools/decomplint/decomplint.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import os import sys import argparse @@ -92,8 +94,9 @@ def main(): would_fail = error_count > 0 or (warning_count > 0 and args.warnfail) if would_fail: - sys.exit(1) + return 1 + return 0 if __name__ == "__main__": - main() + raise SystemExit(main()) diff --git a/tools/patch_c2.py b/tools/patch_c2.py old mode 100644 new mode 100755 diff --git a/tools/reccmp/config.png b/tools/reccmp/config.png new file mode 100644 index 00000000..1f2050ad Binary files /dev/null and b/tools/reccmp/config.png differ diff --git a/tools/vtable/vtable.py b/tools/vtable/vtable.py old mode 100644 new mode 100755 index bdee080b..2c47d1d5 --- a/tools/vtable/vtable.py +++ b/tools/vtable/vtable.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import os import argparse import logging