From 62fa90c839acb25b44cf2e452f1c5b35d07c9e3b Mon Sep 17 00:00:00 2001 From: "NathanNeurotic (Ripto)" <109461996+NathanNeurotic@users.noreply.github.com> Date: Tue, 28 Jul 2026 12:21:59 -0700 Subject: [PATCH 1/2] docs: credit zackcage6, and sweep the docs/CI for retired-flavour drift Credits ------- Adds zackcage6 to every credit surface: CREDITS, the README's real-hardware testing section, and the in-app About dialog. The About entry APPENDS to the existing QA row rather than adding one: that dialog cannot scroll (its only navigable control is the trailing OK, and diaRenderUI pins diaScrollOffset to 0 while focus sits on the first control), so a new row would push both the credit and the OK button past visibleBottom on a 448-line theme. The row is 68 chars, still inside the width the block already proved safe. The rule is now recorded in the comment so it is not rediscovered the hard way. Docs sweep ---------- Retiring the WOPL flavour (#273) and ps2max (#285) left stale references behind. Corrected across README.md, ROLLING_RELEASE.md, docs/NEUTRINO.md, docs/VCD.md, docs/THEME_ENGINE.md and docs/LANGUAGES.md. Findings were verified against the code and then adversarially re-verified before being applied; the two dated snapshots (docs/PARITY-AUDIT-*, docs/RECOVERY-*) were deliberately left alone, since they record history rather than making current claims. CI consistency -------------- * compilation.yml: drop the freepad swap from the three pinned jobs. It was a PROVABLE NO-OP -- freepad.irx is byte-identical (sha256 463fcb30cc4192dc...) across the pinned digest, ps2dev:latest, and the vendored copy -- and it left compilation.yml disagreeing with rolling-release.yml, which had already dropped it. Both workflows now treat the two flavours the same, so they differ by SDK DATE ONLY. * install_coherent_freepad.sh: now unreferenced. Kept, not deleted -- the vendored bytes and PROVENANCE.md are the record of the #254 investigation, and it is the ready-made remedy if a container ever ships an older freepad again. Header records the hashes and says to re-verify before trusting it. * ISSUE_TEMPLATE: the build-flavour dropdown still offered "WOPLSDK variant" and "PS2MAXSDK variant", so reporters were picking builds that no longer exist on the form used to triage them. Now PS2DEVLATESTSDK / PS2DEVPINNEDSDK. * ci-ps2dev-migration-probe.yml: probe the ps2dev digest pin, not ps2max/dev. * Comment drift in install_coherent_mmce.sh, build_rolling_extras.sh, rolling-release.yml and include/system.h. Historical mentions -- the notes explaining why WOPL was dropped and what ps2max used to do -- are deliberately preserved as the reasoning trail. Co-Authored-By: Claude Opus 5 --- .github/ISSUE_TEMPLATE/issue-report.yml | 3 +- .github/scripts/build_rolling_extras.sh | 2 +- .github/scripts/install_coherent_freepad.sh | 21 ++++- .github/scripts/install_coherent_mmce.sh | 4 +- .../workflows/ci-ps2dev-migration-probe.yml | 4 +- .github/workflows/compilation.yml | 21 ----- .github/workflows/rolling-release.yml | 4 +- CREDITS | 3 +- Makefile | 6 +- README.md | 63 ++++++++----- ROLLING_RELEASE.md | 33 ++++--- docs/LANGUAGES.md | 5 +- docs/NEUTRINO.md | 93 ++++++++++++++----- docs/THEME_ENGINE.md | 6 +- docs/VCD.md | 33 ++++--- include/system.h | 2 +- src/dialogs.c | 15 +-- 17 files changed, 192 insertions(+), 126 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/issue-report.yml b/.github/ISSUE_TEMPLATE/issue-report.yml index 979fc6a899..d3d43251ea 100644 --- a/.github/ISSUE_TEMPLATE/issue-report.yml +++ b/.github/ISSUE_TEMPLATE/issue-report.yml @@ -60,8 +60,7 @@ body: description: Each release ships several ELF flavours built with different SDKs — it matters for triage options: - Main RIPTOPL zip (PS2DEVLATESTSDK) - - WOPLSDK variant - - PS2MAXSDK variant + - PS2DEVPINNEDSDK variant (fallback build) - Not sure validations: required: true diff --git a/.github/scripts/build_rolling_extras.sh b/.github/scripts/build_rolling_extras.sh index a44654103f..471565eff2 100644 --- a/.github/scripts/build_rolling_extras.sh +++ b/.github/scripts/build_rolling_extras.sh @@ -7,7 +7,7 @@ # filename: "-PS2DEVPINNEDSDK" for the digest-pinned ps2dev snapshot # build, "-PS2DEVLATESTSDK" for the ps2dev:latest build -- so the VARIANTS and DEBUG zips carry # every SDK flavour of every build. $2 is the LOCALVERSION -# toolchain brand ("PS2MAXSDK"/"PS2DEVLATESTSDK") embedded in each ELF's version string: filenames get renamed +# toolchain brand ("PS2DEVPINNEDSDK"/"PS2DEVLATESTSDK") embedded in each ELF's version string: filenames get renamed # and moved to cards, and the debug/variant builds are exactly the ones that show up in bug # reports -- the on-screen version must self-identify the toolchain like the main builds do. # diff --git a/.github/scripts/install_coherent_freepad.sh b/.github/scripts/install_coherent_freepad.sh index f2c5a5dbe6..187eb57735 100644 --- a/.github/scripts/install_coherent_freepad.sh +++ b/.github/scripts/install_coherent_freepad.sh @@ -1,7 +1,24 @@ #!/bin/sh +# CURRENTLY UNREFERENCED -- no workflow calls this script as of 2026-07-28. +# +# It existed for the two older build containers (ps2max/dev, ghcr ps2homebrew pin), both of which +# are now RETIRED: the WOPLSDK flavour was dropped (#270/#273) and ps2max was replaced by a DIGEST +# PIN of ps2dev/ps2dev itself (#285). Both surviving flavours are now ps2dev images, and the +# vendored bytes are byte-identical to what they ship: +# +# ps2dev/ps2dev@sha256:c64ae69c...be995 freepad.irx sha256 463fcb30cc4192dc... +# ps2dev/ps2dev:latest freepad.irx sha256 463fcb30cc4192dc... +# modules/freepad/freepad.irx (vendored) freepad.irx sha256 463fcb30cc4192dc... +# +# So running it would copy a file over itself. The call sites were removed rather than left as a +# confusing no-op. Kept (not deleted) because the vendored bytes + PROVENANCE.md are the record of +# the #254 investigation, and because it is the ready-made remedy if a future container ever ships +# an older freepad generation again. Re-verify the hashes above before trusting it. +# +# Original rationale follows. +# # Install the vendored NEWER-GENERATION freepad.irx (modules/freepad/, see -# PROVENANCE.md there) over the container's stock freepad, for the two older -# build containers (ps2max/dev, ghcr ps2homebrew pin). The PS2DEVLATESTSDK +# PROVENANCE.md there) over the container's stock freepad. The PS2DEVLATESTSDK # container already ships these exact bytes natively -- do NOT run there. # # WHY (#254, hardware-confirmed by PixeliGer): with Game ID on (the default), diff --git a/.github/scripts/install_coherent_mmce.sh b/.github/scripts/install_coherent_mmce.sh index 39865e8e58..f18b0d0d1c 100644 --- a/.github/scripts/install_coherent_mmce.sh +++ b/.github/scripts/install_coherent_mmce.sh @@ -1,7 +1,7 @@ #!/bin/sh # Install a MENU-coherent mmceman into the container's $(PS2SDK)/iop/irx, replacing the -# SDK-provided prebuilt. Used by ALL THREE build flavours (ps2dev/ps2dev:latest, ps2max/dev, -# ghcr ps2homebrew pin) since the #254 fix. mmcedrv/mmceigr (the IN-GAME modules) are deliberately +# SDK-provided prebuilt. Used by BOTH build flavours (ps2dev/ps2dev:latest and the ps2dev digest +# pin) since the #254 fix. mmcedrv/mmceigr (the IN-GAME modules) are deliberately # LEFT AS THE CONTAINER'S STOCK PREBUILDS. # # WHY (menu / mmceman): the containers' mmce trio comes via ps2sdk-ports, pinned to ps2-mmce diff --git a/.github/workflows/ci-ps2dev-migration-probe.yml b/.github/workflows/ci-ps2dev-migration-probe.yml index 25a21c410b..5559826d7e 100644 --- a/.github/workflows/ci-ps2dev-migration-probe.yml +++ b/.github/workflows/ci-ps2dev-migration-probe.yml @@ -16,8 +16,8 @@ jobs: fail-fast: false matrix: include: - - container_image: ps2max/dev:v20250725-2 - label: ps2max-dev-v20250725-2 + - container_image: ps2dev/ps2dev@sha256:c64ae69c9817865ed98ff054e4ae5360b9e280ed952c97946bca95d9d35be995 + label: ps2dev-pinned - container_image: ps2dev/ps2dev:latest label: ps2dev-latest container: ${{ matrix.container_image }} diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index 7e8c200433..57cdac942e 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -63,13 +63,6 @@ jobs: - name: Install menu-coherent mmceman (#254) run: sh ./.github/scripts/install_coherent_mmce.sh - - name: Install newer-generation freepad (#254 pad death) - # The GameID mmceman load kills pad input with these containers' stock freepad - # builds (PixeliGer: dead cursor, live menu). The digest-pinned job - # in compilation.yml runs in the SAME container -- swap there too. Vendored - # newer-generation bytes (modules/freepad/PROVENANCE.md), fail-loud checks. - run: sh ./.github/scripts/install_coherent_freepad.sh - - name: Compile -> make clean release run: make --trace clean && make --trace release @@ -223,13 +216,6 @@ jobs: - name: Install menu-coherent mmceman (#254) run: sh ./.github/scripts/install_coherent_mmce.sh - - name: Install newer-generation freepad (#254 pad death) - # The GameID mmceman load kills pad input with these containers' stock freepad - # builds (PixeliGer: dead cursor, live menu). The digest-pinned job - # in compilation.yml runs in the SAME container -- swap there too. Vendored - # newer-generation bytes (modules/freepad/PROVENANCE.md), fail-loud checks. - run: sh ./.github/scripts/install_coherent_freepad.sh - - name: Get version run: | echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" @@ -525,13 +511,6 @@ jobs: - name: Install menu-coherent mmceman (#254) run: sh ./.github/scripts/install_coherent_mmce.sh - - name: Install newer-generation freepad (#254 pad death) - # The GameID mmceman load kills pad input with these containers' stock freepad - # builds (PixeliGer: dead cursor, live menu). The digest-pinned job - # in compilation.yml runs in the SAME container -- swap there too. Vendored - # newer-generation bytes (modules/freepad/PROVENANCE.md), fail-loud checks. - run: sh ./.github/scripts/install_coherent_freepad.sh - - name: Get version run: | echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" diff --git a/.github/workflows/rolling-release.yml b/.github/workflows/rolling-release.yml index 3c881dbbd3..5d5172e6a6 100644 --- a/.github/workflows/rolling-release.yml +++ b/.github/workflows/rolling-release.yml @@ -697,8 +697,8 @@ jobs: # # Archive the INSTALLABLE + REPRODUCIBLE payload only. The two big diagnostic BUNDLES are # deliberately EXCLUDED from the permanent MEGA copy: - # RIPTOPL-VARIANTS-*.zip (~120 MB -- every EXTRA_FEATURES x PADEMU combo x 3 SDKs) - # RIPTOPL-DEBUG-*.zip (~91 MB -- iopcore/ingame/eesio/ppctty/DTL debug builds x 3 SDKs) + # RIPTOPL-VARIANTS-*.zip (~120 MB -- every PADEMU x EXTRA_FEATURES x DUALSENSE combo, both SDKs) + # RIPTOPL-DEBUG-*.zip (~91 MB -- iopcore/ingame/eesio/ppctty/DTL debug builds, both SDKs) # They dominate the size (~10x: ~233 MB -> ~22 MB), they still ship on the GitHub rolling # release for the CURRENT build, and a *permanent* per-build archive is for restoring or # rebuilding an installable build -- not for old diagnostic permutations (when you debug, diff --git a/CREDITS b/CREDITS index 8cb2f7170b..0b38b20a23 100644 --- a/CREDITS +++ b/CREDITS @@ -101,7 +101,8 @@ BDMA-ATA (exFAT internal-HDD block-device support), plus fixes, feedback and ove by saildot4k Testing, bug reports and real-hardware feedback -by eliminator1403, lucaslmgv, AndrewBento, AcidReach, bodvenomz, nuno6573 and Blade1984 +by eliminator1403, lucaslmgv, AndrewBento, AcidReach, bodvenomz, nuno6573, Blade1984 +and zackcage6 Financial support by Akilluminati47 diff --git a/Makefile b/Makefile index 7ef23a691d..735cc82552 100644 --- a/Makefile +++ b/Makefile @@ -39,12 +39,12 @@ PADEMU ?= 1 #Enables/disables PS5 DualSense (USB) support in the pad emulator. HW-VALIDATED on a real DS5 #(maintainer, 2026-07-06) but kept OFF in the default build by deliberate choice -- the rolling #release ships ready-made DUALSENSE=1 builds as named RIPTOPL---ds5.ELF assets, -#one per SDK flavour (WOPLSDK / PS2MAXSDK / PS2DEVLATESTSDK). +#one per SDK flavour (PS2DEVLATESTSDK / PS2DEVPINNEDSDK). DUALSENSE ?= 0 #Enables/disables the experimental, hardware-UNVALIDATED GSM 1080p video mode (a GSM-synthetic #progressive raster; see ee_core DTV_1080P). Kept OFF in every default build; the rolling release -#ships ONE ready-made GSM1080P=1 build as a named RIPTOPL--PS2DEVLATESTSDK-1080p.ELF asset +#ships ONE ready-made GSM1080P=1 build as a named RIPTOPL-PS2DEVLATESTSDK-1080p.ELF asset #(latest-SDK flavour only), gated behind a triple-confirm in the GUI. When 0, none of the 1080p #table/GUI/engine code is compiled in. GSM1080P ?= 0 @@ -79,7 +79,7 @@ OPL_VERSION = v$(VERSION).$(SUBVERSION).$(PATCHLEVEL)$(if $(EXTRAVERSION),-$(EXT ifneq ($(GIT_TAG),) ifneq ($(GIT_TAG),latest) - # git revision is tagged. Keep the LOCALVERSION toolchain brand (-WOPLSDK/-PS2MAXSDK/-PS2DEVLATESTSDK) here too: + # git revision is tagged. Keep the LOCALVERSION toolchain brand (-PS2DEVLATESTSDK/-PS2DEVPINNEDSDK) here too: # tagged releases ship BOTH toolchains' ELFs, and without the brand their version strings # would be byte-identical -- a hardware report then can't say which binary it ran. OPL_VERSION = $(GIT_TAG)$(if $(DIRTY),$(DIRTY))$(if $(LOCALVERSION),-$(LOCALVERSION)) diff --git a/README.md b/README.md index d5020cceed..62664a1f06 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ It supports six categories of devices: 2. MMCE (Memory Card Mass Storage protocol devices); 3. MX4SIO (SD card connected to memory card port via adapter); 4. iLink (SBP2 compliant storage devices via IEEE 1394); -5. SMBv1 shares; +5. SMB shares (SMBv1 or SMB2, selectable under Device Settings); 6. ATA/IDE HDDs, including internal exFAT configurations (MBR/GPT). Plus an optional **network-block-device boot** (UDPBD / UDPFS, via Neutrino) that streams games @@ -149,10 +149,13 @@ This build layers several features on top of upstream OPL: fork's **network protocol defaults to Off** — pick UDPFS or UDPBD in Device Settings and it loads live (a restart is only needed to *switch away* from a protocol already loaded). Run it from the **[PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers)** all-in-one PC launcher. See the - network-boot section of **[docs/NEUTRINO.md](docs/NEUTRINO.md#4-network-boot--udpbd--udpfs-neutrino-only)**. + network-boot section of **[docs/NEUTRINO.md](docs/NEUTRINO.md#4-network-boot--the-network-protocol-selector)**. - **UDPFS network boot (Neutrino):** a newer network transport (Neutrino's UDPRDMA) offered - alongside UDPBD. The **Network Protocol** picker under **Device Settings** offers **Off / SMB / - UDPFS / UDPBD**; UDPFS launches via `-bsd=udpfsbd` with a bundled `bsd-udpfsbd.toml`. Use the + alongside UDPBD. Under **Device Settings** the network controls are four rows: **Network + Protocol** (Off / Manual / Auto), **Protocol** (**SMB / UDPFS / UDPBD**), **SMB Version** + (SMBv1 / SMB2, live only while Protocol is SMB), and **Access** (Files / IMG — locked to Files + for SMB and to IMG for UDPBD, free only for UDPFS). UDPFS launches via `-bsd=udpfsbd` with a + bundled `bsd-udpfsbd.toml`. Use the **[PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers)** all-in-one PC launcher for UDPFS, SMB and UDPBD; advanced users can run **[pcm720/udpfsd](https://github.com/pcm720/udpfsd)** directly. Same static-IP and SMB-exclusivity rules as UDPBD. @@ -171,21 +174,23 @@ This build layers several features on top of upstream OPL: 1080i) plus a Neutrino-only **Mode 7** (`-gc=7`). See **[docs/NEUTRINO.md](docs/NEUTRINO.md)**. - **Device Settings hub:** the old "Settings" page is now **General Settings**, and a new **Device Settings** page consolidates the per-device options, cache sizes, Block-Devices - (BDM) settings, all MMCE settings, the network-boot controls (the UDPBD/UDPFS toggle + the - **Net Boot Protocol** picker, interlocked with SMB), and the Favourites tab toggle in one place. + (BDM) settings, all MMCE settings, the network-boot controls (the **Network Protocol** start + row plus the **Protocol**, **SMB Version** and **Access** pickers), and the Favourites tab + toggle in one place. - **DualSense / DualShock 5 (USB):** optional controller support — grab a ready-made `RIPTOPL---ds5.ELF` (one per SDK flavour) from the rolling release, or build with `make DUALSENSE=1`. - **Experimental 1080p GSM mode:** a re-added forced-1080p video mode (progressive - 1920×1080) lives **only** in a dedicated `RIPTOPL--PS2DEVLATESTSDK-1080p.ELF` asset + 1920×1080) lives **only** in a dedicated `RIPTOPL-PS2DEVLATESTSDK-1080p.ELF` asset (latest-SDK flavour only) so the hardware-unvalidated raster code never touches a mainline build. Selecting it in the per-game GSM picker requires clearing a **three-step confirmation**; if your display can't sync it, the **Triangle + Cross** boot combo forces safe 480p. Build your own with `make GSM1080P=1`. - **Ready-to-use defaults:** a fresh install boots with sensible options already enabled — - widescreen, cover art, notifications, sound effects + boot sound, USB, delete/rename, and - the PS2 logo, with the device tabs in **Manual** mode. Video mode stays **Auto**. Change - any of it under Settings. + widescreen, cover art, notifications, sound effects + boot sound, delete/rename, and + the PS2 logo. Video mode stays **Auto**. Every storage device ships **off**, so the first boot + lands on the start menu with no tabs — enable exactly the devices your console has under + **Device Settings**. Change any of it under Settings. - **Private settings, shared data:** RiptOPL saves its master config as **`settings_riptopl.cfg`** (auto-migrated from the older `conf_riptopl.cfg`; not `conf_opl.cfg`), so it can sit on the same memory card as official OPL or wOPL without either build clobbering the other's settings. Everything else under the `OPL/` folder — @@ -255,7 +260,7 @@ work it is built on: Enormous thanks to the testers who run every rolling build on real consoles and file the reports that shape the fixes — **eliminator1403, lucaslmgv, AndrewBento, AcidReach, bodvenomz, -nuno6573 and Blade1984**. +nuno6573, zackcage6 and Blade1984**. ### Financial support (this fork) @@ -269,13 +274,16 @@ because that upstream work is open for everyone to learn from. ## Releases -RiptOPL ships **one full-feature build** — GSM video-mode handling, in-game -screenshots (IGS), DS3/DS4 pad emulation (PADEMU), VMC, PS2RD cheats and parental -controls are all included in the standard ELF (no upstream-style per-feature variants). +RiptOPL ships **one full-feature build** — GSM video-mode handling, DS3/DS4 pad +emulation (PADEMU), VMC, PS2RD cheats and parental controls are all included in the +standard ELF (no upstream-style per-feature variants). The two upstream `EXTRA_FEATURES` +extras — in-game screenshots (IGS) and right-to-left (RTL) language support — are **not** +compiled into any published main ELF (`EXTRA_FEATURES ?= 0`); they ship only in the +`EXTRA_FEATURES=1` builds inside the VARIANTS zip. DualSense / DualShock 5 (USB) support is the one optional extra: the rolling release ships it prebuilt as named `RIPTOPL---ds5.ELF` assets (one per SDK flavour), or build your own with `make DUALSENSE=1`. One further **experimental** variant — a forced-1080p GSM mode -(hardware-unvalidated) — ships **only** as `RIPTOPL--PS2DEVLATESTSDK-1080p.ELF` +(hardware-unvalidated) — ships **only** as `RIPTOPL-PS2DEVLATESTSDK-1080p.ELF` (latest-SDK flavour only, gated behind a three-step in-GUI confirmation), or `make GSM1080P=1`. Every other asset, including the `-ds5` loaders and the VARIANTS zip, is 1080p-free. @@ -292,8 +300,9 @@ contains and how to pull it. > **Which rolling build?** The rolling zip ships two loader ELFs that differ only by build > toolchain — the RiptOPL code in each is identical. Recommended in order of reliability: > **`APP_RIPTOPL-PS2DEVLATESTSDK/`** (#1) — the current SDK with stock drivers, which is what -> RiptOPL is developed and tested against. **`APP_RIPTOPL-PS2MAXSDK/`** (#2) is the safe fallback: -> a pinned 2025 SDK, for when the moving `ps2dev:latest` tag regresses on a given console. +> RiptOPL is developed and tested against. **`APP_RIPTOPL-PS2DEVPINNEDSDK/`** (#2) is the safe +> fallback: the same ps2dev SDK pinned by image digest to a day it was known good, for when the +> moving `ps2dev:latest` tag regresses on a given console. > (A third `WOPLSDK` flavour was dropped in 2026-07 — it crashed at the setup menu, issue #270.) See > [Which build should I use?](ROLLING_RELEASE.md#which-build-should-i-use). @@ -356,14 +365,22 @@ on the host machine or NAS device and make sure that it has full read and write permissions. USB Advance/Extreme format is optional - \*.ISO images are supported using the folder structure above. -> **RiptOPL network defaults:** the network protocol selector defaults to **UDPFS** — switch -> it to **SMB** under **Device Settings** before the **NET Games** tab appears. Network Config +> **SMB version:** **Device Settings** has an **SMB Version** row (SMBv1 / SMB2) directly under +> **Protocol**, live only while **Protocol** is **SMB** (greyed out otherwise). It defaults to +> **SMBv1**; setting it to **SMB2** switches *both* sides — browsing loads the SMB2 driver instead +> of the SMBv1 one, and so does the in-game reader — so the server must speak SMB2 for the whole +> session. + +> **RiptOPL network defaults:** the network protocol selector defaults to **Off** — under +> **Device Settings** set **Network Protocol** to **Manual** or **Auto**, then set **Protocol** +> to **SMB**, before the **NET Games** tab appears. Network Config > ships static defaults (PS2 `192.168.1.10`, PC `192.168.1.100`, share `games`, user `guest`); > adjust them to your LAN. The default **SMB Port is `1111`** — a non-privileged port (>1024), so a server > binds it without admin/root. **Network Config** now opens with **advanced options on**, so > the **Port** field (and ETH link mode) are editable immediately. If Windows 10/11 has -> disabled SMB1/NTLMv1, use the **[PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers)** -> all-in-one launcher instead of Windows' SMB service. Choose its SMBv1 server, then set RiptOPL's +> disabled SMB1/NTLMv1, set **SMB Version** to **SMB2**; the +> **[PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers)** all-in-one launcher remains the +> fallback for SMBv1-only setups. Choose its SMBv1 server, then set RiptOPL's > IP, port, share and credentials to the values the launcher displays (PS2 Servers currently uses > port **1445** by default, so change RiptOPL's saved **1111** when prompted). Release packages > include **`PS2-Servers.url`** as a direct shortcut to the repository. @@ -374,12 +391,12 @@ Both PS2 HDD types are **off by default** in RiptOPL — enable the one you use Settings**. For PS2, 48-bit LBA internal HDDs are supported. The HDD can be formatted as: - APA partitioning with PFS filesystem (up to 2TB) - - OPL will create the `+OPL` partition on the HDD. To avoid this, you can create a text file at the location `hdd0:__common:pfs:OPL/conf_hdd.txt` that contains the preferred partition name (for example `__common`). + - OPL will create the `+OPL` partition on the HDD. To avoid this, create `hdd0:__common/OPL/conf_hdd.cfg` containing the entry `hdd_partition=__common` (or whichever partition you prefer) — the same file and key described above. - MBR partitioning (up to 2TB) or GPT partitioning (unlimited) with the exFAT filesystem - Enable **BDM HDD** in **Device Settings**. The exFAT HDD then mounts through the Block Device Manager (BDMAssault / "BDMA") into the shared `massN:` namespace — the same path as USB/MX4SIO — and appears as an **HDD (exFAT)** games list with the HDD icon. - Files should be added contiguously or synchronously to avoid fragmentation. For example, drag and drop files one at a time, or ensure that files are added sequentially. - When formatting drives for the exFAT filesystem, please make sure the `Allocation unit size` is set to `Default`. - - **PS1 games:** PS1 `*.VCD` titles in the HDD's `POPS/` folder list under the **L3** VCD view like any other device. To boot them, equip **BDMA Mode → HDD (exFAT)** in **General Settings** so POPSTARTER can read the exFAT volume. See **[docs/VCD.md](docs/VCD.md)**. + - **PS1 games:** PS1 `*.VCD` titles in the HDD's `POPS/` folder list under the **L3** VCD view like any other device. To boot them, open **VCD Settings** from the main menu. **VCD BDMA Apply on Launch** is on by default and equips the matching exFAT driver automatically; turn it off to reveal the manual **BDMA Source** / **BDMA Mode** pickers and set **BDMA Mode → HDD (exFAT)** by hand so POPSTARTER can read the exFAT volume. See **[docs/VCD.md](docs/VCD.md)**. ## APPS diff --git a/ROLLING_RELEASE.md b/ROLLING_RELEASE.md index 110e593dd9..9dc6078d8f 100644 --- a/ROLLING_RELEASE.md +++ b/ROLLING_RELEASE.md @@ -13,11 +13,11 @@ ELFs and supporting files are published alongside it: | Asset | What it is | |---|---| -| `RIPTOPL--.zip` | **The installable package.** Contains two loader folders that differ ONLY by the SDK toolchain they were built with (the RiptOPL code in each is identical), each explicitly labeled and recommended in this order: `APP_RIPTOPL-PS2DEVLATESTSDK/RIPTOPL.ELF` (#1), built on the current `ps2dev:latest` SDK with stock drivers, then `APP_RIPTOPL-PS2MAXSDK/RIPTOPL.ELF` (#2), a **pinned** 2025 SDK kept as the safe fallback. There is no unlabeled default folder. Also includes the `POPSTARTER/` + `POPS/` folders for PS1 support, the bundled Neutrino core as a ready-to-use `neutrino/` folder (drag-and-drop to `mc?:/`), and `PS2-Servers.url`, a shortcut to the maintained UDPFS / SMBv1 / UDPBD all-in-one PC launcher. The old `PC-SMB-Server/` folder is no longer embedded. Extract it, pick a folder and copy its `RIPTOPL.ELF` — see [Which build should I use?](#which-build-should-i-use) below. | -| `RIPTOPL--PS2MAXSDK.ELF` | Bare loader, `ps2max/dev` (pinned) toolchain (**safe fallback**; in-app version ends `-PS2MAXSDK`). | +| `RIPTOPL--.zip` | **The installable package.** Contains two loader folders that differ ONLY by the SDK toolchain they were built with (the RiptOPL code in each is identical), each explicitly labeled and recommended in this order: `APP_RIPTOPL-PS2DEVLATESTSDK/RIPTOPL.ELF` (#1), built on the current `ps2dev:latest` SDK with stock drivers, then `APP_RIPTOPL-PS2DEVPINNEDSDK/RIPTOPL.ELF` (#2), the same ps2dev SDK **pinned by image digest** to a day it was known good, kept as the safe fallback. There is no unlabeled default folder. Also includes the `POPSTARTER/` + `POPS/` folders for PS1 support, the bundled Neutrino core as a ready-to-use `neutrino/` folder (drag-and-drop to `mc?:/`), and `PS2-Servers.url`, a shortcut to the maintained UDPFS / SMBv1 / UDPBD all-in-one PC launcher. The old `PC-SMB-Server/` folder is no longer embedded. Extract it, pick a folder and copy its `RIPTOPL.ELF` — see [Which build should I use?](#which-build-should-i-use) below. | +| `RIPTOPL--PS2DEVPINNEDSDK.ELF` | Bare loader, digest-pinned `ps2dev/ps2dev` toolchain (**safe fallback**; in-app version ends `-PS2DEVPINNEDSDK`). | | `RIPTOPL--PS2DEVLATESTSDK.ELF` | Bare loader, `ps2dev/ps2dev:latest` toolchain (**recommended**; in-app version ends `-PS2DEVLATESTSDK`). | -| `RIPTOPL---ds5.ELF` | Same as the bare loader for each SDK flavour, **with DualSense (DS5 USB) pad support** compiled in (`DUALSENSE=1`). One per flavour (`-PS2MAXSDK-ds5` / `-PS2DEVLATESTSDK-ds5`); same reliability order applies. The default builds keep DualSense OFF. Best-effort — a flavour's DS5 build may be absent if it failed that run. | -| `RIPTOPL--PS2DEVLATESTSDK-1080p.ELF` | **Experimental** loader with the re-added forced-**1080p** GSM video mode compiled in (`GSM1080P=1`). **Latest-SDK flavour only** — the raster is hardware-unvalidated, so it is kept out of every other asset. Selecting 1080p in the per-game GSM picker requires clearing a **three-step confirmation**; the Triangle + Cross boot combo forces safe 480p if a display can't sync it. Best-effort. | +| `RIPTOPL---ds5.ELF` | Same as the bare loader for each SDK flavour, **with DualSense (DS5 USB) pad support** compiled in (`DUALSENSE=1`). One per flavour (`-PS2DEVLATESTSDK-ds5` / `-PS2DEVPINNEDSDK-ds5`); same reliability order applies. The default builds keep DualSense OFF. Best-effort — a flavour's DS5 build may be absent if it failed that run. | +| `RIPTOPL-PS2DEVLATESTSDK-1080p.ELF` | **Experimental** loader with the re-added forced-**1080p** GSM video mode compiled in (`GSM1080P=1`). **Latest-SDK flavour only** — the raster is hardware-unvalidated, so it is kept out of every other asset. Selecting 1080p in the per-game GSM picker requires clearing a **three-step confirmation**; the Triangle + Cross boot combo forces safe 480p if a display can't sync it. Best-effort. | | `RIPTOPL--src.zip` | Source snapshot to rebuild this exact commit. | | `SHA256SUMS.txt` | SHA256 of every published binary + the source snapshot. | | `IRX-MANIFEST*.txt` | SHA256 of every SDK-prebuilt IOP module each toolchain consumed (provenance for silent SDK-side driver swaps). | @@ -25,7 +25,7 @@ ELFs and supporting files are published alongside it: | `RIPTOPL-VARIANTS-*.zip` / `RIPTOPL-DEBUG-*.zip` | Alternate build configs and debug builds, both toolchains — for testing/diagnostics. | `` is the `ps2dev:latest` build's `git describe` (e.g. `v1.2.0-Beta-2559-bb25a00`); each -flavour carries the same version with a `-PS2MAXSDK` / `-PS2DEVLATESTSDK` suffix. +flavour carries the same version with a `-PS2DEVLATESTSDK` / `-PS2DEVPINNEDSDK` suffix. ## Which build should I use? @@ -34,18 +34,18 @@ Recommended in this order, by reliability: 1. **`APP_RIPTOPL-PS2DEVLATESTSDK/` (`-PS2DEVLATESTSDK`) — the recommended download.** Built on the current `ps2dev:latest` SDK with its stock drivers, which is what RiptOPL is developed and tested - against. -2. **`APP_RIPTOPL-PS2MAXSDK/` (`-PS2MAXSDK`) is the safe fallback.** A pinned 2025 `ps2max/dev` SDK. - Use it when the recommended build misbehaves on your console. It is built against the - `ps2dev:latest` Docker tag, which **moves constantly** (often several times a day). That makes it the - best early-warning signal for upstream SDK regressions, but it also means it can *intermittently fail - to boot* on some consoles when the SDK underneath it changes — that is expected volatility of a moving + against. That Docker tag **moves constantly** (often several times a day), which makes this flavour the + best early-warning signal for upstream SDK regressions — but it also means it can *intermittently fail + to boot* on some consoles when the SDK underneath it changes. That is expected volatility of a moving tag, **not** a RiptOPL bug (see issue [#102](https://github.com/NathanNeurotic/Open-PS2-Loader/issues/102)). - If the recommended build black-screens at startup or the cursor does not respond, use this one +2. **`APP_RIPTOPL-PS2DEVPINNEDSDK/` (`-PS2DEVPINNEDSDK`) is the safe fallback.** The same ps2dev SDK, + pinned by image digest to a day it was known good, so it does not move underneath you. + Use it when the recommended build misbehaves on your console — + if the recommended build black-screens at startup or the cursor does not respond, use this one and please say which you ran in the report. When something misbehaves on hardware, please say **which flavour you ran** — the in-app version string's -`-PS2MAXSDK` / `-PS2DEVLATESTSDK` suffix tells you. A PS2DEVLATESTSDK-only failure points at an +`-PS2DEVLATESTSDK` / `-PS2DEVPINNEDSDK` suffix tells you. A PS2DEVLATESTSDK-only failure points at an SDK regression; a both-flavour failure points at RiptOPL code. Those bits triple the value of a report. ## Pull the latest build @@ -76,14 +76,13 @@ whether the bleeding-edge build succeeded. - Triggers on every push to `master` (updates `rolling`), on every `v*` **tag** push (cuts a curated per-version release with identical packaging), and on manual **Run workflow** (workflow_dispatch). -- Builds with three toolchains — `ps2dev/ps2dev:latest` (the moving target/canary), wOPL's - digest-pinned `ghcr.io/ps2homebrew` container, and the pinned `ps2max/dev` (2025) — the same - images as the main CI build. +- Builds with two toolchains — `ps2dev/ps2dev:latest` (the moving target/canary) and a + digest pin of that same `ps2dev/ps2dev` image — the same images as the main CI build. - The `ps2dev/ps2dev:latest` build is **required to compile**: if it fails to build, the publish fails loudly. Note this guards against *build* breakage only — because `ps2dev:latest` tracks a moving SDK tag, a green build can still produce a binary that does not boot on hardware (see [Which build should I use?](#which-build-should-i-use)), which is why the pinned - `-PS2MAXSDK` flavour is kept as the safe fallback. The pinned build is best-effort + `-PS2DEVPINNEDSDK` flavour is kept as the safe fallback. The pinned build is best-effort (`continue-on-error`); when one fails, the package ships without that folder and the notes say so. - Publishes/updates the single `rolling` pre-release from the host runner. - `concurrency` cancels superseded in-flight runs, so the release reflects the newest push. diff --git a/docs/LANGUAGES.md b/docs/LANGUAGES.md index 039f97b48c..ce7e8957b8 100644 --- a/docs/LANGUAGES.md +++ b/docs/LANGUAGES.md @@ -41,11 +41,14 @@ translations: ## How to ADD a new string -1. Add it to `lng_tmpl/_base.yml`: +1. Add it to the **END** of `lng_tmpl/_base.yml`, below the APPEND-ONLY banner (~line 923): ```yaml - label: MY_NEW_SETTING string: My New Setting ``` + External `lang_*.lng` files are consumed by **line position** (`lang.c`), so inserting a + label mid-list shifts every later string ID and makes stale user language packs show the + **wrong text** — never an English fallback. 2. Use `_STR_MY_NEW_SETTING` in code (the enum id is auto-generated). 3. That's enough to ship — it shows English everywhere until translated. diff --git a/docs/NEUTRINO.md b/docs/NEUTRINO.md index 3fbe66c917..1a2d4d8caa 100644 --- a/docs/NEUTRINO.md +++ b/docs/NEUTRINO.md @@ -8,22 +8,38 @@ boot better under Neutrino, or for users who prefer Neutrino's loader and its la ## 1. Install Neutrino -Neutrino is **not bundled** with OPL — you supply it. Place the ELF on a memory card at one -of these paths (OPL checks them in order): +Neutrino is **not bundled** with OPL — you supply it. Copy Neutrino's whole `neutrino/` folder, +not just the ELF: OPL only accepts an install when `config/system.toml` (or a flat `system.toml`, +the SAS layout) sits beside `neutrino.elf`. An ELF-only folder is **skipped** and probing +continues, so you get the `` fallback even though the file exists. -| Priority | Path | +A memory card is the zero-config default — `mc0:NEUTRINO/neutrino.elf`, then +`mc1:NEUTRINO/neutrino.elf` — but it is the **last** place OPL looks, not the first. The full +order is: + +| Priority | Where OPL looks | |---|---| -| 1 | `mc0:NEUTRINO/neutrino.elf` | -| 2 | `mc1:NEUTRINO/neutrino.elf` | +| 1 | The device chosen in **Settings → General Settings → Neutrino Device** (see below) | +| 2 | The custom **Neutrino ELF Path** (`neutrino_path`) | +| 3 | The active game's own device — `/neutrino/`, then `/neutrino/` | +| 4 | `mc0:` / `mc1:` — `NEUTRINO/neutrino.elf` and its lowercase / `NEUTRINO.ELF` variants | + +If no complete install is found when you launch a game set to the Neutrino core, OPL shows a +warning and falls back to the `` core for that launch. -If neither exists when you launch a game set to the Neutrino core, OPL shows a warning and -falls back to the `` core for that launch. +**Settings → General Settings → Neutrino Device** picks the device *type* holding +`:/neutrino/neutrino.elf` — **Auto** / Memory Card / USB / MX4SIO / MMCE / HDD (exFAT) / +HDD (APA) / **Game's Device**. A miss on the device you picked is not a dead end: OPL falls +through to the AUTO tiers above. The exception is **Game's Device**, which only ever looks on +the game's own device and reports "not found" instead of falling back. You can also point OPL at a **custom location** via **Settings → General Settings → Neutrino -ELF Path**. When that field is set and the file exists it takes **priority** over the table -above; leave it blank to use the auto-detection (which also checks a few lowercase / -`NEUTRINO.ELF` spelling variants on `mc0:`/`mc1:`). For a path longer than the on-screen -31-character editor, set `neutrino_path` in `settings_riptopl.cfg` directly. +ELF Path**. When that field is set and the file exists it takes **priority** over the +auto-detected tiers above (the game's own device and `mc0:`/`mc1:`) — only the **Neutrino +Device** picker outranks it; leave it blank to use the auto-detection. The custom path is +honoured only when its install passes the same `config/system.toml` completeness check (a path +with no directory component is taken as-is). For a path longer than the on-screen 31-character +editor, set `neutrino_path` in `settings_riptopl.cfg` directly. > **Network boot is the exception:** the UDPFS feature (§4) ships its **own bundled > Neutrino** (a ready-to-use `neutrino/` folder inside the release's installable package, pre-populated with the @@ -63,14 +79,14 @@ settings: | Auto argument | When | |---|---| -| `-bsd=` | always (the storage backend) | +| `-bsd=` | always (the storage backend). APA HDD maps to `ata` (+ `-bsdfs=hdl`), so no separate `apa` token is ever emitted | | `-bsdfs=hdl` | internal HDD (APA) only | | `-bsdfs=` | only if the per-game **Neutrino Filesystem** picker (Compatibility screen) is set off Auto; block-backed devices only (never mmce/udpfs — no filesystem layer there). `hdl`/`bd` also reshape `-dvd` to `hdl:`/`bdfs:`; a hand-typed `-bsdfs=`/`-dvd=` in the args always wins | | `-dvd=` / `-dvd=hdl:` | always (the game image/partition) | | `-gc=` | only if the game has OPL compatibility modes set | | `-dbc` | only if **Debug Colors** is enabled | | `-logo` | only if **PS2 Logo** is enabled | -| `-gsm=` | only if a **Neutrino Video** mode resolves for the game (per-game picker, or the global **Settings → Neutrino Video** default when the per-game picker is "Default") | +| `-gsm=[:]` | only if a **Neutrino Video** mode resolves for the game (per-game picker, or the global **Settings → Neutrino Video** default when the per-game picker is "Default"). The `:` half is appended only when a **Neutrino GSM Compatibility** type is set — it is never emitted on its own | On top of those, you can pass **extra Neutrino flags** (e.g. media-type or video tweaks) in two places. Both are **appended after** the auto-built arguments; **global first, then @@ -86,16 +102,23 @@ per-game**, so a game can extend the global set. **Game Settings → Compatibility Settings → Neutrino Launch Args** (config key `$NeutrinoArgs` in the game's `.cfg`). -Arguments are space-separated, e.g.: +Both rows are **buttons** that open the same structured sub-screen rather than one raw text +field: **Quick Boot** (`-qb`), **Debug Colors** (`-dbc`), **PS2 Logo** (`-logo`), **Working Dir** +(`-cwd`), **Config** (`-cfg`), **Boot ELF** (`-elf`), `-ata0`, `-ata0id`, `-ata1`, plus a +free-text **Extra** field for everything else. OPL reassembles the fields in the order Neutrino +accepts, with the Extra / `--b` tail last. + +The stored format is unchanged — a space-separated string, e.g.: ``` -mt=dvd -gsm=1 ``` -> **Editor length:** OPL's in-app text fields hold up to 31 characters (the same limit as -> Alt-Startup / Game-ID). If you need a longer argument string, edit the value directly in -> the config file — OPL reads and forwards the full string at launch even though the on-screen -> editor caps the visible length. +> **Editor length:** each on-screen field still edits at most 31 characters (the same limit as +> Alt-Startup / Game-ID), but fields you don't touch keep their full stored value, so editing one +> field no longer truncates the others. Edit `neutrino_args` / `$NeutrinoArgs` directly in the +> config file only when a single field needs more than 31 characters — OPL reads and forwards the +> full string at launch. ### Experimental: automatic `-elf=` (config key only) @@ -116,16 +139,23 @@ Protocol** selector with four choices — **Off / SMB / UDPFS / UDPBD**. **UDPFS network-boot protocol (Rick Gaiser's **UDPRDMA** transport); **UDPBD** is the older SUDPBDv2 protocol, kept for users still running the `udpbd-server`. Both appear in OPL as their own games list — with covers and per-game settings — and boot via the external Neutrino core. **SMB** is the exception: it's -a mounted SMBv1 file share served by OPL's **own** core (no Neutrino), and it keeps its own address / -port / share / credentials fields. +a mounted SMB file share served by OPL's **own** core (no Neutrino), and it keeps its own address / +port / share / credentials fields plus an **SMB Version** row (**SMBv1** default, or **SMB2**). +Changing the version only takes effect on the next boot — OPL shows the usual restart notice when a +network stack is already up — and it warns first that SMB2 changes **both** browsing and in-game +reading, so an SMBv1-only server (including the bundled PS2-Servers tool) will list no games. | Choice | Wire protocol | On the PS2 | Core | PC server | |---|---|---|---|---| | **Off** | — | no network device (default) | — | — | -| **SMB** | SMBv1 | a mounted file share | OPL's *own* core (not Neutrino) | [PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers) (recommended) / Samba | +| **SMB** | SMBv1 (default) or SMB2 — Device Settings → **SMB Version** | a mounted file share | OPL's *own* core (not Neutrino) | [PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers) (recommended) / Samba | | **UDPFS** | UDPRDMA | a games source served over UDP (see **UDPFS Access** below) | Neutrino only | [PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers) (recommended) / [`udpfsd`](https://github.com/pcm720/udpfsd) | | **UDPBD** | SUDPBDv2 | a served disk image mounted as `massN:` | Neutrino only | [PS2 Servers](https://github.com/NathanNeurotic/PS2-Servers) (recommended) / [`udpbd-server`](https://github.com/israpps/udpbd-server) | +> **SMB3 is reserved, not offered.** The dialect enum has a slot for it, but packet signing isn't +> implemented, so the picker deliberately stops at SMB2. The bundled PS2-Servers SMB server speaks +> SMBv1 — leave the picker on **SMBv1** unless your server does SMB2. + Because the PS2 has a **single** network adapter, only ONE of these is active per session — the selector is exclusive *by construction* (the old separate ETH start-mode + "Network Boot" toggle + "Net Boot Protocol" picker, and their live interlock, are all gone). Local devices (USB / internal @@ -140,10 +170,10 @@ HDD / MMCE) are independent and browse alongside whichever network protocol you ### UDPFS Access — Files vs Image When **UDPFS** is selected, a second sub-setting **"UDPFS Access"** appears with two values — **Files** -(default) and **Image**. They are the **same UDPFS protocol** in two shapes: Files is the `udpfs_ioman` +(default) and **IMG** (image mode). They are the **same UDPFS protocol** in two shapes: Files is the `udpfs_ioman` FILESYSTEM (`udpfs:`), Image is the `udpfs_bd` BLOCK device (`massN:`). -| | **Files** (default) | **Image** | +| | **Files** (default) | **IMG** | |---|---|---| | IOP driver | `udpfs_ioman.irx` → `udpfs:` (filesystem) | `udpfs_bd.irx` → `massN:` (block device) | | PC serves | a folder containing **`CD/` and `DVD/` subfolders** of ISOs (the standard OPL layout — OPL lists from `/CD` + `/DVD`, NOT from the folder root) | a **FAT/exFAT disk image** | @@ -225,6 +255,11 @@ When a game's core is **Neutrino**: OPL-bitmask data that doesn't map to `-gc`). Modes 1/2/3/5 *do* map to `-gc`, and a Neutrino-only **mode 7** (greyed under the OPL core — the inverse of 4/6) maps to `-gc=7` (fix games that overrun an IOP buffer). +- **Neutrino GSM Compatibility** (Compatibility screen, beside Neutrino Video) — **Off / Type 1 + (GSM/OPL) / Type 2 / Type 3 / Default** — supplies the `:` half of `-gsm=:`, + a field-flipping fix for shake/tear. The comp half is **never** emitted without a video mode (a + bare `:` aborts Neutrino's boot), so the row greys out while the effective video mode is + Off; **Default** follows the global **Settings** value. - **GSM, Cheats, PADEMU, OSD Language** panels are OPL-core-only; opening one shows *"not used with the Neutrino core"* instead of editing dead options (use the Neutrino Video picker above for video forcing). @@ -248,8 +283,16 @@ Args field and Neutrino Video picker are greyed (never read on the OPL path). OPL turns the per-game **VMC** settings (`$VMC_0`/`$VMC_1`) into discrete `-mcN=:…VMC/.bin` arguments — the same `.bin`, in the same `VMC/` folder, that the -OPL core's mcemu uses, so one card serves both cores. Rules that follow from Neutrino's design -(verified against `rickgaiser/neutrino` source): +OPL core's mcemu uses, so one card serves both cores. + +Each slot also has a **Disable VMC N (keep card)** toggle on the Compatibility screen (stored as +`$VMCDisable_0` / `$VMCDisable_1`). It suppresses that slot's `-mc` argument for **Neutrino +launches only** — the card name stays configured and the game sees the real physical card; OPL's +own mcemu ignores the toggle entirely. Dropping the argument also clears that slot from the VMC +slot mask, so the MMCE GameID card-switch re-arms for it, and on APA HDD it silences the +"VMC unsupported under Neutrino" warning. + +Rules that follow from Neutrino's design (verified against `rickgaiser/neutrino` source): - **The `.bin` must already exist.** Neutrino opens it `O_RDWR` with no create, and **aborts the whole boot** (black screen) if it can't. OPL therefore creates/format cards at *config* time diff --git a/docs/THEME_ENGINE.md b/docs/THEME_ENGINE.md index 1ecdcf1b89..8585042d06 100644 --- a/docs/THEME_ENGINE.md +++ b/docs/THEME_ENGINE.md @@ -120,7 +120,7 @@ Every element block starts with `type=` (see §5). Most also accept | `y` | int or `POS_MID` | element-specific | Negative = measured from the **bottom** edge. `POS_MID` = vertical center. | | `width` | int or `DIM_INF` | element-specific | `DIM_INF` = full screen width. | | `height` | int or `DIM_INF` | element-specific | `DIM_INF` = full screen height. | -| `aligned` | `0` / `1` | element-specific | `0` = anchor top-left, `1` = center on (x, y). | +| `aligned` | `0` / `1` / `2` | element-specific | `0` = anchor top-left, `1` = center on (x, y), `2` = right-justified + vertically centered (wOPL/uOPL key; regular OPL renders it centered). | | `scaled` | `0` / `1` | element-specific | `0` = raw pixels, `1` = ratio-correct (handles widescreen + pixel-aspect). Use `1` for images you want undistorted. | | `color` | `#RRGGBB` | `text_color` | Text/tint color. | | `font` | `0`…`15` | `0` | Font index (see §2). | @@ -358,9 +358,9 @@ You can point `default=`/`overlay=` at any of OPL's embedded textures (no file n - **Covers / art:** `cover`, `coverapp`, `disc`, `screen`, `screens` (overlay), `missing` - **Case overlays:** `case` (the shared frame, layer 1), `case_overlay` (layer 2, drawn over `case`), `apps_case` (legacy apps-only frame) -- **Device icons:** `usb`, `mmce`, `hdd`, `eth`, `app`, `usb_bd`, `ilk_bd`, `m4s_bd`, `hdd_bd` +- **Device icons:** `usb`, `mmce`, `hdd`, `eth`, `app`, `fav`, `usb_bd`, `ilk_bd`, `m4s_bd`, `hdd_bd`, `udp_bd` (UDPBD), `udp_fs` (UDPFS) - **BDM indicators:** `Index_0` … `Index_4` -- **Buttons:** `cross`, `circle`, `triangle`, `square`, `left`, `right`, `select`, `start` +- **Buttons:** `cross`, `circle`, `triangle`, `square`, `left`, `right`, `select`, `start`, `L3`, `R3`, `fav_mark` - **Loading frames:** `load0` … `load7` - **Boot logo:** `logo`, `logo0` … `logo6` - **Backgrounds:** `incebtion` (default theme bg), `ip` diff --git a/docs/VCD.md b/docs/VCD.md index 02f8bc7259..863311fa66 100644 --- a/docs/VCD.md +++ b/docs/VCD.md @@ -60,7 +60,7 @@ title and POPSTARTER finds the matching `*.VCD`. An APA one-game install instead with its literal, case-sensitive `PP.` / `__.` partition label so POPSTARTER can mount that partition and boot its fixed `IMAGE0.VCD`. -Where `POPSTARTER.ELF` is loaded from is set by **Settings → General Settings → +Where `POPSTARTER.ELF` is loaded from is set by **Settings → VCD Settings → POPSTARTER.ELF Device** — a driver-accurate picker (matching the Neutrino Device picker): | Choice | Loads `POPS/POPSTARTER.ELF` from | @@ -73,6 +73,7 @@ POPSTARTER.ELF Device** — a driver-accurate picker (matching the Neutrino Devi | HDD (exFAT) | the mounted exFAT internal HDD | | HDD (APA) | see the note below — APA POPSTARTER only applies to HDD-page launches | | **Custom** | reveals a free-text path field — your own absolute `POPSTARTER.ELF` path | +| **Game's Device** | the VCD's own device only (`:/POPS/POPSTARTER.ELF`) — no boot/cwd fallback and no Default fallthrough; a miss aborts with the usual *Missing POPSTARTER.ELF* warning | The picker covers USB / MMCE / MX4SIO / iLink / SMB VCD launches. PS1 VCDs **on the internal APA HDD** always load `POPSTARTER.ELF` from the HDD (the `__common` then `+OPL` `POPS` folder, as @@ -117,8 +118,9 @@ the same physical `IMAGE0.VCD` filename, so config and art use the displayed ` **Module file names matter.** The two driver files in that `POPS/` folder must be named for the > BDMA **MODE** you pick: **`usbd.irx.`** and **`usbhdfsd.irx.`**. For `HDD (exFAT)` that > is **`usbd.irx.ata`** + **`usbhdfsd.irx.ata`** (other modes use `.usbexfat`, `.mx4sio`, `.mmce`). -> Plain `usbd.irx` / `usbhdfsd.irx` with **no suffix** are ignored — that is what triggers the -> *"BDMA module files not found"* message. +> Plain `usbd.irx` / `usbhdfsd.irx` with **no suffix** are ignored — OPL then falls back to its +> built-in embedded pair. The *"BDMA module files not found"* message now appears only when that +> embedded fallback also fails to install. When you change either setting, RiptOPL copies the chosen variant's modules from the SOURCE device's `POPS` folder onto `mc?:/POPSTARTER/` and records the equipped state in a -marker file there (compatible with POPSLoader). Nothing is embedded in the loader — you -provide the module files, so there is no ELF bloat. SMB is network-only, so the BDMA -equip does not apply to it. +marker file there (compatible with POPSLoader). RiptOPL also ships a gzipped copy of each +BDMAssault variant pair inside the ELF as a final fallback, so an MC-only boot with no `POPS/` +folder anywhere still equips. Your own `usbd.irx.` / `usbhdfsd.irx.` files always win +when found — the embedded pair only fills the gap when no seek-path device carries them. SMB is +network-only, so the BDMA equip does not apply to it. The internal **exFAT HDD** (enable *BDM HDD* in Device Settings) mounts as a normal BDM block device, so its PS1 games in `massN:/POPS/` list and launch through the same VCD view @@ -165,7 +170,7 @@ so POPSTARTER itself can read them off the exFAT volume. PS1 games on an SMB share need POPSTARTER's own network config (`IPCONFIG.DAT` + `SMBCONFIG.DAT`) on the memory card, plus its SMB modules. RiptOPL can write those config files for you: enable **Settings → Network Settings → Write POPSTARTER Network Config** -(off by default). On save it mirrors the same IP / share values OPL already uses into +(**on** by default). On save it mirrors the same IP / share values OPL already uses into `mc?:/POPSTARTER/`. The SMB modules themselves ship in the release's `POPSTARTER/` folder (copy them to `mc?:/POPSTARTER/`); if they're missing, an SMB VCD launch warns rather than hanging. @@ -179,9 +184,8 @@ Work down this ladder; each step isolates a different stage (from the #154 foren the **APA HDD start mode OFF** — the two internal-HDD backends are mutually exclusive, and a hand-edited/cross-version config that enables both gets auto-reconciled at boot (you now get a toast when that happens; check Device Settings). -2. **Do PS2 ISOs list from the device?** If yes, the filesystem/mount layer is proven working — - on the WOPLSDK build the exFAT driver is *byte-identical* to wOPL's, so "works in wOPL" adds - no new information past this step. +2. **Do PS2 ISOs list from the device?** If yes, the filesystem/mount layer is proven working and + the problem is downstream of listing — skip to the VCD-specific steps below. 3. **Press L3.** The VCD view is per device and only reachable when *Default game view* is "Both" (or the page is locked to VCD). No L3 response = check that setting. 4. **VCDs are scanned from `:/POPS/*.VCD`** — the game-folder prefix @@ -199,8 +203,9 @@ Work down this ladder; each step isolates a different stage (from the #154 foren - VCD support reuses the normal device pipeline, so covers, favourites and the theme all work exactly as they do for disc games. -- POPSTARTER, the BDMA module variants, and the patch file are supplied by you (or bundled - in the release `POPS/` folder) — RiptOPL embeds none of them. +- POPSTARTER and the patch file are supplied by you (or bundled in the release `POPS/` folder) + — RiptOPL embeds neither. The BDMA module variants **are** embedded (gzipped) as a last-resort + fallback; your own copies still take priority. - The Loader Core, GSM, Cheats, PADEMU and similar per-game options do not apply to PS1 games (POPSTARTER ignores them). diff --git a/include/system.h b/include/system.h index 1ad033e236..e362783dc8 100644 --- a/include/system.h +++ b/include/system.h @@ -58,7 +58,7 @@ void sysLaunchPopstarter(const char *popstarterElf, const char *selector); // target resets the IOP itself). argv is the target's FULL argv, argv[0] INCLUDED and // caller-controlled -- unlike LoadELFFromFileWithPartition, which clobbers the target's argv[0] // with "" (that clobber is what broke POPSTARTER's XX./SB. selector). -// Container-independent: works the same on ps2dev:latest and the PS2MAXSDK pin. Returns only on +// Container-independent: works the same on ps2dev:latest and the PS2DEVPINNEDSDK pin. Returns only on // failure (bad path/ELF). Implemented in elfldr_noreset.c. int sysLoadELFKeepIOP(const char *filename, const char *partition, int argc, char *argv[]); diff --git a/src/dialogs.c b/src/dialogs.c index cdec7dea8d..fa6c14f6e2 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -1123,16 +1123,19 @@ struct UIItem diaAbout[] = { {UI_BREAK}, {UI_SPACER}, - // Blade1984 sits here rather than in a fork-testers block of his own: the About cannot scroll - // (its only navigable control is the trailing OK, and diaRenderUI pins diaScrollOffset to 0 while - // focus is on the first control), so a new heading + name row pushed the content bottom from - // 367px to 442px -- past visibleBottom (gTheme->usedHeight - 40 = 440, and only 408 on a - // 448-line theme). That would have rendered the credit, and the OK button, off-screen. + // Blade1984 and zackcage6 sit here rather than in a fork-testers block of their own: the About + // cannot scroll (its only navigable control is the trailing OK, and diaRenderUI pins + // diaScrollOffset to 0 while focus is on the first control), so a new heading + name row pushed + // the content bottom from 367px to 442px -- past visibleBottom (gTheme->usedHeight - 40 = 440, + // and only 408 on a 448-line theme). That would have rendered the credit, and the OK button, + // off-screen. APPEND fork testers to an existing row; never add a row. {UI_LABEL, 0, 1, 1, -1, 0, 15, {.label = {"algol - Berion - Blade1984 - El_Patas - EP - gledson999 - jolek - lee4", -1}}}, {UI_BREAK}, {UI_SPACER}, - {UI_LABEL, 0, 1, 1, -1, 0, 15, {.label = {"LocalH - RandQalan - ShaolinAssassin - yoshi314 - zero35", -1}}}, + // 67 chars, still shorter than the 69-char row above it, so this stays inside the width the + // block already proved safe on a 448-line theme. + {UI_LABEL, 0, 1, 1, -1, 0, 15, {.label = {"LocalH - RandQalan - ShaolinAssassin - yoshi314 - zero35 - zackcage6", -1}}}, {UI_BREAK}, {UI_BREAK}, From 9d7abb0b7bfc8bc462d4643a267a5ce7284d6a21 Mon Sep 17 00:00:00 2001 From: "NathanNeurotic (Ripto)" <109461996+NathanNeurotic@users.noreply.github.com> Date: Tue, 28 Jul 2026 12:31:37 -0700 Subject: [PATCH 2/2] docs: address CodeRabbit review on #287 Five of six accepted; the sixth declined as inverted. * ROLLING_RELEASE.md + README.md: the pinned loader folder is CONDITIONAL. The build-rolling-pinned job is continue-on-error, and packaging guards the folder with `if [ -d APP_RIPTOPL-PS2DEVPINNEDSDK ]` (rolling-release.yml:507) plus a HAS_PS2DEVPINNEDSDK gate (:538, :612). Both documents promised it unconditionally. Now both say it is best-effort and that only the latest build gates the publish. * docs/NEUTRINO.md: the -bsd table entry's "always" is correct -- sysGetNeutrinoBsdToken returns "udpfs" unconditionally (system.c:1031-1035) -- but the nightly-auto-detect note elsewhere made it read as a version split. Says so explicitly now. * docs/LANGUAGES.md (MD031) and README.md (MD028) formatting. * src/dialogs.c: the QA row comment had a wrong width. The row above is 70 chars, not the 69 I wrote (nor the 71 the review stated); ours is 68. DECLINED: reverting include/system.h to "PS2MAXSDK". That is the retired brand this PR removes -- ps2max/dev was replaced by a ps2dev digest pin in #285 and the workflow passes LOCALVERSION=PS2DEVPINNEDSDK (rolling-release.yml:125, :243), so the suggestion would reintroduce a name matching no build. Co-Authored-By: Claude Opus 5 --- README.md | 8 +++++--- ROLLING_RELEASE.md | 2 +- docs/LANGUAGES.md | 2 ++ docs/NEUTRINO.md | 2 +- src/dialogs.c | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 62664a1f06..19fadf019e 100644 --- a/README.md +++ b/README.md @@ -297,12 +297,14 @@ There are two release channels: See **[ROLLING_RELEASE.md](ROLLING_RELEASE.md)** for exactly what the rolling release contains and how to pull it. -> **Which rolling build?** The rolling zip ships two loader ELFs that differ only by build +> **Which rolling build?** The rolling zip normally ships two loader ELFs that differ only by build > toolchain — the RiptOPL code in each is identical. Recommended in order of reliability: > **`APP_RIPTOPL-PS2DEVLATESTSDK/`** (#1) — the current SDK with stock drivers, which is what > RiptOPL is developed and tested against. **`APP_RIPTOPL-PS2DEVPINNEDSDK/`** (#2) is the safe > fallback: the same ps2dev SDK pinned by image digest to a day it was known good, for when the -> moving `ps2dev:latest` tag regresses on a given console. +> moving `ps2dev:latest` tag regresses on a given console. The pinned build is best-effort, so on a +> run where it fails the zip ships the latest-SDK folder alone — only the latest build gates the +> publish. > (A third `WOPLSDK` flavour was dropped in 2026-07 — it crashed at the setup menu, issue #270.) See > [Which build should I use?](ROLLING_RELEASE.md#which-build-should-i-use). @@ -370,7 +372,7 @@ are supported using the folder structure above. > **SMBv1**; setting it to **SMB2** switches *both* sides — browsing loads the SMB2 driver instead > of the SMBv1 one, and so does the in-game reader — so the server must speak SMB2 for the whole > session. - +> > **RiptOPL network defaults:** the network protocol selector defaults to **Off** — under > **Device Settings** set **Network Protocol** to **Manual** or **Auto**, then set **Protocol** > to **SMB**, before the **NET Games** tab appears. Network Config diff --git a/ROLLING_RELEASE.md b/ROLLING_RELEASE.md index 9dc6078d8f..43ec314779 100644 --- a/ROLLING_RELEASE.md +++ b/ROLLING_RELEASE.md @@ -13,7 +13,7 @@ ELFs and supporting files are published alongside it: | Asset | What it is | |---|---| -| `RIPTOPL--.zip` | **The installable package.** Contains two loader folders that differ ONLY by the SDK toolchain they were built with (the RiptOPL code in each is identical), each explicitly labeled and recommended in this order: `APP_RIPTOPL-PS2DEVLATESTSDK/RIPTOPL.ELF` (#1), built on the current `ps2dev:latest` SDK with stock drivers, then `APP_RIPTOPL-PS2DEVPINNEDSDK/RIPTOPL.ELF` (#2), the same ps2dev SDK **pinned by image digest** to a day it was known good, kept as the safe fallback. There is no unlabeled default folder. Also includes the `POPSTARTER/` + `POPS/` folders for PS1 support, the bundled Neutrino core as a ready-to-use `neutrino/` folder (drag-and-drop to `mc?:/`), and `PS2-Servers.url`, a shortcut to the maintained UDPFS / SMBv1 / UDPBD all-in-one PC launcher. The old `PC-SMB-Server/` folder is no longer embedded. Extract it, pick a folder and copy its `RIPTOPL.ELF` — see [Which build should I use?](#which-build-should-i-use) below. | +| `RIPTOPL--.zip` | **The installable package.** Contains two loader folders that differ ONLY by the SDK toolchain they were built with (the RiptOPL code in each is identical), each explicitly labeled and recommended in this order: `APP_RIPTOPL-PS2DEVLATESTSDK/RIPTOPL.ELF` (#1), built on the current `ps2dev:latest` SDK with stock drivers, then `APP_RIPTOPL-PS2DEVPINNEDSDK/RIPTOPL.ELF` (#2), the same ps2dev SDK **pinned by image digest** to a day it was known good, kept as the safe fallback. The pinned job is best-effort (`continue-on-error`), so if it fails on a given run its folder is simply omitted and the package ships the latest-SDK folder alone — the latest build is the one that gates the publish. There is no unlabeled default folder. Also includes the `POPSTARTER/` + `POPS/` folders for PS1 support, the bundled Neutrino core as a ready-to-use `neutrino/` folder (drag-and-drop to `mc?:/`), and `PS2-Servers.url`, a shortcut to the maintained UDPFS / SMBv1 / UDPBD all-in-one PC launcher. The old `PC-SMB-Server/` folder is no longer embedded. Extract it, pick a folder and copy its `RIPTOPL.ELF` — see [Which build should I use?](#which-build-should-i-use) below. | | `RIPTOPL--PS2DEVPINNEDSDK.ELF` | Bare loader, digest-pinned `ps2dev/ps2dev` toolchain (**safe fallback**; in-app version ends `-PS2DEVPINNEDSDK`). | | `RIPTOPL--PS2DEVLATESTSDK.ELF` | Bare loader, `ps2dev/ps2dev:latest` toolchain (**recommended**; in-app version ends `-PS2DEVLATESTSDK`). | | `RIPTOPL---ds5.ELF` | Same as the bare loader for each SDK flavour, **with DualSense (DS5 USB) pad support** compiled in (`DUALSENSE=1`). One per flavour (`-PS2DEVLATESTSDK-ds5` / `-PS2DEVPINNEDSDK-ds5`); same reliability order applies. The default builds keep DualSense OFF. Best-effort — a flavour's DS5 build may be absent if it failed that run. | diff --git a/docs/LANGUAGES.md b/docs/LANGUAGES.md index ce7e8957b8..a6ecb61342 100644 --- a/docs/LANGUAGES.md +++ b/docs/LANGUAGES.md @@ -42,10 +42,12 @@ translations: ## How to ADD a new string 1. Add it to the **END** of `lng_tmpl/_base.yml`, below the APPEND-ONLY banner (~line 923): + ```yaml - label: MY_NEW_SETTING string: My New Setting ``` + External `lang_*.lng` files are consumed by **line position** (`lang.c`), so inserting a label mid-list shifts every later string ID and makes stale user language packs show the **wrong text** — never an English fallback. diff --git a/docs/NEUTRINO.md b/docs/NEUTRINO.md index 1a2d4d8caa..72d9bef992 100644 --- a/docs/NEUTRINO.md +++ b/docs/NEUTRINO.md @@ -79,7 +79,7 @@ settings: | Auto argument | When | |---|---| -| `-bsd=` | always (the storage backend). APA HDD maps to `ata` (+ `-bsdfs=hdl`), so no separate `apa` token is ever emitted | +| `-bsd=` | always (the storage backend). APA HDD maps to `ata` (+ `-bsdfs=hdl`), so no separate `apa` token is ever emitted. OPL emits this unconditionally for every backend, including `udpfs` — nightly Neutrino builds that auto-detect the backend simply ignore the explicit token, so there is no version split on OPL's side | | `-bsdfs=hdl` | internal HDD (APA) only | | `-bsdfs=` | only if the per-game **Neutrino Filesystem** picker (Compatibility screen) is set off Auto; block-backed devices only (never mmce/udpfs — no filesystem layer there). `hdl`/`bd` also reshape `-dvd` to `hdl:`/`bdfs:`; a hand-typed `-bsdfs=`/`-dvd=` in the args always wins | | `-dvd=` / `-dvd=hdl:` | always (the game image/partition) | diff --git a/src/dialogs.c b/src/dialogs.c index fa6c14f6e2..e474bed426 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -1133,7 +1133,7 @@ struct UIItem diaAbout[] = { {UI_BREAK}, {UI_SPACER}, - // 67 chars, still shorter than the 69-char row above it, so this stays inside the width the + // 68 chars, still shorter than the 70-char row above it, so this stays inside the width the // block already proved safe on a 448-line theme. {UI_LABEL, 0, 1, 1, -1, 0, 15, {.label = {"LocalH - RandQalan - ShaolinAssassin - yoshi314 - zero35 - zackcage6", -1}}}, {UI_BREAK},