diff --git a/.gitignore b/.gitignore index 04d5c0d0..1697f268 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ fceux-net-server /output/cheats /output/snaps /output/sav + +# typical CMake build directory +/build diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 9774b0d3..b6ac0807 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -57,6 +57,7 @@ cmake \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -DCMAKE_PREFIX_PATH=`brew --prefix qt5` \ -DCMAKE_PROJECT_VERSION_MAJOR=$FCEUX_VERSION_MAJOR \ -DCMAKE_PROJECT_VERSION_MINOR=$FCEUX_VERSION_MINOR \ -DCMAKE_PROJECT_VERSION_PATCH=$FCEUX_VERSION_PATCH \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7136145e..ae0c780b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -515,19 +515,24 @@ install( TARGETS ${APP_NAME} BUNDLE DESTINATION . COMPONENT Runtime RUNTIME DESTINATION bin COMPONENT Runtime ) -set( APPS ${CMAKE_INSTALL_PREFIX}/${APP_NAME}.app) -set( DIRS ${CMAKE_BINARY_DIR} /usr/local/lib) - -message(STATUS APPS: ${APPS}) -message(STATUS DIRS: ${DIRS} ) +# Use \$ to defer expansion until install script is called; CPack will call it with its own CMAKE_INSTALL_PREFIX +set(APP \${CMAKE_INSTALL_PREFIX}/${APP_NAME}.app) set(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) -set(CPACK_BUNDLE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) set(CPACK_GENERATOR "DRAGNDROP") include(CPACK) -install( CODE "include(BundleUtilities) - fixup_bundle( \"${APPS}\" \"\" \"${DIRS}\") " +# macdeployqt tool that comes with Qt: https://doc.qt.io/qt-5/macos-deployment.html#macdeploy +# Compared to fixup_bundle, correctly finds and installs Qt-specific resources as well as non-Qt dependencies +find_program(MACDEPLOYQT macdeployqt) +if(NOT MACDEPLOYQT) + message(FATAL_ERROR "Could not find macdeployqt executable") +endif() + +install( CODE " + message(STATUS \"Deploying and fixing up dependencies in app: ${APP}\") + execute_process(COMMAND \"${MACDEPLOYQT}\" \"${APP}\" -verbose=1) + " COMPONENT Runtime ) diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index 87bddb56..7e48c54b 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "../../fceu.h" @@ -23,61 +24,46 @@ static bool luaScriptRunning = false; static bool updateLuaDisplay = false; - -struct luaConsoleOutputLine -{ - char text[256]; - - luaConsoleOutputLine(void) - { - memset( text, 0, sizeof(text) ); - } - - void clear(void) - { - memset( text, 0, sizeof(text) ); - } - - void setText( const char *txt ) - { - strncpy( text, txt, sizeof(text)-1 ); - text[sizeof(text)-1] = 0; - } -}; +static bool openLuaKillMsgBox = false; +static int luaKillMsgBoxRetVal = 0; struct luaConsoleOutputBuffer { int head; int tail; int size; - struct luaConsoleOutputLine *line; + char *buf; luaConsoleOutputBuffer(void) { tail = head = 0; - size = 64; + size = 4096; - line = new luaConsoleOutputLine[size]; + buf = (char*)malloc(size); } ~luaConsoleOutputBuffer(void) { - if ( line ) + if ( buf ) { - delete [] line; line = NULL; + free(buf); buf = NULL; } } void addLine( const char *l ) { + int i=0; //printf("Adding Line %i: '%s'\n", head, l ); - line[head].setText( l ); + while ( l[i] != 0 ) + { + buf[head] = l[i]; i++; - head = (head + 1) % size; + head = (head + 1) % size; - if ( head == tail ) - { - tail = (tail + 1) % size; + if ( head == tail ) + { + tail = (tail + 1) % size; + } } } @@ -215,6 +201,33 @@ void LuaControlDialog_t::updatePeriodic(void) updateLuaWindows(); updateLuaDisplay = false; } + + if ( openLuaKillMsgBox ) + { + openLuaKillMessageBox(); + openLuaKillMsgBox = false; + } +} +//---------------------------------------------------- +void LuaControlDialog_t::openLuaKillMessageBox(void) +{ + int ret; + QMessageBox msgBox(this); + + luaKillMsgBoxRetVal = 0; + + msgBox.setIcon( QMessageBox::Warning ); + msgBox.setText( tr("The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n") ); + msgBox.setStandardButtons(QMessageBox::Yes); + msgBox.addButton(QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + + ret = msgBox.exec(); + + if ( ret == QMessageBox::Yes ) + { + luaKillMsgBoxRetVal = 1; + } } //---------------------------------------------------- void LuaControlDialog_t::openLuaScriptFile(void) @@ -319,7 +332,7 @@ void LuaControlDialog_t::refreshState(void) while ( i != outBuf.head ) { - luaOutputText.append( outBuf.line[i].text ); + luaOutputText.append( 1, outBuf.buf[i] ); i = (i + 1) % outBuf.size; } @@ -345,7 +358,7 @@ void WinLuaOnStart(intptr_t hDlgAsInt) //printf("Lua Script Running: %i \n", luaScriptRunning ); - updateLuaWindows(); + updateLuaDisplay = true; } //---------------------------------------------------- void WinLuaOnStop(intptr_t hDlgAsInt) @@ -354,7 +367,7 @@ void WinLuaOnStop(intptr_t hDlgAsInt) //printf("Lua Script Running: %i \n", luaScriptRunning ); - updateLuaWindows(); + updateLuaDisplay = true; } //---------------------------------------------------- void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) @@ -366,3 +379,40 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) updateLuaDisplay = true; } //---------------------------------------------------- +#ifdef WIN32 +int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char* const format, ...) +#else +int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw() +#endif +{ + int retval; + va_list args; + char msg[2048]; + va_start( args, format ); + retval = ::vsnprintf( msg, sizeof(msg), format, args ); + va_end(args); + + msg[ sizeof(msg)-1 ] = 0; + + outBuf.addLine( msg ); + + updateLuaDisplay = true; + + return(retval); +}; +//---------------------------------------------------- +int LuaKillMessageBox(void) +{ + //printf("Kill Lua Prompted\n"); + luaKillMsgBoxRetVal = 0; + + openLuaKillMsgBox = true; + + while ( openLuaKillMsgBox ) + { + usleep(100000); + } + + return luaKillMsgBoxRetVal; +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index fd475c17..811346a6 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -30,6 +30,7 @@ class LuaControlDialog_t : public QDialog protected: void closeEvent(QCloseEvent *bar); + void openLuaKillMessageBox(void); QTimer *periodicTimer; QLineEdit *scriptPath; @@ -49,3 +50,17 @@ class LuaControlDialog_t : public QDialog void stopLuaScript(void); }; + +// Formatted print +#ifdef WIN32 + int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char* const format, ...) ; +#elif __linux__ + int LuaPrintfToWindowConsole(const char *__restrict format, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 1, 2))); +#else + int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); +#endif + +void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str); + +int LuaKillMessageBox(void); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 242bf349..3ef09af1 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -55,7 +55,7 @@ static const char* HotkeyStrings[HK_MAX] = { "SelectState0", "SelectState1", "SelectState2", "SelectState3", "SelectState4", "SelectState5", "SelectState6", "SelectState7", "SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev", - "VolumeDown", "VolumeUp" }; + "VolumeDown", "VolumeUp", "FKB_Enable" }; const char *getHotkeyString( int i ) { @@ -433,7 +433,10 @@ InitConfig() SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_PAGEUP, // select state next - SDLK_PAGEDOWN}; // select state prev + SDLK_PAGEDOWN, // select state prev + 0, // Volume Up Internal + 0, // Volume Down Internal + SDLK_SCROLLLOCK }; // FKB Enable Toggle prefix = "SDL.Hotkeys."; for(int i=0; i < HK_MAX; i++) diff --git a/src/drivers/Qt/config.h b/src/drivers/Qt/config.h index c413a259..269cce7c 100644 --- a/src/drivers/Qt/config.h +++ b/src/drivers/Qt/config.h @@ -20,6 +20,7 @@ enum HOTKEY { HK_CHEAT_MENU=0, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG, HK_SELECT_STATE_4, HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7, HK_SELECT_STATE_8, HK_SELECT_STATE_9, HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_VOLUME_DOWN, HK_VOLUME_UP, + HK_FKB_ENABLE, HK_MAX}; const char *getHotkeyString( int i ); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index d823ae04..4ab56df4 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -753,7 +753,8 @@ int fceuWrapperInit( int argc, char *argv[] ) g_config->setOption("SDL.LuaScript", ""); if (s != "") { -#ifdef __linux +#if defined(__linux) || defined(__APPLE__) + // Resolve absolute path to file char fullpath[2048]; if ( realpath( s.c_str(), fullpath ) != NULL ) diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 30f4c715..8feebdcc 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -446,7 +446,7 @@ static void KeyboardCommands (void) // check if the family keyboard is enabled if (CurInputType[2] == SIFC_FKB) { - if ( g_keyState[SDL_SCANCODE_SCROLLLOCK] ) + if (_keyonly (Hotkeys[HK_FKB_ENABLE])) { g_fkbEnabled ^= 1; FCEUI_DispMessage ("Family Keyboard %sabled.", 0, diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 424dc53c..363c2d0f 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -1060,6 +1060,43 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str) printf("Lua Output: %s\n", str ); } //---------------------------------------------------- +int LuaKillMessageBox(void) +{ + int kill = 0; + fprintf(stderr, "The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n"); + char buffer[64]; + while (true) { + fprintf(stderr, "(y/n): "); + fgets(buffer, sizeof(buffer), stdin); + if (buffer[0] == 'y' || buffer[0] == 'Y') { + kill = 1; + break; + } + + if (buffer[0] == 'n' || buffer[0] == 'N') + break; + } + return 0; +} +//---------------------------------------------------- +#ifdef WIN32 +int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char* const format, ...) +#else +int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw() +#endif +{ + int retval; + va_list args; + char msg[2048]; + va_start( args, format ); + retval = ::vfprintf( stdout, format, args ); + va_end(args); + + msg[ sizeof(msg)-1 ] = 0; + + return(retval); +}; +//---------------------------------------------------- // dummy functions diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 3fb628c2..fca51711 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -7,8 +7,10 @@ #include #elif __APPLE__ #include +#include #include #include +#define SetCurrentDir chdir #endif #ifdef WIN32 @@ -188,6 +190,16 @@ static intptr_t info_uid; extern HWND LuaConsoleHWnd; extern INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); void TaseditorDisableManualFunctionIfNeeded(); + +#else +int LuaKillMessageBox(void); +#ifdef __linux__ +int LuaPrintfToWindowConsole(const char *__restrict format, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 1, 2))); +#else +int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); +#endif + #endif extern void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str); extern void WinLuaOnStart(intptr_t hDlgAsInt); @@ -606,7 +618,12 @@ static int emu_loadrom(lua_State *L) #else const char *nameo2 = luaL_checkstring(L,1); char nameo[2048]; - strncpy(nameo, nameo2, sizeof(nameo)); + + if ( realpath( nameo2, nameo ) == NULL ) + { + strncpy(nameo, nameo2, sizeof(nameo)); + } + //printf("Load ROM: '%s'\n", nameo ); if (!LoadGame(nameo, true)) { reloadLastGame(); @@ -1328,6 +1345,7 @@ void CallRegisteredLuaSaveFunctions(int savestateNumber, LuaSaveData& saveData) #ifdef WIN32 MessageBox(hAppWnd, lua_tostring(L, -1), "Lua Error in SAVE function", MB_OK); #else + LuaPrintfToWindowConsole("Lua error in registersave function: %s\n", lua_tostring(L, -1)); fprintf(stderr, "Lua error in registersave function: %s\n", lua_tostring(L, -1)); #endif } @@ -1380,6 +1398,7 @@ void CallRegisteredLuaLoadFunctions(int savestateNumber, const LuaSaveData& save #ifdef WIN32 MessageBox(hAppWnd, lua_tostring(L, -1), "Lua Error in LOAD function", MB_OK); #else + LuaPrintfToWindowConsole("Lua error in registerload function: %s\n", lua_tostring(L, -1)); fprintf(stderr, "Lua error in registerload function: %s\n", lua_tostring(L, -1)); #endif } @@ -2021,6 +2040,7 @@ void HandleCallbackError(lua_State* L) #ifdef WIN32 MessageBox( hAppWnd, errmsg, "Lua run error", MB_OK | MB_ICONSTOP); #else + LuaPrintfToWindowConsole("Lua thread bombed out: %s\n", errmsg); fprintf(stderr, "Lua thread bombed out: %s\n", errmsg); #endif @@ -5729,19 +5749,23 @@ static void FCEU_LuaHookFunction(lua_State *L, lua_Debug *dbg) { } #else - fprintf(stderr, "The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n"); - char buffer[64]; - while (TRUE) { - fprintf(stderr, "(y/n): "); - fgets(buffer, sizeof(buffer), stdin); - if (buffer[0] == 'y' || buffer[0] == 'Y') { - kill = 1; - break; - } - - if (buffer[0] == 'n' || buffer[0] == 'N') - break; + if ( LuaKillMessageBox() ) + { + kill = 1; } + //fprintf(stderr, "The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n"); + //char buffer[64]; + //while (TRUE) { + // fprintf(stderr, "(y/n): "); + // fgets(buffer, sizeof(buffer), stdin); + // if (buffer[0] == 'y' || buffer[0] == 'Y') { + // kill = 1; + // break; + // } + + // if (buffer[0] == 'n' || buffer[0] == 'N') + // break; + //} #endif if (kill) { @@ -6138,6 +6162,7 @@ void FCEU_LuaFrameBoundary() //StopSound();//StopSound(); //mbg merge 7/23/08 MessageBox( hAppWnd, errmsg, "Lua run error", MB_OK | MB_ICONSTOP); #else + LuaPrintfToWindowConsole("Lua thread bombed out: %s\n", errmsg); fprintf(stderr, "Lua thread bombed out: %s\n", errmsg); #endif } else { @@ -6165,7 +6190,8 @@ void FCEU_LuaFrameBoundary() * * Returns true on success, false on failure. */ -int FCEU_LoadLuaCode(const char *filename, const char *arg) { +int FCEU_LoadLuaCode(const char *filename, const char *arg) +{ if (!DemandLua()) { return 0; @@ -6177,13 +6203,11 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) { luaScriptName = strdup(filename); } -#if defined(WIN32) || defined(__linux) std::string getfilepath = filename; getfilepath = getfilepath.substr(0,getfilepath.find_last_of("/\\") + 1); SetCurrentDir(getfilepath.c_str()); -#endif //stop any lua we might already have had running FCEU_LuaStop(); @@ -6279,6 +6303,7 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) { //StopSound();//StopSound(); //mbg merge 7/23/08 MessageBox(NULL, lua_tostring(L,-1), "Lua load error", MB_OK | MB_ICONSTOP); #else + LuaPrintfToWindowConsole("Failed to compile file: %s\n", lua_tostring(L,-1)); fprintf(stderr, "Failed to compile file: %s\n", lua_tostring(L,-1)); #endif @@ -6497,6 +6522,7 @@ void FCEU_LuaGui(uint8 *XBuf) //StopSound();//StopSound(); //mbg merge 7/23/08 MessageBox(hAppWnd, lua_tostring(L, -1), "Lua Error in GUI function", MB_OK); #else + LuaPrintfToWindowConsole("Lua error in gui.register function: %s\n", lua_tostring(L, -1)); fprintf(stderr, "Lua error in gui.register function: %s\n", lua_tostring(L, -1)); #endif // This is grounds for trashing the function diff --git a/web/ads.txt b/web/ads.txt new file mode 100644 index 00000000..a3decaad --- /dev/null +++ b/web/ads.txt @@ -0,0 +1 @@ +google.com, pub-0764229755985190, DIRECT, f08c47fec0942fa0 \ No newline at end of file