aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRSDuck <rsduck@users.noreply.github.com>2020-09-11 03:08:06 +0200
committerRSDuck <rsduck@users.noreply.github.com>2020-09-11 03:08:06 +0200
commitf2fa52f26ceb1f385d58e57ab26ca7d5349978d2 (patch)
treecd5a01d7ee45b118bad3fcf8de9e9237c368686a /src
parent00e2ec3faf43b1fa6ad3def0e97828083244a47a (diff)
add functionality to import savefiles
Diffstat (limited to 'src')
-rw-r--r--src/NDS.cpp5
-rw-r--r--src/NDS.h2
-rw-r--r--src/NDSCart.cpp6
-rw-r--r--src/NDSCart.h2
-rw-r--r--src/frontend/FrontendUtil.h3
-rw-r--r--src/frontend/Util_ROM.cpp15
-rw-r--r--src/frontend/qt_sdl/main.cpp41
-rw-r--r--src/frontend/qt_sdl/main.h2
8 files changed, 76 insertions, 0 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 20f149a..90149ad 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -1124,6 +1124,11 @@ void MicInputFrame(s16* data, int samples)
return SPI_TSC::MicInputFrame(data, samples);
}
+int ImportSRAM(u8* data, u32 length)
+{
+ return NDSCart::ImportSRAM(data, length);
+}
+
void Halt()
{
diff --git a/src/NDS.h b/src/NDS.h
index 91bfd1c..046d84b 100644
--- a/src/NDS.h
+++ b/src/NDS.h
@@ -211,6 +211,8 @@ void SetLidClosed(bool closed);
void MicInputFrame(s16* data, int samples);
+int ImportSRAM(u8* data, u32 length);
+
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
void CancelEvent(u32 id);
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp
index 6abfc7c..5710213 100644
--- a/src/NDSCart.cpp
+++ b/src/NDSCart.cpp
@@ -1034,6 +1034,12 @@ void RelocateSave(const char* path, bool write)
NDSCart_SRAM::RelocateSave(path, write);
}
+int ImportSRAM(const u8* data, u32 length)
+{
+ memcpy(NDSCart_SRAM::SRAM, data, std::min(length, NDSCart_SRAM::SRAMLength));
+ return length - NDSCart_SRAM::SRAMLength;
+}
+
void ResetCart()
{
// CHECKME: what if there is a transfer in progress?
diff --git a/src/NDSCart.h b/src/NDSCart.h
index a759c15..9fe916d 100644
--- a/src/NDSCart.h
+++ b/src/NDSCart.h
@@ -48,6 +48,8 @@ void DecryptSecureArea(u8* out);
bool LoadROM(const char* path, const char* sram, bool direct);
void RelocateSave(const char* path, bool write);
+int ImportSRAM(const u8* data, u32 length);
+
void ResetCart();
void WriteROMCnt(u32 val);
diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h
index d30c4e1..caac9f0 100644
--- a/src/frontend/FrontendUtil.h
+++ b/src/frontend/FrontendUtil.h
@@ -100,6 +100,9 @@ bool SaveState(const char* filename);
// undo the latest savestate load
void UndoStateLoad();
+// imports savedata from an external file. Returns the difference between the filesize and the SRAM size
+int ImportSRAM(const char* filename);
+
// enable or disable cheats
void EnableCheats(bool enable);
diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp
index 716ed04..f61c3e3 100644
--- a/src/frontend/Util_ROM.cpp
+++ b/src/frontend/Util_ROM.cpp
@@ -588,6 +588,21 @@ void UndoStateLoad()
}
}
+int ImportSRAM(const char* filename)
+{
+ FILE* file = fopen(filename, "rb");
+ fseek(file, 0, SEEK_END);
+ u32 size = ftell(file);
+ u8* importData = new u8[size];
+ rewind(file);
+ fread(importData, size, 1, file);
+ fclose(file);
+
+ int diff = NDS::ImportSRAM(importData, size);
+ delete[] importData;
+ return diff;
+}
+
void EnableCheats(bool enable)
{
CheatsOn = enable;
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 9d2a2ca..1900998 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1052,6 +1052,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12));
connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad);
+ actImportSavefile = menu->addAction("Import savefile");
+ connect(actImportSavefile, &QAction::triggered, this, &MainWindow::onImportSavefile);
+
menu->addSeparator();
actQuit = menu->addAction("Quit");
@@ -1220,6 +1223,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actLoadState[i]->setEnabled(false);
}
actUndoStateLoad->setEnabled(false);
+ actImportSavefile->setEnabled(false);
actPause->setEnabled(false);
actReset->setEnabled(false);
@@ -1618,6 +1622,41 @@ void MainWindow::onUndoStateLoad()
OSD::AddMessage(0, "State load undone");
}
+void MainWindow::onImportSavefile()
+{
+ if (!RunningSomething) return;
+
+ emuThread->emuPause();
+ QString path = QFileDialog::getOpenFileName(this,
+ "Select savefile",
+ Config::LastROMFolder,
+ "Savefiles (*.sav *.bin *.dsv);;Any file (*.*)");
+
+ if (!path.isEmpty())
+ {
+ if (QMessageBox::warning(this,
+ "Emulation will be reset and data overwritten",
+ "The emulation will be reset and the current savefile overwritten.",
+ QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
+ {
+ int res = Frontend::Reset();
+ if (res != Frontend::Load_OK)
+ {
+ QMessageBox::critical(this, "melonDS", "Reset failed\n" + loadErrorStr(res));
+ }
+ else
+ {
+ int diff = Frontend::ImportSRAM(path.toStdString().c_str());
+ if (diff > 0)
+ OSD::AddMessage(0, "Trimmed savefile");
+ else if (diff < 0)
+ OSD::AddMessage(0, "Savefile shorter than SRAM");
+ }
+ }
+ }
+ emuThread->emuUnpause();
+}
+
void MainWindow::onQuit()
{
QApplication::quit();
@@ -1923,6 +1962,7 @@ void MainWindow::onEmuStart()
actPause->setChecked(false);
actReset->setEnabled(true);
actStop->setEnabled(true);
+ actImportSavefile->setEnabled(true);
actSetupCheats->setEnabled(true);
}
@@ -1937,6 +1977,7 @@ void MainWindow::onEmuStop()
actLoadState[i]->setEnabled(false);
}
actUndoStateLoad->setEnabled(false);
+ actImportSavefile->setEnabled(false);
actPause->setEnabled(false);
actReset->setEnabled(false);
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index 6ae5122..978df9e 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -195,6 +195,7 @@ private slots:
void onSaveState();
void onLoadState();
void onUndoStateLoad();
+ void onImportSavefile();
void onQuit();
void onPause(bool checked);
@@ -247,6 +248,7 @@ public:
QAction* actSaveState[9];
QAction* actLoadState[9];
QAction* actUndoStateLoad;
+ QAction* actImportSavefile;
QAction* actQuit;
QAction* actPause;