Skip to content

Commit 6a8fd6b

Browse files
committed
Add FirmMux updater app and docs updates
1 parent c3b9e5c commit 6a8fd6b

File tree

9 files changed

+527
-10
lines changed

9 files changed

+527
-10
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The script will:
2727
- Stage dependencies (RetroArch data, NTR Forwarder, CIAs)
2828
- Stage optional standalone pathfile package (mGBA/snes9x_3ds/DaedalusX64)
2929
- Show DSP firmware reminder (`sd:/3ds/dspfirm.cdc`)
30+
- On-device updater app is included at `sd:/3ds/firmmux-updater.3dsx` (FirmMux update only).
3031

3132
Autoboot toggle (Settings):
3233
- OFF by default.
@@ -80,6 +81,11 @@ Run the PC setup script:
8081
- `python3 tools/firmmux_setup_pc.py`
8182
- Or: `python3 tools/firmmux_setup_pc.py --sd-root <SD_ROOT>`
8283

84+
On-device updater note:
85+
86+
- `sd:/3ds/firmmux-updater.3dsx` updates FirmMux files only.
87+
- Dependency staging remains PC-side via `tools/FirmMux_Setup.bat` or `tools/firmmux_setup_pc.py`.
88+
8389
Health check also verifies:
8490

8591
- `sd:/3ds/dspfirm.cdc` (if missing, dump DSP firmware from Rosalina menu)

SD/3ds/firmmux-updater.3dsx

153 KB
Binary file not shown.

SD/3ds/firmmux-updater.smdh

13.7 KB
Binary file not shown.

assets/logodl.png

2.36 KB
Loading

build.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,49 @@ build_cia_forwarder() {
2222
APP_AUTHOR='FirmMux Team' 2>&1 | tee -a "$log_file"
2323
}
2424

25+
build_downloader() {
26+
local dl_icon="assets/logodl.png"
27+
if [ -f "$dl_icon" ]; then
28+
local dims
29+
dims="$(python3 - <<'PY'
30+
import struct
31+
try:
32+
with open("assets/logodl.png", "rb") as f:
33+
sig = f.read(8)
34+
if sig != b"\x89PNG\r\n\x1a\n":
35+
print("invalid")
36+
else:
37+
_len = f.read(4)
38+
ctype = f.read(4)
39+
if ctype != b'IHDR':
40+
print("invalid")
41+
else:
42+
data = f.read(13)
43+
w, h = struct.unpack(">II", data[:8])
44+
print(f"{w}x{h}")
45+
except Exception:
46+
print("invalid")
47+
PY
48+
)"
49+
if [ "$dims" != "48x48" ]; then
50+
echo "Downloader icon assets/logodl.png is $dims (expected 48x48). Falling back to assets/icon.png." | tee -a "$log_file"
51+
dl_icon="assets/icon.png"
52+
fi
53+
else
54+
dl_icon="assets/icon.png"
55+
fi
56+
57+
make -B -j4 TARGET=firmmux_downloader \
58+
APP_TITLE='FirmMux Updater' \
59+
APP_DESCRIPTION='Update FirmMux on-device' \
60+
APP_AUTHOR='FirmMux Team' \
61+
APP_ICON="$dl_icon" 2>&1 | tee -a "$log_file"
62+
}
63+
2564
stage_sd() {
2665
cp -f FirmMux.3dsx SD/3ds/FirmMux.3dsx
2766
cp -f FirmMux.smdh SD/3ds/FirmMux.smdh
67+
mkdir -p SD/3ds
2868
mkdir -p SD/3ds/FirmMux
2969
mkdir -p SD/cias
3070
if [ -f boot.3dsx ]; then
@@ -33,6 +73,16 @@ stage_sd() {
3373
if [ -f boot.smdh ]; then
3474
cp -f boot.smdh SD/3ds/FirmMux/boot.smdh
3575
fi
76+
if [ -f firmmux_downloader.3dsx ]; then
77+
cp -f firmmux_downloader.3dsx SD/3ds/firmmux-updater.3dsx
78+
rm -f SD/3ds/FirmMux/firmmux-downloader.3dsx
79+
rm -f SD/3ds/firmmux-downloader.3dsx
80+
fi
81+
if [ -f firmmux_downloader.smdh ]; then
82+
cp -f firmmux_downloader.smdh SD/3ds/firmmux-updater.smdh
83+
rm -f SD/3ds/FirmMux/firmmux-downloader.smdh
84+
rm -f SD/3ds/firmmux-downloader.smdh
85+
fi
3686
echo "Staged SD binaries." | tee -a "$log_file"
3787
}
3888

@@ -74,6 +124,14 @@ else
74124
exit 1
75125
fi
76126

127+
echo "Building FirmMux downloader..."
128+
if build_downloader; then
129+
echo "Downloader build succeeded. Log: $log_file"
130+
else
131+
echo "Downloader build failed. Log: $log_file" >&2
132+
exit 1
133+
fi
134+
77135
echo "Building optional FirmMux CIA..."
78136
echo "Building FirmMux CIA forwarder ELF..."
79137
if build_cia_forwarder; then

docs/PC Setup.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ What it stages:
3737
- RetroArch 3DSX package files
3838
- Optional standalone pathfile package files (latest release)
3939
- Latest FirmMux release SD package (`FirmMux-SD.zip`) when using install/update modes
40+
- On-device updater app:
41+
- `sd:/3ds/firmmux-updater.3dsx`
42+
- `sd:/3ds/firmmux-updater.smdh`
4043

4144
RetroArch staging note:
4245

@@ -61,6 +64,11 @@ After script completes:
6164
- `L + D-Pad Down + Select` -> `Miscellaneous options` -> `Dump DSP firmware`
6265
4. Launch FirmMux and run Health check.
6366

67+
On-device updater scope:
68+
69+
- `firmmux-updater` updates FirmMux files only.
70+
- Use PC setup for dependency staging.
71+
6472
CIA note:
6573

6674
- `FirmMux.cia` is not the runtime app.

docs/SD Layout.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ sd:/
99
3ds/
1010
FirmMux.3dsx
1111
FirmMux.smdh
12+
firmmux-updater.3dsx
13+
firmmux-updater.smdh
1214
FirmMux/
1315
boot.3dsx # autoboot template used by Settings toggle
1416
boot.smdh # autoboot name/icon metadata
@@ -65,6 +67,7 @@ sd:/
6567
- bannertool by carstene1ns: https://github.com/carstene1ns/3ds-bannertool
6668
- makerom from Project_CTR by 3DSGuy: https://github.com/3DSGuy/Project_CTR
6769
- Official runtime path is `sd:/3ds/FirmMux.3dsx` from default Homebrew Menu.
70+
- `sd:/3ds/firmmux-updater.3dsx` updates FirmMux files only (no dependency staging).
6871
- Standalone pathfile routing is optional.
6972
- To enable optional standalone routing, install marker + apps:
7073
- `sd:/3ds/emulators/pathfile`

0 commit comments

Comments
 (0)