From 05393fe7aa43d32bd1e1b0c480539eb1d4fb4a44 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 15:52:21 -0600 Subject: [PATCH 01/12] Update aurora --- extern/aurora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/aurora b/extern/aurora index 10006618ee..f8e9b14fb0 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 10006618ee493f248b8597e4dfa1d2871d76a1d9 +Subproject commit f8e9b14fb09b8ec727635c9b80bd910223ce947a From a68f4ae1e652417901935709fc0516d61bb67eca Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 16:20:11 -0600 Subject: [PATCH 02/12] Update aurora --- extern/aurora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/aurora b/extern/aurora index f8e9b14fb0..1fd905e742 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit f8e9b14fb09b8ec727635c9b80bd910223ce947a +Subproject commit 1fd905e742b901262eb32bbbccd402052578cbe4 From e4caf20a7a68c669980f5c77b3440b6bcc5baed2 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 16:27:28 -0600 Subject: [PATCH 03/12] Update aurora --- extern/aurora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/aurora b/extern/aurora index 1fd905e742..c954d044ef 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 1fd905e742b901262eb32bbbccd402052578cbe4 +Subproject commit c954d044ef902e917fd3ff124253eaf4aa7227f2 From 7a3e8977f144c3bb0bab3da2a1035694c59ba8ef Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 16:31:24 -0600 Subject: [PATCH 04/12] Disabled vendored Dawn for macOS --- CMakePresets.json | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index 0201c61ed6..ce84f84149 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -430,7 +430,6 @@ "x-macos-ci" ], "cacheVariables": { - "AURORA_DAWN_PROVIDER": "vendor", "CMAKE_OSX_ARCHITECTURES": "x86_64", "Rust_CARGO_TARGET": "x86_64-apple-darwin" } From db7e2a1e7b5d5a86d5070a31099b38f2a350b66b Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 17:00:08 -0600 Subject: [PATCH 05/12] Update aurora --- extern/aurora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/aurora b/extern/aurora index c954d044ef..db9923749f 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit c954d044ef902e917fd3ff124253eaf4aa7227f2 +Subproject commit db9923749fb6d24d84a0e6fc7ee875db8fa361af From ce0185adc462cb07bb81cec7da158e1c03b96b9a Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 23 May 2026 19:32:50 -0600 Subject: [PATCH 06/12] CI: Add ARM64 Windows and Linux builds (#1778) * ci: Try arm64 Linux/Windows builds * Update aurora * Explicitly set CMAKE_SYSTEM_PROCESSOR on Windows * Update build-appimage.sh for aarch64 * Set Rust_RUSTUP_INSTALL_MISSING_TARGET=ON * Use CMAKE_SYSTEM_PROCESSOR normalization for jpeg-turbo build too * MSVC ARM64 support for freeverb --- .github/workflows/build.yml | 24 ++++++++++++------------ CMakeLists.txt | 3 +++ CMakePresets.json | 11 +++++++++-- ci/build-appimage.sh | 3 ++- cmake/WindowsTargetProcessor.cmake | 9 +++++++++ extern/aurora | 2 +- libs/freeverb/denormals.h | 15 ++++++++++++++- 7 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 cmake/WindowsTargetProcessor.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 139b0654d3..a157fb8829 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,13 +22,13 @@ jobs: matrix: include: - name: GCC x86_64 - runner: ubuntu-latest + runner: ubuntu-24.04 preset: gcc artifact_arch: x86_64 - # - name: GCC aarch64 - # runner: ubuntu-24.04-arm - # preset: gcc - # artifact_arch: aarch64 + - name: GCC aarch64 + runner: ubuntu-24.04-arm + preset: gcc + artifact_arch: aarch64 # - name: Clang x86_64 # runner: ubuntu-latest # preset: clang @@ -221,12 +221,12 @@ jobs: msvc_arch: amd64 vcpkg_arch: x64 artifact_arch: x86_64 - # - name: MSVC arm64 - # runner: windows-11-arm - # preset: arm64-msvc - # msvc_arch: arm64 - # vcpkg_arch: arm64 - # artifact_arch: arm64 + - name: MSVC arm64 + runner: windows-latest + preset: arm64-msvc + msvc_arch: amd64_arm64 + vcpkg_arch: arm64 + artifact_arch: arm64 # - name: Clang x86_64 # runner: windows-latest # preset: clang @@ -255,7 +255,7 @@ jobs: - name: Install dependencies run: | choco install ninja - vcpkg install freetype:${{matrix.vcpkg_arch}}-windows-static zstd:${{matrix.vcpkg_arch}}-windows-static + vcpkg install freetype:${{matrix.vcpkg_arch}}-windows zstd:${{matrix.vcpkg_arch}}-windows - name: Configure CMake run: cmake --preset x-windows-ci-${{matrix.preset}} diff --git a/CMakeLists.txt b/CMakeLists.txt index 0659dc9c53..e93ba3cb22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,6 +100,8 @@ project(dusklight LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING}) if (APPLE) enable_language(OBJC OBJCXX) endif () +# Adjust CMAKE_SYSTEM_PROCESSOR on Windows to match compiler target +include(cmake/WindowsTargetProcessor.cmake) if (APPLE AND NOT TVOS AND CMAKE_SYSTEM_NAME STREQUAL tvOS) # ios.toolchain.cmake hack for SDL set(TVOS ON) @@ -168,6 +170,7 @@ if (DUSK_MOVIE_SUPPORT) endif () set(_jpeg_cmake_args -DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir} + -DCMAKE_PROJECT_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/WindowsTargetProcessor.cmake -DENABLE_SHARED=OFF -DWITH_TURBOJPEG=ON -DWITH_JAVA=OFF diff --git a/CMakePresets.json b/CMakePresets.json index ce84f84149..1c7f989b0c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -33,7 +33,11 @@ "value": true }, "DUSK_SENTRY_DSN": "$env{SENTRY_DSN}", - "DUSK_SENTRY_ENVIRONMENT": "production" + "DUSK_SENTRY_ENVIRONMENT": "production", + "Rust_RUSTUP_INSTALL_MISSING_TARGET": { + "type": "BOOL", + "value": true + } } }, { @@ -489,7 +493,10 @@ "inherits": [ "x-windows-ci", "windows-arm64-msvc" - ] + ], + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "arm64-windows" + } } ], "buildPresets": [ diff --git a/ci/build-appimage.sh b/ci/build-appimage.sh index 6653876f71..b401dab253 100755 --- a/ci/build-appimage.sh +++ b/ci/build-appimage.sh @@ -6,6 +6,7 @@ fi build_dir="$PWD/build" linuxdeploy="$build_dir/linuxdeploy-$(uname -m).AppImage" +lib_dir="/usr/lib/$(uname -m)-linux-gnu" # Get linuxdeploy mkdir -p "$build_dir" @@ -23,4 +24,4 @@ cp platforms/freedesktop/dusklight.desktop build/appdir/usr/share/applications cd build/install VERSION="$DUSK_VERSION" NO_STRIP=1 "$linuxdeploy" \ - -l /usr/lib/x86_64-linux-gnu/libusb-1.0.so --appdir "$build_dir/appdir" --output appimage + -l "$lib_dir/libusb-1.0.so" --appdir "$build_dir/appdir" --output appimage diff --git a/cmake/WindowsTargetProcessor.cmake b/cmake/WindowsTargetProcessor.cmake new file mode 100644 index 0000000000..0fba82add5 --- /dev/null +++ b/cmake/WindowsTargetProcessor.cmake @@ -0,0 +1,9 @@ +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + if (CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64" OR CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64EC") + set(CMAKE_SYSTEM_PROCESSOR "ARM64") + elseif (CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "x64") + set(CMAKE_SYSTEM_PROCESSOR "AMD64") + elseif (CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "X86") + set(CMAKE_SYSTEM_PROCESSOR "X86") + endif () +endif () diff --git a/extern/aurora b/extern/aurora index db9923749f..924a88cb1e 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit db9923749fb6d24d84a0e6fc7ee875db8fa361af +Subproject commit 924a88cb1edafc7ddbfb285a7872c71831685495 diff --git a/libs/freeverb/denormals.h b/libs/freeverb/denormals.h index d68cb444f7..9193798abe 100644 --- a/libs/freeverb/denormals.h +++ b/libs/freeverb/denormals.h @@ -13,20 +13,33 @@ inline denormal_state denormals_enable() } inline void denormals_restore(denormal_state saved) { _mm_setcsr(saved); } -#elif defined(__aarch64__) || defined(_M_ARM64) +#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) #include +#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM64) || defined(_M_ARM64EC)) +#include +#endif using denormal_state = uint64_t; inline denormal_state denormals_enable() { +#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM64) || defined(_M_ARM64EC)) + denormal_state saved = static_cast(_ReadStatusReg(ARM64_FPCR)); + _WriteStatusReg(ARM64_FPCR, static_cast<__int64>(saved | (1ULL << 24))); // FZ + return saved; +#else denormal_state saved; asm volatile("mrs %0, fpcr" : "=r"(saved)); asm volatile("msr fpcr, %0" :: "r"(saved | (1ULL << 24))); // FZ return saved; +#endif } inline void denormals_restore(denormal_state saved) { +#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM64) || defined(_M_ARM64EC)) + _WriteStatusReg(ARM64_FPCR, static_cast<__int64>(saved)); +#else asm volatile("msr fpcr, %0" :: "r"(saved)); +#endif } #elif defined(__arm__) || defined(_M_ARM) From beb4146f339d47fe1a11ce9c8a41143a6387baee Mon Sep 17 00:00:00 2001 From: SuperDude88 <82904174+SuperDude88@users.noreply.github.com> Date: Sat, 23 May 2026 21:41:18 -0400 Subject: [PATCH 07/12] Rework No Heart Drops (#1448) - Check the setting once in daItem_c::_daItem_create --- src/d/actor/d_a_obj_item.cpp | 5 +++ src/f_op/f_op_actor_mng.cpp | 60 ------------------------------------ 2 files changed, 5 insertions(+), 60 deletions(-) diff --git a/src/d/actor/d_a_obj_item.cpp b/src/d/actor/d_a_obj_item.cpp index e45de1933d..2c95c040be 100644 --- a/src/d/actor/d_a_obj_item.cpp +++ b/src/d/actor/d_a_obj_item.cpp @@ -268,6 +268,11 @@ int daItem_c::_daItem_create() { } m_itemNo = daItem_prm::getItemNo(this); +#if TARGET_PC + if (dusk::getSettings().game.noHeartDrops && isHeart(m_itemNo)) { + return cPhs_ERROR_e; + } +#endif BOOL flag = dItem_data::chkFlag(m_itemNo, 2); #if DEBUG diff --git a/src/f_op/f_op_actor_mng.cpp b/src/f_op/f_op_actor_mng.cpp index 208e868db2..dca07f98ba 100644 --- a/src/f_op/f_op_actor_mng.cpp +++ b/src/f_op/f_op_actor_mng.cpp @@ -1390,12 +1390,6 @@ fpc_ProcID fopAcM_createItemForPresentDemo(cXyz const* i_pos, int i_itemNo, u8 p JUT_ASSERT(3214, 0 <= i_itemNo && i_itemNo < 256); dComIfGp_event_setGtItm(i_itemNo); - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - if (i_itemNo == dItemNo_NONE_e) { OS_REPORT("プレゼントデモ用なのに「ハズレ」です![%d]\n", i_itemNo); // Even though it is for a Present Demo, it is a 'Miss'! return fpcM_ERROR_PROCESS_ID_e; @@ -1410,12 +1404,6 @@ fpc_ProcID fopAcM_createItemForTrBoxDemo(cXyz const* i_pos, int i_itemNo, int i_ JUT_ASSERT(3259, 0 <= i_itemNo && i_itemNo < 256); dComIfGp_event_setGtItm(i_itemNo); - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - if (i_itemNo == dItemNo_NONE_e) { OS_REPORT("ゲットデモ用なのに「ハズレ」です![%d]\n", i_itemNo); // Even though it is for a Get Demo, it is a 'Miss'! return fpcM_ERROR_PROCESS_ID_e; @@ -1541,12 +1529,6 @@ fpc_ProcID fopAcM_createItemFromTable(cXyz const* i_pos, int i_itemNo, int i_ite JUT_ASSERT(3655, 0 <= i_itemNo && i_itemNo <= 255 && (-1 <= i_itemBitNo && i_itemBitNo < (dSv_info_c::DAN_ITEM + dSv_info_c::MEMORY_ITEM + dSv_info_c::ZONE_ITEM )) || i_itemBitNo == 255); // clang-format on - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - u8 tableNum; ItemTableList* tableList; tableList = (ItemTableList*)dComIfGp_getItemTable(); @@ -1590,12 +1572,6 @@ fpc_ProcID fopAcM_createDemoItem(const cXyz* i_pos, int i_itemNo, int i_itemBitN JUT_ASSERT(3824, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo < (dSv_info_c::DAN_ITEM + dSv_info_c::MEMORY_ITEM + dSv_info_c::ZONE_ITEM )) || i_itemBitNo == 255); // clang-format on - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - if (i_itemNo == dItemNo_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } @@ -1607,12 +1583,6 @@ fpc_ProcID fopAcM_createDemoItem(const cXyz* i_pos, int i_itemNo, int i_itemBitN fpc_ProcID fopAcM_createItemForBoss(const cXyz* i_pos, int i_itemNo, int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, f32 i_speedF, f32 i_speedY, int param_8) { - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - int _ = -1; u32 params = 0xFFFF0000 | param_8 << 8 | (i_itemNo & 0xFF); @@ -1629,12 +1599,6 @@ fpc_ProcID fopAcM_createItemForBoss(const cXyz* i_pos, int i_itemNo, int i_roomN fpc_ProcID fopAcM_createItemForMidBoss(const cXyz* i_pos, int i_itemNo, int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, int param_6, int param_7) { - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - UNUSED(i_angle); UNUSED(param_6); fpc_ProcID ret = -1; @@ -1646,12 +1610,6 @@ fpc_ProcID fopAcM_createItemForMidBoss(const cXyz* i_pos, int i_itemNo, int i_ro fopAc_ac_c* fopAcM_createItemForDirectGet(const cXyz* i_pos, int i_itemNo, int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, f32 i_speedF, f32 i_speedY) { - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return NULL; - } - #endif - fopAc_ac_c* item = fopAcM_fastCreateItem(i_pos, i_itemNo, i_roomNo, i_angle, i_scale, &i_speedF, &i_speedY, -1, 0x7, NULL); fopAc_ac_c* ret = item; @@ -1661,12 +1619,6 @@ fopAc_ac_c* fopAcM_createItemForDirectGet(const cXyz* i_pos, int i_itemNo, int i fopAc_ac_c* fopAcM_createItemForSimpleDemo(const cXyz* i_pos, int i_itemNo, int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, f32 i_speedF, f32 i_speedY) { - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return NULL; - } - #endif - fopAc_ac_c* item = fopAcM_fastCreateItem(i_pos, i_itemNo, i_roomNo, i_angle, i_scale, &i_speedF, &i_speedY, -1, 0x4, NULL); fopAc_ac_c* ret = item; @@ -1679,12 +1631,6 @@ fpc_ProcID fopAcM_createItem(const cXyz* i_pos, int i_itemNo, int i_itemBitNo, i JUT_ASSERT(4067, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo < (dSv_info_c::DAN_ITEM + dSv_info_c::MEMORY_ITEM + dSv_info_c::ZONE_ITEM )) || i_itemBitNo == 255); // clang-format on - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return fpcM_ERROR_PROCESS_ID_e; - } - #endif - if (i_itemNo == dItemNo_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } @@ -1749,12 +1695,6 @@ fopAc_ac_c* fopAcM_fastCreateItem2(const cXyz* i_pos, int i_itemNo, int i_itemBi JUT_ASSERT(4202, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo < (dSv_info_c::DAN_ITEM + dSv_info_c::MEMORY_ITEM + dSv_info_c::ZONE_ITEM )) || i_itemBitNo == 255); // clang-format on - #if TARGET_PC - if (dusk::getSettings().game.noHeartDrops && isHeart(i_itemNo)) { - return NULL; - } - #endif - csXyz item_angle(csXyz::Zero); if (i_itemNo == dItemNo_NONE_e) { From 533c76f4d65a4237fcf9b115f20d9a71fe23b306 Mon Sep 17 00:00:00 2001 From: Carlos Manuel Date: Sat, 23 May 2026 19:43:02 -0600 Subject: [PATCH 08/12] Add support for changing save location on Android (#1520) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enabled the Android UI path for changing the data folder - Added Android MANAGE_EXTERNAL_STORAGE permission - Added an Android flow to request “All files access” before opening the folder picker - Added code path to resume the folder selection flow after returning from Android settings - Improved the Android write-probe error message to point users at the required permission --- .../android/app/src/main/AndroidManifest.xml | 1 + .../com/twilitrealm/dusk/DuskActivity.java | 81 +++++++++++++++++++ src/dusk/data.cpp | 7 ++ src/dusk/data.hpp | 2 +- 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/platforms/android/app/src/main/AndroidManifest.xml b/platforms/android/app/src/main/AndroidManifest.xml index f5a0365856..cd687963e1 100644 --- a/platforms/android/app/src/main/AndroidManifest.xml +++ b/platforms/android/app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ + { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | @@ -185,9 +204,71 @@ public class DuskActivity extends SDLActivity { finishFolderDialog(Activity.RESULT_CANCELED, null); } }); + } + + private boolean requiresManageStoragePermission() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R; + } + + private boolean hasManageStoragePermission() { + return !requiresManageStoragePermission() || Environment.isExternalStorageManager(); + } + + private boolean requestManageStoragePermission() { + if (!requiresManageStoragePermission()) { + return true; + } + + awaitingManageStoragePermission = true; + runOnUiThread(() -> { + if (tryStartManageStorageIntent( + new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + .setData(Uri.parse("package:" + getPackageName()))) || + tryStartManageStorageIntent( + new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION))) + { + return; + } + + finishFolderDialogWithError("Unable to request Android file access permission"); + }); return true; } + private boolean tryStartManageStorageIntent(Intent intent) { + try { + startActivityForResult(intent, MANAGE_STORAGE_REQUEST_CODE); + return true; + } catch (ActivityNotFoundException e) { + Log.w(TAG, "Unable to open all-files access settings.", e); + return false; + } + } + + private void resumeFolderDialogAfterPermissionGrant() { + awaitingManageStoragePermission = false; + if (folderDialogUserdata == 0) { + return; + } + + if (hasManageStoragePermission()) { + openFolderDialog(); + return; + } + + finishFolderDialogWithError( + "Allow \"All files access\" for Dusklight before choosing a custom data folder"); + } + + private void finishFolderDialogWithError(String error) { + long userdata = folderDialogUserdata; + folderDialogUserdata = 0; + awaitingManageStoragePermission = false; + if (userdata != 0) { + nativeFolderDialogResult(userdata, null, error); + } + } + private void finishFolderDialog(int resultCode, Intent data) { long userdata = folderDialogUserdata; folderDialogUserdata = 0; diff --git a/src/dusk/data.cpp b/src/dusk/data.cpp index ce61965947..dc666dd236 100644 --- a/src/dusk/data.cpp +++ b/src/dusk/data.cpp @@ -525,7 +525,14 @@ bool validate_writable_data_path(const std::filesystem::path& path, std::string* try { io::FileStream::WriteAllText(probePath, "dusk"); } catch (const std::exception& e) { +#if defined(__ANDROID__) + set_error(errorOut, + fmt::format("{} could not write to the selected folder. On Android, allow " + "\"All files access\" for Dusklight and try again.", + AppName)); +#else set_error(errorOut, fmt::format("{} could not write to the selected folder.", AppName)); +#endif Log.warn("Failed write probe for custom data folder '{}': {}", io::fs_path_to_string(path), e.what()); return false; diff --git a/src/dusk/data.hpp b/src/dusk/data.hpp index c3ce495b46..bf20035a2d 100644 --- a/src/dusk/data.hpp +++ b/src/dusk/data.hpp @@ -15,7 +15,7 @@ #define DUSK_CAN_OPEN_DATA_FOLDER 0 #endif -#if (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || defined(__ANDROID__) +#if (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) #define DUSK_CAN_CHANGE_DATA_FOLDER 0 #else #define DUSK_CAN_CHANGE_DATA_FOLDER 1 From e9a76282184ffb12a90d8ce2b94738573e4210ad Mon Sep 17 00:00:00 2001 From: Reilly Brogan Date: Sat, 23 May 2026 20:56:24 -0500 Subject: [PATCH 09/12] linux: Fix Wayland window associations (#1718) * linux: Fix Wayland window associations `src/m_Do/m_Do_main.cpp` uses `SDL_SetAppMetadata("Dusklight", DUSK_VERSION_STRING, "dev.twilitrealm.dusk")` which results in the Wayland appId getting set to `dev.twilitrealm.dusk`. Wayland compositors associate Wayland windows to desktop files by comparing the window appId against installed desktop files by the name of the desktop files. For a given window with appId `dev.twilitrealm.dusk` it would look for `dev.twilitrealm.dusk.desktop`, and because the desktop file is not named that the compositor is unable to correctly associate the window which results in the default Wayland icon being shown for the window. It also results in windows not being associated with the given launcher if the desktop file is pinned to a task management widget of some kind. Fix this by renaming the desktop file to `dev.twilitrealm.dusk.desktop`. Also while we're at it we can rename the icons as well to match the desktop file name, which isn't required but is a bit cleaner and will fit various packaging standards better. Signed-off-by: Reilly Brogan * Use dev.twilitrealm.dusk instead --------- Signed-off-by: Reilly Brogan --- ci/build-appimage.sh | 2 +- flake.nix | 8 ++++---- .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin .../{dusklight.png => dev.twilitrealm.dusk.png} | Bin ...sklight.desktop => dev.twilitrealm.dusk.desktop} | 2 +- 11 files changed, 6 insertions(+), 6 deletions(-) rename platforms/freedesktop/1024x1024/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/128x128/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/16x16/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/256x256/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/32x32/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/48x48/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/512x512/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/64x64/apps/{dusklight.png => dev.twilitrealm.dusk.png} (100%) rename platforms/freedesktop/{dusklight.desktop => dev.twilitrealm.dusk.desktop} (86%) diff --git a/ci/build-appimage.sh b/ci/build-appimage.sh index b401dab253..e12f1163b9 100755 --- a/ci/build-appimage.sh +++ b/ci/build-appimage.sh @@ -20,7 +20,7 @@ for install_path in build/install/*; do cp -r "$install_path" build/appdir/usr/bin done cp -r platforms/freedesktop/{16x16,32x32,48x48,64x64,128x128,256x256,512x512,1024x1024} build/appdir/usr/share/icons/hicolor -cp platforms/freedesktop/dusklight.desktop build/appdir/usr/share/applications +cp platforms/freedesktop/dev.twilitrealm.dusk.desktop build/appdir/usr/share/applications cd build/install VERSION="$DUSK_VERSION" NO_STRIP=1 "$linuxdeploy" \ diff --git a/flake.nix b/flake.nix index 90c0d21533..0a2156a4d5 100644 --- a/flake.nix +++ b/flake.nix @@ -248,11 +248,11 @@ runHook preInstall install -Dm755 dusklight "$out/bin/dusklight" cp -r "$src/res" "$out/bin/res" - install -Dm644 "$src/platforms/freedesktop/dusklight.desktop" \ - "$out/share/applications/dusklight.desktop" + install -Dm644 "$src/platforms/freedesktop/dev.twilitrealm.dusk.desktop" \ + "$out/share/applications/dev.twilitrealm.dusk.desktop" for size in 16 32 48 64 128 256 512 1024; do - install -Dm644 "$src/platforms/freedesktop/''${size}x''${size}/apps/dusklight.png" \ - "$out/share/icons/hicolor/''${size}x''${size}/apps/dusklight.png" + install -Dm644 "$src/platforms/freedesktop/''${size}x''${size}/apps/dev.twilitrealm.dusk.png" \ + "$out/share/icons/hicolor/''${size}x''${size}/apps/dev.twilitrealm.dusk.png" done runHook postInstall ''; diff --git a/platforms/freedesktop/1024x1024/apps/dusklight.png b/platforms/freedesktop/1024x1024/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/1024x1024/apps/dusklight.png rename to platforms/freedesktop/1024x1024/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/128x128/apps/dusklight.png b/platforms/freedesktop/128x128/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/128x128/apps/dusklight.png rename to platforms/freedesktop/128x128/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/16x16/apps/dusklight.png b/platforms/freedesktop/16x16/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/16x16/apps/dusklight.png rename to platforms/freedesktop/16x16/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/256x256/apps/dusklight.png b/platforms/freedesktop/256x256/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/256x256/apps/dusklight.png rename to platforms/freedesktop/256x256/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/32x32/apps/dusklight.png b/platforms/freedesktop/32x32/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/32x32/apps/dusklight.png rename to platforms/freedesktop/32x32/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/48x48/apps/dusklight.png b/platforms/freedesktop/48x48/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/48x48/apps/dusklight.png rename to platforms/freedesktop/48x48/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/512x512/apps/dusklight.png b/platforms/freedesktop/512x512/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/512x512/apps/dusklight.png rename to platforms/freedesktop/512x512/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/64x64/apps/dusklight.png b/platforms/freedesktop/64x64/apps/dev.twilitrealm.dusk.png similarity index 100% rename from platforms/freedesktop/64x64/apps/dusklight.png rename to platforms/freedesktop/64x64/apps/dev.twilitrealm.dusk.png diff --git a/platforms/freedesktop/dusklight.desktop b/platforms/freedesktop/dev.twilitrealm.dusk.desktop similarity index 86% rename from platforms/freedesktop/dusklight.desktop rename to platforms/freedesktop/dev.twilitrealm.dusk.desktop index 4f6ba034a9..b1ad2831a2 100644 --- a/platforms/freedesktop/dusklight.desktop +++ b/platforms/freedesktop/dev.twilitrealm.dusk.desktop @@ -3,7 +3,7 @@ Name=Dusklight GenericName=Dusklight Comment=PC port of a classic adventure game Exec=dusklight -Icon=dusklight +Icon=dev.twilitrealm.dusk Terminal=false Type=Application Categories=Game; From 114e6e60bb4239d14cfdf0ff3a972eff6addc7a7 Mon Sep 17 00:00:00 2001 From: Irastris Date: Sat, 23 May 2026 22:15:32 -0400 Subject: [PATCH 10/12] build.yml revisions (#1744) * build.yml revisions * Undo push and PR changes --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a157fb8829..7c0cc1b846 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,10 @@ on: - '*LICENSE' pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: SCCACHE_GHA_ENABLED: "true" RUSTC_WRAPPER: "sccache" From ac316f6288821a16e4cc287bc5992b32a25f5087 Mon Sep 17 00:00:00 2001 From: Olivia!! Date: Sun, 24 May 2026 04:16:02 +0200 Subject: [PATCH 11/12] fixes empty howl tab near certain actors (#1771) When howling suns song near actors that arent howl stones, an empty howl tab was shown. This fixes the issue by duplicating a check for sun's song howling into the relevant code branch. --- src/d/actor/d_a_alink_wolf.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d/actor/d_a_alink_wolf.inc b/src/d/actor/d_a_alink_wolf.inc index 67fde3a7a7..43b60e9d42 100644 --- a/src/d/actor/d_a_alink_wolf.inc +++ b/src/d/actor/d_a_alink_wolf.inc @@ -4005,7 +4005,13 @@ int daAlink_c::procWolfHowlDemoInit() { } else if (name == fpcNm_Tag_WaraHowl_e) { mZ2WolfHowlMgr.setCorrectCurve(static_cast(field_0x27f4)->getTuneId()); } else { + #if TARGET_PC + if (mZ2WolfHowlMgr.getCorrectCurveID() != 9) { + mZ2WolfHowlMgr.setCorrectCurve(-1); + } + #else mZ2WolfHowlMgr.setCorrectCurve(-1); + #endif } } else { #if TARGET_PC From edc4aa0be4551b261ba606be99ed14b132e3b6c9 Mon Sep 17 00:00:00 2001 From: Olivia!! Date: Sun, 24 May 2026 05:31:19 +0200 Subject: [PATCH 12/12] Fixes linux credits crash (#1780) alpha comparison mID is u16, but indexes into a 256-item table. this causes MAT3 materials with an alpha comparison index of 0xFF crashes on linux closes #1073 closes #1531 --- libs/JSystem/include/JSystem/J3DGraphBase/J3DMatBlock.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/JSystem/include/JSystem/J3DGraphBase/J3DMatBlock.h b/libs/JSystem/include/JSystem/J3DGraphBase/J3DMatBlock.h index a959609f45..859bd6943e 100644 --- a/libs/JSystem/include/JSystem/J3DGraphBase/J3DMatBlock.h +++ b/libs/JSystem/include/JSystem/J3DGraphBase/J3DMatBlock.h @@ -1575,6 +1575,12 @@ struct J3DAlphaComp { u8 getRef1() const { return mRef1; } void load() const { +#ifdef AVOID_UB + if (mID > 255) { + J3DGDSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + return; + } +#endif J3DGDSetAlphaCompare((GXCompare)getComp0(), mRef0, (GXAlphaOp)getOp(), (GXCompare)getComp1(), mRef1); }