mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
GE Debugger: Simple framework to load dumps.
This tries to execute them within the context of the emulator as much as possible, so we don't have weird bugs. Going with a file type so we can easily load the dump by opening the file directly.
This commit is contained in:
parent
37a894a558
commit
36069d1446
@ -1348,6 +1348,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
|
||||
|
@ -21,7 +21,8 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{533F1D30-D04D-47CC-AD71-20F658907E36}</ProjectGuid>
|
||||
<RootNamespace>Core</RootNamespace>
|
||||
<WindowsTargetPlatformVersion></WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>
|
||||
</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@ -183,6 +184,7 @@
|
||||
<ClCompile Include="..\ext\udis86\syn.c" />
|
||||
<ClCompile Include="..\ext\udis86\udis86.c" />
|
||||
<ClCompile Include="AVIDump.cpp" />
|
||||
<ClCompile Include="FileSystems\BlobFileSystem.cpp" />
|
||||
<ClCompile Include="HLE\KUBridge.cpp" />
|
||||
<ClCompile Include="MIPS\IR\IRAsm.cpp" />
|
||||
<ClCompile Include="MIPS\IR\IRCompALU.cpp" />
|
||||
@ -524,6 +526,7 @@
|
||||
<ClInclude Include="..\ext\udis86\udint.h" />
|
||||
<ClInclude Include="..\ext\udis86\udis86.h" />
|
||||
<ClInclude Include="AVIDump.h" />
|
||||
<ClInclude Include="FileSystems\BlobFileSystem.h" />
|
||||
<ClInclude Include="HLE\KUBridge.h" />
|
||||
<ClInclude Include="MIPS\IR\IRFrontend.h" />
|
||||
<ClInclude Include="MIPS\IR\IRInst.h" />
|
||||
|
@ -680,6 +680,9 @@
|
||||
<ClCompile Include="HLE\KUBridge.cpp">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileSystems\BlobFileSystem.cpp">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ELF\ElfReader.h">
|
||||
@ -1250,10 +1253,13 @@
|
||||
<ClInclude Include="HLE\KUBridge.h">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileSystems\BlobFileSystem.h">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
<None Include="..\LICENSE.TXT" />
|
||||
<None Include="..\android\jni\Android.mk" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
137
Core/FileSystems/BlobFileSystem.cpp
Normal file
137
Core/FileSystems/BlobFileSystem.cpp
Normal file
@ -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<PSPFileInfo> BlobFileSystem::GetDirListing(std::string path) {
|
||||
std::vector<PSPFileInfo> 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;
|
||||
}
|
61
Core/FileSystems/BlobFileSystem.h
Normal file
61
Core/FileSystems/BlobFileSystem.h
Normal file
@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Core/Loaders.h"
|
||||
#include "Core/FileSystems/FileSystem.h"
|
||||
|
||||
class BlobFileSystem : public IFileSystem {
|
||||
public:
|
||||
BlobFileSystem(IHandleAllocator *hAlloc, FileLoader *fileLoader, std::string alias);
|
||||
~BlobFileSystem();
|
||||
|
||||
void DoState(PointerWrap &p) override;
|
||||
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
|
||||
u32 OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
|
||||
void CloseFile(u32 handle) override;
|
||||
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;
|
||||
size_t ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) override;
|
||||
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;
|
||||
size_t WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) override;
|
||||
size_t SeekFile(u32 handle, s32 position, FileMove type) override;
|
||||
PSPFileInfo GetFileInfo(std::string filename) override;
|
||||
bool OwnsHandle(u32 handle) override;
|
||||
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
|
||||
int DevType(u32 handle) override;
|
||||
int Flags() override { return 0; }
|
||||
|
||||
bool MkDir(const std::string &dirname) override;
|
||||
bool RmDir(const std::string &dirname) override;
|
||||
int RenameFile(const std::string &from, const std::string &to) override;
|
||||
bool RemoveFile(const std::string &filename) override;
|
||||
bool GetHostPath(const std::string &inpath, std::string &outpath) override;
|
||||
u64 FreeSpace(const std::string &path) override;
|
||||
|
||||
private:
|
||||
// File positions.
|
||||
std::map<u32, s64> entries_;
|
||||
|
||||
IHandleAllocator *alloc_;
|
||||
FileLoader *fileLoader_;
|
||||
std::string alias_;
|
||||
};
|
@ -92,6 +92,7 @@ const HLEFunction FakeSysCalls[] = {
|
||||
{NID_EXTENDRETURN, __KernelReturnFromExtendStack, "__KernelReturnFromExtendStack"},
|
||||
{NID_MODULERETURN, __KernelReturnFromModuleFunc, "__KernelReturnFromModuleFunc"},
|
||||
{NID_IDLE, __KernelIdle, "_sceKernelIdle"},
|
||||
{NID_GPUREPLAY, __KernelGPUReplay, "__KernelGPUReplay"},
|
||||
};
|
||||
|
||||
const HLEFunction UtilsForUser[] =
|
||||
|
@ -23,5 +23,6 @@
|
||||
#define NID_EXTENDRETURN 0xbad0b0c9
|
||||
#define NID_MODULERETURN 0xbad0d318
|
||||
#define NID_IDLE 0x1d7e1d7e
|
||||
#define NID_GPUREPLAY 0x9e45bd95
|
||||
|
||||
void RegisterAllModules();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/HLETables.h"
|
||||
@ -57,6 +58,7 @@
|
||||
#include "Core/HLE/KernelWaitHelpers.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
|
||||
#include "GPU/Debugger/Record.h"
|
||||
#include "GPU/GPU.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -1513,8 +1515,36 @@ u32 __KernelGetModuleGP(SceUID uid)
|
||||
}
|
||||
}
|
||||
|
||||
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string)
|
||||
{
|
||||
void __KernelLoadReset() {
|
||||
// Wipe kernel here, loadexec should reset the entire system
|
||||
if (__KernelIsRunning()) {
|
||||
u32 error;
|
||||
while (!loadedModules.empty()) {
|
||||
SceUID moduleID = *loadedModules.begin();
|
||||
Module *module = kernelObjects.Get<Module>(moduleID, error);
|
||||
if (module) {
|
||||
module->Cleanup();
|
||||
} else {
|
||||
// An invalid module. We need to remove it or we'll loop forever.
|
||||
WARN_LOG(LOADER, "Invalid module still marked as loaded on loadexec");
|
||||
loadedModules.erase(moduleID);
|
||||
}
|
||||
}
|
||||
|
||||
Replacement_Shutdown();
|
||||
__KernelShutdown();
|
||||
// HLE needs to be reset here
|
||||
HLEShutdown();
|
||||
Replacement_Init();
|
||||
HLEInit();
|
||||
gpu->Reinitialize();
|
||||
}
|
||||
|
||||
__KernelModuleInit();
|
||||
__KernelInit();
|
||||
}
|
||||
|
||||
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) {
|
||||
SceKernelLoadExecParam param;
|
||||
|
||||
if (paramPtr)
|
||||
@ -1536,33 +1566,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
|
||||
Memory::Memcpy(param_key, keyAddr, (u32)keylen);
|
||||
}
|
||||
|
||||
// Wipe kernel here, loadexec should reset the entire system
|
||||
if (__KernelIsRunning())
|
||||
{
|
||||
u32 error;
|
||||
while (!loadedModules.empty()) {
|
||||
SceUID moduleID = *loadedModules.begin();
|
||||
Module *module = kernelObjects.Get<Module>(moduleID, error);
|
||||
if (module) {
|
||||
module->Cleanup();
|
||||
} else {
|
||||
// An invalid module. We need to remove it or we'll loop forever.
|
||||
WARN_LOG(LOADER, "Invalid module still marked as loaded on loadexec");
|
||||
loadedModules.erase(moduleID);
|
||||
}
|
||||
}
|
||||
|
||||
Replacement_Shutdown();
|
||||
__KernelShutdown();
|
||||
//HLE needs to be reset here
|
||||
HLEShutdown();
|
||||
Replacement_Init();
|
||||
HLEInit();
|
||||
gpu->Reinitialize();
|
||||
}
|
||||
|
||||
__KernelModuleInit();
|
||||
__KernelInit();
|
||||
__KernelLoadReset();
|
||||
|
||||
PSPFileInfo info = pspFileSystem.GetFileInfo(filename);
|
||||
if (!info.exists) {
|
||||
@ -1635,6 +1639,33 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __KernelLoadGEDump(std::string *error_string) {
|
||||
__KernelLoadReset();
|
||||
|
||||
mipsr4k.pc = PSP_GetUserMemoryBase();
|
||||
|
||||
const static u32_le runDumpCode[] = {
|
||||
MIPS_MAKE_LUI(MIPS_REG_RA, mipsr4k.pc >> 16),
|
||||
MIPS_MAKE_JR_RA(),
|
||||
MIPS_MAKE_SYSCALL("FakeSysCalls", "__KernelGPUReplay"),
|
||||
MIPS_MAKE_BREAK(0),
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(runDumpCode); ++i) {
|
||||
Memory::WriteUnchecked_U32(runDumpCode[i], mipsr4k.pc + (int)i * sizeof(u32_le));
|
||||
}
|
||||
|
||||
__KernelStartIdleThreads(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void __KernelGPUReplay() {
|
||||
if (!GPURecord::RunMountedReplay()) {
|
||||
Core_Stop();
|
||||
}
|
||||
hleEatCycles(msToCycles(1001.0f / 60.0f));
|
||||
}
|
||||
|
||||
int sceKernelLoadExec(const char *filename, u32 paramPtr)
|
||||
{
|
||||
std::string exec_filename = filename;
|
||||
|
@ -39,7 +39,9 @@ void __KernelModuleDoState(PointerWrap &p);
|
||||
void __KernelModuleShutdown();
|
||||
|
||||
u32 __KernelGetModuleGP(SceUID module);
|
||||
bool __KernelLoadGEDump(std::string *error_string);
|
||||
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string);
|
||||
void __KernelGPUReplay();
|
||||
void __KernelReturnFromModuleFunc();
|
||||
u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus);
|
||||
|
||||
|
@ -69,31 +69,30 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
}
|
||||
|
||||
std::string extension = fileLoader->Extension();
|
||||
if (!strcasecmp(extension.c_str(), ".iso"))
|
||||
{
|
||||
if (!strcasecmp(extension.c_str(), ".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)
|
||||
{
|
||||
if ((fileLoader->FileSize() % 2352) == 0) {
|
||||
unsigned char sync[12];
|
||||
fileLoader->ReadAt(0, 12, sync);
|
||||
|
||||
// each sector in a mode2 image starts with these 12 bytes
|
||||
if (memcmp(sync,"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00",12) == 0)
|
||||
{
|
||||
if (memcmp(sync,"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", 12) == 0) {
|
||||
return IdentifiedFileType::ISO_MODE2;
|
||||
}
|
||||
|
||||
// maybe it also just happened to have that size,
|
||||
}
|
||||
return IdentifiedFileType::PSP_ISO;
|
||||
}
|
||||
else if (!strcasecmp(extension.c_str(),".cso"))
|
||||
{
|
||||
} else if (!strcasecmp(extension.c_str(), ".cso")) {
|
||||
return IdentifiedFileType::PSP_ISO;
|
||||
}
|
||||
else if (!strcasecmp(extension.c_str(),".ppst"))
|
||||
{
|
||||
} else if (!strcasecmp(extension.c_str(), ".ppst")) {
|
||||
return IdentifiedFileType::PPSSPP_SAVESTATE;
|
||||
} else if (!strcasecmp(extension.c_str(), ".ppdmp")) {
|
||||
char data[8]{};
|
||||
fileLoader->ReadAt(0, 8, data);
|
||||
if (memcmp(data, "PPSSPPGE", 8) == 0) {
|
||||
return IdentifiedFileType::PPSSPP_GE_DUMP;
|
||||
}
|
||||
}
|
||||
|
||||
// First, check if it's a directory with an EBOOT.PBP in it.
|
||||
@ -337,6 +336,9 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
*error_string = "This is save data, not a game."; // Actually, we could make it load it...
|
||||
break;
|
||||
|
||||
case IdentifiedFileType::PPSSPP_GE_DUMP:
|
||||
return Load_PSP_GE_Dump(fileLoader, error_string);
|
||||
|
||||
case IdentifiedFileType::UNKNOWN_BIN:
|
||||
case IdentifiedFileType::UNKNOWN_ELF:
|
||||
case IdentifiedFileType::UNKNOWN:
|
||||
|
@ -49,6 +49,8 @@ enum class IdentifiedFileType {
|
||||
PSP_SAVEDATA_DIRECTORY,
|
||||
PPSSPP_SAVESTATE,
|
||||
|
||||
PPSSPP_GE_DUMP,
|
||||
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
|
@ -27,11 +27,12 @@
|
||||
#include "Core/ELF/ElfReader.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
|
||||
#include "FileSystems/BlockDevices.h"
|
||||
#include "FileSystems/DirectoryFileSystem.h"
|
||||
#include "FileSystems/ISOFileSystem.h"
|
||||
#include "FileSystems/MetaFileSystem.h"
|
||||
#include "FileSystems/VirtualDiscFileSystem.h"
|
||||
#include "Core/FileSystems/BlockDevices.h"
|
||||
#include "Core/FileSystems/BlobFileSystem.h"
|
||||
#include "Core/FileSystems/DirectoryFileSystem.h"
|
||||
#include "Core/FileSystems/ISOFileSystem.h"
|
||||
#include "Core/FileSystems/MetaFileSystem.h"
|
||||
#include "Core/FileSystems/VirtualDiscFileSystem.h"
|
||||
|
||||
#include "Core/Loaders.h"
|
||||
#include "Core/MemMap.h"
|
||||
@ -355,3 +356,11 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
|
||||
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||
}
|
||||
|
||||
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) {
|
||||
BlobFileSystem *umd = new BlobFileSystem(&pspFileSystem, fileLoader, "data.ppdmp");
|
||||
pspFileSystem.Mount("disc0:", umd);
|
||||
|
||||
__KernelLoadGEDump(error_string);
|
||||
return true;
|
||||
}
|
||||
|
@ -23,5 +23,6 @@ class FileLoader;
|
||||
|
||||
bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string);
|
||||
bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string);
|
||||
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string);
|
||||
void InitMemoryForGameISO(FileLoader *fileLoader);
|
||||
void InitMemoryForGamePBP(FileLoader *fileLoader);
|
||||
|
@ -21,7 +21,10 @@
|
||||
#include "base/stringutil.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/FileSystems/MetaFileSystem.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/System.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -412,4 +415,47 @@ void NotifyFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
bool RunMountedReplay() {
|
||||
_assert_msg_(SYSTEM, !active && !nextFrame, "Cannot run replay while recording.");
|
||||
|
||||
u32 fp = pspFileSystem.OpenFile("disc0:/data.ppdmp", FILEACCESS_READ);
|
||||
u8 header[8]{};
|
||||
int version = 0;
|
||||
pspFileSystem.ReadFile(fp, header, sizeof(header));
|
||||
pspFileSystem.ReadFile(fp, (u8 *)&version, sizeof(version));
|
||||
|
||||
if (memcmp(header, HEADER, sizeof(HEADER)) != 0 || version != VERSION) {
|
||||
ERROR_LOG(SYSTEM, "Invalid GE dump or unsupported version");
|
||||
return false;
|
||||
}
|
||||
|
||||
int sz = 0;
|
||||
pspFileSystem.ReadFile(fp, (u8 *)&sz, sizeof(sz));
|
||||
int bufsz = 0;
|
||||
pspFileSystem.ReadFile(fp, (u8 *)&bufsz, sizeof(bufsz));
|
||||
|
||||
commands.resize(sz);
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
size_t read = 0;
|
||||
read += pspFileSystem.ReadFile(fp, (u8 *)&commands[i].type, sizeof(commands[i].type));
|
||||
read += pspFileSystem.ReadFile(fp, (u8 *)&commands[i].sz, sizeof(commands[i].sz));
|
||||
read += pspFileSystem.ReadFile(fp, (u8 *)&commands[i].ptr, sizeof(commands[i].ptr));
|
||||
if (read != sizeof(commands[i].type) + sizeof(commands[i].sz) + sizeof(commands[i].ptr)) {
|
||||
ERROR_LOG(SYSTEM, "Truncated GE dump");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pushbuf.resize(bufsz);
|
||||
if (pspFileSystem.ReadFile(fp, pushbuf.data(), bufsz) != bufsz) {
|
||||
ERROR_LOG(SYSTEM, "Truncated GE dump");
|
||||
return false;
|
||||
}
|
||||
|
||||
pspFileSystem.CloseFile(fp);
|
||||
|
||||
// TODO: Execute commands.
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -29,4 +29,6 @@ void NotifyMemset(u32 dest, int v, u32 sz);
|
||||
void NotifyUpload(u32 dest, u32 sz);
|
||||
void NotifyFrame();
|
||||
|
||||
bool RunMountedReplay();
|
||||
|
||||
};
|
||||
|
@ -330,6 +330,7 @@
|
||||
<ClInclude Include="..\..\Core\FileLoaders\LocalFileLoader.h" />
|
||||
<ClInclude Include="..\..\Core\FileLoaders\RamCachingFileLoader.h" />
|
||||
<ClInclude Include="..\..\Core\FileLoaders\RetryingFileLoader.h" />
|
||||
<ClInclude Include="..\..\Core\FileSystems\BlobFileSystem.h" />
|
||||
<ClInclude Include="..\..\Core\FileSystems\BlockDevices.h" />
|
||||
<ClInclude Include="..\..\Core\FileSystems\DirectoryFileSystem.h" />
|
||||
<ClInclude Include="..\..\Core\FileSystems\FileSystem.h" />
|
||||
@ -521,6 +522,7 @@
|
||||
<ClCompile Include="..\..\Core\FileLoaders\LocalFileLoader.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileLoaders\RamCachingFileLoader.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileLoaders\RetryingFileLoader.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileSystems\BlobFileSystem.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileSystems\BlockDevices.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileSystems\DirectoryFileSystem.cpp" />
|
||||
<ClCompile Include="..\..\Core\FileSystems\FileSystem.cpp" />
|
||||
|
@ -166,6 +166,9 @@
|
||||
<ClCompile Include="..\..\Core\MIPS\x86\RegCacheFPU.cpp">
|
||||
<Filter>MIPS\x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Core\FileSystems\BlobFileSystem.cpp">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Core\FileSystems\BlockDevices.cpp">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClCompile>
|
||||
@ -674,6 +677,9 @@
|
||||
<ClInclude Include="..\..\Core\MIPS\x86\RegCacheFPU.h">
|
||||
<Filter>MIPS\x86</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Core\FileSystems\BlobFileSystem.h">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Core\FileSystems\BlockDevices.h">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClInclude>
|
||||
|
@ -364,6 +364,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/Core/HLE/sceGameUpdate.cpp \
|
||||
$(SRC)/Core/HLE/sceNp.cpp \
|
||||
$(SRC)/Core/HLE/scePauth.cpp \
|
||||
$(SRC)/Core/FileSystems/BlobFileSystem.cpp \
|
||||
$(SRC)/Core/FileSystems/BlockDevices.cpp \
|
||||
$(SRC)/Core/FileSystems/ISOFileSystem.cpp \
|
||||
$(SRC)/Core/FileSystems/FileSystem.cpp \
|
||||
|
Loading…
Reference in New Issue
Block a user