From 4446aaaf53bc0119de9b931d3da59d93f3ec1403 Mon Sep 17 00:00:00 2001 From: olebeck <31539311+olebeck@users.noreply.github.com> Date: Wed, 9 Jul 2025 14:55:26 +0200 Subject: [PATCH 1/9] translate and scale touch coordinates to the viewport (#565) --- ISLE/isleapp.cpp | 3 +++ miniwin/src/d3drm/d3drmdevice.cpp | 24 +++++++++++++++++------- miniwin/src/internal/d3drmdevice_impl.h | 2 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 89743a51..2788b8a7 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -428,6 +428,9 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) case SDL_EVENT_MOUSE_MOTION: case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_FINGER_MOTION: + case SDL_EVENT_FINGER_DOWN: + case SDL_EVENT_FINGER_UP: IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice(); if (device && !device->ConvertEventToRenderCoordinates(event)) { SDL_Log("Failed to convert event coordinates: %s", SDL_GetError()); diff --git a/miniwin/src/d3drm/d3drmdevice.cpp b/miniwin/src/d3drm/d3drmdevice.cpp index bae67e94..9f517426 100644 --- a/miniwin/src/d3drm/d3drmdevice.cpp +++ b/miniwin/src/d3drm/d3drmdevice.cpp @@ -150,14 +150,13 @@ ViewportTransform CalculateViewportTransform(int virtualW, int virtualH, int win void Direct3DRMDevice2Impl::Resize() { - int width, height; - SDL_GetWindowSizeInPixels(DDWindow, &width, &height); + SDL_GetWindowSizeInPixels(DDWindow, &m_windowWidth, &m_windowHeight); #ifdef __3DS__ - width = 320; // We are on the lower screen - height = 240; + m_windowWidth = 320; // We are on the lower screen + m_windowHeight = 240; #endif - m_viewportTransform = CalculateViewportTransform(m_virtualWidth, m_virtualHeight, width, height); - m_renderer->Resize(width, height, m_viewportTransform); + m_viewportTransform = CalculateViewportTransform(m_virtualWidth, m_virtualHeight, m_windowWidth, m_windowHeight); + m_renderer->Resize(m_windowWidth, m_windowHeight, m_viewportTransform); m_renderer->Clear(0, 0, 0); for (int i = 0; i < m_viewports->GetSize(); i++) { IDirect3DRMViewport* viewport; @@ -183,7 +182,18 @@ bool Direct3DRMDevice2Impl::ConvertEventToRenderCoordinates(SDL_Event* event) event->motion.x = static_cast(x); event->motion.y = static_cast(y); break; - } break; + } + case SDL_EVENT_FINGER_MOTION: + case SDL_EVENT_FINGER_DOWN: + case SDL_EVENT_FINGER_UP: { + int rawX = event->tfinger.x * m_windowWidth; + int rawY = event->tfinger.y * m_windowHeight; + float x = (rawX - m_viewportTransform.offsetX) / m_viewportTransform.scale; + float y = (rawY - m_viewportTransform.offsetY) / m_viewportTransform.scale; + event->tfinger.x = x / m_virtualWidth; + event->tfinger.y = y / m_virtualHeight; + break; + } } return true; diff --git a/miniwin/src/internal/d3drmdevice_impl.h b/miniwin/src/internal/d3drmdevice_impl.h index daab564a..5679ce0d 100644 --- a/miniwin/src/internal/d3drmdevice_impl.h +++ b/miniwin/src/internal/d3drmdevice_impl.h @@ -40,6 +40,8 @@ struct Direct3DRMDevice2Impl : public Direct3DRMObjectBaseImpl Date: Thu, 10 Jul 2025 15:34:52 +0900 Subject: [PATCH 2/9] Add iOS Port (#566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat: add ios support * ⚗️ chore: trying some experiments to make ci working * ⚗️ chore: is it really ci version problem? * 💚 fix: it really is just a ci version issue * 🩹 fix: go as low as possible * 🩹 fix: support ipad --- .github/workflows/ci.yml | 1 + CMakeLists.txt | 17 +++- ISLE/ios/config.cpp | 25 +++++ ISLE/ios/config.h | 8 ++ ISLE/isleapp.cpp | 13 +++ packaging/CMakeLists.txt | 4 + packaging/ios/CMakeLists.txt | 52 +++++++++++ .../AppIcon.appiconset/AppIcon.png | Bin 0 -> 24327 bytes .../AppIcon.appiconset/Contents.json | 36 ++++++++ .../ios/isle/Assets.xcassets/Contents.json | 6 ++ packaging/ios/isle/Info.plist.in | 86 ++++++++++++++++++ packaging/ios/isle/LaunchScreen.storyboard | 48 ++++++++++ 12 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 ISLE/ios/config.cpp create mode 100644 ISLE/ios/config.h create mode 100644 packaging/ios/CMakeLists.txt create mode 100644 packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/AppIcon.png create mode 100644 packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 packaging/ios/isle/Assets.xcassets/Contents.json create mode 100644 packaging/ios/isle/Info.plist.in create mode 100644 packaging/ios/isle/LaunchScreen.storyboard diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 090b9e1f..1d3b5e5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,7 @@ jobs: - { name: 'msys2 mingw32', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' } - { name: 'msys2 mingw64', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' } - { name: 'macOS', os: 'macos-latest', generator: 'Ninja', dx5: false, config: true, brew: true, werror: true, clang-tidy: false } + - { name: 'iOS', os: 'macos-15', generator: 'Xcode', dx5: false, config: false, brew: true, werror: true, clang-tidy: false, cmake-args: '-DCMAKE_SYSTEM_NAME=iOS' } - { name: 'Emscripten', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: false, emsdk: true, werror: true, clang-tidy: false, cmake-wrapper: 'emcmake' } - { name: 'Nintendo 3DS', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: false, n3ds: true, werror: true, clang-tidy: false, container: 'devkitpro/devkitarm:latest', cmake-args: '-DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/3DS.cmake' } - { name: 'Xbox One', os: 'windows-latest', generator: 'Visual Studio 17 2022', dx5: false, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64', cmake-args: '-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.26100.0', xbox-one: true} diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f26a28b..70ddba15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,12 @@ cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR) project(isle LANGUAGES CXX C VERSION 0.1) +if (IOS) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED NO) + set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0") + add_compile_definitions(IOS) +endif() + if (WINDOWS_STORE) add_compile_definitions(WINDOWS_STORE) endif() @@ -551,6 +557,11 @@ if (ISLE_BUILD_APP) ISLE/xbox_one_series/config.cpp ) endif() + if (IOS) + target_sources(isle PRIVATE + ISLE/ios/config.cpp + ) + endif() if(Python3_FOUND) if(NOT DEFINED PYTHON_PIL_AVAILABLE) execute_process( @@ -803,8 +814,12 @@ if(WINDOWS_STORE) PATTERN "*/*.msix" PATTERN "*/*.msixbundle") endif() -if(MSVC) +if(MSVC OR IOS) set(CPACK_GENERATOR ZIP) + if(IOS) + set(CPACK_ARCHIVE_FILE_EXTENSION ".ipa") + set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) + endif() elseif(APPLE AND NOT IOS) set(CPACK_GENERATOR DragNDrop) else() diff --git a/ISLE/ios/config.cpp b/ISLE/ios/config.cpp new file mode 100644 index 00000000..ee9349fa --- /dev/null +++ b/ISLE/ios/config.cpp @@ -0,0 +1,25 @@ +#include "config.h" + +#include +#include +#include + +void IOS_SetupDefaultConfigOverrides(dictionary* p_dictionary) +{ + SDL_Log("Overriding default config for iOS"); + + // Use DevelopmentFiles path for disk and cd paths + // It's good to use that path since user can easily + // connect through SMB and copy the files + const char* documentFolder = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS); + char* diskPath = new char[strlen(documentFolder) + strlen("isle") + 1](); + strcpy(diskPath, documentFolder); + strcat(diskPath, "isle"); + + if (!SDL_GetPathInfo(diskPath, NULL)) { + SDL_CreateDirectory(diskPath); + } + + iniparser_set(p_dictionary, "isle:diskpath", diskPath); + iniparser_set(p_dictionary, "isle:cdpath", diskPath); +} diff --git a/ISLE/ios/config.h b/ISLE/ios/config.h new file mode 100644 index 00000000..53caf824 --- /dev/null +++ b/ISLE/ios/config.h @@ -0,0 +1,8 @@ +#ifndef IOS_CONFIG_H +#define IOS_CONFIG_H + +#include "dictionary.h" + +void IOS_SetupDefaultConfigOverrides(dictionary* p_dictionary); + +#endif // IOS_CONFIG_H diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 2788b8a7..f8f80e3a 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -63,6 +63,10 @@ #include "xbox_one_series/config.h" #endif +#ifdef IOS +#include "ios/config.h" +#endif + DECOMP_SIZE_ASSERT(IsleApp, 0x8c) // GLOBAL: ISLE 0x410030 @@ -917,7 +921,11 @@ MxResult IsleApp::SetupWindow() // FUNCTION: ISLE 0x4028d0 bool IsleApp::LoadConfig() { +#ifdef IOS + const char* prefPath = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS); +#else char* prefPath = SDL_GetPrefPath("isledecomp", "isle"); +#endif char* iniConfig; #ifdef __EMSCRIPTEN__ @@ -1000,6 +1008,9 @@ bool IsleApp::LoadConfig() #endif #ifdef WINDOWS_STORE XBONE_SetupDefaultConfigOverrides(dict); +#endif +#ifdef IOS + IOS_SetupDefaultConfigOverrides(dict); #endif iniparser_dump_ini(dict, iniFP); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "New config written at '%s'", iniConfig); @@ -1071,7 +1082,9 @@ bool IsleApp::LoadConfig() iniparser_freedict(dict); delete[] iniConfig; +#ifndef IOS SDL_free(prefPath); +#endif return true; } diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 1b178b63..6f5769e9 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -28,3 +28,7 @@ endif() if(APPLE AND NOT IOS) add_subdirectory(macos) endif() + +if(IOS) + add_subdirectory(ios) +endif() diff --git a/packaging/ios/CMakeLists.txt b/packaging/ios/CMakeLists.txt new file mode 100644 index 00000000..418ad518 --- /dev/null +++ b/packaging/ios/CMakeLists.txt @@ -0,0 +1,52 @@ +set(MACOSX_BUNDLE_GUI_IDENTIFIER ${APP_ID}) +set(MACOSX_BUNDLE_COPYRIGHT ${APP_SPDX}) +set(ISLE_TARGET_NAME isle) +set(MACOSX_ISLE_BUNDLE_NAME ${APP_NAME}) # Do note that it can be up to 15 characters long +set(MACOSX_ISLE_BUNDLE_DISPLAY_NAME ${APP_NAME}) +set(MACOSX_BUNDLE_INFO_STRING ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${PROJECT_VERSION}") +set(MACOSX_BUNDLE_REQUIRED_PLATFORM IPhoneOS) + +if(ISLE_BUILD_APP) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/isle/Info.plist.in" + "${CMAKE_CURRENT_BINARY_DIR}/isle/Info.plist" + @ONLY + ) + set(RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/isle/LaunchScreen.storyboard" "${CMAKE_CURRENT_SOURCE_DIR}/isle/Assets.xcassets") + target_sources(${ISLE_TARGET_NAME} PRIVATE ${RESOURCE_FILES}) + set_source_files_properties(${RESOURCE_FILES} + TARGET_DIRECTORY isle + PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set_target_properties(${ISLE_TARGET_NAME} PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/isle/Info.plist" + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon" + XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2") + install(TARGETS ${ISLE_TARGET_NAME} DESTINATION ./) + install(CODE " + file(COPY + \"\$\" + \"\$\" + DESTINATION \"\$\{CMAKE_INSTALL_PREFIX\}/${ISLE_TARGET_NAME}.app/Frameworks\") + execute_process(COMMAND /usr/bin/install_name_tool + -add_rpath @executable_path/Frameworks + \"\$\{CMAKE_INSTALL_PREFIX\}/${ISLE_TARGET_NAME}.app/${ISLE_TARGET_NAME}\" + ) + file(MAKE_DIRECTORY + \"\$\{CMAKE_INSTALL_PREFIX\}/Payload\") + file(RENAME + \"\$\{CMAKE_INSTALL_PREFIX\}/${ISLE_TARGET_NAME}.app\" + \"\$\{CMAKE_INSTALL_PREFIX\}/Payload/${ISLE_TARGET_NAME}.app\") + ") +endif() + +install(CODE " + if(IS_DIRECTORY \"\$\{CMAKE_INSTALL_PREFIX\}/bin\" OR IS_DIRECTORY \"\$\{CMAKE_INSTALL_PREFIX\}/lib\" OR EXISTS \"\$\{CMAKE_INSTALL_PREFIX\}/AppIcon.icns\") + execute_process(COMMAND /bin/rm + -rf \"\$\{CMAKE_INSTALL_PREFIX\}/bin\" \"\$\{CMAKE_INSTALL_PREFIX\}/lib\" \"\$\{CMAKE_INSTALL_PREFIX\}/AppIcon.icns\" + ) + endif() +") diff --git a/packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/AppIcon.png b/packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/AppIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..f51e706908f30270d2e641e2a80fcb7e472f96ce GIT binary patch literal 24327 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 literal 0 HcmV?d00001 diff --git a/packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/Contents.json b/packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..ce8e776e --- /dev/null +++ b/packaging/ios/isle/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,36 @@ +{ + "images" : [ + { + "filename" : "AppIcon.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/packaging/ios/isle/Assets.xcassets/Contents.json b/packaging/ios/isle/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/packaging/ios/isle/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/packaging/ios/isle/Info.plist.in b/packaging/ios/isle/Info.plist.in new file mode 100644 index 00000000..714324a3 --- /dev/null +++ b/packaging/ios/isle/Info.plist.in @@ -0,0 +1,86 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + @MACOSX_BUNDLE_INFO_STRING@ + CFBundleIdentifier + @MACOSX_BUNDLE_GUI_IDENTIFIER@ + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + @MACOSX_BUNDLE_LONG_VERSION_STRING@ + CFBundleName + @MACOSX_ISLE_BUNDLE_NAME@ + CFBundleDisplayName + @MACOSX_ISLE_BUNDLE_DISPLAY_NAME@ + CFBundlePackageType + APPL + CFBundleShortVersionString + @MACOSX_BUNDLE_SHORT_VERSION_STRING@ + CFBundleSignature + ???? + CFBundleVersion + @MACOSX_BUNDLE_BUNDLE_VERSION@ + UILaunchStoryboardName + LaunchScreen + NSHighResolutionCapable + + CSResourcesFileMapped + + LSRequires@MACOSX_BUNDLE_REQUIRED_PLATFORM@ + + NSHumanReadableCopyright + @MACOSX_BUNDLE_COPYRIGHT@ + SDL_FILESYSTEM_BASE_DIR_TYPE + resource + NSSupportsAutomaticGraphicsSwitching + + UIApplicationSupportsIndirectInputEvents + + LSSupportsOpeningDocumentsInPlace + + UIFileSharingEnabled + + CADisableMinimumFrameDurationOnPhone + + UIDeviceFamily + + 1 + 2 + + UIRequiresFullScreen + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + CFBundleAllowMixedLocalizations + + LSApplicationCategoryType + public.app-category.games + DTPlatformName + iphoneos + UIFileSharingEnabled + + LSSupportsOpeningDocumentsInPlace + + + \ No newline at end of file diff --git a/packaging/ios/isle/LaunchScreen.storyboard b/packaging/ios/isle/LaunchScreen.storyboard new file mode 100644 index 00000000..ad167a8a --- /dev/null +++ b/packaging/ios/isle/LaunchScreen.storyboard @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4e8ac864154cecb0cef95217035b5a300d909f61 Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Thu, 10 Jul 2025 15:58:17 +0900 Subject: [PATCH 3/9] Dynamically on/off virtual cursor (#567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat: eliminate need of draw_cursor config * 🩹 fix: type mismatch --- ISLE/isleapp.cpp | 54 ++++++++++++++++--------- ISLE/isleapp.h | 1 + miniwin/include/miniwin/miniwindevice.h | 1 + miniwin/src/d3drm/d3drmdevice.cpp | 8 ++++ miniwin/src/internal/d3drmdevice_impl.h | 1 + 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index f8f80e3a..49a939c2 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -103,6 +103,7 @@ MxFloat g_lastJoystickMouseX = 0; MxFloat g_lastJoystickMouseY = 0; MxFloat g_lastMouseX = 320; MxFloat g_lastMouseY = 240; +MxBool g_mouseWarped = FALSE; bool g_dpadUp = false; bool g_dpadDown = false; @@ -603,6 +604,10 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) break; } case SDL_EVENT_MOUSE_MOTION: + if (g_mouseWarped) { + g_mouseWarped = FALSE; + break; + } #ifdef __EMSCRIPTEN__ if (detectedTouchEvents) { break; @@ -619,9 +624,13 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) 0 ); } + g_lastMouseX = event->motion.x; + g_lastMouseY = event->motion.y; - if (g_isle->GetDrawCursor()) { - VideoManager()->MoveCursor(Min((MxS32) event->motion.x, 639), Min((MxS32) event->motion.y, 479)); + SDL_ShowCursor(); + g_isle->SetDrawCursor(FALSE); + if (VideoManager()) { + VideoManager()->SetCursorBitmap(NULL); } break; case SDL_EVENT_FINGER_MOTION: { @@ -633,12 +642,17 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) float x = SDL_clamp(event->tfinger.x, 0, 1) * 640; float y = SDL_clamp(event->tfinger.y, 0, 1) * 480; + g_lastMouseX = x; + g_lastMouseY = y; + if (InputManager()) { InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0); } - if (g_isle->GetDrawCursor()) { - VideoManager()->MoveCursor(Min((MxS32) x, 639), Min((MxS32) y, 479)); + SDL_HideCursor(); + g_isle->SetDrawCursor(FALSE); + if (VideoManager()) { + VideoManager()->SetCursorBitmap(NULL); } break; } @@ -808,12 +822,9 @@ MxResult IsleApp::SetupWindow() m_cursorBusy = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT); m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED); SDL_SetCursor(m_cursorCurrent); - if (g_isle->GetDrawCursor()) { - SDL_HideCursor(); - m_cursorCurrentBitmap = m_cursorArrowBitmap = &arrow_cursor; - m_cursorBusyBitmap = &busy_cursor; - m_cursorNoBitmap = &no_cursor; - } + m_cursorCurrentBitmap = m_cursorArrowBitmap = &arrow_cursor; + m_cursorBusyBitmap = &busy_cursor; + m_cursorNoBitmap = &no_cursor; SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, g_targetWidth); @@ -897,7 +908,7 @@ MxResult IsleApp::SetupWindow() LegoOmni::GetInstance()->GetInputManager()->SetUseJoystick(m_useJoystick); LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex); } - if (LegoOmni::GetInstance()->GetVideoManager() && g_isle->GetDrawCursor()) { + if (LegoOmni::GetInstance()->GetVideoManager()) { LegoOmni::GetInstance()->GetVideoManager()->SetCursorBitmap(m_cursorCurrentBitmap); } MxDirect3D* d3d = LegoOmni::GetInstance()->GetVideoManager()->GetDirect3D(); @@ -990,7 +1001,6 @@ bool IsleApp::LoadConfig() iniparser_set(dict, "isle:UseJoystick", m_useJoystick ? "true" : "false"); iniparser_set(dict, "isle:JoystickIndex", SDL_itoa(m_joystickIndex, buf, 10)); - iniparser_set(dict, "isle:Draw Cursor", m_drawCursor ? "true" : "false"); SDL_snprintf(buf, sizeof(buf), "%f", m_cursorSensitivity); iniparser_set(dict, "isle:Cursor Sensitivity", buf); @@ -1042,7 +1052,6 @@ bool IsleApp::LoadConfig() m_useMusic = iniparser_getboolean(dict, "isle:Music", m_useMusic); m_useJoystick = iniparser_getboolean(dict, "isle:UseJoystick", m_useJoystick); m_joystickIndex = iniparser_getint(dict, "isle:JoystickIndex", m_joystickIndex); - m_drawCursor = iniparser_getboolean(dict, "isle:Draw Cursor", m_drawCursor); m_cursorSensitivity = iniparser_getdouble(dict, "isle:Cursor Sensitivity", m_cursorSensitivity); MxS32 backBuffersInVRAM = iniparser_getboolean(dict, "isle:Back Buffers in Video RAM", -1); @@ -1213,12 +1222,7 @@ void IsleApp::SetupCursor(Cursor p_cursor) } if (g_isle->GetDrawCursor()) { - if (m_cursorCurrentBitmap == NULL) { - VideoManager()->SetCursorBitmap(NULL); - } - else { - VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap); - } + VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap); } else { if (m_cursorCurrent != NULL) { @@ -1392,8 +1396,18 @@ void IsleApp::MoveVirtualMouseViaJoystick() ); } - if (g_isle->GetDrawCursor()) { + SDL_HideCursor(); + g_isle->SetDrawCursor(TRUE); + if (VideoManager()) { + VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap); VideoManager()->MoveCursor(Min((MxS32) g_lastMouseX, 639), Min((MxS32) g_lastMouseY, 479)); } + IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice(); + if (device) { + Sint32 x, y; + device->ConvertRenderToWindowCoordinates(g_lastMouseX, g_lastMouseY, x, y); + g_mouseWarped = TRUE; + SDL_WarpMouseInWindow(window, x, y); + } } } diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index 70445d05..7054f6d1 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -56,6 +56,7 @@ class IsleApp { void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; } void SetGameStarted(MxS32 p_gameStarted) { m_gameStarted = p_gameStarted; } + void SetDrawCursor(MxS32 p_drawCursor) { m_drawCursor = p_drawCursor; } MxResult ParseArguments(int argc, char** argv); MxResult VerifyFilesystem(); diff --git a/miniwin/include/miniwin/miniwindevice.h b/miniwin/include/miniwin/miniwindevice.h index 00329393..de28e76a 100644 --- a/miniwin/include/miniwin/miniwindevice.h +++ b/miniwin/include/miniwin/miniwindevice.h @@ -6,4 +6,5 @@ DEFINE_GUID(IID_IDirect3DRMMiniwinDevice, 0x6eb09673, 0x8d30, 0x4d8a, 0x8d, 0x81 struct IDirect3DRMMiniwinDevice : virtual public IUnknown { virtual bool ConvertEventToRenderCoordinates(SDL_Event* event) = 0; + virtual bool ConvertRenderToWindowCoordinates(Sint32 inX, Sint32 inY, Sint32& outX, Sint32& outY) = 0; }; diff --git a/miniwin/src/d3drm/d3drmdevice.cpp b/miniwin/src/d3drm/d3drmdevice.cpp index 9f517426..987efb6e 100644 --- a/miniwin/src/d3drm/d3drmdevice.cpp +++ b/miniwin/src/d3drm/d3drmdevice.cpp @@ -198,3 +198,11 @@ bool Direct3DRMDevice2Impl::ConvertEventToRenderCoordinates(SDL_Event* event) return true; } + +bool Direct3DRMDevice2Impl::ConvertRenderToWindowCoordinates(Sint32 inX, Sint32 inY, Sint32& outX, Sint32& outY) +{ + outX = static_cast(inX * m_viewportTransform.scale + m_viewportTransform.offsetX); + outY = static_cast(inY * m_viewportTransform.scale + m_viewportTransform.offsetY); + + return true; +} diff --git a/miniwin/src/internal/d3drmdevice_impl.h b/miniwin/src/internal/d3drmdevice_impl.h index 5679ce0d..46dc5ed2 100644 --- a/miniwin/src/internal/d3drmdevice_impl.h +++ b/miniwin/src/internal/d3drmdevice_impl.h @@ -34,6 +34,7 @@ struct Direct3DRMDevice2Impl : public Direct3DRMObjectBaseImpl Date: Thu, 10 Jul 2025 00:24:59 -0700 Subject: [PATCH 4/9] Add extensions, `TextureLoader` (#570) * Add extensions, `TextureLoader` * Fix wording * Add to default ini * Add folder to flatpak * Use different enable strategy --- CMakeLists.txt | 11 +++ CONTRIBUTING.md | 7 +- ISLE/isleapp.cpp | 20 ++++ .../legoomni/src/common/legotextureinfo.cpp | 7 ++ README.md | 2 +- extensions/include/extensions/extensions.h | 28 ++++++ extensions/include/extensions/textureloader.h | 24 +++++ extensions/src/extensions.cpp | 19 ++++ extensions/src/textureloader.cpp | 98 +++++++++++++++++++ .../linux/flatpak/org.legoisland.Isle.json | 5 + 10 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 extensions/include/extensions/extensions.h create mode 100644 extensions/include/extensions/textureloader.h create mode 100644 extensions/src/extensions.cpp create mode 100644 extensions/src/textureloader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 70ddba15..724ca120 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ option(ISLE_WERROR "Treat warnings as errors" OFF) option(ISLE_DEBUG "Enable imgui debug" ON) cmake_dependent_option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" "${NOT_MINGW}" "WIN32;CMAKE_SIZEOF_VOID_P EQUAL 4" OFF) cmake_dependent_option(ISLE_MINIWIN "Use miniwin" ON "NOT ISLE_USE_DX5" OFF) +cmake_dependent_option(ISLE_EXTENSIONS "Use extensions" ON "NOT ISLE_USE_DX5" OFF) cmake_dependent_option(ISLE_BUILD_CONFIG "Build CONFIG.EXE application" ON "MSVC OR ISLE_MINIWIN;NOT NINTENDO_3DS;NOT WINDOWS_STORE" OFF) cmake_dependent_option(ISLE_COMPILE_SHADERS "Compile shaders" ON "SDL_SHADERCROSS_BIN;TARGET Python3::Interpreter" OFF) option(CMAKE_POSITION_INDEPENDENT_CODE "Build with -fPIC" ON) @@ -61,6 +62,7 @@ message(STATUS "Isle app: ${ISLE_BUILD_APP}") message(STATUS "Config app: ${ISLE_BUILD_CONFIG}") message(STATUS "Internal DirectX5 SDK: ${ISLE_USE_DX5}") message(STATUS "Internal miniwin: ${ISLE_MINIWIN}") +message(STATUS "Isle extensions: ${ISLE_EXTENSIONS}") message(STATUS "Isle debugging: ${ISLE_DEBUG}") message(STATUS "Compile shaders: ${ISLE_COMPILE_SHADERS}") @@ -170,6 +172,7 @@ add_library(lego1 target_precompile_headers(lego1 PRIVATE "LEGO1/lego1_pch.h") set_property(TARGET lego1 PROPERTY DEFINE_SYMBOL "LEGO1_DLL") target_include_directories(lego1 PUBLIC "$") +target_include_directories(lego1 PUBLIC "$") target_include_directories(lego1 PUBLIC "$") target_include_directories(lego1 PUBLIC "$") target_include_directories(lego1 PUBLIC "$") @@ -487,6 +490,14 @@ if (NOT ISLE_MINIWIN) target_compile_definitions(lego1 PRIVATE DIRECTINPUT_VERSION=0x0500) endif() +if (ISLE_EXTENSIONS) + target_compile_definitions(lego1 PUBLIC EXTENSIONS) + target_sources(lego1 PRIVATE + extensions/src/extensions.cpp + extensions/src/textureloader.cpp + ) +endif() + if (ISLE_BUILD_APP) add_executable(isle WIN32 ISLE/res/isle.rc diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 61b8cf68..8be43bce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,12 +6,7 @@ If you feel fit to contribute, feel free to create a pull request! Someone will Please keep your pull requests small and understandable; you may be able to shoot ahead and make a lot of progress in a short amount of time, but this is a collaborative project, so you must allow others to catch up and follow along. Large pull requests become significantly more unwieldy to review, and as such make it exponentially more likely for a mistake or error to go undetected. They also make it harder to merge other pull requests because the more files you modify, the more likely it is for a merge conflict to occur. A general guideline is to keep submissions limited to one class at a time. Sometimes two or more classes may be too interlinked for this to be feasible, so this is not a hard rule, however if your PR is starting to modify more than 10 or so files, it's probably getting too big. -This repository has a single goal: achieving platform independence. Consequently, contributions that do not support this goal cannot be accepted. Examples of out-of-scope contributions include: - -* Improving code efficiency or performance without addressing platform compatibility -* Replacing `MxString` with `std::string` -* Fixing gameplay bugs -* Enhancing audio or video quality +This repository has achieving platform independence as its primary goal, with limited support for light modding (using [`extensions`](/extensions)). Any changes that modify code in `LEGO1` are unlikely to be accepted, unless they directly serve to increase platform compatibility. If in doubt, please contact us in the [Matrix chatroom](https://matrix.to/#/#isledecomp:matrix.org). diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 49a939c2..ddbeb6c4 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -37,6 +37,7 @@ #include "tgl/d3drm/impl.h" #include "viewmanager/viewmanager.h" +#include #include #define SDL_MAIN_USE_CALLBACKS @@ -1013,6 +1014,13 @@ bool IsleApp::LoadConfig() iniparser_set(dict, "isle:Max Allowed Extras", SDL_itoa(m_maxAllowedExtras, buf, 10)); iniparser_set(dict, "isle:Transition Type", SDL_itoa(m_transitionType, buf, 10)); +#ifdef EXTENSIONS + iniparser_set(dict, "extensions", NULL); + for (const char* key : Extensions::availableExtensions) { + iniparser_set(dict, key, "false"); + } +#endif + #ifdef __3DS__ N3DS_SetupDefaultConfigOverrides(dict); #endif @@ -1089,6 +1097,18 @@ bool IsleApp::LoadConfig() m_savePath = new char[strlen(savePath) + 1]; strcpy(m_savePath, savePath); +#ifdef EXTENSIONS + std::vector keys; + keys.resize(iniparser_getsecnkeys(dict, "extensions")); + iniparser_getseckeys(dict, "extensions", keys.data()); + + for (const char* key : keys) { + if (iniparser_getboolean(dict, key, 0)) { + Extensions::Enable(key); + } + } +#endif + iniparser_freedict(dict); delete[] iniConfig; #ifndef IOS diff --git a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp index eb639d84..a0be25b7 100644 --- a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp +++ b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp @@ -1,5 +1,6 @@ #include "legotextureinfo.h" +#include "extensions/textureloader.h" #include "legovideomanager.h" #include "misc.h" #include "misc/legoimage.h" @@ -9,6 +10,8 @@ DECOMP_SIZE_ASSERT(LegoTextureInfo, 0x10) +using namespace Extensions; + // FUNCTION: LEGO1 0x10065bf0 LegoTextureInfo::LegoTextureInfo() { @@ -56,6 +59,10 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text strcpy(textureInfo->m_name, p_name); } + if (Extension::Call(PatchTexture, textureInfo).value_or(false)) { + return textureInfo; + } + LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw(); LegoImage* image = p_texture->GetImage(); diff --git a/README.md b/README.md index 765c74d2..70ea1aa4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This initiative is a portable version of LEGO Island (Version 1.1, English) based on the [decompilation project](https://github.com/isledecomp/isle). Our primary goal is to transform the codebase to achieve platform independence, thereby enhancing compatibility across various systems while preserving the original game's experience as faithfully as possible. -Please note: this project is dedicated to achieving platform independence without altering the core gameplay, adding new features, enhancing visual quality, or rewriting code for improvement's sake. While those are worthwhile objectives, they are not within the scope of this project. +Please note: this project is primarily dedicated to achieving platform independence without altering the core gameplay or rewriting code for improvement's sake. While those are worthwhile objectives, they are not within the scope of this project. `isle-portable` offers support for light modding using [`extensions`](/extensions). ## Status diff --git a/extensions/include/extensions/extensions.h b/extensions/include/extensions/extensions.h new file mode 100644 index 00000000..215bf80a --- /dev/null +++ b/extensions/include/extensions/extensions.h @@ -0,0 +1,28 @@ +#pragma once + +#include "lego1_export.h" + +#include +#include +#include + +namespace Extensions +{ +constexpr const char* availableExtensions[] = {"extensions:texture loader"}; + +LEGO1_EXPORT void Enable(const char* p_key); + +template +struct Extension { + template + static auto Call(Function&& function, Args&&... args) -> std::optional> + { +#ifdef EXTENSIONS + if (T::enabled) { + return std::invoke(std::forward(function), std::forward(args)...); + } +#endif + return std::nullopt; + } +}; +}; // namespace Extensions diff --git a/extensions/include/extensions/textureloader.h b/extensions/include/extensions/textureloader.h new file mode 100644 index 00000000..649c6112 --- /dev/null +++ b/extensions/include/extensions/textureloader.h @@ -0,0 +1,24 @@ +#pragma once + +#include "extensions/extensions.h" +#include "legotextureinfo.h" + +namespace Extensions +{ +class TextureLoader { +public: + static bool PatchTexture(LegoTextureInfo* p_textureInfo); + static bool enabled; + +private: + static constexpr const char* texturePath = "/textures/"; + + static SDL_Surface* FindTexture(const char* p_name); +}; + +#ifdef EXTENSIONS +constexpr auto PatchTexture = &TextureLoader::PatchTexture; +#else +constexpr decltype(&TextureLoader::PatchTexture) PatchTexture = nullptr; +#endif +}; // namespace Extensions diff --git a/extensions/src/extensions.cpp b/extensions/src/extensions.cpp new file mode 100644 index 00000000..e1d0c389 --- /dev/null +++ b/extensions/src/extensions.cpp @@ -0,0 +1,19 @@ +#include "extensions/extensions.h" + +#include "extensions/textureloader.h" + +#include + +void Extensions::Enable(const char* p_key) +{ + for (const char* key : availableExtensions) { + if (!SDL_strcasecmp(p_key, key)) { + if (!SDL_strcasecmp(p_key, "extensions:texture loader")) { + TextureLoader::enabled = true; + } + + SDL_Log("Enabled extension: %s", p_key); + break; + } + } +} diff --git a/extensions/src/textureloader.cpp b/extensions/src/textureloader.cpp new file mode 100644 index 00000000..ee057997 --- /dev/null +++ b/extensions/src/textureloader.cpp @@ -0,0 +1,98 @@ +#include "extensions/textureloader.h" + +using namespace Extensions; + +bool TextureLoader::enabled = false; + +bool TextureLoader::PatchTexture(LegoTextureInfo* p_textureInfo) +{ + SDL_Surface* surface = FindTexture(p_textureInfo->m_name); + if (!surface) { + return false; + } + + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(surface->format); + + DDSURFACEDESC desc; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + desc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; + desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); + desc.dwWidth = surface->w; + desc.dwHeight = surface->h; + desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + desc.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel == 8 ? 24 : details->bits_per_pixel; + desc.ddpfPixelFormat.dwRBitMask = details->Rmask; + desc.ddpfPixelFormat.dwGBitMask = details->Gmask; + desc.ddpfPixelFormat.dwBBitMask = details->Bmask; + desc.ddpfPixelFormat.dwRGBAlphaBitMask = details->Amask; + + if (VideoManager()->GetDirect3D()->DirectDraw()->CreateSurface(&desc, &p_textureInfo->m_surface, NULL) != DD_OK) { + SDL_DestroySurface(surface); + return false; + } + + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (p_textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) != DD_OK) { + SDL_DestroySurface(surface); + return false; + } + + MxU8* dst = (MxU8*) desc.lpSurface; + Uint8* srcPixels = (Uint8*) surface->pixels; + + if (details->bits_per_pixel == 8) { + SDL_Palette* palette = SDL_GetSurfacePalette(surface); + if (palette) { + for (int y = 0; y < surface->h; ++y) { + Uint8* srcRow = srcPixels + y * surface->pitch; + Uint8* dstRow = dst + y * desc.lPitch; + for (int x = 0; x < surface->w; ++x) { + SDL_Color color = palette->colors[srcRow[x]]; + dstRow[x * 3 + 0] = color.r; + dstRow[x * 3 + 1] = color.g; + dstRow[x * 3 + 2] = color.b; + } + } + } + else { + p_textureInfo->m_surface->Unlock(desc.lpSurface); + SDL_DestroySurface(surface); + return false; + } + } + else { + memcpy(dst, srcPixels, surface->pitch * surface->h); + } + + p_textureInfo->m_surface->Unlock(desc.lpSurface); + p_textureInfo->m_palette = NULL; + + if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer()) + ->CreateTextureFromSurface(p_textureInfo->m_surface, &p_textureInfo->m_texture) != D3DRM_OK) { + SDL_DestroySurface(surface); + return false; + } + + p_textureInfo->m_texture->SetAppData((LPD3DRM_APPDATA) p_textureInfo); + SDL_DestroySurface(surface); + return true; +} + +SDL_Surface* TextureLoader::FindTexture(const char* p_name) +{ + SDL_Surface* surface; + MxString path = MxString(MxOmni::GetHD()) + texturePath + p_name + ".bmp"; + + path.MapPathToFilesystem(); + if (!(surface = SDL_LoadBMP(path.GetData()))) { + path = MxString(MxOmni::GetCD()) + texturePath + p_name + ".bmp"; + path.MapPathToFilesystem(); + surface = SDL_LoadBMP(path.GetData()); + } + + return surface; +} diff --git a/packaging/linux/flatpak/org.legoisland.Isle.json b/packaging/linux/flatpak/org.legoisland.Isle.json index 178434fa..229ba424 100644 --- a/packaging/linux/flatpak/org.legoisland.Isle.json +++ b/packaging/linux/flatpak/org.legoisland.Isle.json @@ -55,6 +55,11 @@ "path": "../../../miniwin", "dest": "miniwin/" }, + { + "type": "dir", + "path": "../../../extensions", + "dest": "extensions/" + }, { "type": "dir", "path": "../../../packaging", From e61f9209f2b64e03b3bd41d0ecbb90a760ff7c4a Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 10 Jul 2025 00:28:35 -0700 Subject: [PATCH 5/9] Update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70ea1aa4..95237c85 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ Please note: this project is primarily dedicated to achieving platform independe | [Web](https://isle.pizza) | [![CI](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml/badge.svg)](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml) | | Nintendo 3DS | [![CI](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml/badge.svg)](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml) | | Xbox One | [![CI](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml/badge.svg)](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml) | +| iOS | [![CI](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml/badge.svg)](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml) | We are actively working to support more platforms. If you have experience with a particular platform, we encourage you to contribute to `isle-portable`. You can find a [list of ongoing efforts](https://github.com/isledecomp/isle-portable/wiki/Work%E2%80%90in%E2%80%90progress-ports) in our Wiki. - ## Usage **An existing copy of LEGO Island is required to use this project.** From 078b1b52d0103c4c0ffbba320e3197ad69f02180 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 10 Jul 2025 00:32:55 -0700 Subject: [PATCH 6/9] Update Dockerfile --- docker/emscripten/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/emscripten/Dockerfile b/docker/emscripten/Dockerfile index a213093c..707b3c7a 100644 --- a/docker/emscripten/Dockerfile +++ b/docker/emscripten/Dockerfile @@ -28,6 +28,7 @@ COPY --chown=emscripten:emscripten miniwin/ ./miniwin/ COPY --chown=emscripten:emscripten util/ ./util/ COPY --chown=emscripten:emscripten CMake/ ./CMake/ COPY --chown=emscripten:emscripten packaging/ ./packaging/ +COPY --chown=emscripten:emscripten extensions/ ./extensions/ COPY --chown=emscripten:emscripten CMakeLists.txt . RUN emcmake cmake -S . -B build -DISLE_BUILD_CONFIG=OFF -DISLE_DEBUG=OFF -DCMAKE_BUILD_TYPE=Release -DISLE_EMSCRIPTEN_HOST=/assets && \ From 96f60cb683c5e5f2008f8996be535123abcd0298 Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Thu, 10 Jul 2025 19:43:46 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=A9=B9=20fix:=20touch=20screens=20go?= =?UTF-8?q?=20beep=20and=20done=20(#573)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ISLE/isleapp.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index ddbeb6c4..dbb3c9ff 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -625,6 +625,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) 0 ); } + g_lastMouseX = event->motion.x; g_lastMouseY = event->motion.y; @@ -643,13 +644,13 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) float x = SDL_clamp(event->tfinger.x, 0, 1) * 640; float y = SDL_clamp(event->tfinger.y, 0, 1) * 480; - g_lastMouseX = x; - g_lastMouseY = y; - if (InputManager()) { InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0); } + g_lastMouseX = x; + g_lastMouseY = y; + SDL_HideCursor(); g_isle->SetDrawCursor(FALSE); if (VideoManager()) { @@ -687,6 +688,15 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) if (InputManager()) { InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0); } + + g_lastMouseX = x; + g_lastMouseY = y; + + SDL_HideCursor(); + g_isle->SetDrawCursor(FALSE); + if (VideoManager()) { + VideoManager()->SetCursorBitmap(NULL); + } break; } case SDL_EVENT_MOUSE_BUTTON_UP: From 28b026f6053f9cbb8c8cffc0ebfe494342636a6a Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Thu, 10 Jul 2025 18:07:03 +0200 Subject: [PATCH 8/9] Maintain paletted textures (#574) --- extensions/src/textureloader.cpp | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/extensions/src/textureloader.cpp b/extensions/src/textureloader.cpp index ee057997..dd96105e 100644 --- a/extensions/src/textureloader.cpp +++ b/extensions/src/textureloader.cpp @@ -22,13 +22,14 @@ bool TextureLoader::PatchTexture(LegoTextureInfo* p_textureInfo) desc.dwWidth = surface->w; desc.dwHeight = surface->h; desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - desc.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel == 8 ? 24 : details->bits_per_pixel; + desc.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel; desc.ddpfPixelFormat.dwRBitMask = details->Rmask; desc.ddpfPixelFormat.dwGBitMask = details->Gmask; desc.ddpfPixelFormat.dwBBitMask = details->Bmask; desc.ddpfPixelFormat.dwRGBAlphaBitMask = details->Amask; - if (VideoManager()->GetDirect3D()->DirectDraw()->CreateSurface(&desc, &p_textureInfo->m_surface, NULL) != DD_OK) { + LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw(); + if (pDirectDraw->CreateSurface(&desc, &p_textureInfo->m_surface, NULL) != DD_OK) { SDL_DestroySurface(surface); return false; } @@ -45,29 +46,31 @@ bool TextureLoader::PatchTexture(LegoTextureInfo* p_textureInfo) Uint8* srcPixels = (Uint8*) surface->pixels; if (details->bits_per_pixel == 8) { - SDL_Palette* palette = SDL_GetSurfacePalette(surface); - if (palette) { - for (int y = 0; y < surface->h; ++y) { - Uint8* srcRow = srcPixels + y * surface->pitch; - Uint8* dstRow = dst + y * desc.lPitch; - for (int x = 0; x < surface->w; ++x) { - SDL_Color color = palette->colors[srcRow[x]]; - dstRow[x * 3 + 0] = color.r; - dstRow[x * 3 + 1] = color.g; - dstRow[x * 3 + 2] = color.b; - } - } - } - else { - p_textureInfo->m_surface->Unlock(desc.lpSurface); + SDL_Palette* sdlPalette = SDL_GetSurfacePalette(surface); + if (!sdlPalette) { SDL_DestroySurface(surface); return false; } - } - else { - memcpy(dst, srcPixels, surface->pitch * surface->h); + + PALETTEENTRY entries[256]; + for (int i = 0; i < sdlPalette->ncolors; ++i) { + entries[i].peRed = sdlPalette->colors[i].r; + entries[i].peGreen = sdlPalette->colors[i].g; + entries[i].peBlue = sdlPalette->colors[i].b; + entries[i].peFlags = PC_NONE; + } + + LPDIRECTDRAWPALETTE ddPalette = nullptr; + if (pDirectDraw->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, entries, &ddPalette, NULL) != DD_OK) { + SDL_DestroySurface(surface); + return false; + } + + p_textureInfo->m_surface->SetPalette(ddPalette); + ddPalette->Release(); } + memcpy(dst, srcPixels, surface->pitch * surface->h); p_textureInfo->m_surface->Unlock(desc.lpSurface); p_textureInfo->m_palette = NULL; From b26a707db286868b558922966db77335e8ef3b3d Mon Sep 17 00:00:00 2001 From: olebeck <31539311+olebeck@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:19:21 +0200 Subject: [PATCH 9/9] put ifdefs around every d3drm backend so that any can be disabled (#569) * put ifdefs around every d3drm backend so that any can be disabled * make clang-format happy * move backend selection and enum to its own functions --- miniwin/CMakeLists.txt | 74 +++++++++++++++++---------- miniwin/src/d3drm/d3drm.cpp | 43 +--------------- miniwin/src/d3drm/d3drmrenderer.cpp | 76 ++++++++++++++++++++++++++++ miniwin/src/ddraw/ddraw.cpp | 61 ++-------------------- miniwin/src/internal/d3drmrenderer.h | 3 ++ 5 files changed, 133 insertions(+), 124 deletions(-) create mode 100644 miniwin/src/d3drm/d3drmrenderer.cpp diff --git a/miniwin/CMakeLists.txt b/miniwin/CMakeLists.txt index 1ed5e909..3fe96ea3 100644 --- a/miniwin/CMakeLists.txt +++ b/miniwin/CMakeLists.txt @@ -19,42 +19,44 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL src/d3drm/d3drmmesh.cpp src/d3drm/d3drmtexture.cpp src/d3drm/d3drmviewport.cpp + src/d3drm/d3drmrenderer.cpp src/internal/meshutils.cpp - - # D3DRM backends - src/d3drm/backends/sdl3gpu/renderer.cpp - src/d3drm/backends/sdl3gpu/shaders/generated/ShaderIndex.cpp - src/d3drm/backends/software/renderer.cpp ) target_compile_definitions(miniwin PRIVATE $<$:DEBUG> ) -find_package(OpenGL) -if(OpenGL_FOUND AND NOT WINDOWS_STORE) - message(STATUS "Found OpenGL: enabling OpenGL 1.x renderer") - target_sources(miniwin PRIVATE - src/d3drm/backends/opengl1/actual.cpp - src/d3drm/backends/opengl1/renderer.cpp - ) - target_compile_definitions(miniwin PRIVATE USE_OPENGL1) - target_link_libraries(miniwin PRIVATE OpenGL::GL) -else() - message(STATUS "🧩 OpenGL 1.x support not enabled — needs OpenGL") +list(APPEND GRAPHICS_BACKENDS USE_SOFTWARE_RENDER) +list(APPEND GRAPHICS_BACKENDS USE_SDL_GPU) + +if(NOT WINDOWS_STORE) + find_package(OpenGL) + if(OpenGL_FOUND) + message(STATUS "Found OpenGL: enabling OpenGL 1.x renderer") + target_sources(miniwin PRIVATE + src/d3drm/backends/opengl1/actual.cpp + src/d3drm/backends/opengl1/renderer.cpp + ) + list(APPEND GRAPHICS_BACKENDS USE_OPENGL1) + target_link_libraries(miniwin PRIVATE OpenGL::GL) + else() + message(STATUS "🧩 OpenGL 1.x support not enabled — needs OpenGL") + endif() + + find_library(OPENGL_ES2_LIBRARY NAMES GLESv2) + if(EMSCRIPTEN OR OPENGL_ES2_LIBRARY) + message(STATUS "Found OpenGL: enabling OpenGL ES 2.x renderer") + target_sources(miniwin PRIVATE src/d3drm/backends/opengles2/renderer.cpp) + list(APPEND GRAPHICS_BACKENDS USE_OPENGLES2) + if(OPENGL_ES2_LIBRARY) + target_link_libraries(miniwin PRIVATE ${OPENGL_ES2_LIBRARY}) + endif() + else() + message(STATUS "🧩 OpenGL ES 2.x support not enabled") + endif() endif() -find_library(OPENGL_ES2_LIBRARY NAMES GLESv2) -if(EMSCRIPTEN OR OPENGL_ES2_LIBRARY AND NOT WINDOWS_STORE) - message(STATUS "Found OpenGL: enabling OpenGL ES 2.x renderer") - target_sources(miniwin PRIVATE src/d3drm/backends/opengles2/renderer.cpp) - target_compile_definitions(miniwin PRIVATE USE_OPENGLES2) - if(OPENGL_ES2_LIBRARY) - target_link_libraries(miniwin PRIVATE OpenGL::GL) - endif() -else() - message(STATUS "🧩 OpenGL ES 2.x support not enabled") -endif() if(NINTENDO_3DS) if(ISLE_DEBUG) @@ -68,6 +70,7 @@ if(NINTENDO_3DS) ctr_add_shader_library(vshader src/d3drm/backends/citro3d/vshader.v.pica) dkp_add_embedded_binary_library(3ds_shaders vshader) target_link_libraries(miniwin PRIVATE ${CITRO3D_LIBRARY} 3ds_shaders) + list(APPEND GRAPHICS_BACKENDS USE_CITRO3D) else() message(STATUS "🧩 Citro3D support not enabled") endif() @@ -79,12 +82,26 @@ if(WIN32 AND NOT WINDOWS_STORE) src/d3drm/backends/directx9/renderer.cpp ) target_link_libraries(miniwin PRIVATE d3d9) + list(APPEND GRAPHICS_BACKENDS USE_DIRECTX9) endif() if(WINDOWS_STORE) add_compile_definitions(WINDOWS_STORE) endif() +if(USE_SDL_GPU IN_LIST GRAPHICS_BACKENDS) + target_sources(miniwin PRIVATE + src/d3drm/backends/sdl3gpu/renderer.cpp + src/d3drm/backends/sdl3gpu/shaders/generated/ShaderIndex.cpp + ) +endif() + +if(USE_SOFTWARE_RENDER IN_LIST GRAPHICS_BACKENDS) + target_sources(miniwin PRIVATE + src/d3drm/backends/software/renderer.cpp + ) +endif() + target_compile_definitions(miniwin PUBLIC MINIWIN) target_include_directories(miniwin @@ -96,6 +113,9 @@ target_link_libraries(miniwin PUBLIC miniwin-headers) target_link_libraries(miniwin PRIVATE SDL3::SDL3) +target_compile_definitions(miniwin PUBLIC ${GRAPHICS_BACKENDS}) + + # Shader stuff set(shader_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/src/d3drm/backends/sdl3gpu/shaders/src") diff --git a/miniwin/src/d3drm/d3drm.cpp b/miniwin/src/d3drm/d3drm.cpp index 1088a943..7328d21c 100644 --- a/miniwin/src/d3drm/d3drm.cpp +++ b/miniwin/src/d3drm/d3drm.cpp @@ -7,20 +7,6 @@ #include "d3drmmesh_impl.h" #include "d3drmobject_impl.h" #include "d3drmrenderer.h" -#ifdef USE_OPENGL1 -#include "d3drmrenderer_opengl1.h" -#endif -#ifdef USE_OPENGLES2 -#include "d3drmrenderer_opengles2.h" -#endif -#ifdef __3DS__ -#include "d3drmrenderer_citro3d.h" -#endif -#ifdef _WIN32 -#include "d3drmrenderer_directx9.h" -#endif -#include "d3drmrenderer_sdl3gpu.h" -#include "d3drmrenderer_software.h" #include "d3drmtexture_impl.h" #include "d3drmviewport_impl.h" #include "ddraw_impl.h" @@ -146,33 +132,8 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface( DDSDesc.dwSize = sizeof(DDSURFACEDESC); surface->GetSurfaceDesc(&DDSDesc); - if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) { - DDRenderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } - else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) { - DDRenderer = new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#ifdef USE_OPENGLES2 - else if (SDL_memcmp(&guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) { - DDRenderer = OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#ifdef USE_OPENGL1 - else if (SDL_memcmp(&guid, &OpenGL1_GUID, sizeof(GUID)) == 0) { - DDRenderer = OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#ifdef __3DS__ - else if (SDL_memcmp(&guid, &Citro3D_GUID, sizeof(GUID)) == 0) { - DDRenderer = new Citro3DRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#if defined(_WIN32) && !defined(WINDOWS_STORE) - else if (SDL_memcmp(&guid, &DirectX9_GUID, sizeof(GUID)) == 0) { - DDRenderer = DirectX9Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif - else { + DDRenderer = CreateDirect3DRMRenderer(DDSDesc, guid); + if (!DDRenderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized"); return E_NOINTERFACE; } diff --git a/miniwin/src/d3drm/d3drmrenderer.cpp b/miniwin/src/d3drm/d3drmrenderer.cpp new file mode 100644 index 00000000..ca9b5541 --- /dev/null +++ b/miniwin/src/d3drm/d3drmrenderer.cpp @@ -0,0 +1,76 @@ +#include "d3drmrenderer.h" +#ifdef USE_OPENGL1 +#include "d3drmrenderer_opengl1.h" +#endif +#ifdef USE_OPENGLES2 +#include "d3drmrenderer_opengles2.h" +#endif +#ifdef USE_CITRO3D +#include "d3drmrenderer_citro3d.h" +#endif +#ifdef USE_DIRECTX9 +#include "d3drmrenderer_directx9.h" +#endif +#ifdef USE_SDL_GPU +#include "d3drmrenderer_sdl3gpu.h" +#endif +#ifdef USE_SOFTWARE_RENDER +#include "d3drmrenderer_software.h" +#endif + +Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid) +{ +#ifdef USE_SDL_GPU + if (SDL_memcmp(guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) { + return Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif +#ifdef USE_SOFTWARE_RENDER + if (SDL_memcmp(guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) { + return new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif +#ifdef USE_OPENGLES2 + if (SDL_memcmp(guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) { + return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif +#ifdef USE_OPENGL1 + if (SDL_memcmp(guid, &OpenGL1_GUID, sizeof(GUID)) == 0) { + return OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif +#ifdef USE_CITRO3D + if (SDL_memcmp(guid, &Citro3D_GUID, sizeof(GUID)) == 0) { + return new Citro3DRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif +#ifdef USE_DIRECTX9 + if (SDL_memcmp(guid, &DirectX9_GUID, sizeof(GUID)) == 0) { + return DirectX9Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif + return nullptr; +} + +void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +{ +#ifdef USE_SDL_GPU + Direct3DRMSDL3GPU_EnumDevice(cb, ctx); +#endif +#ifdef USE_OPENGLES2 + OpenGLES2Renderer_EnumDevice(cb, ctx); +#endif +#ifdef USE_OPENGL1 + OpenGL1Renderer_EnumDevice(cb, ctx); +#endif +#ifdef USE_CITRO3D + Citro3DRenderer_EnumDevice(cb, ctx); +#endif +#ifdef USE_DIRECTX9 + DirectX9Renderer_EnumDevice(cb, ctx); +#endif +#ifdef USE_SOFTWARE_RENDER + Direct3DRMSoftware_EnumDevice(cb, ctx); +#endif +} diff --git a/miniwin/src/ddraw/ddraw.cpp b/miniwin/src/ddraw/ddraw.cpp index d2ce8743..264ceeb1 100644 --- a/miniwin/src/ddraw/ddraw.cpp +++ b/miniwin/src/ddraw/ddraw.cpp @@ -1,17 +1,5 @@ -#ifdef USE_OPENGL1 -#include "d3drmrenderer_opengl1.h" -#endif -#ifdef USE_OPENGLES2 -#include "d3drmrenderer_opengles2.h" -#endif -#ifdef __3DS__ -#include "d3drmrenderer_citro3d.h" -#endif -#if defined(_WIN32) && !defined(WINDOWS_STORE) -#include "d3drmrenderer_directx9.h" -#endif -#include "d3drmrenderer_sdl3gpu.h" -#include "d3drmrenderer_software.h" + +#include "d3drmrenderer.h" #include "ddpalette_impl.h" #include "ddraw_impl.h" #include "ddsurface_impl.h" @@ -232,21 +220,7 @@ void EnumDevice( HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - Direct3DRMSDL3GPU_EnumDevice(cb, ctx); -#ifdef USE_OPENGLES2 - OpenGLES2Renderer_EnumDevice(cb, ctx); -#endif -#ifdef USE_OPENGL1 - OpenGL1Renderer_EnumDevice(cb, ctx); -#endif -#ifdef __3DS__ - Citro3DRenderer_EnumDevice(cb, ctx); -#endif -#if defined(_WIN32) && !defined(WINDOWS_STORE) - DirectX9Renderer_EnumDevice(cb, ctx); -#endif - Direct3DRMSoftware_EnumDevice(cb, ctx); - + Direct3DRMRenderer_EnumDevices(cb, ctx); return S_OK; } @@ -343,33 +317,8 @@ HRESULT DirectDrawImpl::CreateDevice( DDSDesc.dwSize = sizeof(DDSURFACEDESC); pBackBuffer->GetSurfaceDesc(&DDSDesc); - if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) { - DDRenderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#ifdef USE_OPENGLES2 - else if (SDL_memcmp(&guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) { - DDRenderer = OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#ifdef USE_OPENGL1 - else if (SDL_memcmp(&guid, &OpenGL1_GUID, sizeof(GUID)) == 0) { - DDRenderer = OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#ifdef __3DS__ - else if (SDL_memcmp(&guid, &Citro3D_GUID, sizeof(GUID)) == 0) { - DDRenderer = new Citro3DRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif -#if defined(_WIN32) && !defined(WINDOWS_STORE) - else if (SDL_memcmp(&guid, &DirectX9_GUID, sizeof(GUID)) == 0) { - DDRenderer = DirectX9Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); - } -#endif - else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) { - DDRenderer = new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); - } - else { + DDRenderer = CreateDirect3DRMRenderer(DDSDesc, &guid); + if (!DDRenderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized"); return E_NOINTERFACE; } diff --git a/miniwin/src/internal/d3drmrenderer.h b/miniwin/src/internal/d3drmrenderer.h index 7cfe14b2..85b2d1b9 100644 --- a/miniwin/src/internal/d3drmrenderer.h +++ b/miniwin/src/internal/d3drmrenderer.h @@ -60,3 +60,6 @@ class Direct3DRMRenderer : public IDirect3DDevice2 { int m_virtualWidth, m_virtualHeight; ViewportTransform m_viewportTransform; }; + +Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid); +void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx);