Merge pull request #12945 from unknownbrackets/io-timing

Make file open timing a bit more accurate
This commit is contained in:
Henrik Rydgård 2020-07-13 13:37:53 +02:00 committed by GitHub
commit b58ca8af12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 194 additions and 154 deletions

View File

@ -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 -1;
PSPDevType BlobFileSystem::DevType(u32 handle) {
return PSPDevType::FILE;
}
bool BlobFileSystem::MkDir(const std::string &dirname) {

View File

@ -43,8 +43,8 @@ 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;
int Flags() override { return 0; }
PSPDevType DevType(u32 handle) override;
FileSystemFlags Flags() override { return FileSystemFlags::FLASH; }
bool MkDir(const std::string &dirname) override;
bool RmDir(const std::string &dirname) override;

View File

@ -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_;

View File

@ -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;
}
@ -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) {
@ -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;
@ -874,7 +869,9 @@ std::vector<PSPFileInfo> 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 +918,9 @@ std::vector<PSPFileInfo> 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;
@ -1090,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;
@ -1117,8 +1117,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) {

View File

@ -20,8 +20,7 @@
// TODO: Remove the Windows-specific code, FILE is fine there too.
#include <map>
#include "../Core/FileSystems/FileSystem.h"
#include "Core/FileSystems/FileSystem.h"
#ifdef _WIN32
typedef void * HANDLE;
@ -85,7 +84,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();
@ -102,14 +101,14 @@ 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;
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 +122,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);
};
@ -147,14 +146,14 @@ 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;
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::FLASH; }
u64 FreeSpace(const std::string &path) override { return 0; }
private:

View File

@ -20,6 +20,7 @@
#include <vector>
#include <string>
#include <cstring>
#include "base/basictypes.h"
#include "Core/HLE/sceKernel.h"
@ -44,15 +45,24 @@ 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 FileSystemFlags {
FILESYSTEM_SIMULATE_FAT32 = 1,
enum class FileSystemFlags {
NONE = 0,
SIMULATE_FAT32 = 1,
UMD = 2,
CARD = 4,
FLASH = 8,
};
ENUM_CLASS_BITOPS(FileSystemFlags);
class IHandleAllocator {
public:
@ -78,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;
};
@ -125,8 +131,8 @@ 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 int Flags() = 0;
virtual PSPDevType DevType(u32 handle) = 0;
virtual FileSystemFlags Flags() = 0;
virtual u64 FreeSpace(const std::string &path) = 0;
};
@ -151,8 +157,8 @@ 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 int Flags() 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; }
};

View File

@ -461,10 +461,18 @@ 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() {
// 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)
@ -607,7 +615,9 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) {
PSPFileInfo fileInfo;
fileInfo.name = 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;
@ -616,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;
@ -649,16 +657,14 @@ std::vector<PSPFileInfo> 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;

View File

@ -41,8 +41,8 @@ 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;
int Flags() override { return 0; }
PSPDevType DevType(u32 handle) override;
FileSystemFlags Flags() override;
u64 FreeSpace(const std::string &path) override { return 0; }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;
@ -134,10 +134,10 @@ 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);
}
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 {

View File

@ -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<std::recursive_mutex> 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());
@ -256,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"))
@ -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)
@ -368,7 +370,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename)
}
else
{
PSPFileInfo bogus; // TODO
PSPFileInfo bogus;
return bogus;
}
}
@ -536,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<std::recursive_mutex> 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)

View File

@ -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);
@ -114,8 +118,8 @@ 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;
int Flags() override { return 0; }
PSPDevType DevType(u32 handle) override;
FileSystemFlags Flags() override { return FileSystemFlags::NONE; }
u64 FreeSpace(const std::string &path) override;
// Convenience helper - returns < 0 on failure.

View File

@ -552,9 +552,12 @@ 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;
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) {
@ -569,7 +572,9 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) {
PSPFileInfo fileInfo;
fileInfo.name = 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;
@ -581,6 +586,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)) {
@ -609,6 +615,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;
@ -620,12 +627,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;
@ -690,7 +693,7 @@ std::vector<PSPFileInfo> 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);
@ -736,7 +739,7 @@ std::vector<PSPFileInfo> 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);

View File

@ -38,10 +38,10 @@ 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<PSPFileInfo> GetDirListing(std::string path) override;
int Flags() override { return 0; }
FileSystemFlags Flags() override { return FileSystemFlags::UMD; }
u64 FreeSpace(const std::string &path) override { return 0; }
// unsupported operations

View File

@ -621,9 +621,9 @@ 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 | 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, FILESYSTEM_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 {
@ -1251,7 +1251,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;
@ -1260,7 +1260,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;
@ -1429,8 +1429,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;
@ -1469,41 +1468,49 @@ 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;
hleEatCycles(18000);
if (!__KernelIsDispatchEnabled()) {
hleEatCycles(48000);
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_NODEV) {
return hleLogError(SCEIO, error, "device not found");
} else if (error == (int)SCE_KERNEL_ERROR_ERRNO_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.
// 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 {
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<FileNode>(f->GetUID());
return id;
return hleLogError(SCEIO, hleDelayResult(id, "file opened", 1000), "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);
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;
return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", delay));
}
}
@ -2038,8 +2045,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())
@ -2050,8 +2058,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) {
if (error == 0)
error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;
assert(error != 0);
if (error == SCE_KERNEL_ERROR_NODEV)
return hleLogError(SCEIO, error, "device not found");
f = new FileNode();
f->handle = kernelObjects.Create(f);
@ -2063,7 +2072,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode)
int fd = __IoAllocFd(f);
if (fd < 0) {
kernelObjects.Destroy<FileNode>(f->GetUID());
return hleLogError(SCEIO, fd, "out of fds");
return hleLogError(SCEIO, hleDelayResult(fd, "file opened", 1000), "out of fds");
}
auto &params = asyncParams[fd];
@ -2299,13 +2308,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() & FILESYSTEM_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
@ -2718,10 +2721,24 @@ 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.
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;
}
case IoAsyncOp::CLOSE:
f->asyncResult = 0;

View File

@ -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);
}
}
@ -386,7 +387,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 | FileSystemFlags::CARD);
pspFileSystem.Mount("umd0:", fs);
std::string finalName = ms_path + file + extension;

View File

@ -17,6 +17,7 @@
#pragma once
#include "base/basictypes.h"
#include "GPU/Common/ShaderCommon.h"
struct CardboardSettings {
@ -69,17 +70,7 @@ enum class OutputFlags {
POSITION_FLIPPED = 0x0008,
PILLARBOX = 0x0010,
};
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:

View File

@ -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:

View File

@ -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);

View File

@ -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;