reconnect the save manager thing

This commit is contained in:
Arisotura 2022-01-03 19:12:11 +01:00
parent 3abfa269ba
commit 52a9abde6f
11 changed files with 167 additions and 97 deletions

View File

@ -1161,8 +1161,6 @@ u32 RunFrame()
GPU3D::Timestamp-SysTimestamp); GPU3D::Timestamp-SysTimestamp);
#endif #endif
SPU::TransferOutput(); SPU::TransferOutput();
//NDSCart::FlushSRAMFile();
} }
// In the context of TASes, frame count is traditionally the primary measure of emulated time, // In the context of TASes, frame count is traditionally the primary measure of emulated time,

View File

@ -672,6 +672,7 @@ u8 CartRetail::SRAMWrite_EEPROMTiny(u8 val, u32 pos, bool last)
if (pos < 2) if (pos < 2)
{ {
SRAMAddr = val; SRAMAddr = val;
SRAMFirstAddr = SRAMAddr;
} }
else else
{ {
@ -679,11 +680,15 @@ u8 CartRetail::SRAMWrite_EEPROMTiny(u8 val, u32 pos, bool last)
if (SRAMStatus & (1<<1)) if (SRAMStatus & (1<<1))
{ {
SRAM[(SRAMAddr + ((SRAMCmd==0x0A)?0x100:0)) & 0x1FF] = val; SRAM[(SRAMAddr + ((SRAMCmd==0x0A)?0x100:0)) & 0x1FF] = val;
SRAMFileDirty |= last;
} }
SRAMAddr++; SRAMAddr++;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
(SRAMFirstAddr + ((SRAMCmd==0x0A)?0x100:0)) & 0x1FF, SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
case 0x03: // read low case 0x03: // read low
@ -731,6 +736,7 @@ u8 CartRetail::SRAMWrite_EEPROM(u8 val, u32 pos, bool last)
{ {
SRAMAddr <<= 8; SRAMAddr <<= 8;
SRAMAddr |= val; SRAMAddr |= val;
SRAMFirstAddr = SRAMAddr;
} }
else else
{ {
@ -738,11 +744,15 @@ u8 CartRetail::SRAMWrite_EEPROM(u8 val, u32 pos, bool last)
if (SRAMStatus & (1<<1)) if (SRAMStatus & (1<<1))
{ {
SRAM[SRAMAddr & (SRAMLength-1)] = val; SRAM[SRAMAddr & (SRAMLength-1)] = val;
SRAMFileDirty |= last;
} }
SRAMAddr++; SRAMAddr++;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
case 0x03: // read case 0x03: // read
@ -783,6 +793,7 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMAddr <<= 8; SRAMAddr <<= 8;
SRAMAddr |= val; SRAMAddr |= val;
SRAMFirstAddr = SRAMAddr;
} }
else else
{ {
@ -790,11 +801,15 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
// CHECKME: should it be &=~val ?? // CHECKME: should it be &=~val ??
SRAM[SRAMAddr & (SRAMLength-1)] = 0; SRAM[SRAMAddr & (SRAMLength-1)] = 0;
SRAMFileDirty |= last;
} }
SRAMAddr++; SRAMAddr++;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
case 0x03: // read case 0x03: // read
@ -816,17 +831,22 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMAddr <<= 8; SRAMAddr <<= 8;
SRAMAddr |= val; SRAMAddr |= val;
SRAMFirstAddr = SRAMAddr;
} }
else else
{ {
if (SRAMStatus & (1<<1)) if (SRAMStatus & (1<<1))
{ {
SRAM[SRAMAddr & (SRAMLength-1)] = val; SRAM[SRAMAddr & (SRAMLength-1)] = val;
SRAMFileDirty |= last;
} }
SRAMAddr++; SRAMAddr++;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
case 0x0B: // fast read case 0x0B: // fast read
@ -857,6 +877,7 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMAddr <<= 8; SRAMAddr <<= 8;
SRAMAddr |= val; SRAMAddr |= val;
SRAMFirstAddr = SRAMAddr;
} }
if ((pos == 3) && (SRAMStatus & (1<<1))) if ((pos == 3) && (SRAMStatus & (1<<1)))
{ {
@ -865,9 +886,13 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
SRAM[SRAMAddr & (SRAMLength-1)] = 0; SRAM[SRAMAddr & (SRAMLength-1)] = 0;
SRAMAddr++; SRAMAddr++;
} }
SRAMFileDirty = true;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
case 0xDB: // page erase case 0xDB: // page erase
@ -875,6 +900,7 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMAddr <<= 8; SRAMAddr <<= 8;
SRAMAddr |= val; SRAMAddr |= val;
SRAMFirstAddr = SRAMAddr;
} }
if ((pos == 3) && (SRAMStatus & (1<<1))) if ((pos == 3) && (SRAMStatus & (1<<1)))
{ {
@ -883,9 +909,13 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
SRAM[SRAMAddr & (SRAMLength-1)] = 0; SRAM[SRAMAddr & (SRAMLength-1)] = 0;
SRAMAddr++; SRAMAddr++;
} }
SRAMFileDirty = true;
} }
if (last) SRAMStatus &= ~(1<<1); if (last)
{
SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM, SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr);
}
return 0; return 0;
default: default:
@ -974,7 +1004,7 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len)
if (SRAMLength && SRAMAddr < (SRAMBase+SRAMLength-0x20000)) if (SRAMLength && SRAMAddr < (SRAMBase+SRAMLength-0x20000))
{ {
memcpy(&SRAM[SRAMAddr - SRAMBase], SRAMWriteBuffer, 0x800); memcpy(&SRAM[SRAMAddr - SRAMBase], SRAMWriteBuffer, 0x800);
SRAMFileDirty = true; Platform::WriteNDSSave(SRAM, SRAMLength, SRAMAddr - SRAMBase, 0x800);
} }
SRAMAddr = 0; SRAMAddr = 0;

View File

@ -99,11 +99,9 @@ protected:
u32 SRAMLength; u32 SRAMLength;
u32 SRAMType; u32 SRAMType;
char SRAMPath[1024];
bool SRAMFileDirty;
u8 SRAMCmd; u8 SRAMCmd;
u32 SRAMAddr; u32 SRAMAddr;
u32 SRAMFirstAddr;
u8 SRAMStatus; u8 SRAMStatus;
}; };

View File

@ -145,8 +145,11 @@ void Mutex_Unlock(Mutex* mutex);
bool Mutex_TryLock(Mutex* mutex); bool Mutex_TryLock(Mutex* mutex);
void WriteNDSSave(const u8* savedata, u32 savelen); // functions called when the NDS or GBA save files need to be written back to storage
void WriteGBASave(const u8* savedata, u32 savelen); // savedata and savelen are always the entire save memory buffer and its full length
// writeoffset and writelen indicate which part of the memory was altered
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen);
void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen);
// local multiplayer comm interface // local multiplayer comm interface

View File

@ -25,7 +25,7 @@ SET(SOURCES_QT_SDL
font.h font.h
Platform.cpp Platform.cpp
QPathInput.h QPathInput.h
ROMLoader.cpp ROMManager.cpp
SaveManager.cpp SaveManager.cpp
ArchiveUtil.h ArchiveUtil.h

View File

@ -52,6 +52,7 @@
#include "Platform.h" #include "Platform.h"
#include "Config.h" #include "Config.h"
#include "ROMManager.h"
#include "LAN_Socket.h" #include "LAN_Socket.h"
#include "LAN_PCap.h" #include "LAN_PCap.h"
#include <string> #include <string>
@ -372,12 +373,13 @@ bool Mutex_TryLock(Mutex* mutex)
} }
void WriteNDSSave(const u8* savedata, u32 savelen) void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
{ {
// if (ROMManager::NDSSave)
ROMManager::NDSSave->RequestFlush(savedata, savelen, writeoffset, writelen);
} }
void WriteGBASave(const u8* savedata, u32 savelen) void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
{ {
// //
} }

View File

@ -25,26 +25,27 @@
#ifdef ARCHIVE_SUPPORT_ENABLED #ifdef ARCHIVE_SUPPORT_ENABLED
#include "ArchiveUtil.h" #include "ArchiveUtil.h"
#endif #endif
#include "ROMLoader.h" #include "ROMManager.h"
#include "Config.h" #include "Config.h"
#include "Platform.h" #include "Platform.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h" #include "DSi.h"
#include "GBACart.h"
#include "AREngine.h" #include "AREngine.h"
namespace ROMLoader namespace ROMManager
{ {
std::string FullROMPath; std::string FullROMPath = "";
std::string BaseROMDir; std::string BaseROMDir = "";
std::string BaseROMName; std::string BaseROMName = "";
std::string BaseAssetName; std::string BaseAssetName = "";
int GBACartType; int GBACartType = -1;
SaveManager* NDSSave = nullptr;
int LastSep(std::string path) int LastSep(std::string path)
@ -280,6 +281,9 @@ bool LoadBIOS()
if (NDS::NeedsDirectBoot()) if (NDS::NeedsDirectBoot())
return false; return false;
if (NDSSave) delete NDSSave;
NDSSave = nullptr;
FullROMPath = ""; FullROMPath = "";
BaseROMDir = ""; BaseROMDir = "";
BaseROMName = ""; BaseROMName = "";
@ -362,6 +366,9 @@ bool LoadROM(QStringList filepath, bool reset)
else else
return false; return false;
if (NDSSave) delete NDSSave;
NDSSave = nullptr;
FullROMPath = fullpath; FullROMPath = fullpath;
BaseROMDir = basepath; BaseROMDir = basepath;
BaseROMName = romname; BaseROMName = romname;
@ -398,6 +405,11 @@ bool LoadROM(QStringList filepath, bool reset)
} }
} }
if (res)
{
NDSSave = new SaveManager(savname);
}
delete[] savedata; delete[] savedata;
delete[] filedata; delete[] filedata;
return res; return res;
@ -405,6 +417,9 @@ bool LoadROM(QStringList filepath, bool reset)
void EjectCart() void EjectCart()
{ {
if (NDSSave) delete NDSSave;
NDSSave = nullptr;
NDS::EjectCart(); NDS::EjectCart();
FullROMPath = ""; FullROMPath = "";
@ -456,6 +471,8 @@ QString GBACartLabel()
void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef) void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef)
{ {
int index = 0; int index = 0;

View File

@ -16,17 +16,20 @@
with melonDS. If not, see http://www.gnu.org/licenses/. with melonDS. If not, see http://www.gnu.org/licenses/.
*/ */
#ifndef ROMLOADER_H #ifndef ROMMANAGER_H
#define ROMLOADER_H #define ROMMANAGER_H
#include "types.h" #include "types.h"
#include "SaveManager.h"
#include <string> #include <string>
#include <vector> #include <vector>
namespace ROMLoader namespace ROMManager
{ {
extern SaveManager* NDSSave;
QString VerifySetup(); QString VerifySetup();
void Reset(); void Reset();
bool LoadBIOS(); bool LoadBIOS();
@ -81,4 +84,4 @@ enum
} }
#endif // ROMLOADER_H #endif // ROMMANAGER_H

View File

@ -23,12 +23,29 @@
#include "Platform.h" #include "Platform.h"
SaveManager::SaveManager() SaveManager::SaveManager(std::string path) : QThread()
{ {
SecondaryBuffer = nullptr; SecondaryBuffer = nullptr;
SecondaryBufferLength = 0;
SecondaryBufferLock = new QMutex(); SecondaryBufferLock = new QMutex();
Running = false; Running = false;
Path = path;
Buffer = nullptr;
Length = 0;
FlushRequested = false;
FlushVersion = 0;
PreviousFlushVersion = 0;
TimeAtLastFlushRequest = 0;
if (!path.empty())
{
Running = true;
start();
}
} }
SaveManager::~SaveManager() SaveManager::~SaveManager()
@ -43,49 +60,59 @@ SaveManager::~SaveManager()
if (SecondaryBuffer) delete[] SecondaryBuffer; if (SecondaryBuffer) delete[] SecondaryBuffer;
delete SecondaryBufferLock; delete SecondaryBufferLock;
if (Buffer) delete[] Buffer;
} }
void SaveManager::Setup(std::string path, u8* buffer, u32 length) void SaveManager::RequestFlush(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
{ {
// Flush SRAM in case there is unflushed data from previous state. if (Length != savelen)
FlushSecondaryBuffer();
SecondaryBufferLock->lock();
Path = path;
Buffer = buffer;
Length = length;
if(SecondaryBuffer) delete[] SecondaryBuffer; // Delete secondary buffer, there might be previous state.
SecondaryBuffer = new u8[length];
SecondaryBufferLength = length;
FlushVersion = 0;
PreviousFlushVersion = 0;
TimeAtLastFlushRequest = 0;
SecondaryBufferLock->unlock();
if ((!path.empty()) && (!Running))
{ {
Running = true; if (Buffer) delete[] Buffer;
start();
Length = savelen;
Buffer = new u8[Length];
memcpy(Buffer, savedata, Length);
} }
else if (path.empty() && Running) else
{ {
Running = false; if ((writeoffset+writelen) > savelen)
wait(); {
u32 len = savelen - writeoffset;
memcpy(&Buffer[writeoffset], &savedata[writeoffset], len);
len = writelen - len;
if (len > savelen) len = savelen;
memcpy(&Buffer[0], &savedata[0], len);
}
else
{
memcpy(&Buffer[writeoffset], &savedata[writeoffset], writelen);
}
} }
FlushRequested = true;
} }
void SaveManager::RequestFlush() void SaveManager::CheckFlush()
{ {
if (!FlushRequested) return;
SecondaryBufferLock->lock(); SecondaryBufferLock->lock();
printf("SaveManager: Flush requested\n"); printf("SaveManager: Flush requested\n");
if (SecondaryBufferLength != Length)
{
if (SecondaryBuffer) delete[] SecondaryBuffer;
SecondaryBufferLength = Length;
SecondaryBuffer = new u8[SecondaryBufferLength];
}
memcpy(SecondaryBuffer, Buffer, Length); memcpy(SecondaryBuffer, Buffer, Length);
FlushRequested = false;
FlushVersion++; FlushVersion++;
TimeAtLastFlushRequest = time(nullptr); TimeAtLastFlushRequest = time(nullptr);
@ -112,6 +139,8 @@ void SaveManager::run()
void SaveManager::FlushSecondaryBuffer(u8* dst, u32 dstLength) void SaveManager::FlushSecondaryBuffer(u8* dst, u32 dstLength)
{ {
if (!SecondaryBuffer) return;
// When flushing to a file, there's no point in re-writing the exact same data. // When flushing to a file, there's no point in re-writing the exact same data.
if (!dst && !NeedsFlush()) return; if (!dst && !NeedsFlush()) return;
// When flushing to memory, we don't know if dst already has any data so we only check that we CAN flush. // When flushing to memory, we don't know if dst already has any data so we only check that we CAN flush.
@ -141,16 +170,3 @@ bool SaveManager::NeedsFlush()
{ {
return FlushVersion != PreviousFlushVersion; return FlushVersion != PreviousFlushVersion;
} }
void SaveManager::UpdateBuffer(u8* src, u32 srcLength)
{
if (!src || srcLength != Length) return;
// should we create a lock for the primary buffer? this method is not intended to be called from a secondary thread in the way Flush is
memcpy(Buffer, src, srcLength);
SecondaryBufferLock->lock();
memcpy(SecondaryBuffer, src, srcLength);
SecondaryBufferLock->unlock();
PreviousFlushVersion = FlushVersion;
}

View File

@ -34,15 +34,14 @@ class SaveManager : public QThread
void run() override; void run() override;
public: public:
SaveManager(); SaveManager(std::string path);
~SaveManager(); ~SaveManager();
void Setup(std::string path, u8* buffer, u32 length); void RequestFlush(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen);
void RequestFlush(); void CheckFlush();
bool NeedsFlush(); bool NeedsFlush();
void FlushSecondaryBuffer(u8* dst = nullptr, u32 dstLength = 0); void FlushSecondaryBuffer(u8* dst = nullptr, u32 dstLength = 0);
void UpdateBuffer(u8* src, u32 srcLength);
private: private:
std::string Path; std::string Path;
@ -51,6 +50,7 @@ private:
u8* Buffer; u8* Buffer;
u32 Length; u32 Length;
bool FlushRequested;
QMutex* SecondaryBufferLock; QMutex* SecondaryBufferLock;
u8* SecondaryBuffer; u8* SecondaryBuffer;

View File

@ -81,7 +81,7 @@
#include "main_shaders.h" #include "main_shaders.h"
#include "ROMLoader.h" #include "ROMManager.h"
#include "ArchiveUtil.h" #include "ArchiveUtil.h"
// TODO: uniform variable spelling // TODO: uniform variable spelling
@ -543,6 +543,9 @@ void EmuThread::run()
// emulate // emulate
u32 nlines = NDS::RunFrame(); u32 nlines = NDS::RunFrame();
if (ROMManager::NDSSave)
ROMManager::NDSSave->CheckFlush();
FrontBufferLock.lock(); FrontBufferLock.lock();
FrontBuffer = GPU::FrontBuffer; FrontBuffer = GPU::FrontBuffer;
#ifdef OGLRENDERER_ENABLED #ifdef OGLRENDERER_ENABLED
@ -1308,7 +1311,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
menu->addSeparator(); menu->addSeparator();
actCurrentCart = menu->addAction("DS slot: " + ROMLoader::CartLabel()); actCurrentCart = menu->addAction("DS slot: " + ROMManager::CartLabel());
actCurrentCart->setEnabled(false); actCurrentCart->setEnabled(false);
actInsertCart = menu->addAction("Insert cart..."); actInsertCart = menu->addAction("Insert cart...");
@ -1319,7 +1322,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
menu->addSeparator(); menu->addSeparator();
actCurrentGBACart = menu->addAction("GBA slot: " + ROMLoader::GBACartLabel()); actCurrentGBACart = menu->addAction("GBA slot: " + ROMManager::GBACartLabel());
actCurrentGBACart->setEnabled(false); actCurrentGBACart->setEnabled(false);
actInsertGBACart = menu->addAction("Insert ROM cart..."); actInsertGBACart = menu->addAction("Insert ROM cart...");
@ -2019,7 +2022,7 @@ void MainWindow::loadROM(QString filename)
bool MainWindow::verifySetup() bool MainWindow::verifySetup()
{ {
QString res = ROMLoader::VerifySetup(); QString res = ROMManager::VerifySetup();
if (!res.isEmpty()) if (!res.isEmpty())
{ {
QMessageBox::critical(this, "melonDS", res); QMessageBox::critical(this, "melonDS", res);
@ -2145,7 +2148,7 @@ void MainWindow::onOpenFile()
// TODO: add to recent ROM list // TODO: add to recent ROM list
if (!ROMLoader::LoadROM(file, true)) if (!ROMManager::LoadROM(file, true))
{ {
// TODO: better error reporting? // TODO: better error reporting?
QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
@ -2156,7 +2159,7 @@ void MainWindow::onOpenFile()
NDS::Start(); NDS::Start();
emuThread->emuRun(); emuThread->emuRun();
actCurrentCart->setText("DS slot: " + ROMLoader::CartLabel()); actCurrentCart->setText("DS slot: " + ROMManager::CartLabel());
actEjectCart->setEnabled(true); actEjectCart->setEnabled(true);
} }
@ -2308,7 +2311,7 @@ void MainWindow::onBootFirmware()
return; return;
} }
if (!ROMLoader::LoadBIOS()) if (!ROMManager::LoadBIOS())
{ {
// TODO: better error reporting? // TODO: better error reporting?
QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); QMessageBox::critical(this, "melonDS", "This firmware is not bootable.");
@ -2333,7 +2336,7 @@ void MainWindow::onInsertCart()
// TODO: add to recent ROM list?? // TODO: add to recent ROM list??
if (!ROMLoader::LoadROM(file, false)) if (!ROMManager::LoadROM(file, false))
{ {
// TODO: better error reporting? // TODO: better error reporting?
QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
@ -2343,7 +2346,7 @@ void MainWindow::onInsertCart()
emuThread->emuUnpause(); emuThread->emuUnpause();
actCurrentCart->setText("DS slot: " + ROMLoader::CartLabel()); actCurrentCart->setText("DS slot: " + ROMManager::CartLabel());
actEjectCart->setEnabled(true); actEjectCart->setEnabled(true);
} }
@ -2351,11 +2354,11 @@ void MainWindow::onEjectCart()
{ {
emuThread->emuPause(); emuThread->emuPause();
ROMLoader::EjectCart(); ROMManager::EjectCart();
emuThread->emuUnpause(); emuThread->emuUnpause();
actCurrentCart->setText("DS slot: " + ROMLoader::CartLabel()); actCurrentCart->setText("DS slot: " + ROMManager::CartLabel());
actEjectCart->setEnabled(false); actEjectCart->setEnabled(false);
} }
@ -2368,11 +2371,11 @@ void MainWindow::onInsertGBAAddon()
emuThread->emuPause(); emuThread->emuPause();
ROMLoader::LoadGBAAddon(type); ROMManager::LoadGBAAddon(type);
emuThread->emuUnpause(); emuThread->emuUnpause();
actCurrentGBACart->setText("GBA slot: " + ROMLoader::GBACartLabel()); actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel());
actEjectGBACart->setEnabled(true); actEjectGBACart->setEnabled(true);
} }
@ -2554,7 +2557,7 @@ void MainWindow::onReset()
actUndoStateLoad->setEnabled(false); actUndoStateLoad->setEnabled(false);
ROMLoader::Reset(); ROMManager::Reset();
OSD::AddMessage(0, "Reset"); OSD::AddMessage(0, "Reset");
emuThread->emuRun(); emuThread->emuRun();