diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 3f76185ec8..e1caa22745 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -166,7 +166,18 @@ enum class DisableHLEFlags : int { sceCcc = (1 << 7), // character conversion library. // Swaps in flash0:/kd/libmp4.prx and mp4msv.prx, which then decode through our sceAudiocodec. sceMp4 = (1 << 8), - Count = 9, + // Small leaf libraries games carry on the disc themselves - see AlwaysDisableHLEFlags. None of + // them is in any firmware dump, so the game's own copy is the only one there is, and none + // imports anything we don't already have. + sceDeflt = (1 << 9), + sceAdler = (1 << 10), + sceMd5 = (1 << 11), + sceSha256 = (1 << 12), + sceMt19937 = (1 << 13), + sceSfmt19937 = (1 << 14), + sceHeap = (1 << 15), + sceParseUri = (1 << 16), + Count = 17, // TODO: Some of the networking libraries may be interesting candidates, like HTTP. }; ENUM_CLASS_BITOPS(DisableHLEFlags); diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 206b9054f7..ec60ecf29a 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -43,6 +43,8 @@ #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceKernelModule.h" +#include "Core/HLE/sceFont.h" +#include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/HLE.h" enum { @@ -141,8 +143,6 @@ static const HLEModuleMeta g_moduleMeta[] = { {"sceNetAdhocctl_Library"}, {"sceNetIfhandle_Service"}, {"sceSsl_Module"}, - {"sceDEFLATE_Library"}, - {"sceMD5_Library"}, {"sceMemab"}, // Underlying AdHoc crypto library {"sceAvcodec_driver"}, {"sceAudiocodec_Driver"}, @@ -160,7 +160,17 @@ static const HLEModuleMeta g_moduleMeta[] = { {"sceMp4_library", "sceMp4", DisableHLEFlags::sceMp4}, {"mp4msv_module", "mp4msv", DisableHLEFlags::sceMp4}, {"SceParseHTTPheader_Library", "sceParseHttp", DisableHLEFlags::sceParseHttp}, - {"SceParseURI_Library"}, + {"SceParseURI_Library", "sceParseUri", DisableHLEFlags::sceParseUri}, + // Leaf libraries games carry on the disc. Module names and export library names read off the + // copies on real discs with --re-module disc0:/...; all but sceHeap import nothing at all, and + // sceHeap only Kernel_Library and ThreadManForUser. + {"sceDEFLATE_Library", "sceDeflt", DisableHLEFlags::sceDeflt}, + {"sceADLER32_Library", "sceAdler", DisableHLEFlags::sceAdler}, + {"sceMD5_Library", "sceMd5", DisableHLEFlags::sceMd5}, + {"sceSHA256_Library", "sceSha256", DisableHLEFlags::sceSha256}, + {"sceMT19937_Library", "sceMt19937", DisableHLEFlags::sceMt19937}, + {"sceSfmt19937_Library", "sceSfmt19937", DisableHLEFlags::sceSfmt19937}, + {"sceHeap_Library", "sceHeap", DisableHLEFlags::sceHeap}, // Guessing these names {"sceJpeg", "sceJpeg"}, {"sceJpeg_library", "sceJpeg"}, @@ -200,7 +210,25 @@ DisableHLEFlags AlwaysDisableHLEFlags() { // // PSMF testing issue: #20200 // sceCcc is simply a character conversion library, zero deps. If available we just load it. - return DisableHLEFlags::scePsmf | DisableHLEFlags::scePsmfPlayer | DisableHLEFlags::sceCcc; + // sceDeflt is zip format decompression. + // sceSmft19937 and sceMt19937 are random number generation. + // sceAdler, sceSha256, sceMd5 are hashes. + // sceHeap is a memory allocator wrapper. + // + // All these are found in game discs, and are basically dependency-less libraries that we + // can just run as-is, no need for HLE. Games always ship these if they use them. + // + // sceFont is the odd one out: the module is on the disc like the others, but it reads its fonts + // from flash0:/font, so it is only usable with a firmware dump installed - see + // CheckDisableHLEAvailability, which puts the HLE back when those fonts aren't there. + // + // sceParseUri and sceParseHttp are not here - those two are also in the firmware, and + // sceUtility can load them (modules 0x103 and 0x104), so unlike the rest a game may import them + // without carrying a copy. + return DisableHLEFlags::scePsmf | DisableHLEFlags::scePsmfPlayer | DisableHLEFlags::sceCcc | + DisableHLEFlags::sceDeflt | DisableHLEFlags::sceAdler | DisableHLEFlags::sceMd5 | + DisableHLEFlags::sceSha256 | DisableHLEFlags::sceMt19937 | DisableHLEFlags::sceSfmt19937 | + DisableHLEFlags::sceHeap | DisableHLEFlags::sceFont; } // Which modules we're HLE-ing is part of the machine's state, not a live setting: it's decided @@ -314,9 +342,22 @@ static void hleDelayResultFinish(u64 userdata, int cycleslate) { static void CheckDisableHLEAvailability() { g_unavailableDisableFlags = (DisableHLEFlags)0; + // The real libfont.prx a disc ships reads its fonts from flash0:/font and has nothing to fall + // back on, so without them it would render nothing at all. Our HLE does have a fallback - the + // fonts in assets - so keep it when the NAND set isn't there. Same question the HLE font loader + // asks itself, so the same answer: "the fonts this game's firmware would have had", not every + // font we know of, since an older game's firmware never had the later ones. + if (AlwaysDisableHLEFlags() & DisableHLEFlags::sceFont) { + if (!NandFontsComplete()) { + g_unavailableDisableFlags |= DisableHLEFlags::sceFont; + INFO_LOG(Log::HLE, "flash0:/font doesn't have this firmware's fonts - using the HLE sceFont rather than the disc's."); + } + } + if ((DisableHLEFlags)g_Config.iDisableHLE & DisableHLEFlags::sceMp4) { const Path kd = g_Config.nandRootDirectory / "flash0" / "kd"; - if (!File::Exists(kd / "libmp4.prx") || !File::Exists(kd / "mp4msv.prx")) { + if (!pspFileSystem.GetFileInfo("flash0:/kd/libmp4.prx").exists || + !pspFileSystem.GetFileInfo("flash0:/kd/mp4msv.prx").exists) { g_unavailableDisableFlags |= DisableHLEFlags::sceMp4; ERROR_LOG(Log::HLE, "Asked to run the real sceMp4, but %s doesn't have libmp4.prx and " "mp4msv.prx - keeping the HLE.", kd.c_str()); diff --git a/Core/HLE/sceAdler.h b/Core/HLE/sceAdler.h index 9acd6a2042..7bdc8b8c7e 100644 --- a/Core/HLE/sceAdler.h +++ b/Core/HLE/sceAdler.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceAdler is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceAdler(); diff --git a/Core/HLE/sceDeflt.h b/Core/HLE/sceDeflt.h index 8196ab8869..8c56066f21 100644 --- a/Core/HLE/sceDeflt.h +++ b/Core/HLE/sceDeflt.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceDeflt is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceDeflt(); diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index c6c89fdc0c..0c83bb0d45 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -907,7 +907,7 @@ static int GameFirmwareVersion() { // // One directory listing rather than a stat per font, since on Android's scoped storage the // individual checks are slow. -static bool NandFontsComplete() { +bool NandFontsComplete() { const int firmware = GameFirmwareVersion(); std::string_view fontDir(g_nandFontPath); diff --git a/Core/HLE/sceFont.h b/Core/HLE/sceFont.h index 9291029807..7a7a0a433a 100644 --- a/Core/HLE/sceFont.h +++ b/Core/HLE/sceFont.h @@ -5,6 +5,12 @@ class PointerWrap; void Register_sceFont(); void Register_sceLibFttt(); +// Whether flash0:/font holds the fonts this game's firmware would have had. Used two ways: the +// HLE font loader asks so it knows whether to unpack them off the disc's updater first, and +// CheckDisableHLEAvailability asks because the real libfont.prx a disc ships reads its fonts from +// there and has nothing to fall back on - so it can only replace our HLE when they're present. +bool NandFontsComplete(); + void __FontInit(); void __FontShutdown(); void __FontDoState(PointerWrap &p); \ No newline at end of file diff --git a/Core/HLE/sceHeap.h b/Core/HLE/sceHeap.h index 68e1c808d8..06d02929c2 100644 --- a/Core/HLE/sceHeap.h +++ b/Core/HLE/sceHeap.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceHeap is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceHeap(); diff --git a/Core/HLE/sceMd5.h b/Core/HLE/sceMd5.h index 311103d28c..23837626de 100644 --- a/Core/HLE/sceMd5.h +++ b/Core/HLE/sceMd5.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceMd5 is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once #include "Common/CommonTypes.h" diff --git a/Core/HLE/sceMt19937.h b/Core/HLE/sceMt19937.h index 71ed7afc5a..981eb6216f 100644 --- a/Core/HLE/sceMt19937.h +++ b/Core/HLE/sceMt19937.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceMt19937 is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceMt19937(); diff --git a/Core/HLE/sceParseHttp.h b/Core/HLE/sceParseHttp.h index 6c67a246b2..154a6328e0 100644 --- a/Core/HLE/sceParseHttp.h +++ b/Core/HLE/sceParseHttp.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: a graduation candidate, but not graduated. sceParseHttp is a small library with no +// dependencies beyond the kernel, and most games that use it ship their own copy - but it is also +// in the firmware, and sceUtility can load it (module 0x104), so a game may import it without +// carrying one. Letting the game's module win would hand that game unresolved imports. It can +// follow once sceUtility loads the firmware copy the way it does for sceMp3 and sceMp4. + #pragma once void Register_sceParseHttp(); \ No newline at end of file diff --git a/Core/HLE/sceParseUri.h b/Core/HLE/sceParseUri.h index 9b3bb7d06b..5d7b677b2c 100644 --- a/Core/HLE/sceParseUri.h +++ b/Core/HLE/sceParseUri.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: a graduation candidate, but not graduated. sceParseUri is a small library with no +// dependencies beyond the kernel, and most games that use it ship their own copy - but it is also +// in the firmware, and sceUtility can load it (module 0x103), so a game may import it without +// carrying one. Letting the game's module win would hand that game unresolved imports. It can +// follow once sceUtility loads the firmware copy the way it does for sceMp3 and sceMp4. + #pragma once #ifdef _MSC_VER diff --git a/Core/HLE/sceSfmt19937.h b/Core/HLE/sceSfmt19937.h index 31b62663f1..0cd16f0cf1 100644 --- a/Core/HLE/sceSfmt19937.h +++ b/Core/HLE/sceSfmt19937.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceSfmt19937 is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceSfmt19937(); diff --git a/Core/HLE/sceSha256.h b/Core/HLE/sceSha256.h index eefb687f48..05d34c284d 100644 --- a/Core/HLE/sceSha256.h +++ b/Core/HLE/sceSha256.h @@ -15,6 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +// NOTE: This is now unmaintained legacy code. sceSha256 is a small leaf library that games ship +// on the disc themselves and that appears in no firmware dump, so we let the game's own module run +// and this HLE is only a fallback for the rare game that imports it without shipping it, and for +// old savestates - whose syscall opcodes index these tables, which is why nothing here is removed. +// See AlwaysDisableHLEFlags in Core/HLE/HLE.cpp. + #pragma once void Register_sceSha256(); diff --git a/Core/System.cpp b/Core/System.cpp index 740d6ddbee..62f75b570c 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -506,9 +506,6 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin DisplayHWInit(); - // Init all the HLE modules - HLEInit(); - // TODO: Put this somewhere better? if (!g_CoreParameter.mountIso.empty()) { g_CoreParameter.mountIsoLoader = ConstructFileLoader(g_CoreParameter.mountIso); @@ -521,6 +518,13 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin MountFileSystems(); + // Init all the HLE modules. After the mount, and after the firmware install above, so that the + // checks in HLEInit deciding whether a library can run its real module instead of our HLE can + // ask the PSP filesystem the way everything else does - and see a firmware this very boot just + // installed off the disc. Nothing between CoreTiming::Init above and here touches HLE, and the + // kernel and the game's modules both come later, in the switch below. + HLEInit(); + // Game-specific settings are load from for example Load_PSP_ISO (which calls g_Config.LoadGameConfig). // We can't do things that depend on these before the below switch. So for example, the adjustment of the GPU core // to software has now been moved below it.