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..19fadf019e 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. @@ -289,11 +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-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. 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). @@ -356,14 +367,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 +393,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..43ec314779 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. 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 (`-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..a6ecb61342 100644 --- a/docs/LANGUAGES.md +++ b/docs/LANGUAGES.md @@ -41,11 +41,16 @@ 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..72d9bef992 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. 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) | | `-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..e474bed426 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}}}, + // 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}, {UI_BREAK},