From a3bcf1f8cb7c68e32d50aa21ac805787ca8fed73 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 11 Jul 2024 23:39:47 +0900 Subject: [PATCH 1/7] Some WIN32 updates --- .github/workflows/win32.yml | 6 +-- es-app/CMakeLists.txt | 1 + es-app/src/EmulationStation.manifest | 9 ++++ es-app/src/FileData.cpp | 6 ++- es-app/src/guis/GuiMenu.cpp | 2 + es-core/src/Scripting.cpp | 2 - es-core/src/platform.cpp | 72 +++++++++++++++++++++++----- es-core/src/platform.h | 3 +- es-core/src/utils/FileSystemUtil.cpp | 54 ++++++++++----------- es-core/src/utils/FileSystemUtil.h | 2 - 10 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 es-app/src/EmulationStation.manifest diff --git a/.github/workflows/win32.yml b/.github/workflows/win32.yml index f5f1d11fcb..5188c58a91 100644 --- a/.github/workflows/win32.yml +++ b/.github/workflows/win32.yml @@ -27,14 +27,14 @@ jobs: # Check-out repository under $GITHUB_WORKSPACE # https://github.com/actions/checkout - name: Check-out repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true # Discover location of MSBuild tool and to PATH environment variables # https://github.com/microsoft/setup-msbuild - name: Locate MSBuild - uses: microsoft/setup-msbuild@v1.3.1 + uses: microsoft/setup-msbuild@v2 # Use NuGet to download the latest libVLC. - name: Download libVLC @@ -130,7 +130,7 @@ jobs: # Uploads artifacts from workflow # https://github.com/actions/upload-artifact - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: EmulationStation path: | diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index a828a462f3..0c29f5c480 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -120,6 +120,7 @@ set(ES_SOURCES if(MSVC) LIST(APPEND ES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/EmulationStation.rc + ${CMAKE_CURRENT_SOURCE_DIR}/src/EmulationStation.manifest ) endif() diff --git a/es-app/src/EmulationStation.manifest b/es-app/src/EmulationStation.manifest new file mode 100644 index 0000000000..36a6891970 --- /dev/null +++ b/es-app/src/EmulationStation.manifest @@ -0,0 +1,9 @@ + + + + + PerMonitorV2 + UTF-8 + + + diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 1aa4f0f076..5e892ac216 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -280,10 +280,12 @@ void FileData::launchGame(Window* window) { LOG(LogInfo) << "Attempting to launch game..."; +#ifndef _WIN32 AudioManager::getInstance()->deinit(); VolumeControl::getInstance()->deinit(); InputManager::getInstance()->deinit(); window->deinit(); +#endif std::string command = mEnvData->mLaunchCommand; @@ -299,7 +301,7 @@ void FileData::launchGame(Window* window) Scripting::fireEvent("game-start", rom, basename, name); LOG(LogInfo) << " " << command; - int exitCode = runSystemCommand(command); + int exitCode = launchGameCommand(command); if(exitCode != 0) { @@ -308,10 +310,12 @@ void FileData::launchGame(Window* window) Scripting::fireEvent("game-end"); +#ifndef _WIN32 window->init(); InputManager::getInstance()->init(); VolumeControl::getInstance()->init(); window->normalizeNextUpdate(); +#endif //update number of times the game has been launched diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index b3150db4a5..ed06664384 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -522,6 +522,7 @@ void GuiMenu::openQuitMenu() ComponentListRow row; if (UIModeController::getInstance()->isUIModeFull()) { +#ifndef _WIN32 auto static restart_es_fx = []() { Scripting::fireEvent("quit"); if (quitES(QuitMode::RESTART)) { @@ -538,6 +539,7 @@ void GuiMenu::openQuitMenu() } row.addElement(std::make_shared(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); s->addRow(row); +#endif if(Settings::getInstance()->getBool("ShowExit")) { diff --git a/es-core/src/Scripting.cpp b/es-core/src/Scripting.cpp index 19b7797a40..6cb67ff8d1 100644 --- a/es-core/src/Scripting.cpp +++ b/es-core/src/Scripting.cpp @@ -30,12 +30,10 @@ namespace Scripting for(std::list::const_iterator dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) { std::list scripts = Utils::FileSystem::getDirContent(*dirIt); for (std::list::const_iterator it = scripts.cbegin(); it != scripts.cend(); ++it) { -#ifndef WIN32 // osx / linux if (!Utils::FileSystem::isExecutable(*it)) { LOG(LogWarning) << *it << " is not executable. Review file permissions."; continue; } -#endif std::string script = *it; if (arg1.length() > 0) { script += " \"" + arg1 + "\""; diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index dc904c49ed..b004b44f37 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -3,6 +3,10 @@ #include #ifdef WIN32 #include +#include +#include +#include +#include "renderers/Renderer.h" #else #include #endif @@ -30,15 +34,63 @@ int runRestartCommand() int runSystemCommand(const std::string& cmd_utf8) { -#ifdef WIN32 - // on Windows we use _wsystem to support non-ASCII paths - // which requires converting from utf8 to a wstring - typedef std::codecvt_utf8 convert_type; - std::wstring_convert converter; - std::wstring wchar_str = converter.from_bytes(cmd_utf8); - return _wsystem(wchar_str.c_str()); -#else return system(cmd_utf8.c_str()); +} + +int launchGameCommand(const std::string& cmd_utf8) +{ +#ifdef _WIN32 + STARTUPINFO + si; + PROCESS_INFORMATION + pi; + SDL_Event + event; + DWORD + rcode = 0; + Uint32 + wf; + int + width, + height; + + wf = SDL_GetWindowFlags(Renderer::getSDLWindow()); + SDL_SetWindowFullscreen(Renderer::getSDLWindow(), 0); + SDL_SetWindowBordered(Renderer::getSDLWindow(), SDL_TRUE); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + Renderer::swapBuffers(); + + memset(&si, 0, sizeof si); + memset(&pi, 0, sizeof pi); + si.cb = sizeof si; + + if(!CreateProcess(NULL, (LPSTR)cmd_utf8.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + return 9009; + + while(true){ + if(WaitForSingleObject(pi.hProcess, 200) == 0) + break; + while(SDL_PollEvent(&event)) + ; // NOP + } + + GetExitCodeProcess(pi.hProcess, &rcode); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + if(wf & SDL_WINDOW_FULLSCREEN) + SDL_SetWindowFullscreen(Renderer::getSDLWindow(), SDL_WINDOW_FULLSCREEN); + if(wf & SDL_WINDOW_BORDERLESS) + SDL_SetWindowBordered(Renderer::getSDLWindow(), SDL_FALSE); + + wf = SDL_GetWindowFlags(Renderer::getSDLWindow()); + if(wf & SDL_WINDOW_MINIMIZED) + SDL_RestoreWindow(Renderer::getSDLWindow()); + + return rcode; +#else + return runSystemCommand(cmd_utf8); #endif } @@ -57,9 +109,7 @@ int quitES(QuitMode mode) void touch(const std::string& filename) { #ifdef WIN32 - FILE* fp = fopen(filename.c_str(), "ab+"); - if (fp != NULL) - fclose(fp); + // Windows hasn't /tmp directory usualy so nothing to touch. #else int fd = open(filename.c_str(), O_CREAT|O_WRONLY, 0644); if (fd >= 0) diff --git a/es-core/src/platform.h b/es-core/src/platform.h index 1df4d56c68..b774a07be6 100644 --- a/es-core/src/platform.h +++ b/es-core/src/platform.h @@ -17,7 +17,8 @@ enum QuitMode REBOOT = 3 }; -int runSystemCommand(const std::string& cmd_utf8); // run a utf-8 encoded in the shell (requires wstring conversion on Windows) +int runSystemCommand(const std::string& cmd_utf8); // run a utf-8 encoded in the shell +int launchGameCommand(const std::string& cmd_utf8); int quitES(QuitMode mode = QuitMode::QUIT); void processQuitMode(); diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index 94be3a58bd..e5c8e364c1 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -9,6 +9,7 @@ #if defined(_WIN32) // because windows... +#include "utils/StringUtil.h" #include #include #define getcwd _getcwd @@ -34,21 +35,6 @@ namespace Utils static std::string exePath = ""; static std::map pathExistsIndex = std::map(); -////////////////////////////////////////////////////////////////////////// - -#if defined(_WIN32) - static std::string convertFromWideString(const std::wstring _wstring) - { - const int numBytes = WideCharToMultiByte(CP_UTF8, 0, _wstring.c_str(), (int)_wstring.length(), nullptr, 0, nullptr, nullptr); - std::string string(numBytes, 0); - - WideCharToMultiByte(CP_UTF8, 0, _wstring.c_str(), (int)_wstring.length(), (char*)string.c_str(), numBytes, nullptr, nullptr); - - return std::string(string); - - } // convertFromWideString -#endif // _WIN32 - ////////////////////////////////////////////////////////////////////////// stringList getDirContent(const std::string& _path, const bool _recursive) @@ -62,16 +48,16 @@ namespace Utils #if defined(_WIN32) const std::unique_lock lock(mutex); - WIN32_FIND_DATAW findData; + WIN32_FIND_DATA findData; const std::string wildcard = path + "/*"; - const HANDLE hFind = FindFirstFileW(std::wstring(wildcard.begin(), wildcard.end()).c_str(), &findData); + const HANDLE hFind = FindFirstFile(wildcard.c_str(), &findData); if(hFind != INVALID_HANDLE_VALUE) { // loop over all files in the directory do { - const std::string name = convertFromWideString(findData.cFileName); + const std::string name = findData.cFileName; // ignore "." and ".." if((name != ".") && (name != "..")) @@ -84,7 +70,7 @@ namespace Utils contentList.merge(getDirContent(fullName, true)); } } - while(FindNextFileW(hFind, &findData)); + while(FindNextFile(hFind, &findData)); FindClose(hFind); } @@ -216,13 +202,14 @@ namespace Utils void setExePath(const std::string& _path) { const size_t path_max = 32767; + std::string result(path_max, 0); #if defined(_WIN32) - std::wstring result(path_max, 0); - if(GetModuleFileNameW(nullptr, &result[0], path_max) != 0) - exePath = convertFromWideString(result); + if(GetModuleFileName(nullptr, &result[0], path_max) != 0){ + result.resize(result.find_first_of('\0')); + exePath = result; + } #else // _WIN32 - std::string result(path_max, 0); if(readlink("/proc/self/exe", &result[0], path_max) != -1) exePath = result; #endif // !_WIN32 @@ -570,9 +557,9 @@ namespace Utils if(hFile != INVALID_HANDLE_VALUE) { resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0, FILE_NAME_NORMALIZED) + 1); - if(GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(), (DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0) + if(GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(), resolved.size(), FILE_NAME_NORMALIZED) > 0) { - resolved.resize(resolved.size() - 1); + resolved.resize(resolved.find_first_of('\0')); resolved = getGenericPath(resolved); } CloseHandle(hFile); @@ -606,7 +593,7 @@ namespace Utils return true; bool removed = (unlink(path.c_str()) == 0); - + // if removed, let's remove it from the index if (removed) pathExistsIndex[_path] = false; @@ -764,9 +751,19 @@ namespace Utils ////////////////////////////////////////////////////////////////////////// -#if !defined(_WIN32) bool isExecutable(const std::string& _path) { +#ifdef _WIN32 + std::string ext = getenv("PATHEXT"); + Utils::String::stringVector pathext = Utils::String::delimitedStringToVector(ext, ";"); + + ext = getExtension(_path); + for(auto it = pathext.cbegin(); it != pathext.cend(); it++) + if(stricmp(ext.c_str(), it->c_str()) == 0) + return true; + + return false; +#else const std::string path = getGenericPath(_path); // regular files and executables, but not setuid, setgid, shared text @@ -780,9 +777,8 @@ namespace Utils // check for mask attributes return (info.st_mode & mask) == mask && (info.st_mode & mask_exec) != 0; - +#endif } // isExecutable -#endif // !_WIN32 } // FileSystem:: diff --git a/es-core/src/utils/FileSystemUtil.h b/es-core/src/utils/FileSystemUtil.h index ac7a423843..cb950b1ab4 100644 --- a/es-core/src/utils/FileSystemUtil.h +++ b/es-core/src/utils/FileSystemUtil.h @@ -39,9 +39,7 @@ namespace Utils bool isDirectory (const std::string& _path); bool isSymlink (const std::string& _path); bool isHidden (const std::string& _path); -#if !defined(_WIN32) bool isExecutable (const std::string& _path); -#endif // !_WIN32 } // FileSystem:: From a82d3cc8e81b1abbd483e09fbe004d95e979d4e3 Mon Sep 17 00:00:00 2001 From: opa Date: Sun, 14 Jul 2024 21:05:21 +0900 Subject: [PATCH 2/7] window->normalizeNextUpdate() --- es-app/src/FileData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 5e892ac216..b9ea8fcf42 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -314,8 +314,8 @@ void FileData::launchGame(Window* window) window->init(); InputManager::getInstance()->init(); VolumeControl::getInstance()->init(); - window->normalizeNextUpdate(); #endif + window->normalizeNextUpdate(); //update number of times the game has been launched From c548c98ab16ff4a60d8e68d3e4b8581b40112923 Mon Sep 17 00:00:00 2001 From: opa Date: Wed, 17 Jul 2024 15:11:30 +0900 Subject: [PATCH 3/7] unreferenced local variable --- es-core/src/platform.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index b004b44f37..02f34397d0 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -50,9 +50,6 @@ int launchGameCommand(const std::string& cmd_utf8) rcode = 0; Uint32 wf; - int - width, - height; wf = SDL_GetWindowFlags(Renderer::getSDLWindow()); SDL_SetWindowFullscreen(Renderer::getSDLWindow(), 0); From 4542a0199e761892fa199c85405ae953e4ab6940 Mon Sep 17 00:00:00 2001 From: opa Date: Sun, 4 Aug 2024 21:15:02 +0900 Subject: [PATCH 4/7] Fix Utils::FileSystem::getDirContent --- es-core/src/utils/FileSystemUtil.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index e5c8e364c1..50ff815b56 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -69,8 +69,10 @@ namespace Utils if(_recursive && isDirectory(fullName)) contentList.merge(getDirContent(fullName, true)); } + + FindNextFile(hFind, &findData); } - while(FindNextFile(hFind, &findData)); + while(GetLastError() != ERROR_NO_MORE_FILES); FindClose(hFind); } From a0a0eba3488c1eb9c4d74184fce1e99b14354237 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 22 Aug 2024 11:48:33 +0900 Subject: [PATCH 5/7] Fix and save resource --- .github/workflows/win32.yml | 1 - es-app/src/FileData.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/win32.yml b/.github/workflows/win32.yml index 5188c58a91..b9cd7499eb 100644 --- a/.github/workflows/win32.yml +++ b/.github/workflows/win32.yml @@ -98,7 +98,6 @@ jobs: -DSDL2_LIBRARY=%SDL2_LIBRARY% -DVLC_LIBRARIES=%VLC_LIBRARIES% -DVLC_VERSION=%VLC_VERSION% - -DCMAKE_EXE_LINKER_FLAGS=/SAFESEH:NO # Use CMake to build project - name: Build EmulationStation diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index b9ea8fcf42..38314dbeba 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -280,10 +280,10 @@ void FileData::launchGame(Window* window) { LOG(LogInfo) << "Attempting to launch game..."; -#ifndef _WIN32 AudioManager::getInstance()->deinit(); VolumeControl::getInstance()->deinit(); InputManager::getInstance()->deinit(); +#ifndef _WIN32 window->deinit(); #endif @@ -312,9 +312,9 @@ void FileData::launchGame(Window* window) #ifndef _WIN32 window->init(); +#endif InputManager::getInstance()->init(); VolumeControl::getInstance()->init(); -#endif window->normalizeNextUpdate(); //update number of times the game has been launched From d0fdbe58dfa9b1ea7fcb744112fd23e2e2ae88d7 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 22 Aug 2024 13:58:49 +0900 Subject: [PATCH 6/7] Doc & more simpler loop --- README.md | 3 +-- es-core/src/platform.cpp | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0f16f47a23..e91e771fea 100644 --- a/README.md +++ b/README.md @@ -158,8 +158,7 @@ C:\src\EmulationStation>cmake . -B build -A Win32 ^ -DCURL_LIBRARY=%CURL_LIBRARY% ^ -DSDL2_LIBRARY=%SDL2_LIBRARY% ^ -DVLC_LIBRARIES=%VLC_LIBRARIES% ^ --DVLC_VERSION=%VLC_VERSION% ^ --DCMAKE_EXE_LINKER_FLAGS=/SAFESEH:NO +-DVLC_VERSION=%VLC_VERSION% ``` * Use CMake to build the Visual Studio project. diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index 02f34397d0..3f1ba82b8d 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -65,12 +65,9 @@ int launchGameCommand(const std::string& cmd_utf8) if(!CreateProcess(NULL, (LPSTR)cmd_utf8.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return 9009; - while(true){ - if(WaitForSingleObject(pi.hProcess, 200) == 0) - break; + while(WaitForSingleObject(pi.hProcess, 200) == WAIT_TIMEOUT) while(SDL_PollEvent(&event)) ; // NOP - } GetExitCodeProcess(pi.hProcess, &rcode); CloseHandle(pi.hProcess); From 37ec854ff1b135a74bb320ee749861f43234a23d Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 22 Aug 2024 15:03:56 +0900 Subject: [PATCH 7/7] Delete non-need header --- es-core/src/components/VideoVlcComponent.cpp | 1 - es-core/src/platform.cpp | 3 --- 2 files changed, 4 deletions(-) diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp index 4ef7500d05..7ad0ca02b3 100644 --- a/es-core/src/components/VideoVlcComponent.cpp +++ b/es-core/src/components/VideoVlcComponent.cpp @@ -7,7 +7,6 @@ #include "Settings.h" #ifdef WIN32 #include -#include typedef SSIZE_T ssize_t; #else #include diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index 3f1ba82b8d..92dffd6955 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -2,9 +2,7 @@ #include #ifdef WIN32 -#include #include -#include #include #include "renderers/Renderer.h" #else @@ -55,7 +53,6 @@ int launchGameCommand(const std::string& cmd_utf8) SDL_SetWindowFullscreen(Renderer::getSDLWindow(), 0); SDL_SetWindowBordered(Renderer::getSDLWindow(), SDL_TRUE); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Renderer::swapBuffers(); memset(&si, 0, sizeof si);