mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 12:33:53 -06:00
feat: bind retrobat switch portable folders
RetroBat's generators create user/ beside yuzu.exe and eden.exe and portable/ beside Ryujinx.exe, which the emulators read in place of %APPDATA% (PORTABLE_DIR, Ryujinx AppDataManager.cs:12, 60). Their keys now go below emulators/<key>/.
This commit is contained in:
1 parent
7e22c38113
commit
111a93440f
6 files changed
+100
-26
No files matched your search
@@ -63,6 +63,7 @@ files:
|
||||
standalone_directories:
|
||||
- "$XDG_DATA_HOME/eden"
|
||||
- "$HOME/.local/share/eden"
|
||||
- "PORTABLE_DIR"
|
||||
data_root:
|
||||
windows:
|
||||
path: "%APPDATA%/eden"
|
||||
|
||||
@@ -19,6 +19,7 @@ mode: standalone
|
||||
standalone_directories:
|
||||
- "$XDG_CONFIG_HOME/Ryujinx"
|
||||
- "$HOME/.config/Ryujinx"
|
||||
- "DefaultPortableDir"
|
||||
data_root:
|
||||
windows:
|
||||
path: "%APPDATA%/Ryujinx"
|
||||
|
||||
@@ -59,6 +59,7 @@ files:
|
||||
standalone_directories:
|
||||
- "$XDG_DATA_HOME/yuzu"
|
||||
- "$HOME/.local/share/yuzu"
|
||||
- "PORTABLE_DIR"
|
||||
data_root:
|
||||
windows:
|
||||
path: "%APPDATA%/yuzu"
|
||||
|
||||
+27
-2
@@ -4971,17 +4971,42 @@ launchers:
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"citron\")>/user"
|
||||
passes_to: PORTABLE_DIR, the user folder beside citron.exe
|
||||
passes_to: PORTABLE_DIR, the portable folder beside citron.exe
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Citron.Generator.cs:25, 29-30"
|
||||
- emulator: eden
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"eden\")>/user"
|
||||
passes_to: PORTABLE_DIR, the portable folder beside eden.exe
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Eden.Generator.cs:28, 35-36"
|
||||
- emulator: ryujinx
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"ryujinx\")>/portable"
|
||||
passes_to: DefaultPortableDir, the portable folder beside Ryujinx.exe
|
||||
fails_when_missing: false
|
||||
depends_on_option: unless saves/switch/ryujinx/portable exists, passed with -r
|
||||
source_ref: "emulatorLauncher/Generators/Ryujinx.Generator.cs:31, 73-75"
|
||||
- emulator: shadps4
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"shadps4\")>/user"
|
||||
passes_to: PORTABLE_DIR, the user folder beside shadPS4.exe
|
||||
passes_to: PORTABLE_DIR, the portable folder beside shadPS4.exe
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/ShadPS4.Generator.cs:29, 158-160"
|
||||
- emulator: yuzu
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"yuzu\")>/user"
|
||||
passes_to: PORTABLE_DIR, the portable folder beside yuzu.exe
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Yuzu.Generator.cs:24, 33-34"
|
||||
- emulator: bizhawk
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
|
||||
@@ -32,6 +32,7 @@ SOURCE_FILES = (
|
||||
f"{GENERATORS}/DosBoxPure.Generator.cs",
|
||||
f"{GENERATORS}/DosBoxStaging.Generator.cs",
|
||||
f"{GENERATORS}/Duckstation.Generator.cs",
|
||||
f"{GENERATORS}/Eden.Generator.cs",
|
||||
f"{GENERATORS}/Eka2l1.Generator.cs",
|
||||
f"{GENERATORS}/Fbneo.Generator.cs",
|
||||
f"{GENERATORS}/Flycast.Generator.cs",
|
||||
@@ -57,6 +58,7 @@ SOURCE_FILES = (
|
||||
f"{GENERATORS}/Project64.Generator.cs",
|
||||
f"{GENERATORS}/Raine.Generator.cs",
|
||||
f"{GENERATORS}/Rpcs3.Generator.cs",
|
||||
f"{GENERATORS}/Ryujinx.Generator.cs",
|
||||
f"{GENERATORS}/SSF.Generator.cs",
|
||||
f"{GENERATORS}/ScummVm.Generator.cs",
|
||||
f"{GENERATORS}/ShadPS4.Generator.cs",
|
||||
@@ -68,6 +70,7 @@ SOURCE_FILES = (
|
||||
f"{GENERATORS}/Xroar.Generator.cs",
|
||||
f"{GENERATORS}/Yabasanshiro.Generator.cs",
|
||||
f"{GENERATORS}/Ymir.Generator.cs",
|
||||
f"{GENERATORS}/Yuzu.Generator.cs",
|
||||
f"{GENERATORS}/mGBA.Generator.cs",
|
||||
FEATURES,
|
||||
)
|
||||
@@ -2982,44 +2985,63 @@ def xroar(sources: dict[str, Source]) -> list[Record]:
|
||||
return _covered(src, records)
|
||||
|
||||
|
||||
# Generators that create a portable user folder beside the emulator's binary,
|
||||
# and the emulator each one starts: the folder AppConfig.GetFullPath gives.
|
||||
# Generators that start an emulator with a portable data folder beside its
|
||||
# binary: (generator, emulator key, binary, the code's name for the folder).
|
||||
PORTABLE_USERS = (
|
||||
("Citron.Generator.cs", "citron", "citron.exe"),
|
||||
("ShadPS4.Generator.cs", "shadps4", "shadPS4.exe"),
|
||||
("Citron.Generator.cs", "citron", "citron.exe", "PORTABLE_DIR"),
|
||||
("Eden.Generator.cs", "eden", "eden.exe", "PORTABLE_DIR"),
|
||||
("Ryujinx.Generator.cs", "ryujinx", "Ryujinx.exe", "DefaultPortableDir"),
|
||||
("ShadPS4.Generator.cs", "shadps4", "shadPS4.exe", "PORTABLE_DIR"),
|
||||
("Yuzu.Generator.cs", "yuzu", "yuzu.exe", "PORTABLE_DIR"),
|
||||
)
|
||||
_EMULATOR_FOLDER = (
|
||||
r"GetEmulatorPathAndExe\(emulator, out string path, out string exe, \"[^\"]+\"\)"
|
||||
r"|string path = AppConfig\.GetFullPath\(emulator\);"
|
||||
r"|string path = AppConfig\.GetFullPath\((?:emulator(?:\.Replace\(\"-\", \" \"\))?"
|
||||
r"|\"\w+\")\);"
|
||||
)
|
||||
_PORTABLE_FOLDER = r'string (userFolder|setupPath) = Path\.Combine\(path, "(\w+)"\);'
|
||||
# Ryujinx's generator hands --root-data-dir saves/switch/ryujinx/portable
|
||||
# instead when that folder exists.
|
||||
_ALTERNATE_ROOT = (
|
||||
r'string portablePath = Path\.Combine\(AppConfig\.GetFullPath\("saves"\), "switch", '
|
||||
r'"ryujinx", "portable"\);'
|
||||
)
|
||||
|
||||
|
||||
def portable_users(sources: dict[str, Source]) -> list[Record]:
|
||||
"""The portable user folder a generator creates beside the binary.
|
||||
"""The portable data folder a generator gives an emulator beside its binary.
|
||||
|
||||
The emulator folder comes from AppConfig.GetFullPath(emulator), and the
|
||||
generator creates <folder>/user before launching: the emulator then
|
||||
keeps its data there (keys/, sys_modules/) in place of %APPDATA%.
|
||||
The emulator folder comes from AppConfig.GetFullPath, and the generator
|
||||
creates or configures <folder>/user (<folder>/portable for Ryujinx)
|
||||
before launching: the emulator then keeps its data there (keys/,
|
||||
sys_modules/, system/) in place of %APPDATA%.
|
||||
"""
|
||||
records = []
|
||||
for name, emulator, binary in PORTABLE_USERS:
|
||||
for name, emulator, binary, handle in PORTABLE_USERS:
|
||||
src = sources[f"{GENERATORS}/{name}"]
|
||||
found = src.find(_EMULATOR_FOLDER, f"{emulator} folder")
|
||||
user = src.find(r'string userFolder = Path\.Combine\(path, "(\w+)"\);', "user folder")
|
||||
create = src.find(
|
||||
r"Directory\.CreateDirectory\(userFolder\)", "user folder creation", user.end()
|
||||
)
|
||||
folder = src.find(_PORTABLE_FOLDER, "portable folder")
|
||||
spans = [src.lines(found.start(), found.end()), src.lines(folder.start(), folder.end())]
|
||||
if folder.group(1) == "userFolder":
|
||||
create = src.find(
|
||||
r"Directory\.CreateDirectory\(userFolder\)", "user folder creation", folder.end()
|
||||
)
|
||||
spans[-1] = src.lines(folder.start(), create.end())
|
||||
depends = None
|
||||
alternate = re.search(_ALTERNATE_ROOT, src.text)
|
||||
if alternate:
|
||||
spans.append(src.lines(alternate.start(), alternate.end()))
|
||||
depends = "unless saves/switch/ryujinx/portable exists, passed with -r"
|
||||
records.append(_record(
|
||||
emulator,
|
||||
"standalone",
|
||||
"passes_path",
|
||||
[],
|
||||
source_ref((src.path, [
|
||||
src.lines(found.start(), found.end()), src.lines(user.start(), create.end()),
|
||||
])),
|
||||
search_dir=f'<AppConfig.GetFullPath("{emulator}")>/{user.group(1)}',
|
||||
passes_to=f"PORTABLE_DIR, the user folder beside {binary}",
|
||||
source_ref((src.path, spans)),
|
||||
search_dir=f'<AppConfig.GetFullPath("{emulator}")>/{folder.group(2)}',
|
||||
passes_to=f"{handle}, the portable folder beside {binary}",
|
||||
fails_when_missing=False,
|
||||
depends_on_option=depends,
|
||||
))
|
||||
return records
|
||||
|
||||
|
||||
@@ -176,12 +176,28 @@ class APortableUserFolder(unittest.TestCase):
|
||||
}
|
||||
"""
|
||||
|
||||
RYUJINX = """
|
||||
public override System.Diagnostics.ProcessStartInfo Generate(string system, string emulator, string core, string rom, string playersControllers, ScreenResolution resolution)
|
||||
{
|
||||
string path = AppConfig.GetFullPath("ryujinx");
|
||||
string portablePath = Path.Combine(AppConfig.GetFullPath("saves"), "switch", "ryujinx", "portable");
|
||||
string setupPath = Path.Combine(path, "portable");
|
||||
}
|
||||
"""
|
||||
|
||||
def sources(self) -> dict[str, rl.Source]:
|
||||
def source(ref: str, text: str) -> rl.Source:
|
||||
return rl.Source(ref, textwrap.dedent(text).lstrip("\n"))
|
||||
|
||||
def yuzu_like(exe: str) -> str:
|
||||
return self.CITRON.replace("citron.exe", exe)
|
||||
|
||||
return {
|
||||
f"{rl.GENERATORS}/Citron.Generator.cs": rl.Source(
|
||||
"c", textwrap.dedent(self.CITRON).lstrip("\n")),
|
||||
f"{rl.GENERATORS}/ShadPS4.Generator.cs": rl.Source(
|
||||
"s", textwrap.dedent(self.SHADPS4).lstrip("\n")),
|
||||
f"{rl.GENERATORS}/Citron.Generator.cs": source("c", self.CITRON),
|
||||
f"{rl.GENERATORS}/Eden.Generator.cs": source("e", yuzu_like("eden.exe")),
|
||||
f"{rl.GENERATORS}/Ryujinx.Generator.cs": source("r", self.RYUJINX),
|
||||
f"{rl.GENERATORS}/ShadPS4.Generator.cs": source("s", self.SHADPS4),
|
||||
f"{rl.GENERATORS}/Yuzu.Generator.cs": source("y", yuzu_like("yuzu.exe")),
|
||||
}
|
||||
|
||||
def test_each_generator_gives_its_user_folder(self):
|
||||
@@ -189,7 +205,15 @@ class APortableUserFolder(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
[(r["emulator"], r["search_dir"], r["source_ref"]) for r in found],
|
||||
[("citron", '<AppConfig.GetFullPath("citron")>/user', "c:3, 7-8"),
|
||||
("shadps4", '<AppConfig.GetFullPath("shadps4")>/user', "s:3, 8-10")],
|
||||
("eden", '<AppConfig.GetFullPath("eden")>/user', "e:3, 7-8"),
|
||||
("ryujinx", '<AppConfig.GetFullPath("ryujinx")>/portable', "r:3-5"),
|
||||
("shadps4", '<AppConfig.GetFullPath("shadps4")>/user', "s:3, 8-10"),
|
||||
("yuzu", '<AppConfig.GetFullPath("yuzu")>/user', "y:3, 7-8")],
|
||||
)
|
||||
ryujinx = found[2]
|
||||
self.assertEqual(ryujinx["passes_to"], "DefaultPortableDir, the portable folder beside Ryujinx.exe")
|
||||
self.assertEqual(
|
||||
ryujinx["depends_on_option"], "unless saves/switch/ryujinx/portable exists, passed with -r"
|
||||
)
|
||||
|
||||
def test_the_user_folder_binds_below_the_emulator_folder(self):
|
||||
|
||||
Reference in new issue
Block a user