From 84e5d243988964290365e59fac8afa3f88b38031 Mon Sep 17 00:00:00 2001 From: whitecum1488 Date: Fri, 21 Aug 2026 23:01:25 +0300 Subject: [PATCH] Some Android/Termux changes and engine fixes --- CMakeLists.txt | 55 +++++++++++++++++++----------- src/config.cpp | 2 +- src/debugwriter.h | 12 ++++--- src/main.cpp | 85 ++++++++++++++++++++++++----------------------- src/oneshot.cpp | 13 +++++++- src/security.cpp | 11 +++--- 6 files changed, 107 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5d30ca..2bcd38a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.28.3) +cmake_minimum_required(VERSION 3.9) project(oneshot) include(FindPackageHandleStandardArgs) include(CheckCXXCompilerFlag) @@ -16,9 +16,8 @@ function(check_option var a) set(all ${a}) set(var "") list(APPEND all ${ARGN}) - foreach(x IN LISTS all) - check_cxx_compiler_flag(${x} HAVE_OPTION) + check_cxx_compiler_flag(${x} HAVE_OPTION) if(HAVE_OPTION) message(STATUS "${x} SUPPORTED") list(APPEND var ${x}) @@ -31,8 +30,7 @@ function(check_option var a) message(STATUS "${x} UNSUPPORTED") endif() endif() - - endforeach() + endforeach() set(${var} "${var}" PARENT_SCOPE) endfunction() @@ -45,6 +43,7 @@ option(STATIC "Build more static build" OFF) option(USE_OPENGL_ES2 "GLES2_HEADER define" OFF) set(VERSION_STRING "0.1.2" CACHE STRING "Version string") option(DEVBUILD "Developoment build" OFF) +option(TERMUX "Build for TERMUX" OFF) # Configuration set(CMAKE_DISABLE_IN_SOURCE_BUILD TRUE) @@ -197,6 +196,14 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") include_directories(${LINUXPKGS_INCLUDE_DIRS}) add_compile_options(${LINUXPKGS_CFLAGS_OTHER}) list(APPEND PLATFORM_LIBRARIES ${LINUXPKGS_LDFLAGS}) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") + if(TERMUX) + find_package(PkgConfig REQUIRED) + pkg_check_modules(ANDROIDPKGS REQUIRED gtk+-3.0 libxfconf-0) + include_directories(${ANDROIDPKGS_INCLUDE_DIRS}) + add_compile_options(${ANDROIDPKGS_CFLAGS_OTHER}) + list(APPEND PLATFORM_LIBRARIES ${ANDROIDPKGS_LDFLAGS}) + endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") find_package(PkgConfig REQUIRED) pkg_check_modules(LINUXPKGS REQUIRED gtk+-3.0 libxfconf-0) @@ -384,14 +391,14 @@ else() -fimplicit-constexpr -fomit-frame-pointer) add_compile_options(${OPTIONS_RELEASE}) - - add_link_options(-Wl,-O2 - -Wl,--gc-sections - -Wl,--as-needed + + add_link_options(-Wl,-O2 + -Wl,--gc-sections + -Wl,--as-needed -Wl,--no-undefined -Wl,--strip-all -Wl,--no-copy-dt-needed-entries) - + if("${ARCH_RELEASE}" STREQUAL "") message(STATUS "ARCH_RELEASE empty") else() @@ -401,21 +408,28 @@ else() endif() if(ANDROID) - add_library(main SHARED - ${MAIN_HEADERS} - ${MAIN_SOURCE} - ${BINDING_HEADERS} - ${BINDING_SOURCE} - ${EMBEDDED_SOURCE} - ) + if(TERMUX) + add_executable(${PROJECT_NAME} + ${MAIN_HEADERS} + ${MAIN_SOURCE} + ${BINDING_HEADERS} + ${BINDING_SOURCE} + ${EMBEDDED_SOURCE}) + else() + add_library(main SHARED + ${MAIN_HEADERS} + ${MAIN_SOURCE} + ${BINDING_HEADERS} + ${BINDING_SOURCE} + ${EMBEDDED_SOURCE}) + endif() else() add_executable(${PROJECT_NAME} MACOSX_BUNDLE WIN32 ${MAIN_HEADERS} ${MAIN_SOURCE} ${BINDING_HEADERS} ${BINDING_SOURCE} - ${EMBEDDED_SOURCE} - ) + ${EMBEDDED_SOURCE}) endif() if(NOT DEBUG) @@ -433,6 +447,9 @@ if(DEVBUILD) target_compile_definitions(${PROJECT_NAME} PRIVATE DEVBUILD) endif() target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION_STRING="${VERSION_STRING}") +if(TERMUX) + target_compile_definitions(${PROJECT_NAME} PRIVATE TERMUX=1) +endif() find_package(PkgConfig REQUIRED) find_package(ZLIB REQUIRED) diff --git a/src/config.cpp b/src/config.cpp index 1dc93b1..771016a 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -144,7 +144,7 @@ void Config::read(int argc, char *argv[]){ #undef PO_DESC_ALL SE.sourceCount = clamp(SE.sourceCount, 1, 64); - #ifdef __ANDROID__ + #if defined(__ANDROID__) && !defined(TERMUX) commonDataPath = prefPath(SDL_GetAndroidInternalStoragePath(), "/SunshineSaves"); gameFolder = ""; gameFolder.append(SDL_GetAndroidInternalStoragePath()).append("/Sunshine"); diff --git a/src/debugwriter.h b/src/debugwriter.h index e84cfb9..368477b 100644 --- a/src/debugwriter.h +++ b/src/debugwriter.h @@ -31,7 +31,7 @@ #undef snprintf #ifdef __ANDROID__ - #include + #include #elif __EMSCRIPTEN__ #include #endif @@ -66,13 +66,17 @@ public: ~Debug() noexcept { #ifdef __ANDROID__ - __android_log_write(ANDROID_LOG_DEBUG, "sunshine", result.view().c_str()); + //TODO: Linking error + //__android_log_write(ANDROID_LOG_DEBUG, "sunshine", buf.str().c_str()); + #ifdef TERMUX + std::cout << buf.view() << '\n'; + #endif #elif __EMSCRIPTEN__ - emscripten_console_log(result.view().c_str()); + emscripten_console_log(result.view().c_str()); #else - logs.emplace_back(buf.view()); std::cout << buf.view() << '\n'; #endif + logs.emplace_back(buf.view()); } private: diff --git a/src/main.cpp b/src/main.cpp index cfe38a0..94f484b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,7 +63,7 @@ #endif #ifndef VERSION_STRING - #define VERSION_STRING ">w<" + #define VERSION_STRING "Unknown" #endif static void rgssThreadError(RGSSThreadData *rtData, const std::string &msg){ @@ -157,9 +157,7 @@ int main(int argc, char *argv[]){ //X11 work on *BSD,Solaris too! #if unix_like SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); - #if SDL_VERSION_ATLEAST(3, 4, 10) - SDL_SetHint(SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT, "1"); - #endif + SDL_SetHint(SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT, "1"); #elif windows SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1"); #elif android @@ -215,7 +213,6 @@ int main(int argc, char *argv[]){ } std::string path; - if (!conf.gameFolder.empty()) { if (conf.gameFolder == ".") { path = std::filesystem::current_path().string(); @@ -225,14 +222,14 @@ int main(int argc, char *argv[]){ } else { path = std::filesystem::current_path().string(); } - + std::ofstream out(std::filesystem::temp_directory_path() / "sunshine"); if (!out) { WarnMsg("Failed to write game directory path to temp file, problems with journal app expected!"); } else { out << path; } - + extern int screenMain(Config &conf); if (conf.screenMode) return screenMain(conf); @@ -288,7 +285,7 @@ int main(int argc, char *argv[]){ WarnMsg("Error creating Mixer Device, check your system audio configuration"); MIX_Quit(); TTF_Quit(); - SDL_Quit(); + SDL_Quit(); return 0; } @@ -303,55 +300,59 @@ int main(int argc, char *argv[]){ #endif int winW, winH; - SDL_GetWindowSize(win, &winW, &winH); // SDL_GL_GetDrawableSize(win, &winW, &winH); + SDL_GetWindowSize(win, &winW, &winH); rtData.windowSizeMsg.post(Vec2i(winW, winH)); ModLoader(conf, win); - /* Load and post key bindings */ rtData.bindingUpdateMsg.post(loadBindings(conf)); /* Start RGSS thread */ - SDL_Thread *rgssThread = SDL_CreateThread(rgssThreadFun, "rgss", &rtData); + try{ + SDL_Thread *rgssThread = SDL_CreateThread(rgssThreadFun, "rgss", &rtData); + if(rgssThread){ + WarnMsg("Thread creation failed: %s", SDL_GetError()); + return -1; + } + /* Start event processing */ + eventThread.process(rtData); - /* Start event processing */ - eventThread.process(rtData); + /* Request RGSS thread to stop */ + rtData.rqTerm.set(); - /* Request RGSS thread to stop */ - rtData.rqTerm.set(); + /* Wait for RGSS thread response */ + for (int i = 0; i < 1000; ++i){ + /* We can stop waiting when the request was ack'd */ + if (rtData.rqTermAck){ + Debug() << "[main] RGSS thread ack'd request after" << i*10 << "ms"; + break; + } - /* Wait for RGSS thread response */ - for (int i = 0; i < 1000; ++i){ - /* We can stop waiting when the request was ack'd */ - if (rtData.rqTermAck){ - Debug() << "[main] RGSS thread ack'd request after" << i*10 << "ms"; - break; + /* Give RGSS thread some time to respond */ + SDL_Delay(10); } - /* Give RGSS thread some time to respond */ - SDL_Delay(10); + /* If RGSS thread ack'd request, wait for it to shutdown, + * otherwise abandon hope and just end the process as is. */ + if (rtData.rqTermAck){ + SDL_WaitThread(rgssThread, 0); + }else{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(), "The RGSS script seems to be stuck and Sunshine will now force quit", win); + } + + if (!rtData.rgssErrorMsg.empty()) + ErrorMsg(rtData.rgssErrorMsg.c_str()); + + /* Clean up any remainin events */ + eventThread.cleanup(); + + unloadLocale(); + unloadLanguageMetadata(); + }catch(const char* msg){ + ErrorMsg(msg); } - - /* If RGSS thread ack'd request, wait for it to shutdown, - * otherwise abandon hope and just end the process as is. */ - if (rtData.rqTermAck){ - SDL_WaitThread(rgssThread, 0); - }else{ - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(), "The RGSS script seems to be stuck and Sunshine will now force quit", win); - } - - if (!rtData.rgssErrorMsg.empty()) - ErrorMsg(rtData.rgssErrorMsg.c_str()); - - /* Clean up any remainin events */ - eventThread.cleanup(); - - unloadLocale(); - unloadLanguageMetadata(); - if(show_crash_sceen){ crash_screen(win); } - MIX_DestroyMixer(mixer); SDL_DestroyWindow(win); diff --git a/src/oneshot.cpp b/src/oneshot.cpp index 87448d0..53f2e0a 100644 --- a/src/oneshot.cpp +++ b/src/oneshot.cpp @@ -32,6 +32,8 @@ #include #include #include +#elif android + //idk #else #error "Operating system not detected or unsupported." #endif @@ -177,6 +179,12 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){ #elif unix_like //TODO: FIX IT p->os = "linux"; +#elif android + #ifdef TERMUX + p->os = "linux"; + #else + p->os = "Android"; + #endif #endif /******************** @@ -231,6 +239,7 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){ #elif unix_like struct passwd *pwd = getpwuid(getuid()); #endif + #ifdef unix_like if (pwd){ if (pwd->pw_gecos && pwd->pw_gecos[0] && pwd->pw_gecos[0] != ','){ // Get the user's full name @@ -241,6 +250,9 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){ else p->userName = pwd->pw_name; } + #elif android + p->userName = "Player"; + #endif #ifdef apple p->journal = "_______.app"; @@ -257,7 +269,6 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){ #else p->gamePath = path; #endif - Debug() << "[oneshot] Game path :" << p->gamePath; Debug() << "[oneshot] Docs path :" << p->docsPath; diff --git a/src/security.cpp b/src/security.cpp index 791a53b..daf3f1c 100644 --- a/src/security.cpp +++ b/src/security.cpp @@ -5,6 +5,7 @@ #include // this component is needed to protect users from mod attacks. +#ifndef __ANDROID__ #ifdef __linux__ #include #include @@ -17,7 +18,7 @@ SCMP_SYS(vhangup), SCMP_SYS(settimeofday), SCMP_SYS(stime), - SCMP_SYS(clock_settime), + SCMP_SYS(clock_settime), SCMP_SYS(clock_settime64), SCMP_SYS(iopl), SCMP_SYS(ioperm), @@ -62,24 +63,23 @@ SCMP_SYS(setdomainname), SCMP_SYS(setns), SCMP_SYS(unshare), - #ifdef __ARM_NR SCMP_SYS(breakpoint), #endif - #ifdef __powerpc__ SCMP_SYS(sys_debug_setcontext), SCMP_SYS(rtas), #endif - #ifdef __alpha SCMP_SYS(oldumount), #endif SCMP_SYS(setpgid), SCMP_SYS(pciconfig_write)}; #endif +#endif void SecurityManagerInit(){ + #ifndef __ANDROID__ #ifdef __linux__ Debug() << "[SECURITY] initializing SECCOMP filter..."; ctx = seccomp_init(SCMP_ACT_ALLOW); // Default action: Kill the process @@ -123,10 +123,13 @@ void SecurityManagerInit(){ #else Debug() << "[SECURITY] SecurityManager doesn't support this platform."; #endif + #endif } void SecurityManagerDeInit(){ + #ifndef __ANDROID__ #ifdef __linux__ seccomp_release(ctx); #endif + #endif }