Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some WIN32 updates #879

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/win32.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -130,7 +129,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: |
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions es-app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
9 changes: 9 additions & 0 deletions es-app/src/EmulationStation.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly manifestVersion='1.0' xmlns='urn:schemas-microsoft-com:asm.v1'>
<application>
<windowsSettings>
<dpiAwareness xmlns='http://schemas.microsoft.com/SMI/2016/WindowsSettings'>PerMonitorV2</dpiAwareness>
<activeCodePage xmlns='http://schemas.microsoft.com/SMI/2019/WindowsSettings'>UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>
6 changes: 5 additions & 1 deletion es-app/src/FileData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ void FileData::launchGame(Window* window)
AudioManager::getInstance()->deinit();
VolumeControl::getInstance()->deinit();
InputManager::getInstance()->deinit();
#ifndef _WIN32
window->deinit();
#endif

std::string command = mEnvData->mLaunchCommand;

Expand All @@ -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)
{
Expand All @@ -308,7 +310,9 @@ void FileData::launchGame(Window* window)

Scripting::fireEvent("game-end");

#ifndef _WIN32
window->init();
#endif
InputManager::getInstance()->init();
VolumeControl::getInstance()->init();
window->normalizeNextUpdate();
Expand Down
2 changes: 2 additions & 0 deletions es-app/src/guis/GuiMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -538,6 +539,7 @@ void GuiMenu::openQuitMenu()
}
row.addElement(std::make_shared<TextComponent>(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row);
#endif

if(Settings::getInstance()->getBool("ShowExit"))
{
Expand Down
2 changes: 0 additions & 2 deletions es-core/src/Scripting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ namespace Scripting
for(std::list<std::string>::const_iterator dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) {
std::list<std::string> scripts = Utils::FileSystem::getDirContent(*dirIt);
for (std::list<std::string>::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 + "\"";
Expand Down
1 change: 0 additions & 1 deletion es-core/src/components/VideoVlcComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "Settings.h"
#ifdef WIN32
#include <basetsd.h>
#include <codecvt>
typedef SSIZE_T ssize_t;
#else
#include <unistd.h>
Expand Down
65 changes: 53 additions & 12 deletions es-core/src/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

#include <SDL_events.h>
#ifdef WIN32
#include <codecvt>
#include <SDL.h>
#include <Windows.h>
#include "renderers/Renderer.h"
#else
#include <unistd.h>
#endif
Expand Down Expand Up @@ -30,15 +32,56 @@ 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<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> 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;

wf = SDL_GetWindowFlags(Renderer::getSDLWindow());
SDL_SetWindowFullscreen(Renderer::getSDLWindow(), 0);
SDL_SetWindowBordered(Renderer::getSDLWindow(), SDL_TRUE);

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(WaitForSingleObject(pi.hProcess, 200) == WAIT_TIMEOUT)
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
}

Expand All @@ -57,9 +100,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)
Expand Down
3 changes: 2 additions & 1 deletion es-core/src/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
56 changes: 27 additions & 29 deletions es-core/src/utils/FileSystemUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#if defined(_WIN32)
// because windows...
#include "utils/StringUtil.h"
#include <direct.h>
#include <Windows.h>
#define getcwd _getcwd
Expand All @@ -34,21 +35,6 @@ namespace Utils
static std::string exePath = "";
static std::map<std::string, bool> pathExistsIndex = std::map<std::string, bool>();

//////////////////////////////////////////////////////////////////////////

#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)
Expand All @@ -62,16 +48,16 @@ namespace Utils

#if defined(_WIN32)
const std::unique_lock<std::recursive_mutex> 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 != ".."))
Expand All @@ -83,8 +69,10 @@ namespace Utils
if(_recursive && isDirectory(fullName))
contentList.merge(getDirContent(fullName, true));
}

FindNextFile(hFind, &findData);
}
while(FindNextFileW(hFind, &findData));
while(GetLastError() != ERROR_NO_MORE_FILES);

FindClose(hFind);
}
Expand Down Expand Up @@ -216,13 +204,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
Expand Down Expand Up @@ -570,9 +559,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);
Expand Down Expand Up @@ -606,7 +595,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;
Expand Down Expand Up @@ -764,9 +753,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
Expand All @@ -780,9 +779,8 @@ namespace Utils

// check for mask attributes
return (info.st_mode & mask) == mask && (info.st_mode & mask_exec) != 0;

#endif
} // isExecutable
#endif // !_WIN32

} // FileSystem::

Expand Down
2 changes: 0 additions & 2 deletions es-core/src/utils/FileSystemUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand Down