psp: detect installed PS1 games (incl. Category Lite folders)
PS1 EBOOTs install as PSP/GAME/{category}/{GAME_ID}/EBOOT.PBP, which the
PSP index ignored (it only indexed ISO games/videos), so the app never
marked them 'on PSP'. Index homebrew EBOOTs by folder id + embedded title,
match PS1 library items against them, and make 'Delete from PSP' remove the
whole game folder.
This commit is contained in:
+46
-1
@@ -3604,6 +3604,7 @@ class MainWindow(QMainWindow):
|
||||
self._psp_root = ""
|
||||
self._psp_index = {}
|
||||
self._psp_paths = {}
|
||||
self._psp_homebrew = []
|
||||
self._pending_umd_dump = None
|
||||
self._auto_rename_umd = None
|
||||
self._library_threads = []
|
||||
@@ -4149,6 +4150,7 @@ class MainWindow(QMainWindow):
|
||||
inventory = self.psp_page.inventory() or {}
|
||||
self._psp_index = psp.build_index(inventory)
|
||||
self._psp_paths = {"raw": {}, "norm": {}}
|
||||
self._psp_homebrew = list(inventory.get("homebrew", []))
|
||||
for group in ("games", "videos"):
|
||||
for it in inventory.get(group, []):
|
||||
stem = Path(it["name"]).stem
|
||||
@@ -4162,6 +4164,7 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
self._psp_index = {}
|
||||
self._psp_paths = {}
|
||||
self._psp_homebrew = []
|
||||
if hasattr(self, "details_panel"):
|
||||
self.details_panel.set_copy_available(bool(self._psp_root))
|
||||
current = getattr(self, "_current_item", None)
|
||||
@@ -4180,7 +4183,20 @@ class MainWindow(QMainWindow):
|
||||
if stem.lower() in self._psp_index.get("raw", set()):
|
||||
return True
|
||||
norm = matcher.normalize_name(stem)
|
||||
return bool(norm) and norm in self._psp_index.get("names", set())
|
||||
if norm and norm in self._psp_index.get("names", set()):
|
||||
return True
|
||||
if item.get("system") == "ps1":
|
||||
# PS1 EBOOTs install as PSP/GAME/{category}/{GAME_ID}/EBOOT.PBP, so
|
||||
# match the source game-folder id (or the embedded title) against
|
||||
# the homebrew index (which includes Category Lite subfolders).
|
||||
game_id = Path(item.get("path") or "").parent.name.strip().lower()
|
||||
if game_id and game_id in self._psp_index.get("homebrew_ids", set()):
|
||||
return True
|
||||
if stem.lower() in self._psp_index.get("homebrew_names", set()):
|
||||
return True
|
||||
if norm and norm in self._psp_index.get("homebrew_names", set()):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _psp_dot_icon(self):
|
||||
icon = getattr(self, "_psp_icon", None)
|
||||
@@ -4371,6 +4387,35 @@ class MainWindow(QMainWindow):
|
||||
QMessageBox.information(self, "Not on PSP", "That disc is not installed on the PSP.")
|
||||
return
|
||||
stem = Path(item.get("canonical") or item.get("name") or "").stem
|
||||
if item.get("system") == "ps1":
|
||||
# PS1 EBOOTs live as PSP/GAME/{category}/{GAME_ID}/EBOOT.PBP; delete
|
||||
# the whole game folder, matched by the source folder id (or title).
|
||||
game_id = Path(item.get("path") or "").parent.name.strip().lower()
|
||||
hb = self._psp_homebrew or []
|
||||
if game_id:
|
||||
matches = [h for h in hb if (h.get("id") or "").strip().lower() == game_id]
|
||||
else:
|
||||
matches = [h for h in hb if Path(h.get("name") or "").stem.lower() == stem.lower()]
|
||||
if not matches:
|
||||
QMessageBox.warning(self, "Not found", f"Could not find the installed copy on the PSP:\n{stem}")
|
||||
return
|
||||
name = item.get("title_override") or item.get("canonical") or item.get("name") or stem
|
||||
preview = "\n".join(str(Path(m["path"]).parent) for m in matches[:5])
|
||||
res = QMessageBox.question(
|
||||
self, "Delete from PSP",
|
||||
f"Delete this game folder from the PSP?\n\n{name}\n\n{preview}",
|
||||
QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel,
|
||||
)
|
||||
if res != QMessageBox.Yes:
|
||||
return
|
||||
failed = 0
|
||||
for m in matches:
|
||||
if not transfers.remove_path(Path(m["path"]).parent):
|
||||
failed += 1
|
||||
if failed:
|
||||
QMessageBox.warning(self, "Delete incomplete", f"{failed} folder(s) could not be deleted.")
|
||||
self._refresh_psp()
|
||||
return
|
||||
matches = list(self._psp_paths.get("raw", {}).get(stem.lower(), []))
|
||||
if not matches:
|
||||
n = matcher.normalize_name(stem)
|
||||
|
||||
+19
-3
@@ -236,8 +236,11 @@ def list_installed(root):
|
||||
def build_index(inventory):
|
||||
"""Build a lookup index for matching library discs against the PSP.
|
||||
|
||||
Returns ``{"raw": set, "names": set}`` where ``raw`` holds lowercase ISO
|
||||
stems (exact filename match) and ``names`` holds fuzzy-normalized stems.
|
||||
Returns ``{"raw", "names", "homebrew_ids", "homebrew_names"}`` where
|
||||
``raw`` holds lowercase ISO stems (exact filename match), ``names`` holds
|
||||
fuzzy-normalized stems, and the homebrew keys index ``PSP/GAME/**/EBOOT.PBP``
|
||||
(homebrew + PS1 Classics, including Category Lite subfolders) by folder id
|
||||
and embedded title.
|
||||
"""
|
||||
raw, names = set(), set()
|
||||
for group in ("games", "videos"):
|
||||
@@ -247,7 +250,20 @@ def build_index(inventory):
|
||||
norm = matcher.normalize_name(stem)
|
||||
if norm:
|
||||
names.add(norm)
|
||||
return {"raw": raw, "names": names}
|
||||
|
||||
hb_ids, hb_names = set(), set()
|
||||
for it in (inventory or {}).get("homebrew", []):
|
||||
ident = str(it.get("id") or "").strip().lower()
|
||||
if ident:
|
||||
hb_ids.add(ident)
|
||||
stem = Path(it.get("name") or "").stem.strip().lower()
|
||||
if stem:
|
||||
hb_names.add(stem)
|
||||
norm = matcher.normalize_name(Path(it.get("name") or "").stem)
|
||||
if norm:
|
||||
hb_names.add(norm)
|
||||
return {"raw": raw, "names": names,
|
||||
"homebrew_ids": hb_ids, "homebrew_names": hb_names}
|
||||
|
||||
|
||||
def find_umd_iso(root):
|
||||
|
||||
Reference in New Issue
Block a user