diff --git a/CMakeLists.txt b/CMakeLists.txt index cf69a8e2ac..0659dc9c53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ if (DUSK_VERSION_OVERRIDE) set(DUSK_WC_DESCRIBE "${DUSK_VERSION_OVERRIDE}") set(DUSK_VERSION_STRING "0.0.0.0") set(DUSK_SHORT_VERSION_STRING "0.0.0") + set(DUSK_VERSION_CODE "1") set(DUSK_WC_REVISION "") set(DUSK_WC_BRANCH "") set(DUSK_WC_DATE "") @@ -61,6 +62,9 @@ endif () if (DUSK_WC_DESCRIBE MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)([-+].*)?$") set(DUSK_SHORT_VERSION_STRING "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + set(_ver_major ${CMAKE_MATCH_1}) + set(_ver_minor ${CMAKE_MATCH_2}) + set(_ver_patch ${CMAKE_MATCH_3}) set(DUSK_VERSION_TWEAK "0") if (DUSK_WC_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+)(-dirty)?$") set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}") @@ -68,10 +72,19 @@ if (DUSK_WC_DESCRIBE MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)([-+].*)?$") set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}") endif () set(DUSK_VERSION_STRING "${DUSK_SHORT_VERSION_STRING}.${DUSK_VERSION_TWEAK}") + if(DUSK_VERSION_TWEAK GREATER 999) + set(_tweak 999) + else() + set(_tweak ${DUSK_VERSION_TWEAK}) + endif() + # encoding: major*1e7 + minor*1e5 + patch*1e3 + tweak; collision-free for major<210, minor<100, patch<100, tweak<=999 + math(EXPR DUSK_VERSION_CODE + "${_ver_major} * 10000000 + ${_ver_minor} * 100000 + ${_ver_patch} * 1000 + ${_tweak}") else () set(DUSK_WC_DESCRIBE "UNKNOWN-VERSION") set(DUSK_VERSION_STRING "0.0.0.0") set(DUSK_SHORT_VERSION_STRING "0.0.0") + set(DUSK_VERSION_CODE "1") endif () endif () @@ -79,6 +92,7 @@ endif () # Add version information to CI environment variables if(DEFINED ENV{GITHUB_ENV}) file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION=${DUSK_WC_DESCRIBE}\n") + file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION_CODE=${DUSK_VERSION_CODE}\n") endif() message(STATUS "Dusklight version set to ${DUSK_WC_DESCRIBE}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") 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 diff --git a/flake.lock b/flake.lock index 8ec14d2852..08dc0f458c 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1775710090, - "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "4c1018dae018162ec878d42fec712642d214fdfa", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 29c99b10a5..90c0d21533 100644 --- a/flake.nix +++ b/flake.nix @@ -1,219 +1,374 @@ { - inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - }; - outputs = { self, nixpkgs }: + description = "Dusklight — native PC port of the Twilight Princess decompilation"; + + inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + outputs = + { self, nixpkgs }: let + inherit (nixpkgs) lib; + supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; - forAllSystems = nixpkgs.lib.genAttrs supportedSystems; - pkgsFor = system: import nixpkgs { inherit system; }; + forAllSystems = lib.genAttrs supportedSystems; - # Dependencies that are not packaged in nixpkgs (used by the Linux package build): - buildSources = pkgs: { - dawn-src = pkgs.fetchzip { - url = "https://github.com/encounter/dawn-build/releases/download/v20260423.175430/dawn-linux-x86_64.tar.gz"; + dawnVersion = "v20260423.175430"; + nodVersion = "v2.0.0-alpha.8"; + versionSuffix = "nix-" + (self.shortRev or self.dirtyShortRev or "dirty"); + + dawnInfo = { + "x86_64-linux" = { + triple = "linux-x86_64"; hash = "sha256-HXfKTLHtMPwupnFnaflCARtXVPuS/0PoCePXidjE5xs="; - stripRoot = false; }; - nod-src = pkgs.fetchzip { - url = "https://github.com/encounter/nod/releases/download/v2.0.0-alpha.8/libnod-linux-x86_64.tar.gz"; - hash = "sha256-mUqvLsbsqaZ+HAjMmHYPYO+MgtanGRTw7Gzn5uXR5rE="; - stripRoot = false; + "aarch64-linux" = { + triple = "linux-aarch64"; + hash = "sha256-34yyFpfqBZUwoFXQ41F0AwAU78FaNihOSY0oriwn6B0="; }; - # The version of imgui on nixpkgs does not map cleanly. - imgui-src = pkgs.fetchFromGitHub { - owner = "ocornut"; - repo = "imgui"; - rev = "v1.91.9b-docking"; - hash = "sha256-mQOJ6jCN+7VopgZ61yzaCnt4R1QLrW7+47xxMhFRHLQ="; + "aarch64-darwin" = { + triple = "darwin-arm64"; + hash = "sha256-eQnzrBp6gjiBek1VYQ9A5W13ClYWrDDKjIqv/7eNTR4="; }; - sqlite-src = pkgs.fetchzip { - url = "https://sqlite.org/2026/sqlite-amalgamation-3510300.zip"; - hash = "sha256-pNMR8zxaaqfAzQ0AQBOXMct4usdjey1Q0Gnitg06UhM="; - }; - rmlui-src = pkgs.fetchzip { - url = "https://github.com/mikke89/RmlUi/archive/f9b8c9e2935d5df2c7dff2c190d3968e99b0c3dc.tar.gz"; - hash = "sha256-g4O/JZUrrcseOz8o2QJRt+2CeuiLnVeuDJc906xvuIg="; + "x86_64-darwin" = { + triple = "darwin-x86_64"; + hash = "sha256-QGWiGdxiI9kci3NPXH6QFFirxn16851zB/w3jqhIBJ4="; }; }; - # Dusklight Actual (Linux x86_64 only — relies on prebuilt dawn/nod binaries) - mkDusklight = pkgs: - let srcs = buildSources pkgs; - versionSuffix = if self ? shortRev && self.shortRev != null - then "nix-${self.shortRev}" - else "nix-dirty"; - in - pkgs.stdenv.mkDerivation { - name = "dusklight"; - src = ./.; - postUnpack = '' - sed -i '/add_subdirectory(tests)/d' $sourceRoot/extern/aurora/CMakeLists.txt - ''; - # Remove last line to re-enable tests - cmakeFlags = [ - "-DDUSK_VERSION_OVERRIDE=${versionSuffix}" - "-DFETCHCONTENT_FULLY_DISCONNECTED=ON" - "-DFETCHCONTENT_SOURCE_DIR_CXXOPTS=${pkgs.cxxopts.src}" - "-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}" - "-DFETCHCONTENT_SOURCE_DIR_DAWN_PREBUILT=${srcs.dawn-src}" - "-DFETCHCONTENT_SOURCE_DIR_XXHASH=${pkgs.xxHash.src}" - "-DFETCHCONTENT_SOURCE_DIR_FMT=${pkgs.fmt.src}" - "-DFETCHCONTENT_SOURCE_DIR_TRACY=${pkgs.tracy.src}" - "-DAURORA_SDL3_PROVIDER=system" - "-DFETCHCONTENT_SOURCE_DIR_NOD_PREBUILT=${srcs.nod-src}" - "-DAURORA_NOD_PROVIDER=package" - "-DFETCHCONTENT_SOURCE_DIR_FREETYPE=${pkgs.freetype.src}" - "-DFETCHCONTENT_SOURCE_DIR_ZSTD=${pkgs.zstd.src}" - "-DFETCHCONTENT_SOURCE_DIR_SQLITE3=${srcs.sqlite-src}" - "-DFETCHCONTENT_SOURCE_DIR_IMGUI=${srcs.imgui-src}" - "-DFETCHCONTENT_SOURCE_DIR_RMLUI=${srcs.rmlui-src}" - "-DCMAKE_CROSSCOMPILING=ON" # Tests are not working as I didn't want to work through getting google's test suite working as well. This is the only guard I could find to disable it. - ]; - installPhase = '' - mkdir -p $out/bin - cp dusklight $out/bin/dusklight - cp -r ./res $out/bin/res + nodPrebuiltInfo = { + "x86_64-linux" = { + triple = "linux-x86_64"; + hash = "sha256-mUqvLsbsqaZ+HAjMmHYPYO+MgtanGRTw7Gzn5uXR5rE="; + }; + "aarch64-darwin" = { + triple = "macos-arm64"; + hash = "sha256-UPy1ywCcv0K6VJOU3uUelJuUdBh3UNaPRlyP5LOBeDw="; + }; + }; - mkdir -p $out/share/applications - cp $src/platforms/freedesktop/dusklight.desktop $out/share/applications/dusklight.desktop + perSystem = + system: + let + pkgs = import nixpkgs { inherit system; }; + inherit (pkgs.stdenv.hostPlatform) isDarwin; + hasNodPrebuilt = nodPrebuiltInfo ? ${system}; - 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 - done - ''; - nativeBuildInputs = [ + aurora = pkgs.fetchFromGitHub { + owner = "encounter"; + repo = "aurora"; + rev = "10006618ee493f248b8597e4dfa1d2871d76a1d9"; + hash = "sha256-lY2xuVyB7aPJ9+2wwLRB3F5U/BuPSxdSpegdG+qNd9o="; + }; + + dawn = pkgs.fetchzip { + url = "https://github.com/encounter/dawn-build/releases/download/${dawnVersion}/dawn-${dawnInfo.${system}.triple}.tar.gz"; + hash = dawnInfo.${system}.hash; + stripRoot = false; + }; + + corrosion = pkgs.fetchFromGitHub { + owner = "corrosion-rs"; + repo = "corrosion"; + rev = "v0.6.1"; + hash = "sha256-ppuDNObfKhneD9AlnPAvyCRHKW3BidXKglD1j/LE9CM="; + }; + + nodFromSource = pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "nod"; + version = nodVersion; + src = pkgs.fetchFromGitHub { + owner = "encounter"; + repo = "nod"; + rev = nodVersion; + hash = "sha256-+zrtVzjo0+X/6uMcNUn1+FaSR+jOhrcQSDNBFjw0NDs="; + }; + cargoDeps = pkgs.rustPlatform.importCargoLock { + lockFile = "${finalAttrs.src}/Cargo.lock"; + }; + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-warn "add_subdirectory(nod-ffi/examples)" "" + ''; + nativeBuildInputs = [ + pkgs.cmake + pkgs.ninja + pkgs.rustPlatform.cargoSetupHook + pkgs.cargo + pkgs.rustc + ]; + CARGO_NET_OFFLINE = "true"; + cmakeFlags = [ + "-DFETCHCONTENT_FULLY_DISCONNECTED=ON" + "-DFETCHCONTENT_SOURCE_DIR_CORROSION=${corrosion}" + "-DNOD_ENABLE_INSTALL=ON" + "-DBUILD_SHARED_LIBS=OFF" + ]; + doCheck = false; + }); + + nod = + if hasNodPrebuilt then + pkgs.fetchzip { + url = "https://github.com/encounter/nod/releases/download/${nodVersion}/libnod-${ + nodPrebuiltInfo.${system}.triple + }.tar.gz"; + hash = nodPrebuiltInfo.${system}.hash; + stripRoot = false; + } + else + nodFromSource; + + fetchContentDirs = { + DAWN_PREBUILT = dawn; + NOD_PREBUILT = nod; + CXXOPTS = pkgs.cxxopts.src; + JSON = pkgs.nlohmann_json.src; + XXHASH = pkgs.xxHash.src; + ZSTD = pkgs.zstd.src; + FMT = pkgs.fetchzip { + url = "https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz"; + hash = "sha256-sUbxlYi/Aupaox3JjWFqXIjcaQa0LFjclQAOleT+FRA="; + }; + TRACY = pkgs.fetchzip { + url = "https://github.com/wolfpld/tracy/archive/a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz"; + hash = "sha256-hbNGOsGeyGSvCJ2No8RkwOib1lX2on3vNZSzyVkZdXw="; + }; + IMGUI = pkgs.fetchFromGitHub { + owner = "ocornut"; + repo = "imgui"; + rev = "v1.91.9b-docking"; + hash = "sha256-mQOJ6jCN+7VopgZ61yzaCnt4R1QLrW7+47xxMhFRHLQ="; + }; + SQLITE3 = pkgs.fetchzip { + url = "https://sqlite.org/2026/sqlite-amalgamation-3510300.zip"; + hash = "sha256-pNMR8zxaaqfAzQ0AQBOXMct4usdjey1Q0Gnitg06UhM="; + }; + RMLUI = pkgs.fetchzip { + url = "https://github.com/mikke89/RmlUi/archive/f9b8c9e2935d5df2c7dff2c190d3968e99b0c3dc.tar.gz"; + hash = "sha256-g4O/JZUrrcseOz8o2QJRt+2CeuiLnVeuDJc906xvuIg="; + }; + }; + + dusklight = pkgs.stdenv.mkDerivation { + pname = "dusklight"; + version = versionSuffix; + src = ./.; + + postUnpack = '' + chmod -R u+w "$sourceRoot" + rm -rf "$sourceRoot/extern/aurora" + mkdir -p "$sourceRoot/extern" + cp -r ${aurora} "$sourceRoot/extern/aurora" + chmod -R u+w "$sourceRoot/extern/aurora" + substituteInPlace "$sourceRoot/extern/aurora/CMakeLists.txt" \ + --replace-warn "add_subdirectory(tests)" "" + ''; + + nativeBuildInputs = [ + pkgs.cmake + pkgs.ninja + pkgs.pkg-config + pkgs.python3 + pkgs.python3Packages.markupsafe + ] + ++ lib.optionals (!isDarwin) [ pkgs.autoPatchelfHook ]; + + buildInputs = [ + pkgs.sdl3 + pkgs.freetype + pkgs.zstd + pkgs.cxxopts + pkgs.nlohmann_json + pkgs.xxHash + pkgs.abseil-cpp + pkgs.zlib + pkgs.libpng + pkgs.libjpeg_turbo + pkgs.curl + pkgs.openssl + ] + ++ lib.optionals isDarwin [ + pkgs.apple-sdk_15 + pkgs.libiconv + ] + ++ lib.optionals (!isDarwin) [ + pkgs.libGL + pkgs.libGLU + pkgs.libglvnd + pkgs.vulkan-loader + pkgs.libX11 + pkgs.libxcb + pkgs.libXcursor + pkgs.libxi + pkgs.libxrandr + pkgs.libxscrnsaver + pkgs.libxtst + pkgs.libxinerama + pkgs.libxkbcommon + pkgs.wayland + pkgs.libdecor + pkgs.alsa-lib + pkgs.libpulseaudio + pkgs.pipewire + pkgs.dbus + pkgs.udev + pkgs.libusb1 + pkgs.libunwind + pkgs.gtk3 + ]; + + cmakeBuildType = "RelWithDebInfo"; + ninjaFlags = [ "dusklight" ]; + + cmakeFlags = [ + "-DDUSK_VERSION_OVERRIDE=${versionSuffix}" + "-DFETCHCONTENT_FULLY_DISCONNECTED=ON" + "-DAURORA_DAWN_PROVIDER=package" + "-DAURORA_DAWN_LINKAGE=static" + "-DAURORA_NOD_PROVIDER=package" + "-DAURORA_NOD_LINKAGE=static" + "-DAURORA_SDL3_PROVIDER=system" + ] + ++ lib.mapAttrsToList (key: src: "-DFETCHCONTENT_SOURCE_DIR_${key}=${src}") fetchContentDirs; + + installPhase = + if isDarwin then + '' + runHook preInstall + mkdir -p "$out/Applications" + cp -r Dusklight.app "$out/Applications/Dusklight.app" + runHook postInstall + '' + else + '' + 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" + 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" + done + runHook postInstall + ''; + + dontStrip = true; + + meta = { + description = "Dusklight — native PC port of the Twilight Princess decompilation"; + homepage = "https://github.com/zeldaret/tp"; + platforms = supportedSystems; + mainProgram = "dusklight"; + }; + }; + + # Tooling common to every supported host (Linux and macOS). + commonDevTools = [ pkgs.cmake + pkgs.ninja pkgs.pkg-config - pkgs.wayland + pkgs.git + pkgs.python3 + pkgs.python3Packages.markupsafe + pkgs.rustc + pkgs.cargo + pkgs.sccache ]; - buildInputs = [ - pkgs.libGL - pkgs.libX11 - pkgs.libXcursor - pkgs.libxi - pkgs.libxcb - pkgs.libxrandr - pkgs.libxscrnsaver - pkgs.libxtst - pkgs.libjpeg8 - pkgs.libxkbcommon - pkgs.libglvnd + + # Linux-only system libraries — mirrors the apt deps from .github/workflows/build.yml + # so the cmake presets resolve the same set of headers as CI. + linuxDevDeps = [ + # Compilers / linkers + pkgs.clang + pkgs.lld + # C/C++ utilities + pkgs.curl + pkgs.openssl + pkgs.zlib + pkgs.libpng + pkgs.libjpeg_turbo + pkgs.freetype + pkgs.zstd + pkgs.fmt + pkgs.tracy pkgs.cxxopts pkgs.abseil-cpp pkgs.sdl3 - pkgs.fmt - pkgs.tracy - pkgs.freetype - pkgs.zstd + pkgs.ncurses + pkgs.libunwind + pkgs.libusb1 + pkgs.fuse + # Wayland / display server + pkgs.wayland + pkgs.wayland-protocols + pkgs.libxkbcommon + pkgs.libdecor + # OpenGL / Vulkan + pkgs.libGL + pkgs.libGLU + pkgs.libglvnd + pkgs.vulkan-headers + pkgs.vulkan-loader + # X11 + pkgs.libX11 + pkgs.libxcb + pkgs.libXcursor + pkgs.libxi + pkgs.libxrandr + pkgs.libxscrnsaver + pkgs.libxtst + pkgs.libxinerama + # Audio + pkgs.alsa-lib + pkgs.libpulseaudio + pkgs.pipewire + # System integration + pkgs.dbus + pkgs.udev + pkgs.gtk3 ]; + + # On macOS we deliberately avoid pulling Nix's cc-wrapper so CMake picks up + # Apple Clang and the Xcode SDK directly, matching the macOS CI workflow. + darwinShell = pkgs.mkShellNoCC { + packages = commonDevTools; + shellHook = '' + echo "Dusklight dev shell (macOS)" + echo "Requires Xcode Command Line Tools for Apple Clang and the macOS SDK." + echo "Configure: cmake --preset macos-default-relwithdebinfo" + echo "Build: cmake --build --preset macos-default-relwithdebinfo" + ''; + }; + + linuxShell = pkgs.mkShell { + packages = commonDevTools ++ linuxDevDeps; + shellHook = '' + echo "Dusklight dev shell (Linux)" + echo "Configure: cmake --preset linux-default-relwithdebinfo" + echo " cmake --preset linux-clang-relwithdebinfo" + echo "Build: cmake --build --preset " + ''; + }; + in + { + packages = { + default = dusklight; + dusklight = dusklight; + } + // lib.optionalAttrs (!hasNodPrebuilt) { nod = nodFromSource; }; + + devShells.default = if isDarwin then darwinShell else linuxShell; }; - # Tooling common to every supported host (Linux and macOS). - commonDevTools = pkgs: [ - pkgs.cmake - pkgs.ninja - pkgs.pkg-config - pkgs.git - pkgs.python3 - pkgs.python3Packages.markupsafe - pkgs.rustc - pkgs.cargo - pkgs.sccache - ]; - - # Linux-only system libraries — mirrors the apt deps from .github/workflows/build.yml - # so the cmake presets resolve the same set of headers as CI. - linuxDevDeps = pkgs: [ - # Compilers / linkers - pkgs.clang - pkgs.lld - # C/C++ utilities - pkgs.curl - pkgs.openssl - pkgs.zlib - pkgs.libpng - pkgs.libjpeg_turbo - pkgs.freetype - pkgs.zstd - pkgs.fmt - pkgs.tracy - pkgs.cxxopts - pkgs.abseil-cpp - pkgs.sdl3 - pkgs.ncurses - pkgs.libunwind - pkgs.libusb1 - pkgs.fuse - # Wayland / display server - pkgs.wayland - pkgs.wayland-protocols - pkgs.libxkbcommon - pkgs.libdecor - # OpenGL / Vulkan - pkgs.libGL - pkgs.libGLU - pkgs.libglvnd - pkgs.vulkan-headers - pkgs.vulkan-loader - # X11 - pkgs.libX11 - pkgs.libxcb - pkgs.libXcursor - pkgs.libxi - pkgs.libxrandr - pkgs.libxscrnsaver - pkgs.libxtst - pkgs.libxinerama - # Audio - pkgs.alsa-lib - pkgs.libpulseaudio - pkgs.pipewire - # System integration - pkgs.dbus - pkgs.udev - pkgs.gtk3 - ]; - - # On macOS we deliberately avoid pulling Nix's cc-wrapper so CMake picks up - # Apple Clang and the Xcode SDK directly, matching the macOS CI workflow. - mkDarwinShell = pkgs: - pkgs.mkShellNoCC { - packages = commonDevTools pkgs; - shellHook = '' - echo "Dusklight dev shell (macOS)" - echo "Requires Xcode Command Line Tools for Apple Clang and the macOS SDK." - echo "Configure: cmake --preset macos-default-relwithdebinfo" - echo "Build: cmake --build --preset macos-default-relwithdebinfo" - ''; - }; - - mkLinuxShell = pkgs: - pkgs.mkShell { - packages = (commonDevTools pkgs) ++ (linuxDevDeps pkgs); - shellHook = '' - echo "Dusklight dev shell (Linux)" - echo "Configure: cmake --preset linux-default-relwithdebinfo" - echo " cmake --preset linux-clang-relwithdebinfo" - echo "Build: cmake --build --preset " - ''; - }; - - mkDevShell = pkgs: - if pkgs.stdenv.isDarwin - then mkDarwinShell pkgs - else mkLinuxShell pkgs; - in { - packages.x86_64-linux.default = mkDusklight (pkgsFor "x86_64-linux"); - - devShells = forAllSystems (system: { - default = mkDevShell (pkgsFor system); - }); + systems = forAllSystems perSystem; + in + { + packages = lib.mapAttrs (_: s: s.packages) systems; + devShells = lib.mapAttrs (_: s: s.devShells) systems; }; } diff --git a/include/d/actor/d_a_movie_player.h b/include/d/actor/d_a_movie_player.h index 0e666ae470..c382e0d1f7 100644 --- a/include/d/actor/d_a_movie_player.h +++ b/include/d/actor/d_a_movie_player.h @@ -5,6 +5,7 @@ #include #else #include +#include #endif #include "f_op/f_op_actor.h" #include "d/d_drawlist.h" @@ -125,6 +126,7 @@ struct daMP_THPPlayer { /* 0x0D4 */ s32 curCount; #if TARGET_PC /* 0x0D8 */ std::atomic videoDecodeCount; + std::chrono::steady_clock::time_point thpPlaybackClock; #else /* 0x0D8 */ s32 videoDecodeCount; #endif diff --git a/platforms/android/app/build.gradle b/platforms/android/app/build.gradle index 2dc8575f86..8527cd1f4d 100644 --- a/platforms/android/app/build.gradle +++ b/platforms/android/app/build.gradle @@ -2,6 +2,9 @@ plugins { id 'com.android.application' } +def versionNameStr = (System.getenv("DUSK_VERSION") ?: "v0.1.0").replaceFirst("^v", "") +def versionCodeInt = (System.getenv("DUSK_VERSION_CODE") ?: "100000").toInteger() + def duskRepoDir = rootProject.projectDir.parentFile.parentFile def duskGeneratedAssetsDir = layout.buildDirectory.dir('generated/assets/dusklight').get().asFile def syncDuskAssets = tasks.register('syncDuskAssets', Sync) { @@ -20,8 +23,8 @@ android { applicationId 'dev.twilitrealm.dusk' minSdk 26 targetSdk 36 - versionCode 1 - versionName '0.1.0' + versionCode versionCodeInt + versionName versionNameStr } buildTypes { diff --git a/res/rml/prelaunch.rcss b/res/rml/prelaunch.rcss index f5d7240d56..73efc18086 100644 --- a/res/rml/prelaunch.rcss +++ b/res/rml/prelaunch.rcss @@ -447,6 +447,7 @@ body.animate-in .intro-item { top: auto; text-align: right; font-size: 16dp; + gap: 8dp; } #disc-status { @@ -468,6 +469,7 @@ body.animate-in .intro-item { top: 32dp; text-align: right; font-size: 16dp; + gap: 8dp; } .update { diff --git a/src/d/actor/d_a_movie_player.cpp b/src/d/actor/d_a_movie_player.cpp index 1f8bdeecd7..fcd1fb6dff 100644 --- a/src/d/actor/d_a_movie_player.cpp +++ b/src/d/actor/d_a_movie_player.cpp @@ -26,15 +26,16 @@ #include "f_op/f_op_overlap_mng.h" +#include "JSystem/JAudio2/JASCriticalSection.h" + +#if TARGET_PC #include "dusk/gx_helper.h" #include "dusk/os.h" #include "dusk/layout.hpp" - -#include "JSystem/JAudio2/JASCriticalSection.h" - #if MOVIE_SUPPORT #include "turbojpeg.h" #endif +#endif inline s32 daMP_NEXT_READ_SIZE(daMP_THPReadBuffer* readBuf) { return *(BE(s32)*)readBuf->ptr; @@ -3912,13 +3913,20 @@ static BOOL daMP_ProperTimingForGettingNextFrame() { return TRUE; } } else { - s32 frameRate = daMP_ActivePlayer.header.frameRate * 100.0f; #if TARGET_PC - // DUSK HACK: We only fire retrace callbacks *half* as often as the game expects, - // because we only run them once per frame, and normally there should be two scans - // per game frame. - frameRate *= 2; -#endif + const f32 fps = daMP_ActivePlayer.header.frameRate; + if (fps > 0.0f) { + const f32 elapsed = std::chrono::duration( + std::chrono::steady_clock::now() - daMP_ActivePlayer.thpPlaybackClock).count(); + const s32 desired = static_cast(elapsed * fps); + if (desired != daMP_ActivePlayer.prevCount) { + daMP_ActivePlayer.prevCount = desired; + daMP_ActivePlayer.curCount = desired; + return TRUE; + } + } +#else + s32 frameRate = daMP_ActivePlayer.header.frameRate * 100.0f; if (VIGetTvFormat() == VI_PAL) { daMP_ActivePlayer.curCount = daMP_ActivePlayer.retaceCount * frameRate / 5000; } else { @@ -3929,6 +3937,7 @@ static BOOL daMP_ProperTimingForGettingNextFrame() { daMP_ActivePlayer.prevCount = daMP_ActivePlayer.curCount; return TRUE; } +#endif } return FALSE; @@ -4133,6 +4142,9 @@ static BOOL daMP_THPPlayerPlay() { daMP_ActivePlayer.prevCount = 0; daMP_ActivePlayer.curCount = 0; daMP_ActivePlayer.retaceCount = -1; +#if TARGET_PC + daMP_ActivePlayer.thpPlaybackClock = std::chrono::steady_clock::now(); +#endif return TRUE; } diff --git a/src/dusk/achievements.cpp b/src/dusk/achievements.cpp index a8e4ff3916..5b76d7e8e8 100644 --- a/src/dusk/achievements.cpp +++ b/src/dusk/achievements.cpp @@ -442,7 +442,7 @@ std::vector AchievementSystem::makeEntries() { { "dark_hammer_one_hit", "Mortal Edge", - "Defeat Dark Hammer in a single hit.", + "Defeat Darkhammer in a single hit.", AchievementCategory::Misc, false, 0, 0, false }, diff --git a/src/dusk/imgui/ImGuiConsole.cpp b/src/dusk/imgui/ImGuiConsole.cpp index 077b4c15bc..d8b85b2d63 100644 --- a/src/dusk/imgui/ImGuiConsole.cpp +++ b/src/dusk/imgui/ImGuiConsole.cpp @@ -322,8 +322,8 @@ namespace dusk { } ImGui::PushFont(ImGuiEngine::fontLarge); ImGuiTextCenter("Failed to initialize any graphics backend."); - ImGuiTextCenter("\nDusklight requires Vulkan 1.1+, or Direct X 12.0."); - ImGuiTextCenter("\nTry updating your Operating System and GPU drivers."); + ImGuiTextCenter("\nDusklight requires at least Vulkan 1.1 or Direct3D 12."); + ImGuiTextCenter("\nTry updating your operating system and GPU drivers."); const auto& style = ImGui::GetStyle(); const auto retrySize = ImGui::CalcTextSize("Retry (Auto backend)"); const auto quitSize = ImGui::CalcTextSize("Quit"); diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index e009497045..42f205f12c 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -887,14 +887,19 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { config_bool_select(leftPane, rightPane, getSettings().game.enableDepthOfField, { .key = "Enable Depth of Field", + .helpText = "Render a blurring effect for out-of-focus areas in some situations. May impact performance." }); config_bool_select(leftPane, rightPane, getSettings().game.enableMapBackground, { .key = "Enable Mini-Map Shadows", + .helpText = "Render a thick shadow around the mini-map. May impact performance." }); config_bool_select(leftPane, rightPane, getSettings().game.disableCutscenePillarboxing, { .key = "Disable Cutscene Pillarboxing", + .helpText = "Disable black bars on the left and right sides of the screen " + "during some cutscenes, particularly on ultra-wide displays. " + "Visuals beyond the original intended framing may appear buggy." }); }); diff --git a/src/dusk/ui/ui.cpp b/src/dusk/ui/ui.cpp index 98c9ca5782..83a331c1fc 100644 --- a/src/dusk/ui/ui.cpp +++ b/src/dusk/ui/ui.cpp @@ -315,6 +315,7 @@ NavCommand map_nav_event(const Rml::Event& event) noexcept { case Rml::Input::KeyIdentifier::KI_ESCAPE: return NavCommand::Cancel; case Rml::Input::KeyIdentifier::KI_RETURN: + case Rml::Input::KeyIdentifier::KI_NUMPADENTER: return NavCommand::Confirm; case Rml::Input::KeyIdentifier::KI_F1: return event.GetParameter("shift_key", 0) ? NavCommand::None : NavCommand::Menu;