From f3f125d9455acf1236e64b46cf50573abaaec463 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 12:02:27 +0100 Subject: [PATCH] feat: profile Recalbox's libretro PCSX2 Recalbox 10.1.1 builds the wxWidgets-era libretro PCSX2 for x86_64 at 408e3b2 with 0003-bios-path.patch, which moves the BIOS scan from pcsx2/bios to ps2, and lists it as the libretro core pcsx2 of the ps2 system. Since lrps2-9485a53 took the ps2 name no profile described it. pcsx2-libretro-408e3b2 is built_by recalbox under the name pcsx2, beside standalone PCSX2 and LRPS2. It reads .rom1, rom2, erom, nvm and mec beside the selected image. GameIndex.yaml and the patch archives are compiled in. --- emulators/pcsx2-libretro-408e3b2.yml | 118 +++++++++++++++++++++++++++ tests/test_batocera_cores.py | 14 +++- 2 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 emulators/pcsx2-libretro-408e3b2.yml diff --git a/emulators/pcsx2-libretro-408e3b2.yml b/emulators/pcsx2-libretro-408e3b2.yml new file mode 100644 index 000000000..b90a4468f --- /dev/null +++ b/emulators/pcsx2-libretro-408e3b2.yml @@ -0,0 +1,118 @@ +# libretro PCSX2 at 408e3b2 with Recalbox's BIOS path patch +# Source: https://gitlab.com/recalbox/packages/libretro/libretro-pcsx2 +# Upstream: https://github.com/PCSX2/pcsx2 + +emulator: "PCSX2 libretro (408e3b2, Recalbox)" +type: libretro +core_classification: community_fork +bios_mode: agnostic +source: "https://gitlab.com/recalbox/packages/libretro/libretro-pcsx2" +upstream: "https://github.com/PCSX2/pcsx2" +profiled_date: "2026-11-10" +source_commit: "408e3b253847b25536ad77e4ab0c3aff6b8b896f" +pin_frozen: "Recalbox, the only platform that ships it, builds this revision with package/libretro-pcsx2/0003-bios-path.patch (Recalbox package/libretro-pcsx2/libretro-pcsx2.mk:8 at tag 10.1.1). Later commits are not part of that build." +pin_build: + - platform: recalbox + repo: "https://gitlab.com/recalbox/recalbox" + revision: "10.1.1" + path: "package/libretro-pcsx2/libretro-pcsx2.mk" + variable: LIBRETRO_PCSX2_VERSION + value: "408e3b253847b25536ad77e4ab0c3aff6b8b896f" +core_version: "1.7.0" +version_basis: + kind: file + path: "pcsx2/SysForwardDefs.h" + pattern: 'PCSX2_VersionHi\s*=\s*(\d+);\s*\n.*PCSX2_VersionMid\s*=\s*(\d+);\s*\n.*PCSX2_VersionLo\s*=\s*(\d+);' + format: "{1}.{2}.{3}" +display_name: "Sony - PlayStation 2 (PCSX2 libretro 408e3b2 for Recalbox)" +cores: [pcsx2] +built_by: [recalbox] +systems: [sony-playstation-2] + +bios_directory: "ps2/" + +notes: | + The wxWidgets-era libretro port of PCSX2 1.7.0. Recalbox builds it for + x86_64 only (Recalbox package/libretro-pcsx2/Config.in:3, Recalbox + configs/recalbox-x86_64_defconfig:352), installs it as pcsx2_libretro.so + (Recalbox package/libretro-pcsx2/libretro-pcsx2.mk:30-31) and lists it as + the libretro core pcsx2 of the ps2 system (Recalbox + package/recalbox-romfs2/systems/ps2/system.ini:54-58). + The library version is git describe of the build tree, empty when the tree + has no .git (cmake/Pcsx2Utils.cmake:38-52, 70-72, libretro/main.cpp:447-448). + + Its patch moves the BIOS scan from pcsx2/bios to ps2 below the system + directory (libretro/main.cpp:264), /recalbox/share/bios/ps2 on Recalbox. + + BIOS detection is filename-agnostic: every file in ps2/ whose romdir holds + a RESET and a ROMVER entry is listed, no size or hash is checked, and the + list fills the pcsx2_bios core option whose default is the first BIOS found + (libretro/main.cpp:262-303). Without one, retro_init returns before it + creates the emulator and no game starts (libretro/main.cpp:282-287, + 325-328). The companion files take their path from the selected BIOS. + + GameIndex.yaml and the widescreen, no-interlacing and 60 fps patch archives + are compiled in (pcsx2/CMakeLists.txt:338-367, + pcsx2/gui/AppGameDatabase.cpp:20-24, pcsx2/Patch.cpp:30-32). DEV9 is the + null device (pcsx2/DEV9/DEV9.cpp:59-64), so no hard disk, EEPROM or flash + file is read. Memory cards and pnach patches under system/pcsx2 are user + files. + +files: + - name: ".bin" + found_by: content + path: "ps2/.bin" + required: true + description: "PS2 BIOS binary" + min_size: 4194304 + max_size: 8388608 + config_key: "pcsx2_bios" + source_ref: "source libretro/main.cpp:262-303, source libretro/main.cpp:317-328, source libretro/main.cpp:653-654, source pcsx2/ps2/BiosTools.cpp:74-167, 261-319, 340-356, source pcsx2/MemoryTypes.h:21" + note: > + Any file in ps2/ whose romdir holds RESET and ROMVER, picked by the + pcsx2_bios core option. No size is checked: RESET is looked for in the + first 8 MB (pcsx2/ps2/BiosTools.cpp:79-84) and the first 4 MB are + mapped. + + - name: ".rom1" + path: "ps2/.rom1" + required: false + description: "DVD player ROM" + source_ref: "source pcsx2/ps2/BiosTools.cpp:191-229, 294, source pcsx2/MemoryTypes.h:22" + note: "Tries .rom1, then the BIOS path with its extension replaced by rom1. Skipped when neither exists. The first 256 KB are read." + + - name: ".rom2" + path: "ps2/.rom2" + required: false + description: "Chinese ROM extension" + source_ref: "source pcsx2/ps2/BiosTools.cpp:191-229, 295, source pcsx2/MemoryTypes.h:23" + note: "Same naming as rom1. Present only on Chinese consoles. The first 512 KB are read." + + - name: ".erom" + path: "ps2/.erom" + required: false + description: "DVD player extension ROM" + source_ref: "source pcsx2/ps2/BiosTools.cpp:191-229, 296, source pcsx2/MemoryTypes.h:24" + note: "Same naming as rom1. The first 0x1C0000 bytes are read." + + - name: ".nvm" + path: "ps2/.nvm" + required: false + hle_fallback: true + size: 1024 + description: "NVRAM / EEPROM data" + source_ref: "source pcsx2/CDVD/CDVD.cpp:142-187, source libretro/main.cpp:634-642, source libretro/language_injector.cpp:231-262" + note: > + Read at the BIOS path with the extension replaced by nvm. A file shorter + than 1024 bytes is replaced by a blank one with a dummy i.LINK ID. + Without it the fast boot option is ignored. When it exists and the BIOS + is in the language table, the system language option is written into it. + + - name: ".mec" + path: "ps2/.mec" + required: false + hle_fallback: true + size: 4 + description: "Mechacon version" + source_ref: "source pcsx2/CDVD/CDVD.cpp:96-126" + note: "Read at the BIOS path with the extension replaced by mec. Written as bytes 03 06 02 00 when missing." diff --git a/tests/test_batocera_cores.py b/tests/test_batocera_cores.py index 890cf67b3..271bd276c 100644 --- a/tests/test_batocera_cores.py +++ b/tests/test_batocera_cores.py @@ -195,14 +195,20 @@ class APatchedLibretroBuildTakesItsNameOnly(unittest.TestCase): } self.assertEqual(ps2_cores("batocera"), {"lrps2-416291a", "pcsx2", "pcee2"}) - self.assertEqual(ps2_cores("recalbox"), {"lrps2-9485a53", "pcsx2"}) + # Recalbox ships two libretro PS2 builds on x86_64: LRPS2 as ps2 and + # the wxWidgets-era libretro PCSX2 as pcsx2, beside standalone PCSX2. + self.assertEqual( + ps2_cores("recalbox"), {"lrps2-9485a53", "pcsx2-libretro-408e3b2", "pcsx2"} + ) + own_builds = {"lrps2-416291a", "lrps2-9485a53", "pcsx2-libretro-408e3b2"} for platform in ("retroarch", "retrobat", "emudeck", "retrodeck"): with self.subTest(platform=platform): cores = ps2_cores(platform) self.assertIn("lrps2", cores) - self.assertFalse({"lrps2-416291a", "lrps2-9485a53"} & cores) - self.assertEqual(profiles["lrps2-416291a"]["files"][0]["path"], "ps2/.bin") - self.assertEqual(profiles["lrps2-9485a53"]["files"][0]["path"], "ps2/.bin") + self.assertFalse(own_builds & cores) + self.assertNotIn("pcsx2-libretro-408e3b2", ps2_cores("batocera")) + for name in sorted(own_builds): + self.assertEqual(profiles[name]["files"][0]["path"], "ps2/.bin") if __name__ == "__main__":