diff --git a/nix/steam_deck/configuration/hosts/deck/default.nix b/nix/steam_deck/configuration/hosts/deck/default.nix index 38668ba..edaf472 100644 --- a/nix/steam_deck/configuration/hosts/deck/default.nix +++ b/nix/steam_deck/configuration/hosts/deck/default.nix @@ -18,9 +18,9 @@ me.rpcs3.enable = true; me.ryujinx.enable = true; me.ship2harkinian.enable = true; - me.shipwright.enable = false; + me.shipwright.enable = true; me.sm64ex.enable = true; - me.spaghettikart.enable = false; + me.spaghettikart.enable = true; me.steam_rom_manager.enable = true; # Steam rom manager UI does not render. I think it wants to be in an AppImage. me.yuzu.enable = true; }; diff --git a/nix/steam_deck/configuration/roles/shipwright/default.nix b/nix/steam_deck/configuration/roles/shipwright/default.nix index 635b91a..1354695 100644 --- a/nix/steam_deck/configuration/roles/shipwright/default.nix +++ b/nix/steam_deck/configuration/roles/shipwright/default.nix @@ -49,6 +49,7 @@ in ( final: prev: let + modified_package = (pkgs.callPackage ./package/package.nix { }); optimizeWithFlags = pkg: flags: pkg.overrideAttrs (old: { @@ -57,12 +58,12 @@ in }); original_package = if config.me.optimizations.enable then - (optimizeWithFlags prev.shipwright [ + (optimizeWithFlags modified_package [ "-march=znver2" "-mtune=znver2" ]) else - prev.shipwright; + modified_package; in { shipwright = pkgs.buildEnv { diff --git a/nix/steam_deck/configuration/roles/shipwright/package/LICENSE b/nix/steam_deck/configuration/roles/shipwright/package/LICENSE new file mode 100644 index 0000000..cd250d1 --- /dev/null +++ b/nix/steam_deck/configuration/roles/shipwright/package/LICENSE @@ -0,0 +1,26 @@ +# The files in this folder are imported from nixpkg https://github.com/NixOS/nixpkgs . +# +# They have slight modifications to fix the package build on my home-manager systems. +# +# The original license is reproduced below: + +Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/nix/steam_deck/configuration/roles/shipwright/package/darwin-fixes.patch b/nix/steam_deck/configuration/roles/shipwright/package/darwin-fixes.patch new file mode 100644 index 0000000..de91358 --- /dev/null +++ b/nix/steam_deck/configuration/roles/shipwright/package/darwin-fixes.patch @@ -0,0 +1,37 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2771ee8c..0702adad 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -250,17 +250,13 @@ endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin") + add_custom_target(CreateOSXIcons + COMMAND mkdir -p ${CMAKE_BINARY_DIR}/macosx/soh.iconset +- COMMAND sips -z 16 16 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16.png +- COMMAND sips -z 32 32 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16@2x.png +- COMMAND sips -z 32 32 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32.png +- COMMAND sips -z 64 64 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32@2x.png +- COMMAND sips -z 128 128 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128.png +- COMMAND sips -z 256 256 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128@2x.png +- COMMAND sips -z 256 256 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256.png +- COMMAND sips -z 512 512 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256@2x.png +- COMMAND sips -z 512 512 ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512.png +- COMMAND cp ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512@2x.png +- COMMAND iconutil -c icns -o ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 16x16 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16.png ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 32x32 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32.png ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 64x64 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_64.png ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 128x128 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128.png ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 256x256 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256.png ++ COMMAND convert ${CMAKE_SOURCE_DIR}/soh/macosx/sohIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512.png ++ COMMAND png2icns ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_{16,32,64,128,256,512}.png + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Creating OSX icons ..." + ) +@@ -288,7 +284,6 @@ INSTALL(CODE "FILE(RENAME \${CMAKE_INSTALL_PREFIX}/../MacOS/soh-macos \${CMAKE_I + + install(CODE " + include(BundleUtilities) +- fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/../MacOS/soh\" \"\" \"${dirs}\") + ") + + endif() diff --git a/nix/steam_deck/configuration/roles/shipwright/package/disable-downloading-stb_image.patch b/nix/steam_deck/configuration/roles/shipwright/package/disable-downloading-stb_image.patch new file mode 100644 index 0000000..eade8db --- /dev/null +++ b/nix/steam_deck/configuration/roles/shipwright/package/disable-downloading-stb_image.patch @@ -0,0 +1,16 @@ +Submodule libultraship contains modified content +diff --git a/libultraship/cmake/dependencies/common.cmake b/libultraship/cmake/dependencies/common.cmake +index 596158c..c62d7b2 100644 +--- a/libultraship/cmake/dependencies/common.cmake ++++ b/libultraship/cmake/dependencies/common.cmake +@@ -47,10 +47,6 @@ set(stormlib_optimizations_patch git apply ${CMAKE_CURRENT_SOURCE_DIR}/cmake/dep + endif() + + #=================== STB =================== +-set(STB_DIR ${CMAKE_BINARY_DIR}/_deps/stb) +-file(DOWNLOAD "https://github.com/nothings/stb/raw/0bc88af4de5fb022db643c2d8e549a0927749354/stb_image.h" "${STB_DIR}/stb_image.h") +-file(WRITE "${STB_DIR}/stb_impl.c" "#define STB_IMAGE_IMPLEMENTATION\n#include \"stb_image.h\"") +- + add_library(stb STATIC) + + target_sources(stb PRIVATE diff --git a/nix/steam_deck/configuration/roles/shipwright/package/package.nix b/nix/steam_deck/configuration/roles/shipwright/package/package.nix new file mode 100644 index 0000000..20452c8 --- /dev/null +++ b/nix/steam_deck/configuration/roles/shipwright/package/package.nix @@ -0,0 +1,291 @@ +{ + apple-sdk_13, + stdenv, + cmake, + lsb-release, + ninja, + lib, + fetchFromGitHub, + fetchurl, + copyDesktopItems, + makeDesktopItem, + python3, + glew, + boost, + SDL2, + SDL2_net, + pkg-config, + libpulseaudio, + libpng, + imagemagick, + zenity, + makeWrapper, + darwin, + libicns, + libzip, + nlohmann_json, + tinyxml-2, + spdlog, + writeTextFile, + fixDarwinDylibNames, + applyPatches, +}: + +let + + # The following would normally get fetched at build time, or a specific version is required + + shipwright_version = "9.0.5"; + shipwright_src = fetchFromGitHub { + owner = "harbourmasters"; + repo = "shipwright"; + tag = shipwright_version; + hash = "sha256-F5d4u3Nq/+yYiOgkH/bwWPhZDxgBpJ5ktee0Hc5UmEo="; + fetchSubmodules = true; + deepClone = true; + postFetch = '' + cd $out + git branch --show-current > GIT_BRANCH + git rev-parse --short=7 HEAD > GIT_COMMIT_HASH + (git describe --tags --abbrev=0 --exact-match HEAD 2>/dev/null || echo "") > GIT_COMMIT_TAG + rm -rf .git + ''; + }; + + gamecontrollerdb = fetchFromGitHub { + owner = "mdqinc"; + repo = "SDL_GameControllerDB"; + rev = "a74711e1e87733ccdf02d7020d8fa9e4fa67176e"; + hash = "sha256-rXC4akz9BaKzr/C2CryZC6RGk6+fGVG7RsQryUFUUk0="; + }; + + imgui' = applyPatches { + src = fetchFromGitHub { + owner = "ocornut"; + repo = "imgui"; + tag = "v1.91.6-docking"; + hash = "sha256-28wyzzwXE02W5vbEdRCw2iOF8ONkb3M3Al8XlYBvz1A="; + }; + patches = [ + "${shipwright_src}/libultraship/cmake/dependencies/patches/imgui-fixes-and-config.patch" + ]; + }; + + libgfxd = fetchFromGitHub { + owner = "glankk"; + repo = "libgfxd"; + rev = "008f73dca8ebc9151b205959b17773a19c5bd0da"; + hash = "sha256-AmHAa3/cQdh7KAMFOtz5TQpcM6FqO9SppmDpKPTjTt8="; + }; + + prism = fetchFromGitHub { + owner = "KiritoDv"; + repo = "prism-processor"; + rev = "fb3f8b4a2d14dfcbae654d0f0e59a73b6f6ca850"; + hash = "sha256-gGdQSpX/TgCNZ0uyIDdnazgVHpAQhl30e+V0aVvTFMM="; + }; + + stb_impl = writeTextFile { + name = "stb_impl.c"; + text = '' + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + ''; + }; + + stb' = fetchurl { + name = "stb_image.h"; + url = "https://raw.githubusercontent.com/nothings/stb/0bc88af4de5fb022db643c2d8e549a0927749354/stb_image.h"; + hash = "sha256-xUsVponmofMsdeLsI6+kQuPg436JS3PBl00IZ5sg3Vw="; + }; + + stormlib' = applyPatches { + src = fetchFromGitHub { + owner = "ladislav-zezula"; + repo = "StormLib"; + tag = "v9.25"; + hash = "sha256-HTi2FKzKCbRaP13XERUmHkJgw8IfKaRJvsK3+YxFFdc="; + }; + patches = [ + "${shipwright_src}/libultraship/cmake/dependencies/patches/stormlib-optimizations.patch" + ]; + }; + + thread_pool = fetchFromGitHub { + owner = "bshoshany"; + repo = "thread-pool"; + tag = "v4.1.0"; + hash = "sha256-zhRFEmPYNFLqQCfvdAaG5VBNle9Qm8FepIIIrT9sh88="; + }; + + metalcpp = fetchFromGitHub { + owner = "briaguya-ai"; + repo = "single-header-metal-cpp"; + tag = "macOS13_iOS16"; + hash = "sha256-CSYIpmq478bla2xoPL/cGYKIWAeiORxyFFZr0+ixd7I"; + }; +in +stdenv.mkDerivation (finalAttrs: { + pname = "shipwright"; + version = shipwright_version; + src = shipwright_src; + + patches = [ + ./darwin-fixes.patch + ./disable-downloading-stb_image.patch + ]; + + nativeBuildInputs = [ + cmake + ninja + pkg-config + python3 + imagemagick + makeWrapper + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + lsb-release + copyDesktopItems + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + libicns + darwin.sigtool + fixDarwinDylibNames + ]; + + buildInputs = [ + boost + glew + SDL2 + SDL2_net + libpng + libzip + nlohmann_json + tinyxml-2 + spdlog + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + libpulseaudio + zenity + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + # Metal.hpp requires macOS 13.x min. + apple-sdk_13 + ]; + + cmakeFlags = [ + (lib.cmakeBool "BUILD_REMOTE_CONTROL" true) + (lib.cmakeBool "NON_PORTABLE" true) + (lib.cmakeFeature "CMAKE_INSTALL_PREFIX" "${placeholder "out"}/lib") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_IMGUI" "${imgui'}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_LIBGFXD" "${libgfxd}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_PRISM" "${prism}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_STORMLIB" "${stormlib'}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_THREADPOOL" "${thread_pool}") + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_METALCPP" "${metalcpp}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_SPDLOG" "${spdlog}") + ]; + + env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.hostPlatform.isDarwin "-Wno-int-conversion -Wno-implicit-int -Wno-elaborated-enum-base"; + + dontAddPrefix = true; + + # Linking fails without this + hardeningDisable = [ "format" ]; + + preConfigure = '' + mkdir stb + cp ${stb'} ./stb/${stb'.name} + cp ${stb_impl} ./stb/${stb_impl.name} + substituteInPlace libultraship/cmake/dependencies/common.cmake \ + --replace-fail "\''${STB_DIR}" "$(readlink -f ./stb)" + ''; + + postPatch = '' + substituteInPlace soh/src/boot/build.c.in \ + --replace-fail "@CMAKE_PROJECT_GIT_BRANCH@" "$(cat GIT_BRANCH)" \ + --replace-fail "@CMAKE_PROJECT_GIT_COMMIT_HASH@" "$(cat GIT_COMMIT_HASH)" \ + --replace-fail "@CMAKE_PROJECT_GIT_COMMIT_TAG@" "$(cat GIT_COMMIT_TAG)" + ''; + + postBuild = '' + port_ver=$(grep CMAKE_PROJECT_VERSION: "$PWD/CMakeCache.txt" | cut -d= -f2) + cp ${gamecontrollerdb}/gamecontrollerdb.txt gamecontrollerdb.txt + mv ../libultraship/src/graphic/Fast3D/shaders ../soh/assets/custom + pushd ../OTRExporter + python3 ./extract_assets.py -z ../build/ZAPD/ZAPD.out --norom --xml-root ../soh/assets/xml --custom-assets-path ../soh/assets/custom --custom-otr-file soh.otr --port-ver $port_ver + popd + ''; + + preInstall = '' + # Cmake likes it here for its install paths + cp ../OTRExporter/soh.otr soh/soh.otr + ''; + + postInstall = + lib.optionalString stdenv.hostPlatform.isLinux '' + mkdir -p $out/bin + ln -s $out/lib/soh.elf $out/bin/soh + install -Dm644 ../soh/macosx/sohIcon.png $out/share/pixmaps/soh.png + '' + + lib.optionalString stdenv.hostPlatform.isDarwin '' + # Recreate the macOS bundle (without using cpack) + # We mirror the structure of the bundle distributed by the project + + mkdir -p $out/Applications/soh.app/Contents + cp $src/soh/macosx/Info.plist.in $out/Applications/soh.app/Contents/Info.plist + substituteInPlace $out/Applications/soh.app/Contents/Info.plist \ + --replace-fail "@CMAKE_PROJECT_VERSION@" "${finalAttrs.version}" + + mv $out/MacOS $out/Applications/soh.app/Contents/MacOS + + # "lib" contains all resources that are in "Resources" in the official bundle. + # We move them to the right place and symlink them back to $out/lib, + # as that's where the game expects them. + mv $out/Resources $out/Applications/soh.app/Contents/Resources + mv $out/lib/** $out/Applications/soh.app/Contents/Resources + rm -rf $out/lib + ln -s $out/Applications/soh.app/Contents/Resources $out/lib + + # Copy icons + cp -r ../build/macosx/soh.icns $out/Applications/soh.app/Contents/Resources/soh.icns + + # Codesign (ad-hoc) + codesign -f -s - $out/Applications/soh.app/Contents/MacOS/soh + ''; + + fixupPhase = lib.optionalString stdenv.hostPlatform.isLinux '' + wrapProgram $out/lib/soh.elf --prefix PATH ":" ${lib.makeBinPath [ zenity ]} + ''; + + desktopItems = [ + (makeDesktopItem { + name = "soh"; + icon = "soh"; + exec = "soh"; + comment = finalAttrs.meta.description; + genericName = "Ship of Harkinian"; + desktopName = "soh"; + categories = [ "Game" ]; + }) + ]; + + meta = { + homepage = "https://github.com/HarbourMasters/Shipwright"; + description = "PC port of Ocarina of Time with modern controls, widescreen, high-resolution, and more"; + mainProgram = "soh"; + platforms = lib.platforms.linux ++ lib.platforms.darwin; + maintainers = with lib.maintainers; [ + j0lol + matteopacini + ]; + license = with lib.licenses; [ + # OTRExporter, OTRGui, ZAPDTR, libultraship + mit + # Ship of Harkinian itself + unfree + ]; + }; +}) diff --git a/nix/steam_deck/configuration/roles/spaghettikart/default.nix b/nix/steam_deck/configuration/roles/spaghettikart/default.nix index 15c9348..4008d94 100644 --- a/nix/steam_deck/configuration/roles/spaghettikart/default.nix +++ b/nix/steam_deck/configuration/roles/spaghettikart/default.nix @@ -49,6 +49,7 @@ in ( final: prev: let + modified_package = (pkgs.callPackage ./package/package.nix { }); optimizeWithFlags = pkg: flags: pkg.overrideAttrs (old: { @@ -56,12 +57,12 @@ in }); original_package = if config.me.optimizations.enable then - (optimizeWithFlags prev.spaghettikart [ + (optimizeWithFlags modified_package [ "-march=znver2" "-mtune=znver2" ]) else - prev.spaghettikart; + modified_package; in { spaghettikart = pkgs.buildEnv { @@ -76,7 +77,7 @@ in ]; # We have to use 555 instead of the normal 444 here because the .desktop file ends up inside $HOME on steam deck and desktop files must be either not in $HOME or must be executable, otherwise KDE Plasma refuses to execute them. postBuild = '' - chmod 0555 $out/share/applications/SpaghettiKart.desktop + chmod 0555 $out/share/applications/spaghettikart.desktop ''; }; } diff --git a/nix/steam_deck/configuration/roles/spaghettikart/package/LICENSE b/nix/steam_deck/configuration/roles/spaghettikart/package/LICENSE new file mode 100644 index 0000000..cd250d1 --- /dev/null +++ b/nix/steam_deck/configuration/roles/spaghettikart/package/LICENSE @@ -0,0 +1,26 @@ +# The files in this folder are imported from nixpkg https://github.com/NixOS/nixpkgs . +# +# They have slight modifications to fix the package build on my home-manager systems. +# +# The original license is reproduced below: + +Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/nix/steam_deck/configuration/roles/spaghettikart/package/dont-fetch-stb.patch b/nix/steam_deck/configuration/roles/spaghettikart/package/dont-fetch-stb.patch new file mode 100644 index 0000000..eade8db --- /dev/null +++ b/nix/steam_deck/configuration/roles/spaghettikart/package/dont-fetch-stb.patch @@ -0,0 +1,16 @@ +Submodule libultraship contains modified content +diff --git a/libultraship/cmake/dependencies/common.cmake b/libultraship/cmake/dependencies/common.cmake +index 596158c..c62d7b2 100644 +--- a/libultraship/cmake/dependencies/common.cmake ++++ b/libultraship/cmake/dependencies/common.cmake +@@ -47,10 +47,6 @@ set(stormlib_optimizations_patch git apply ${CMAKE_CURRENT_SOURCE_DIR}/cmake/dep + endif() + + #=================== STB =================== +-set(STB_DIR ${CMAKE_BINARY_DIR}/_deps/stb) +-file(DOWNLOAD "https://github.com/nothings/stb/raw/0bc88af4de5fb022db643c2d8e549a0927749354/stb_image.h" "${STB_DIR}/stb_image.h") +-file(WRITE "${STB_DIR}/stb_impl.c" "#define STB_IMAGE_IMPLEMENTATION\n#include \"stb_image.h\"") +- + add_library(stb STATIC) + + target_sources(stb PRIVATE diff --git a/nix/steam_deck/configuration/roles/spaghettikart/package/git-deps.patch b/nix/steam_deck/configuration/roles/spaghettikart/package/git-deps.patch new file mode 100644 index 0000000..4cf9d14 --- /dev/null +++ b/nix/steam_deck/configuration/roles/spaghettikart/package/git-deps.patch @@ -0,0 +1,44 @@ +diff --git a/torch/CMakeLists.txt b/torch/CMakeLists.txt +index ba3859a..cf3da99 100644 +--- a/torch/CMakeLists.txt ++++ b/torch/CMakeLists.txt +@@ -36,8 +36,7 @@ if(USE_STANDALONE) + # Because libgfxd is not a CMake project, we have to manually fetch it and add it to the build + FetchContent_Declare( + libgfxd +- GIT_REPOSITORY https://github.com/glankk/libgfxd.git +- GIT_TAG 96fd3b849f38b3a7c7b7f3ff03c5921d328e6cdf ++ URL @libgfxd_src@ + ) + + FetchContent_GetProperties(libgfxd) +@@ -205,8 +204,7 @@ set(YAML_CPP_BUILD_TESTS OFF) + set(YAML_CPP_DISABLE_UNINSTALL ON) + FetchContent_Declare( + yaml-cpp +- GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git +- GIT_TAG 2f86d13775d119edbb69af52e5f566fd65c6953b ++ URL @yaml-cpp_src@ + ) + set(YAML_CPP_BUILD_TESTS OFF) + FetchContent_MakeAvailable(yaml-cpp) +@@ -219,8 +217,7 @@ endif() + if(USE_STANDALONE) + FetchContent_Declare( + spdlog +- GIT_REPOSITORY https://github.com/gabime/spdlog.git +- GIT_TAG 7e635fca68d014934b4af8a1cf874f63989352b7 ++ URL @spdlog_src@ + ) + + FetchContent_MakeAvailable(spdlog) +@@ -234,8 +231,7 @@ endif() + set(tinyxml2_BUILD_TESTING OFF) + FetchContent_Declare( + tinyxml2 +- GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git +- GIT_TAG 10.0.0 ++ URL @tinyxml2_src@ + OVERRIDE_FIND_PACKAGE + ) + FetchContent_MakeAvailable(tinyxml2) diff --git a/nix/steam_deck/configuration/roles/spaghettikart/package/package.nix b/nix/steam_deck/configuration/roles/spaghettikart/package/package.nix new file mode 100644 index 0000000..efad2f9 --- /dev/null +++ b/nix/steam_deck/configuration/roles/spaghettikart/package/package.nix @@ -0,0 +1,264 @@ +{ + lib, + fetchFromGitHub, + applyPatches, + writeTextFile, + fetchurl, + stdenv, + replaceVars, + yaml-cpp, + srcOnly, + cmake, + copyDesktopItems, + installShellFiles, + lsb-release, + makeWrapper, + ninja, + pkg-config, + libGL, + libvorbis, + libX11, + libzip, + nlohmann_json, + SDL2, + SDL2_net, + spdlog, + tinyxml-2, + zenity, + sdl_gamecontrollerdb, + makeDesktopItem, +}: + +let + + # The following are either normally fetched during build time or a specific version is required + + spaghettikart_src = fetchFromGitHub { + owner = "HarbourMasters"; + repo = "SpaghettiKart"; + rev = "334fdeafd26c15e03b4f198002ad86b8422c0e2f"; + hash = "sha256-0nDaX34C7stg7S2mzPChz0fRz/t7yyevKEAPmIR+lak="; + fetchSubmodules = true; + deepClone = true; + postFetch = '' + cd $out + (git describe --tags HEAD 2>/dev/null || echo "") > PROJECT_VERSION + git log --pretty=format:%h -1 > PROJECT_VERSION_PATCH + rm -rf .git + ''; + }; + + dr_libs = fetchFromGitHub { + owner = "mackron"; + repo = "dr_libs"; + rev = "da35f9d6c7374a95353fd1df1d394d44ab66cf01"; + hash = "sha256-ydFhQ8LTYDBnRTuETtfWwIHZpRciWfqGsZC6SuViEn0="; + }; + + imgui' = applyPatches { + src = fetchFromGitHub { + owner = "ocornut"; + repo = "imgui"; + tag = "v1.91.9b-docking"; + hash = "sha256-mQOJ6jCN+7VopgZ61yzaCnt4R1QLrW7+47xxMhFRHLQ="; + }; + patches = [ + "${spaghettikart_src}/libultraship/cmake/dependencies/patches/imgui-fixes-and-config.patch" + ]; + }; + + libgfxd = fetchFromGitHub { + owner = "glankk"; + repo = "libgfxd"; + rev = "008f73dca8ebc9151b205959b17773a19c5bd0da"; + hash = "sha256-AmHAa3/cQdh7KAMFOtz5TQpcM6FqO9SppmDpKPTjTt8="; + }; + + prism = fetchFromGitHub { + owner = "KiritoDv"; + repo = "prism-processor"; + rev = "7ae724a6fb7df8cbf547445214a1a848aefef747"; + hash = "sha256-G7koDUxD6PgZWmoJtKTNubDHg6Eoq8I+AxIJR0h3i+A="; + }; + + stb_impl = writeTextFile { + name = "stb_impl.c"; + text = '' + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + ''; + }; + + stb' = fetchurl { + name = "stb_image.h"; + url = "https://raw.githubusercontent.com/nothings/stb/0bc88af4de5fb022db643c2d8e549a0927749354/stb_image.h"; + hash = "sha256-xUsVponmofMsdeLsI6+kQuPg436JS3PBl00IZ5sg3Vw="; + }; + + stormlib' = applyPatches { + src = fetchFromGitHub { + owner = "ladislav-zezula"; + repo = "StormLib"; + tag = "v9.25"; + hash = "sha256-HTi2FKzKCbRaP13XERUmHkJgw8IfKaRJvsK3+YxFFdc="; + }; + patches = [ + "${spaghettikart_src}/libultraship/cmake/dependencies/patches/stormlib-optimizations.patch" + ]; + }; + + thread_pool = fetchFromGitHub { + owner = "bshoshany"; + repo = "thread-pool"; + tag = "v4.1.0"; + hash = "sha256-zhRFEmPYNFLqQCfvdAaG5VBNle9Qm8FepIIIrT9sh88="; + }; + +in +stdenv.mkDerivation (finalAttrs: { + pname = "spaghettikart"; + version = "0-unstable-2025-08-07"; + + src = spaghettikart_src; + + patches = [ + # Don't fetch stb as we will patch our own + ./dont-fetch-stb.patch + + # Can't fetch these torch deps in the sandbox + (replaceVars ./git-deps.patch { + libgfxd_src = fetchFromGitHub { + owner = "glankk"; + repo = "libgfxd"; + rev = "96fd3b849f38b3a7c7b7f3ff03c5921d328e6cdf"; + hash = "sha256-dedZuV0BxU6goT+rPvrofYqTz9pTA/f6eQcsvpDWdvQ="; + }; + spdlog_src = fetchFromGitHub { + owner = "gabime"; + repo = "spdlog"; + rev = "7e635fca68d014934b4af8a1cf874f63989352b7"; + hash = "sha256-cxTaOuLXHRU8xMz9gluYz0a93O0ez2xOxbloyc1m1ns="; + }; + yaml-cpp_src = fetchFromGitHub { + owner = "jbeder"; + repo = "yaml-cpp"; + rev = "28f93bdec6387d42332220afa9558060c8016795"; + hash = "sha256-59/s4Rqiiw7LKQw0UwH3vOaT/YsNVcoq3vblK0FiO5c="; + }; + tinyxml2_src = srcOnly tinyxml-2; + }) + ]; + + # Recent builds enabled LTO which won't build with nix + NIX_CFLAGS_COMPILE = "-fno-lto"; + + nativeBuildInputs = [ + cmake + copyDesktopItems + installShellFiles + lsb-release + makeWrapper + ninja + pkg-config + ]; + + buildInputs = [ + libGL + libvorbis + libX11 + libzip + nlohmann_json + SDL2 + SDL2_net + spdlog + tinyxml-2 + zenity + ]; + + cmakeFlags = [ + (lib.cmakeFeature "CMAKE_INSTALL_PREFIX" "${placeholder "out"}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_DR_LIBS" "${dr_libs}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_IMGUI" "${imgui'}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_LIBGFXD" "${libgfxd}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_PRISM" "${prism}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_STORMLIB" "${stormlib'}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_THREADPOOL" "${thread_pool}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_TINYXML2" "${tinyxml-2}") + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_YAML-CPP" "${yaml-cpp.src}") + ]; + + strictDeps = true; + + # Linking fails without this + hardeningDisable = [ "format" ]; + + preConfigure = '' + mkdir stb + cp ${stb'} ./stb/${stb'.name} + cp ${stb_impl} ./stb/${stb_impl.name} + substituteInPlace libultraship/cmake/dependencies/common.cmake \ + --replace-fail "\''${STB_DIR}" "$(readlink -f ./stb)" + ''; + + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail "COMMAND git describe --tags" "COMMAND echo $(cat PROJECT_VERSION)" \ + --replace-fail "COMMAND git log --pretty=format:%h -1" "COMMAND echo $(cat PROJECT_VERSION_PATCH)" + ''; + + postBuild = '' + cp ${sdl_gamecontrollerdb}/share/gamecontrollerdb.txt gamecontrollerdb.txt + ./TorchExternal/src/TorchExternal-build/torch pack ../assets spaghetti.o2r o2r + ''; + + postInstall = '' + installBin Spaghettify + mkdir -p $out/share/spaghettikart + cp -r ../yamls $out/share/spaghettikart/ + install -Dm644 -t $out/share/spaghettikart {spaghetti.o2r,config.yml,gamecontrollerdb.txt} + install -Dm644 ../icon.png $out/share/pixmaps/spaghettikart.png + install -Dm644 -t $out/share/licenses/spaghettikart/libgfxd ${libgfxd}/LICENSE + install -Dm644 -t $out/share/licenses/spaghettikart/libultraship ../libultraship/LICENSE + install -Dm644 -t $out/share/licenses/spaghettikart/thread_pool ${thread_pool}/LICENSE.txt + ''; + + # Unfortunately, spaghettikart really wants a writable working directory + # Create $HOME/.local/share/spaghettikart and symlink required files + + postFixup = '' + wrapProgram $out/bin/Spaghettify \ + --prefix PATH ":" ${lib.makeBinPath [ zenity ]} \ + --run 'mkdir -p ~/.local/share/spaghettikart' \ + --run "ln -sf $out/share/spaghettikart/spaghetti.o2r ~/.local/share/spaghettikart/spaghetti.o2r" \ + --run "ln -sf $out/share/spaghettikart/config.yml ~/.local/share/spaghettikart/config.yml" \ + --run "ln -sfT $out/share/spaghettikart/yamls ~/.local/share/spaghettikart/yamls" \ + --run "ln -sf $out/share/spaghettikart/gamecontrollerdb.txt ~/.local/share/spaghettikart/gamecontrollerdb.txt" \ + --run 'cd ~/.local/share/spaghettikart' + ''; + + desktopItems = [ + (makeDesktopItem { + name = "spaghettikart"; + icon = "spaghettikart"; + exec = "Spaghettify"; + comment = finalAttrs.meta.description; + genericName = "spaghettikart"; + desktopName = "spaghettikart"; + categories = [ "Game" ]; + }) + ]; + + meta = { + homepage = "https://github.com/HarbourMasters/SpaghettiKart"; + description = "Mario Kart 64 PC Port"; + mainProgram = "Spaghettify"; + platforms = [ "x86_64-linux" ]; + maintainers = with lib.maintainers; [ qubitnano ]; + license = with lib.licenses; [ + # libultraship, libgfxd, thread_pool, dr_libs, prism-processor + mit + # Reverse engineering + unfree + ]; + }; +})