Merge pull request #418 from outis1one/claude/wolf-pair-port-conflict-7nz8qg

wolf: add Cemu (Wii U), TI-99/4A custom ES-DE system, BIOS/MAME-sampl…
This commit is contained in:
Outis
2026-09-02 14:16:59 -04:00
committed by GitHub
+149 -6
View File
@@ -798,7 +798,8 @@ UDEV
"$GAME_STORAGE_DIR/steam-cache" \
"$GAME_STORAGE_DIR/bios" "$GAME_STORAGE_DIR/retroarch/cores" \
"$GAME_STORAGE_DIR/retroarch/shaders" "$GAME_STORAGE_DIR/retroarch/overlays" \
"$GAME_STORAGE_DIR/retro-home" "$GAME_STORAGE_DIR/retro-home-data"
"$GAME_STORAGE_DIR/retro-home" "$GAME_STORAGE_DIR/retro-home-data" \
"$GAME_STORAGE_DIR/esde-custom-systems"
# ── Wolf state folder on the game drive ───────────────────────────────────
# This is the clean way to keep Steam (and everything else) off the OS
@@ -860,7 +861,7 @@ UDEV
# confirmed live: "data is corrupted" / "could not write to/read from Wii
# system memory" was this directory not existing at all, since only
# .config had a persistent mount before this).
chown -R 1000:1000 "$GAME_STORAGE_DIR/retro-home" "$GAME_STORAGE_DIR/retro-home-data" "$GAME_STORAGE_DIR/retroarch" 2>/dev/null || true
chown -R 1000:1000 "$GAME_STORAGE_DIR/retro-home" "$GAME_STORAGE_DIR/retro-home-data" "$GAME_STORAGE_DIR/retroarch" "$GAME_STORAGE_DIR/esde-custom-systems" 2>/dev/null || true
log_success "Storage layout: $GAME_STORAGE_DIR/{roms/<system>/,steam,saves,media,emulators,...}"
log_info "ES-DE ROM directories pre-created. Drop ROMs in the matching subfolder."
@@ -910,6 +911,93 @@ UDEV
log_success "Linked $_EMU_DIR/Dolphin_Emulator.AppImage -> $(basename "$_DOLPHIN_REAL") (the filename ES-DE's own find-rules require)"
fi
# Cemu (Wii U) — no libretro core exists (checked live: a third-party
# attempt exists but was never merged into RetroArch and there are no
# plans to; standalone is the only real path). Cemu's own official
# release asset is already named Cemu-<version>-x86_64.AppImage, which
# matches ES-DE's own find-rule (Cemu*.AppImage) directly — no
# Dolphin-style rename/symlink needed here.
#
# SECURITY NOTE: Cemu's official Linux release assets were compromised
# (supply-chain attack) for a period around v2.6 in 2026-05, later
# restored — confirmed via Datadog Security Labs' public writeup. Always
# download from cemu-project/Cemu's own GitHub releases (which this
# does) rather than a mirror, and check the project's own release notes
# if you want to verify checksums before running it.
log_warning "Cemu (Wii U) downloads from cemu-project's official releases. Its Linux release assets"
log_warning "were briefly compromised in a supply-chain attack around v2.6 (since restored) — worth"
log_warning "knowing given Wii U games are otherwise unverifiable executables running with your GPU."
_wolf_download_emulator_appimage \
"Cemu (Wii U)" "cemu-project/Cemu" "Cemu*.AppImage" "$_EMU_DIR"
log_info "Cemu needs its own Wii U common key (keys.txt) for most encrypted retail games — that's"
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: 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
# tracking) needs a custom system definition — confirmed against ES-DE's
# own USERGUIDE.md: a custom_systems/es_systems.xml, living outside the
# bundled config specifically so it complements rather than replaces it,
# at ~/ES-DE/custom_systems/ inside the container (its own mount, added
# above — that path isn't covered by any of the existing .config/
# .local/share mounts). js99er (this repo's existing browser-based
# TI-99/4A emulator, a separate non-Wolf service) is deliberately not
# used here — it's not something ES-DE can launch as a system.
#
# ti99sim-sdl (billzajac/ti99sim) is the real target — genuine SDL2
# joystick/gamepad support, confirmed against its own README — but it's
# source-only with no AppImage, so unlike Azahar/PCSX2/Dolphin/Cemu this
# installer can't just download a working binary: building it here would
# mean compiling against the HOST's glibc/SDL2 while the binary actually
# needs to run inside the ES-DE container's own (different) runtime, and
# that mismatch isn't something to guess at blind. The custom system
# definition below always gets written — cheap and correct regardless —
# pointing at emulators/ti99sim-sdl (the same ~/Applications convention
# every other standalone emulator here uses), so dropping a working
# binary there is the only remaining step.
echo ""
local _GET_TI99=""
prompt_yn "Set up TI-99/4A as its own ES-DE system (artwork scraping, gameplay-time tracking)? (y/n):" "n" _GET_TI99
if [[ "$_GET_TI99" =~ ^[Yy]$ ]]; then
mkdir -p "$GAME_STORAGE_DIR/esde-custom-systems" "$GAME_STORAGE_DIR/roms/ti994a"
local _TI99_XML="$GAME_STORAGE_DIR/esde-custom-systems/es_systems.xml"
if [ ! -f "$_TI99_XML" ] || ! grep -q '<name>ti994a</name>' "$_TI99_XML" 2>/dev/null; then
backup_if_exists "$_TI99_XML"
[ -f "$_TI99_XML" ] || echo '<systemList>' > "$_TI99_XML"
sed -i 's#</systemList>##' "$_TI99_XML" 2>/dev/null
cat >> "$_TI99_XML" << 'XMLEOF'
<system>
<name>ti994a</name>
<fullname>Texas Instruments TI-99/4A</fullname>
<path>%ROMPATH%/ti994a</path>
<extension>.ctg .rpk .bin</extension>
<command>%INJECT%=%BASENAME%.esprefix /home/retro/Applications/ti99sim-sdl --joystick1=1 %ROM%</command>
<platform>ti99</platform>
<theme>ti99</theme>
</system>
</systemList>
XMLEOF
chown "$ACTUAL_USER:$ACTUAL_USER" "$_TI99_XML"
log_success "TI-99/4A added as an ES-DE system (roms/ti994a/, custom_systems/es_systems.xml)"
else
log_info "TI-99/4A system definition already present — left as-is."
fi
echo ""
log_warning "ti99sim-sdl itself still needs to be built and placed by hand — this installer can't"
log_warning "safely cross-compile a binary that's guaranteed to run inside the ES-DE container:"
log_info " 1. git clone https://github.com/billzajac/ti99sim.git && cd ti99sim && make"
log_info " (needs libsdl2-dev — same build machine/container the ES-DE image itself runs on"
log_info " gives the best chance the result actually runs; a plain host build may hit a"
log_info " glibc/SDL2 mismatch inside the container)"
log_info " 2. Copy the resulting ti99sim-sdl binary to:"
log_info " $GAME_STORAGE_DIR/emulators/ti99sim-sdl"
log_info " 3. You'll also need your own TI-99/4A console ROM + GROM dump (real console"
log_info " firmware, same legal situation as any other console BIOS) — ti99sim's own"
log_info " README covers where it expects that once you have it."
log_info " 4. Drop .ctg/.rpk/.bin cartridge files into roms/ti994a/"
fi
# ── App selection ─────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════════════════"
@@ -1436,7 +1524,8 @@ CATALOG = {
f'{games}/retro-home-data:/home/retro/.local/share:rw',
f'{games}/retroarch:/home/retro/.config/retroarch:rw',
f'{games}/emulators:/mnt/games/emulators:rw',
f'{games}/emulators:/home/retro/Applications:rw'],
f'{games}/emulators:/home/retro/Applications:rw',
f'{games}/esde-custom-systems:/home/retro/ES-DE/custom_systems:rw'],
env=STD_ENV, cap_add=STD_CAP, security_opt=[], ipc_mode='host',
ulimits=[], privileged=False,
),
@@ -2817,7 +2906,8 @@ CATALOG = {
f'{games}/retro-home-data:/home/retro/.local/share:rw',
f'{games}/retroarch:/home/retro/.config/retroarch:rw',
f'{games}/emulators:/mnt/games/emulators:rw',
f'{games}/emulators:/home/retro/Applications:rw'],
f'{games}/emulators:/home/retro/Applications:rw',
f'{games}/esde-custom-systems:/home/retro/ES-DE/custom_systems:rw'],
env=STD_ENV, cap_add=STD_CAP, security_opt=[], ipc_mode='host',
ulimits=[], privileged=False,
),
@@ -3092,7 +3182,9 @@ PYEOF
echo "── EMULATION (ES-DE) FIRST RUN ───────────────────────"
echo ""
echo " • Drop ROMs in roms/<system>/ (e.g. roms/snes/, roms/genesis/)"
echo " • Drop BIOS files in bios/ (PSX/Saturn/Dreamcast/Neo-Geo need them)"
echo " • Drop BIOS files in bios/ (PSX/Saturn/Dreamcast/Neo-Geo need them; PS2/PCSX2 and"
echo " TI-99/4A need their own BIOS/console ROM too, but PS2 is configured inside PCSX2's own"
echo " settings rather than auto-detected from bios/, and TI-99/4A's setup is manual — see below)"
echo " • RetroArch cores are pre-downloaded — retro games launch immediately"
echo " • Shaders, overlays, cheats, and the game database are pre-downloaded too —"
echo " all persist on the game drive and survive new sessions and reinstalls"
@@ -3268,7 +3360,11 @@ ES-DE is usable the moment you launch it; only ROMs and BIOS are yours to add.
- **ROMs**: drop files into \`roms/<system>/\` (e.g. \`roms/snes/\`, \`roms/genesis/\`).
Every standard system folder is pre-created.
- **BIOS**: drop firmware into \`bios/\` (mounted at \`~/bioses\`). Required for
PSX, Saturn, Dreamcast, Neo-Geo, PC Engine CD, etc.
PSX, Saturn, Dreamcast, Neo-Geo, PC Engine CD, etc. **PS2/PCSX2 also needs
its own BIOS**, but it's configured inside PCSX2's own settings UI (BIOS
directory) rather than auto-detected from this shared folder — point it at
\`bios/\` there, or its own default location. **TI-99/4A** needs a real
console ROM + GROM dump too — see the TI-99/4A section below.
- **RetroArch cores**: pre-downloaded into \`retroarch/cores/\` and mounted at
\`~/.config/retroarch/cores\`, so libretro games launch right away. Refresh or
expand the set with \`./manage.sh cores\` (\`all\` = full buildbot set + the
@@ -3359,6 +3455,53 @@ auto-detected. Missing ones get offered again on a fresh install
(\`sudo ./setup.sh wolf\`); to grab just one by hand, download its AppImage
into \`emulators/\`, \`chmod +x\` it.
## Wii U (Cemu)
No libretro core exists for Wii U — Cemu is standalone-only, same download
pattern as the three above (\`emulators/\`, official cemu-project/Cemu
releases, auto-offered on install). Two things worth knowing:
- Cemu's own Linux release assets were briefly compromised in a
supply-chain attack around v2.6 (2026-05, since restored) — this
installer downloads straight from cemu-project's own GitHub releases,
but it's worth being aware of if you want to check checksums yourself.
- Most retail Wii U games are encrypted and need your own Wii U common key
(\`keys.txt\`) — Cemu's own First-Time Setup Wizard covers where that goes.
## TI-99/4A
If you said yes to the TI-99/4A prompt during install, it's set up as a
real ES-DE system (\`roms/ti994a/\`, artwork scraping, gameplay-time
tracking) via a custom system definition at
\`esde-custom-systems/es_systems.xml\` — **not** this repo's \`js99er\`
service, which is browser-based and isn't something ES-DE can launch as a
system.
The emulator itself, \`ti99sim-sdl\` (real SDL2 gamepad support), isn't
auto-downloaded — it has no AppImage, and building it on the host risks a
glibc/SDL2 mismatch against the ES-DE container's own runtime that isn't
safe to guess at blind. Build it yourself and drop the binary at
\`emulators/ti99sim-sdl\`:
\`\`\`bash
git clone https://github.com/billzajac/ti99sim.git && cd ti99sim && make
\`\`\`
(needs \`libsdl2-dev\`). You'll also need your own TI-99/4A console ROM +
GROM dump — same legal situation as any other console BIOS, and not
something this installer supplies — ti99sim's own README covers where it
expects that. Then drop \`.ctg\`/\`.rpk\`/\`.bin\` cartridge files into
\`roms/ti994a/\`.
## MAME: sample packs showing up as games
MAME sample packs (audio for a handful of older analog-sound games) use the
exact same \`.zip\`-per-game naming as real ROMs, so if they're sitting in
\`roms/mame/\` alongside your actual ROM set, ES-DE/RetroArch's MAME core
lists them as if they were games too — there's no reliable filename-only
way to tell them apart (a samples zip and a ROM zip for the same game can
share the identical name). They belong in RetroArch's system directory
instead, under a MAME-core-specific \`samples/\` subfolder (e.g.
\`retroarch/system/mame2003-plus/samples/\` for MAME2003-Plus — the exact
subfolder name depends on which MAME core variant you're using), never in
\`roms/mame/\` itself. A samples zip's contents are almost entirely \`.wav\`
files where a real ROM zip's aren't, which is the practical way to tell
them apart if you're not sure which of your files are which.
## Troubleshooting: app exits immediately ("Permission denied")
If a launcher (Steam, etc.) closes the moment it opens, its Wolf-managed home
dir has root-owned files the in-container user (uid 1000) can't write. Fix: