From 196259c6c982426c2b9f3d4e02012655b9814ad7 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 26 Jun 2024 20:24:40 +0200 Subject: [PATCH] Parse cli arguments + log with SDL_Log (#30) * cmake: copy DLL dependencies to output path This also copies SDL3.dll from an external path when using system dependencies. * Only include * isle: parse cli argument (--ini for custom ini path) * Use SDL_CreateWIndowWithProperties to create SDL window Less branching => Clearer code * Log mxdirectx failure using SDL_Log + E_NOINTERFACE * Fix d3drm32.def for msvc * Define D3DRM_WINE when using d3drm from wine * Ignore failed assertions from d3drm unimplemented functions * inparser will/should create libiniparser.lib for static libraries and iniparser.lib for a shared library --- 3rdparty/d3drm/CMakeLists.txt | 6 +- 3rdparty/d3drm/{d3drm64.def => d3drm.def} | 2 + 3rdparty/d3drm/d3drm32.def | 22 ------- CMakeLists.txt | 6 ++ ISLE/isleapp.cpp | 65 ++++++++++++++++----- ISLE/isleapp.h | 4 ++ LEGO1/lego/sources/3dmanager/tglsurface.cpp | 25 +++++++- LEGO1/mxdirectx/mxdirect3d.cpp | 11 ++-- LEGO1/tgl/d3drm/impl.h | 2 +- cmake/Findiniparser.cmake | 4 +- 10 files changed, 97 insertions(+), 50 deletions(-) rename 3rdparty/d3drm/{d3drm64.def => d3drm.def} (89%) delete mode 100644 3rdparty/d3drm/d3drm32.def diff --git a/3rdparty/d3drm/CMakeLists.txt b/3rdparty/d3drm/CMakeLists.txt index 3ef12866..8db17833 100644 --- a/3rdparty/d3drm/CMakeLists.txt +++ b/3rdparty/d3drm/CMakeLists.txt @@ -45,12 +45,8 @@ add_library(d3drm-wine SHARED texture.c version.rc viewport.c + d3drm.def ) -if(CMAKE_SIZEOF_VOID_P EQUAL 4) - target_sources(d3drm-wine PRIVATE d3drm32.def) -else() - target_sources(d3drm-wine PRIVATE d3drm64.def) -endif() if(WINE_D3DRM_DYNAMIC_D3DXOF) target_sources(d3drm-wine PRIVATE dyn_d3dxof.c dyn_d3dxof.h) target_compile_definitions(d3drm-wine PRIVATE DYNAMIC_D3DXOF) diff --git a/3rdparty/d3drm/d3drm64.def b/3rdparty/d3drm/d3drm.def similarity index 89% rename from 3rdparty/d3drm/d3drm64.def rename to 3rdparty/d3drm/d3drm.def index 31aec2dc..f8c0a465 100644 --- a/3rdparty/d3drm/d3drm64.def +++ b/3rdparty/d3drm/d3drm.def @@ -20,3 +20,5 @@ EXPORTS D3DRMVectorScale D3DRMVectorSubtract Direct3DRMCreate + ; DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE \ No newline at end of file diff --git a/3rdparty/d3drm/d3drm32.def b/3rdparty/d3drm/d3drm32.def deleted file mode 100644 index ae143f3e..00000000 --- a/3rdparty/d3drm/d3drm32.def +++ /dev/null @@ -1,22 +0,0 @@ -EXPORTS - D3DRMColorGetAlpha@4 - D3DRMColorGetBlue@4 - D3DRMColorGetGreen@4 - D3DRMColorGetRed@4 - D3DRMCreateColorRGB@12 - D3DRMCreateColorRGBA@16 - D3DRMMatrixFromQuaternion@8 - D3DRMQuaternionFromRotation@12 - D3DRMQuaternionMultiply@12 - D3DRMQuaternionSlerp@16 - D3DRMVectorAdd@12 - D3DRMVectorCrossProduct@12 - D3DRMVectorDotProduct@8 - D3DRMVectorModulus@4 - D3DRMVectorNormalize@4 - D3DRMVectorRandom@4 - D3DRMVectorReflect@12 - D3DRMVectorRotate@16 - D3DRMVectorScale@12 - D3DRMVectorSubtract@12 - Direct3DRMCreate@4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d2fd5c7..d47be918 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -470,6 +470,7 @@ foreach(tgt IN LISTS lego1_targets) target_include_directories(${tgt} PRIVATE $<$:$>) target_link_libraries(${tgt} PRIVATE $<$:DirectX5::DirectX5> SDL3::SDL3) target_compile_definitions(${tgt} PRIVATE $<$:DIRECTX5_SDK>) + target_compile_definitions(${tgt} PRIVATE $<$:D3DRM_WINE>) endforeach() # Make sure filenames are ALL CAPS @@ -482,6 +483,10 @@ if (ISLE_BUILD_APP) ISLE/res/isle.rc ISLE/isleapp.cpp ) + add_custom_command(TARGET isle POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy $ "$" + COMMAND_EXPAND_LISTS + ) target_compile_definitions(isle PRIVATE ISLE_APP) @@ -518,6 +523,7 @@ if (ISLE_BUILD_CONFIG) target_link_libraries(config PRIVATE DirectX5::DirectX5) endif() target_compile_definitions(config PRIVATE DIRECT3D_VERSION=0x500) + target_link_libraries(config PRIVATE SDL3::SDL3) target_link_libraries(config PRIVATE ddraw dxguid) set_property(TARGET config PROPERTY OUTPUT_NAME "CONFIG") set_property(TARGET config PROPERTY SUFFIX ".EXE") diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index b6c62300..f365a6db 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -30,11 +30,8 @@ #include "viewmanager/viewmanager.h" #define SDL_MAIN_USE_CALLBACKS -#include -#include +#include #include -#include -#include #include #include @@ -116,6 +113,8 @@ IsleApp::IsleApp() m_cursorCurrent = NULL; LegoOmni::CreateInstance(); + + m_iniPath = NULL; } // FUNCTION: ISLE 0x4011a0 @@ -254,6 +253,16 @@ int SDL_AppInit(void** appstate, int argc, char** argv) // Create global app instance g_isle = new IsleApp(); + if (g_isle->ParseArguments(argc, argv) != SUCCESS) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "LEGO® Island Error", + "\"LEGO® Island\" failed to start. Invalid CLI arguments.", + NULL + ); + return SDL_APP_FAILURE; + } + // Create window if (g_isle->SetupWindow() != SUCCESS) { SDL_ShowSimpleMessageBox( @@ -449,12 +458,15 @@ MxResult IsleApp::SetupWindow() m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED); SDL_SetCursor(m_cursorCurrent); - if (m_fullScreen) { - m_windowHandle = SDL_CreateWindow(WINDOW_TITLE, g_targetWidth, g_targetHeight, SDL_WINDOW_FULLSCREEN); - } - else { - m_windowHandle = SDL_CreateWindow(WINDOW_TITLE, g_targetWidth, g_targetHeight, 0); - } + SDL_PropertiesID props = SDL_CreateProperties(); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, g_targetWidth); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, g_targetHeight); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, m_fullScreen); + SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, WINDOW_TITLE); + + m_windowHandle = SDL_CreateWindowWithProperties(props); + + SDL_DestroyProperties(props); if (!m_windowHandle) { return FAILURE; @@ -502,9 +514,18 @@ void IsleApp::LoadConfig() { char* basePath = SDL_GetBasePath(); char* prefPath = SDL_GetPrefPath("isledecomp", "isle"); - char* iniConfig = new char[strlen(prefPath) + strlen("isle.ini") + 1](); - strcat(iniConfig, prefPath); - strcat(iniConfig, "isle.ini"); + char* iniConfig; + if (m_iniPath) { + iniConfig = new char[strlen(m_iniPath) + 1]; + strcpy(iniConfig, m_iniPath); + } + else { + iniConfig = new char[strlen(prefPath) + strlen("isle.ini") + 1](); + strcat(iniConfig, prefPath); + strcat(iniConfig, "isle.ini"); + } + SDL_Log("Reading configuration from \"%s\"", iniConfig); + dictionary* dict = iniparser_load(iniConfig); const char* hdPath = iniparser_getstring(dict, "isle:diskpath", basePath); @@ -677,3 +698,21 @@ void IsleApp::SetupCursor(Cursor p_cursor) SDL_HideCursor(); } } + +MxResult IsleApp::ParseArguments(int argc, char** argv) +{ + + for (int i = 1, consumed; i < argc; i += consumed) { + consumed = -1; + + if (strcmp(argv[i], "--ini") == 0 && i + 1 < argc) { + m_iniPath = argv[i + 1]; + consumed = 2; + } + if (consumed <= 0) { + SDL_Log("Invalid argument(s): %s", argv[i]); + return FAILURE; + } + } + return SUCCESS; +} diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index 7acea89c..f8206e18 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -47,6 +47,8 @@ class IsleApp { inline void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; } + MxResult ParseArguments(int argc, char** argv); + private: char* m_hdPath; // 0x00 char* m_cdPath; // 0x04 @@ -75,6 +77,8 @@ class IsleApp { SDL_Cursor* m_cursorBusy; // 0x80 SDL_Cursor* m_cursorNo; // 0x84 SDL_Cursor* m_cursorCurrent; // 0x88 + + char* m_iniPath; }; #endif // ISLEAPP_H diff --git a/LEGO1/lego/sources/3dmanager/tglsurface.cpp b/LEGO1/lego/sources/3dmanager/tglsurface.cpp index f03206d9..fef0d511 100644 --- a/LEGO1/lego/sources/3dmanager/tglsurface.cpp +++ b/LEGO1/lego/sources/3dmanager/tglsurface.cpp @@ -8,6 +8,25 @@ DECOMP_SIZE_ASSERT(TglSurface, 0x70); using namespace Tgl; +#ifdef D3DRM_WINE + +#include + +#define d3drm_wine_assert(COND) \ + do { \ + if (!(COND)) { \ + SDL_Log( \ + "%s:%d Assertion failed: \"%s\" (ignored because wine-d3d does not implement it)", \ + __FILE__, \ + __LINE__, \ + #COND \ + ); \ + } \ + } while (0) +#else +#define d3drm_wine_assert(X) assert(X) +#endif + ///////////////////////////////////////////////////////////////////////////// // TglSurface @@ -126,11 +145,11 @@ BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, if (textureShadeCount != -1) { result = pRenderer->SetTextureDefaultShadeCount(textureShadeCount); - assert(Succeeded(result)); + d3drm_wine_assert(Succeeded(result)); } if (textureColorCount != -1) { result = pRenderer->SetTextureDefaultColorCount(textureColorCount); - assert(Succeeded(result)); + d3drm_wine_assert(Succeeded(result)); } result = m_pDevice->SetColorModel(colorModel); @@ -138,7 +157,7 @@ BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, result = m_pDevice->SetShadingModel(shadingModel); assert(Succeeded(result)); result = m_pDevice->SetShadeCount(shadeCount); - assert(Succeeded(result)); + d3drm_wine_assert(Succeeded(result)); result = m_pDevice->SetDither(dither); assert(Succeeded(result)); diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index d1f23abd..bc27d68f 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -1,6 +1,7 @@ #include "mxdirect3d.h" -#include // for vsprintf +#include // for SDL_Log +#include // for vsprintf #if !defined(MXDIRECTX_FOR_CONFIG) DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4); @@ -176,7 +177,7 @@ BOOL MxDirect3D::D3DSetMode() backBuffer->Unlock(desc.lpSurface); } else { - OutputDebugString("MxDirect3D::D3DSetMode() back lock failed\n"); + SDL_Log("MxDirect3D::D3DSetMode() back lock failed\n"); } if (m_bFullScreen) { @@ -194,7 +195,7 @@ BOOL MxDirect3D::D3DSetMode() frontBuffer->Unlock(desc.lpSurface); } else { - OutputDebugString("MxDirect3D::D3DSetMode() front lock failed\n"); + SDL_Log("MxDirect3D::D3DSetMode() front lock failed\n"); } } @@ -550,7 +551,7 @@ void MxDeviceEnumerate::BuildErrorString(const char* p_format, ...) vsprintf(buf, p_format, args); va_end(args); - OutputDebugString(buf); + SDL_Log("%s", buf); } // FUNCTION: CONFIG 0x00401bf0 @@ -639,6 +640,8 @@ const char* MxDeviceEnumerate::EnumerateErrorToString(HRESULT p_error) switch (p_error) { case DD_OK: return "No error."; + case E_NOINTERFACE: + return "No such interface supported"; case DDERR_GENERIC: return "Generic failure."; case DDERR_UNSUPPORTED: diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index 413f7110..558671b4 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -5,7 +5,7 @@ #include -#ifdef DIRECTX5_SDK +#ifndef D3DRM_WINE typedef DWORD LPD3DRM_APPDATA; #else typedef LPVOID LPD3DRM_APPDATA; diff --git a/cmake/Findiniparser.cmake b/cmake/Findiniparser.cmake index 3b4e188c..18a7545c 100644 --- a/cmake/Findiniparser.cmake +++ b/cmake/Findiniparser.cmake @@ -1,6 +1,6 @@ if(WIN32) - set(__iniparser_shared_names "libiniparser.dll.a" "libiniparser.lib") - set(__iniparser_static_names "libiniparser.a" "iniparser.lib") + set(__iniparser_shared_names "libiniparser.dll.a" "iniparser.lib") + set(__iniparser_static_names "libiniparser.a" "libiniparser.lib") else() if(APPLE) set(__iniparser_shared_names "libiniparser.dylib")