mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 04:04:18 +02:00
Install script: take a .zip or .7z holding the disc image
An archive is recognised by its first bytes, unpacked into the work dir with whichever unpacker the machine has (7-Zip, bsdtar, unzip, Python's zipfile, or bsdtar in a container of the machine's own architecture), and every file in it is offered to nodtool, largest first. The RMCP01 image wins; another region's disc is passed on so the ID check names it. The unpacked files are removed once the disc is extracted, or when no disc is found. Tested each unpacker with zip and 7z archives holding an RVZ in a subfolder, an archive holding NTSC and PAL images, an NTSC-only one, one with no disc, a password-protected zip and truncated archives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HBRGKTE1GnN2ah8gcZKr3
This commit is contained in:
2 files changed
+94
-14
No files matched your search
@@ -15,8 +15,8 @@
|
||||
#
|
||||
# Options:
|
||||
# --disc PATH your clean PAL RMCP01 disc: an ISO, WBFS or RVZ image (or WIA, CISO, GCZ, NFS,
|
||||
# TGC), or an extracted disc folder holding sys/ and files/. Needed for the first
|
||||
# build only.
|
||||
# TGC), a .zip or .7z holding one, or an extracted disc folder holding sys/ and
|
||||
# files/. Needed for the first build only.
|
||||
# --frame HOST where to install: an SSH destination (steamos@<frame-ip>, or an ~/.ssh/config
|
||||
# host such as Frame Control's "frame"), or "local" when running on the Frame.
|
||||
# Without it the game is only built.
|
||||
@@ -203,6 +203,74 @@ check_disc_id() {
|
||||
esac
|
||||
}
|
||||
|
||||
get_nodtool() {
|
||||
nodtool="$work_dir/nodtool-$nodtool_version"
|
||||
if [[ ! -x "$nodtool" ]]; then
|
||||
curl -fL --progress-bar -o "$nodtool.partial" \
|
||||
"https://github.com/encounter/nod/releases/download/$nodtool_version/nodtool-linux-$host_arch"
|
||||
chmod +x "$nodtool.partial"
|
||||
mv "$nodtool.partial" "$nodtool"
|
||||
fi
|
||||
}
|
||||
|
||||
archive_kind() {
|
||||
# Prints zip or 7z when $1 is such an archive, judged by its first bytes rather than its name.
|
||||
case "$(od -An -tx1 -N6 "$1" | tr -d ' \n')" in
|
||||
504b0304*|504b0506*|504b0708*) echo zip ;;
|
||||
377abcaf271c) echo 7z ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
unpack_archive() {
|
||||
# unpack_archive ARCHIVE DEST KIND, with whichever unpacker this machine has.
|
||||
local archive=$1 dest=$2 kind=$3 tool
|
||||
for tool in 7zz 7z 7za; do
|
||||
if command -v "$tool" >/dev/null 2>&1; then
|
||||
"$tool" x -y "-o$dest" "$archive" >/dev/null
|
||||
return
|
||||
fi
|
||||
done
|
||||
if command -v bsdtar >/dev/null 2>&1; then
|
||||
bsdtar -xf "$archive" -C "$dest"
|
||||
return
|
||||
fi
|
||||
if [[ "$kind" == zip ]] && command -v unzip >/dev/null 2>&1; then
|
||||
unzip -qo "$archive" -d "$dest"
|
||||
return
|
||||
fi
|
||||
if [[ "$kind" == zip ]] && command -v python3 >/dev/null 2>&1; then
|
||||
python3 -m zipfile -e "$archive" "$dest"
|
||||
return
|
||||
fi
|
||||
# Nothing here unpacks it: bsdtar in a container of this machine's own architecture.
|
||||
note "no 7-Zip or bsdtar on this machine; unpacking in a container"
|
||||
local platform=linux/amd64
|
||||
[[ "$host_arch" == aarch64 ]] && platform=linux/arm64
|
||||
"$runtime" run --rm --platform "$platform" -e OWNER="$(id -u):$(id -g)" \
|
||||
-v "$archive:/archive:ro,z" -v "$dest:/out:z" "$image" bash -c '
|
||||
apt-get update -qq && apt-get install -y -qq --no-install-recommends libarchive-tools >/dev/null &&
|
||||
bsdtar -xf /archive -C /out && chown -R "$OWNER" /out'
|
||||
}
|
||||
|
||||
find_disc_image() {
|
||||
# Prints the disc image nodtool reads under $1, largest first, preferring Mario Kart Wii PAL;
|
||||
# another disc is printed if there is no RMCP01, so the ID check names what it is.
|
||||
local file id first=""
|
||||
while IFS= read -r -d '' file; do
|
||||
id=$("$nodtool" --no-color info "$file" 2>/dev/null |
|
||||
sed -n 's/^Game ID: *\([A-Z0-9]\{6\}\).*/\1/p' | head -n 1) || true
|
||||
[[ -n "$id" ]] || continue
|
||||
if [[ "$id" == RMCP01 ]]; then
|
||||
printf '%s\n' "$file"
|
||||
return 0
|
||||
fi
|
||||
[[ -n "$first" ]] || first=$file
|
||||
done < <(find "$1" -type f -printf '%s\t%p\0' | sort -zrn | cut -zf2-)
|
||||
[[ -n "$first" ]] || return 1
|
||||
printf '%s\n' "$first"
|
||||
}
|
||||
|
||||
disc_dir="$work_dir/disc"
|
||||
if [[ -n "$disc" ]]; then
|
||||
[[ -e "$disc" ]] || fail "no disc at $disc"
|
||||
@@ -220,20 +288,31 @@ if [[ -n "$disc" ]]; then
|
||||
[[ -f "$disc_dir/sys/main.dol" && -f "$disc_dir/files/rel/StaticR.rel" ]] ||
|
||||
fail "$disc is not an extracted disc: it needs sys/main.dol and files/rel/StaticR.rel"
|
||||
elif [[ ! -f "$disc_dir/sys/main.dol" ]]; then
|
||||
say "Extracting your disc (a minute or two)"
|
||||
nodtool="$work_dir/nodtool-$nodtool_version"
|
||||
if [[ ! -x "$nodtool" ]]; then
|
||||
curl -fL --progress-bar -o "$nodtool.partial" \
|
||||
"https://github.com/encounter/nod/releases/download/$nodtool_version/nodtool-linux-$host_arch"
|
||||
chmod +x "$nodtool.partial"
|
||||
mv "$nodtool.partial" "$nodtool"
|
||||
get_nodtool
|
||||
disc_image=$disc
|
||||
if kind=$(archive_kind "$disc"); then
|
||||
say "Unpacking the $kind archive (a minute or two)"
|
||||
rm -rf "$work_dir/archive"
|
||||
mkdir -p "$work_dir/archive"
|
||||
unpack_archive "$disc" "$work_dir/archive" "$kind" || {
|
||||
rm -rf "$work_dir/archive"
|
||||
fail "could not unpack $disc (a damaged or password-protected archive?)"
|
||||
}
|
||||
disc_image=$(find_disc_image "$work_dir/archive") || {
|
||||
rm -rf "$work_dir/archive"
|
||||
fail "there is no disc image nodtool reads inside $disc. It reads ISO, WBFS, RVZ, WIA,
|
||||
CISO, GCZ, NFS and TGC images; an archive inside the archive has to be unpacked by hand."
|
||||
}
|
||||
note "found ${disc_image#"$work_dir/archive/"} inside"
|
||||
fi
|
||||
say "Extracting your disc (a minute or two)"
|
||||
rm -rf "$disc_dir.partial"
|
||||
# nodtool tells the format from the file's contents, whatever it is named.
|
||||
"$nodtool" extract -q "$disc" "$disc_dir.partial" ||
|
||||
"$nodtool" extract -q "$disc_image" "$disc_dir.partial" ||
|
||||
fail "nodtool could not read $disc. It reads ISO, WBFS, RVZ, WIA, CISO, GCZ, NFS and TGC
|
||||
images; unpack a .zip or .7z first."
|
||||
images, and those inside a .zip or .7z."
|
||||
mv "$disc_dir.partial" "$disc_dir"
|
||||
rm -rf "$work_dir/archive"
|
||||
fi
|
||||
fi
|
||||
if [[ ! -f "$disc_dir/sys/main.dol" || ! -f "$disc_dir/files/rel/StaticR.rel" ]]; then
|
||||
|
||||
@@ -42,7 +42,7 @@ of it compiling Dawn under emulation; later builds reuse it.
|
||||
- a Steam Frame with Developer Mode on (Steam Settings → System → Enable Developer Mode, then set a
|
||||
user password), on the same network as your PC;
|
||||
- your own clean PAL `RMCP01` disc of Mario Kart Wii: an ISO, WBFS or RVZ image (WIA, CISO, GCZ
|
||||
and NFS work too), or a folder you extracted it to;
|
||||
and NFS work too), as is or in a `.zip` or `.7z`, or a folder you extracted it to;
|
||||
- an x86_64 Linux PC with about 20 GB free and 16 GB of memory or more.
|
||||
|
||||
The PC commands below work in bash, zsh and fish.
|
||||
@@ -75,8 +75,9 @@ curl -fsSL https://raw.githubusercontent.com/mitch030504/Wiicompiled_VR_Frame/op
|
||||
```
|
||||
|
||||
- `--disc` takes the image whatever its name or extension; the format is read from the file
|
||||
itself. It checks the game ID before building and stops on any disc other than PAL `RMCP01`.
|
||||
A `.zip` or `.7z` has to be unpacked first.
|
||||
itself. A `.zip` or `.7z` is unpacked first (with 7-Zip, bsdtar or unzip if you have one, in a
|
||||
container otherwise), and the disc image inside it is found and used. It checks the game ID
|
||||
before building and stops on any disc other than PAL `RMCP01`.
|
||||
- It asks for the Frame's password when it gets there. If you use
|
||||
[Frame Control](https://github.com/saphid/frame-control), pass `--frame frame` instead: its SSH
|
||||
key answers to that name.
|
||||
|
||||
Reference in new issue
Block a user