mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 09:09:29 +01:00
Merge pull request #8834 from unknownbrackets/report-crc
Send disc CRC with compatibility reports
This commit is contained in:
commit
345e2756a9
20 files changed
+304
-126
No files matched your search
+1
-1
@@ -458,7 +458,7 @@ static ConfigSetting graphicsSettings[] = {
|
||||
ReportedConfigSetting("HighQualityDepth", &g_Config.bHighQualityDepth, true, true, true),
|
||||
ReportedConfigSetting("FrameSkip", &g_Config.iFrameSkip, 0, true, true),
|
||||
ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true),
|
||||
ReportedConfigSetting("FrameRate", &g_Config.iFpsLimit, 0, true, true),
|
||||
ConfigSetting("FrameRate", &g_Config.iFpsLimit, 0, true, true),
|
||||
#ifdef _WIN32
|
||||
ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, false, true, true),
|
||||
ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false),
|
||||
|
||||
@@ -84,7 +84,7 @@ void CachingFileLoader::Seek(s64 absolutePos) {
|
||||
filepos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||
Prepare();
|
||||
if (absolutePos >= filesize_) {
|
||||
bytes = 0;
|
||||
@@ -92,19 +92,25 @@ size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
bytes = filesize_ - absolutePos;
|
||||
}
|
||||
|
||||
size_t readSize = ReadFromCache(absolutePos, bytes, data);
|
||||
// While in case the cache size is too small for the entire read.
|
||||
while (readSize < bytes) {
|
||||
SaveIntoCache(absolutePos + readSize, bytes - readSize);
|
||||
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||
readSize += bytesFromCache;
|
||||
if (bytesFromCache == 0) {
|
||||
// We can't read any more.
|
||||
break;
|
||||
size_t readSize = 0;
|
||||
if ((flags & Flags::HINT_UNCACHED) != 0) {
|
||||
lock_guard guard(backendMutex_);
|
||||
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||
} else {
|
||||
readSize = ReadFromCache(absolutePos, bytes, data);
|
||||
// While in case the cache size is too small for the entire read.
|
||||
while (readSize < bytes) {
|
||||
SaveIntoCache(absolutePos + readSize, bytes - readSize, flags);
|
||||
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||
readSize += bytesFromCache;
|
||||
if (bytesFromCache == 0) {
|
||||
// We can't read any more.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StartReadAhead(absolutePos + readSize);
|
||||
StartReadAhead(absolutePos + readSize);
|
||||
}
|
||||
|
||||
filepos_ = absolutePos + readSize;
|
||||
return readSize;
|
||||
@@ -158,7 +164,7 @@ size_t CachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||
return readSize;
|
||||
}
|
||||
|
||||
void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead) {
|
||||
void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, Flags flags, bool readingAhead) {
|
||||
s64 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
||||
|
||||
@@ -184,7 +190,7 @@ void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead)
|
||||
|
||||
u8 *buf = new u8[BLOCK_SIZE];
|
||||
backendMutex_.lock();
|
||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf);
|
||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf, flags);
|
||||
backendMutex_.unlock();
|
||||
|
||||
blocksMutex_.lock();
|
||||
@@ -200,7 +206,7 @@ void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead)
|
||||
|
||||
u8 *wholeRead = new u8[blocksToRead << BLOCK_SHIFT];
|
||||
backendMutex_.lock();
|
||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead);
|
||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead, flags);
|
||||
backendMutex_.unlock();
|
||||
|
||||
blocksMutex_.lock();
|
||||
@@ -288,7 +294,7 @@ void CachingFileLoader::StartReadAhead(s64 pos) {
|
||||
auto block = blocks_.find(i);
|
||||
if (block == blocks_.end()) {
|
||||
blocksMutex_.unlock();
|
||||
SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, true);
|
||||
SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,25 +25,25 @@
|
||||
class CachingFileLoader : public FileLoader {
|
||||
public:
|
||||
CachingFileLoader(FileLoader *backend);
|
||||
virtual ~CachingFileLoader() override;
|
||||
~CachingFileLoader() override;
|
||||
|
||||
virtual bool Exists() override;
|
||||
virtual bool ExistsFast() override;
|
||||
virtual bool IsDirectory() override;
|
||||
virtual s64 FileSize() override;
|
||||
virtual std::string Path() const override;
|
||||
bool Exists() override;
|
||||
bool ExistsFast() override;
|
||||
bool IsDirectory() override;
|
||||
s64 FileSize() override;
|
||||
std::string Path() const override;
|
||||
|
||||
virtual void Seek(s64 absolutePos) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(filepos_, bytes, count, data);
|
||||
void Seek(s64 absolutePos) override;
|
||||
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, count, data, flags);
|
||||
}
|
||||
virtual size_t Read(size_t bytes, void *data) override {
|
||||
return ReadAt(filepos_, bytes, data);
|
||||
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, data, flags);
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
||||
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;
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
@@ -51,7 +51,7 @@ private:
|
||||
void ShutdownCache();
|
||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||
// Guaranteed to read at least one block into the cache.
|
||||
void SaveIntoCache(s64 pos, size_t bytes, bool readingAhead = false);
|
||||
void SaveIntoCache(s64 pos, size_t bytes, Flags flags, bool readingAhead = false);
|
||||
bool MakeCacheSpaceFor(size_t blocks, bool readingAhead);
|
||||
void StartReadAhead(s64 pos);
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ void DiskCachingFileLoader::Seek(s64 absolutePos) {
|
||||
filepos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||
Prepare();
|
||||
size_t readSize;
|
||||
|
||||
@@ -99,11 +99,11 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data)
|
||||
bytes = filesize_ - absolutePos;
|
||||
}
|
||||
|
||||
if (cache_ && cache_->IsValid()) {
|
||||
if (cache_ && cache_->IsValid() && (flags & Flags::HINT_UNCACHED) == 0) {
|
||||
readSize = cache_->ReadFromCache(absolutePos, bytes, data);
|
||||
// While in case the cache size is too small for the entire read.
|
||||
while (readSize < bytes) {
|
||||
readSize += cache_->SaveIntoCache(backend_, absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||
readSize += cache_->SaveIntoCache(backend_, absolutePos + readSize, bytes - readSize, (u8 *)data + readSize, flags);
|
||||
// If there are already-cached blocks afterward, we have to read them.
|
||||
size_t bytesFromCache = cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||
readSize += bytesFromCache;
|
||||
@@ -113,7 +113,7 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
readSize = backend_->ReadAt(absolutePos, bytes, data);
|
||||
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||
}
|
||||
|
||||
filepos_ = absolutePos + readSize;
|
||||
@@ -256,12 +256,12 @@ size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *da
|
||||
return readSize;
|
||||
}
|
||||
|
||||
size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data) {
|
||||
size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data, FileLoader::Flags flags) {
|
||||
lock_guard guard(lock_);
|
||||
|
||||
if (!f_) {
|
||||
// Just to keep things working.
|
||||
return backend->ReadAt(pos, bytes, data);
|
||||
return backend->ReadAt(pos, bytes, data, flags);
|
||||
}
|
||||
|
||||
s64 cacheStartPos = pos / blockSize_;
|
||||
@@ -290,7 +290,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s
|
||||
auto &info = index_[cacheStartPos];
|
||||
|
||||
u8 *buf = new u8[blockSize_];
|
||||
size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blockSize_, buf);
|
||||
size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blockSize_, buf, flags);
|
||||
|
||||
// Check if it was written while we were busy. Might happen if we thread.
|
||||
if (info.block == INVALID_BLOCK && readBytes != 0) {
|
||||
@@ -306,7 +306,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s
|
||||
delete [] buf;
|
||||
} else {
|
||||
u8 *wholeRead = new u8[blocksToRead * blockSize_];
|
||||
size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blocksToRead * blockSize_, wholeRead);
|
||||
size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blocksToRead * blockSize_, wholeRead, flags);
|
||||
|
||||
for (size_t i = 0; i < blocksToRead; ++i) {
|
||||
auto &info = index_[cacheStartPos + i];
|
||||
|
||||
@@ -28,25 +28,25 @@ class DiskCachingFileLoaderCache;
|
||||
class DiskCachingFileLoader : public FileLoader {
|
||||
public:
|
||||
DiskCachingFileLoader(FileLoader *backend);
|
||||
virtual ~DiskCachingFileLoader() override;
|
||||
~DiskCachingFileLoader() override;
|
||||
|
||||
virtual bool Exists() override;
|
||||
virtual bool ExistsFast() override;
|
||||
virtual bool IsDirectory() override;
|
||||
virtual s64 FileSize() override;
|
||||
virtual std::string Path() const override;
|
||||
bool Exists() override;
|
||||
bool ExistsFast() override;
|
||||
bool IsDirectory() override;
|
||||
s64 FileSize() override;
|
||||
std::string Path() const override;
|
||||
|
||||
virtual void Seek(s64 absolutePos) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(filepos_, bytes, count, data);
|
||||
void Seek(s64 absolutePos) override;
|
||||
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, count, data, flags);
|
||||
}
|
||||
virtual size_t Read(size_t bytes, void *data) override {
|
||||
return ReadAt(filepos_, bytes, data);
|
||||
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, data, flags);
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
||||
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;
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
static std::vector<std::string> GetCachedPathsInUse();
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
|
||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||
// Guaranteed to read at least one block into the cache.
|
||||
size_t SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data);
|
||||
size_t SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data, FileLoader::Flags flags);
|
||||
|
||||
bool HasData() const;
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ void HTTPFileLoader::Seek(s64 absolutePos) {
|
||||
filepos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||
Prepare();
|
||||
s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_);
|
||||
if (absolutePos >= filesize_ || bytes == 0) {
|
||||
|
||||
@@ -35,16 +35,16 @@ public:
|
||||
virtual std::string Path() const override;
|
||||
|
||||
virtual void Seek(s64 absolutePos) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(filepos_, bytes, count, data);
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, count, data, flags);
|
||||
}
|
||||
virtual size_t Read(size_t bytes, void *data) override {
|
||||
return ReadAt(filepos_, bytes, data);
|
||||
virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, data, flags);
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
||||
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;
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
|
||||
@@ -81,7 +81,7 @@ void LocalFileLoader::Seek(s64 absolutePos) {
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data) {
|
||||
size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data, Flags flags) {
|
||||
#ifdef ANDROID
|
||||
return read(fd_, data, bytes * count) / bytes;
|
||||
#else
|
||||
@@ -89,7 +89,7 @@ size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data) {
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) {
|
||||
size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) {
|
||||
Seek(absolutePos);
|
||||
return Read(bytes, count, data);
|
||||
}
|
||||
@@ -31,8 +31,8 @@ public:
|
||||
virtual std::string Path() const override;
|
||||
|
||||
virtual void Seek(s64 absolutePos) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) override;
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override;
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
// First only used by Android, but we can keep it here for everyone.
|
||||
|
||||
@@ -77,16 +77,16 @@ void RamCachingFileLoader::Seek(s64 absolutePos) {
|
||||
filepos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||
size_t readSize = 0;
|
||||
if (cache_ == nullptr) {
|
||||
if (cache_ == nullptr || (flags & Flags::HINT_UNCACHED) != 0) {
|
||||
lock_guard guard(backendMutex_);
|
||||
readSize = backend_->ReadAt(absolutePos, bytes, data);
|
||||
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||
} else {
|
||||
readSize = ReadFromCache(absolutePos, bytes, data);
|
||||
// While in case the cache size is too small for the entire read.
|
||||
while (readSize < bytes) {
|
||||
SaveIntoCache(absolutePos + readSize, bytes - readSize);
|
||||
SaveIntoCache(absolutePos + readSize, bytes - readSize, flags);
|
||||
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||
readSize += bytesFromCache;
|
||||
if (bytesFromCache == 0) {
|
||||
@@ -94,9 +94,9 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StartReadAhead(absolutePos + readSize);
|
||||
StartReadAhead(absolutePos + readSize);
|
||||
}
|
||||
|
||||
filepos_ = absolutePos + readSize;
|
||||
return readSize;
|
||||
@@ -172,7 +172,7 @@ size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||
return readSize;
|
||||
}
|
||||
|
||||
void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) {
|
||||
void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, Flags flags) {
|
||||
s64 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
||||
if ((size_t)cacheEndPos >= blocks_.size()) {
|
||||
@@ -194,7 +194,7 @@ void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) {
|
||||
|
||||
backendMutex_.lock();
|
||||
s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT;
|
||||
size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos]);
|
||||
size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos], flags);
|
||||
backendMutex_.unlock();
|
||||
|
||||
// In case there was an error, let's not mark blocks that failed to read as read.
|
||||
@@ -247,7 +247,7 @@ void RamCachingFileLoader::StartReadAhead(s64 pos) {
|
||||
|
||||
for (u32 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||
if (blocks_[i] == 0) {
|
||||
SaveIntoCache((u64)i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD);
|
||||
SaveIntoCache((u64)i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,23 +34,23 @@ public:
|
||||
std::string Path() const override;
|
||||
|
||||
void Seek(s64 absolutePos) override;
|
||||
size_t Read(size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(filepos_, bytes, count, data);
|
||||
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, count, data, flags);
|
||||
}
|
||||
size_t Read(size_t bytes, void *data) override {
|
||||
return ReadAt(filepos_, bytes, data);
|
||||
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, data, flags);
|
||||
}
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
||||
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;
|
||||
}
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
void InitCache();
|
||||
void ShutdownCache();
|
||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||
// Guaranteed to read at least one block into the cache.
|
||||
void SaveIntoCache(s64 pos, size_t bytes);
|
||||
void SaveIntoCache(s64 pos, size_t bytes, Flags flags);
|
||||
void StartReadAhead(s64 pos);
|
||||
u32 NextAheadBlock();
|
||||
|
||||
|
||||
@@ -64,13 +64,13 @@ void RetryingFileLoader::Seek(s64 absolutePos) {
|
||||
filepos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
size_t readSize = backend_->ReadAt(absolutePos, bytes, data);
|
||||
size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||
size_t readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||
|
||||
int retries = 0;
|
||||
while (readSize < bytes && retries < MAX_RETRIES) {
|
||||
u8 *p = (u8 *)data;
|
||||
readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize);
|
||||
readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize, flags);
|
||||
++retries;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,25 @@
|
||||
class RetryingFileLoader : public FileLoader {
|
||||
public:
|
||||
RetryingFileLoader(FileLoader *backend);
|
||||
virtual ~RetryingFileLoader() override;
|
||||
~RetryingFileLoader() override;
|
||||
|
||||
virtual bool Exists() override;
|
||||
virtual bool ExistsFast() override;
|
||||
virtual bool IsDirectory() override;
|
||||
virtual s64 FileSize() override;
|
||||
virtual std::string Path() const override;
|
||||
bool Exists() override;
|
||||
bool ExistsFast() override;
|
||||
bool IsDirectory() override;
|
||||
s64 FileSize() override;
|
||||
std::string Path() const override;
|
||||
|
||||
virtual void Seek(s64 absolutePos) override;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(filepos_, bytes, count, data);
|
||||
void Seek(s64 absolutePos) override;
|
||||
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, count, data, flags);
|
||||
}
|
||||
virtual size_t Read(size_t bytes, void *data) override {
|
||||
return ReadAt(filepos_, bytes, data);
|
||||
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||
return ReadAt(filepos_, bytes, data, flags);
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
||||
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;
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
||||
@@ -45,6 +45,21 @@ BlockDevice *constructBlockDevice(FileLoader *fileLoader) {
|
||||
return new FileBlockDevice(fileLoader);
|
||||
}
|
||||
|
||||
u32 BlockDevice::CalculateCRC() {
|
||||
u32 crc = crc32(0, Z_NULL, 0);
|
||||
|
||||
u8 block[2048];
|
||||
for (u32 i = 0; i < GetNumBlocks(); ++i) {
|
||||
if (!ReadBlock(i, block, true)) {
|
||||
ERROR_LOG(HLE, "Failed to read block for CRC");
|
||||
return 0;
|
||||
}
|
||||
crc = crc32(crc, block, 2048);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
||||
FileBlockDevice::FileBlockDevice(FileLoader *fileLoader)
|
||||
: fileLoader_(fileLoader) {
|
||||
@@ -54,8 +69,9 @@ FileBlockDevice::FileBlockDevice(FileLoader *fileLoader)
|
||||
FileBlockDevice::~FileBlockDevice() {
|
||||
}
|
||||
|
||||
bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) {
|
||||
if (fileLoader_->ReadAt((u64)blockNumber * (u64)GetBlockSize(), 1, 2048, outPtr) != 2048) {
|
||||
bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) {
|
||||
FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE;
|
||||
if (fileLoader_->ReadAt((u64)blockNumber * (u64)GetBlockSize(), 1, 2048, outPtr, flags) != 2048) {
|
||||
DEBUG_LOG(FILESYS, "Could not read 2048 bytes from block");
|
||||
return false;
|
||||
}
|
||||
@@ -178,8 +194,9 @@ CISOFileBlockDevice::~CISOFileBlockDevice()
|
||||
delete [] zlibBuffer;
|
||||
}
|
||||
|
||||
bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
|
||||
{
|
||||
FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE;
|
||||
if ((u32)blockNumber >= numBlocks)
|
||||
{
|
||||
memset(outPtr, 0, GetBlockSize());
|
||||
@@ -200,7 +217,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
const int plain = idx & 0x80000000;
|
||||
if (plain)
|
||||
{
|
||||
int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr);
|
||||
int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr, flags);
|
||||
if (readSize < GetBlockSize())
|
||||
memset(outPtr + readSize, 0, GetBlockSize() - readSize);
|
||||
}
|
||||
@@ -211,7 +228,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer);
|
||||
const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer, flags);
|
||||
|
||||
z.zalloc = Z_NULL;
|
||||
z.zfree = Z_NULL;
|
||||
@@ -423,8 +440,9 @@ NPDRMDemoBlockDevice::~NPDRMDemoBlockDevice()
|
||||
|
||||
int lzrc_decompress(void *out, int out_len, void *in, int in_len);
|
||||
|
||||
bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
|
||||
{
|
||||
FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE;
|
||||
lock_guard guard(mutex_);
|
||||
CIPHER_KEY ckey;
|
||||
int block, lba, lzsize;
|
||||
@@ -453,7 +471,7 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
else
|
||||
readBuf = blockBuf;
|
||||
|
||||
readSize = fileLoader_->ReadAt(psarOffset+table[block].offset, 1, table[block].size, readBuf);
|
||||
readSize = fileLoader_->ReadAt(psarOffset+table[block].offset, 1, table[block].size, readBuf, flags);
|
||||
if(readSize != (size_t)table[block].size){
|
||||
if((u32)block==(numBlocks-1))
|
||||
return true;
|
||||
|
||||
@@ -33,7 +33,7 @@ class BlockDevice
|
||||
{
|
||||
public:
|
||||
virtual ~BlockDevice() {}
|
||||
virtual bool ReadBlock(int blockNumber, u8 *outPtr) = 0;
|
||||
virtual bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) = 0;
|
||||
virtual bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) {
|
||||
for (int b = 0; b < count; ++b) {
|
||||
if (!ReadBlock(minBlock + b, outPtr)) {
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
}
|
||||
int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses
|
||||
virtual u32 GetNumBlocks() = 0;
|
||||
|
||||
u32 CalculateCRC();
|
||||
};
|
||||
|
||||
|
||||
@@ -53,7 +55,7 @@ class CISOFileBlockDevice : public BlockDevice
|
||||
public:
|
||||
CISOFileBlockDevice(FileLoader *fileLoader);
|
||||
~CISOFileBlockDevice();
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr) override;
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override;
|
||||
bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override;
|
||||
u32 GetNumBlocks() override { return numBlocks; }
|
||||
|
||||
@@ -76,7 +78,7 @@ class FileBlockDevice : public BlockDevice
|
||||
public:
|
||||
FileBlockDevice(FileLoader *fileLoader);
|
||||
~FileBlockDevice();
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr) override;
|
||||
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());}
|
||||
|
||||
@@ -102,7 +104,7 @@ public:
|
||||
NPDRMDemoBlockDevice(FileLoader *fileLoader);
|
||||
~NPDRMDemoBlockDevice();
|
||||
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr) override;
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override;
|
||||
u32 GetNumBlocks() override {return (u32)lbaSize;}
|
||||
|
||||
private:
|
||||
|
||||
+16
-6
@@ -51,6 +51,12 @@ enum IdentifiedFileType {
|
||||
|
||||
class FileLoader {
|
||||
public:
|
||||
enum class Flags {
|
||||
NONE,
|
||||
// Not necessary to read from / store into cache.
|
||||
HINT_UNCACHED,
|
||||
};
|
||||
|
||||
virtual ~FileLoader() {}
|
||||
|
||||
virtual bool Exists() = 0;
|
||||
@@ -71,16 +77,20 @@ public:
|
||||
}
|
||||
|
||||
virtual void Seek(s64 absolutePos) = 0;
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data) = 0;
|
||||
virtual size_t Read(size_t bytes, void *data) {
|
||||
return Read(1, bytes, data);
|
||||
virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) = 0;
|
||||
virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) {
|
||||
return Read(1, bytes, data, flags);
|
||||
}
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) = 0;
|
||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||
return ReadAt(absolutePos, 1, bytes, data);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
inline u32 operator & (const FileLoader::Flags &a, const FileLoader::Flags &b) {
|
||||
return (u32)a & (u32)b;
|
||||
}
|
||||
|
||||
FileLoader *ConstructFileLoader(const std::string &filename);
|
||||
// Resolve to the target binary, ISO, or other file (e.g. from a directory.)
|
||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
|
||||
|
||||
+104
-6
@@ -21,8 +21,10 @@
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CwCheat.h"
|
||||
#include "Core/Loaders.h"
|
||||
#include "Core/SaveState.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/FileSystems/BlockDevices.h"
|
||||
#include "Core/FileSystems/MetaFileSystem.h"
|
||||
#include "Core/HLE/sceDisplay.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
@@ -37,6 +39,7 @@
|
||||
#include "base/stringutil.h"
|
||||
#include "base/buffer.h"
|
||||
#include "thread/thread.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "file/zip_read.h"
|
||||
|
||||
#include <set>
|
||||
@@ -59,6 +62,8 @@ namespace Reporting
|
||||
static bool everUnsupported = false;
|
||||
// Support is cached here to avoid checking it on every single request.
|
||||
static bool currentSupported = false;
|
||||
// Whether the most recent server request seemed successful.
|
||||
static bool serverWorking = true;
|
||||
|
||||
enum class RequestType
|
||||
{
|
||||
@@ -79,6 +84,68 @@ namespace Reporting
|
||||
static Payload payloadBuffer[PAYLOAD_BUFFER_SIZE];
|
||||
static int payloadBufferPos = 0;
|
||||
|
||||
static recursive_mutex crcLock;
|
||||
static condition_variable crcCond;
|
||||
static std::string crcFilename;
|
||||
static std::map<std::string, u32> crcResults;
|
||||
|
||||
static int CalculateCRCThread() {
|
||||
setCurrentThreadName("ReportCRC");
|
||||
|
||||
// TODO: Use the blockDevice from pspFileSystem?
|
||||
FileLoader *fileLoader = ConstructFileLoader(crcFilename);
|
||||
BlockDevice *blockDevice = constructBlockDevice(fileLoader);
|
||||
|
||||
u32 crc = 0;
|
||||
if (blockDevice) {
|
||||
crc = blockDevice->CalculateCRC();
|
||||
}
|
||||
|
||||
delete blockDevice;
|
||||
delete fileLoader;
|
||||
|
||||
lock_guard guard(crcLock);
|
||||
crcResults[crcFilename] = crc;
|
||||
crcCond.notify_one();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QueueCRC() {
|
||||
lock_guard guard(crcLock);
|
||||
|
||||
const std::string &gamePath = PSP_CoreParameter().fileToStart;
|
||||
auto it = crcResults.find(gamePath);
|
||||
if (it != crcResults.end()) {
|
||||
// Nothing to do, we've already calculated it.
|
||||
// Note: we assume it stays static until the app is closed.
|
||||
return;
|
||||
}
|
||||
|
||||
if (crcFilename == gamePath) {
|
||||
// Already in process.
|
||||
return;
|
||||
}
|
||||
|
||||
crcFilename = gamePath;
|
||||
std::thread th(CalculateCRCThread);
|
||||
th.detach();
|
||||
}
|
||||
|
||||
u32 RetrieveCRC() {
|
||||
const std::string &gamePath = PSP_CoreParameter().fileToStart;
|
||||
QueueCRC();
|
||||
|
||||
lock_guard guard(crcLock);
|
||||
auto it = crcResults.find(gamePath);
|
||||
while (it == crcResults.end()) {
|
||||
crcCond.wait(crcLock);
|
||||
it = crcResults.find(gamePath);
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Returns the full host (e.g. report.ppsspp.org:80.)
|
||||
std::string ServerHost()
|
||||
{
|
||||
@@ -162,9 +229,10 @@ namespace Reporting
|
||||
|
||||
if (http.Resolve(serverHost, ServerPort())) {
|
||||
http.Connect();
|
||||
http.POST(uri, data, mimeType, output);
|
||||
int result = http.POST(uri, data, mimeType, output);
|
||||
http.Disconnect();
|
||||
return true;
|
||||
|
||||
return result >= 200 && result < 300;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -324,7 +392,10 @@ namespace Reporting
|
||||
|
||||
int Process(int pos)
|
||||
{
|
||||
setCurrentThreadName("Report");
|
||||
|
||||
Payload &payload = payloadBuffer[pos];
|
||||
Buffer output;
|
||||
|
||||
MultipartFormDataEncoder postdata;
|
||||
AddSystemInfo(postdata);
|
||||
@@ -335,6 +406,7 @@ namespace Reporting
|
||||
switch (payload.type)
|
||||
{
|
||||
case RequestType::MESSAGE:
|
||||
// TODO: Add CRC?
|
||||
postdata.Add("message", payload.string1);
|
||||
postdata.Add("value", payload.string2);
|
||||
// We tend to get corrupted data, this acts as a very primitive verification check.
|
||||
@@ -343,7 +415,9 @@ namespace Reporting
|
||||
payload.string2.clear();
|
||||
|
||||
postdata.Finish();
|
||||
SendReportRequest("/report/message", postdata.ToString(), postdata.GetMimeType());
|
||||
serverWorking = true;
|
||||
if (!SendReportRequest("/report/message", postdata.ToString(), postdata.GetMimeType()))
|
||||
serverWorking = false;
|
||||
break;
|
||||
|
||||
case RequestType::COMPAT:
|
||||
@@ -353,12 +427,23 @@ namespace Reporting
|
||||
postdata.Add("graphics", StringFromFormat("%d", payload.int1));
|
||||
postdata.Add("speed", StringFromFormat("%d", payload.int2));
|
||||
postdata.Add("gameplay", StringFromFormat("%d", payload.int3));
|
||||
postdata.Add("crc", StringFromFormat("%08x", RetrieveCRC()));
|
||||
AddScreenshotData(postdata, payload.string2);
|
||||
payload.string1.clear();
|
||||
payload.string2.clear();
|
||||
|
||||
postdata.Finish();
|
||||
SendReportRequest("/report/compat", postdata.ToString(), postdata.GetMimeType());
|
||||
serverWorking = true;
|
||||
if (!SendReportRequest("/report/compat", postdata.ToString(), postdata.GetMimeType(), &output)) {
|
||||
serverWorking = false;
|
||||
} else {
|
||||
char res = 0;
|
||||
if (!output.empty()) {
|
||||
output.Take(1, &res);
|
||||
}
|
||||
if (res == 0)
|
||||
serverWorking = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case RequestType::NONE:
|
||||
@@ -427,6 +512,20 @@ namespace Reporting
|
||||
g_Config.sReportHost = "default";
|
||||
}
|
||||
|
||||
Status GetStatus()
|
||||
{
|
||||
if (!serverWorking)
|
||||
return Status::FAILING;
|
||||
|
||||
for (int pos = 0; pos < PAYLOAD_BUFFER_SIZE; ++pos)
|
||||
{
|
||||
if (payloadBuffer[pos].type != RequestType::NONE)
|
||||
return Status::BUSY;
|
||||
}
|
||||
|
||||
return Status::WORKING;
|
||||
}
|
||||
|
||||
int NextFreePos()
|
||||
{
|
||||
int start = payloadBufferPos % PAYLOAD_BUFFER_SIZE;
|
||||
@@ -484,7 +583,7 @@ namespace Reporting
|
||||
th.detach();
|
||||
}
|
||||
|
||||
void ReportCompatibility(const char *compat, int graphics, int speed, int gameplay, std::string screenshotFilename)
|
||||
void ReportCompatibility(const char *compat, int graphics, int speed, int gameplay, const std::string &screenshotFilename)
|
||||
{
|
||||
if (!IsEnabled())
|
||||
return;
|
||||
@@ -503,5 +602,4 @@ namespace Reporting
|
||||
std::thread th(Process, pos);
|
||||
th.detach();
|
||||
}
|
||||
|
||||
}
|
||||
+12
-1
@@ -15,6 +15,8 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Log.h"
|
||||
#include <string>
|
||||
@@ -70,11 +72,20 @@ namespace Reporting
|
||||
void ReportMessageFormatted(const char *message, const char *formatted);
|
||||
|
||||
// Report the compatibility of the current game / configuration.
|
||||
void ReportCompatibility(const char *compat, int graphics, int speed, int gameplay, std::string screenshotFilename);
|
||||
void ReportCompatibility(const char *compat, int graphics, int speed, int gameplay, const std::string &screenshotFilename);
|
||||
|
||||
// Returns true if that identifier has not been logged yet.
|
||||
bool ShouldLogOnce(const char *identifier);
|
||||
|
||||
enum class Status {
|
||||
WORKING,
|
||||
BUSY,
|
||||
FAILING,
|
||||
};
|
||||
|
||||
// Whether server requests appear to be working.
|
||||
Status GetStatus();
|
||||
|
||||
// Return the currently active host (or blank if not active.)
|
||||
std::string ServerHost();
|
||||
|
||||
|
||||
+30
-1
@@ -223,6 +223,10 @@ void ReportScreen::CreateViews() {
|
||||
reportingNotice_ = nullptr;
|
||||
}
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
leftColumnItems->Add(new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetEnabledPtr(&enableReporting_);
|
||||
#endif
|
||||
|
||||
std::string path = GetSysDirectory(DIRECTORY_SCREENSHOT);
|
||||
if (!File::Exists(path)) {
|
||||
File::CreateDir(path);
|
||||
@@ -294,7 +298,7 @@ EventReturn ReportScreen::HandleBrowser(EventParams &e) {
|
||||
}
|
||||
|
||||
ReportFinishScreen::ReportFinishScreen(const std::string &gamePath)
|
||||
: UIScreenWithGameBackground(gamePath) {
|
||||
: UIScreenWithGameBackground(gamePath), resultNotice_(nullptr), setStatus_(false) {
|
||||
}
|
||||
|
||||
void ReportFinishScreen::CreateViews() {
|
||||
@@ -309,6 +313,7 @@ void ReportFinishScreen::CreateViews() {
|
||||
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL);
|
||||
|
||||
leftColumnItems->Add(new TextView(rp->T("FeedbackThanks", "Thanks for your feedback."), new LinearLayoutParams(Margins(12, 5, 0, 5))));
|
||||
resultNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDelayInfo", "Your data is being submitted in the background."), new LinearLayoutParams(Margins(12, 5, 0, 5))));
|
||||
|
||||
rightColumnItems->SetSpacing(0.0f);
|
||||
rightColumnItems->Add(new Choice(rp->T("View Feedback")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback);
|
||||
@@ -324,6 +329,30 @@ void ReportFinishScreen::CreateViews() {
|
||||
rightColumn->Add(rightColumnItems);
|
||||
}
|
||||
|
||||
void ReportFinishScreen::update(InputState &input) {
|
||||
I18NCategory *rp = GetI18NCategory("Reporting");
|
||||
|
||||
if (!setStatus_) {
|
||||
Reporting::Status status = Reporting::GetStatus();
|
||||
switch (status) {
|
||||
case Reporting::Status::WORKING:
|
||||
resultNotice_->SetText(rp->T("FeedbackSubmitDone", "Your data has been submitted."));
|
||||
break;
|
||||
|
||||
case Reporting::Status::FAILING:
|
||||
resultNotice_->SetText(rp->T("FeedbackSubmitFail", "Could not submit data to server. Try updating PPSSPP."));
|
||||
break;
|
||||
|
||||
case Reporting::Status::BUSY:
|
||||
default:
|
||||
// Can't update yet.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UIScreenWithGameBackground::update(input);
|
||||
}
|
||||
|
||||
UI::EventReturn ReportFinishScreen::HandleViewFeedback(UI::EventParams &e) {
|
||||
const std::string url = "http://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID();
|
||||
LaunchBrowser(url.c_str());
|
||||
|
||||
@@ -55,7 +55,11 @@ public:
|
||||
ReportFinishScreen(const std::string &gamePath);
|
||||
|
||||
protected:
|
||||
void update(InputState &input) override;
|
||||
void CreateViews() override;
|
||||
|
||||
UI::EventReturn HandleViewFeedback(UI::EventParams &e);
|
||||
|
||||
UI::TextView *resultNotice_;
|
||||
bool setStatus_;
|
||||
};
|
||||
Reference in new issue
Block a user