Skip to content

Instantly share code, notes, and snippets.

@Gemba
Created October 5, 2023 05:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gemba/410710b53be04a9de16d190b988eca56 to your computer and use it in GitHub Desktop.
Save Gemba/410710b53be04a9de16d190b988eca56 to your computer and use it in GitHub Desktop.
Creates a cross-reference between RetroPie's ROM folders to emulators using those and vice-versa.
#! /usr/bin/env python3
# Creates two JSON files as cross-reference between RetroPie's ROM folders and
# emulators.
#
# romfolder_to_emus.json: mapping which emulators (values) use which romfolder
# (keys)
#
# emu_to_romfolders.json: mapping which romfolders (values) are used by which
# emulator (keys)
#
# Does not include the RetroPie-Setup/ext/ folders.
#
# (c) 2023 Gemba @ GitHub, license MIT
import json
import re
from itertools import chain
from pathlib import Path
RP_SETUP = Path.home() / "RetroPie-Setup"
emus = sorted(RP_SETUP.rglob("emulators/*.sh"))
lr = sorted(RP_SETUP.rglob("libretrocores/*.sh"))
ports = sorted(RP_SETUP.rglob("ports/*.sh"))
ml = RP_SETUP.rglob("supplementary/moonlight.sh")
scriptmodules = chain(emus, lr, ports, ml)
xref = {}
for s in scriptmodules:
with open(s) as fh:
lines = fh.readlines()
folders = set()
rp_module_id = None
multiline = False
for line in lines:
if 'rp_module_id' in line:
rp_module_id = line.split("=")[-1].replace('"', '').strip()
# filter advmame-1.5.4, love-0.10.2, ...
m = re.search(r"^.+-\d+\..+$", rp_module_id)
if rp_module_id == "retroarch" or m:
rp_module_id = None
break
if 'addSystem "' in line or 'local system="' in line:
_fd = line.split('"')[1].strip()
if '$' not in _fd:
folders.add(_fd)
if 'for system in ' in line:
if '$' in line:
continue
line = line.replace('for system in ', '')
line = line[0:line.find(';')]
_fd = [f.replace('"', '').strip()
for f in line.split(" ") if f]
for f in _fd:
folders.add(f)
if 'local systems=' in line or multiline:
if line.find('(') > 0 and line.find(')') > 0:
_fd = line.split(
'=')[-1].replace('(', '',).replace(')', '').split(" ")
for f in _fd:
folders.add(f.strip())
elif line.find('(') > 0:
multiline = True
# catch folder on same line
f = line.split('(')[1].strip()
if f:
folders.add(f)
elif multiline:
f = line.strip().replace(')', '').replace('"', '')
if f:
folders.add(f)
if line.find(')') > 0:
multiline = False
if rp_module_id:
if not folders:
folders.add("ports")
xref[rp_module_id] = list(sorted(folders))
# correct scriptmodule "inheritance"
for emu, folders in xref.items():
if emu in ["dosbox-sdl2", "dosbox-staging"]:
xref[emu] = xref["dosbox"]
elif emu == "lr-mess2016":
xref[emu] = xref["lr-mess"]
elif emu == "lr-mame2003-plus":
xref[emu] = xref["lr-mame2003"]
elif emu == "scummvm-sdl1":
xref[emu] = xref["scummvm"]
# "invert" the dictonary
inv_xref = {}
for emu, folders in xref.items():
for f in folders:
if f not in inv_xref:
inv_xref[f] = list()
inv_xref[f].append(emu)
for folder, emus in inv_xref.items():
inv_xref[folder] = sorted(emus)
with open("emu_to_romfolders.json", "w") as outfile:
json.dump(xref, outfile, indent=4, sort_keys=True)
with open("romfolder_to_emus.json", "w") as outfile:
json.dump(inv_xref, outfile, indent=4, sort_keys=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment