From 3777d32ac862f4e74669a914d787b0ddf71d6818 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:08:10 -0700 Subject: [PATCH 01/11] Io: Cleanup sceIoOpen errors and logging. --- Core/FileSystems/MetaFileSystem.cpp | 6 +++-- Core/HLE/sceIo.cpp | 42 +++++++++++------------------ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 19bddf251e..648189b52e 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -178,7 +178,7 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system) { - int error = -1; + int error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; std::lock_guard guard(lock); std::string realpath; @@ -246,6 +246,8 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath return error == SCE_KERNEL_ERROR_NOCWD ? error : 0; } } + + error = SCE_KERNEL_ERROR_NODEV; } DEBUG_LOG(FILESYS, "MapFilePath: failed mapping \"%s\", returning false", inpath.c_str()); @@ -353,7 +355,7 @@ int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char if (error == 0) return mount->system->OpenFile(of, access, mount->prefix.c_str()); else - return error == -1 ? SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : error; + return error; } PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 567f0c069a..d35df60aee 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1463,41 +1463,33 @@ static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) } static u32 sceIoOpen(const char *filename, int flags, int mode) { - if (!__KernelIsDispatchEnabled()) - return -1; + if (!__KernelIsDispatchEnabled()) { + return hleLogError(SCEIO, SCE_KERNEL_ERROR_CAN_NOT_WAIT, "dispatch disabled"); + } int error; FileNode *f = __IoOpen(error, filename, flags, mode); - if (f == NULL) - { - // Timing is not accurate, aiming low for now. - if (error == (int)SCE_KERNEL_ERROR_NOCWD) - { - ERROR_LOG(SCEIO, "SCE_KERNEL_ERROR_NOCWD=sceIoOpen(%s, %08x, %08x) - no current working directory", filename, flags, mode); - return hleDelayResult(SCE_KERNEL_ERROR_NOCWD, "no cwd", 10000); - } - else if (error != 0) - { - ERROR_LOG(SCEIO, "%08x=sceIoOpen(%s, %08x, %08x)", error, filename, flags, mode); - return hleDelayResult(error, "file opened", 10000); - } - else - { - ERROR_LOG(SCEIO, "ERROR_ERRNO_FILE_NOT_FOUND=sceIoOpen(%s, %08x, %08x) - file not found", filename, flags, mode); - return hleDelayResult(SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND, "file opened", 10000); + if (!f) { + assert(error != 0); + if (error == (int)SCE_KERNEL_ERROR_NOCWD) { + // TODO: Timing is not accurate. + return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000), "no current working directory"); + } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { + // TODO: Depends on filesys. + return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); + } else { + return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000)); } } int id = __IoAllocFd(f); if (id < 0) { - ERROR_LOG(SCEIO, "%08x=sceIoOpen(%s, %08x, %08x): out of fds", id, filename, flags, mode); kernelObjects.Destroy(f->GetUID()); - return id; + return hleLogError(SCEIO, id, "out of fds"); } else { - DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode); asyncParams[id].priority = asyncDefaultPriority; // Timing is not accurate, aiming low for now. - return hleDelayResult(id, "file opened", 100); + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 100)); } } @@ -2044,9 +2036,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. if (f == nullptr) { - if (error == 0) - error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; - + assert(error != 0); f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; From 51db9f0f858de178c5d3fb491ee3abd69d5f14da Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:42:43 -0700 Subject: [PATCH 02/11] Io: Improve timing of sceIoOpen(). Currently ignores filesystem, but this is more accurate. --- Core/HLE/sceIo.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index d35df60aee..12e1781683 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1463,7 +1463,10 @@ static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) } static u32 sceIoOpen(const char *filename, int flags, int mode) { + hleEatCycles(18000); + if (!__KernelIsDispatchEnabled()) { + hleEatCycles(48000); return hleLogError(SCEIO, SCE_KERNEL_ERROR_CAN_NOT_WAIT, "dispatch disabled"); } @@ -1474,6 +1477,8 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { if (error == (int)SCE_KERNEL_ERROR_NOCWD) { // TODO: Timing is not accurate. return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000), "no current working directory"); + } else if (error == (int)SCE_KERNEL_ERROR_NODEV) { + return hleLogError(SCEIO, error, "device not found"); } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { // TODO: Depends on filesys. return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); @@ -1485,11 +1490,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { int id = __IoAllocFd(f); if (id < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, id, "out of fds"); + return hleLogError(SCEIO, hleDelayResult(id, "file opened", 10000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; - // Timing is not accurate, aiming low for now. - return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 100)); + // TODO: Depends on filesys. Timing is not accurate, aiming low for now. + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 1000)); } } From 67416e591933c746ac6e7725ef9938304d56d44f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:55:25 -0700 Subject: [PATCH 03/11] Io: Simulate VFAT bug only when simulating FAT32. And cleanup flag handling a bit. --- Core/FileSystems/BlobFileSystem.cpp | 2 +- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 10 +++++++--- Core/FileSystems/DirectoryFileSystem.h | 8 ++++---- Core/FileSystems/FileSystem.h | 16 ++++++++++++---- Core/FileSystems/ISOFileSystem.h | 4 ++-- Core/FileSystems/MetaFileSystem.h | 2 +- Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 9 ++++----- Core/PSPLoaders.cpp | 2 +- 10 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index 0f02bbd821..ceaeb9e1c7 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -109,7 +109,7 @@ int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out } int BlobFileSystem::DevType(u32 handle) { - return -1; + return PSP_DEV_TYPE_FILE; } bool BlobFileSystem::MkDir(const std::string &dirname) { diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index 2a877918d9..756122468c 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -44,7 +44,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index f5bbf8e03b..90d623b350 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -150,7 +150,7 @@ bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBeha #endif -DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags) : basePath(_basePath), flags(_flags) { +DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, FileSystemFlags _flags) : basePath(_basePath), flags(_flags) { File::CreateFullPath(basePath); hAlloc = _hAlloc; } @@ -874,7 +874,9 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { entry.size = 4096; else entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32); - entry.name = SimulateVFATBug(ConvertWStringToUTF8(findData.cFileName)); + entry.name = ConvertWStringToUTF8(findData.cFileName); + if (Flags() & FileSystemFlags::SIMULATE_FAT32) + entry.name = SimulateVFATBug(entry.name); bool hideFile = false; if (hideISOFiles && (endsWithNoCase(entry.name, ".cso") || endsWithNoCase(entry.name, ".iso"))) { @@ -921,7 +923,9 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { else entry.type = FILETYPE_NORMAL; entry.access = s.st_mode & 0x1FF; - entry.name = SimulateVFATBug(dirp->d_name); + entry.name = dirp->d_name; + if (Flags() & FileSystemFlags::SIMULATE_FAT32) + entry.name = SimulateVFATBug(entry.name); entry.size = s.st_size; bool hideFile = false; diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index e00a4c4946..edc4b5db27 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -85,7 +85,7 @@ struct DirectoryFileHandle { class DirectoryFileSystem : public IFileSystem { public: - DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags = 0); + DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, FileSystemFlags _flags = FileSystemFlags::NONE); ~DirectoryFileSystem(); void CloseAll(); @@ -109,7 +109,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - int Flags() override { return flags; } + FileSystemFlags Flags() override { return flags; } u64 FreeSpace(const std::string &path) override; private: @@ -123,7 +123,7 @@ private: EntryMap entries; std::string basePath; IHandleAllocator *hAlloc; - int flags; + FileSystemFlags flags; // In case of Windows: Translate slashes, etc. std::string GetLocalPath(std::string localpath); }; @@ -154,7 +154,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } private: diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 4f87736613..a958771de9 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -50,10 +50,18 @@ enum DevType { PSP_DEV_TYPE_ALIAS = 0x20, }; -enum FileSystemFlags { - FILESYSTEM_SIMULATE_FAT32 = 1, +enum class FileSystemFlags { + NONE = 0, + SIMULATE_FAT32 = 1, }; +inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { + return FileSystemFlags((int)lhs | (int)rhs); +} +inline bool operator &(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { + return ((int)lhs & (int)rhs) != 0; +} + class IHandleAllocator { public: virtual ~IHandleAllocator() {} @@ -126,7 +134,7 @@ public: virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0; virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0; virtual int DevType(u32 handle) = 0; - virtual int Flags() = 0; + virtual FileSystemFlags Flags() = 0; virtual u64 FreeSpace(const std::string &path) = 0; }; @@ -152,7 +160,7 @@ public: virtual bool GetHostPath(const std::string &inpath, std::string &outpath) override {return false;} virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override {return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } virtual int DevType(u32 handle) override { return 0; } - virtual int Flags() override { return 0; } + virtual FileSystemFlags Flags() override { return FileSystemFlags::NONE; } virtual u64 FreeSpace(const std::string &path) override { return 0; } }; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 34b24bb081..a8a2ec7746 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -42,7 +42,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override; @@ -137,7 +137,7 @@ public: int DevType(u32 handle) override { return isoFileSystem_->DevType(handle); } - int Flags() override { return isoFileSystem_->Flags(); } + FileSystemFlags Flags() override { return isoFileSystem_->Flags(); } u64 FreeSpace(const std::string &path) override { return isoFileSystem_->FreeSpace(path); } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override { diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index c4bfd8d37f..37bde0d256 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -115,7 +115,7 @@ public: bool RemoveFile(const std::string &filename) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override; // Convenience helper - returns < 0 on failure. diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index b4ad72924b..9b676fd9ad 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -41,7 +41,7 @@ public: int DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } // unsupported operations diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 12e1781683..186b7280ec 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -621,7 +621,7 @@ void __IoInit() { asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); - memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FILESYSTEM_SIMULATE_FAT32); + memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32); #if defined(USING_WIN_UI) || defined(APPLE) flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory); #else @@ -637,7 +637,7 @@ void __IoInit() { const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); const std::string exdataPath = g_Config.memStickDirectory + "exdata/" + gameId + "/"; if (File::Exists(exdataPath)) { - exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FILESYSTEM_SIMULATE_FAT32); + exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32); pspFileSystem.Mount("exdata0:", exdataSystem); INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str()); } else { @@ -1423,8 +1423,7 @@ static u32 sceIoLseek32Async(int id, int offset, int whence) { return 0; } -static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) { - //memory stick filename +static FileNode *__IoOpen(int &error, const char *filename, int flags, int mode) { int access = FILEACCESS_NONE; if (flags & PSP_O_RDONLY) access |= FILEACCESS_READ; @@ -2290,7 +2289,7 @@ static u32 sceIoDread(int id, u32 dirent_addr) { bool isFAT = false; IFileSystem *sys = pspFileSystem.GetSystemFromFilename(dir->name); - if (sys && (sys->Flags() & FILESYSTEM_SIMULATE_FAT32)) + if (sys && (sys->Flags() & FileSystemFlags::SIMULATE_FAT32)) isFAT = true; else isFAT = false; diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index d72c648601..887b61b8c3 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -386,7 +386,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.SetStartingDirectory(ms_path); } - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path); + DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32); pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file + extension; From c829ccb87d89b209086b747ecda5a19ab78909b3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:10:08 -0700 Subject: [PATCH 04/11] Io: Track whether the game is on a UMD or storage. --- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/BlockDevices.h | 4 ++++ Core/FileSystems/DirectoryFileSystem.h | 2 +- Core/FileSystems/FileSystem.h | 3 +++ Core/FileSystems/ISOFileSystem.cpp | 6 ++++++ Core/FileSystems/ISOFileSystem.h | 2 +- Core/FileSystems/MetaFileSystem.h | 4 ++++ Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 14 ++++---------- Core/PSPLoaders.cpp | 2 +- 10 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index 756122468c..ded4829384 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -44,7 +44,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index 6e17aaa4ea..2db068c777 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -45,6 +45,7 @@ public: } int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses virtual u32 GetNumBlocks() = 0; + virtual bool IsDisc() = 0; u32 CalculateCRC(); void NotifyReadError(); @@ -60,6 +61,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override { return numBlocks; } + bool IsDisc() override { return true; } private: FileLoader *fileLoader_; @@ -83,6 +85,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override {return (u32)(filesize_ / GetBlockSize());} + bool IsDisc() override { return true; } private: FileLoader *fileLoader_; @@ -107,6 +110,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; u32 GetNumBlocks() override {return (u32)lbaSize;} + bool IsDisc() override { return false; } private: FileLoader *fileLoader_; diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index edc4b5db27..44c12b939d 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -154,7 +154,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } u64 FreeSpace(const std::string &path) override { return 0; } private: diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index a958771de9..93ad733192 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -53,6 +53,9 @@ enum DevType { enum class FileSystemFlags { NONE = 0, SIMULATE_FAT32 = 1, + UMD = 2, + CARD = 4, + FLASH = 8, }; inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 39e54b8bb6..3a73b1a96e 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -467,6 +467,12 @@ int ISOFileSystem::DevType(u32 handle) return iter->second.isBlockSectorMode ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; } +FileSystemFlags ISOFileSystem::Flags() { + // TODO: Here may be a good place to force things, in case users recompress games + // as PBP or CSO when they were originally the other type. + return blockDevice->IsDisc() ? FileSystemFlags::UMD : FileSystemFlags::CARD; +} + size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { int ignored; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index a8a2ec7746..c2c73592d6 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -42,7 +42,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override; u64 FreeSpace(const std::string &path) override { return 0; } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override; diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 37bde0d256..f348f476ab 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -56,6 +56,10 @@ public: IFileSystem *GetSystem(const std::string &prefix); IFileSystem *GetSystemFromFilename(const std::string &filename); + FileSystemFlags FlagsFromFilename(const std::string &filename) { + IFileSystem *sys = GetSystemFromFilename(filename); + return sys ? sys->Flags() : FileSystemFlags::NONE; + } void ThreadEnded(int threadID); diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index 9b676fd9ad..a2fd8be4ba 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -41,7 +41,7 @@ public: int DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::UMD; } u64 FreeSpace(const std::string &path) override { return 0; } // unsupported operations diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 186b7280ec..8a56ab6a84 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -621,9 +621,9 @@ void __IoInit() { asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); - memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32); + memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); #if defined(USING_WIN_UI) || defined(APPLE) - flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory); + flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory, FileSystemFlags::FLASH); #else flash0System = new VFSFileSystem(&pspFileSystem, "flash0"); #endif @@ -637,7 +637,7 @@ void __IoInit() { const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); const std::string exdataPath = g_Config.memStickDirectory + "exdata/" + gameId + "/"; if (File::Exists(exdataPath)) { - exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32); + exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); pspFileSystem.Mount("exdata0:", exdataSystem); INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str()); } else { @@ -2287,13 +2287,7 @@ static u32 sceIoDread(int id, u32 dirent_addr) { strncpy(entry->d_name, info.name.c_str(), 256); entry->d_name[255] = '\0'; - bool isFAT = false; - IFileSystem *sys = pspFileSystem.GetSystemFromFilename(dir->name); - if (sys && (sys->Flags() & FileSystemFlags::SIMULATE_FAT32)) - isFAT = true; - else - isFAT = false; - + bool isFAT = pspFileSystem.FlagsFromFilename(dir->name) & FileSystemFlags::SIMULATE_FAT32; // Only write d_private for memory stick if (isFAT) { // write d_private for supporting Custom BGM diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 887b61b8c3..0f4732b772 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -386,7 +386,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.SetStartingDirectory(ms_path); } - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32); + DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file + extension; From 52283a50dcb6e88fcdaedbbcb54dfbda9ac5bbfa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:28:05 -0700 Subject: [PATCH 05/11] Io: Improve non-async open timing. --- Core/HLE/sceIo.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 8a56ab6a84..8f630ad803 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1479,8 +1479,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { } else if (error == (int)SCE_KERNEL_ERROR_NODEV) { return hleLogError(SCEIO, error, "device not found"); } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { - // TODO: Depends on filesys. - return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); + // UMD: Varies between 5-10ms, could take longer if disc spins up. + // TODO: Bad filename at root (disc0:/no.exist) should take ~200us. + // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 6000 : 10000; + return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", delay), "file not found"); } else { return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000)); } @@ -1489,11 +1492,13 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { int id = __IoAllocFd(f); if (id < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, hleDelayResult(id, "file opened", 10000), "out of fds"); + return hleLogError(SCEIO, hleDelayResult(id, "file opened", 1000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; - // TODO: Depends on filesys. Timing is not accurate, aiming low for now. - return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 1000)); + // UMD: Speed varies from 1-6ms. + // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 4000 : 10000; + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", delay)); } } From 5e1adcdbd20e9d227544db1cb065062d1487638a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:34:04 -0700 Subject: [PATCH 06/11] Io: Fail without fd on bad device in OpenAsync. --- Core/HLE/sceIo.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 8f630ad803..fe6ee2e716 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2033,8 +2033,9 @@ static u32 sceIoSetAsyncCallback(int id, u32 clbckId, u32 clbckArg) } } -static u32 sceIoOpenAsync(const char *filename, int flags, int mode) -{ +static u32 sceIoOpenAsync(const char *filename, int flags, int mode) { + hleEatCycles(18000); + // TOOD: Use an internal method so as not to pollute the log? // Intentionally does not work when interrupts disabled. if (!__KernelIsDispatchEnabled()) @@ -2046,6 +2047,9 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. if (f == nullptr) { assert(error != 0); + if (error == SCE_KERNEL_ERROR_NODEV) + return hleLogError(SCEIO, error, "device not found"); + f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; @@ -2056,7 +2060,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) int fd = __IoAllocFd(f); if (fd < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, fd, "out of fds"); + return hleLogError(SCEIO, hleDelayResult(fd, "file opened", 1000), "out of fds"); } auto ¶ms = asyncParams[fd]; From 91427c1f4e83286f57583049b0dea00eb50b04de Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:58:19 -0700 Subject: [PATCH 07/11] Io: Account for OpenAsync timing. --- Core/HLE/sceIo.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index fe6ee2e716..eee2edc76d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1482,6 +1482,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { // UMD: Varies between 5-10ms, could take longer if disc spins up. // TODO: Bad filename at root (disc0:/no.exist) should take ~200us. // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + // TODO: If a UMD and spun down, this can easily take 1s+. int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 6000 : 10000; return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", delay), "file not found"); } else { @@ -2709,10 +2710,15 @@ static int IoAsyncFinish(int id) { break; case IoAsyncOp::OPEN: - // TODO: Timing is very inconsistent. From ms0, 10ms - 20ms depending on filesize/dir depth? From umd, can take > 1s. - // For now let's aim low. - us = 100; + { + // See notes on timing in sceIoOpen. + FileSystemFlags flags = pspFileSystem.FlagsFromFilename(Memory::GetCharPointer(params.open.filenameAddr)); + if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) + us = flags & FileSystemFlags::UMD ? 6000 : 10000; + else + us = flags & FileSystemFlags::UMD ? 4000 : 10000; break; + } case IoAsyncOp::CLOSE: f->asyncResult = 0; From 49abe9ed6c536d3803663948df51fbaf1cec260e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 17:57:41 -0700 Subject: [PATCH 08/11] Io: Open sce_lbn references and whole ISO faster. --- Core/FileSystems/BlobFileSystem.cpp | 4 ++-- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 8 +++---- Core/FileSystems/DirectoryFileSystem.h | 7 +++--- Core/FileSystems/FileSystem.h | 25 ++++++++++--------- Core/FileSystems/ISOFileSystem.cpp | 9 ++++--- Core/FileSystems/ISOFileSystem.h | 4 ++-- Core/FileSystems/MetaFileSystem.cpp | 4 ++-- Core/FileSystems/MetaFileSystem.h | 2 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 5 ++-- Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 28 ++++++++++++++++------ GPU/Common/PresentationCommon.h | 13 ++-------- UI/MainScreen.h | 9 +------ Windows/MainWindowMenu.cpp | 2 +- ext/native/base/basictypes.h | 14 +++++++++++ 16 files changed, 76 insertions(+), 62 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index ceaeb9e1c7..730dca7854 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -108,8 +108,8 @@ int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out return -1; } -int BlobFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType BlobFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } bool BlobFileSystem::MkDir(const std::string &dirname) { diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index ded4829384..3657522ddd 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -43,7 +43,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } bool MkDir(const std::string &dirname) override; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 90d623b350..4bfd6a3b43 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -663,8 +663,8 @@ int DirectoryFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u3 return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int DirectoryFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType DirectoryFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } size_t DirectoryFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { @@ -1121,8 +1121,8 @@ int VFSFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int VFSFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType VFSFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } size_t VFSFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index 44c12b939d..84e51bbf32 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -20,8 +20,7 @@ // TODO: Remove the Windows-specific code, FILE is fine there too. #include - -#include "../Core/FileSystems/FileSystem.h" +#include "Core/FileSystems/FileSystem.h" #ifdef _WIN32 typedef void * HANDLE; @@ -102,7 +101,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; @@ -147,7 +146,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 93ad733192..542569071e 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -20,6 +20,7 @@ #include #include #include +#include "base/basictypes.h" #include "Core/HLE/sceKernel.h" @@ -44,11 +45,15 @@ enum FileType { FILETYPE_DIRECTORY = 2 }; -enum DevType { - PSP_DEV_TYPE_BLOCK = 0x04, - PSP_DEV_TYPE_FILE = 0x10, - PSP_DEV_TYPE_ALIAS = 0x20, +enum class PSPDevType { + INVALID = 0, + BLOCK = 0x04, + FILE = 0x10, + ALIAS = 0x20, + EMU_MASK = 0xFF, + EMU_LBN = 0x10000, }; +ENUM_CLASS_BITOPS(PSPDevType); enum class FileSystemFlags { NONE = 0, @@ -57,13 +62,7 @@ enum class FileSystemFlags { CARD = 4, FLASH = 8, }; - -inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { - return FileSystemFlags((int)lhs | (int)rhs); -} -inline bool operator &(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(FileSystemFlags); class IHandleAllocator { public: @@ -136,7 +135,7 @@ public: virtual bool RemoveFile(const std::string &filename) = 0; virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0; virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0; - virtual int DevType(u32 handle) = 0; + virtual PSPDevType DevType(u32 handle) = 0; virtual FileSystemFlags Flags() = 0; virtual u64 FreeSpace(const std::string &path) = 0; }; @@ -162,7 +161,7 @@ public: virtual bool RemoveFile(const std::string &filename) override {return false;} virtual bool GetHostPath(const std::string &inpath, std::string &outpath) override {return false;} virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override {return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } - virtual int DevType(u32 handle) override { return 0; } + virtual PSPDevType DevType(u32 handle) override { return PSPDevType::INVALID; } virtual FileSystemFlags Flags() override { return FileSystemFlags::NONE; } virtual u64 FreeSpace(const std::string &path) override { return 0; } }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 3a73b1a96e..0e6593a71a 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -461,10 +461,12 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int ISOFileSystem::DevType(u32 handle) -{ +PSPDevType ISOFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.isBlockSectorMode ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; + PSPDevType type = iter->second.isBlockSectorMode ? PSPDevType::BLOCK : PSPDevType::FILE; + if (iter->second.isRawSector) + type |= PSPDevType::EMU_LBN; + return type; } FileSystemFlags ISOFileSystem::Flags() { @@ -613,6 +615,7 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { PSPFileInfo fileInfo; fileInfo.name = filename; fileInfo.exists = true; + fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index c2c73592d6..273d845301 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -41,7 +41,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override; u64 FreeSpace(const std::string &path) override { return 0; } @@ -134,7 +134,7 @@ public: int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override { return isoFileSystem_->Ioctl(handle, cmd, indataPtr, inlen, outdataPtr, outlen, usec); } - int DevType(u32 handle) override { + PSPDevType DevType(u32 handle) override { return isoFileSystem_->DevType(handle); } FileSystemFlags Flags() override { return isoFileSystem_->Flags(); } diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 648189b52e..687dc20bd8 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -538,13 +538,13 @@ int MetaFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out return SCE_KERNEL_ERROR_ERROR; } -int MetaFileSystem::DevType(u32 handle) +PSPDevType MetaFileSystem::DevType(u32 handle) { std::lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) return sys->DevType(handle); - return SCE_KERNEL_ERROR_ERROR; + return PSPDevType::INVALID; } void MetaFileSystem::CloseFile(u32 handle) diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index f348f476ab..8294ba16da 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -118,7 +118,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override; diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 7ff3dc07ed..b7274ab9c0 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -552,9 +552,9 @@ int VirtualDiscFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int VirtualDiscFileSystem::DevType(u32 handle) { +PSPDevType VirtualDiscFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.type == VFILETYPE_ISO ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; + return iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; } PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { @@ -569,6 +569,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { PSPFileInfo fileInfo; fileInfo.name = filename; fileInfo.exists = true; + fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index a2fd8be4ba..cdf6a54ccd 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -38,7 +38,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; FileSystemFlags Flags() override { return FileSystemFlags::UMD; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index eee2edc76d..d9a5c5ae8d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1245,7 +1245,7 @@ static u32 sceIoWriteAsync(int id, u32 data_addr, int size) { static u32 sceIoGetDevType(int id) { if (id == PSP_STDOUT || id == PSP_STDERR || id == PSP_STDIN) { DEBUG_LOG(SCEIO, "sceIoGetDevType(%d)", id); - return PSP_DEV_TYPE_FILE; + return (u32)PSPDevType::FILE; } u32 error; @@ -1254,7 +1254,7 @@ static u32 sceIoGetDevType(int id) { if (f) { // TODO: When would this return PSP_DEV_TYPE_ALIAS? WARN_LOG(SCEIO, "sceIoGetDevType(%d - %s)", id, f->fullpath.c_str()); - result = pspFileSystem.DevType(f->handle); + result = (u32)pspFileSystem.DevType(f->handle) & (u32)PSPDevType::EMU_MASK; } else { ERROR_LOG(SCEIO, "sceIoGetDevType: unknown id %d", id); result = SCE_KERNEL_ERROR_BADF; @@ -1496,6 +1496,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { return hleLogError(SCEIO, hleDelayResult(id, "file opened", 1000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; + IFileSystem *sys = pspFileSystem.GetSystemFromFilename(filename); + if (sys && (sys->DevType(f->handle) & (PSPDevType::BLOCK | PSPDevType::EMU_LBN))) { + // These are fast to open, no delay or even rescheduling happens. + return hleLogSuccessI(SCEIO, id); + } // UMD: Speed varies from 1-6ms. // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 4000 : 10000; @@ -2712,11 +2717,20 @@ static int IoAsyncFinish(int id) { case IoAsyncOp::OPEN: { // See notes on timing in sceIoOpen. - FileSystemFlags flags = pspFileSystem.FlagsFromFilename(Memory::GetCharPointer(params.open.filenameAddr)); - if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) - us = flags & FileSystemFlags::UMD ? 6000 : 10000; - else - us = flags & FileSystemFlags::UMD ? 4000 : 10000; + const std::string filename = Memory::GetCharPointer(params.open.filenameAddr); + IFileSystem *sys = pspFileSystem.GetSystemFromFilename(filename); + if (sys) { + if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { + us = sys->Flags() & FileSystemFlags::UMD ? 6000 : 10000; + } else if (sys->DevType(f->handle) & (PSPDevType::BLOCK | PSPDevType::EMU_LBN)) { + // These are fast to open, no delay or even rescheduling happens. + us = 80; + } else { + us = sys->Flags() & FileSystemFlags::UMD ? 4000 : 10000; + } + } else { + us = 80; + } break; } diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index eae2834abf..c3a695f310 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -17,6 +17,7 @@ #pragma once +#include "base/basictypes.h" #include "GPU/Common/ShaderCommon.h" struct CardboardSettings { @@ -59,17 +60,7 @@ enum class OutputFlags { BACKBUFFER_FLIPPED = 0x0004, POSITION_FLIPPED = 0x0008, }; - -inline OutputFlags operator | (const OutputFlags &lhs, const OutputFlags &rhs) { - return OutputFlags((int)lhs | (int)rhs); -} -inline OutputFlags operator |= (OutputFlags &lhs, const OutputFlags &rhs) { - lhs = lhs | rhs; - return lhs; -} -inline bool operator & (const OutputFlags &lhs, const OutputFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(OutputFlags); class PresentationCommon { public: diff --git a/UI/MainScreen.h b/UI/MainScreen.h index 832d104043..fe1b09ad4b 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -36,14 +36,7 @@ enum class BrowseFlags { HOMEBREW_STORE = 8, STANDARD = 1 | 2 | 4, }; - -static inline BrowseFlags operator |(const BrowseFlags &lhs, const BrowseFlags &rhs) { - return BrowseFlags((int)lhs | (int)rhs); -} - -static inline bool operator &(const BrowseFlags &lhs, const BrowseFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(BrowseFlags); class GameBrowser : public UI::LinearLayout { public: diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b5e1bb0eb0..2ab276eec3 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -928,7 +928,7 @@ namespace MainWindow { u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, ""); // Note: len may be in blocks. size_t len = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END); - bool isBlockMode = pspFileSystem.DevType(handle) == PSP_DEV_TYPE_BLOCK; + bool isBlockMode = pspFileSystem.DevType(handle) & PSPDevType::BLOCK; FILE *fp = File::OpenCFile(fn, "wb"); pspFileSystem.SeekFile(handle, 0, FILEMOVE_BEGIN); diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index 8cd0fd0e1e..2f9c7d0321 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -14,6 +14,20 @@ void operator =(const t &other) = delete; #endif +#ifndef ENUM_CLASS_BITOPS +#define ENUM_CLASS_BITOPS(T) \ + static inline T operator |(const T &lhs, const T &rhs) { \ + return T((int)lhs | (int)rhs); \ + } \ + static inline T &operator |= (T &lhs, const T &rhs) { \ + lhs = lhs | rhs; \ + return lhs; \ + } \ + static inline bool operator &(const T &lhs, const T &rhs) { \ + return ((int)lhs & (int)rhs) != 0; \ + } +#endif + #ifdef _WIN32 typedef intptr_t ssize_t; From 9b112efa0bbfe66e62470ed878e5856207512201 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 18:01:53 -0700 Subject: [PATCH 09/11] Headless: Handle umd mapping with block devices. --- Core/FileSystems/MetaFileSystem.cpp | 4 ++-- Core/PSPLoaders.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 687dc20bd8..fdd85a6245 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -258,8 +258,8 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const { // Let's apply some mapping here since it won't break savestates. if (prefix == "memstick:") prefix = "ms0:"; - // Seems like umd00: etc. work just fine... - if (startsWith(prefix, "umd")) + // Seems like umd00: etc. work just fine... avoid umd1/umd for tests. + if (startsWith(prefix, "umd") && prefix != "umd1:" && prefix != "umd:") prefix = "umd0:"; // Seems like umd00: etc. work just fine... if (startsWith(prefix, "host")) diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 0f4732b772..4773a670e4 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -340,10 +340,11 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { auto bd = constructBlockDevice(PSP_CoreParameter().mountIsoLoader); if (bd != NULL) { ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd); + ISOBlockSystem *blockSystem = new ISOBlockSystem(umd2); - pspFileSystem.Mount("umd1:", umd2); + pspFileSystem.Mount("umd1:", blockSystem); pspFileSystem.Mount("disc0:", umd2); - pspFileSystem.Mount("umd:", umd2); + pspFileSystem.Mount("umd:", blockSystem); } } From d7ad43b1d9e35cc4b6afdd5d3ebea616d1c3bb7d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 18:20:38 -0700 Subject: [PATCH 10/11] Io: Cleanup access bits for files. Also, we default a lot of these members, so don't need to reset. --- Core/FileSystems/DirectoryFileSystem.cpp | 6 +---- Core/FileSystems/FileSystem.h | 28 ++++++++++------------ Core/FileSystems/ISOFileSystem.cpp | 15 +++++------- Core/FileSystems/MetaFileSystem.cpp | 2 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 11 ++++----- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 4bfd6a3b43..1e38103ff2 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -742,11 +742,6 @@ PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) { File::FileDetails details; if (!File::GetFileDetails(fullName, &details)) { ERROR_LOG(FILESYS, "DirectoryFileSystem::GetFileInfo: GetFileDetails failed: %s", fullName.c_str()); - x.size = 0; - x.access = 0; - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.ctime, 0, sizeof(x.ctime)); - memset(&x.mtime, 0, sizeof(x.mtime)); } else { x.size = details.size; x.access = details.access; @@ -1094,6 +1089,7 @@ PSPFileInfo VFSFileSystem::GetFileInfo(std::string filename) { if (x.exists) { x.size = fo.size; x.type = fo.isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; + x.access = fo.isWritable ? 0666 : 0444; } } else { x.exists = false; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 542569071e..6c069efe0d 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -88,29 +88,25 @@ private: }; struct PSPFileInfo { - PSPFileInfo() - : size(0), access(0), exists(false), type(FILETYPE_NORMAL), isOnSectorSystem(false), startSector(0), numSectors(0), sectorSize(0) { - memset(&ctime, 0, sizeof(ctime)); - memset(&atime, 0, sizeof(atime)); - memset(&mtime, 0, sizeof(mtime)); + PSPFileInfo() { } void DoState(PointerWrap &p); std::string name; - s64 size; - u32 access; //unix 777 - bool exists; - FileType type; + s64 size = 0; + u32 access = 0; //unix 777 + bool exists = false; + FileType type = FILETYPE_NORMAL; - tm atime; - tm ctime; - tm mtime; + tm atime{}; + tm ctime{}; + tm mtime{}; - bool isOnSectorSystem; - u32 startSector; - u32 numSectors; - u32 sectorSize; + bool isOnSectorSystem = false; + u32 startSector = 0; + u32 numSectors = 0; + u32 sectorSize = 0; }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 0e6593a71a..3f481a2f9b 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -617,6 +617,7 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { fileInfo.exists = true; fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; + fileInfo.access = 0444; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; fileInfo.numSectors = (readSize + sectorSize - 1) / sectorSize; @@ -625,12 +626,10 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { TreeEntry *entry = GetFromPath(filename, false); PSPFileInfo x; - if (!entry) { - x.size = 0; - x.exists = false; - } else { + if (entry) { x.name = entry->name; - x.access = FILEACCESS_READ; + // Strangely, it seems to be executable even for files. + x.access = 0555; x.size = entry->size; x.exists = true; x.type = entry->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; @@ -658,16 +657,14 @@ std::vector ISOFileSystem::GetDirListing(std::string path) { PSPFileInfo x; x.name = e->name; - x.access = FILEACCESS_READ; + // Strangely, it seems to be executable even for files. + x.access = 0555; x.size = e->size; x.type = e->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.isOnSectorSystem = true; x.startSector = e->startingPosition/2048; x.sectorSize = sectorSize; x.numSectors = (u32)((e->size + sectorSize - 1) / sectorSize); - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.mtime, 0, sizeof(x.mtime)); - memset(&x.ctime, 0, sizeof(x.ctime)); myVector.push_back(x); } return myVector; diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index fdd85a6245..3b6d487e9f 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -370,7 +370,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) } else { - PSPFileInfo bogus; // TODO + PSPFileInfo bogus; return bogus; } } diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index b7274ab9c0..452b1b018e 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -571,6 +571,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { fileInfo.exists = true; fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; + fileInfo.access = 0444; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; fileInfo.numSectors = (readSize + 2047) / 2048; @@ -582,6 +583,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.type = FILETYPE_NORMAL; x.isOnSectorSystem = true; x.startSector = fileList[fileIndex].firstBlock; + x.access = 0555; HandlerFileHandle temp = fileList[fileIndex].handler; if (temp.Open(basePath, filename, FILEACCESS_READ)) { @@ -610,6 +612,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.type = File::IsDirectory(fullName) ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.exists = true; + x.access = 0555; if (fileIndex != -1) { x.isOnSectorSystem = true; x.startSector = fileList[fileIndex].firstBlock; @@ -621,12 +624,8 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { ERROR_LOG(FILESYS, "DirectoryFileSystem::GetFileInfo: GetFileDetails failed: %s", fullName.c_str()); x.size = 0; x.access = 0; - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.ctime, 0, sizeof(x.ctime)); - memset(&x.mtime, 0, sizeof(x.mtime)); } else { x.size = details.size; - x.access = details.access; time_t atime = details.atime; time_t ctime = details.ctime; time_t mtime = details.mtime; @@ -691,7 +690,7 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) entry.type = FILETYPE_NORMAL; } - entry.access = FILEACCESS_READ; + entry.access = 0555; entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32); entry.name = ConvertWStringToUTF8(findData.cFileName); tmFromFiletime(entry.atime, findData.ftLastAccessTime); @@ -737,7 +736,7 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) entry.type = FILETYPE_DIRECTORY; else entry.type = FILETYPE_NORMAL; - entry.access = s.st_mode & 0x1FF; + entry.access = 0555; entry.name = dirp->d_name; entry.size = s.st_size; localtime_r((time_t*)&s.st_atime,&entry.atime); From 4bd60ed791c21b00d0da5596ba04cc399b1d28dc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 22 May 2020 00:31:17 -0700 Subject: [PATCH 11/11] Io: Fix LBN timing for virtual discs. --- Core/FileSystems/VirtualDiscFileSystem.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 452b1b018e..81ecbeef57 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -554,7 +554,10 @@ int VirtualDiscFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, PSPDevType VirtualDiscFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; + PSPDevType type = iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; + if (iter->second.type == VFILETYPE_LBN) + type |= PSPDevType::EMU_LBN; + return type; } PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) {