Some Android/Termux changes and engine fixes

This commit is contained in:
whitecum1488 2026-08-21 23:01:25 +03:00
parent 20c4c61614
commit 84e5d24398
6 changed files with 107 additions and 71 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.28.3) cmake_minimum_required(VERSION 3.9)
project(oneshot) project(oneshot)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
@ -16,9 +16,8 @@ function(check_option var a)
set(all ${a}) set(all ${a})
set(var "") set(var "")
list(APPEND all ${ARGN}) list(APPEND all ${ARGN})
foreach(x IN LISTS all) foreach(x IN LISTS all)
check_cxx_compiler_flag(${x} HAVE_OPTION) check_cxx_compiler_flag(${x} HAVE_OPTION)
if(HAVE_OPTION) if(HAVE_OPTION)
message(STATUS "${x} SUPPORTED") message(STATUS "${x} SUPPORTED")
list(APPEND var ${x}) list(APPEND var ${x})
@ -31,8 +30,7 @@ function(check_option var a)
message(STATUS "${x} UNSUPPORTED") message(STATUS "${x} UNSUPPORTED")
endif() endif()
endif() endif()
endforeach()
endforeach()
set(${var} "${var}" PARENT_SCOPE) set(${var} "${var}" PARENT_SCOPE)
endfunction() endfunction()
@ -45,6 +43,7 @@ option(STATIC "Build more static build" OFF)
option(USE_OPENGL_ES2 "GLES2_HEADER define" OFF) option(USE_OPENGL_ES2 "GLES2_HEADER define" OFF)
set(VERSION_STRING "0.1.2" CACHE STRING "Version string") set(VERSION_STRING "0.1.2" CACHE STRING "Version string")
option(DEVBUILD "Developoment build" OFF) option(DEVBUILD "Developoment build" OFF)
option(TERMUX "Build for TERMUX" OFF)
# Configuration # Configuration
set(CMAKE_DISABLE_IN_SOURCE_BUILD TRUE) set(CMAKE_DISABLE_IN_SOURCE_BUILD TRUE)
@ -197,6 +196,14 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
include_directories(${LINUXPKGS_INCLUDE_DIRS}) include_directories(${LINUXPKGS_INCLUDE_DIRS})
add_compile_options(${LINUXPKGS_CFLAGS_OTHER}) add_compile_options(${LINUXPKGS_CFLAGS_OTHER})
list(APPEND PLATFORM_LIBRARIES ${LINUXPKGS_LDFLAGS}) 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") elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(LINUXPKGS REQUIRED gtk+-3.0 libxfconf-0) pkg_check_modules(LINUXPKGS REQUIRED gtk+-3.0 libxfconf-0)
@ -384,14 +391,14 @@ else()
-fimplicit-constexpr -fimplicit-constexpr
-fomit-frame-pointer) -fomit-frame-pointer)
add_compile_options(${OPTIONS_RELEASE}) add_compile_options(${OPTIONS_RELEASE})
add_link_options(-Wl,-O2 add_link_options(-Wl,-O2
-Wl,--gc-sections -Wl,--gc-sections
-Wl,--as-needed -Wl,--as-needed
-Wl,--no-undefined -Wl,--no-undefined
-Wl,--strip-all -Wl,--strip-all
-Wl,--no-copy-dt-needed-entries) -Wl,--no-copy-dt-needed-entries)
if("${ARCH_RELEASE}" STREQUAL "") if("${ARCH_RELEASE}" STREQUAL "")
message(STATUS "ARCH_RELEASE empty") message(STATUS "ARCH_RELEASE empty")
else() else()
@ -401,21 +408,28 @@ else()
endif() endif()
if(ANDROID) if(ANDROID)
add_library(main SHARED if(TERMUX)
${MAIN_HEADERS} add_executable(${PROJECT_NAME}
${MAIN_SOURCE} ${MAIN_HEADERS}
${BINDING_HEADERS} ${MAIN_SOURCE}
${BINDING_SOURCE} ${BINDING_HEADERS}
${EMBEDDED_SOURCE} ${BINDING_SOURCE}
) ${EMBEDDED_SOURCE})
else()
add_library(main SHARED
${MAIN_HEADERS}
${MAIN_SOURCE}
${BINDING_HEADERS}
${BINDING_SOURCE}
${EMBEDDED_SOURCE})
endif()
else() else()
add_executable(${PROJECT_NAME} MACOSX_BUNDLE WIN32 add_executable(${PROJECT_NAME} MACOSX_BUNDLE WIN32
${MAIN_HEADERS} ${MAIN_HEADERS}
${MAIN_SOURCE} ${MAIN_SOURCE}
${BINDING_HEADERS} ${BINDING_HEADERS}
${BINDING_SOURCE} ${BINDING_SOURCE}
${EMBEDDED_SOURCE} ${EMBEDDED_SOURCE})
)
endif() endif()
if(NOT DEBUG) if(NOT DEBUG)
@ -433,6 +447,9 @@ if(DEVBUILD)
target_compile_definitions(${PROJECT_NAME} PRIVATE DEVBUILD) target_compile_definitions(${PROJECT_NAME} PRIVATE DEVBUILD)
endif() endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION_STRING="${VERSION_STRING}") 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(PkgConfig REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)

View File

@ -144,7 +144,7 @@ void Config::read(int argc, char *argv[]){
#undef PO_DESC_ALL #undef PO_DESC_ALL
SE.sourceCount = clamp(SE.sourceCount, 1, 64); SE.sourceCount = clamp(SE.sourceCount, 1, 64);
#ifdef __ANDROID__ #if defined(__ANDROID__) && !defined(TERMUX)
commonDataPath = prefPath(SDL_GetAndroidInternalStoragePath(), "/SunshineSaves"); commonDataPath = prefPath(SDL_GetAndroidInternalStoragePath(), "/SunshineSaves");
gameFolder = ""; gameFolder = "";
gameFolder.append(SDL_GetAndroidInternalStoragePath()).append("/Sunshine"); gameFolder.append(SDL_GetAndroidInternalStoragePath()).append("/Sunshine");

View File

@ -31,7 +31,7 @@
#undef snprintf #undef snprintf
#ifdef __ANDROID__ #ifdef __ANDROID__
#include <android/SDL_log.h> #include <android/log.h>
#elif __EMSCRIPTEN__ #elif __EMSCRIPTEN__
#include <emscripten/console.h> #include <emscripten/console.h>
#endif #endif
@ -66,13 +66,17 @@ public:
~Debug() noexcept { ~Debug() noexcept {
#ifdef __ANDROID__ #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__ #elif __EMSCRIPTEN__
emscripten_console_log(result.view().c_str()); emscripten_console_log(result.view().c_str());
#else #else
logs.emplace_back(buf.view());
std::cout << buf.view() << '\n'; std::cout << buf.view() << '\n';
#endif #endif
logs.emplace_back(buf.view());
} }
private: private:

View File

@ -63,7 +63,7 @@
#endif #endif
#ifndef VERSION_STRING #ifndef VERSION_STRING
#define VERSION_STRING ">w<" #define VERSION_STRING "Unknown"
#endif #endif
static void rgssThreadError(RGSSThreadData *rtData, const std::string &msg){ 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! //X11 work on *BSD,Solaris too!
#if unix_like #if unix_like
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); 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");
SDL_SetHint(SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT, "1");
#endif
#elif windows #elif windows
SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1"); SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1");
#elif android #elif android
@ -215,7 +213,6 @@ int main(int argc, char *argv[]){
} }
std::string path; std::string path;
if (!conf.gameFolder.empty()) { if (!conf.gameFolder.empty()) {
if (conf.gameFolder == ".") { if (conf.gameFolder == ".") {
path = std::filesystem::current_path().string(); path = std::filesystem::current_path().string();
@ -225,14 +222,14 @@ int main(int argc, char *argv[]){
} else { } else {
path = std::filesystem::current_path().string(); path = std::filesystem::current_path().string();
} }
std::ofstream out(std::filesystem::temp_directory_path() / "sunshine"); std::ofstream out(std::filesystem::temp_directory_path() / "sunshine");
if (!out) { if (!out) {
WarnMsg("Failed to write game directory path to temp file, problems with journal app expected!"); WarnMsg("Failed to write game directory path to temp file, problems with journal app expected!");
} else { } else {
out << path; out << path;
} }
extern int screenMain(Config &conf); extern int screenMain(Config &conf);
if (conf.screenMode) if (conf.screenMode)
return screenMain(conf); return screenMain(conf);
@ -288,7 +285,7 @@ int main(int argc, char *argv[]){
WarnMsg("Error creating Mixer Device, check your system audio configuration"); WarnMsg("Error creating Mixer Device, check your system audio configuration");
MIX_Quit(); MIX_Quit();
TTF_Quit(); TTF_Quit();
SDL_Quit(); SDL_Quit();
return 0; return 0;
} }
@ -303,55 +300,59 @@ int main(int argc, char *argv[]){
#endif #endif
int winW, winH; 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)); rtData.windowSizeMsg.post(Vec2i(winW, winH));
ModLoader(conf, win); ModLoader(conf, win);
/* Load and post key bindings */ /* Load and post key bindings */
rtData.bindingUpdateMsg.post(loadBindings(conf)); rtData.bindingUpdateMsg.post(loadBindings(conf));
/* Start RGSS thread */ /* 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 */ /* Request RGSS thread to stop */
eventThread.process(rtData); rtData.rqTerm.set();
/* Request RGSS thread to stop */ /* Wait for RGSS thread response */
rtData.rqTerm.set(); 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 */ /* Give RGSS thread some time to respond */
for (int i = 0; i < 1000; ++i){ SDL_Delay(10);
/* 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 */ /* If RGSS thread ack'd request, wait for it to shutdown,
SDL_Delay(10); * 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){ if(show_crash_sceen){
crash_screen(win); crash_screen(win);
} }
MIX_DestroyMixer(mixer); MIX_DestroyMixer(mixer);
SDL_DestroyWindow(win); SDL_DestroyWindow(win);

View File

@ -32,6 +32,8 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdk.h> #include <gdk/gdk.h>
#elif android
//idk
#else #else
#error "Operating system not detected or unsupported." #error "Operating system not detected or unsupported."
#endif #endif
@ -177,6 +179,12 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){
#elif unix_like #elif unix_like
//TODO: FIX IT //TODO: FIX IT
p->os = "linux"; p->os = "linux";
#elif android
#ifdef TERMUX
p->os = "linux";
#else
p->os = "Android";
#endif
#endif #endif
/******************** /********************
@ -231,6 +239,7 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){
#elif unix_like #elif unix_like
struct passwd *pwd = getpwuid(getuid()); struct passwd *pwd = getpwuid(getuid());
#endif #endif
#ifdef unix_like
if (pwd){ if (pwd){
if (pwd->pw_gecos && pwd->pw_gecos[0] && pwd->pw_gecos[0] != ','){ if (pwd->pw_gecos && pwd->pw_gecos[0] && pwd->pw_gecos[0] != ','){
// Get the user's full name // Get the user's full name
@ -241,6 +250,9 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){
else else
p->userName = pwd->pw_name; p->userName = pwd->pw_name;
} }
#elif android
p->userName = "Player";
#endif
#ifdef apple #ifdef apple
p->journal = "_______.app"; p->journal = "_______.app";
@ -257,7 +269,6 @@ Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData){
#else #else
p->gamePath = path; p->gamePath = path;
#endif #endif
Debug() << "[oneshot] Game path :" << p->gamePath; Debug() << "[oneshot] Game path :" << p->gamePath;
Debug() << "[oneshot] Docs path :" << p->docsPath; Debug() << "[oneshot] Docs path :" << p->docsPath;

View File

@ -5,6 +5,7 @@
#include <SDL3/SDL_system.h> #include <SDL3/SDL_system.h>
// this component is needed to protect users from mod attacks. // this component is needed to protect users from mod attacks.
#ifndef __ANDROID__
#ifdef __linux__ #ifdef __linux__
#include <sys/socket.h> #include <sys/socket.h>
#include <seccomp.h> #include <seccomp.h>
@ -17,7 +18,7 @@
SCMP_SYS(vhangup), SCMP_SYS(vhangup),
SCMP_SYS(settimeofday), SCMP_SYS(settimeofday),
SCMP_SYS(stime), SCMP_SYS(stime),
SCMP_SYS(clock_settime), SCMP_SYS(clock_settime),
SCMP_SYS(clock_settime64), SCMP_SYS(clock_settime64),
SCMP_SYS(iopl), SCMP_SYS(iopl),
SCMP_SYS(ioperm), SCMP_SYS(ioperm),
@ -62,24 +63,23 @@
SCMP_SYS(setdomainname), SCMP_SYS(setdomainname),
SCMP_SYS(setns), SCMP_SYS(setns),
SCMP_SYS(unshare), SCMP_SYS(unshare),
#ifdef __ARM_NR #ifdef __ARM_NR
SCMP_SYS(breakpoint), SCMP_SYS(breakpoint),
#endif #endif
#ifdef __powerpc__ #ifdef __powerpc__
SCMP_SYS(sys_debug_setcontext), SCMP_SYS(sys_debug_setcontext),
SCMP_SYS(rtas), SCMP_SYS(rtas),
#endif #endif
#ifdef __alpha #ifdef __alpha
SCMP_SYS(oldumount), SCMP_SYS(oldumount),
#endif #endif
SCMP_SYS(setpgid), SCMP_SYS(setpgid),
SCMP_SYS(pciconfig_write)}; SCMP_SYS(pciconfig_write)};
#endif #endif
#endif
void SecurityManagerInit(){ void SecurityManagerInit(){
#ifndef __ANDROID__
#ifdef __linux__ #ifdef __linux__
Debug() << "[SECURITY] initializing SECCOMP filter..."; Debug() << "[SECURITY] initializing SECCOMP filter...";
ctx = seccomp_init(SCMP_ACT_ALLOW); // Default action: Kill the process ctx = seccomp_init(SCMP_ACT_ALLOW); // Default action: Kill the process
@ -123,10 +123,13 @@ void SecurityManagerInit(){
#else #else
Debug() << "[SECURITY] SecurityManager doesn't support this platform."; Debug() << "[SECURITY] SecurityManager doesn't support this platform.";
#endif #endif
#endif
} }
void SecurityManagerDeInit(){ void SecurityManagerDeInit(){
#ifndef __ANDROID__
#ifdef __linux__ #ifdef __linux__
seccomp_release(ctx); seccomp_release(ctx);
#endif #endif
#endif
} }