mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-12 04:53:52 -06:00
chore: merge origin/main
This commit is contained in:
commit
2dc427d5d0
106 files changed
+5458
-13655
No files matched your search
@@ -3560,6 +3560,25 @@ SYSTEM_ALIASES: dict[str, str] = {
|
||||
"snesmsu": "nintendo-snes",
|
||||
"megadrivemsu": "sega-megadrive",
|
||||
"sgb-msu1": "nintendo-sgb",
|
||||
# Spellings profiles gave a machine the others call by another id:
|
||||
# ares's own system names, dgen and picodrive's sega-genesis beside
|
||||
# sega-megadrive, fbneo's sinclair-spectrum and snk-neogeo-pocket,
|
||||
# emux_sms's sms. muOS names its GBA folder gameboyadvance first, the
|
||||
# folder resolved to ares's game-boy-advance, and an unrecognised GBA
|
||||
# game got no file of the nintendo-gba list.
|
||||
"famicom": "nintendo-nes",
|
||||
"famicom-disk-system": "nintendo-fds",
|
||||
"super-famicom": "nintendo-snes",
|
||||
"game-boy-advance": "nintendo-gba",
|
||||
"neo-geo-pocket": "snk-ngp",
|
||||
"snk-neogeo-pocket": "snk-ngp",
|
||||
"neo-geo-pocket-color": "snk-ngpc",
|
||||
"wonderswan": "bandai-wswan",
|
||||
"wonderswan-color": "bandai-wswanc",
|
||||
"sega-genesis": "sega-megadrive",
|
||||
"genesis": "sega-megadrive",
|
||||
"sinclair-spectrum": "sinclair-zx-spectrum",
|
||||
"sms": "sega-mastersystem",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -282,9 +282,19 @@ def resolve_folder(
|
||||
An arcade core is the exception: the arcade index names each set's
|
||||
files, and its hundred machines would make any unknown file a fallback
|
||||
for all of them.
|
||||
|
||||
A name that spells a machine its core does not run adds the core's
|
||||
machines to it: the games run on that core. Mednafen's PC Engine core
|
||||
lists nec-pc-engine, the CD folder resolved to nec-pc-engine-cd alone,
|
||||
and an unrecognised CD game got no System Card.
|
||||
"""
|
||||
resolution = resolver.resolve(folder_names(row), platform)
|
||||
own = [str(s) for s in profiles.profiles.get(profile or "", {}).get("systems") or []]
|
||||
if resolution.systems and own and profile not in arcade:
|
||||
runs = {sid for s in own for sid in resolver.equivalents(s)}
|
||||
if not runs & set(resolution.systems):
|
||||
systems = set(resolution.systems) | {resolver.canonical(s) for s in own}
|
||||
return Resolution(sorted(systems), f"{resolution.basis}, and systems of {profile}")
|
||||
if resolution.systems or not own:
|
||||
return resolution
|
||||
if len(own) == 1:
|
||||
|
||||
@@ -81,6 +81,7 @@ from common import (
|
||||
load_platform_config,
|
||||
without_profile_blind,
|
||||
MANUFACTURER_PREFIXES,
|
||||
_norm_system_id,
|
||||
require_yaml,
|
||||
ProfileSelectionError,
|
||||
core_system_dirs,
|
||||
@@ -419,6 +420,17 @@ def platform_list_version(config: dict, platform: str) -> str:
|
||||
PACK_DOCUMENTS = ("README.txt", "manifest.json")
|
||||
|
||||
|
||||
def pack_markers(
|
||||
platform_name: str, target_name: str | None, platforms_dir: str
|
||||
) -> tuple[str, ...]:
|
||||
"""The empty files a pack carries for the systems it is unzipped on,
|
||||
as named before flattening: the .nomedia of a pack for Android."""
|
||||
from common import list_available_targets
|
||||
|
||||
names = [t["name"] for t in list_available_targets(platform_name, platforms_dir)]
|
||||
return (MEDIA_MARKER,) if lands_on_android(names, target_name) else ()
|
||||
|
||||
|
||||
def core_data_trees(
|
||||
config: dict,
|
||||
profiles: dict[str, dict],
|
||||
@@ -1495,6 +1507,10 @@ def generate_pack(
|
||||
),
|
||||
)
|
||||
_write_generated_member(zf, "README.txt", readme_text)
|
||||
for marker in pack_markers(platform_name, target_name, platforms_dir):
|
||||
_write_generated_member(
|
||||
zf, _flat(f"{base_dest}/{marker}" if base_dest else marker, base_dest, flatten), ""
|
||||
)
|
||||
|
||||
_report_pack_counts(
|
||||
zip_path, file_status, total_files, core_count, source,
|
||||
@@ -5209,7 +5225,7 @@ def generate_manifest(
|
||||
data_sizes = pack_only_sizes + [os.path.getsize(src) for src, _dest in data_members]
|
||||
data_directories = _manifest_data_directories(
|
||||
data_members, data_refs, data_registry or {}, base_dest,
|
||||
tree_readers(pack_systems, core_trees),
|
||||
tree_readers(pack_systems, core_trees), pack_systems,
|
||||
)
|
||||
|
||||
now = _build_timestamp(db)
|
||||
@@ -5243,7 +5259,7 @@ def generate_manifest(
|
||||
"total_size": total_size,
|
||||
"pack_files": (
|
||||
len(manifest_files) + len(data_sizes) + len(PACK_DOCUMENTS)
|
||||
+ len(rename_notes)
|
||||
+ len(rename_notes) + len(pack_markers(platform_name, target_name, platforms_dir))
|
||||
),
|
||||
"pack_size": total_size + sum(data_sizes),
|
||||
"total_omitted": len(omitted_by_destination),
|
||||
@@ -5324,6 +5340,7 @@ def _manifest_data_directories(
|
||||
registry: dict,
|
||||
base_dest: str,
|
||||
readers: dict[str, list[str]] | None = None,
|
||||
platform_systems: Iterable[str] | None = None,
|
||||
) -> list[dict]:
|
||||
"""Each data directory the pack carries, as the installer rebuilds it.
|
||||
|
||||
@@ -5334,6 +5351,11 @@ def _manifest_data_directories(
|
||||
changed since is refused rather than installed. archive_size is the
|
||||
size of the archive refresh_data_dirs last downloaded, what fetching
|
||||
the tree costs: a tarball whose tree is 10 KB is a download of 21 MB.
|
||||
``systems`` are the platform's ids (``platform_systems``) the tree's
|
||||
systems normalize to, as a core extra's are: a tree no platform system
|
||||
serves has none, and goes with the files of no system, as the pack
|
||||
built with --system puts it in the part of its own. FBNeo's cheats
|
||||
carried sega-megadrive where RetroArch's list says sega-mega-drive.
|
||||
``optional`` marks a tree every core reading it runs without
|
||||
(``required: false``): install.py --required-only leaves it out, as the
|
||||
pack built with --required-only does. ``cores`` names the cores that
|
||||
@@ -5342,8 +5364,13 @@ def _manifest_data_directories(
|
||||
"""
|
||||
grouped: dict[tuple[str, str], dict] = {}
|
||||
versions: dict[str, dict[str, dict]] = {}
|
||||
by_norm: dict[str, list[str]] = {}
|
||||
for sys_id in sorted(platform_systems or ()):
|
||||
by_norm.setdefault(_norm_system_id(sys_id), []).append(sys_id)
|
||||
for src, full in members:
|
||||
ref, systems, prefix, needed = refs[full]
|
||||
if platform_systems is not None:
|
||||
systems = tuple(own for sid in systems for own in by_norm.get(_norm_system_id(sid), ()))
|
||||
entry = registry.get(ref, {})
|
||||
key = (ref, prefix)
|
||||
group = grouped.get(key)
|
||||
@@ -5826,6 +5853,8 @@ def verify_and_finalize_packs(
|
||||
return all_ok
|
||||
|
||||
from packpaths import ( # noqa: E402,F401
|
||||
MEDIA_MARKER,
|
||||
lands_on_android,
|
||||
_archive_destination,
|
||||
_path_parents,
|
||||
_has_path_conflict,
|
||||
|
||||
@@ -192,6 +192,23 @@ def _register_path(dest: str, seen_files: set[str], seen_parents: set[str]) -> N
|
||||
for parent in _path_parents(dest):
|
||||
seen_parents.add(parent)
|
||||
|
||||
# Android's media scanner hides a folder holding a .nomedia file, and every
|
||||
# folder below it (MediaProvider a183e2b9, FileUtils.java:1587-1629
|
||||
# isDirectoryHidden, ModernMediaScanner.java:845-846). RetroArch writes none
|
||||
# (libretro-common/file/file_path_io.c:194 only skips one), so a pack
|
||||
# unzipped into RetroArch Android's system folder put its samples, overlays
|
||||
# and videos in the gallery and music apps.
|
||||
MEDIA_MARKER = ".nomedia"
|
||||
|
||||
|
||||
def lands_on_android(target_names: Iterable[str], target: str | None) -> bool:
|
||||
"""Whether a pack can be unzipped on Android: its target is an Android
|
||||
one, or, unfiltered, the platform files one."""
|
||||
if target:
|
||||
return target.startswith("android")
|
||||
return any(name.startswith("android") for name in target_names)
|
||||
|
||||
|
||||
def _flat(arcname: str, prefix: str, flatten: bool) -> str:
|
||||
"""Strip base_destination prefix from ZIP arcname when flattening."""
|
||||
if flatten and prefix and arcname.startswith(prefix + "/"):
|
||||
|
||||
@@ -10,7 +10,7 @@ from collections import Counter
|
||||
|
||||
from auto_fetch import DEFAULT_BIOS_DIR
|
||||
from artifacts import _build_timestamp
|
||||
from packpaths import _has_path_conflict
|
||||
from packpaths import MEDIA_MARKER, _has_path_conflict
|
||||
from ziptools import build_zip_contents_index
|
||||
from ziptools import check_inside_zip
|
||||
from nativemode import digest_algorithm
|
||||
@@ -170,7 +170,7 @@ def verify_pack(
|
||||
# (bios/INSTRUCTIONS_x.txt, games/keen6/INSTRUCTIONS_y.txt), so
|
||||
# they are told by their own name, not by a root prefix.
|
||||
base = name.rsplit("/", 1)[-1]
|
||||
if base.startswith(("INSTRUCTIONS_", "RENAMED_")) or name in (
|
||||
if base.startswith(("INSTRUCTIONS_", "RENAMED_")) or base == MEDIA_MARKER or name in (
|
||||
"manifest.json",
|
||||
"README.txt",
|
||||
):
|
||||
@@ -539,7 +539,7 @@ def _structural_errors(zf: zipfile.ZipFile, zip_set: set) -> list[str]:
|
||||
if "GraphicMods" not in info.filename and info.filename not in (
|
||||
"manifest.json",
|
||||
"README.txt",
|
||||
):
|
||||
) and info.filename.rsplit("/", 1)[-1] != MEDIA_MARKER:
|
||||
errors.append(f"zero-byte: {info.filename}")
|
||||
|
||||
return errors
|
||||
@@ -746,7 +746,7 @@ def verify_pack_against_platform(
|
||||
is_flat = bool(base_dest) and not any(
|
||||
n.startswith(base_dest + "/")
|
||||
for n in zip_set
|
||||
if n not in ("README.txt", "manifest.json") and not n.endswith("/")
|
||||
if n not in ("README.txt", "manifest.json", MEDIA_MARKER) and not n.endswith("/")
|
||||
)
|
||||
|
||||
errors.extend(_structural_errors(zf, zip_set))
|
||||
|
||||
@@ -92,8 +92,8 @@ NOINTRO_DATS: dict[str, tuple[str, int]] = {
|
||||
"Sega - 32X": ("sega-32x", 202),
|
||||
"Bandai - WonderSwan": ("wonderswan", 244),
|
||||
"Bandai - WonderSwan Color": ("wonderswan-color", 229),
|
||||
"SNK - NeoGeo Pocket": ("snk-neogeo-pocket", 12),
|
||||
"SNK - NeoGeo Pocket Color": ("neo-geo-pocket-color", 121),
|
||||
"SNK - NeoGeo Pocket": ("snk-ngp", 12),
|
||||
"SNK - NeoGeo Pocket Color": ("snk-ngpc", 121),
|
||||
}
|
||||
|
||||
# redump.info datfile code -> (DAT header name, repository system id, floor).
|
||||
|
||||
@@ -881,7 +881,6 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"atari-zn1": "Atari ZN-1",
|
||||
"atlus-zn1": "Atlus ZN-1",
|
||||
"bandai-playdia": "Bandai Playdia",
|
||||
"bandai-wswan": "Bandai WonderSwan",
|
||||
"bandai-wswanc": "Bandai WonderSwan Color",
|
||||
"barcrest-mpu4": "Barcrest MPU4",
|
||||
"bbc-master-128": "Acorn BBC Master 128",
|
||||
@@ -958,7 +957,6 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"exhumed": "PowerSlave",
|
||||
"exidy-maxaflex": "Exidy Max-A-Flex",
|
||||
"fallout": "Fallout",
|
||||
"famicom": "Nintendo Famicom",
|
||||
"flash": "Adobe Flash",
|
||||
"flashback": "Flashback",
|
||||
"fm77av": "Fujitsu FM77AV",
|
||||
@@ -1059,15 +1057,11 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"napalm": "NAPALM",
|
||||
"nec-pc-80": "NEC PC-8001",
|
||||
"nec-supergrafx": "NEC SuperGrafx",
|
||||
"neo-geo-pocket-color": "SNK Neo Geo Pocket Color",
|
||||
"neogeo64": "SNK Hyper Neo Geo 64",
|
||||
"ngp": "SNK Neo Geo Pocket",
|
||||
"ngpc": "SNK Neo Geo Pocket Color",
|
||||
"nichibutsu-hrdvd": "Nichibutsu High Rate DVD",
|
||||
"nintendo-aleck64": "Nintendo Aleck64",
|
||||
"nintendo-fds": "Nintendo Famicom Disk System",
|
||||
"nintendo-gb": "Nintendo Game Boy",
|
||||
"nintendo-gba": "Nintendo Game Boy Advance",
|
||||
"nintendo-gbc": "Nintendo Game Boy Color",
|
||||
"nintendo-nss": "Nintendo Super System",
|
||||
"nintendo-playch10": "Nintendo PlayChoice-10",
|
||||
@@ -1128,7 +1122,6 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"sdlpal": "The Legend of Sword and Fairy",
|
||||
"sega-atomiswave": "Sammy Atomiswave",
|
||||
"sega-dreamcast-arcade": "Sega Dreamcast-based arcade boards",
|
||||
"sega-genesis": "Sega Genesis",
|
||||
"sega-isgsm": "Sega ISG Selection Master",
|
||||
"sega-megaplay": "Sega Mega Play",
|
||||
"sega-megatech": "Sega Mega-Tech",
|
||||
@@ -1148,15 +1141,12 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"sg-1000": "Sega SG-1000",
|
||||
"sielectronics-y2": "SiElectronics System Y2",
|
||||
"sinclair-ql": "Sinclair QL",
|
||||
"sinclair-spectrum": "Sinclair ZX Spectrum",
|
||||
"sinclair-zx-spectrum-next": "ZX Spectrum Next",
|
||||
"sinclair-zx80-81": "Sinclair ZX80 and ZX81",
|
||||
"skin-deep": "Skin Deep",
|
||||
"smbx": "Super Mario Bros. X",
|
||||
"sms": "Sega Master System",
|
||||
"snk-neogeo-aes": "SNK Neo Geo AES",
|
||||
"snk-neogeo-mvs": "SNK Neo Geo MVS",
|
||||
"snk-ngp": "SNK Neo Geo Pocket",
|
||||
"snk-ngpc": "SNK Neo Geo Pocket Color",
|
||||
"soh": "The Legend of Zelda: Ocarina of Time",
|
||||
"sonic-1-2013": "Sonic the Hedgehog (2013)",
|
||||
@@ -1172,7 +1162,6 @@ SYSTEM_NAMES: dict[str, str] = {
|
||||
"strife": "Strife",
|
||||
"sunplus-native32": "Sunplus Native32",
|
||||
"sunplus-spmp8000": "Sunplus SPMP8000",
|
||||
"super-famicom": "Nintendo Super Famicom",
|
||||
"super-kaneko-nova": "Kaneko Super Nova System",
|
||||
"super-mario-war": "Super Mario War game",
|
||||
"superacan": "Funtech Super A'Can",
|
||||
@@ -1278,7 +1267,6 @@ SYSTEM_PARENTS: dict[str, tuple[str, str]] = {
|
||||
# SNK
|
||||
"ngpc": ("SNK", "Neo Geo Pocket"),
|
||||
"snk-ngpc": ("SNK", "Neo Geo Pocket"),
|
||||
"neo-geo-pocket-color": ("SNK", "Neo Geo Pocket"),
|
||||
"snk-neogeo-aes": ("SNK", "Neo Geo"),
|
||||
"snk-neogeo-mvs": ("SNK", "Neo Geo"),
|
||||
# Sega. The VMU is the Dreamcast's memory card, its images sit there.
|
||||
|
||||
Reference in new issue
Block a user