From e6335506479f2c4b3f7ee8e5c6040720c352de21 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 16 Oct 2023 14:55:01 -0500 Subject: [PATCH] automatic safe mode! to-do: test on Windows... --- src/engine/engine.cpp | 21 ++++++++++++++++++++- src/engine/engine.h | 7 +++++-- src/fileutils.cpp | 24 ++++++++++++++++++++++++ src/fileutils.h | 1 + src/gui/gui.cpp | 6 ++++++ src/main.cpp | 31 ++++++++++++++++++++++++++++++- 6 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 84c6a6de6..0963c21c9 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3634,7 +3634,8 @@ bool DivEngine::deinitAudioBackend(bool dueToSwitchMaster) { return true; } -void DivEngine::preInit() { +bool DivEngine::preInit(bool noSafeMode) { + bool wantSafe=false; // register systems if (!systemsRegistered) registerSystems(); @@ -3642,6 +3643,13 @@ void DivEngine::preInit() { initConfDir(); logD("config path: %s",configPath.c_str()); + if (!noSafeMode) { + String safeModePath=configPath+DIR_SEPARATOR_STR+"safemode"; + if (touchFile(safeModePath.c_str())==-EEXIST) { + wantSafe=true; + } + } + String logPath=configPath+DIR_SEPARATOR_STR+"furnace.log"; startLogFile(logPath.c_str()); @@ -3655,6 +3663,17 @@ void DivEngine::preInit() { SDL_SetHint("SDL_HINT_AUDIODRIVER",audioDriver.c_str()); } #endif + + if (wantSafe) { + logW("requesting safe mode."); + } + + return wantSafe; +} + +void DivEngine::everythingOK() { + String safeModePath=configPath+DIR_SEPARATOR_STR+"safemode"; + deleteFile(safeModePath.c_str()); } bool DivEngine::init() { diff --git a/src/engine/engine.h b/src/engine/engine.h index 33ed54206..3faf95284 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -1196,12 +1196,15 @@ class DivEngine { // quit dispatch void quitDispatch(); - // pre-initialize the engine. - void preInit(); + // pre-initialize the engine. returns whether Furnace should run in safe mode. + bool preInit(bool noSafeMode=true); // initialize the engine. bool init(); + // confirm that the engine is running (delete safe mode file). + void everythingOK(); + // terminate the engine. bool quit(); diff --git a/src/fileutils.cpp b/src/fileutils.cpp index f729bd5d6..ede4054c8 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -25,6 +25,7 @@ #include #else #include +#include #include #include #endif @@ -100,3 +101,26 @@ bool makeDir(const char* path) { return (mkdir(path,0755)==0); #endif } + +int touchFile(const char* path) { +#ifdef _WIN32 + HANDLE h=CreateFileW(utf8To16(path).c_str(),GENERIC_WRITE,FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_NEW,FILE_ATTRIBUTE_TEMPORARY,NULL); + if (h==INVALID_HANDLE_VALUE) { + switch (GetLastError()) { + case ERROR_FILE_EXISTS: + return -EEXIST; + break; + } + return -EPERM; + } + if (CloseHandle(h)==0) { + return -EBADF; + } + return 0; +#else + int fd=open(path,O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,0666); + if (fd<0) return -errno; + close(fd); + return 0; +#endif +} diff --git a/src/fileutils.h b/src/fileutils.h index 17ff89883..38b5732be 100644 --- a/src/fileutils.h +++ b/src/fileutils.h @@ -28,5 +28,6 @@ bool deleteFile(const char* path); int fileExists(const char* path); bool dirExists(const char* what); bool makeDir(const char* path); +int touchFile(const char* path); #endif diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index d40688715..b57721b5a 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3455,6 +3455,11 @@ bool FurnaceGUI::loop() { logD("key input: main thread"); } + if (safeMode) { + showError("Furnace has been started in Safe Mode.\nthis means that:\n\n- software rendering is being used\n- audio output may not work\n- font loading is disabled\n\ncheck any settings which may have made Furnace start up in this mode.\nfont loading is one of these."); + settingsOpen=true; + } + while (!quit) { SDL_Event ev; if (e->isPlaying()) { @@ -6244,6 +6249,7 @@ bool FurnaceGUI::loop() { if (mustClear) { rend->clear(ImVec4(0,0,0,0)); mustClear--; + if (mustClear==0) e->everythingOK(); } else { if (initialScreenWipe>0.0f && !settings.disableFadeIn) { WAKE_UP; diff --git a/src/main.cpp b/src/main.cpp index 61f32dddd..a5eaa02ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -131,14 +131,24 @@ TAParamResult pConsole(String val) { } TAParamResult pSafeMode(String val) { +#ifdef HAVE_GUI safeMode=true; return TA_PARAM_SUCCESS; +#else + logE("Furnace was compiled without the GUI. safe mode is pointless."); + return TA_PARAM_ERROR; +#endif } TAParamResult pSafeModeAudio(String val) { +#ifdef HAVE_GUI safeMode=true; safeModeWithAudio=true; return TA_PARAM_SUCCESS; +#else + logE("Furnace was compiled without the GUI. safe mode is pointless."); + return TA_PARAM_ERROR; +#endif } TAParamResult pBinary(String val) { @@ -515,7 +525,24 @@ int main(int argc, char** argv) { return 1; } - e.preInit(); +#ifdef HAVE_GUI + if (e.preInit(false)) { + if (consoleMode || benchMode || outName!="" || vgmOutName!="" || cmdOutName!="") { + logW("engine wants safe mode, but Furnace GUI is not going to start."); + } else { + safeMode=true; + } + } +#else + if (e.preInit(true)) { + logW("engine wants safe mode, but Furnace GUI is not available."); + } +#endif + + if (safeMode && (consoleMode || benchMode || outName!="" || vgmOutName!="" || cmdOutName!="")) { + logE("you can't use safe mode and console/export mode together."); + return 0; + } if (safeMode && !safeModeWithAudio) { e.setAudio(DIV_AUDIO_DUMMY); @@ -684,6 +711,7 @@ int main(int argc, char** argv) { if (!g.init()) { reportError(g.getLastError()); finishLogFile(); + e.everythingOK(); return 1; } @@ -720,5 +748,6 @@ int main(int argc, char** argv) { CoUninitialize(); } #endif + e.everythingOK(); return 0; }