From 7ced173c1764fa53d7c340ee59010c544cca471f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 23:08:45 +0200 Subject: [PATCH] UI: List PS1 EBOOTs, with their own disc ID The game browser left out EBOOTs with the PS1 category, which couldn't run. Now they're listed where the Media Engine can be emulated (Memory::CanCreateMESpace). And as a PS1 game's PARAM.SFO has no DISC_TOTAL, the browser took it for homebrew and gave it a made-up ID (SCUS00580 for Crash Bandicoot's SCUS94900): its own is kept now. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/MemMap.cpp | 1 + Core/MemMap.h | 8 ++++++++ UI/GameBrowser.cpp | 4 +++- UI/GameInfoCache.cpp | 4 +++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 69ded52416..2bc1df8e6a 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -689,6 +689,7 @@ AddressSpace *CreateMESpace() { _dbg_assert_(base != nullptr && g_meSpace.base == nullptr); #if defined(MASKED_PSP_MEMORY) || defined(NO_MMAP) // TODO: Masking would fold the eDRAM mirrors onto the scratchpad and boot page addresses. + static_assert(!CanCreateMESpace()); return nullptr; #else size_t span = 0; diff --git a/Core/MemMap.h b/Core/MemMap.h index 63307b937c..a32b7ae773 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -377,6 +377,14 @@ extern AddressSpace g_mainSpace; // as in g_mainSpace. Returns null if this platform can't map memory twice. Only for a boot that runs // the ME; Shutdown() (and so Reinit()) destroys it. AddressSpace *CreateMESpace(); +// Whether this platform can have one (not with masked memory, or without mmap). +constexpr bool CanCreateMESpace() { +#if defined(MASKED_PSP_MEMORY) || defined(NO_MMAP) + return false; +#else + return true; +#endif +} void DestroyMESpace(); void WriteOrException_U8(const u8 data, const u32 address); diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index 486edcae11..4a41492f15 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -38,6 +38,7 @@ #include "Core/Util/RecentFiles.h" #include "Core/HLE/sceCtrl.h" #include "Core/ELF/PBPReader.h" +#include "Core/MemMap.h" #include "Core/Util/VideoPlayer.h" #include "UI/GameBrowser.h" @@ -986,7 +987,8 @@ static bool IsValidPBP(const Path &path, bool allowHomebrew) { if (!allowHomebrew && sfo.GetValueString("DISC_ID").empty()) return false; - if (sfo.GetValueString("CATEGORY") == "ME") + // PS1 games, which need the Media Engine. + if (sfo.GetValueString("CATEGORY") == "ME" && !Memory::CanCreateMESpace()) return false; return true; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 0cde31802f..ebde4182cd 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -634,8 +634,10 @@ public: info_->paramSFO.ReadSFO(sfoData); info_->ParseParamSFO(fileType); - // Assuming PSP_PBP_DIRECTORY without ID or with disc_total < 1 in GAME dir must be homebrew + // Assuming PSP_PBP_DIRECTORY without ID or with disc_total < 1 in GAME dir must be homebrew. + // Not a PS1 game, whose PARAM.SFO has no DISC_TOTAL. if ((info_->id.empty() || !info_->disc_total) + && info_->paramSFO.GetValueString("CATEGORY") != "ME" && gamePath_.FilePathContainsNoCase("PSP/GAME/") && fileType == IdentifiedFileType::PSP_PBP_DIRECTORY) { info_->id = g_paramSFO.GenerateFakeID(gamePath_);