mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-07 19:03:29 +00:00
Merge pull request #12945 from unknownbrackets/io-timing
Make file open timing a bit more accurate
This commit is contained in:
commit
b58ca8af12
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 ¶ms = 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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user