mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
Add support for memory card dumps in save data imports.
This commit is contained in:
parent
b2b86f9d94
commit
5d4e2acf19
7 changed files with 71 additions and 5 deletions
|
@ -477,6 +477,8 @@ set(COMMON_SRC_FILES
|
|||
saves/MaxSaveImporter.h
|
||||
saves/McDumpReader.cpp
|
||||
saves/McDumpReader.h
|
||||
saves/McDumpSaveImporter.cpp
|
||||
saves/McDumpSaveImporter.h
|
||||
saves/MemoryCard.cpp
|
||||
saves/PsuSaveImporter.cpp
|
||||
saves/PsuSaveImporter.h
|
||||
|
|
|
@ -46,7 +46,7 @@ CMcDumpReader::CMcDumpReader(Framework::CStream& stream)
|
|||
m_rawPageSize = m_header.pageSize + pageSpareSize;
|
||||
}
|
||||
|
||||
CMcDumpReader::Directory CMcDumpReader::ReadDirectory(uint32 dirCluster)
|
||||
CMcDumpReader::Directory CMcDumpReader::ReadDirectory(uint32 dirCluster, int32 entryCount)
|
||||
{
|
||||
std::vector<DIRENTRY> result;
|
||||
CFatReader reader(*this, dirCluster);
|
||||
|
@ -54,8 +54,13 @@ CMcDumpReader::Directory CMcDumpReader::ReadDirectory(uint32 dirCluster)
|
|||
FRAMEWORK_MAYBE_UNUSED uint32 readAmount = reader.Read(&baseDirEntry, sizeof(DIRENTRY));
|
||||
assert(readAmount == sizeof(DIRENTRY));
|
||||
result.push_back(baseDirEntry);
|
||||
assert(baseDirEntry.length >= 2);
|
||||
for(uint32 i = 0; i < (baseDirEntry.length - 1); i++)
|
||||
if(entryCount == -1)
|
||||
{
|
||||
//Use number of entries from entry itself, only seems to work with root dir.
|
||||
entryCount = baseDirEntry.length;
|
||||
}
|
||||
assert(entryCount >= 2);
|
||||
for(uint32 i = 0; i < (entryCount - 1); i++)
|
||||
{
|
||||
DIRENTRY dirEntry = {};
|
||||
readAmount = reader.Read(&dirEntry, sizeof(DIRENTRY));
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
|
||||
CMcDumpReader(Framework::CStream&);
|
||||
|
||||
Directory ReadDirectory(uint32);
|
||||
Directory ReadDirectory(uint32, int32 = -1);
|
||||
Directory ReadRootDirectory();
|
||||
std::vector<uint8> ReadFile(uint32, uint32);
|
||||
|
||||
|
|
39
Source/saves/McDumpSaveImporter.cpp
Normal file
39
Source/saves/McDumpSaveImporter.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "McDumpSaveImporter.h"
|
||||
#include "StdStreamUtils.h"
|
||||
|
||||
void CMcDumpSaveImporter::Import(Framework::CStream& input, const fs::path& basePath)
|
||||
{
|
||||
CMcDumpReader reader(input);
|
||||
auto dir = reader.ReadRootDirectory();
|
||||
ImportDirectory(reader, dir, basePath);
|
||||
}
|
||||
|
||||
void CMcDumpSaveImporter::ImportDirectory(CMcDumpReader& reader, const CMcDumpReader::Directory& dir, const fs::path& basePath)
|
||||
{
|
||||
if(!fs::exists(basePath))
|
||||
{
|
||||
fs::create_directory(basePath);
|
||||
}
|
||||
|
||||
for(const auto& dirEntry : dir)
|
||||
{
|
||||
if(!strcmp(dirEntry.name, ".")) continue;
|
||||
if(!strcmp(dirEntry.name, "..")) continue;
|
||||
auto entryOutputPath = basePath / dirEntry.name;
|
||||
if(dirEntry.mode & CMcDumpReader::DF_DIRECTORY)
|
||||
{
|
||||
auto subDir = reader.ReadDirectory(dirEntry.cluster, dirEntry.length);
|
||||
ImportDirectory(reader, subDir, entryOutputPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CanExtractFile(entryOutputPath))
|
||||
{
|
||||
auto fileContents = reader.ReadFile(dirEntry.cluster, dirEntry.length);
|
||||
assert(fileContents.size() == dirEntry.length);
|
||||
auto output = Framework::CreateOutputStdStream(entryOutputPath.native());
|
||||
output.Write(fileContents.data(), fileContents.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
Source/saves/McDumpSaveImporter.h
Normal file
15
Source/saves/McDumpSaveImporter.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "SaveImporterBase.h"
|
||||
#include "McDumpReader.h"
|
||||
|
||||
class CMcDumpSaveImporter : public CSaveImporterBase
|
||||
{
|
||||
public:
|
||||
virtual ~CMcDumpSaveImporter() = default;
|
||||
|
||||
void Import(Framework::CStream&, const fs::path&) override;
|
||||
|
||||
private:
|
||||
void ImportDirectory(CMcDumpReader&, const CMcDumpReader::Directory&, const fs::path&);
|
||||
};
|
|
@ -3,6 +3,7 @@
|
|||
#include "PsuSaveImporter.h"
|
||||
#include "XpsSaveImporter.h"
|
||||
#include "MaxSaveImporter.h"
|
||||
#include "McDumpSaveImporter.h"
|
||||
|
||||
void CSaveImporter::ImportSave(Framework::CStream& input, const fs::path& outputPath, const OverwritePromptHandlerType& overwritePromptHandler)
|
||||
{
|
||||
|
@ -23,6 +24,10 @@ void CSaveImporter::ImportSave(Framework::CStream& input, const fs::path& output
|
|||
{
|
||||
importer = std::make_shared<CMaxSaveImporter>();
|
||||
}
|
||||
else if(signature == 0x796E6F53)
|
||||
{
|
||||
importer = std::make_shared<CMcDumpSaveImporter>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unknown input file format.");
|
||||
|
|
|
@ -37,7 +37,7 @@ void MemoryCardManagerDialog::on_import_saves_button_clicked()
|
|||
QFileDialog dialog(this);
|
||||
dialog.setDirectory(m_lastpath);
|
||||
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||
dialog.setNameFilter(tr("All Supported types (*.psu *.sps *.xps *.max);;EMS Memory Adapter Save Dumps (*.psu);;Sharkport/X-Port Save Dumps (*.sps; *.xps);;Action Replay MAX Save Dumps (*.max);;All files (*.*)"));
|
||||
dialog.setNameFilter(tr("All Supported types (*.psu *.sps *.xps *.max; *.ps2);;EMS Memory Adapter Save Dumps (*.psu);;Sharkport/X-Port Save Dumps (*.sps; *.xps);;Action Replay MAX Save Dumps (*.max);;Raw Memory Card Dumps (*.ps2);;All files (*.*)"));
|
||||
if(dialog.exec())
|
||||
{
|
||||
QString fileName = dialog.selectedFiles().first();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue