mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 20:43:50 -06:00
chore: merge the PS2 BIOS placement work
This commit is contained in:
commit
a42f60ef50
11 files changed
+728
-24
No files matched your search
@@ -0,0 +1,152 @@
|
||||
# LRPS2 at 416291a with Batocera's BIOS directory patch
|
||||
# Source: https://github.com/libretro/parallel-ps2
|
||||
# Upstream: https://github.com/PCSX2/pcsx2
|
||||
|
||||
emulator: "LRPS2 (416291a, Batocera)"
|
||||
type: libretro
|
||||
core_classification: community_fork
|
||||
bios_mode: agnostic
|
||||
source: "https://github.com/libretro/parallel-ps2"
|
||||
upstream: "https://github.com/PCSX2/pcsx2"
|
||||
profiled_date: "2026-11-10"
|
||||
source_commit: "416291ad7dc3caf5df4501c9249cbbe30cbef811"
|
||||
pin_frozen: "Batocera, the only platform that ships it, builds this revision with package/batocera/emulators/retroarch/libretro/libretro-ps2/001.bios-dir.patch (Batocera package/batocera/emulators/retroarch/libretro/libretro-ps2/libretro-ps2.mk:7 at batocera-43.1). Later commits are not part of that build."
|
||||
pin_build:
|
||||
- platform: batocera
|
||||
repo: "https://github.com/batocera-linux/batocera.linux"
|
||||
revision: "batocera-43.1"
|
||||
path: "package/batocera/emulators/retroarch/libretro/libretro-ps2/libretro-ps2.mk"
|
||||
variable: LIBRETRO_PS2_VERSION
|
||||
value: "416291ad7dc3caf5df4501c9249cbbe30cbef811"
|
||||
core_version: null
|
||||
version_basis:
|
||||
kind: none
|
||||
display_name: "Sony - PlayStation 2 (LRPS2 416291a for Batocera)"
|
||||
cores: [pcsx2]
|
||||
built_by: [batocera]
|
||||
systems: [sony-playstation-2]
|
||||
|
||||
bios_directory: "ps2/"
|
||||
resources_directory: "pcsx2/resources/"
|
||||
|
||||
notes: |
|
||||
Batocera installs the build as pcsx2_libretro.so (Batocera
|
||||
package/batocera/emulators/retroarch/libretro/libretro-ps2/libretro-ps2.mk:35-36)
|
||||
and launches it as the libretro core pcsx2 of the ps2 system (Batocera
|
||||
package/batocera/emulationstation/batocera-es-system/es_systems.yml:2293-2294).
|
||||
The library version is the short commit hash git reports at build time
|
||||
(cmake/BuildParameters.cmake:4-9, libretro/main.cpp:1423-1427).
|
||||
|
||||
Its patch moves the BIOS scan from pcsx2/bios to ps2 below the system
|
||||
directory (libretro/main.cpp:1806) and the BIOS folder default to
|
||||
/userdata/bios/ps2, the same folder on Batocera (pcsx2/Pcsx2Config.cpp:1042).
|
||||
The data root stays system/pcsx2, so resources are read from
|
||||
pcsx2/resources and memory cards are written to pcsx2/memcards
|
||||
(libretro/main.cpp:1910-1912).
|
||||
|
||||
BIOS detection is filename-agnostic: ps2/ is scanned for any file between
|
||||
4 and 8 MB with a RESET and a ROMVER romdir entry, no hash is checked, and
|
||||
the list fills the pcsx2_bios core option whose default is the first BIOS
|
||||
found (libretro/main.cpp:1800-1838). retro_load_game refuses to start when
|
||||
no BIOS was found (libretro/main.cpp:1927-1931). The companion files take
|
||||
their path from the selected BIOS.
|
||||
|
||||
The DEV9 hard disk image is user storage the core creates, not a file to
|
||||
obtain.
|
||||
|
||||
files:
|
||||
- name: "<bios>.bin"
|
||||
found_by: content
|
||||
path: "ps2/<bios>.bin"
|
||||
required: true
|
||||
description: "PS2 BIOS binary"
|
||||
min_size: 4194304
|
||||
max_size: 8388608
|
||||
validation: [size]
|
||||
config_key: "pcsx2_bios"
|
||||
source_ref: "source libretro/main.cpp:1800-1838, source libretro/main.cpp:360-365, source libretro/main.cpp:1927-1931, source pcsx2/ps2/BiosTools.cpp:31-32, 60-187, 231-323, source pcsx2/Pcsx2Config.cpp:994-1000, 1042, 1051-1061"
|
||||
note: >
|
||||
Any file of 4 to 8 MB in ps2/ whose romdir holds RESET and ROMVER. The
|
||||
pcsx2_bios core option picks one, and the first valid image found is used
|
||||
when the configured one is missing.
|
||||
|
||||
- name: "<bios>.rom1"
|
||||
path: "ps2/<bios>.rom1"
|
||||
required: false
|
||||
max_size: 4194304
|
||||
description: "DVD player ROM"
|
||||
source_ref: "source pcsx2/ps2/BiosTools.cpp:189-213, 314, source pcsx2/MemoryTypes.h:24"
|
||||
note: "Tries <bios path>.rom1, then the BIOS path with its extension replaced by rom1. Skipped when neither exists."
|
||||
|
||||
- name: "<bios>.rom2"
|
||||
path: "ps2/<bios>.rom2"
|
||||
required: false
|
||||
max_size: 524288
|
||||
description: "Chinese ROM extension"
|
||||
source_ref: "source pcsx2/ps2/BiosTools.cpp:189-213, 315, source pcsx2/MemoryTypes.h:25"
|
||||
note: "Same naming as rom1. Present only on Chinese consoles."
|
||||
|
||||
- name: "<bios>.nvm"
|
||||
path: "ps2/<bios>.nvm"
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 1024
|
||||
description: "NVRAM / EEPROM data"
|
||||
source_ref: "source pcsx2/CDVD/CDVD.cpp:59-60, source pcsx2/CDVD/CDVD.cpp:160-184"
|
||||
note: >
|
||||
Read at the BIOS path with the extension replaced by nvm. Region and
|
||||
language defaults are filled in when the file is missing, short, or has
|
||||
no language or region parameters.
|
||||
|
||||
- name: "<bios>.mec"
|
||||
path: "ps2/<bios>.mec"
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 4
|
||||
description: "Mechacon version"
|
||||
source_ref: "source pcsx2/CDVD/CDVD.cpp:62, source pcsx2/CDVD/CDVD.cpp:186-196"
|
||||
note: "Read at the BIOS path with the extension replaced by mec. Written as 0x00020603 when missing."
|
||||
|
||||
- name: "GameIndex.yaml"
|
||||
path: "pcsx2/resources/GameIndex.yaml"
|
||||
required: false
|
||||
installed_on: [batocera]
|
||||
description: "Per-game fixes and settings database"
|
||||
source_ref: "source pcsx2/GameDatabase.cpp:48, source pcsx2/GameDatabase.cpp:880-885, source libretro/main.cpp:2324-2361"
|
||||
note: >
|
||||
Read from pcsx2/resources at the first game lookup. Without it no game
|
||||
fix applies. Batocera installs the copy of the built tree in
|
||||
bios/pcsx2/resources (Batocera
|
||||
package/batocera/emulators/retroarch/libretro/libretro-ps2/libretro-ps2.mk:37-39).
|
||||
|
||||
- name: "cheats_ws.zip"
|
||||
path: "pcsx2/resources/cheats_ws.zip"
|
||||
required: false
|
||||
description: "widescreen patches archive"
|
||||
source_ref: "source pcsx2/VMManager.cpp:333-348, source libretro/main.cpp:2315-2322"
|
||||
note: "Read when widescreen patches are enabled and pcsx2/cheats_ws holds no patch for the game."
|
||||
|
||||
- name: "cheats_ni.zip"
|
||||
path: "pcsx2/resources/cheats_ni.zip"
|
||||
required: false
|
||||
description: "no-interlacing patches archive"
|
||||
source_ref: "source pcsx2/VMManager.cpp:366-383, source libretro/main.cpp:2315-2322"
|
||||
note: "Read when no-interlacing patches are enabled and pcsx2/cheats_ni holds no patch for the game."
|
||||
|
||||
- name: "eeprom.dat"
|
||||
load_from: working_directory
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 64
|
||||
description: "DEV9 EEPROM"
|
||||
source_ref: "source pcsx2/DEV9/DEV9.cpp:107-116, source pcsx2/DEV9/DEV9.cpp:152-167"
|
||||
note: "Opened from the working directory when DEV9 starts and mapped over 64 bytes. A compiled-in image stands in when the file is missing."
|
||||
|
||||
- name: "flash.dat"
|
||||
load_from: working_directory
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 8650752
|
||||
description: "DEV9 flash memory with ECC"
|
||||
source_ref: "source pcsx2/DEV9/flash.cpp:21-28, source pcsx2/DEV9/flash.cpp:74-101"
|
||||
note: "Read from the working directory when DEV9 starts. The flash is blank (0xFF) when the file is missing."
|
||||
@@ -0,0 +1,151 @@
|
||||
# LRPS2 at 9485a53 with Recalbox's path patch
|
||||
# Source: https://github.com/libretro/parallel-ps2
|
||||
# Upstream: https://github.com/PCSX2/pcsx2
|
||||
|
||||
emulator: "LRPS2 (9485a53, Recalbox)"
|
||||
type: libretro
|
||||
core_classification: community_fork
|
||||
bios_mode: agnostic
|
||||
source: "https://github.com/libretro/parallel-ps2"
|
||||
upstream: "https://github.com/PCSX2/pcsx2"
|
||||
profiled_date: "2026-11-10"
|
||||
source_commit: "9485a53fa5aa2bff17e04518116107f81a8c82e3"
|
||||
pin_frozen: "Recalbox, the only platform that ships it, builds this revision with package/libretro-ps2/0001-recalbox-paths.patch (Recalbox package/libretro-ps2/libretro-ps2.mk:9 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-ps2/libretro-ps2.mk"
|
||||
variable: LIBRETRO_PS2_VERSION
|
||||
value: "9485a53fa5aa2bff17e04518116107f81a8c82e3"
|
||||
core_version: null
|
||||
version_basis:
|
||||
kind: none
|
||||
display_name: "Sony - PlayStation 2 (LRPS2 9485a53 for Recalbox)"
|
||||
cores: [ps2]
|
||||
built_by: [recalbox]
|
||||
systems: [sony-playstation-2]
|
||||
|
||||
bios_directory: "ps2/"
|
||||
resources_directory: "ps2/resources/"
|
||||
|
||||
notes: |
|
||||
Recalbox installs the build as ps2_libretro.so (Recalbox
|
||||
package/libretro-ps2/libretro-ps2.mk:31-33) and lists it as the libretro
|
||||
core ps2 of the ps2 system (Recalbox
|
||||
package/recalbox-romfs2/systems/ps2/system.ini:65-69).
|
||||
The library version is the short commit hash git reports at build time
|
||||
(cmake/BuildParameters.cmake:4-9, libretro/main.cpp:1424-1428).
|
||||
|
||||
Its patch moves the BIOS scan from pcsx2/bios to ps2 below the system
|
||||
directory (libretro/main.cpp:1807), the data root from system/pcsx2 to
|
||||
system/ps2, so resources are read from ps2/resources
|
||||
(libretro/main.cpp:1911-1913), the BIOS folder default to
|
||||
/recalbox/share/bios/ps2, the same folder on Recalbox, and memory cards to
|
||||
/recalbox/share/saves/ps2 (pcsx2/Pcsx2Config.cpp:1042-1043, 1061-1062).
|
||||
|
||||
BIOS detection is filename-agnostic: ps2/ is scanned for any file between
|
||||
4 and 8 MB with a RESET and a ROMVER romdir entry, no hash is checked, and
|
||||
the list fills the pcsx2_bios core option whose default is the first BIOS
|
||||
found (libretro/main.cpp:1801-1839). retro_load_game refuses to start when
|
||||
no BIOS was found (libretro/main.cpp:1928-1932). The companion files take
|
||||
their path from the selected BIOS.
|
||||
|
||||
The DEV9 hard disk image is user storage the core creates, not a file to
|
||||
obtain.
|
||||
|
||||
files:
|
||||
- name: "<bios>.bin"
|
||||
found_by: content
|
||||
path: "ps2/<bios>.bin"
|
||||
required: true
|
||||
description: "PS2 BIOS binary"
|
||||
min_size: 4194304
|
||||
max_size: 8388608
|
||||
validation: [size]
|
||||
config_key: "pcsx2_bios"
|
||||
source_ref: "source libretro/main.cpp:1801-1839, source libretro/main.cpp:360-365, source libretro/main.cpp:1928-1932, source pcsx2/ps2/BiosTools.cpp:31-32, 60-187, 231-323, source pcsx2/Pcsx2Config.cpp:994-1000, 1042, 1051-1061"
|
||||
note: >
|
||||
Any file of 4 to 8 MB in ps2/ whose romdir holds RESET and ROMVER. The
|
||||
pcsx2_bios core option picks one, and the first valid image found is used
|
||||
when the configured one is missing.
|
||||
|
||||
- name: "<bios>.rom1"
|
||||
path: "ps2/<bios>.rom1"
|
||||
required: false
|
||||
max_size: 4194304
|
||||
description: "DVD player ROM"
|
||||
source_ref: "source pcsx2/ps2/BiosTools.cpp:189-213, 314, source pcsx2/MemoryTypes.h:24"
|
||||
note: "Tries <bios path>.rom1, then the BIOS path with its extension replaced by rom1. Skipped when neither exists."
|
||||
|
||||
- name: "<bios>.rom2"
|
||||
path: "ps2/<bios>.rom2"
|
||||
required: false
|
||||
max_size: 524288
|
||||
description: "Chinese ROM extension"
|
||||
source_ref: "source pcsx2/ps2/BiosTools.cpp:189-213, 315, source pcsx2/MemoryTypes.h:25"
|
||||
note: "Same naming as rom1. Present only on Chinese consoles."
|
||||
|
||||
- name: "<bios>.nvm"
|
||||
path: "ps2/<bios>.nvm"
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 1024
|
||||
description: "NVRAM / EEPROM data"
|
||||
source_ref: "source pcsx2/CDVD/CDVD.cpp:59-60, source pcsx2/CDVD/CDVD.cpp:160-184"
|
||||
note: >
|
||||
Read at the BIOS path with the extension replaced by nvm. Region and
|
||||
language defaults are filled in when the file is missing, short, or has
|
||||
no language or region parameters.
|
||||
|
||||
- name: "<bios>.mec"
|
||||
path: "ps2/<bios>.mec"
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 4
|
||||
description: "Mechacon version"
|
||||
source_ref: "source pcsx2/CDVD/CDVD.cpp:62, source pcsx2/CDVD/CDVD.cpp:186-196"
|
||||
note: "Read at the BIOS path with the extension replaced by mec. Written as 0x00020603 when missing."
|
||||
|
||||
- name: "GameIndex.yaml"
|
||||
path: "ps2/resources/GameIndex.yaml"
|
||||
required: false
|
||||
installed_on: [recalbox]
|
||||
description: "Per-game fixes and settings database"
|
||||
source_ref: "source pcsx2/GameDatabase.cpp:48, source pcsx2/GameDatabase.cpp:880-885, source libretro/main.cpp:2265-2302"
|
||||
note: >
|
||||
Read from ps2/resources at the first game lookup. Without it no game fix
|
||||
applies. Recalbox installs the copy of the built tree in
|
||||
bios/ps2/resources (Recalbox package/libretro-ps2/libretro-ps2.mk:34-37).
|
||||
|
||||
- name: "cheats_ws.zip"
|
||||
path: "ps2/resources/cheats_ws.zip"
|
||||
required: false
|
||||
description: "widescreen patches archive"
|
||||
source_ref: "source pcsx2/VMManager.cpp:333-348, source libretro/main.cpp:2256-2263"
|
||||
note: "Read when widescreen patches are enabled and ps2/cheats_ws holds no patch for the game."
|
||||
|
||||
- name: "cheats_ni.zip"
|
||||
path: "ps2/resources/cheats_ni.zip"
|
||||
required: false
|
||||
description: "no-interlacing patches archive"
|
||||
source_ref: "source pcsx2/VMManager.cpp:366-383, source libretro/main.cpp:2256-2263"
|
||||
note: "Read when no-interlacing patches are enabled and ps2/cheats_ni holds no patch for the game."
|
||||
|
||||
- name: "eeprom.dat"
|
||||
load_from: working_directory
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 64
|
||||
description: "DEV9 EEPROM"
|
||||
source_ref: "source pcsx2/DEV9/DEV9.cpp:107-116, source pcsx2/DEV9/DEV9.cpp:152-167"
|
||||
note: "Opened from the working directory when DEV9 starts and mapped over 64 bytes. A compiled-in image stands in when the file is missing."
|
||||
|
||||
- name: "flash.dat"
|
||||
load_from: working_directory
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 8650752
|
||||
description: "DEV9 flash memory with ECC"
|
||||
source_ref: "source pcsx2/DEV9/flash.cpp:21-28, source pcsx2/DEV9/flash.cpp:74-101"
|
||||
note: "Read from the working directory when DEV9 starts. The flash is blank (0xFF) when the file is missing."
|
||||
@@ -140,6 +140,15 @@ files:
|
||||
flash is blank (0xFF) when neither exists. Written back only after the
|
||||
emulated system programs it.
|
||||
|
||||
- name: "eeprom.dat"
|
||||
load_from: working_directory
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 64
|
||||
description: "DEV9 EEPROM"
|
||||
source_ref: "source pcsx2/DEV9/DEV9.cpp:111-123, source pcsx2/DEV9/DEV9.cpp:159-176"
|
||||
note: "Opened from the working directory when DEV9 starts and mapped over 64 bytes. A compiled-in image stands in when the file is missing."
|
||||
|
||||
- name: "mg_keystore.bin"
|
||||
path: "pcsx2/bios/mg_keystore.bin"
|
||||
required: false
|
||||
|
||||
@@ -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: "<bios>.bin"
|
||||
found_by: content
|
||||
path: "ps2/<bios>.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: "<bios>.rom1"
|
||||
path: "ps2/<bios>.rom1"
|
||||
required: false
|
||||
description: "DVD player ROM"
|
||||
source_ref: "source pcsx2/ps2/BiosTools.cpp:191-229, 294, source pcsx2/MemoryTypes.h:22"
|
||||
note: "Tries <bios path>.rom1, then the BIOS path with its extension replaced by rom1. Skipped when neither exists. The first 256 KB are read."
|
||||
|
||||
- name: "<bios>.rom2"
|
||||
path: "ps2/<bios>.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: "<bios>.erom"
|
||||
path: "ps2/<bios>.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: "<bios>.nvm"
|
||||
path: "ps2/<bios>.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: "<bios>.mec"
|
||||
path: "ps2/<bios>.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."
|
||||
+19
-3
@@ -3308,6 +3308,11 @@ def _platform_profiles(
|
||||
}
|
||||
index = upstream_profile_index(profiles)
|
||||
platform = str(config.get("_key") or "")
|
||||
dual_names = {str(c) for c in config.get("dual_mode_cores") or []}
|
||||
|
||||
def build_modes(p: dict) -> set[str]:
|
||||
kind = str(p.get("type", ""))
|
||||
return {mode for mode in ("standalone", "libretro") if mode in kind}
|
||||
|
||||
def designated(name: str) -> set[str]:
|
||||
# A build the platform compiles itself (built_by) is what its
|
||||
@@ -3319,10 +3324,21 @@ def _platform_profiles(
|
||||
p for p in index.get(name, ())
|
||||
if platform and platform in (profiles[p].get("built_by") or [])
|
||||
}
|
||||
if own:
|
||||
return own
|
||||
preferred = preferred_profile(index, name)
|
||||
return {preferred} if preferred is not None else set()
|
||||
if not own:
|
||||
return {preferred} if preferred is not None else set()
|
||||
# The own builds stand for the modes they are built in only.
|
||||
# Batocera builds LRPS2 as pcsx2_libretro.so and launches
|
||||
# standalone PCSX2 under the same name.
|
||||
own_modes = set().union(*(build_modes(profiles[p]) for p in own))
|
||||
if (
|
||||
name in dual_names
|
||||
and preferred is not None
|
||||
and preferred not in own
|
||||
and not build_modes(profiles[preferred]) & own_modes
|
||||
):
|
||||
own.add(preferred)
|
||||
return own
|
||||
|
||||
result = {profile for c in core_set for profile in designated(c)}
|
||||
# A name the platform launches both ways designates its libretro
|
||||
|
||||
@@ -4091,8 +4091,20 @@ def _data_root_target(system: str, text: str) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def _one_content(held: list[str], entries: dict[str, dict], emulator: str) -> list[str]:
|
||||
"""The one dest a copy reads when every held dest carries the same bytes.
|
||||
|
||||
Unchanged when the contents differ: the name then designates nothing.
|
||||
"""
|
||||
if len({entries[dest].get("sha1") for dest in held}) != 1:
|
||||
return held
|
||||
own = [dest for dest in held if emulator in (entries[dest].get("cores") or ())]
|
||||
return [min(own or held, key=lambda dest: (dest.count("/"), len(dest), dest))]
|
||||
|
||||
|
||||
def _profile_copies(
|
||||
profiles: dict[str, dict], dests: list[str], declared: list[dict],
|
||||
entries: dict[str, dict] | None = None,
|
||||
) -> list[dict]:
|
||||
"""The standalone copies the emulator profiles document: each file with
|
||||
a standalone_path, into the data_root of each system that names a place.
|
||||
@@ -4105,6 +4117,10 @@ def _profile_copies(
|
||||
file found by content (found_by) sits wherever the folder the user set
|
||||
for the scan points: Amiberry reads its ROMs from rom_path, which
|
||||
amiberry.conf moves, so its name under data_root proves nothing.
|
||||
``entries`` maps each dest to its manifest entry: one file carried at
|
||||
two paths with the same bytes is one source, the copy whose cores name
|
||||
the emulator, else the shortest path. DuckStation's ps2_scph50006.bin
|
||||
sits at the BIOS root and under pcsx2/bios/ for the libretro PS2 cores.
|
||||
"""
|
||||
from fnmatch import fnmatch # noqa: PLC0415
|
||||
|
||||
@@ -4143,6 +4159,8 @@ def _profile_copies(
|
||||
or entry.get("type") == "directory" or entry.get("found_by") == "content"):
|
||||
continue
|
||||
held = by_tail.get(entry.get("path") or entry["name"], [])
|
||||
if len(held) > 1 and entries is not None:
|
||||
held = _one_content(held, entries, profile_name)
|
||||
if len(held) != 1:
|
||||
continue
|
||||
source = held[0]
|
||||
@@ -4171,8 +4189,10 @@ def _standalone_copies(
|
||||
whose registry entry declares none gets none."""
|
||||
if not declared:
|
||||
return []
|
||||
dests = [entry["dest"] for entry in manifest_files if entry.get("root") != "save"]
|
||||
return _placed_copies(declared, dests) + _profile_copies(profiles, dests, declared)
|
||||
kept = [entry for entry in manifest_files if entry.get("root") != "save"]
|
||||
dests = [entry["dest"] for entry in kept]
|
||||
entries = {entry["dest"]: entry for entry in kept}
|
||||
return _placed_copies(declared, dests) + _profile_copies(profiles, dests, declared, entries)
|
||||
|
||||
|
||||
def _stable_hashes(local_path: str, db: dict) -> dict:
|
||||
|
||||
+62
-18
@@ -513,6 +513,7 @@ def _agnostic_scan_extras(
|
||||
extras_prefix: str,
|
||||
standalone_set: set[str] | None = None,
|
||||
taken: dict[str, dict] | None = None,
|
||||
all_profiles: dict | None = None,
|
||||
) -> list[dict]:
|
||||
"""Every interchangeable candidate a filename-agnostic core accepts.
|
||||
|
||||
@@ -521,6 +522,8 @@ def _agnostic_scan_extras(
|
||||
The directory is the delicate part: anchoring it on a single
|
||||
filename walked into another emulator's tree, so the profile's own
|
||||
files have to agree before the scan follows an ambiguous name.
|
||||
``all_profiles`` are the profiles a placeholder's directory is proven
|
||||
from, ``profiles`` when not given.
|
||||
"""
|
||||
extras: list[dict] = []
|
||||
files_db = db.get("files", {})
|
||||
@@ -617,7 +620,21 @@ def _agnostic_scan_extras(
|
||||
resolved_dirs.get(id(image), "") if image
|
||||
else resolved_dirs.get(id(f), "")
|
||||
)
|
||||
if not path_prefix:
|
||||
# A placeholder (<bios>.bin) resolves to nothing and anchors no
|
||||
# directory. The folders where the system's other profiles
|
||||
# resolve hashed files of that shape do, those folders only:
|
||||
# LRPS2 and PCEE2 are made of placeholders, and on Batocera,
|
||||
# where no other libretro PS2 core anchors pcsx2/bios/, the
|
||||
# pack held nothing there. A companion (<bios>.nvm) looks
|
||||
# where its image is proven: RetroBat's pcsx2/bios/ had
|
||||
# scph39001.bin and its .nvm only at the BIOS root.
|
||||
exact_dirs: frozenset[str] = frozenset()
|
||||
anchor = image if image else f
|
||||
if not path_prefix and "<" in str(anchor.get("name", "")):
|
||||
exact_dirs = placeholder_directories(
|
||||
anchor, emu_name, profile, db, all_profiles or profiles
|
||||
)
|
||||
if not path_prefix and not exact_dirs:
|
||||
continue
|
||||
# A name matching one file identifies it. A name matching several
|
||||
# identifies nothing on its own, so the profile's other files have
|
||||
@@ -629,7 +646,11 @@ def _agnostic_scan_extras(
|
||||
# Scan DB for all files under this prefix matching size
|
||||
for sha1, entry in files_db.items():
|
||||
path = entry.get("path", "")
|
||||
if not path.startswith(path_prefix):
|
||||
if exact_dirs:
|
||||
if ("/" not in path or path.rsplit("/", 1)[0] not in exact_dirs
|
||||
or "/.variants/" in path):
|
||||
continue
|
||||
elif not path.startswith(path_prefix):
|
||||
continue
|
||||
if not companion_ext and not size_fits(f, entry.get("size", 0)):
|
||||
continue
|
||||
@@ -676,9 +697,16 @@ def _agnostic_scan_extras(
|
||||
"agnostic_scan": True,
|
||||
}
|
||||
extra["claim_order"] = (4, 0, emu_name)
|
||||
if not _take(extra, full_dest, seen_dests, taken):
|
||||
continue
|
||||
extras.append(extra)
|
||||
if _take(extra, full_dest, seen_dests, taken):
|
||||
extras.append(extra)
|
||||
else:
|
||||
# The image another core's scan placed is this core's
|
||||
# too, and so are the companions it reads beside it:
|
||||
# Recalbox's libretro PCSX2 opens <bios>.erom next to
|
||||
# the images LRPS2 placed, which LRPS2 never reads.
|
||||
held = taken.get(full_dest) if taken is not None else None
|
||||
if held is None or held.get("sha1") != sha1:
|
||||
continue
|
||||
extras.extend(_companion_extras(
|
||||
_companions(path, scan_name, _companion_extensions(profile, fname), files_db),
|
||||
folder, extras_prefix, seen_dests, profile, emu_name, f, taken,
|
||||
@@ -686,6 +714,31 @@ def _agnostic_scan_extras(
|
||||
return extras
|
||||
|
||||
|
||||
def placeholder_directories(
|
||||
seed: dict, emu_name: str, profile: dict, db: dict, all_profiles: dict,
|
||||
) -> frozenset[str]:
|
||||
"""The folders that hold the dumps a placeholder entry accepts.
|
||||
|
||||
Each folder where another profile of the same system resolves a hashed
|
||||
file of the seed's shape by content: PCSX2 proves bios/Sony/PlayStation 2/.
|
||||
Only that folder, not the ones below it (its DVD firmware).
|
||||
"""
|
||||
systems = set(profile.get("systems", []))
|
||||
directories: set[str] = set()
|
||||
for other_name, other in all_profiles.items():
|
||||
if other_name == emu_name or not systems & set(other.get("systems", [])):
|
||||
continue
|
||||
for f in other.get("files", []):
|
||||
if not isinstance(f, dict) or not any(f.get(h) for h in ("sha1", "md5", "sha256", "crc32")):
|
||||
continue
|
||||
if f.get("size") and not size_fits(seed, f["size"]):
|
||||
continue
|
||||
local, status = resolve_local_file({**f, "source_profile": other_name}, db)
|
||||
if local and "/" in local and resolution_is_hash_exact(status):
|
||||
directories.add(local.rsplit("/", 1)[0])
|
||||
return frozenset(directories)
|
||||
|
||||
|
||||
def _placeholder_scan(
|
||||
files: list[dict], emu_name: str, profile: dict, db: dict, standalone: bool,
|
||||
all_profiles: dict | None = None,
|
||||
@@ -699,7 +752,6 @@ def _placeholder_scan(
|
||||
(its DVD firmware). Nothing proven, nothing scanned.
|
||||
"""
|
||||
files_db = db.get("files", {})
|
||||
systems = set(profile.get("systems", []))
|
||||
extras: list[dict] = []
|
||||
for seed in files:
|
||||
name = str(seed.get("name", ""))
|
||||
@@ -707,18 +759,10 @@ def _placeholder_scan(
|
||||
continue
|
||||
if not (seed.get("size") or seed.get("min_size") or seed.get("max_size")):
|
||||
continue
|
||||
directories: set[str] = set()
|
||||
for other_name, other in (all_profiles or load_emulator_profiles("emulators")).items():
|
||||
if other_name == emu_name or not systems & set(other.get("systems", [])):
|
||||
continue
|
||||
for f in other.get("files", []):
|
||||
if not any(f.get(h) for h in ("sha1", "md5", "sha256", "crc32")):
|
||||
continue
|
||||
if f.get("size") and not size_fits(seed, f["size"]):
|
||||
continue
|
||||
local, status = resolve_local_file({**f, "source_profile": other_name}, db)
|
||||
if local and "/" in local and resolution_is_hash_exact(status):
|
||||
directories.add(local.rsplit("/", 1)[0])
|
||||
directories = placeholder_directories(
|
||||
seed, emu_name, profile, db,
|
||||
all_profiles or load_emulator_profiles("emulators"),
|
||||
)
|
||||
layout = (seed.get("standalone_path") if standalone else None) or seed.get("path") or ""
|
||||
folder = layout.rsplit("/", 1)[0] if "/" in layout else ""
|
||||
for sha1, entry in sorted(files_db.items(), key=lambda kv: kv[1].get("path", "")):
|
||||
|
||||
@@ -55,6 +55,96 @@ class AgnosticScan(unittest.TestCase):
|
||||
["pcsx2/bios/scph1.bin", "pcsx2/bios/scph2.bin"])
|
||||
|
||||
|
||||
def test_a_placeholder_scans_the_folder_another_profile_proves(self):
|
||||
"""LRPS2 and PCEE2 name their BIOS <bios>.bin, which resolves nowhere.
|
||||
|
||||
On RetroArch yaps2 anchored pcsx2/bios/ for them; on Batocera no
|
||||
other libretro PS2 core runs, and the pack held nothing there. The
|
||||
folder where another profile of the system resolves a hashed dump of
|
||||
that shape is the evidence, that folder only.
|
||||
"""
|
||||
from packextras import _agnostic_scan_extras
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
files, by_name = {}, {}
|
||||
for path, data in (
|
||||
("bios/PS2/scph1.bin", b"a" * 64),
|
||||
("bios/PS2/scph2.bin", b"b" * 64),
|
||||
("bios/PS2/scph2.bin.rom1", b"r" * 8),
|
||||
("bios/PS2/scph1.nvm", b"n" * 8),
|
||||
("bios/PS2/.variants/scph3.bin", b"e" * 64),
|
||||
("bios/PS2/DVD/dvd.bin", b"f" * 64),
|
||||
):
|
||||
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
||||
Path(path).write_bytes(data)
|
||||
sha1 = hashlib.sha1(data).hexdigest()
|
||||
name = path.rsplit("/", 1)[1]
|
||||
files[sha1] = {"path": path, "name": name, "size": len(data), "sha1": sha1}
|
||||
by_name.setdefault(name, []).append(sha1)
|
||||
db = {"files": files, "indexes": {"by_name": by_name, "by_md5": {}, "by_crc32": {},
|
||||
"by_path_suffix": {}}}
|
||||
placeholders = {"emulator": "L", "type": "libretro", "bios_mode": "agnostic",
|
||||
"bios_directory": "pcsx2/bios/", "systems": ["ps2"], "files": [
|
||||
{"name": "<bios>.bin", "found_by": "content",
|
||||
"path": "pcsx2/bios/<bios>.bin", "min_size": 32, "max_size": 64},
|
||||
{"name": "<bios>.rom1", "path": "pcsx2/bios/<bios>.rom1"},
|
||||
{"name": "<bios>.nvm", "path": "pcsx2/bios/<bios>.nvm", "size": 8},
|
||||
]}
|
||||
pinned = {"emulator": "S", "type": "standalone", "systems": ["ps2"], "files": [
|
||||
{"name": "scph1.bin", "size": 64,
|
||||
"sha1": hashlib.sha1(b"a" * 64).hexdigest()},
|
||||
]}
|
||||
extras = _agnostic_scan_extras(
|
||||
{"l": placeholders, "s": pinned}, {"l"}, db, by_name, set(), "")
|
||||
self.assertEqual(sorted(e["destination"] for e in extras), [
|
||||
"pcsx2/bios/scph1.bin", "pcsx2/bios/scph1.nvm", "pcsx2/bios/scph2.bin",
|
||||
"pcsx2/bios/scph2.bin.rom1",
|
||||
])
|
||||
self.assertTrue(all(e["source_profile"] == "l" for e in extras))
|
||||
# An image the platform already ships there still gets its
|
||||
# companion: RetroBat lists pcsx2/bios/scph39001.bin itself.
|
||||
shipped = {"pcsx2/bios/scph1.bin"}
|
||||
extras = _agnostic_scan_extras(
|
||||
{"l": placeholders, "s": pinned}, {"l"}, db, by_name, shipped, "")
|
||||
self.assertIn("pcsx2/bios/scph1.nvm", {e["destination"] for e in extras})
|
||||
# Nothing proves the folder: nothing is scanned.
|
||||
self.assertEqual(
|
||||
_agnostic_scan_extras({"l": placeholders}, {"l"}, db, by_name, set(), ""), [])
|
||||
|
||||
|
||||
class OneContentTwoPaths(unittest.TestCase):
|
||||
"""A standalone copy reads one file the manifest carries at two paths.
|
||||
|
||||
The libretro PS2 cores put DuckStation's ps2_scph50006.bin under
|
||||
pcsx2/bios/ beside the BIOS root copy, and the copy into DuckStation's
|
||||
folder was dropped as ambiguous on Batocera, Recalbox and RetroBat.
|
||||
"""
|
||||
|
||||
DUCK = {"data_root": {"linux": {"path": "~/.local/share/duckstation", "source_ref": "x"}},
|
||||
"files": [{"name": "ps2_scph50006.bin", "standalone_path": "bios/ps2_scph50006.bin"}]}
|
||||
|
||||
def _copies(self, entries):
|
||||
from generate_pack import _profile_copies
|
||||
|
||||
return _profile_copies({"duckstation": self.DUCK}, list(entries), [], entries)
|
||||
|
||||
def test_same_bytes_take_the_copy_that_serves_the_emulator(self):
|
||||
(copy,) = self._copies({
|
||||
"pcsx2/bios/ps2_scph50006.bin": {"sha1": "a", "cores": ["lrps2"]},
|
||||
"ps2_scph50006.bin": {"sha1": "a", "cores": ["duckstation", "pcsx2"]},
|
||||
})
|
||||
self.assertEqual(copy["file"], "ps2_scph50006.bin")
|
||||
|
||||
def test_other_bytes_under_one_name_designate_nothing(self):
|
||||
self.assertEqual(self._copies({
|
||||
"pcsx2/bios/ps2_scph50006.bin": {"sha1": "a", "cores": ["lrps2"]},
|
||||
"ps2_scph50006.bin": {"sha1": "b", "cores": ["duckstation"]},
|
||||
}), [])
|
||||
|
||||
|
||||
class BundledHashIsProof(unittest.TestCase):
|
||||
"""A bundled file with a declared hash is served by those bytes or flagged.
|
||||
|
||||
|
||||
@@ -160,5 +160,56 @@ class APlatformsOwnBuildWinsItsName(unittest.TestCase):
|
||||
self.assertEqual(resolve_platform_cores(retropie, profiles), {"uae4all"})
|
||||
|
||||
|
||||
class APatchedLibretroBuildTakesItsNameOnly(unittest.TestCase):
|
||||
"""Batocera and Recalbox compile LRPS2 with a patch that reads the BIOS
|
||||
from ps2/ instead of pcsx2/bios/. Their own build replaces the buildbot
|
||||
LRPS2 under the name they ship, and Batocera's standalone PCSX2, under
|
||||
the same name, stays."""
|
||||
|
||||
def test_own_libretro_build_keeps_the_standalone_of_a_dual_name(self):
|
||||
from common import resolve_platform_cores
|
||||
|
||||
profiles = {
|
||||
"pcsx2": {"type": "standalone", "source": "s", "cores": ["pcsx2"]},
|
||||
"lrps2": {"type": "libretro", "source": "l", "cores": ["lrps2", "pcsx2"]},
|
||||
"lrps2-own": {"type": "libretro", "source": "l", "cores": ["pcsx2"],
|
||||
"built_by": ["x"]},
|
||||
}
|
||||
config = {"_key": "x", "cores": ["pcsx2"], "standalone_cores": ["pcsx2"],
|
||||
"dual_mode_cores": ["pcsx2"]}
|
||||
self.assertEqual(resolve_platform_cores(config, profiles), {"pcsx2", "lrps2-own"})
|
||||
del config["dual_mode_cores"]
|
||||
self.assertEqual(resolve_platform_cores(config, profiles), {"lrps2-own"})
|
||||
|
||||
def test_the_registry_resolves_each_platform_build(self):
|
||||
from common import load_emulator_profiles, load_platform_config, resolve_platform_cores
|
||||
|
||||
profiles = load_emulator_profiles(str(REPO_ROOT / "emulators"))
|
||||
platforms = str(REPO_ROOT / "platforms")
|
||||
|
||||
def ps2_cores(platform: str) -> set[str]:
|
||||
config = load_platform_config(platform, platforms)
|
||||
return {
|
||||
c for c in resolve_platform_cores(config, profiles)
|
||||
if c.startswith(("lrps2", "pcsx2", "pcee2"))
|
||||
}
|
||||
|
||||
self.assertEqual(ps2_cores("batocera"), {"lrps2-416291a", "pcsx2", "pcee2"})
|
||||
# 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(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/<bios>.bin")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -108,6 +108,56 @@ class Companions(unittest.TestCase):
|
||||
self.assertIn("SCPH-70004.rom1", names)
|
||||
self.assertFalse({"SCPH-70004.ROM1", "cheats_ws.zip", "GameIndex.yaml"} & names)
|
||||
|
||||
def test_a_shared_image_brings_each_cores_companions(self):
|
||||
"""Recalbox runs LRPS2 and the old libretro PCSX2 on one ps2/ folder.
|
||||
LRPS2's scan placed SCPH-70004.BIN and its rom1, and the second core's
|
||||
scan stopped at the taken image, so the .erom only it reads stayed out."""
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from packextras import _agnostic_scan_extras
|
||||
|
||||
def profile(name: str, ext: str) -> dict:
|
||||
return {"emulator": name, "bios_mode": "agnostic", "files": [
|
||||
{"name": "ps2-0230a-20080220.bin", "found_by": "content",
|
||||
"path": "ps2/ps2-0230a-20080220.bin", "min_size": 8, "max_size": 16},
|
||||
{"name": f"ps2-0230a-20080220.{ext}", "path": f"ps2/ps2-0230a-20080220.{ext}"},
|
||||
]}
|
||||
|
||||
stored = {
|
||||
"ps2-0230a-20080220.bin": b"I" * 8,
|
||||
"ps2-0230a-20080220.rom1": b"R",
|
||||
"ps2-0230a-20080220.erom": b"E",
|
||||
}
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cwd = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
try:
|
||||
files, by_name = {}, {}
|
||||
for name, payload in stored.items():
|
||||
path = f"bios/PS2/{name}"
|
||||
os.makedirs("bios/PS2", exist_ok=True)
|
||||
Path(path).write_bytes(payload)
|
||||
sha1 = f"{len(files):040d}"
|
||||
files[sha1] = {"path": path, "name": name, "size": len(payload),
|
||||
"sha1": sha1}
|
||||
by_name[name] = [sha1]
|
||||
db = {"files": files, "indexes": {
|
||||
"by_name": by_name, "by_md5": {}, "by_crc32": {}, "by_path_suffix": {},
|
||||
}}
|
||||
profiles = {"a": profile("A", "rom1"), "b": profile("B", "erom")}
|
||||
extras = _agnostic_scan_extras(
|
||||
profiles, {"a", "b"}, db, by_name, set(), "", taken={},
|
||||
)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
placed = [(e["destination"], e["source_profile"]) for e in extras]
|
||||
self.assertEqual(sorted(placed), [
|
||||
("ps2/ps2-0230a-20080220.bin", "a"),
|
||||
("ps2/ps2-0230a-20080220.erom", "b"),
|
||||
("ps2/ps2-0230a-20080220.rom1", "a"),
|
||||
])
|
||||
|
||||
def test_pcsx2_profiles_name_no_free_standing_companion(self):
|
||||
for name in ("pcsx2", "pcsx2-legacy"):
|
||||
profile = yaml.safe_load((REPO_ROOT / "emulators" / f"{name}.yml").read_text())
|
||||
|
||||
@@ -195,7 +195,10 @@ resolved. Three strategies exist:
|
||||
|
||||
- **Explicit list**: `cores: [beetle_psx, dolphin, ...]` - match by profile key name
|
||||
or by any name in a profile's `cores:`. When a profile's `built_by` names this
|
||||
platform, that profile answers for the name (ROCKNIX's `yabadabadoo`). Used by
|
||||
platform, that profile answers for the name (ROCKNIX's `yabadabadoo`). On a
|
||||
`dual_mode_cores` name it answers for its own build mode only: Batocera's
|
||||
patched LRPS2 (`lrps2-416291a`) takes the libretro `pcsx2` and the standalone
|
||||
PCSX2 stays. Used by
|
||||
Batocera, Recalbox, RetroBat, RomM, KNULLI, AmberELEC, EmuELEC, MinUI, NextUI,
|
||||
MyMinUI, ROCKNIX, RetroPie, EmuDeck, RetroDECK. A list that names `retroarch`
|
||||
(the last three) also takes every libretro profile, as `all_libretro` does,
|
||||
|
||||
Reference in new issue
Block a user