diff --git a/Utils/CMakeLists.txt b/Utils/CMakeLists.txt index 537e23350..052623927 100644 --- a/Utils/CMakeLists.txt +++ b/Utils/CMakeLists.txt @@ -29,6 +29,7 @@ set(UtilsSrc "${CMAKE_CURRENT_SOURCE_DIR}/Text Utils.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Timer Control.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Utilities.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/wine.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/WordWrap.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/XMLProperties.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/XMLWriter.cpp" diff --git a/Utils/wine.cpp b/Utils/wine.cpp new file mode 100644 index 000000000..17c5c4af9 --- /dev/null +++ b/Utils/wine.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "wine.h" + + +BOOL wine_add_dll_overrides() +{ + BOOL dd = wine_add_dll_override(L"ddraw"); + //BOOL ws = wine_add_dll_override(L"wsock32"); + + return dd; // || ws; +} + +BOOL wine_add_dll_override(const WCHAR* dll_name) +{ + if (!IS_WINE) + return FALSE; + + WCHAR exe_path[MAX_PATH] = { 0 }; + if (!GetModuleFileNameW(NULL, exe_path, _countof(exe_path) - 1)) + return FALSE; + + WCHAR exe_file_name[MAX_PATH] = { 0 }; + WCHAR exe_file_ext[MAX_PATH] = { 0 }; + _wsplitpath(exe_path, NULL, NULL, exe_file_name, exe_file_ext); + + WCHAR reg_path[512] = { 0 }; + _snwprintf( + reg_path, + _countof(reg_path) - 1, + L"SOFTWARE\\Wine\\AppDefaults\\%s%s\\DllOverrides", + exe_file_name, + exe_file_ext); + + BOOL result = FALSE; + HKEY hkey; + LONG status = + RegCreateKeyExW( + HKEY_CURRENT_USER, + reg_path, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_READ, + NULL, + &hkey, + NULL); + + if (status == ERROR_SUCCESS) + { + if (RegQueryValueExW(hkey, dll_name, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + WCHAR v[] = L"native, builtin"; + if (RegSetValueExW(hkey, dll_name, 0, REG_SZ, (LPCBYTE)v, sizeof(v)) == ERROR_SUCCESS && + RegQueryValueExW(hkey, dll_name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + result = TRUE; + } + } + + RegCloseKey(hkey); + } + + return result; +} diff --git a/Utils/wine.h b/Utils/wine.h new file mode 100644 index 000000000..2929c5433 --- /dev/null +++ b/Utils/wine.h @@ -0,0 +1,15 @@ +#ifndef WINE_H +#define WINE_H + +#define IS_WINE (GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0) + +// ### types ### + +// ### Variables ### + +// ### Functions ### + +BOOL wine_add_dll_overrides(); +BOOL wine_add_dll_override(const WCHAR* dll_name); + +#endif diff --git a/sgp/sgp.cpp b/sgp/sgp.cpp index be1fcf5ad..8f3f77ba9 100644 --- a/sgp/sgp.cpp +++ b/sgp/sgp.cpp @@ -49,6 +49,7 @@ #include "Lua Interpreter.h" #include "connect.h" #include "english.h" +#include "wine.h" #include "BuildDefines.h" #include "Intro.h" @@ -766,7 +767,16 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC HWND hPrevInstanceWindow; UINT32 uiTimer = 0; + // Make sure the game works out of the box on Linux/macOS/Android (WINE) + if (wine_add_dll_overrides()) + { + /* newly added dll overrides only work after a restart */ + char exe_path[MAX_PATH] = { 0 }; + GetModuleFileNameA(NULL, exe_path, _countof(exe_path)); + ShellExecuteA(NULL, "open", exe_path, pCommandLine, NULL, sCommandShow); + return 0; + } vfs::Log::setSharedString( getGameID() ); //if(!vfs::Aspects::getMutexFactory())