start moving ROM/firmware loading to the emuthread to avoid cursed bugs

This commit is contained in:
Arisotura 2024-10-24 00:27:05 +02:00
parent 1428bfb2cf
commit 82f38f0b7a
3 changed files with 63 additions and 48 deletions

View File

@ -541,7 +541,8 @@ void EmuThread::handleMessages()
break; break;
case msg_EmuStop: case msg_EmuStop:
if (msg.stopExternal) emuInstance->nds->Stop(); if (msg.param.value<bool>())
emuInstance->nds->Stop();
emuStatus = emuStatus_Paused; emuStatus = emuStatus_Paused;
emuActive = false; emuActive = false;
@ -574,6 +575,26 @@ void EmuThread::handleMessages()
emuInstance->deinitOpenGL(); emuInstance->deinitOpenGL();
useOpenGL = false; useOpenGL = false;
break; break;
case msg_BootROM:
bootResult = 0;
if (!emuInstance->loadROM(msg.param.value<QStringList>(), true))
break;
assert(emuInstance->nds != nullptr);
emuInstance->nds->Start();
bootResult = 1;
break;
case msg_BootFirmware:
bootResult = 0;
if (!emuInstance->bootToMenu())
break;
assert(emuInstance->nds != nullptr);
emuInstance->nds->Start();
bootResult = 1;
break;
} }
msgSemaphore.release(); msgSemaphore.release();
@ -626,7 +647,7 @@ void EmuThread::emuTogglePause()
void EmuThread::emuStop(bool external) void EmuThread::emuStop(bool external)
{ {
sendMessage({.type = msg_EmuStop, .stopExternal = external}); sendMessage({.type = msg_EmuStop, .param = external});
waitMessage(); waitMessage();
} }
@ -660,6 +681,32 @@ bool EmuThread::emuIsActive()
return emuActive; return emuActive;
} }
int EmuThread::bootROM(QStringList filename)
{
sendMessage(msg_EmuPause);
sendMessage({.type = msg_BootROM, .param = filename});
waitMessage(2);
if (!bootResult)
return bootResult;
sendMessage(msg_EmuRun);
waitMessage();
return bootResult;
}
int EmuThread::bootFirmware()
{
sendMessage(msg_EmuPause);
sendMessage(msg_BootFirmware);
waitMessage(2);
if (!bootResult)
return bootResult;
sendMessage(msg_EmuRun);
waitMessage();
return bootResult;
}
void EmuThread::updateRenderer() void EmuThread::updateRenderer()
{ {
if (videoRenderer != lastVideoRenderer) if (videoRenderer != lastVideoRenderer)

View File

@ -68,15 +68,15 @@ public:
msg_InitGL, msg_InitGL,
msg_DeInitGL, msg_DeInitGL,
msg_BootROM,
msg_BootFirmware,
}; };
struct Message struct Message
{ {
MessageType type; MessageType type;
union QVariant param;
{
bool stopExternal;
};
}; };
void sendMessage(Message msg); void sendMessage(Message msg);
@ -100,6 +100,9 @@ public:
void emuFrameStep(); void emuFrameStep();
void emuReset(); void emuReset();
int bootROM(QStringList filename);
int bootFirmware();
bool emuIsRunning(); bool emuIsRunning();
bool emuIsActive(); bool emuIsActive();
@ -153,6 +156,8 @@ private:
constexpr static int emuPauseStackPauseThreshold = 1; constexpr static int emuPauseStackPauseThreshold = 1;
int emuPauseStack; int emuPauseStack;
int bootResult = 0;
QMutex msgMutex; QMutex msgMutex;
QSemaphore msgSemaphore; QSemaphore msgSemaphore;
QQueue<Message> msgQueue; QQueue<Message> msgQueue;

View File

@ -1211,24 +1211,15 @@ void MainWindow::updateCartInserted(bool gba)
void MainWindow::onOpenFile() void MainWindow::onOpenFile()
{ {
emuThread->emuPause();
if (!verifySetup()) if (!verifySetup())
{
emuThread->emuUnpause();
return; return;
}
QStringList file = pickROM(false); QStringList file = pickROM(false);
if (file.isEmpty()) if (file.isEmpty())
{
emuThread->emuUnpause();
return; return;
}
if (!emuInstance->loadROM(file, true)) if (!emuThread->bootROM(file))
{ {
emuThread->emuUnpause();
return; return;
} }
@ -1237,10 +1228,6 @@ void MainWindow::onOpenFile()
recentFileList.prepend(filename); recentFileList.prepend(filename);
updateRecentFilesMenu(); updateRecentFilesMenu();
assert(emuInstance->nds != nullptr);
emuInstance->nds->Start();
emuThread->emuRun();
updateCartInserted(false); updateCartInserted(false);
} }
@ -1310,24 +1297,15 @@ void MainWindow::onClickRecentFile()
QAction *act = (QAction *)sender(); QAction *act = (QAction *)sender();
QString filename = act->data().toString(); QString filename = act->data().toString();
emuThread->emuPause();
if (!verifySetup()) if (!verifySetup())
{
emuThread->emuUnpause();
return; return;
}
const QStringList file = splitArchivePath(filename, true); const QStringList file = splitArchivePath(filename, true);
if (file.isEmpty()) if (file.isEmpty())
{
emuThread->emuUnpause();
return; return;
}
if (!emuInstance->loadROM(file, true)) if (!emuThread->bootROM(file))
{ {
emuThread->emuUnpause();
return; return;
} }
@ -1335,34 +1313,19 @@ void MainWindow::onClickRecentFile()
recentFileList.prepend(filename); recentFileList.prepend(filename);
updateRecentFilesMenu(); updateRecentFilesMenu();
assert(emuInstance->nds != nullptr);
emuInstance->nds->Start();
emuThread->emuRun();
updateCartInserted(false); updateCartInserted(false);
} }
void MainWindow::onBootFirmware() void MainWindow::onBootFirmware()
{ {
emuThread->emuPause();
if (!verifySetup()) if (!verifySetup())
{
emuThread->emuUnpause();
return; return;
}
if (!emuInstance->bootToMenu()) if (!emuThread->bootFirmware())
{ {
// TODO: better error reporting?
QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); QMessageBox::critical(this, "melonDS", "This firmware is not bootable.");
emuThread->emuUnpause();
return; return;
} }
assert(emuInstance->nds != nullptr);
emuInstance->nds->Start();
emuThread->emuRun();
} }
void MainWindow::onInsertCart() void MainWindow::onInsertCart()