Skip to content

Commit

Permalink
Add support for memory card dumps in save data imports.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Dec 18, 2023
1 parent b2b86f9 commit 5d4e2ac
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 8 additions & 3 deletions Source/saves/McDumpReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,21 @@ 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);
DIRENTRY baseDirEntry = {};
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));
Expand Down
2 changes: 1 addition & 1 deletion Source/saves/McDumpReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class CMcDumpReader

CMcDumpReader(Framework::CStream&);

Directory ReadDirectory(uint32);
Directory ReadDirectory(uint32, int32 = -1);
Directory ReadRootDirectory();
std::vector<uint8> ReadFile(uint32, uint32);

Expand Down
39 changes: 39 additions & 0 deletions Source/saves/McDumpSaveImporter.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions Source/saves/McDumpSaveImporter.h
Original file line number Diff line number Diff line change
@@ -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&);
};
5 changes: 5 additions & 0 deletions Source/saves/SaveImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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.");
Expand Down
2 changes: 1 addition & 1 deletion Source/ui_qt/memorycardmanagerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 5d4e2ac

Please sign in to comment.