From 28f4e87121b06745fc1d23c33bb0b3d476a2e7ba Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Tue, 16 Nov 2021 00:10:34 -0500 Subject: [PATCH] Modified Qt GUI Lua loadRom functionality to signal the main thread to perform the ROM load. Doing so in the emulation thread can cause crashes. --- src/drivers/Qt/ConsoleWindow.cpp | 15 ++++++++++++ src/drivers/Qt/ConsoleWindow.h | 3 +++ src/drivers/Qt/fceuWrapper.cpp | 42 +++++++++++++++++++++++++------- src/drivers/Qt/fceuWrapper.h | 1 + src/lua-engine.cpp | 38 ++++++++++++++++++++--------- 5 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 2c070936..0a9dfb61 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -159,6 +159,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); connect(emulatorThread, SIGNAL(frameFinished(void)), this, SLOT(emuFrameFinish(void)) ); + connect(emulatorThread, SIGNAL(loadRomRequest(QString)), this, SLOT(loadRomRequestCB(QString)) ); connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updatePeriodic ); @@ -2268,6 +2269,15 @@ void consoleWin_t::openROMFile(void) return; } +void consoleWin_t::loadRomRequestCB( QString s ) +{ + printf("Load ROM Req: '%s'\n", s.toStdString().c_str() ); + fceuWrapperLock(); + CloseGame (); + LoadGame ( s.toStdString().c_str() ); + fceuWrapperUnLock(); +} + void consoleWin_t::closeROMCB(void) { fceuWrapperLock(); @@ -4512,6 +4522,11 @@ void emulatorThread_t::signalFrameFinished(void) emit frameFinished(); } +void emulatorThread_t::signalRomLoad( const char *path ) +{ + emit loadRomRequest( QString(path) ); +} + //----------------------------------------------------------------------------- // Custom QMenuBar for Console //----------------------------------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 1e4d7981..0b218d55 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -53,6 +53,7 @@ class emulatorThread_t : public QThread int getMaxSchedPriority(void); #endif void signalFrameFinished(void); + void signalRomLoad(const char *rom); private: void init(void); @@ -64,6 +65,7 @@ class emulatorThread_t : public QThread signals: void finished(void); void frameFinished(void); + void loadRomRequest( QString s ); }; class consoleMenuBar : public QMenuBar @@ -447,6 +449,7 @@ class consoleWin_t : public QMainWindow void winActiveChanged(void); void emuFrameFinish(void); void videoBgColorChanged( QColor &c ); + void loadRomRequestCB( QString s ); }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 8084cad2..b121da39 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -231,6 +231,17 @@ DriverKill() inited=0; } +int LoadGameFromLua( const char *path ) +{ + //printf("Load From Lua: '%s'\n", path); + fceuWrapperUnLock(); + + consoleWindow->emulatorThread->signalRomLoad(path); + + fceuWrapperLock(); + return 0; +} + /** * Reloads last game */ @@ -249,23 +260,36 @@ int reloadLastGame(void) */ int LoadGame(const char *path, bool silent) { - char fullpath[4096]; + std::string fullpath; int gg_enabled, autoLoadDebug, autoOpenDebugger, autoInputPreset; if (isloaded){ CloseGame(); } -#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) + QFileInfo fi( path ); // Resolve absolute path to file - if ( realpath( path, fullpath ) == NULL ) + if ( fi.exists() ) { - strcpy( fullpath, path ); + //printf("FI: '%s'\n", fi.absoluteFilePath().toStdString().c_str() ); + //printf("FI: '%s'\n", fi.canonicalFilePath().toStdString().c_str() ); + fullpath = fi.canonicalFilePath().toStdString(); } -#else - strcpy( fullpath, path ); -#endif + else + { + fullpath.assign( path ); + } +//#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) +// +// // Resolve absolute path to file +// if ( realpath( path, fullpath ) == NULL ) +// { +// strcpy( fullpath, path ); +// } +//#else +// strcpy( fullpath, path ); +//#endif //printf("Fullpath: %zi '%s'\n", sizeof(fullpath), fullpath ); @@ -280,13 +304,13 @@ int LoadGame(const char *path, bool silent) g_config->getOption ("SDL.RamInitMethod", &RAMInitOption); // Load the game - if(!FCEUI_LoadGame(fullpath, 1, silent)) { + if(!FCEUI_LoadGame(fullpath.c_str(), 1, silent)) { return 0; } if ( consoleWindow ) { - consoleWindow->addRecentRom( fullpath ); + consoleWindow->addRecentRom( fullpath.c_str() ); } hexEditorLoadBookmarks(); diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 198d6563..66814c7d 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -28,6 +28,7 @@ extern Config *g_config; int LoadGame(const char *path, bool silent = false); int CloseGame(void); int reloadLastGame(void); +int LoadGameFromLua( const char *path ); int fceuWrapperInit( int argc, char *argv[] ); int fceuWrapperMemoryCleanup( void ); diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index a5c2b0cd..b8ae3260 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -609,6 +609,21 @@ static int emu_getdir(lua_State *L) { extern void ReloadRom(void); +//#ifdef __QT_DRIVER__ +//static int emu_wait_for_rom_load(lua_State *L) +//{ +// fceuWrapperUnLock(); +// printf("Waiting for ROM\n"); +// #ifdef WIN32 +// msleep(1000); +// #else +// usleep(1000000); +// #endif +// fceuWrapperLock(); +// +// return 0; +//} +//#endif // emu.loadrom(string filename) // @@ -639,23 +654,22 @@ static int emu_loadrom(lua_State *L) return 1; } return 0; -#else +#elif defined(__QT_DRIVER__) const char *nameo2 = luaL_checkstring(L,1); char nameo[2048]; - #ifndef WIN32 - if ( realpath( nameo2, nameo ) == NULL ) - { - strncpy(nameo, nameo2, sizeof(nameo)); - } - #endif + strncpy(nameo, nameo2, sizeof(nameo)); + nameo[sizeof(nameo)-1] = 0; + LoadGameFromLua( nameo ); + + //lua_cpcall(L, emu_wait_for_rom_load, NULL); //printf("Attempting to Load ROM: '%s'\n", nameo ); - if (!LoadGame(nameo, true)) - { - //printf("Failed to Load ROM: '%s'\n", nameo ); - reloadLastGame(); - } + //if (!LoadGame(nameo, true)) + //{ + // //printf("Failed to Load ROM: '%s'\n", nameo ); + // reloadLastGame(); + //} if ( GameInfo ) { //printf("Currently Loaded ROM: '%s'\n", GameInfo->filename );