diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 2c34e5fecf..693021d959 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1766,8 +1766,8 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o case 0x01F20001: // Get UMD disc type if (Memory::IsValid4AlignedRange(outPtr, 8) && outLen >= 8) { - // A game disc, or none in an empty drive (as JPCSP answers without a disc). - Memory::WriteUnchecked_U32(__UmdIsInserted() ? PSP_UMD_TYPE_GAME : 0, outPtr + 4); + // What's on the disc, or none in an empty drive (as JPCSP answers without a disc). + Memory::WriteUnchecked_U32(__UmdDiscType(), outPtr + 4); return hleLogDebug(Log::sceIo, 0); } else { return hleLogError(Log::sceIo, SCE_ERROR_MEMSTICK_DEVCTL_BAD_PARAMS); diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 8da4ad0579..955c4c6dfb 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -287,7 +287,9 @@ static u32 sceUmdGetDiscInfo(u32 infoAddr) { if (info->size != 8) return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT); - info->type = PSP_UMD_TYPE_GAME; + // Games see a game disc, whatever else is on it. + const u32 type = __UmdDiscType(); + info->type = (type & PSP_UMD_TYPE_GAME) || type == 0 ? PSP_UMD_TYPE_GAME : type; return hleLogDebug(Log::sceIo, 0); } else { return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT); @@ -546,6 +548,28 @@ bool __UmdIsInserted() { return UMDInserted; } +u32 __UmdDiscType() { + if (!UMDInserted) { + return 0; + } + auto hasDir = [](const char *path) { + const PSPFileInfo info = pspFileSystem.GetFileInfo(path); + return info.exists && info.type == FILETYPE_DIRECTORY; + }; + u32 type = 0; + if (hasDir("disc0:/PSP_GAME")) { + type |= PSP_UMD_TYPE_GAME; + } + if (hasDir("disc0:/UMD_VIDEO")) { + type |= PSP_UMD_TYPE_VIDEO; + } + if (hasDir("disc0:/UMD_AUDIO")) { + type |= PSP_UMD_TYPE_AUDIO; + } + // A loose game directory or an ISO without the usual layout still boots as a game. + return type != 0 ? type : PSP_UMD_TYPE_GAME; +} + bool getUMDReplacePermit() { return g_UMDReplacePermit; } diff --git a/Core/HLE/sceUmd.h b/Core/HLE/sceUmd.h index 165f7e3153..43681ec189 100644 --- a/Core/HLE/sceUmd.h +++ b/Core/HLE/sceUmd.h @@ -44,6 +44,8 @@ void __UmdReplace(const Path &filepath); bool __UmdInsert(const Path &filepath, std::string *error); void __UmdEject(); bool __UmdIsInserted(); +// What's on the disc in the drive (PSP_UMD_TYPE_* bits), or 0 for an empty drive. +u32 __UmdDiscType(); bool getUMDReplacePermit(); void Register_sceUmdUser(); diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 095dd3b321..72cc4620b7 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -376,6 +376,7 @@ bool UmdMount(const Path &filepath, FileLoader **fileLoader, std::string &error) case IdentifiedFileType::PSP_ISO: case IdentifiedFileType::PSP_ISO_NP: case IdentifiedFileType::PSP_DISC_DIRECTORY: + case IdentifiedFileType::PSP_UMD_VIDEO_ISO: if (!MountGameISO(loadedFile, &error)) { error = "mounting the ISO failed: " + error; return false;