ps1: preview EBOOT icon/background in the PS1 tab before converting
Selecting a pending disc in the PS1 tab now shows a live preview of the ICON0 (144x80 XMB icon) and PIC1 (480x272 launch background) that the converter would embed, fetched asynchronously so the UI stays responsive. Converted discs/EBOOTs show an 'already converted' notice, and ps1_art now falls back to a name-derived cache key when a disc has no serial.
This commit is contained in:
+2
-1
@@ -861,8 +861,9 @@ def ps1_art(title, release_id, timeout=10):
|
||||
sources (libretro, ScreenScraper, IGDB, Wikipedia). Returns
|
||||
``(None, None)`` when no art can be produced.
|
||||
"""
|
||||
key = release_id or stable_key(title)
|
||||
try:
|
||||
path = fetch_cover(title, release_id, "ps1", timeout=timeout)
|
||||
path = fetch_cover(title, key, "ps1", timeout=timeout)
|
||||
except Exception: # noqa: BLE001
|
||||
return None, None
|
||||
if path is None:
|
||||
|
||||
+116
-1
@@ -3365,6 +3365,27 @@ class Ps1ScanWorker(QObject):
|
||||
self.failed.emit(str(exc))
|
||||
|
||||
|
||||
class Ps1PreviewWorker(QObject):
|
||||
"""Fetch a disc's cover art and build the EBOOT icon/background preview."""
|
||||
|
||||
result = Signal(int, str, object, object) # gen, game_id, icon0 bytes, pic1 bytes
|
||||
finished = Signal()
|
||||
|
||||
def __init__(self, gen, title, game_id):
|
||||
super().__init__()
|
||||
self.gen = gen
|
||||
self.title = title
|
||||
self.game_id = game_id
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
icon0, pic1 = covers.ps1_art(self.title, self.game_id)
|
||||
except Exception: # noqa: BLE001
|
||||
icon0, pic1 = None, None
|
||||
self.result.emit(self.gen, self.game_id, icon0, pic1)
|
||||
self.finished.emit()
|
||||
|
||||
|
||||
class Ps1Page(QWidget):
|
||||
"""PS1 tab: list raw source discs, converted EBOOTs and PSN games."""
|
||||
|
||||
@@ -3377,6 +3398,9 @@ class Ps1Page(QWidget):
|
||||
self._entries = []
|
||||
self._thread = None
|
||||
self._worker = None
|
||||
self._preview_gen = 0
|
||||
self._preview_threads = []
|
||||
self._preview_workers = []
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
bar = QHBoxLayout()
|
||||
@@ -3396,7 +3420,98 @@ class Ps1Page(QWidget):
|
||||
self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
|
||||
self.table.verticalHeader().setVisible(False)
|
||||
self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
|
||||
layout.addWidget(self.table, 1)
|
||||
self.table.itemSelectionChanged.connect(self._on_preview_changed)
|
||||
|
||||
self.preview_title = QLabel("Select a disc to preview its XMB look.")
|
||||
self.preview_title.setWordWrap(True)
|
||||
self.preview_title.setStyleSheet("font-weight: bold;")
|
||||
self.preview_icon0 = QLabel()
|
||||
self.preview_icon0.setAlignment(Qt.AlignCenter)
|
||||
self.preview_icon0.setFixedSize(288, 160)
|
||||
self.preview_icon0.setStyleSheet("background: #14151a; border: 1px solid #333; color: #888;")
|
||||
self.preview_pic1 = QLabel()
|
||||
self.preview_pic1.setAlignment(Qt.AlignCenter)
|
||||
self.preview_pic1.setFixedSize(480, 272)
|
||||
self.preview_pic1.setStyleSheet("background: #14151a; border: 1px solid #333; color: #888;")
|
||||
|
||||
preview = QWidget()
|
||||
pv = QVBoxLayout(preview)
|
||||
pv.setContentsMargins(8, 0, 0, 0)
|
||||
pv.addWidget(QLabel("<b>Preview</b>"))
|
||||
pv.addWidget(self.preview_title)
|
||||
pv.addWidget(QLabel("ICON0 — XMB icon"))
|
||||
pv.addWidget(self.preview_icon0)
|
||||
pv.addWidget(QLabel("PIC1 — launch background"))
|
||||
pv.addWidget(self.preview_pic1)
|
||||
pv.addStretch(1)
|
||||
|
||||
splitter = QSplitter(Qt.Horizontal)
|
||||
splitter.addWidget(self.table)
|
||||
splitter.addWidget(preview)
|
||||
splitter.setStretchFactor(0, 1)
|
||||
layout.addWidget(splitter, 1)
|
||||
|
||||
def _on_preview_changed(self):
|
||||
row = self.table.currentRow()
|
||||
if row < 0 or row >= len(self._entries):
|
||||
self._reset_preview("Select a disc to preview its XMB look.")
|
||||
return
|
||||
e = self._entries[row]
|
||||
if e["kind"] != "disc":
|
||||
self._reset_preview("This game is already converted.")
|
||||
return
|
||||
if e.get("status") == "converted":
|
||||
self._reset_preview("This disc has already been converted.")
|
||||
return
|
||||
self.preview_title.setText(e["name"])
|
||||
self.preview_icon0.setPixmap(QPixmap())
|
||||
self.preview_icon0.setText("Loading…")
|
||||
self.preview_pic1.setPixmap(QPixmap())
|
||||
self.preview_pic1.setText("Loading…")
|
||||
self._preview_gen += 1
|
||||
self._start_preview(self._preview_gen, e["name"], e.get("serial") or "")
|
||||
|
||||
def _start_preview(self, gen, title, game_id):
|
||||
worker = Ps1PreviewWorker(gen, title, game_id)
|
||||
thread = QThread(self)
|
||||
worker.moveToThread(thread)
|
||||
thread.started.connect(worker.run)
|
||||
worker.result.connect(self._on_preview_result)
|
||||
worker.finished.connect(thread.quit)
|
||||
worker.finished.connect(worker.deleteLater)
|
||||
thread.finished.connect(thread.deleteLater)
|
||||
thread.start()
|
||||
self._preview_threads.append(thread)
|
||||
self._preview_workers.append(worker)
|
||||
|
||||
def _on_preview_result(self, gen, game_id, icon0, pic1):
|
||||
if gen != self._preview_gen:
|
||||
return
|
||||
self.preview_icon0.setText("")
|
||||
self.preview_pic1.setText("")
|
||||
if icon0:
|
||||
pm = QPixmap()
|
||||
pm.loadFromData(icon0)
|
||||
self.preview_icon0.setPixmap(
|
||||
pm.scaled(self.preview_icon0.width(), self.preview_icon0.height(),
|
||||
Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
||||
else:
|
||||
self.preview_icon0.setText("No art found")
|
||||
if pic1:
|
||||
pm = QPixmap()
|
||||
pm.loadFromData(pic1)
|
||||
self.preview_pic1.setPixmap(
|
||||
pm.scaled(self.preview_pic1.width(), self.preview_pic1.height(),
|
||||
Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
||||
else:
|
||||
self.preview_pic1.setText("No art found — the default icon will be used")
|
||||
|
||||
def _reset_preview(self, message):
|
||||
self.preview_title.setText(message)
|
||||
self.preview_icon0.setPixmap(QPixmap())
|
||||
self.preview_icon0.setText("")
|
||||
self.preview_pic1.setPixmap(QPixmap())
|
||||
self.preview_pic1.setText("")
|
||||
|
||||
def set_dirs(self, ps1_dir, output_dir):
|
||||
self._ps1_dir = ps1_dir
|
||||
|
||||
Reference in New Issue
Block a user