diff --git a/.gitignore b/.gitignore index 2dcd2d0..ba0fedb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ backups/ interface.ini settings.json *.bak* +publish/ diff --git a/README.md b/README.md index 0468da1..0bd3a28 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ - [Troubleshooting](#troubleshooting) - [Known issues](#known-issues) - [Building from source](#building-from-source) +- [Linux and SteamOS handhelds (AppImage)](#linux-and-steamos-handhelds-appimage) - [License](#license) - [Disclaimer](#disclaimer) - [Credits](#credits) @@ -263,6 +264,52 @@ contain (`.git\info\banned-words.txt`, one per line) and does not run without it +## Linux and SteamOS handhelds (AppImage) + +
+Build an AppImage for Steam Deck, Legion Go, ROG Ally (Bazzite/SteamOS) or desktop Linux + +The game runtime is cross-platform (SDL2, OpenGL, OpenAL through Silk.NET), so the port also runs natively on +Linux, packaged as a single self-contained AppImage (no .NET install needed on the device). Tested on a Legion Go 2 +running Bazzite (Radeon 890M, OpenGL 4.6, Game Mode through Steam). + +**Build it** (on any x86_64 Linux machine or WSL, from your own disc image): + +``` +git clone --recurse-submodules +cd KnowYourRoleRecomp + +# with Docker (no local .NET SDK needed) +docker build -t kyr-linux tools/linux +docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/src" -v "/path/to/your/disc:/disc:ro" \ + kyr-linux "/disc/WWF SmackDown! 2 - Know Your Role (USA).cue" + +# or with the .NET 10 SDK installed +tools/linux/build-appimage.sh "/path/to/your/disc/WWF SmackDown! 2 - Know Your Role (USA).cue" +``` + +This writes `dist/KnowYourRole-x86_64.AppImage`. It contains code generated from **your** disc: keep it to yourself. + +**On the device**: copy the AppImage anywhere (for example `~/Games/KnowYourRole/`) and add it to Steam as a +non-Steam game (no Proton / compatibility tool). On first start pick your `.cue` in the game's disc picker, or +point it at the disc beforehand: + +``` +mkdir -p ~/.local/share/KnowYourRoleRecomp +echo "/path/to/WWF SmackDown! 2 - Know Your Role (USA).cue" > ~/.local/share/KnowYourRoleRecomp/disc.txt +``` + +Saves, settings and logs live in `~/.local/share/KnowYourRoleRecomp/`. + +**Handheld-friendly defaults**: +- **Widescreen**: *Settings > Display > Widescreen* (`auto`, `off`, `16:9`, `16:10`). `auto` (default) matches the + screen, so a 16:10 handheld gets a 16:10 picture: 3D is rendered with a wider field of view instead of being + stretched, while the HUD, menus and videos keep their original 4:3 proportions, centred. Objects right at the edges + may pop in, since the game culls for a 4:3 view. +- **Menu bar hidden** by default. Toggle it with **F1**, or **L3 + R3** on player 1's controller. + +
+ ## License The port's code is MIT licensed ([LICENSE](LICENSE)). RecompOne is MIT licensed by its authors and included as a diff --git a/RecompOne b/RecompOne index d54b944..58c945c 160000 --- a/RecompOne +++ b/RecompOne @@ -1 +1 @@ -Subproject commit d54b944fd3a7e3eaaac4cd7e62ea460440c3f9e7 +Subproject commit 58c945c0b1ab0c45bb6a8f9eb6861b7ae2e4790b diff --git a/tools/linux/AppRun b/tools/linux/AppRun new file mode 100755 index 0000000..5c5f6f7 --- /dev/null +++ b/tools/linux/AppRun @@ -0,0 +1,28 @@ +#!/bin/sh +# Know Your Role Recomp - AppImage launcher (Linux / SteamOS-like handhelds). +# +# Saves, settings and logs live in ${XDG_DATA_HOME:-~/.local/share}/KnowYourRoleRecomp (an AppImage is read-only). +# Disc: the first argument, else $KYR_DISC, else the path in /disc.txt. The runtime validates the disc from +# settings.json (CdPath), so a known disc is written there while CdPath is empty; with no disc known, the game shows +# its own disc picker and remembers the choice. +HERE="$(dirname "$(readlink -f "$0")")" +DATA="${XDG_DATA_HOME:-$HOME/.local/share}/KnowYourRoleRecomp" +mkdir -p "$DATA/logs" +export RECOMPONE_DATA_DIR="${RECOMPONE_DATA_DIR:-$DATA}" +export RECOMPONE_LOG_DIR="${RECOMPONE_LOG_DIR:-$DATA/logs}" + +DISC="${1:-${KYR_DISC:-}}" +[ -z "$DISC" ] && [ -f "$DATA/disc.txt" ] && DISC="$(cat "$DATA/disc.txt")" + +S="$DATA/settings.json" +if [ -n "$DISC" ] && [ -f "$S" ] && grep -q '"CdPath": ""' "$S"; then + ESC="$(printf '%s' "$DISC" | sed 's/[\\"]/\\&/g; s/[&|]/\\&/g')" + sed -i "s|\"CdPath\": \"\"|\"CdPath\": \"$ESC\"|" "$S" +fi + +cd "$DATA" +if [ -n "$DISC" ]; then + exec "$HERE/usr/bin/KnowYourRole.Game" "$DISC" +else + exec "$HERE/usr/bin/KnowYourRole.Game" +fi diff --git a/tools/linux/Dockerfile b/tools/linux/Dockerfile new file mode 100755 index 0000000..49d0ca4 --- /dev/null +++ b/tools/linux/Dockerfile @@ -0,0 +1,24 @@ +# Build environment for the Linux AppImage (tools/linux/build-appimage.sh), so no local .NET SDK is needed. +# +# docker build -t kyr-linux tools/linux +# docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/src" -v "/path/to/your/disc:/disc:ro" \ +# kyr-linux /disc/YourDisc.cue +# +# The repository is mounted at /src (clone it with --recurse-submodules first); the AppImage lands in dist/. +FROM mcr.microsoft.com/dotnet/sdk:10.0 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends git curl python3 file ca-certificates \ + && rm -rf /var/lib/apt/lists/* \ + && git config --system --add safe.directory '*' + +# writable homes for dotnet/NuGet when running as the host user +ENV HOME=/tmp/home \ + DOTNET_CLI_HOME=/tmp/home \ + NUGET_PACKAGES=/tmp/home/.nuget/packages \ + DOTNET_CLI_TELEMETRY_OPTOUT=1 \ + DOTNET_NOLOGO=1 +RUN mkdir -p /tmp/home && chmod 1777 /tmp/home + +WORKDIR /src +ENTRYPOINT ["bash", "tools/linux/build-appimage.sh"] diff --git a/tools/linux/build-appimage.sh b/tools/linux/build-appimage.sh new file mode 100755 index 0000000..5d65bcd --- /dev/null +++ b/tools/linux/build-appimage.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Builds a Linux AppImage of Know Your Role Recomp from your own disc image, for desktop Linux and SteamOS-like +# handhelds (Steam Deck, Legion Go, ROG Ally on Bazzite, ...). +# +# tools/linux/build-appimage.sh [path/to/KnowYourRole.cue] +# +# Needs: the .NET 10 SDK (dotnet on PATH or in ~/.dotnet), git, curl, python3, and x86_64 Linux (WSL works). +# Output: dist/KnowYourRole-x86_64.AppImage. It contains code generated from YOUR disc: do not share it. +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +cd "$ROOT" +export PATH="$HOME/.dotnet:$PATH" DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1 +command -v dotnet >/dev/null || { echo "dotnet not found: install the .NET 10 SDK (https://dot.net)"; exit 1; } + +if [ $# -ge 1 ]; then + CUE="$(readlink -f "$1")" + mkdir -p disc + # the config expects disc/KnowYourRole.cue; write a cue pointing at the given image's .bin + BIN="$(dirname "$CUE")/$(sed -n 's/^FILE "\(.*\)".*/\1/p' "$CUE" | head -1)" + [ -f "$BIN" ] || BIN="$(find "$(dirname "$CUE")" -maxdepth 1 -iname '*.bin' | head -1)" + [ -f "$BIN" ] || { echo "no .bin found next to $CUE"; exit 1; } + ln -sf "$BIN" disc/KnowYourRole.bin + printf 'FILE "KnowYourRole.bin" BINARY\r\n TRACK 01 MODE2/2352\r\n INDEX 01 00:00:00\r\n' > disc/KnowYourRole.cue +fi +[ -f disc/KnowYourRole.cue ] || { echo "put your disc at disc/KnowYourRole.cue (+ .bin) or pass the .cue path"; exit 1; } + +echo "== recompiling from your disc" +[ -f RecompOne/RecompOne.sln ] || git submodule update --init --recursive +dotnet build RecompOne/RecompOne.Recompiler -c Release -v quiet +(cd RecompOne/RecompOne.Recompiler && dotnet run -c Release --no-build -- ../../config/KnowYourRole.json) + +echo "== publishing (self-contained linux-x64)" +rm -rf publish +dotnet publish KnowYourRole.csproj -c Release -r linux-x64 --self-contained true -m:1 -o publish -v quiet + +echo "== packaging AppImage" +APPDIR="$ROOT/dist/AppDir" +rm -rf "$APPDIR" && mkdir -p "$APPDIR/usr/bin" +cp -a publish/. "$APPDIR/usr/bin/" +rm -f "$APPDIR"/usr/bin/*.pdb +chmod +x "$APPDIR/usr/bin/KnowYourRole.Game" +install -m 755 tools/linux/AppRun "$APPDIR/AppRun" +install -m 644 tools/linux/knowyourrole.desktop "$APPDIR/knowyourrole.desktop" +# icon: the largest PNG inside Launcher/app.ico +python3 - "$ROOT/Launcher/app.ico" "$APPDIR/knowyourrole.png" <<'PY' +import struct, sys +d = open(sys.argv[1], 'rb').read(); best = None +for i in range(struct.unpack_from(' best[0]): best = (w or 256, blob) +open(sys.argv[2], 'wb').write(best[1]) +PY + +TOOL="$ROOT/dist/appimagetool" +[ -x "$TOOL" ] || { curl -fsSL -o "$TOOL" https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage; chmod +x "$TOOL"; } +# --appimage-extract-and-run: works without FUSE (containers, WSL) +ARCH=x86_64 "$TOOL" --appimage-extract-and-run "$APPDIR" "$ROOT/dist/KnowYourRole-x86_64.AppImage" >/dev/null +echo "== done: dist/KnowYourRole-x86_64.AppImage" +echo " first run: pick your .cue in the game's disc picker (or: echo /path/to/game.cue > ~/.local/share/KnowYourRoleRecomp/disc.txt)" diff --git a/tools/linux/knowyourrole.desktop b/tools/linux/knowyourrole.desktop new file mode 100755 index 0000000..94222b1 --- /dev/null +++ b/tools/linux/knowyourrole.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Type=Application +Name=WWF SmackDown! 2 Know Your Role (Recomp) +Exec=AppRun +Icon=knowyourrole +Categories=Game; +Terminal=false