mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
It never ends...
This commit is contained in:
parent
a40b1dec5f
commit
2e16e83159
@ -1,6 +1,6 @@
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/StringUtils.h"
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Data/Encoding/Utf8.h"
|
||||
|
||||
Path::Path(const std::string &str) {
|
||||
@ -39,10 +39,22 @@ void Path::Init(const std::string &str) {
|
||||
}
|
||||
}
|
||||
|
||||
// We always use forward slashes internally, we convert to backslash only when
|
||||
// converted to a wstring.
|
||||
Path Path::operator /(const std::string &subdir) const {
|
||||
// We always use forward slashes internally, we convert to backslash only when
|
||||
// converted to a wstring.
|
||||
return Path(path_ + "/" + subdir);
|
||||
if (subdir.empty()) {
|
||||
return Path(path_);
|
||||
}
|
||||
std::string fullPath = path_;
|
||||
if (subdir.front() != '/') {
|
||||
fullPath += "/";
|
||||
}
|
||||
fullPath += subdir;
|
||||
// Prevent adding extra slashes.
|
||||
if (fullPath.back() == '/') {
|
||||
fullPath.pop_back();
|
||||
}
|
||||
return Path(fullPath);
|
||||
}
|
||||
|
||||
void Path::operator /=(const std::string &subdir) {
|
||||
@ -50,18 +62,40 @@ void Path::operator /=(const std::string &subdir) {
|
||||
}
|
||||
|
||||
Path Path::WithExtraExtension(const std::string &ext) const {
|
||||
return Path(path_ + "." + ext);
|
||||
_dbg_assert_(!ext.empty() && ext[0] == '.');
|
||||
return Path(path_ + ext);
|
||||
}
|
||||
|
||||
Path Path::WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const {
|
||||
if (endsWithNoCase(path_, "." + oldExtension)) {
|
||||
std::string newPath = path_.substr(0, path_.size() - oldExtension.size() - 1);
|
||||
return Path(newPath + "." + newExtension);
|
||||
_dbg_assert_(!oldExtension.empty() && oldExtension[0] == '.');
|
||||
_dbg_assert_(!newExtension.empty() && newExtension[0] == '.');
|
||||
if (endsWithNoCase(path_, oldExtension)) {
|
||||
std::string newPath = path_.substr(0, path_.size() - oldExtension.size());
|
||||
return Path(newPath + newExtension);
|
||||
} else {
|
||||
return Path(*this);
|
||||
}
|
||||
}
|
||||
|
||||
Path Path::WithReplacedExtension(const std::string &newExtension) const {
|
||||
_dbg_assert_(!newExtension.empty() && newExtension[0] == '.');
|
||||
if (path_.empty()) {
|
||||
return Path(*this);
|
||||
}
|
||||
std::string extension = GetFileExtension();
|
||||
std::string newPath = path_.substr(0, path_.size() - extension.size()) + newExtension;
|
||||
return Path(newPath);
|
||||
}
|
||||
|
||||
std::string Path::GetFilename() const {
|
||||
size_t pos = path_.rfind('/');
|
||||
if (pos != std::string::npos) {
|
||||
return path_.substr(pos + 1);
|
||||
}
|
||||
// No directory components, just return the full path.
|
||||
return path_;
|
||||
}
|
||||
|
||||
std::string Path::GetFileExtension() const {
|
||||
size_t pos = path_.rfind(".");
|
||||
if (pos == std::string::npos) {
|
||||
@ -72,17 +106,27 @@ std::string Path::GetFileExtension() const {
|
||||
// Don't want to detect "df/file" from "/as.df/file"
|
||||
return "";
|
||||
}
|
||||
std::string ext = path_.substr(pos + 1);
|
||||
std::string ext = path_.substr(pos);
|
||||
for (size_t i = 0; i < ext.size(); i++) {
|
||||
ext[i] = tolower(ext[i]);
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
Path Path::Directory() const {
|
||||
std::string directory;
|
||||
SplitPath(path_, &directory, nullptr, nullptr);
|
||||
return Path(directory);
|
||||
std::string Path::GetDirectory() const {
|
||||
size_t pos = path_.rfind('/');
|
||||
if (pos != std::string::npos) {
|
||||
return path_.substr(0, pos);
|
||||
} else {
|
||||
// There could be a ':', too. Unlike the slash, let's include that
|
||||
// in the returned directory.
|
||||
size_t c_pos = path_.rfind(':');
|
||||
if (c_pos != std::string::npos) {
|
||||
return path_.substr(0, c_pos + 1);
|
||||
}
|
||||
}
|
||||
// No directory components, just return the full path.
|
||||
return path_;
|
||||
}
|
||||
|
||||
bool Path::FilePathContains(const std::string &needle) const {
|
||||
@ -125,6 +169,11 @@ bool Path::CanNavigateUp() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
Path Path::NavigateUp() const {
|
||||
std::string dir = GetDirectory();
|
||||
return Path(dir);
|
||||
}
|
||||
|
||||
bool Path::IsAbsolute() const {
|
||||
if (path_.empty())
|
||||
return true;
|
||||
|
@ -59,11 +59,12 @@ public:
|
||||
// File extension manipulation.
|
||||
Path WithExtraExtension(const std::string &ext) const;
|
||||
Path WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const;
|
||||
Path WithReplacedExtension(const std::string &newExtension) const;
|
||||
|
||||
// Removes the last component.
|
||||
Path Directory() const;
|
||||
|
||||
std::string GetFileExtension() const;
|
||||
std::string GetFilename() const; // Really, GetLastComponent. Could be a file or directory.
|
||||
std::string GetFileExtension() const; // Always lowercase return. Includes the dot.
|
||||
std::string GetDirectory() const;
|
||||
|
||||
const std::string &ToString() const;
|
||||
|
||||
@ -74,6 +75,8 @@ public:
|
||||
std::string ToVisualString() const;
|
||||
|
||||
bool CanNavigateUp() const;
|
||||
Path NavigateUp() const;
|
||||
|
||||
bool operator ==(const Path &other) const {
|
||||
return path_ == other.path_ && type_ == other.type_;
|
||||
}
|
||||
|
@ -125,22 +125,6 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetFilenameFromPath(std::string full_path) {
|
||||
size_t pos;
|
||||
#ifdef _WIN32
|
||||
pos = full_path.rfind('\\');
|
||||
if (pos != std::string::npos) {
|
||||
return full_path.substr(pos + 1);
|
||||
}
|
||||
#endif
|
||||
pos = full_path.rfind('/');
|
||||
if (pos != std::string::npos) {
|
||||
return full_path.substr(pos + 1);
|
||||
}
|
||||
// No directory components, just return the full path.
|
||||
return full_path;
|
||||
}
|
||||
|
||||
std::string LineNumberString(const std::string &str) {
|
||||
std::stringstream input(str);
|
||||
std::stringstream output;
|
||||
|
@ -101,5 +101,3 @@ inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...)
|
||||
|
||||
// "C:/Windows/winhelp.exe" to "C:/Windows/", "winhelp", ".exe"
|
||||
bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension);
|
||||
|
||||
std::string GetFilenameFromPath(std::string full_path);
|
||||
|
@ -1536,7 +1536,7 @@ void Config::RemoveRecent(const std::string &file) {
|
||||
void Config::CleanRecent() {
|
||||
std::vector<std::string> cleanedRecent;
|
||||
for (size_t i = 0; i < recentIsos.size(); i++) {
|
||||
FileLoader *loader = ConstructFileLoader(recentIsos[i]);
|
||||
FileLoader *loader = ConstructFileLoader(Path(recentIsos[i]));
|
||||
if (loader->ExistsFast()) {
|
||||
// Make sure we don't have any redundant items.
|
||||
auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), recentIsos[i]);
|
||||
@ -1577,7 +1577,8 @@ const Path Config::FindConfigFile(const std::string &baseFilename) {
|
||||
|
||||
const Path filename = defaultPath_ / baseFilename;
|
||||
if (!File::Exists(filename)) {
|
||||
Path path = filename.Directory();
|
||||
// Make sure at least the directory it's supposed to be in exists.
|
||||
Path path = filename.NavigateUp();
|
||||
if (createdPath_ != path) {
|
||||
File::CreateFullPath(path);
|
||||
createdPath_ = path;
|
||||
|
@ -45,7 +45,7 @@ static const u32 CACHE_SPACE_FLEX = 4;
|
||||
|
||||
Path DiskCachingFileLoaderCache::cacheDir_;
|
||||
|
||||
std::map<std::string, DiskCachingFileLoaderCache *> DiskCachingFileLoader::caches_;
|
||||
std::map<Path, DiskCachingFileLoaderCache *> DiskCachingFileLoader::caches_;
|
||||
std::mutex DiskCachingFileLoader::cachesMutex_;
|
||||
|
||||
// Takes ownership of backend.
|
||||
@ -118,11 +118,11 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data,
|
||||
return readSize;
|
||||
}
|
||||
|
||||
std::vector<std::string> DiskCachingFileLoader::GetCachedPathsInUse() {
|
||||
std::vector<Path> DiskCachingFileLoader::GetCachedPathsInUse() {
|
||||
std::lock_guard<std::mutex> guard(cachesMutex_);
|
||||
|
||||
// This is on the file loader so that it can manage the caches_.
|
||||
std::vector<std::string> files;
|
||||
std::vector<Path> files;
|
||||
|
||||
for (auto it : caches_) {
|
||||
files.push_back(it.first);
|
||||
@ -134,7 +134,7 @@ std::vector<std::string> DiskCachingFileLoader::GetCachedPathsInUse() {
|
||||
void DiskCachingFileLoader::InitCache() {
|
||||
std::lock_guard<std::mutex> guard(cachesMutex_);
|
||||
|
||||
std::string path = ProxiedFileLoader::GetPath();
|
||||
Path path = ProxiedFileLoader::GetPath();
|
||||
auto &entry = caches_[path];
|
||||
if (!entry) {
|
||||
entry = new DiskCachingFileLoaderCache(path, filesize_);
|
||||
@ -155,7 +155,7 @@ void DiskCachingFileLoader::ShutdownCache() {
|
||||
cache_ = nullptr;
|
||||
}
|
||||
|
||||
DiskCachingFileLoaderCache::DiskCachingFileLoaderCache(const std::string &path, u64 filesize)
|
||||
DiskCachingFileLoaderCache::DiskCachingFileLoaderCache(const Path &path, u64 filesize)
|
||||
: filesize_(filesize), origPath_(path) {
|
||||
InitCache(path);
|
||||
}
|
||||
@ -164,7 +164,7 @@ DiskCachingFileLoaderCache::~DiskCachingFileLoaderCache() {
|
||||
ShutdownCache();
|
||||
}
|
||||
|
||||
void DiskCachingFileLoaderCache::InitCache(const std::string &filename) {
|
||||
void DiskCachingFileLoaderCache::InitCache(const Path &filename) {
|
||||
cacheSize_ = 0;
|
||||
indexCount_ = 0;
|
||||
oldestGeneration_ = 0;
|
||||
@ -172,7 +172,7 @@ void DiskCachingFileLoaderCache::InitCache(const std::string &filename) {
|
||||
flags_ = 0;
|
||||
generation_ = 0;
|
||||
|
||||
const Path cacheFilePath = Path(MakeCacheFilePath(filename));
|
||||
const Path cacheFilePath = MakeCacheFilePath(filename);
|
||||
bool fileLoaded = LoadCacheFile(cacheFilePath);
|
||||
|
||||
// We do some basic locking to protect against two things: crashes and concurrency.
|
||||
@ -409,9 +409,9 @@ u32 DiskCachingFileLoaderCache::AllocateBlock(u32 indexPos) {
|
||||
return INVALID_BLOCK;
|
||||
}
|
||||
|
||||
std::string DiskCachingFileLoaderCache::MakeCacheFilename(const std::string &path) {
|
||||
std::string DiskCachingFileLoaderCache::MakeCacheFilename(const Path &path) {
|
||||
static const char *const invalidChars = "?*:/\\^|<>\"'";
|
||||
std::string filename = path;
|
||||
std::string filename = path.ToString();
|
||||
for (size_t i = 0; i < filename.size(); ++i) {
|
||||
int c = filename[i];
|
||||
if (strchr(invalidChars, c) != nullptr) {
|
||||
@ -421,7 +421,7 @@ std::string DiskCachingFileLoaderCache::MakeCacheFilename(const std::string &pat
|
||||
return filename + ".ppdc";
|
||||
}
|
||||
|
||||
::Path DiskCachingFileLoaderCache::MakeCacheFilePath(const std::string &filename) {
|
||||
::Path DiskCachingFileLoaderCache::MakeCacheFilePath(const Path &filename) {
|
||||
Path dir = cacheDir_;
|
||||
if (dir.empty()) {
|
||||
dir = GetSysDirectory(DIRECTORY_CACHE);
|
||||
@ -801,9 +801,9 @@ u32 DiskCachingFileLoaderCache::CountCachedFiles() {
|
||||
|
||||
void DiskCachingFileLoaderCache::GarbageCollectCacheFiles(u64 goalBytes) {
|
||||
// We attempt to free up at least enough files from the cache to get goalBytes more space.
|
||||
const std::vector<std::string> usedPaths = DiskCachingFileLoader::GetCachedPathsInUse();
|
||||
const std::vector<Path> usedPaths = DiskCachingFileLoader::GetCachedPathsInUse();
|
||||
std::set<std::string> used;
|
||||
for (std::string path : usedPaths) {
|
||||
for (const Path &path : usedPaths) {
|
||||
used.insert(MakeCacheFilename(path));
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
}
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
static std::vector<std::string> GetCachedPathsInUse();
|
||||
static std::vector<Path> GetCachedPathsInUse();
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
@ -55,13 +55,13 @@ private:
|
||||
|
||||
// We don't support concurrent disk cache access (we use memory cached indexes.)
|
||||
// So we have to ensure there's only one of these per.
|
||||
static std::map<std::string, DiskCachingFileLoaderCache *> caches_;
|
||||
static std::map<Path, DiskCachingFileLoaderCache *> caches_;
|
||||
static std::mutex cachesMutex_;
|
||||
};
|
||||
|
||||
class DiskCachingFileLoaderCache {
|
||||
public:
|
||||
DiskCachingFileLoaderCache(const std::string &path, u64 filesize);
|
||||
DiskCachingFileLoaderCache(const Path &path, u64 filesize);
|
||||
~DiskCachingFileLoaderCache();
|
||||
|
||||
bool IsValid() {
|
||||
@ -87,7 +87,7 @@ public:
|
||||
bool HasData() const;
|
||||
|
||||
private:
|
||||
void InitCache(const std::string &path);
|
||||
void InitCache(const Path &path);
|
||||
void ShutdownCache();
|
||||
bool MakeCacheSpaceFor(size_t blocks);
|
||||
void RebalanceGenerations();
|
||||
@ -99,8 +99,8 @@ private:
|
||||
void WriteIndexData(u32 indexPos, BlockInfo &info);
|
||||
s64 GetBlockOffset(u32 block);
|
||||
|
||||
::Path MakeCacheFilePath(const std::string &filename);
|
||||
std::string MakeCacheFilename(const std::string &path);
|
||||
Path MakeCacheFilePath(const Path &filename);
|
||||
std::string MakeCacheFilename(const Path &path);
|
||||
bool LoadCacheFile(const Path &path);
|
||||
void LoadCacheIndex();
|
||||
void CreateCacheFile(const Path &path);
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "Core/Config.h"
|
||||
#include "Core/FileLoaders/HTTPFileLoader.h"
|
||||
|
||||
HTTPFileLoader::HTTPFileLoader(const std::string &filename)
|
||||
: url_(filename), progress_(&cancel_), filename_(filename) {
|
||||
HTTPFileLoader::HTTPFileLoader(const ::Path &filename)
|
||||
: url_(filename.ToString()), progress_(&cancel_), filename_(filename) {
|
||||
}
|
||||
|
||||
void HTTPFileLoader::Prepare() {
|
||||
@ -172,7 +172,7 @@ s64 HTTPFileLoader::FileSize() {
|
||||
return filesize_;
|
||||
}
|
||||
|
||||
std::string HTTPFileLoader::GetPath() const {
|
||||
Path HTTPFileLoader::GetPath() const {
|
||||
return filename_;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/Net/HTTPClient.h"
|
||||
#include "Common/Net/Resolve.h"
|
||||
#include "Common/Net/URL.h"
|
||||
@ -28,7 +29,7 @@
|
||||
|
||||
class HTTPFileLoader : public FileLoader {
|
||||
public:
|
||||
HTTPFileLoader(const std::string &filename);
|
||||
HTTPFileLoader(const ::Path &filename);
|
||||
virtual ~HTTPFileLoader() override;
|
||||
|
||||
bool IsRemote() override {
|
||||
@ -38,7 +39,7 @@ public:
|
||||
virtual bool ExistsFast() override;
|
||||
virtual bool IsDirectory() override;
|
||||
virtual s64 FileSize() override;
|
||||
virtual std::string GetPath() const override;
|
||||
virtual Path GetPath() const override;
|
||||
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(absolutePos, bytes * count, data, flags) / bytes;
|
||||
@ -71,7 +72,7 @@ private:
|
||||
Url url_;
|
||||
http::Client client_;
|
||||
http::RequestProgress progress_;
|
||||
std::string filename_;
|
||||
::Path filename_;
|
||||
bool connected_ = false;
|
||||
bool cancel_ = false;
|
||||
const char *latestError_ = "";
|
||||
|
@ -32,7 +32,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
LocalFileLoader::LocalFileLoader(int fd, const std::string &filename) : fd_(fd), filename_(filename), isOpenedByFd_(fd != -1) {
|
||||
LocalFileLoader::LocalFileLoader(int fd, const Path &filename) : fd_(fd), filename_(filename), isOpenedByFd_(fd != -1) {
|
||||
if (fd != -1) {
|
||||
DetectSizeFd();
|
||||
}
|
||||
@ -51,7 +51,7 @@ void LocalFileLoader::DetectSizeFd() {
|
||||
}
|
||||
#endif
|
||||
|
||||
LocalFileLoader::LocalFileLoader(const std::string &filename)
|
||||
LocalFileLoader::LocalFileLoader(const Path &filename)
|
||||
: filesize_(0), filename_(filename), isOpenedByFd_(false) {
|
||||
if (filename.empty()) {
|
||||
ERROR_LOG(FILESYS, "LocalFileLoader can't load empty filenames");
|
||||
@ -70,9 +70,9 @@ LocalFileLoader::LocalFileLoader(const std::string &filename)
|
||||
|
||||
const DWORD access = GENERIC_READ, share = FILE_SHARE_READ, mode = OPEN_EXISTING, flags = FILE_ATTRIBUTE_NORMAL;
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
handle_ = CreateFile2(ConvertUTF8ToWString(filename).c_str(), access, share, mode, nullptr);
|
||||
handle_ = CreateFile2(filename.ToWString().c_str(), access, share, mode, nullptr);
|
||||
#else
|
||||
handle_ = CreateFile(ConvertUTF8ToWString(filename).c_str(), access, share, nullptr, mode, flags, nullptr);
|
||||
handle_ = CreateFile(filename.ToWString().c_str(), access, share, nullptr, mode, flags, nullptr);
|
||||
#endif
|
||||
if (handle_ == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
@ -130,10 +130,6 @@ s64 LocalFileLoader::FileSize() {
|
||||
return filesize_;
|
||||
}
|
||||
|
||||
std::string LocalFileLoader::GetPath() const {
|
||||
return filename_.ToString();
|
||||
}
|
||||
|
||||
size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) {
|
||||
if (bytes == 0)
|
||||
return 0;
|
||||
|
@ -23,21 +23,22 @@
|
||||
#include "Common/File/Path.h"
|
||||
#include "Core/Loaders.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef void *HANDLE;
|
||||
#endif
|
||||
|
||||
class LocalFileLoader : public FileLoader {
|
||||
public:
|
||||
LocalFileLoader(const std::string &filename);
|
||||
LocalFileLoader(const int fd, const std::string &filename);
|
||||
LocalFileLoader(const Path &filename);
|
||||
LocalFileLoader(const int fd, const Path &filename);
|
||||
virtual ~LocalFileLoader();
|
||||
|
||||
virtual bool Exists() override;
|
||||
virtual bool IsDirectory() override;
|
||||
virtual s64 FileSize() override;
|
||||
virtual std::string GetPath() const override;
|
||||
virtual Path GetPath() const override {
|
||||
return filename_;
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
@ -48,7 +49,7 @@ private:
|
||||
HANDLE handle_;
|
||||
#endif
|
||||
u64 filesize_;
|
||||
::Path filename_;
|
||||
Path filename_;
|
||||
std::mutex readLock_;
|
||||
bool isOpenedByFd_;
|
||||
};
|
||||
|
@ -129,7 +129,7 @@ bool BlobFileSystem::RemoveFile(const std::string &filename) {
|
||||
}
|
||||
|
||||
bool BlobFileSystem::GetHostPath(const std::string &inpath, Path &outpath) {
|
||||
outpath = Path(fileLoader_->GetPath());
|
||||
outpath = fileLoader_->GetPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@
|
||||
|
||||
const std::string INDEX_FILENAME = ".ppsspp-index.lst";
|
||||
|
||||
VirtualDiscFileSystem::VirtualDiscFileSystem(IHandleAllocator *_hAlloc, std::string _basePath)
|
||||
: basePath(_basePath),currentBlockIndex(0) {
|
||||
VirtualDiscFileSystem::VirtualDiscFileSystem(IHandleAllocator *_hAlloc, const Path &_basePath)
|
||||
: basePath(_basePath), currentBlockIndex(0) {
|
||||
hAlloc = _hAlloc;
|
||||
LoadFileListIndex();
|
||||
}
|
||||
@ -78,13 +78,6 @@ void VirtualDiscFileSystem::LoadFileListIndex() {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
in.open(filename.c_str(), std::ios::in);
|
||||
if (in.fail()) {
|
||||
>>>>>>> 52a34c2de (Introduce Path, start using it all over the place.)
|
||||
return;
|
||||
}*/
|
||||
|
||||
std::string buf;
|
||||
static const int MAX_LINE_SIZE = 2048;
|
||||
char linebuf[MAX_LINE_SIZE]{};
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
class VirtualDiscFileSystem: public IFileSystem {
|
||||
public:
|
||||
VirtualDiscFileSystem(IHandleAllocator *_hAlloc, std::string _basePath);
|
||||
VirtualDiscFileSystem(IHandleAllocator *_hAlloc, const Path &_basePath);
|
||||
~VirtualDiscFileSystem();
|
||||
|
||||
void DoState(PointerWrap &p) override;
|
||||
|
@ -482,7 +482,7 @@ static u32 sceUmdGetErrorStat()
|
||||
return umdErrorStat;
|
||||
}
|
||||
|
||||
void __UmdReplace(std::string filepath) {
|
||||
void __UmdReplace(Path filepath) {
|
||||
std::string error = "";
|
||||
if (!UmdReplace(filepath, error)) {
|
||||
ERROR_LOG(SCEIO, "UMD Replace failed: %s", error.c_str());
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/File/Path.h"
|
||||
|
||||
enum pspUmdState {
|
||||
PSP_UMD_INIT = 0x00,
|
||||
PSP_UMD_NOT_PRESENT = 0x01,
|
||||
@ -41,7 +43,7 @@ enum pspUmdType {
|
||||
void __UmdInit();
|
||||
void __UmdDoState(PointerWrap &p);
|
||||
|
||||
void __UmdReplace(std::string filepath);
|
||||
void __UmdReplace(Path filepath);
|
||||
bool getUMDReplacePermit();
|
||||
|
||||
void Register_sceUmdUser();
|
||||
|
@ -40,8 +40,8 @@ void RegisterFileLoaderFactory(std::string prefix, std::unique_ptr<FileLoaderFac
|
||||
factories[prefix] = std::move(factory);
|
||||
}
|
||||
|
||||
FileLoader *ConstructFileLoader(const std::string &filename) {
|
||||
if (filename.find("http://") == 0 || filename.find("https://") == 0) {
|
||||
FileLoader *ConstructFileLoader(const Path &filename) {
|
||||
if (filename.Type() == PathType::HTTP) {
|
||||
FileLoader *baseLoader = new RetryingFileLoader(new HTTPFileLoader(filename));
|
||||
// For headless, avoid disk caching since it's usually used for tests that might mutate.
|
||||
if (!PSP_CoreParameter().headLess) {
|
||||
@ -51,7 +51,7 @@ FileLoader *ConstructFileLoader(const std::string &filename) {
|
||||
}
|
||||
|
||||
for (auto &iter : factories) {
|
||||
if (startsWith(filename, iter.first)) {
|
||||
if (startsWith(filename.ToString(), iter.first)) {
|
||||
return iter.second->ConstructFileLoader(filename);
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
return IdentifiedFileType::ERROR_IDENTIFYING;
|
||||
}
|
||||
|
||||
std::string extension = File::GetFileExtension(fileLoader->GetPath());
|
||||
std::string extension = fileLoader->GetPath().GetFileExtension();
|
||||
if (extension == ".iso") {
|
||||
// may be a psx iso, they have 2352 byte sectors. You never know what some people try to open
|
||||
if ((fileLoader->FileSize() % 2352) == 0) {
|
||||
@ -143,9 +143,9 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
}
|
||||
|
||||
if (id == 'FLE\x7F') {
|
||||
std::string filename = fileLoader->GetPath();
|
||||
Path filename = fileLoader->GetPath();
|
||||
// There are a few elfs misnamed as pbp (like Trig Wars), accept that.
|
||||
if (extension == ".plf" || strstr(filename.c_str(), "BOOT.BIN") ||
|
||||
if (extension == ".plf" || strstr(filename.GetFilename().c_str(), "BOOT.BIN") ||
|
||||
extension == ".elf" || extension == ".prx" || extension == ".pbp") {
|
||||
return IdentifiedFileType::PSP_ELF;
|
||||
}
|
||||
@ -176,14 +176,13 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
|
||||
// Let's check if we got pointed to a PBP within such a directory.
|
||||
// If so we just move up and return the directory itself as the game.
|
||||
std::string path = File::GetDir(fileLoader->GetPath());
|
||||
// If loading from memstick...
|
||||
size_t pos = path.find("PSP/GAME/");
|
||||
if (pos != std::string::npos) {
|
||||
if (fileLoader->GetPath().FilePathContains("PSP/GAME/")) {
|
||||
return IdentifiedFileType::PSP_PBP_DIRECTORY;
|
||||
}
|
||||
return IdentifiedFileType::PSP_PBP;
|
||||
} else if (extension == ".pbp") {
|
||||
}
|
||||
else if (extension == ".pbp") {
|
||||
ERROR_LOG(LOADER, "A PBP with the wrong magic number?");
|
||||
return IdentifiedFileType::PSP_PBP;
|
||||
} else if (extension == ".bin") {
|
||||
@ -205,7 +204,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader) {
|
||||
IdentifiedFileType type = Identify_File(fileLoader);
|
||||
if (type == IdentifiedFileType::PSP_PBP_DIRECTORY) {
|
||||
const std::string ebootFilename = ResolvePBPFile(fileLoader->GetPath());
|
||||
const Path ebootFilename = ResolvePBPFile(fileLoader->GetPath());
|
||||
if (ebootFilename != fileLoader->GetPath()) {
|
||||
// Switch fileLoader to the actual EBOOT.
|
||||
delete fileLoader;
|
||||
@ -215,28 +214,20 @@ FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader) {
|
||||
return fileLoader;
|
||||
}
|
||||
|
||||
std::string ResolvePBPDirectory(const std::string &filename) {
|
||||
bool hasPBP = endsWith(filename, "/EBOOT.PBP");
|
||||
#ifdef _WIN32
|
||||
hasPBP = hasPBP || endsWith(filename, "\\EBOOT.PBP");
|
||||
#endif
|
||||
|
||||
if (hasPBP) {
|
||||
return filename.substr(0, filename.length() - strlen("/EBOOT.PBP"));
|
||||
Path ResolvePBPDirectory(const Path &filename) {
|
||||
if (filename.GetFilename() == "EBOOT.PBP") {
|
||||
return filename.NavigateUp();
|
||||
} else {
|
||||
return filename;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string ResolvePBPFile(const std::string &filename) {
|
||||
bool hasPBP = endsWith(filename, "/EBOOT.PBP");
|
||||
#ifdef _WIN32
|
||||
hasPBP = hasPBP || endsWith(filename, "\\EBOOT.PBP");
|
||||
#endif
|
||||
|
||||
if (!hasPBP) {
|
||||
return filename + "/EBOOT.PBP";
|
||||
Path ResolvePBPFile(const Path &filename) {
|
||||
if (filename.GetFilename() != "EBOOT.PBP") {
|
||||
return filename / "EBOOT.PBP";
|
||||
} else {
|
||||
return filename;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
@ -260,11 +251,12 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
coreState = CORE_BOOT_ERROR;
|
||||
return false;
|
||||
}
|
||||
std::string path = fileLoader->GetPath();
|
||||
size_t pos = path.find("PSP/GAME/");
|
||||
|
||||
std::string dir = fileLoader->GetPath().GetDirectory();
|
||||
size_t pos = dir.find("PSP/GAME/");
|
||||
if (pos != std::string::npos) {
|
||||
path = ResolvePBPDirectory(path);
|
||||
pspFileSystem.SetStartingDirectory("ms0:/" + path.substr(pos));
|
||||
dir = ResolvePBPDirectory(Path(dir)).ToString();
|
||||
pspFileSystem.SetStartingDirectory("ms0:/" + dir.substr(pos));
|
||||
}
|
||||
return Load_PSP_ELF_PBP(fileLoader, error_string);
|
||||
} else {
|
||||
@ -355,7 +347,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UmdReplace(std::string filepath, std::string &error) {
|
||||
bool UmdReplace(const Path &filepath, std::string &error) {
|
||||
IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:");
|
||||
|
||||
if (!currentUMD) {
|
||||
@ -367,7 +359,7 @@ bool UmdReplace(std::string filepath, std::string &error) {
|
||||
|
||||
if (!loadedFile->Exists()) {
|
||||
delete loadedFile;
|
||||
error = loadedFile->GetPath() + " doesn't exist";
|
||||
error = loadedFile->GetPath().ToVisualString() + " doesn't exist";
|
||||
return false;
|
||||
}
|
||||
UpdateLoadedFile(loadedFile);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File/Path.h"
|
||||
|
||||
enum class IdentifiedFileType {
|
||||
ERROR_IDENTIFYING,
|
||||
@ -74,15 +75,15 @@ public:
|
||||
}
|
||||
virtual bool IsDirectory() = 0;
|
||||
virtual s64 FileSize() = 0;
|
||||
virtual std::string GetPath() const = 0;
|
||||
virtual Path GetPath() const = 0;
|
||||
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) = 0;
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) {
|
||||
return ReadAt(absolutePos, 1, bytes, data, flags);
|
||||
}
|
||||
|
||||
// Cancel any operations that might block, if possible.
|
||||
virtual void Cancel() {
|
||||
}
|
||||
virtual void Cancel() {}
|
||||
|
||||
virtual std::string LatestError() const {
|
||||
return "";
|
||||
@ -112,7 +113,7 @@ public:
|
||||
s64 FileSize() override {
|
||||
return backend_->FileSize();
|
||||
}
|
||||
std::string GetPath() const override {
|
||||
Path GetPath() const override {
|
||||
return backend_->GetPath();
|
||||
}
|
||||
void Cancel() override {
|
||||
@ -136,23 +137,23 @@ inline u32 operator & (const FileLoader::Flags &a, const FileLoader::Flags &b) {
|
||||
return (u32)a & (u32)b;
|
||||
}
|
||||
|
||||
FileLoader *ConstructFileLoader(const std::string &filename);
|
||||
FileLoader *ConstructFileLoader(const Path &filename);
|
||||
// Resolve to the target binary, ISO, or other file (e.g. from a directory.)
|
||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
|
||||
|
||||
std::string ResolvePBPDirectory(const std::string &filename);
|
||||
std::string ResolvePBPFile(const std::string &filename);
|
||||
Path ResolvePBPDirectory(const Path &filename);
|
||||
Path ResolvePBPFile(const Path &filename);
|
||||
|
||||
IdentifiedFileType Identify_File(FileLoader *fileLoader);
|
||||
|
||||
class FileLoaderFactory {
|
||||
public:
|
||||
virtual ~FileLoaderFactory() {}
|
||||
virtual FileLoader *ConstructFileLoader(const std::string &filename) = 0;
|
||||
virtual FileLoader *ConstructFileLoader(const Path &filename) = 0;
|
||||
};
|
||||
void RegisterFileLoaderFactory(std::string name, std::unique_ptr<FileLoaderFactory> factory);
|
||||
void RegisterFileLoaderFactory(std::string prefix, std::unique_ptr<FileLoaderFactory> factory);
|
||||
|
||||
// Can modify the string filename, as it calls IdentifyFile above.
|
||||
bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string);
|
||||
|
||||
bool UmdReplace(std::string filepath, std::string &error);
|
||||
bool UmdReplace(const Path &filepath, std::string &error);
|
||||
|
@ -375,16 +375,10 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
pspFileSystem.Mount("umd:", blockSystem);
|
||||
}
|
||||
}
|
||||
|
||||
std::string full_path = fileLoader->GetPath();
|
||||
std::string path, file, extension;
|
||||
SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
|
||||
if (!path.empty() && path.back() == '/')
|
||||
path.resize(path.size() - 1);
|
||||
#ifdef _WIN32
|
||||
if (!path.empty() && path.back() == '\\')
|
||||
path.resize(path.size() - 1);
|
||||
#endif
|
||||
Path full_path = fileLoader->GetPath();
|
||||
std::string path = full_path.GetDirectory();
|
||||
std::string extension = full_path.GetFileExtension();
|
||||
std::string file = full_path.GetFilename();
|
||||
|
||||
size_t pos = path.find("PSP/GAME/");
|
||||
std::string ms_path;
|
||||
@ -396,11 +390,6 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
ms_path = "umd0:/";
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Turn the slashes back to the Windows way.
|
||||
path = ReplaceAll(path, "/", "\\");
|
||||
#endif
|
||||
|
||||
if (!PSP_CoreParameter().mountRoot.empty()) {
|
||||
// We don't want to worry about .. and cwd and such.
|
||||
const Path rootNorm = NormalizePath(PSP_CoreParameter().mountRoot);
|
||||
@ -425,7 +414,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, Path(path), FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD);
|
||||
pspFileSystem.Mount("umd0:", fs);
|
||||
|
||||
std::string finalName = ms_path + file + extension;
|
||||
std::string finalName = ms_path + file;
|
||||
|
||||
std::string homebrewName = PSP_CoreParameter().fileToStart.ToVisualString();
|
||||
std::size_t lslash = homebrewName.find_last_of("/");
|
||||
@ -449,14 +438,14 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
Path oldNamePrefix = savestateDir / StringFromFormat("%s_%d", homebrewName.c_str(), i);
|
||||
Path oldIDPrefix = savestateDir / StringFromFormat("%s_1.00_%d", madeUpID.c_str(), i);
|
||||
|
||||
if (oldIDPrefix != newPrefix && File::Exists(oldIDPrefix.WithExtraExtension("ppst")))
|
||||
File::Rename(oldIDPrefix.WithExtraExtension("ppst"), newPrefix.WithExtraExtension("ppst"));
|
||||
else if (File::Exists(oldNamePrefix.WithExtraExtension("ppst")))
|
||||
File::Rename(oldNamePrefix.WithExtraExtension("ppst"), newPrefix.WithExtraExtension("ppst"));
|
||||
if (oldIDPrefix != newPrefix && File::Exists(oldIDPrefix.WithExtraExtension("jpg")))
|
||||
File::Rename(oldIDPrefix.WithExtraExtension("jpg"), newPrefix.WithExtraExtension("jpg"));
|
||||
else if (File::Exists(oldNamePrefix.WithExtraExtension("jpg")))
|
||||
File::Rename(oldNamePrefix.WithExtraExtension("jpg"), newPrefix.WithExtraExtension("jpg"));
|
||||
if (oldIDPrefix != newPrefix && File::Exists(oldIDPrefix.WithExtraExtension(".ppst")))
|
||||
File::Rename(oldIDPrefix.WithExtraExtension(".ppst"), newPrefix.WithExtraExtension(".ppst"));
|
||||
else if (File::Exists(oldNamePrefix.WithExtraExtension(".ppst")))
|
||||
File::Rename(oldNamePrefix.WithExtraExtension(".ppst"), newPrefix.WithExtraExtension(".ppst"));
|
||||
if (oldIDPrefix != newPrefix && File::Exists(oldIDPrefix.WithExtraExtension(".jpg")))
|
||||
File::Rename(oldIDPrefix.WithExtraExtension(".jpg"), newPrefix.WithExtraExtension(".jpg"));
|
||||
else if (File::Exists(oldNamePrefix.WithExtraExtension(".jpg")))
|
||||
File::Rename(oldNamePrefix.WithExtraExtension(".jpg"), newPrefix.WithExtraExtension(".jpg"));
|
||||
}
|
||||
|
||||
PSPLoaders_Shutdown();
|
||||
|
@ -101,8 +101,8 @@ namespace Reporting
|
||||
|
||||
static std::mutex crcLock;
|
||||
static std::condition_variable crcCond;
|
||||
static std::string crcFilename;
|
||||
static std::map<std::string, u32> crcResults;
|
||||
static Path crcFilename;
|
||||
static std::map<Path, u32> crcResults;
|
||||
static volatile bool crcPending = false;
|
||||
static volatile bool crcCancel = false;
|
||||
static std::thread crcThread;
|
||||
@ -126,11 +126,10 @@ namespace Reporting
|
||||
crcResults[crcFilename] = crc;
|
||||
crcPending = false;
|
||||
crcCond.notify_one();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QueueCRC(const std::string &gamePath) {
|
||||
void QueueCRC(const Path &gamePath) {
|
||||
std::lock_guard<std::mutex> guard(crcLock);
|
||||
|
||||
auto it = crcResults.find(gamePath);
|
||||
@ -151,12 +150,12 @@ namespace Reporting
|
||||
crcThread = std::thread(CalculateCRCThread);
|
||||
}
|
||||
|
||||
bool HasCRC(const std::string &gamePath) {
|
||||
bool HasCRC(const Path &gamePath) {
|
||||
std::lock_guard<std::mutex> guard(crcLock);
|
||||
return crcResults.find(gamePath) != crcResults.end();
|
||||
}
|
||||
|
||||
uint32_t RetrieveCRC(const std::string &gamePath) {
|
||||
uint32_t RetrieveCRC(const Path &gamePath) {
|
||||
QueueCRC(gamePath);
|
||||
|
||||
std::unique_lock<std::mutex> guard(crcLock);
|
||||
@ -173,11 +172,11 @@ namespace Reporting
|
||||
|
||||
static uint32_t RetrieveCRCUnlessPowerSaving(const Path &gamePath) {
|
||||
// It's okay to use it if we have it already.
|
||||
if (Core_GetPowerSaving() && !HasCRC(gamePath.ToString())) {
|
||||
if (Core_GetPowerSaving() && !HasCRC(gamePath)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return RetrieveCRC(gamePath.ToString());
|
||||
return RetrieveCRC(gamePath);
|
||||
}
|
||||
|
||||
static void PurgeCRC() {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
#define DEBUG_LOG_REPORT(t,...) do { DEBUG_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false)
|
||||
@ -88,14 +89,14 @@ namespace Reporting
|
||||
std::vector<std::string> CompatibilitySuggestions();
|
||||
|
||||
// Queues game for CRC hash if needed.
|
||||
void QueueCRC(const std::string &gamePath);
|
||||
void QueueCRC(const Path &gamePath);
|
||||
|
||||
// Returns true if the hash is available, does not queue if not.
|
||||
bool HasCRC(const std::string &gamePath);
|
||||
bool HasCRC(const Path &gamePath);
|
||||
|
||||
// Blocks until the CRC hash is available for game, and returns it.
|
||||
// To avoid stalling, call HasCRC() in update() or similar and call this if it returns true.
|
||||
uint32_t RetrieveCRC(const std::string &gamePath);
|
||||
uint32_t RetrieveCRC(const Path &gamePath);
|
||||
|
||||
// Returns true if that identifier has not been logged yet.
|
||||
bool ShouldLogNTimes(const char *identifier, int n);
|
||||
|
@ -463,7 +463,7 @@ namespace SaveState
|
||||
}
|
||||
|
||||
static void SwapIfExists(const Path &from, const Path &to) {
|
||||
Path temp = from.WithExtraExtension("tmp");
|
||||
Path temp = from.WithExtraExtension(".tmp");
|
||||
if (File::Exists(from)) {
|
||||
File::Rename(from, temp);
|
||||
File::Rename(to, from);
|
||||
@ -486,7 +486,7 @@ namespace SaveState
|
||||
} else {
|
||||
DeleteIfExists(fn);
|
||||
}
|
||||
File::Rename(fn.WithExtraExtension("tmp"), fn);
|
||||
File::Rename(fn.WithExtraExtension(".tmp"), fn);
|
||||
}
|
||||
if (callback) {
|
||||
callback(status, message, data);
|
||||
@ -498,7 +498,7 @@ namespace SaveState
|
||||
RenameIfExists(shot, shotUndo);
|
||||
}
|
||||
SaveScreenshot(shot, Callback(), 0);
|
||||
Save(fn.WithExtraExtension("tmp"), slot, renameCallback, cbUserData);
|
||||
Save(fn.WithExtraExtension(".tmp"), slot, renameCallback, cbUserData);
|
||||
} else {
|
||||
auto sy = GetI18NCategory("System");
|
||||
if (callback)
|
||||
@ -532,7 +532,7 @@ namespace SaveState
|
||||
bool HasUndoSaveInSlot(const std::string &gameFilename, int slot)
|
||||
{
|
||||
Path fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
|
||||
return File::Exists(fn.WithExtraExtension("undo"));
|
||||
return File::Exists(fn.WithExtraExtension(".undo"));
|
||||
}
|
||||
|
||||
bool HasScreenshotInSlot(const std::string &gameFilename, int slot)
|
||||
|
@ -231,7 +231,7 @@ bool CPU_Init() {
|
||||
Memory::g_PSPModel = g_Config.iPSPModel;
|
||||
|
||||
Path filename = coreParameter.fileToStart;
|
||||
loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename.ToString()));
|
||||
loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename));
|
||||
#if PPSSPP_ARCH(AMD64)
|
||||
if (g_Config.bCacheFullIsoInRam) {
|
||||
loadedFile = new RamCachingFileLoader(loadedFile);
|
||||
@ -241,7 +241,7 @@ bool CPU_Init() {
|
||||
|
||||
// TODO: Put this somewhere better?
|
||||
if (!coreParameter.mountIso.empty()) {
|
||||
coreParameter.mountIsoLoader = ConstructFileLoader(coreParameter.mountIso.ToString());
|
||||
coreParameter.mountIsoLoader = ConstructFileLoader(coreParameter.mountIso);
|
||||
}
|
||||
|
||||
MIPSAnalyst::Reset();
|
||||
|
@ -15,6 +15,8 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
@ -137,7 +139,7 @@ void GameManager::Update() {
|
||||
return;
|
||||
}
|
||||
// Game downloaded to temporary file - install it!
|
||||
InstallGameOnThread(curDownload_->url(), fileName.ToString(), true);
|
||||
InstallGameOnThread(Path(curDownload_->url()), fileName, true);
|
||||
} else {
|
||||
ERROR_LOG(HLE, "Expected HTTP status code 200, got status code %d. Install cancelled, deleting partial file '%s'",
|
||||
curDownload_->ResultCode(), fileName.c_str());
|
||||
@ -169,7 +171,7 @@ static void countSlashes(const std::string &fileName, int *slashLocation, int *s
|
||||
}
|
||||
}
|
||||
|
||||
ZipFileContents DetectZipFileContents(std::string fileName, ZipFileInfo *info) {
|
||||
ZipFileContents DetectZipFileContents(const Path &fileName, ZipFileInfo *info) {
|
||||
int error = 0;
|
||||
struct zip *z = zip_open(fileName.c_str(), 0, &error);
|
||||
if (!z) {
|
||||
@ -254,7 +256,8 @@ ZipFileContents DetectZipFileContents(struct zip *z, ZipFileInfo *info) {
|
||||
}
|
||||
}
|
||||
|
||||
bool GameManager::InstallGame(const std::string &url, const std::string &fileName, bool deleteAfter) {
|
||||
// Parameters need to be by value, since this is a thread func.
|
||||
bool GameManager::InstallGame(Path url, Path fileName, bool deleteAfter) {
|
||||
if (installInProgress_) {
|
||||
ERROR_LOG(HLE, "Cannot have two installs in progress at the same time");
|
||||
return false;
|
||||
@ -265,10 +268,11 @@ bool GameManager::InstallGame(const std::string &url, const std::string &fileNam
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string extension = url.GetFileExtension();
|
||||
// Examine the URL to guess out what we're installing.
|
||||
if (endsWithNoCase(url, ".cso") || endsWithNoCase(url, ".iso")) {
|
||||
if (extension == "cso" || extension == "iso") {
|
||||
// It's a raw ISO or CSO file. We just copy it to the destination.
|
||||
std::string shortFilename = GetFilenameFromPath(url);
|
||||
std::string shortFilename = Path(url).GetFilename();
|
||||
return InstallRawISO(fileName, shortFilename, deleteAfter);
|
||||
}
|
||||
|
||||
@ -278,6 +282,8 @@ bool GameManager::InstallGame(const std::string &url, const std::string &fileNam
|
||||
Path pspGame = GetSysDirectory(DIRECTORY_GAME);
|
||||
Path dest = pspGame;
|
||||
int error = 0;
|
||||
|
||||
// TODO(scoped): zip_open ain't gonna work. zip_fdopen though..
|
||||
struct zip *z = zip_open(fileName.c_str(), 0, &error);
|
||||
if (!z) {
|
||||
ERROR_LOG(HLE, "Failed to open ZIP file '%s', error code=%i", fileName.c_str(), error);
|
||||
@ -351,7 +357,7 @@ bool GameManager::DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest)
|
||||
if (games.size() > 1) {
|
||||
// Check for any supported game on their recent list and use that instead.
|
||||
for (const std::string &path : g_Config.recentIsos) {
|
||||
std::string recentID = GetGameID(path);
|
||||
std::string recentID = GetGameID(Path(path));
|
||||
if (games.find(recentID) != games.end()) {
|
||||
gameID = recentID;
|
||||
break;
|
||||
@ -371,7 +377,7 @@ void GameManager::SetInstallError(const std::string &err) {
|
||||
InstallDone();
|
||||
}
|
||||
|
||||
std::string GameManager::GetGameID(const std::string &path) const {
|
||||
std::string GameManager::GetGameID(const Path &path) const {
|
||||
auto loader = ConstructFileLoader(path);
|
||||
std::string id;
|
||||
|
||||
@ -495,7 +501,7 @@ bool GameManager::ExtractFile(struct zip *z, int file_index, const Path &outFile
|
||||
}
|
||||
|
||||
// TODO(scoped): This one will be slightly tricky.
|
||||
bool GameManager::InstallMemstickGame(struct zip *z, const std::string &zipfile, const std::string &dest, const ZipFileInfo &info, bool allowRoot, bool deleteAfter) {
|
||||
bool GameManager::InstallMemstickGame(struct zip *z, const Path &zipfile, const std::string &dest, const ZipFileInfo &info, bool allowRoot, bool deleteAfter) {
|
||||
size_t allBytes = 0;
|
||||
size_t bytesCopied = 0;
|
||||
|
||||
@ -591,7 +597,7 @@ bail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, std::string zipfile, bool deleteAfter) {
|
||||
bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, const Path &zipfile, bool deleteAfter) {
|
||||
// Let's place the output file in the currently selected Games directory.
|
||||
|
||||
std::string fn = zip_get_name(z, isoFileIndex, 0);
|
||||
@ -614,7 +620,7 @@ bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, std::string
|
||||
}
|
||||
zip_close(z);
|
||||
if (deleteAfter) {
|
||||
File::Delete(Path(zipfile));
|
||||
File::Delete(zipfile);
|
||||
}
|
||||
|
||||
z = 0;
|
||||
@ -625,7 +631,7 @@ bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, std::string
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameManager::InstallGameOnThread(std::string url, std::string fileName, bool deleteAfter) {
|
||||
bool GameManager::InstallGameOnThread(const Path &url, const Path &fileName, bool deleteAfter) {
|
||||
if (installInProgress_) {
|
||||
return false;
|
||||
}
|
||||
@ -633,12 +639,12 @@ bool GameManager::InstallGameOnThread(std::string url, std::string fileName, boo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameManager::InstallRawISO(const std::string &file, const std::string &originalName, bool deleteAfter) {
|
||||
bool GameManager::InstallRawISO(const Path &file, const std::string &originalName, bool deleteAfter) {
|
||||
Path destPath = Path(g_Config.currentDirectory) / originalName;
|
||||
// TODO: To save disk space, we should probably attempt a move first.
|
||||
if (File::Copy(Path(file), destPath)) {
|
||||
if (File::Copy(file, destPath)) {
|
||||
if (deleteAfter) {
|
||||
File::Delete(Path(file));
|
||||
File::Delete(file);
|
||||
}
|
||||
}
|
||||
installProgress_ = 1.0f;
|
||||
|
@ -73,20 +73,20 @@ public:
|
||||
}
|
||||
|
||||
// Only returns false if there's already an installation in progress.
|
||||
bool InstallGameOnThread(std::string url, std::string tempFileName, bool deleteAfter);
|
||||
bool InstallGameOnThread(const Path &url, const Path &tempFileName, bool deleteAfter);
|
||||
|
||||
private:
|
||||
bool InstallGame(const std::string &url, const std::string &tempFileName, bool deleteAfter);
|
||||
bool InstallMemstickGame(struct zip *z, const std::string &zipFile, const std::string &pspGame, const ZipFileInfo &info, bool allowRoot, bool deleteAfter);
|
||||
bool InstallZippedISO(struct zip *z, int isoFileIndex, std::string zipfile, bool deleteAfter);
|
||||
bool InstallRawISO(const std::string &zipFile, const std::string &originalName, bool deleteAfter);
|
||||
bool InstallGame(Path url, Path tempFileName, bool deleteAfter);
|
||||
bool InstallMemstickGame(struct zip *z, const Path &zipFile, const std::string &pspGame, const ZipFileInfo &info, bool allowRoot, bool deleteAfter);
|
||||
bool InstallZippedISO(struct zip *z, int isoFileIndex, const Path &zipfile, bool deleteAfter);
|
||||
bool InstallRawISO(const Path &zipFile, const std::string &originalName, bool deleteAfter);
|
||||
void InstallDone();
|
||||
bool ExtractFile(struct zip *z, int file_index, const Path &outFilename, size_t *bytesCopied, size_t allBytes);
|
||||
bool DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest);
|
||||
void SetInstallError(const std::string &err);
|
||||
|
||||
std::string GetTempFilename() const;
|
||||
std::string GetGameID(const std::string &path) const;
|
||||
std::string GetGameID(const Path &path) const;
|
||||
std::string GetPBPGameID(FileLoader *loader) const;
|
||||
std::string GetISOGameID(FileLoader *loader) const;
|
||||
std::shared_ptr<http::Download> curDownload_;
|
||||
@ -115,4 +115,4 @@ struct ZipFileInfo {
|
||||
};
|
||||
|
||||
ZipFileContents DetectZipFileContents(struct zip *z, ZipFileInfo *info);
|
||||
ZipFileContents DetectZipFileContents(std::string fileName, ZipFileInfo *info);
|
||||
ZipFileContents DetectZipFileContents(const Path &fileName, ZipFileInfo *info);
|
||||
|
@ -71,7 +71,7 @@ bool GameInfo::Delete() {
|
||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||
{
|
||||
// TODO: This could be handled by Core/Util/GameManager too somehow.
|
||||
Path directoryToRemove = Path(ResolvePBPDirectory(filePath_.ToString()));
|
||||
Path directoryToRemove = ResolvePBPDirectory(filePath_);
|
||||
INFO_LOG(SYSTEM, "Deleting %s", directoryToRemove.c_str());
|
||||
if (!File::DeleteDirRecursively(directoryToRemove)) {
|
||||
ERROR_LOG(SYSTEM, "Failed to delete file");
|
||||
@ -115,7 +115,7 @@ u64 GameInfo::GetGameSizeInBytes() {
|
||||
switch (fileType) {
|
||||
case IdentifiedFileType::PSP_PBP_DIRECTORY:
|
||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||
return File::GetDirectoryRecursiveSize(Path(ResolvePBPDirectory(filePath_.ToString())), nullptr, File::GETFILES_GETHIDDEN);
|
||||
return File::GetDirectoryRecursiveSize(ResolvePBPDirectory(filePath_), nullptr, File::GETFILES_GETHIDDEN);
|
||||
|
||||
default:
|
||||
return GetFileLoader()->FileSize();
|
||||
@ -201,7 +201,7 @@ bool GameInfo::LoadFromPath(const Path &gamePath) {
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
// No need to rebuild if we already have it loaded.
|
||||
if (filePath_ != gamePath) {
|
||||
fileLoader.reset(ConstructFileLoader(gamePath.ToString()));
|
||||
fileLoader.reset(ConstructFileLoader(gamePath));
|
||||
if (!fileLoader)
|
||||
return false;
|
||||
filePath_ = gamePath;
|
||||
@ -220,7 +220,7 @@ std::shared_ptr<FileLoader> GameInfo::GetFileLoader() {
|
||||
return fileLoader;
|
||||
}
|
||||
if (!fileLoader) {
|
||||
fileLoader.reset(ConstructFileLoader(filePath_.ToString()));
|
||||
fileLoader.reset(ConstructFileLoader(filePath_));
|
||||
}
|
||||
return fileLoader;
|
||||
}
|
||||
@ -361,9 +361,9 @@ public:
|
||||
{
|
||||
auto pbpLoader = info_->GetFileLoader();
|
||||
if (info_->fileType == IdentifiedFileType::PSP_PBP_DIRECTORY) {
|
||||
Path ebootPath = Path(ResolvePBPFile(gamePath_.ToString()));
|
||||
Path ebootPath = ResolvePBPFile(gamePath_);
|
||||
if (ebootPath != gamePath_) {
|
||||
pbpLoader.reset(ConstructFileLoader(ebootPath.ToString()));
|
||||
pbpLoader.reset(ConstructFileLoader(ebootPath));
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ public:
|
||||
if (pbp.IsELF()) {
|
||||
goto handleELF;
|
||||
}
|
||||
ERROR_LOG(LOADER, "invalid pbp %s\n", pbpLoader->GetPath().c_str());
|
||||
ERROR_LOG(LOADER, "invalid pbp '%s'\n", pbpLoader->GetPath().c_str());
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
return;
|
||||
@ -466,7 +466,7 @@ handleELF:
|
||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||
{
|
||||
SequentialHandleAllocator handles;
|
||||
VirtualDiscFileSystem umd(&handles, gamePath_.c_str());
|
||||
VirtualDiscFileSystem umd(&handles, gamePath_);
|
||||
|
||||
// Alright, let's fetch the PARAM.SFO.
|
||||
std::string paramSFOcontents;
|
||||
@ -507,7 +507,7 @@ handleELF:
|
||||
{
|
||||
info_->fileType = IdentifiedFileType::PSP_ISO;
|
||||
SequentialHandleAllocator handles;
|
||||
VirtualDiscFileSystem umd(&handles, gamePath_.c_str());
|
||||
VirtualDiscFileSystem umd(&handles, gamePath_);
|
||||
|
||||
// Alright, let's fetch the PARAM.SFO.
|
||||
std::string paramSFOcontents;
|
||||
|
@ -96,7 +96,7 @@ void GameScreen::CreateViews() {
|
||||
tvRegion_->SetShadow(true);
|
||||
tvCRC_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
tvCRC_->SetShadow(true);
|
||||
tvCRC_->SetVisibility(Reporting::HasCRC(gamePath_.ToString()) ? V_VISIBLE : V_GONE);
|
||||
tvCRC_->SetVisibility(Reporting::HasCRC(gamePath_) ? V_VISIBLE : V_GONE);
|
||||
} else {
|
||||
tvTitle_ = nullptr;
|
||||
tvGameSize_ = nullptr;
|
||||
@ -240,9 +240,9 @@ void GameScreen::render() {
|
||||
}
|
||||
}
|
||||
|
||||
if (tvCRC_ && Reporting::HasCRC(gamePath_.ToString())) {
|
||||
if (tvCRC_ && Reporting::HasCRC(gamePath_)) {
|
||||
auto rp = GetI18NCategory("Reporting");
|
||||
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_.ToString()));
|
||||
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_));
|
||||
tvCRC_->SetText(ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: [VALUE]"), "[VALUE]", crc));
|
||||
tvCRC_->SetVisibility(UI::V_VISIBLE);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ void InstallZipScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
File::FileInfo fileInfo;
|
||||
bool success = File::GetFileInfo(Path(zipPath_), &fileInfo);
|
||||
bool success = File::GetFileInfo(zipPath_, &fileInfo);
|
||||
|
||||
auto di = GetI18NCategory("Dialog");
|
||||
auto iz = GetI18NCategory("InstallZip");
|
||||
@ -43,7 +43,7 @@ void InstallZipScreen::CreateViews() {
|
||||
root_->Add(leftColumn);
|
||||
root_->Add(rightColumnItems);
|
||||
|
||||
std::string shortFilename = GetFilenameFromPath(zipPath_);
|
||||
std::string shortFilename = zipPath_.GetFilename();
|
||||
|
||||
// TODO: Do in the background?
|
||||
ZipFileInfo zipInfo;
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
class InstallZipScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
InstallZipScreen(std::string zipPath) : zipPath_(zipPath) {}
|
||||
InstallZipScreen(const Path &zipPath) : zipPath_(zipPath) {}
|
||||
virtual void update() override;
|
||||
virtual bool key(const KeyInput &key) override;
|
||||
|
||||
@ -40,7 +40,7 @@ private:
|
||||
UI::Choice *backChoice_ = nullptr;
|
||||
UI::ProgressBar *progressBar_ = nullptr;
|
||||
UI::TextView *doneView_ = nullptr;
|
||||
std::string zipPath_;
|
||||
Path zipPath_;
|
||||
bool returnToHomebrew_ = true;
|
||||
bool installStarted_ = false;
|
||||
bool deleteZipFile_ = false;
|
||||
|
@ -69,7 +69,7 @@ bool MainScreen::showHomebrewTab = false;
|
||||
|
||||
bool LaunchFile(ScreenManager *screenManager, const Path &path) {
|
||||
// Depending on the file type, we don't want to launch EmuScreen at all.
|
||||
auto loader = ConstructFileLoader(path.ToString());
|
||||
auto loader = ConstructFileLoader(path);
|
||||
if (!loader) {
|
||||
return false;
|
||||
}
|
||||
@ -79,7 +79,7 @@ bool LaunchFile(ScreenManager *screenManager, const Path &path) {
|
||||
|
||||
switch (type) {
|
||||
case IdentifiedFileType::ARCHIVE_ZIP:
|
||||
screenManager->push(new InstallZipScreen(path.ToString()));
|
||||
screenManager->push(new InstallZipScreen(path));
|
||||
break;
|
||||
default:
|
||||
// Let the EmuScreen take care of it.
|
||||
@ -620,7 +620,7 @@ static bool IsValidPBP(const Path &path, bool allowHomebrew) {
|
||||
if (!File::Exists(path))
|
||||
return false;
|
||||
|
||||
std::unique_ptr<FileLoader> loader(ConstructFileLoader(path.ToString()));
|
||||
std::unique_ptr<FileLoader> loader(ConstructFileLoader(path));
|
||||
PBPReader pbp(loader.get());
|
||||
std::vector<u8> sfoData;
|
||||
if (!pbp.GetSubFile(PBP_PARAM_SFO, &sfoData))
|
||||
@ -1509,7 +1509,7 @@ void UmdReplaceScreen::update() {
|
||||
}
|
||||
|
||||
UI::EventReturn UmdReplaceScreen::OnGameSelected(UI::EventParams &e) {
|
||||
__UmdReplace(e.s);
|
||||
__UmdReplace(Path(e.s));
|
||||
TriggerFinish(DR_OK);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
@ -1525,7 +1525,7 @@ UI::EventReturn UmdReplaceScreen::OnGameSettings(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
UI::EventReturn UmdReplaceScreen::OnGameSelectedInstant(UI::EventParams &e) {
|
||||
__UmdReplace(e.s);
|
||||
__UmdReplace(Path(e.s));
|
||||
TriggerFinish(DR_OK);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
struct ShaderInfo;
|
||||
struct TextureShaderInfo;
|
||||
|
||||
extern std::string boot_filename;
|
||||
extern Path boot_filename;
|
||||
void UIBackgroundInit(UIContext &dc);
|
||||
void UIBackgroundShutdown();
|
||||
|
||||
|
@ -207,7 +207,7 @@ int Win32Mix(short *buffer, int numSamples, int bits, int rate, int channels) {
|
||||
|
||||
// globals
|
||||
static LogListener *logger = nullptr;
|
||||
std::string boot_filename = "";
|
||||
Path boot_filename;
|
||||
|
||||
void NativeHost::InitSound() {
|
||||
#if PPSSPP_PLATFORM(IOS)
|
||||
@ -559,7 +559,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
bool gotBootFilename = false;
|
||||
bool gotoGameSettings = false;
|
||||
bool gotoTouchScreenTest = false;
|
||||
boot_filename = "";
|
||||
boot_filename.clear();
|
||||
|
||||
// Parse command line
|
||||
LogTypes::LOG_LEVELS logLevel = LogTypes::LINFO;
|
||||
@ -644,10 +644,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
}
|
||||
}
|
||||
if (okToLoad) {
|
||||
boot_filename = argv[i];
|
||||
#ifdef _WIN32
|
||||
boot_filename = ReplaceAll(boot_filename, "\\", "/");
|
||||
#endif
|
||||
boot_filename = Path(std::string(argv[i]));
|
||||
skipLogo = true;
|
||||
}
|
||||
if (okToLoad && okToCheck) {
|
||||
@ -758,7 +755,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
screenManager->switchScreen(new MainScreen());
|
||||
screenManager->push(new TouchTestScreen());
|
||||
} else if (skipLogo) {
|
||||
screenManager->switchScreen(new EmuScreen(Path(boot_filename)));
|
||||
screenManager->switchScreen(new EmuScreen(boot_filename));
|
||||
} else {
|
||||
screenManager->switchScreen(new LogoScreen());
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ void ReportScreen::CreateViews() {
|
||||
}
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
if (!Core_GetPowerSaving() && !Reporting::HasCRC(gamePath_.ToString())) {
|
||||
if (!Core_GetPowerSaving() && !Reporting::HasCRC(gamePath_)) {
|
||||
auto crcWarning = new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)));
|
||||
crcWarning->SetShadow(true);
|
||||
crcWarning->SetEnabledPtr(&enableReporting_);
|
||||
@ -334,8 +334,8 @@ void ReportScreen::UpdateCRCInfo() {
|
||||
auto rp = GetI18NCategory("Reporting");
|
||||
std::string updated;
|
||||
|
||||
if (Reporting::HasCRC(gamePath_.ToString())) {
|
||||
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_.ToString()));
|
||||
if (Reporting::HasCRC(gamePath_)) {
|
||||
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_));
|
||||
updated = ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: [VALUE]"), "[VALUE]", crc);
|
||||
} else if (showCRC_) {
|
||||
updated = rp->T("FeedbackCRCCalculating", "Disc CRC: Calculating...");
|
||||
@ -395,7 +395,7 @@ EventReturn ReportScreen::HandleBrowser(EventParams &e) {
|
||||
}
|
||||
|
||||
EventReturn ReportScreen::HandleShowCRC(EventParams &e) {
|
||||
Reporting::QueueCRC(gamePath_.ToString());
|
||||
Reporting::QueueCRC(gamePath_);
|
||||
showCRC_ = true;
|
||||
return EVENT_DONE;
|
||||
}
|
||||
|
@ -426,11 +426,11 @@ bool SavedataBrowser::ByFilename(const UI::View *v1, const UI::View *v2) {
|
||||
}
|
||||
|
||||
static time_t GetTotalSize(const SavedataButton *b) {
|
||||
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath().ToString()));
|
||||
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath()));
|
||||
switch (Identify_File(fileLoader.get())) {
|
||||
case IdentifiedFileType::PSP_PBP_DIRECTORY:
|
||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||
return File::GetDirectoryRecursiveSize(Path(ResolvePBPDirectory(b->GamePath().ToString())), nullptr, File::GETFILES_GETHIDDEN);
|
||||
return File::GetDirectoryRecursiveSize(ResolvePBPDirectory(b->GamePath()), nullptr, File::GETFILES_GETHIDDEN);
|
||||
|
||||
default:
|
||||
return fileLoader->FileSize();
|
||||
@ -447,7 +447,7 @@ bool SavedataBrowser::BySize(const UI::View *v1, const UI::View *v2) {
|
||||
}
|
||||
|
||||
static time_t GetDateSeconds(const SavedataButton *b) {
|
||||
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath().ToString()));
|
||||
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath()));
|
||||
tm datetm;
|
||||
bool success;
|
||||
if (Identify_File(fileLoader.get()) == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) {
|
||||
|
@ -175,6 +175,6 @@ size_t StorageFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, vo
|
||||
}
|
||||
}
|
||||
|
||||
FileLoader *StorageFileLoaderFactory::ConstructFileLoader(const std::string &filename) {
|
||||
FileLoader *StorageFileLoaderFactory::ConstructFileLoader(const Path &filename) {
|
||||
return file_ ? new StorageFileLoader(file_) : nullptr;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Core/Loaders.h"
|
||||
|
||||
// This thing is a terrible abomination that wraps asynchronous file access behind a synchronous interface,
|
||||
@ -24,7 +25,7 @@ public:
|
||||
|
||||
bool IsDirectory() override;
|
||||
s64 FileSize() override;
|
||||
std::string GetPath() const override;
|
||||
Path GetPath() const override;
|
||||
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
@ -73,7 +74,7 @@ private:
|
||||
class StorageFileLoaderFactory : public FileLoaderFactory {
|
||||
public:
|
||||
StorageFileLoaderFactory(Windows::Storage::StorageFile ^file, IdentifiedFileType fileType) : file_(file), fileType_(fileType) { }
|
||||
FileLoader *ConstructFileLoader(const std::string &filename) override;
|
||||
FileLoader *ConstructFileLoader(const Path &filename) override;
|
||||
|
||||
private:
|
||||
Windows::Storage::StorageFile ^file_;
|
||||
|
@ -450,8 +450,7 @@ namespace MainWindow {
|
||||
}
|
||||
|
||||
if (W32Util::BrowseForFileName(true, GetHWND(), L"Switch UMD", 0, ConvertUTF8ToWString(filter).c_str(), L"*.pbp;*.elf;*.iso;*.cso;", fn)) {
|
||||
fn = ReplaceAll(fn, "\\", "/");
|
||||
__UmdReplace(fn);
|
||||
__UmdReplace(Path(fn));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@ struct JNIEnv {};
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/File/VFS/VFS.h"
|
||||
#include "Common/File/VFS/AssetReader.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
@ -248,9 +249,9 @@ int Android_OpenContentUriFd(const std::string &filename) {
|
||||
|
||||
class ContentURIFileLoader : public ProxiedFileLoader {
|
||||
public:
|
||||
ContentURIFileLoader(const std::string &filename)
|
||||
ContentURIFileLoader(const Path &filename)
|
||||
: ProxiedFileLoader(nullptr) { // we overwrite the nullptr below
|
||||
int fd = Android_OpenContentUriFd(filename);
|
||||
int fd = Android_OpenContentUriFd(filename.ToString());
|
||||
INFO_LOG(SYSTEM, "Fd %d for content URI: '%s'", fd, filename.c_str());
|
||||
backend_ = new LocalFileLoader(fd, filename);
|
||||
}
|
||||
@ -267,7 +268,7 @@ public:
|
||||
class AndroidContentLoaderFactory : public FileLoaderFactory {
|
||||
public:
|
||||
AndroidContentLoaderFactory() {}
|
||||
FileLoader *ConstructFileLoader(const std::string &filename) override {
|
||||
FileLoader *ConstructFileLoader(const Path &filename) override {
|
||||
return new ContentURIFileLoader(filename);
|
||||
}
|
||||
};
|
||||
|
@ -168,24 +168,17 @@ protected:
|
||||
size_t pos_ = 0;
|
||||
};
|
||||
|
||||
std::string ExpectedFromFilename(const std::string &bootFilename) {
|
||||
size_t pos = bootFilename.find_last_of('.');
|
||||
if (pos == bootFilename.npos) {
|
||||
return bootFilename + ".expected";
|
||||
Path ExpectedScreenshotFromFilename(const Path &bootFilename) {
|
||||
std::string extension = bootFilename.GetFileExtension();
|
||||
if (extension.empty()) {
|
||||
return bootFilename.WithExtraExtension(".bmp");
|
||||
}
|
||||
return bootFilename.substr(0, pos) + ".expected";
|
||||
}
|
||||
|
||||
std::string ExpectedScreenshotFromFilename(const std::string &bootFilename) {
|
||||
size_t pos = bootFilename.find_last_of('.');
|
||||
if (pos == bootFilename.npos) {
|
||||
return bootFilename + ".bmp";
|
||||
}
|
||||
// Let's use pngs as the default for ppdmp tests.
|
||||
if (bootFilename.substr(pos) == ".ppdmp") {
|
||||
return bootFilename.substr(0, pos) + ".png";
|
||||
if (extension == ".ppdmp") {
|
||||
return bootFilename.WithReplacedExtension(".png");
|
||||
}
|
||||
return bootFilename.substr(0, pos) + ".expected.bmp";
|
||||
return bootFilename.WithReplacedExtension(".expected.bmp");
|
||||
}
|
||||
|
||||
static std::string ChopFront(std::string s, std::string front)
|
||||
@ -209,14 +202,14 @@ static std::string ChopEnd(std::string s, std::string end)
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string GetTestName(const std::string &bootFilename)
|
||||
std::string GetTestName(const Path &bootFilename)
|
||||
{
|
||||
// Kinda ugly, trying to guesstimate the test name from filename...
|
||||
return ChopEnd(ChopFront(ChopFront(bootFilename, "tests/"), "pspautotests/tests/"), ".prx");
|
||||
return ChopEnd(ChopFront(ChopFront(bootFilename.ToString(), "tests/"), "pspautotests/tests/"), ".prx");
|
||||
}
|
||||
|
||||
bool CompareOutput(const std::string &bootFilename, const std::string &output, bool verbose) {
|
||||
std::string expect_filename = ExpectedFromFilename(bootFilename);
|
||||
bool CompareOutput(const Path &bootFilename, const std::string &output, bool verbose) {
|
||||
Path expect_filename = bootFilename.WithReplacedExtension("prx", "expected");
|
||||
std::unique_ptr<FileLoader> expect_loader(ConstructFileLoader(expect_filename));
|
||||
|
||||
if (expect_loader->Exists()) {
|
||||
@ -372,7 +365,7 @@ std::vector<u32> TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32
|
||||
return data;
|
||||
}
|
||||
|
||||
double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32 h, const std::string& screenshotFilename, std::string &error)
|
||||
double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32 h, const Path& screenshotFilename, std::string &error)
|
||||
{
|
||||
if (pixels.size() < stride * h)
|
||||
{
|
||||
@ -388,7 +381,7 @@ double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32
|
||||
if (loader->Exists()) {
|
||||
uint8_t header[2];
|
||||
if (loader->ReadAt(0, 2, header) != 2) {
|
||||
error = "Unable to read screenshot data: " + screenshotFilename;
|
||||
error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
@ -397,7 +390,7 @@ double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32
|
||||
asBitmap = true;
|
||||
// The bitmap header is 14 + 40 bytes. We could validate it but the test would fail either way.
|
||||
if (reference && loader->ReadAt(14 + 40, sizeof(u32), stride * h, reference) != stride * h) {
|
||||
error = "Unable to read screenshot data: " + screenshotFilename;
|
||||
error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
} else {
|
||||
@ -405,23 +398,23 @@ double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32
|
||||
std::vector<uint8_t> compressed;
|
||||
compressed.resize(loader->FileSize());
|
||||
if (loader->ReadAt(0, compressed.size(), &compressed[0]) != compressed.size()) {
|
||||
error = "Unable to read screenshot data: " + screenshotFilename;
|
||||
error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
if (!pngLoadPtr(&compressed[0], compressed.size(), &width, &height, (unsigned char **)&reference)) {
|
||||
error = "Unable to read screenshot data: " + screenshotFilename;
|
||||
error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error = "Unable to read screenshot: " + screenshotFilename;
|
||||
error = "Unable to read screenshot: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
if (!reference) {
|
||||
error = "Unable to allocate screenshot data: " + screenshotFilename;
|
||||
error = "Unable to allocate screenshot data: " + screenshotFilename.ToVisualString();
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File/Path.h"
|
||||
|
||||
struct GPUDebugBuffer;
|
||||
|
||||
@ -27,10 +28,10 @@ extern std::string currentTestName;
|
||||
void TeamCityPrint(const char *fmt, ...);
|
||||
void GitHubActionsPrint(const char *type, const char *fmt, ...);
|
||||
|
||||
std::string ExpectedFromFilename(const std::string &bootFilename);
|
||||
std::string ExpectedScreenshotFromFilename(const std::string &bootFilename);
|
||||
std::string GetTestName(const std::string &bootFilename);
|
||||
Path ExpectedFromFilename(const Path &bootFilename);
|
||||
Path ExpectedScreenshotFromFilename(const Path &bootFilename);
|
||||
std::string GetTestName(const Path &bootFilename);
|
||||
|
||||
bool CompareOutput(const std::string &bootFilename, const std::string &output, bool verbose);
|
||||
bool CompareOutput(const Path &bootFilename, const std::string &output, bool verbose);
|
||||
std::vector<u32> TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32 stride, u32 h);
|
||||
double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32 h, const std::string& screenshotFilename, std::string &error);
|
||||
double CompareScreenshot(const std::vector<u32> &pixels, u32 stride, u32 w, u32 h, const Path &screenshotFilename, std::string &error);
|
||||
|
@ -152,7 +152,7 @@ static HeadlessHost *getHost(GPUCore gpuCore) {
|
||||
bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool autoCompare, bool verbose, double timeout)
|
||||
{
|
||||
// Kinda ugly, trying to guesstimate the test name from filename...
|
||||
currentTestName = GetTestName(coreParameter.fileToStart.ToString());
|
||||
currentTestName = GetTestName(coreParameter.fileToStart);
|
||||
|
||||
std::string output;
|
||||
if (autoCompare)
|
||||
@ -172,7 +172,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool
|
||||
host->BootDone();
|
||||
|
||||
if (autoCompare)
|
||||
headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart.ToString()));
|
||||
headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart));
|
||||
|
||||
bool passed = true;
|
||||
// TODO: We must have some kind of stack overflow or we're not following the ABI right.
|
||||
@ -221,7 +221,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool
|
||||
headlessHost->FlushDebugOutput();
|
||||
|
||||
if (autoCompare && passed)
|
||||
passed = CompareOutput(coreParameter.fileToStart.ToString(), output, verbose);
|
||||
passed = CompareOutput(coreParameter.fileToStart, output, verbose);
|
||||
|
||||
TeamCityPrint("testFinished name='%s'", currentTestName.c_str());
|
||||
|
||||
@ -423,7 +423,7 @@ int main(int argc, const char* argv[])
|
||||
g_Config.flash0Directory = Path(File::GetExeDirectory()) / "assets/flash0";
|
||||
|
||||
if (screenshotFilename != 0)
|
||||
headlessHost->SetComparisonScreenshot(screenshotFilename);
|
||||
headlessHost->SetComparisonScreenshot(Path(std::string(screenshotFilename)));
|
||||
|
||||
#ifdef __ANDROID__
|
||||
// For some reason the debugger installs it with this name?
|
||||
@ -456,7 +456,7 @@ int main(int argc, const char* argv[])
|
||||
bool passed = RunAutoTest(headlessHost, coreParameter, autoCompare, verbose, timeout);
|
||||
if (autoCompare)
|
||||
{
|
||||
std::string testName = GetTestName(coreParameter.fileToStart.ToString());
|
||||
std::string testName = GetTestName(coreParameter.fileToStart);
|
||||
if (passed)
|
||||
{
|
||||
passedTests.push_back(testName);
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/File/Path.h"
|
||||
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/Debugger/SymbolMap.h"
|
||||
@ -66,7 +68,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetComparisonScreenshot(const std::string &filename) {
|
||||
virtual void SetComparisonScreenshot(const Path &filename) {
|
||||
comparisonScreenshot_ = filename;
|
||||
}
|
||||
|
||||
@ -80,7 +82,7 @@ public:
|
||||
protected:
|
||||
void SendOrCollectDebugOutput(const std::string &output);
|
||||
|
||||
std::string comparisonScreenshot_;
|
||||
Path comparisonScreenshot_;
|
||||
std::string debugOutputBuffer_;
|
||||
GPUCore gpuCore_;
|
||||
GraphicsContext *gfx_ = nullptr;
|
||||
|
@ -588,13 +588,18 @@ static bool TestPath() {
|
||||
EXPECT_EQ_STR(path.ToString(), std::string("/asdf/jkl"));
|
||||
|
||||
Path path2("/asdf/jkl");
|
||||
EXPECT_EQ_STR(path2.ToString(), std::string("/asdf/jkl"));
|
||||
EXPECT_EQ_STR(path2.NavigateUp().ToString(), std::string("/asdf"));
|
||||
|
||||
Path path3 = path2 / "foo/bar";
|
||||
EXPECT_EQ_STR(path3.WithExtraExtension("txt").ToString(), std::string("/asdf/jkl/foo/bar.txt"));
|
||||
EXPECT_EQ_STR(path3.WithExtraExtension(".txt").ToString(), std::string("/asdf/jkl/foo/bar.txt"));
|
||||
|
||||
EXPECT_EQ_STR(Path("foo.bar/hello").GetFileExtension(), std::string(""));
|
||||
EXPECT_EQ_STR(Path("foo.bar/hello.txt").WithReplacedExtension("txt", "html").ToString(), std::string("foo.bar/hello.html"));
|
||||
EXPECT_EQ_STR(Path("foo.bar/hello.txt").WithReplacedExtension(".txt", ".html").ToString(), std::string("foo.bar/hello.html"));
|
||||
|
||||
EXPECT_EQ_STR(Path("C:\\Yo").GetDirectory(), std::string("C:"));
|
||||
EXPECT_EQ_STR(Path("C:\\Yo").GetFilename(), std::string("Yo"));
|
||||
EXPECT_EQ_STR(Path("C:\\Yo\\Lo").GetDirectory(), std::string("C:/Yo"));
|
||||
EXPECT_EQ_STR(Path("C:\\Yo\\Lo").GetFilename(), std::string("Lo"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user