Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08a2617b06 | ||
|
|
39387b5e0f | ||
|
|
e67ac50c61 | ||
|
|
3ebbeba672 | ||
|
|
07394769ca | ||
|
|
ae939c4085 | ||
|
|
28996eff57 | ||
|
|
93efe0d607 |
+324
-4
@@ -285,6 +285,84 @@ print(pick[0]["browser_download_url"] if pick else "")
|
||||
esac
|
||||
}
|
||||
|
||||
# Same job as _wolf_download_emulator_appimage above, but against GitLab's
|
||||
# Releases API instead of GitHub's — needed for any project (ES-DE included)
|
||||
# that's hosted on GitLab rather than GitHub, since GitHub's API obviously
|
||||
# can't answer for a repo it doesn't host. Mirrors the same arch-matching /
|
||||
# post-download ELF-header verification logic so both call sites behave
|
||||
# identically from the caller's point of view.
|
||||
_wolf_download_emulator_appimage_gitlab() {
|
||||
local _display_name="$1" _project_path="$2" _existing_glob="$3" _dir="$4"
|
||||
if ls "$_dir"/$_existing_glob 2>/dev/null | grep -q .; then
|
||||
log_info "$_display_name already present in $_dir/"
|
||||
return 0
|
||||
fi
|
||||
local _get=""
|
||||
echo ""
|
||||
log_info "$_display_name can be auto-downloaded."
|
||||
prompt_yn "Download $_display_name AppImage now? (y/n):" "y" _get
|
||||
[[ "$_get" =~ ^[Yy]$ ]] || return 0
|
||||
|
||||
log_info "Fetching latest $_display_name release from GitLab..."
|
||||
local _encoded_path
|
||||
_encoded_path=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=''))" "$_project_path")
|
||||
local _url
|
||||
_url=$(curl -fsSL "https://gitlab.com/api/v4/projects/${_encoded_path}/releases" \
|
||||
| HOST_ARCH="$(uname -m)" python3 -c '
|
||||
import sys, json, os
|
||||
host = os.environ.get("HOST_ARCH", "")
|
||||
arch_tags = {
|
||||
"x86_64": ["x86_64", "amd64", "x64"],
|
||||
"aarch64": ["aarch64", "arm64"],
|
||||
"arm64": ["aarch64", "arm64"],
|
||||
}.get(host, [host] if host else [])
|
||||
all_arch_tags = ["x86_64", "amd64", "x64", "aarch64", "arm64", "armv7", "armhf", "i386", "i686"]
|
||||
def has(name, tags):
|
||||
n = name.lower()
|
||||
return any(t in n for t in tags)
|
||||
releases = json.load(sys.stdin)
|
||||
# GitLab does not guarantee list order — sort explicitly instead of
|
||||
# assuming index 0 is the newest (the mistake that would silently pick a
|
||||
# stale/older release on some future API response ordering change).
|
||||
releases = sorted(releases, key=lambda r: r.get("released_at") or "", reverse=True)
|
||||
assets = []
|
||||
for r in releases:
|
||||
for link in r.get("assets", {}).get("links", []):
|
||||
url = link.get("direct_asset_url") or link.get("url") or ""
|
||||
if url.endswith(".AppImage"):
|
||||
assets.append({"name": link.get("name", url), "browser_download_url": url})
|
||||
if assets:
|
||||
break
|
||||
matching = [a for a in assets if arch_tags and has(a["name"], arch_tags)]
|
||||
untagged = [a for a in assets if not has(a["name"], all_arch_tags)]
|
||||
pick = matching or untagged or assets
|
||||
print(pick[0]["browser_download_url"] if pick else "")
|
||||
' 2>/dev/null)
|
||||
if [[ -z "$_url" ]]; then
|
||||
log_warning "Could not resolve download URL — get it manually from https://gitlab.com/${_project_path}/-/releases"
|
||||
return 1
|
||||
fi
|
||||
local _file="$_dir/$(basename "$_url")"
|
||||
curl -fL --progress-bar -o "$_file" "$_url" \
|
||||
&& chmod +x "$_file" \
|
||||
&& chown "$ACTUAL_USER:$ACTUAL_USER" "$_file" \
|
||||
&& log_success "$_display_name downloaded: $_file" \
|
||||
|| { log_warning "Download failed — get it manually from https://gitlab.com/${_project_path}/-/releases"; return 1; }
|
||||
|
||||
local _got_arch
|
||||
_got_arch=$(file -b "$_file" 2>/dev/null)
|
||||
case "$(uname -m)" in
|
||||
x86_64)
|
||||
echo "$_got_arch" | grep -qi 'x86-64\|x86_64' || \
|
||||
log_warning "$_file doesn't look like an x86_64 build ($_got_arch) — it will fail with 'exec format error'. Grab the x86_64 asset by hand from https://gitlab.com/${_project_path}/-/releases"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
echo "$_got_arch" | grep -qi 'aarch64\|arm64' || \
|
||||
log_warning "$_file doesn't look like an aarch64 build ($_got_arch) — it may fail to run. Grab the aarch64 asset by hand from https://gitlab.com/${_project_path}/-/releases"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_wolf() {
|
||||
require_docker || return 1
|
||||
|
||||
@@ -939,6 +1017,85 @@ UDEV
|
||||
log_info "not something this installer can supply. Cemu's own First-Time Setup Wizard covers where"
|
||||
log_info "to put it once you have one."
|
||||
|
||||
# ── Optional: ES-DE and RetroArch as standalone AppImages (for Steam) ────
|
||||
# These are ADDITIONAL to the esde/retroarch Wolf catalog containers
|
||||
# above, not a replacement — nothing here removes or changes those. The
|
||||
# only reason to want this: once added as a Steam non-Steam game
|
||||
# (./manage.sh steam-add-nonsteam-game, which the wolf mount fix above
|
||||
# already extended to reach the same roms/saves/bios/retro-home/
|
||||
# retroarch paths the esde/retroarch containers use), Steam Input can
|
||||
# give each of up to 4 identical-model controllers its own distinct
|
||||
# identity by device path — the one thing Wolf's own 3-concrete-pad-type
|
||||
# ceiling can't do for a 4th controller (see manage.sh's own "4
|
||||
# controllers (Cemu / Wii U games)" help text). Skip both prompts below
|
||||
# if you're happy running Wii U/retro systems through the esde app
|
||||
# directly and don't need Steam's per-device controller assignment.
|
||||
#
|
||||
# Both download to a FIXED, predictable filename (ES-DE.AppImage /
|
||||
# RetroArch.AppImage) regardless of the real upstream release asset's
|
||||
# own name — steam-add-nonsteam-game matches by substring against the
|
||||
# actual filename on disk, and bash glob matching is case-sensitive, so
|
||||
# a fixed name (same symlink trick already used for Dolphin above) is
|
||||
# what makes './manage.sh steam-add-nonsteam-game es-de' reliably find
|
||||
# it regardless of how the vendor's own release happens to be named.
|
||||
if [ ! -f "$_EMU_DIR/ES-DE.AppImage" ]; then
|
||||
echo ""
|
||||
# ES-DE is hosted on GitLab, not GitHub (confirmed against its own
|
||||
# project page) — a different Releases API than every other
|
||||
# standalone emulator above, hence the separate _gitlab helper.
|
||||
log_info "ES-DE also ships an official standalone Linux AppImage — separate from the esde Wolf"
|
||||
log_info "app above. Only useful for adding to Steam (see this repo's wolf README); skip this if"
|
||||
log_info "you'll only ever use the esde app directly."
|
||||
local _GET_ESDE_APPIMAGE=""
|
||||
prompt_yn "Download the ES-DE AppImage for use via Steam? (y/n):" "n" _GET_ESDE_APPIMAGE
|
||||
if [[ "$_GET_ESDE_APPIMAGE" =~ ^[Yy]$ ]]; then
|
||||
_wolf_download_emulator_appimage_gitlab \
|
||||
"ES-DE" "es-de/emulationstation-de" "ES-DE.AppImage" "$_EMU_DIR"
|
||||
local _ESDE_REAL
|
||||
_ESDE_REAL=$(ls "$_EMU_DIR"/*.AppImage 2>/dev/null \
|
||||
| grep -iE '/(es-?de|emulationstation)[^/]*\.AppImage$' \
|
||||
| grep -v '/ES-DE\.AppImage$' | head -1)
|
||||
if [[ -n "$_ESDE_REAL" ]]; then
|
||||
ln -sf "$(basename "$_ESDE_REAL")" "$_EMU_DIR/ES-DE.AppImage"
|
||||
chown -h "$ACTUAL_USER:$ACTUAL_USER" "$_EMU_DIR/ES-DE.AppImage" 2>/dev/null || true
|
||||
log_success "Linked $_EMU_DIR/ES-DE.AppImage -> $(basename "$_ESDE_REAL")"
|
||||
log_info "Once Wolf is running, add it to Steam with: cd $WOLF_DIR && ./manage.sh steam-setup-frontends"
|
||||
log_info "(waits for Steam sign-in — QR code via Moonlight — then wires this in automatically)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$_EMU_DIR/RetroArch.AppImage" ]; then
|
||||
echo ""
|
||||
# Libretro's own buildbot doesn't publish through a GitHub/GitLab
|
||||
# Releases API this installer can automate against — hizzlekizzle/
|
||||
# RetroArch-AppImage is the well-regarded THIRD-PARTY nightly-build
|
||||
# project the AppImage community catalogs (appimage.github.io etc.)
|
||||
# themselves point to, same "flagged, not silently offered as
|
||||
# official" treatment as the Dolphin community build above.
|
||||
log_info "RetroArch also has a standalone Linux AppImage, separate from the retroarch Wolf app"
|
||||
log_info "above — same rationale as ES-DE just above (Steam Input's per-device controller"
|
||||
log_info "assignment). This comes from hizzlekizzle/RetroArch-AppImage, a well-regarded but"
|
||||
log_info "THIRD-PARTY nightly-build project, not an official libretro.org release — grab"
|
||||
log_info "RetroArch's own build by hand instead if you'd rather not run that."
|
||||
local _GET_RA_APPIMAGE=""
|
||||
prompt_yn "Download the RetroArch AppImage for use via Steam? (y/n):" "n" _GET_RA_APPIMAGE
|
||||
if [[ "$_GET_RA_APPIMAGE" =~ ^[Yy]$ ]]; then
|
||||
_wolf_download_emulator_appimage \
|
||||
"RetroArch" "hizzlekizzle/RetroArch-AppImage" "RetroArch.AppImage" "$_EMU_DIR"
|
||||
local _RA_REAL
|
||||
_RA_REAL=$(ls "$_EMU_DIR"/*[Rr]etro[Aa]rch*.AppImage 2>/dev/null \
|
||||
| grep -v '/RetroArch\.AppImage$' | head -1)
|
||||
if [[ -n "$_RA_REAL" ]]; then
|
||||
ln -sf "$(basename "$_RA_REAL")" "$_EMU_DIR/RetroArch.AppImage"
|
||||
chown -h "$ACTUAL_USER:$ACTUAL_USER" "$_EMU_DIR/RetroArch.AppImage" 2>/dev/null || true
|
||||
log_success "Linked $_EMU_DIR/RetroArch.AppImage -> $(basename "$_RA_REAL")"
|
||||
log_info "Once Wolf is running, add it to Steam with: cd $WOLF_DIR && ./manage.sh steam-setup-frontends"
|
||||
log_info "(waits for Steam sign-in — QR code via Moonlight — then wires this in automatically)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Optional: TI-99/4A as its own ES-DE system ────────────────────────────
|
||||
# TI-99/4A has no libretro core and isn't one of ES-DE's built-in systems,
|
||||
# so getting it real ES-DE treatment (artwork scraping, gameplay-time
|
||||
@@ -2166,7 +2323,26 @@ CATALOG = {
|
||||
# (see below) — without it, an emulator AppImage (Cemu, etc.)
|
||||
# added as a non-Steam game (./manage.sh steam-add-nonsteam-game)
|
||||
# has no file to actually point Exe at from inside this container.
|
||||
f'{games}/emulators:/home/retro/Applications:rw'],
|
||||
f'{games}/emulators:/home/retro/Applications:rw',
|
||||
# Same roms/saves/bios/retro-home/retroarch mounts as esde/
|
||||
# retroarch below — without these, a standalone ES-DE or
|
||||
# RetroArch AppImage added here as a non-Steam game (same
|
||||
# mechanism as Cemu above) would see none of the ROMs, cores,
|
||||
# save states, BIOS files, or ES-DE's own settings/custom
|
||||
# systems (TI-99, Wii U AntiMicroX command) that the esde/
|
||||
# retroarch containers already have — it'd start from a
|
||||
# completely empty config instead of reusing what's already
|
||||
# set up. Every path here is the exact same host directory
|
||||
# those two containers mount, just also visible from Steam.
|
||||
f'{games}/roms:/ROMs:rw',
|
||||
f'{games}/saves:/mnt/games/saves:rw',
|
||||
f'{games}/media:/media:rw',
|
||||
f'{games}/bios:/home/retro/bioses:rw',
|
||||
f'{games}/retro-home:/home/retro/.config:rw',
|
||||
f'{games}/retro-home-data:/home/retro/.local/share:rw',
|
||||
f'{games}/retroarch:/home/retro/.config/retroarch:rw',
|
||||
f'{games}/esde-custom-systems:/home/retro/ES-DE/custom_systems:rw',
|
||||
f'{games}/esde-settings:/home/retro/ES-DE/settings:rw'],
|
||||
env=['PROTON_LOG=1', 'RUN_SWAY=true',
|
||||
'GOW_REQUIRED_DEVICES=/dev/input/* /dev/dri/* /dev/nvidia*'],
|
||||
cap_add=['SYS_ADMIN', 'SYS_NICE', 'SYS_PTRACE', 'NET_RAW', 'MKNOD', 'NET_ADMIN'],
|
||||
@@ -3554,7 +3730,7 @@ _manage_wolf_complete() {
|
||||
local commands="start stop restart logs status pin controllers update apps cores reorder
|
||||
add-web ge-proton games setup-swbf2 fix-ea-game wait-ea-app
|
||||
install-ea-app diagnose-ea fix-perms install-completion backup
|
||||
steam-add-nonsteam-game cemu-clone-controller cemu-sync-controllers"
|
||||
steam-add-nonsteam-game steam-setup-frontends cemu-clone-controller cemu-sync-controllers"
|
||||
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
||||
}
|
||||
# Register for both 'manage.sh' and './manage.sh' invocation styles
|
||||
@@ -4014,6 +4190,75 @@ VDFPY
|
||||
echo "'Force the use of a specific Steam Play compatibility tool' is OFF — Cemu and"
|
||||
echo "other native Linux AppImages don't run through Proton."
|
||||
;;
|
||||
steam-setup-frontends)
|
||||
# One command covering what the ES-DE/RetroArch AppImage download
|
||||
# step in setup.sh can't finish on its own: that step runs before
|
||||
# Wolf/Steam containers even exist, so it can only download the
|
||||
# AppImages and print instructions. This picks up from there —
|
||||
# start Steam if needed, WAIT for it to be signed in (Steam Guard's
|
||||
# QR-code sign-in itself can't be scripted: it needs a phone
|
||||
# approving a prompt, so this only polls for the result, never
|
||||
# performs the sign-in), then add whichever AppImage(s) already got
|
||||
# downloaded as Steam non-Steam games via the existing
|
||||
# steam-add-nonsteam-game command above (re-invoked, not
|
||||
# reimplemented, so the two never drift apart).
|
||||
if ! docker ps --format '{{.Names}}' | grep -qi WolfSteam; then
|
||||
echo "Starting Wolf (docker compose up -d)..."
|
||||
docker compose up -d
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
_SSF_SIGNED_IN() {
|
||||
local _home
|
||||
_home=$(_steam_home)
|
||||
[ -n "$_home" ] && [ -n "$(sudo ls "$_home/.steam/steam/userdata/" 2>/dev/null)" ]
|
||||
}
|
||||
|
||||
if _SSF_SIGNED_IN; then
|
||||
echo "Steam is already signed in — proceeding."
|
||||
else
|
||||
echo ""
|
||||
echo "Steam isn't signed in yet. In Moonlight:"
|
||||
echo " 1. Connect to the Steam app."
|
||||
echo " 2. On Steam's login screen, choose 'Sign in with QR code'."
|
||||
echo " 3. Scan it with your phone's Steam app and approve the prompt."
|
||||
echo ""
|
||||
echo "Waiting for sign-in (up to 10 minutes, checking every 5s — Ctrl+C to give up"
|
||||
echo "and finish this later by re-running './manage.sh steam-setup-frontends')..."
|
||||
_SSF_WAITED=0
|
||||
until _SSF_SIGNED_IN; do
|
||||
sleep 5
|
||||
_SSF_WAITED=$((_SSF_WAITED + 5))
|
||||
if [ "$_SSF_WAITED" -ge 600 ]; then
|
||||
echo "Still not signed in after 10 minutes — giving up for now."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "Signed in."
|
||||
fi
|
||||
|
||||
GAME_DIR=$(grep '^GAME_STORAGE_DIR=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d= -f2-)
|
||||
if [ -z "$GAME_DIR" ]; then read -r -p " Game storage path: " GAME_DIR; fi
|
||||
_SSF_EMU_DIR="$GAME_DIR/emulators"
|
||||
_SSF_ADDED_ANY=0
|
||||
if [ -f "$_SSF_EMU_DIR/ES-DE.AppImage" ]; then
|
||||
"$0" steam-add-nonsteam-game es-de "EmulationStation (ES-DE)" && _SSF_ADDED_ANY=1
|
||||
else
|
||||
echo "ES-DE.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf"
|
||||
fi
|
||||
if [ -f "$_SSF_EMU_DIR/RetroArch.AppImage" ]; then
|
||||
"$0" steam-add-nonsteam-game retroarch "RetroArch" && _SSF_ADDED_ANY=1
|
||||
else
|
||||
echo "RetroArch.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf"
|
||||
fi
|
||||
|
||||
if [ "$_SSF_ADDED_ANY" = 1 ]; then
|
||||
echo ""
|
||||
echo "Cores/shaders/overlays live in the same retroarch/ directory the esde/retroarch apps"
|
||||
echo "already use (shared mount — nothing new to configure there). If you haven't already:"
|
||||
echo " ./manage.sh cores all (downloads every libretro core + shaders/overlays/database)"
|
||||
fi
|
||||
;;
|
||||
cemu-clone-controller)
|
||||
# Clones a WORKING Cemu controller mapping onto a new device slot,
|
||||
# skipping Cemu's own Input Settings dialog entirely for that slot.
|
||||
@@ -4178,7 +4423,7 @@ CLONEPY
|
||||
fi
|
||||
echo "Reading live controller GUIDs from $_CSC_CONTAINER..."
|
||||
|
||||
_CSC_PROBE=$(docker exec -u retro "$_CSC_CONTAINER" python3 - << 'PROBEPY'
|
||||
_CSC_PROBE=$(docker exec -i -u retro "$_CSC_CONTAINER" python3 - << 'PROBEPY'
|
||||
import ctypes, ctypes.util, sys
|
||||
|
||||
libname = ctypes.util.find_library("SDL2") or "libSDL2-2.0.so.0"
|
||||
@@ -4327,6 +4572,8 @@ SYNCPY
|
||||
echo " ./manage.sh install-completion - Enable tab-completion for this script"
|
||||
echo " ./manage.sh steam-add-nonsteam-game [name] [display name]"
|
||||
echo " - Add an emulator (emulators/) as a non-Steam game, no GUI needed"
|
||||
echo " ./manage.sh steam-setup-frontends - Wait for Steam sign-in (QR code via Moonlight), then add"
|
||||
echo " downloaded ES-DE/RetroArch AppImages to Steam"
|
||||
echo " ./manage.sh cemu-clone-controller [slot 0-3] [uuid] [display name]"
|
||||
echo " - Clone a working Cemu controller mapping onto a new device slot"
|
||||
echo " ./manage.sh cemu-sync-controllers - Auto-detect connected controllers via SDL and clone mappings onto all of them"
|
||||
@@ -4819,7 +5066,17 @@ PYEOF
|
||||
echo " Online together → each player launches their own session,"
|
||||
echo " all connect to the same game server"
|
||||
echo ""
|
||||
echo "Manage: cd $WOLF_DIR && ./manage.sh {start|stop|restart|logs|status|pin|update|apps|reorder|add-web|ge-proton|fix-ea-game}"
|
||||
echo " 4 controllers, one game (e.g. Cemu/Wii U)? Steam Input tells identical"
|
||||
echo " controllers apart by device path, not just SDL GUID — add the emulator"
|
||||
echo " to Steam as a non-Steam game instead of launching it from ES-DE:"
|
||||
echo " ./manage.sh steam-setup-frontends # ES-DE/RetroArch AppImages into Steam"
|
||||
echo " ./manage.sh steam-add-nonsteam-game cemu"
|
||||
echo " ./manage.sh cemu-clone-controller / cemu-sync-controllers"
|
||||
echo " For the ES-DE/RetroArch Wolf apps directly, force distinct virtual pad"
|
||||
echo " types per slot instead: ./manage.sh controllers (see README.md)"
|
||||
echo ""
|
||||
echo "Manage: cd $WOLF_DIR && ./manage.sh {start|stop|restart|logs|status|update|cores|reorder|add-web|backup|ge-proton|fix-ea-game|controllers|steam-add-nonsteam-game|steam-setup-frontends|pin}"
|
||||
echo " ./manage.sh install-completion # tab-complete every command above"
|
||||
echo ""
|
||||
echo "── EA GAMES (Battlefront II, etc.) ───────────────────"
|
||||
echo ""
|
||||
@@ -4929,6 +5186,69 @@ container-created virtual controllers specifically (real hardware behaves
|
||||
this way; whether Steam Input sees Wolf's virtual joypads the same way is
|
||||
still to be tested) — worth trying before assuming it works.
|
||||
|
||||
## Running ES-DE and/or RetroArch through Steam instead of their own Wolf apps
|
||||
The same Steam Input reasoning above applies beyond just Cemu: ES-DE and
|
||||
RetroArch both ship their own official standalone Linux AppImages
|
||||
(separate from the \`esde\`/\`retroarch\` Wolf catalog apps this installer
|
||||
already runs), and adding one of those to Steam gets you the same
|
||||
per-device controller assignment for every system it covers, not just
|
||||
Cemu. \`sudo ./setup.sh wolf\` offers to download both (opt-in, default
|
||||
no) right after the Cemu step — ES-DE's from its GitLab releases (it
|
||||
isn't on GitHub), RetroArch's from \`hizzlekizzle/RetroArch-AppImage\` (a
|
||||
well-regarded third-party nightly build — libretro.org's own buildbot
|
||||
doesn't publish through an API this installer can automate against).
|
||||
Both land in \`emulators/\` under a fixed name (\`ES-DE.AppImage\` /
|
||||
\`RetroArch.AppImage\`) regardless of the real release asset's own
|
||||
filename, so Steam's non-Steam-game matching finds them reliably.
|
||||
|
||||
They reuse the exact same \`roms/\`, \`saves/\`, \`bios/\`, \`retro-home\`, and
|
||||
\`retroarch\` (cores/shaders/overlays) directories the \`esde\`/\`retroarch\`
|
||||
containers already use — the \`steam\` Wolf app mounts all of the same
|
||||
paths, so nothing needs re-downloading or re-scraping just because it's
|
||||
now also reachable from Steam. If you haven't already populated cores:
|
||||
\`\`\`bash
|
||||
cd $WOLF_DIR && ./manage.sh cores all
|
||||
\`\`\`
|
||||
|
||||
Finishing the Steam side needs one thing that can't be scripted — Steam
|
||||
Guard's QR-code sign-in requires a phone approving a prompt — so this
|
||||
polls for it instead of trying to script past it:
|
||||
\`\`\`bash
|
||||
cd $WOLF_DIR && ./manage.sh steam-setup-frontends
|
||||
\`\`\`
|
||||
Starts Wolf if it isn't already up, checks whether Steam's already
|
||||
signed in (proceeds immediately if so), otherwise prints the QR-code
|
||||
steps and waits (up to 10 minutes) for sign-in to complete, then adds
|
||||
whichever of ES-DE.AppImage/RetroArch.AppImage was downloaded as a Steam
|
||||
non-Steam game — re-using \`steam-add-nonsteam-game\` above rather than
|
||||
duplicating its shortcuts.vdf-writing logic. Safe to re-run any time
|
||||
(e.g. if it timed out waiting, or you downloaded the second AppImage
|
||||
later) — already-added shortcuts are updated in place, not duplicated.
|
||||
|
||||
**Returning to Steam from ES-DE, without a second instance:** if ES-DE
|
||||
is running as a Steam non-Steam game (via the AppImage above, not the
|
||||
separate \`esde\` Wolf app), Steam is the parent process the whole
|
||||
time — quitting ES-DE drops you back into the same still-running Steam
|
||||
Big Picture session rather than starting a new one. This only works for
|
||||
the AppImage-in-Steam path; the standalone \`esde\` Wolf app is a
|
||||
completely separate container, and Wolf has no supported way to hand off
|
||||
from one running app to another mid-session (switching apps means
|
||||
closing the Moonlight session and reconnecting to the other one).
|
||||
|
||||
**Multiple devices, same Steam account, same controller mappings?**
|
||||
Worth knowing before relying on it: Wolf gives each *paired client* its
|
||||
own separate Steam container/home directory (confirmed against this
|
||||
repo's own \`_steam_home()\` — it searches across multiple
|
||||
\`.../Steam\` directories, not just one), so a second device connecting
|
||||
to Wolf doesn't reuse the first device's Steam install and has to sign
|
||||
in separately the first time. Once it's signed into the *same* Steam
|
||||
account, Valve's own account-level Steam Cloud config sync should
|
||||
replicate your Steam Input controller bindings across those separate
|
||||
local installs (the same mechanism that syncs bindings between a Steam
|
||||
Deck and a gaming PC) — but that's a Steam-account feature, not
|
||||
something Wolf or this installer controls, and hasn't been confirmed
|
||||
live in this specific setup.
|
||||
|
||||
## Multiple controllers (same game/emulator can't tell them apart)
|
||||
**Symptom:** two or more controllers connected through the same Moonlight
|
||||
session, but the game/emulator only ever sees one — the first controller
|
||||
|
||||
Reference in New Issue
Block a user