From 84c4f97c6c3de56adf34a5656b673ce66fd10977 Mon Sep 17 00:00:00 2001 From: Struma Date: Sun, 23 May 2021 21:40:48 -0400 Subject: [PATCH] Add more detailed platform detection --- binding/binding-mri.cpp | 97 +++++++++++++++++++++++++++++++++-- binding/miniffi-binding.cpp | 2 +- src/audio/fluid-fun.cpp | 2 +- src/display/graphics.cpp | 2 +- src/eventthread.cpp | 6 +-- src/system/system.h | 23 +++++++++ src/system/systemImpl.cpp | 34 ++++++++++++ src/system/systemImplApple.mm | 20 ++++++++ src/util/string-util.h | 2 +- 9 files changed, 176 insertions(+), 12 deletions(-) diff --git a/binding/binding-mri.cpp b/binding/binding-mri.cpp index d2ffa392..3cc5aa6c 100644 --- a/binding/binding-mri.cpp +++ b/binding/binding-mri.cpp @@ -58,6 +58,7 @@ extern "C" { #include #include +#include #include #define MACRO_STRINGIFY(x) #x @@ -115,7 +116,16 @@ RB_METHOD(mkxpDesensitize); RB_METHOD(mkxpPuts); RB_METHOD(mkxpRawKeyStates); RB_METHOD(mkxpMouseInWindow); + RB_METHOD(mkxpPlatform); +RB_METHOD(mkxpIsMacHost); +RB_METHOD(mkxpIsWindowsHost); +RB_METHOD(mkxpIsLinuxHost); +RB_METHOD(mkxpIsUsingRosetta); +RB_METHOD(mkxpIsUsingWine); +RB_METHOD(mkxpIsReallyMacHost); +RB_METHOD(mkxpIsReallyLinuxHost); + RB_METHOD(mkxpUserLanguage); RB_METHOD(mkxpUserName); RB_METHOD(mkxpGameTitle); @@ -193,6 +203,7 @@ static void mriBindingInit() { VALUE mod = rb_define_module("System"); _rb_define_module_function(mod, "delta", mkxpDelta); + _rb_define_module_function(mod, "uptime", mkxpDelta); _rb_define_module_function(mod, "data_directory", mkxpDataDirectory); _rb_define_module_function(mod, "set_window_title", mkxpSetTitle); _rb_define_module_function(mod, "show_settings", mkxpSettingsMenu); @@ -200,7 +211,21 @@ static void mriBindingInit() { _rb_define_module_function(mod, "desensitize", mkxpDesensitize); _rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates); _rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow); + _rb_define_module_function(mod, "mouse_in_window?", mkxpMouseInWindow); + _rb_define_module_function(mod, "platform", mkxpPlatform); + + _rb_define_module_function(mod, "is_mac?", mkxpIsMacHost); + _rb_define_module_function(mod, "is_rosetta?", mkxpIsUsingRosetta); + + _rb_define_module_function(mod, "is_linux?", mkxpIsLinuxHost); + + _rb_define_module_function(mod, "is_windows?", mkxpIsWindowsHost); + _rb_define_module_function(mod, "is_wine?", mkxpIsUsingWine); + _rb_define_module_function(mod, "is_really_mac?", mkxpIsReallyMacHost); + _rb_define_module_function(mod, "is_really_linux?", mkxpIsReallyLinuxHost); + + _rb_define_module_function(mod, "user_language", mkxpUserLanguage); _rb_define_module_function(mod, "user_name", mkxpUserName); _rb_define_module_function(mod, "game_title", mkxpGameTitle); @@ -345,7 +370,70 @@ RB_METHOD(mkxpMouseInWindow) { RB_METHOD(mkxpPlatform) { RB_UNUSED_PARAM; - return rb_utf8_str_new_cstr(SDL_GetPlatform()); +#if MKXPZ_PLATFORM == MKXPZ_PLATFORM_MACOS + std::string platform("macOS"); + + if (mkxp_sys::isRosetta()) + platform += " (Rosetta)"; + +#elif MKXPZ_PLATFORM == MKXPZ_PLATFORM_WINDOWS + std::string platform("Windows"); + + if (mkxp_sys::isWine()) { + platform += " (Wine - "; + switch (mkxp_sys::getRealHostType()) { + case mkxp_sys::WineHostType::Mac: + platform += "macOS)"; + break; + default: + platform += "Linux)"; + break; + } + } +#else + std::string platform("Linux"); +#endif + + return rb_utf8_str_new_cstr(platform.c_str()); +} + +RB_METHOD(mkxpIsMacHost) { + RB_UNUSED_PARAM; + + return rb_bool_new(MKXPZ_PLATFORM == MKXPZ_PLATFORM_MACOS); +} + +RB_METHOD(mkxpIsUsingRosetta) { + RB_UNUSED_PARAM; + + return rb_bool_new(mkxp_sys::isRosetta()); +} + +RB_METHOD(mkxpIsLinuxHost) { + RB_UNUSED_PARAM; + + return rb_bool_new(MKXPZ_PLATFORM == MKXPZ_PLATFORM_LINUX); +} + +RB_METHOD(mkxpIsWindowsHost) { + RB_UNUSED_PARAM; + + return rb_bool_new(MKXPZ_PLATFORM == MKXPZ_PLATFORM_WINDOWS); +} + +RB_METHOD(mkxpIsUsingWine) { + RB_UNUSED_PARAM; + return rb_bool_new(mkxp_sys::isWine()); +} + +RB_METHOD(mkxpIsReallyMacHost) { + RB_UNUSED_PARAM; + return rb_bool_new(mkxp_sys::getRealHostType() == mkxp_sys::WineHostType::Mac); +} + +RB_METHOD(mkxpIsReallyLinuxHost) { + RB_UNUSED_PARAM; + return rb_bool_new(mkxp_sys::getRealHostType() == mkxp_sys::WineHostType::Linux); } RB_METHOD(mkxpUserLanguage) { @@ -453,7 +541,7 @@ RB_METHOD(mkxpRemovePath) { return path; } -#ifdef __MACOSX__ +#ifdef __APPLE__ #define OPENCMD "open " #define OPENARGS "--args" #elif defined(__linux__) @@ -500,8 +588,6 @@ RB_METHOD(mkxpLaunch) { raiseRbExc(Exception(Exception::MKXPError, "Failed to launch \"%s\"", RSTRING_PTR(cmdname))); } - Debug() << command; - return RUBY_Qnil; } @@ -768,7 +854,7 @@ static void runRMXPScripts(BacktraceData &btData) { // Adding a 'not' symbol means it WON'T run on that // platform (i.e. |!W| won't run on Windows) - +/* if (scriptName[0] == '|') { int len = strlen(scriptName); if (len > 2) { @@ -782,6 +868,7 @@ static void runRMXPScripts(BacktraceData &btData) { continue; } } + */ int state; diff --git a/binding/miniffi-binding.cpp b/binding/miniffi-binding.cpp index 4537a143..11b064ba 100644 --- a/binding/miniffi-binding.cpp +++ b/binding/miniffi-binding.cpp @@ -82,7 +82,7 @@ RB_METHOD(MiniFFI_initialize) { rb_scan_args(argc, argv, "22", &libname, &func, &imports, &exports); SafeStringValue(libname); SafeStringValue(func); -#ifdef __MACOSX__ +#ifdef __APPLE__ void *hlib = SDL_LoadObject(mkxp_fs::normalizePath(RSTRING_PTR(libname), 1, 1).c_str()); #else void *hlib = SDL_LoadObject(RSTRING_PTR(libname)); diff --git a/src/audio/fluid-fun.cpp b/src/audio/fluid-fun.cpp index 84a8ae40..17298894 100644 --- a/src/audio/fluid-fun.cpp +++ b/src/audio/fluid-fun.cpp @@ -10,7 +10,7 @@ #define FLUID_LIB "libfluidsynth.so.3" #elif MKXPZ_BUILD_XCODE #define FLUID_LIB "@rpath/libfluidsynth.dylib" -#elif __MACOSX__ +#elif __APPLE__ #define FLUID_LIB "libfluidsynth.3.dylib" #elif __WINDOWS__ #define FLUID_LIB "fluidsynth.dll" diff --git a/src/display/graphics.cpp b/src/display/graphics.cpp index ab226528..413d7be9 100644 --- a/src/display/graphics.cpp +++ b/src/display/graphics.cpp @@ -617,7 +617,7 @@ Graphics::Graphics(RGSSThreadData *data) { #ifndef MKXPZ_STATIC_FRAMERATE if (data->config.syncToRefreshrate) { p->frameRate = data->refreshRate; -#if defined(__MACOSX__) && defined(GLES2_HEADER) +#if defined(__APPLE__) && defined(GLES2_HEADER) // VSync seems to be broken at the moment, could be anywhere in the // GLES -> ANGLE -> OpenGL -> Metal (if Apple Silicon) translation p->fpsLimiter.setDesiredFPS(data->refreshRate); diff --git a/src/eventthread.cpp b/src/eventthread.cpp index e5e7b57a..0d38ab6c 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -46,7 +46,7 @@ #include "al-util.h" #include "debugwriter.h" -#ifndef __MACOSX__ +#ifndef __APPLE__ #include "util/string-util.h" #endif @@ -142,7 +142,7 @@ void EventThread::process(RGSSThreadData &rtData) initALCFunctions(rtData.alcDev); // XXX this function breaks input focus on OSX -#ifndef __MACOSX__ +#ifndef __APPLE__ SDL_SetEventFilter(eventFilter, &rtData); #endif @@ -491,7 +491,7 @@ void EventThread::process(RGSSThreadData &rtData) case REQUEST_MESSAGEBOX : { -#ifndef __MACOSX__ +#ifndef __APPLE__ // Try to format the message with additional newlines std::string message = copyWithNewlines((const char*) event.user.data1, 70); diff --git a/src/system/system.h b/src/system/system.h index 42d003fc..87197e27 100644 --- a/src/system/system.h +++ b/src/system/system.h @@ -10,10 +10,33 @@ #include +#define MKXPZ_PLATFORM_WINDOWS 0 +#define MKXPZ_PLATFORM_MACOS 1 +#define MKXPZ_PLATFORM_LINUX 2 + +#ifdef __WINDOWS__ +#define MKXPZ_PLATFORM MKXPZ_PLATFORM_WINDOWS +#elif defined __APPLE__ +#define MKXPZ_PLATFORM MKXPZ_PLATFORM_MACOS +#elif defined __linux__ +#define MKXPZ_PLATFORM MKXPZ_PLATFORM_LINUX +#else +#error "Can't identify platform." +#endif + namespace systemImpl { +enum WineHostType { + Windows, + Linux, + Mac +}; std::string getSystemLanguage(); std::string getUserName(); int getScalingFactor(); + +bool isWine(); +bool isRosetta(); +WineHostType getRealHostType(); } #ifdef MKXPZ_BUILD_XCODE diff --git a/src/system/systemImpl.cpp b/src/system/systemImpl.cpp index afcad2ff..085d4a71 100644 --- a/src/system/systemImpl.cpp +++ b/src/system/systemImpl.cpp @@ -54,6 +54,40 @@ std::string systemImpl::getUserName() { return std::string(ret); } + +bool systemImpl::isWine() { +#if MKXPZ_PLATFORM != MKXPZ_PLATFORM_WINDOWS + return false; +#else + void *ntdll = SDL_LoadObject("ntdll.dll"); + return SDL_LoadFunction(ntdll, "wine_get_host_version") != 0; +#endif +} + +bool systemImpl::isRosetta() { + return false; +} + +systemImpl::WineHostType systemImpl::getRealHostType() { +#if MKXPZ_PLATFORM != MKXPZ_PLATFORM_WINDOWS + return WineHostType::Linux; +#else + void *ntdll = SDL_LoadObject("ntdll.dll"); + void (*wine_get_host_version)(const char **, const char **) = + (void (*)(const char **, const char **))SDL_LoadFunction(ntdll, "wine_get_host_version"); + + if (wine_get_host_version == 0) + return WineHostType::Windows; + + const char *kernel = 0; + wine_get_host_version(&kernel, 0); + + if (!strcmp(kernel, "Darwin")) + return WineHostType::Mac; + + return WineHostType::Linux; +#endif +} // HiDPI scaling not supported outside of macOS for now int systemImpl::getScalingFactor() { diff --git a/src/system/systemImplApple.mm b/src/system/systemImplApple.mm index f19e9e42..736ba222 100644 --- a/src/system/systemImplApple.mm +++ b/src/system/systemImplApple.mm @@ -6,6 +6,7 @@ // #import +#import #import "system.h" #import "SettingsMenuController.h" @@ -23,6 +24,25 @@ int systemImpl::getScalingFactor() { return NSApplication.sharedApplication.mainWindow.backingScaleFactor; } +bool systemImpl::isWine() { + return false; +} + +bool systemImpl::isRosetta() { + int translated = 0; + size_t size = sizeof(translated); + int result = sysctlbyname("sysctl.proc_translated", &translated, &size, NULL, 0); + + if (result == -1) + return false; + + return translated; +} + +systemImpl::WineHostType systemImpl::getRealHostType() { + return WineHostType::Mac; +} + // constant, if it's not nil then just raise the menu instead SettingsMenu *smenu = nil; diff --git a/src/util/string-util.h b/src/util/string-util.h index b89ab0e0..e675d1aa 100644 --- a/src/util/string-util.h +++ b/src/util/string-util.h @@ -1,7 +1,7 @@ #ifndef STRING_UTIL_H #define STRING_UTIL_H -#ifndef __MACOSX__ +#ifndef __APPLE__ #include