diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6021144a5b..6985fa0f12 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1268,6 +1268,8 @@ set(GPU_SOURCES
GPU/Common/SplineCommon.h
GPU/Debugger/Breakpoints.cpp
GPU/Debugger/Breakpoints.h
+ GPU/Debugger/Record.cpp
+ GPU/Debugger/Record.h
GPU/Debugger/Stepping.cpp
GPU/Debugger/Stepping.h
GPU/GPUInterface.h
@@ -1350,6 +1352,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/ELF/ParamSFO.cpp
Core/ELF/ParamSFO.h
Core/FileSystems/tlzrc.cpp
+ Core/FileSystems/BlobFileSystem.cpp
+ Core/FileSystems/BlobFileSystem.h
Core/FileSystems/BlockDevices.cpp
Core/FileSystems/BlockDevices.h
Core/FileSystems/DirectoryFileSystem.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index ce2cb5033b..e02438f7f9 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -21,7 +21,8 @@
{533F1D30-D04D-47CC-AD71-20F658907E36}
Core
-
+
+
@@ -183,6 +184,7 @@
+
@@ -524,6 +526,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 234ff2172a..79da4d1df0 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -680,6 +680,9 @@
HLE\Libraries
+
+ FileSystems
+
@@ -1250,10 +1253,13 @@
HLE\Libraries
+
+ FileSystems
+
-
+
\ No newline at end of file
diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp
index 1c148c86c3..1f41a6f802 100644
--- a/Core/CoreTiming.cpp
+++ b/Core/CoreTiming.cpp
@@ -573,6 +573,10 @@ void ForceCheck()
currentMIPS->downcount = -1;
// But let's not eat a bunch more time in Advance() because of this.
slicelength = -1;
+
+#ifdef _DEBUG
+ _dbg_assert_msg_(CPU, cyclesExecuted >= 0, "Shouldn't have a negative cyclesExecuted");
+#endif
}
void Advance()
@@ -613,7 +617,7 @@ void LogPendingEvents()
Event *ptr = first;
while (ptr)
{
- //INFO_LOG(TIMER, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type);
+ //INFO_LOG(CPU, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type);
ptr = ptr->next;
}
}
diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h
index ead49feff8..940280bac3 100644
--- a/Core/ELF/ParamSFO.h
+++ b/Core/ELF/ParamSFO.h
@@ -37,6 +37,14 @@ public:
std::vector GetKeys();
std::string GenerateFakeID(std::string filename = "");
+ std::string GetDiscID() {
+ const std::string discID = GetValueString("DISC_ID");
+ if (discID.empty()) {
+ return GenerateFakeID();
+ }
+ return discID;
+ }
+
bool ReadSFO(const u8 *paramsfo, size_t size);
bool WriteSFO(u8 **paramsfo, size_t *size);
diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp
new file mode 100644
index 0000000000..059e79199f
--- /dev/null
+++ b/Core/FileSystems/BlobFileSystem.cpp
@@ -0,0 +1,137 @@
+// Copyright (c) 2017- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#include "Core/FileSystems/BlobFileSystem.h"
+
+BlobFileSystem::BlobFileSystem(IHandleAllocator *hAlloc, FileLoader *fileLoader, std::string alias)
+: alloc_(hAlloc), fileLoader_(fileLoader), alias_(alias) {
+}
+
+BlobFileSystem::~BlobFileSystem() {
+ // TODO: Who deletes fileLoader?
+}
+
+void BlobFileSystem::DoState(PointerWrap &p) {
+ // Not used in real emulation.
+}
+
+std::vector BlobFileSystem::GetDirListing(std::string path) {
+ std::vector listing;
+ listing.push_back(GetFileInfo(alias_));
+ return listing;
+}
+
+u32 BlobFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) {
+ u32 newHandle = alloc_->GetNewHandle();
+ entries_[newHandle] = 0;
+ return newHandle;
+}
+
+void BlobFileSystem::CloseFile(u32 handle) {
+ alloc_->FreeHandle(handle);
+ entries_.erase(handle);
+}
+
+size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) {
+ auto entry = entries_.find(handle);
+ if (entry != entries_.end()) {
+ size_t readSize = fileLoader_->ReadAt(entry->second, size, pointer);
+ entry->second += readSize;
+ return readSize;
+ }
+ return 0;
+}
+
+size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) {
+ usec = 0;
+ return ReadFile(handle, pointer, size);
+}
+
+size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) {
+ return 0;
+}
+
+size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) {
+ return 0;
+}
+
+size_t BlobFileSystem::SeekFile(u32 handle, s32 position, FileMove type) {
+ auto entry = entries_.find(handle);
+ if (entry != entries_.end()) {
+ switch (type) {
+ case FILEMOVE_BEGIN:
+ entry->second = position;
+ break;
+ case FILEMOVE_CURRENT:
+ entry->second += position;
+ break;
+ case FILEMOVE_END:
+ entry->second = fileLoader_->FileSize() + position;
+ break;
+ }
+ return (size_t)entry->second;
+ }
+ return 0;
+}
+
+PSPFileInfo BlobFileSystem::GetFileInfo(std::string filename) {
+ PSPFileInfo info{};
+ info.name = alias_;
+ info.size = fileLoader_->FileSize();
+ info.access = 0666;
+ info.exists = true;
+ info.type = FILETYPE_NORMAL;
+ return info;
+}
+
+bool BlobFileSystem::OwnsHandle(u32 handle) {
+ auto entry = entries_.find(handle);
+ return entry != entries_.end();
+}
+
+int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
+ return -1;
+}
+
+int BlobFileSystem::DevType(u32 handle) {
+ return -1;
+}
+
+bool BlobFileSystem::MkDir(const std::string &dirname) {
+ return false;
+}
+
+bool BlobFileSystem::RmDir(const std::string &dirname) {
+ return false;
+}
+
+int BlobFileSystem::RenameFile(const std::string &from, const std::string &to) {
+ return -1;
+}
+
+bool BlobFileSystem::RemoveFile(const std::string &filename) {
+ return false;
+}
+
+bool BlobFileSystem::GetHostPath(const std::string &inpath, std::string &outpath) {
+ outpath = fileLoader_->Path();
+ return true;
+}
+
+u64 BlobFileSystem::FreeSpace(const std::string &path) {
+ return 0;
+}
diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h
new file mode 100644
index 0000000000..573fdacdd7
--- /dev/null
+++ b/Core/FileSystems/BlobFileSystem.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2017- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+// This is used for opening a debug file as a blob, and mounting it.
+// Importantly, uses a fileLoader for all access, so http:// URLs are supported.
+// As of writing, only used by GE dump replay.
+
+#include