From 7b9012671abdbe1d3b831099ea052f5682ba82e2 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 30 Oct 2023 19:01:26 +0200 Subject: [PATCH 01/12] Add libuv --- .gitmodules | 6 ++++++ CMakeLists.txt | 11 ++++++++++- src/lua.cpp | 7 +++++++ third_party/libuv | 1 + third_party/luv | 1 + 5 files changed, 25 insertions(+), 1 deletion(-) create mode 160000 third_party/libuv create mode 160000 third_party/luv diff --git a/.gitmodules b/.gitmodules index 8a6cac496..93bb8f9dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,3 +43,9 @@ [submodule "third_party/hydra_core"] path = third_party/hydra_core url = https://github.com/hydra-emu/core +[submodule "third_party/luv"] + path = third_party/luv + url = https://github.com/luvit/luv +[submodule "third_party/libuv"] + path = third_party/libuv + url = https://github.com/libuv/libuv diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a718fbb3..52ddb495e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,6 +245,15 @@ set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp third_party/xxhash/xxhash.c ) +if(ENABLE_LUAJIT) + # Build luv and libuv for TCP Lua server usage + include_directories(third_party/luv/src) + include_directories(third_party/luv/deps/lua-compat-5.3/c-api) + include_directories(third_party/libuv/include) + set(THIRD_PARTY_SOURCE_FILES ${THIRD_PARTY_SOURCE_FILES} third_party/luv/src/luv.c) + + add_subdirectory(third_party/libuv) +endif() if(ENABLE_QT_GUI) include_directories(third_party/duckstation) @@ -399,7 +408,7 @@ endif() if(ENABLE_LUAJIT) target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_LUA=1") - target_link_libraries(Alber PRIVATE libluajit) + target_link_libraries(Alber PRIVATE libluajit uv) endif() if(ENABLE_OPENGL) diff --git a/src/lua.cpp b/src/lua.cpp index 729b65817..f7e0b7191 100644 --- a/src/lua.cpp +++ b/src/lua.cpp @@ -1,6 +1,10 @@ #ifdef PANDA3DS_ENABLE_LUA #include "lua_manager.hpp" +extern "C" { + #include "luv.h" +} + void LuaManager::initialize() { L = luaL_newstate(); // Open Lua @@ -11,6 +15,9 @@ void LuaManager::initialize() { } luaL_openlibs(L); + lua_pushstring(L, "luv"); + luaopen_luv(L); + lua_settable(L, LUA_GLOBALSINDEX); initializeThunks(); initialized = true; diff --git a/third_party/libuv b/third_party/libuv new file mode 160000 index 000000000..b8368a144 --- /dev/null +++ b/third_party/libuv @@ -0,0 +1 @@ +Subproject commit b8368a1441fd4ebdaaae70b67136c80b1a98be32 diff --git a/third_party/luv b/third_party/luv new file mode 160000 index 000000000..3e55ac433 --- /dev/null +++ b/third_party/luv @@ -0,0 +1 @@ +Subproject commit 3e55ac4331d06aa5f43016a142aa2aaa23264105 From 93042b928348d615505b4af4cd622f04c4154894 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 30 Oct 2023 21:37:59 +0200 Subject: [PATCH 02/12] Disable libuv on Android --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52ddb495e..82484596c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,11 @@ option(ENABLE_LUAJIT "Enable scripting with the Lua programming language" ON) option(ENABLE_QT_GUI "Enable the Qt GUI. If not selected then the emulator uses a minimal SDL-based UI instead" OFF) option(BUILD_HYDRA_CORE "Build a Hydra core" OFF) +if(ENABLE_LUAJIT AND ANDROID) + message(STATUS "Enabled LuaJIT on Android build. Automatically disabling it until it works properly") + set(ENABLE_LUAJIT OFF) +endif() + include_directories(${PROJECT_SOURCE_DIR}/include/) include_directories(${PROJECT_SOURCE_DIR}/include/kernel) include_directories (${FMT_INCLUDE_DIR}) From 3bb4af5e13bd0ea125cf1d22daf9a694061f34fb Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:47:39 +0200 Subject: [PATCH 03/12] Fix libuv linkage --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82484596c..0d8278cde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -413,7 +413,7 @@ endif() if(ENABLE_LUAJIT) target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_LUA=1") - target_link_libraries(Alber PRIVATE libluajit uv) + target_link_libraries(Alber PRIVATE libluajit uv_a) endif() if(ENABLE_OPENGL) From eabd22423c4098be90776e86324035fa2172f5ff Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 29 Jan 2024 19:36:49 +0200 Subject: [PATCH 04/12] Remove outdated stubs in Mii Selector applet --- src/core/applets/mii_selector.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/applets/mii_selector.cpp b/src/core/applets/mii_selector.cpp index d6dd79dab..ab6455fc2 100644 --- a/src/core/applets/mii_selector.cpp +++ b/src/core/applets/mii_selector.cpp @@ -22,7 +22,6 @@ Result::HorizonResult MiiSelectorApplet::start(const MemoryBlock* sharedMem, con // Thanks to Citra devs as always for the default mii data and other applet help output = getDefaultMii(); output.returnCode = 0; // Success - // output.selectedMiiData = miiData; output.selectedGuestMiiIndex = std::numeric_limits::max(); output.miiChecksum = boost::crc<16, 0x1021, 0, 0, false, false>(&output.selectedMiiData, sizeof(MiiData) + sizeof(output.unknown1)); @@ -84,4 +83,4 @@ MiiResult MiiSelectorApplet::getDefaultMii() { result.guestMiiName.fill(0x0); return result; -} \ No newline at end of file +} From 9cc3fc0c4c1f5a5ba5223f4341b83af9ad77ffc9 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:07:21 +0200 Subject: [PATCH 05/12] [Qt] Add touchscreen --- include/panda_qt/main_window.hpp | 10 ++++++++ src/panda_qt/main_window.cpp | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/panda_qt/main_window.hpp b/include/panda_qt/main_window.hpp index c03cffbb2..c2db9ac1a 100644 --- a/include/panda_qt/main_window.hpp +++ b/include/panda_qt/main_window.hpp @@ -42,6 +42,8 @@ class MainWindow : public QMainWindow { SetCirclePadY, LoadLuaScript, EditCheat, + PressTouchscreen, + ReleaseTouchscreen, }; // Tagged union representing our message queue messages @@ -68,6 +70,11 @@ class MainWindow : public QMainWindow { struct { CheatMessage* c; } cheat; + + struct { + u16 x; + u16 y; + } touchscreen; }; }; @@ -108,6 +115,9 @@ class MainWindow : public QMainWindow { void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void loadLuaScript(const std::string& code); void editCheat(u32 handle, const std::vector& cheat, const std::function& callback); }; \ No newline at end of file diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index 1d7118bcc..de70cc187 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -277,6 +278,10 @@ void MainWindow::dispatchMessage(const EmulatorMessage& message) { case MessageType::ReleaseKey: emu->getServiceManager().getHID().releaseKey(message.key.key); break; case MessageType::SetCirclePadX: emu->getServiceManager().getHID().setCirclepadX(message.circlepad.value); break; case MessageType::SetCirclePadY: emu->getServiceManager().getHID().setCirclepadY(message.circlepad.value); break; + case MessageType::PressTouchscreen: + emu->getServiceManager().getHID().setTouchScreenPress(message.touchscreen.x, message.touchscreen.y); + break; + case MessageType::ReleaseTouchscreen: emu->getServiceManager().getHID().releaseTouchScreen(); break; } } @@ -357,6 +362,40 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) { } } +void MainWindow::mousePressEvent(QMouseEvent* event) { + if (event->button() == Qt::MouseButton::LeftButton) { + const QPointF clickPos = event->globalPosition(); + const QPointF widgetPos = screen.mapFromGlobal(clickPos); + + // Press is inside the screen area + if (widgetPos.x() >= 0 && widgetPos.x() < screen.width() && widgetPos.y() >= 0 && widgetPos.y() < screen.height()) { + // Go from widget positions to [0, 400) for x and [0, 480) for y + uint x = (uint)std::round(widgetPos.x() / screen.width() * 400.f); + uint y = (uint)std::round(widgetPos.y() / screen.height() * 480.f); + + // Check if touch falls in the touch screen area + if (y >= 240 && y <= 480 && x >= 40 && x < 40 + 320) { + // Convert to 3DS coordinates + u16 x_converted = static_cast(x) - 40; + u16 y_converted = static_cast(y) - 240; + + EmulatorMessage message{.type = MessageType::PressTouchscreen}; + message.touchscreen.x = x_converted; + message.touchscreen.y = y_converted; + sendMessage(message); + } else { + sendMessage(EmulatorMessage{.type = MessageType::ReleaseTouchscreen}); + } + } + } +} + +void MainWindow::mouseReleaseEvent(QMouseEvent* event) { + if (event->button() == Qt::MouseButton::LeftButton) { + sendMessage(EmulatorMessage{.type = MessageType::ReleaseTouchscreen}); + } +} + void MainWindow::loadLuaScript(const std::string& code) { EmulatorMessage message{.type = MessageType::LoadLuaScript}; From e6d012d05d487ce2ceea7afc4da7372175a46754 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:34:03 +0530 Subject: [PATCH 06/12] Compile release APK on CI *Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> --- .github/workflows/Android_Build.yml | 56 +++++++++++++------ src/pandroid/app/build.gradle.kts | 16 +++++- src/pandroid/app/src/main/AndroidManifest.xml | 2 + 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml index 7625e18d8..137577c18 100644 --- a/.github/workflows/Android_Build.yml +++ b/.github/workflows/Android_Build.yml @@ -6,15 +6,19 @@ on: - master pull_request: -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - jobs: x64: runs-on: ubuntu-latest + strategy: + matrix: + build_type: + - release + steps: + - name: Set BUILD_TYPE variable + run: echo "BUILD_TYPE=${{ matrix.build_type }}" >> $GITHUB_ENV + - uses: actions/checkout@v2 - name: Fetch submodules run: git submodule update --init --recursive @@ -29,7 +33,7 @@ jobs: - name: Setup Java uses: actions/setup-java@v3 with: - distribution: 'zulu' # See 'Supported distributions' for available options + distribution: 'zulu' java-version: '17' - name: Configure CMake @@ -37,23 +41,36 @@ jobs: - name: Build run: | + # Apply patch for GLES compatibility git apply ./.github/gles.patch - cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + # Build the project with CMake + cmake --build ${{github.workspace}}/build --config ${{ env.BUILD_TYPE }} + # Move the generated library to the appropriate location mv ./build/libAlber.so ./src/pandroid/app/src/main/jniLibs/x86_64/ + # Build the Android app with Gradle cd src/pandroid - ./gradlew assembleDebug + ./gradlew assemble${{ env.BUILD_TYPE }} cd ../.. - - name: Upload executable + - name: Upload artifacts uses: actions/upload-artifact@v2 with: - name: Android APK (x86-64) - path: './src/pandroid/app/build/outputs/apk/debug/app-debug.apk' + name: Android APKs (x86-64) + path: | + ./src/pandroid/app/build/outputs/apk/${{ env.BUILD_TYPE }}/app-${{ env.BUILD_TYPE }}.apk arm64: runs-on: ubuntu-latest + strategy: + matrix: + build_type: + - release + steps: + - name: Set BUILD_TYPE variable + run: echo "BUILD_TYPE=${{ matrix.build_type }}" >> $GITHUB_ENV + - uses: actions/checkout@v2 - name: Fetch submodules run: git submodule update --init --recursive @@ -68,7 +85,7 @@ jobs: - name: Setup Java uses: actions/setup-java@v3 with: - distribution: 'zulu' # See 'Supported distributions' for available options + distribution: 'zulu' java-version: '17' - name: Configure CMake @@ -76,16 +93,21 @@ jobs: - name: Build run: | + # Apply patch for GLES compatibility git apply ./.github/gles.patch - cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + # Build the project with CMake + cmake --build ${{github.workspace}}/build --config ${{ env.BUILD_TYPE }} + # Move the generated library to the appropriate location mv ./build/libAlber.so ./src/pandroid/app/src/main/jniLibs/arm64-v8a/ + # Build the Android app with Gradle cd src/pandroid - ./gradlew assembleDebug + ./gradlew assemble${{ env.BUILD_TYPE }} + ls -R app/build/outputs cd ../.. - - name: Upload executable + - name: Upload artifacts uses: actions/upload-artifact@v2 with: - name: Android APK (arm64) - path: './src/pandroid/app/build/outputs/apk/debug/app-debug.apk' - + name: Android APKs (arm64) + path: | + ./src/pandroid/app/build/outputs/apk/${{ env.BUILD_TYPE }}/app-${{ env.BUILD_TYPE }}.apk diff --git a/src/pandroid/app/build.gradle.kts b/src/pandroid/app/build.gradle.kts index f1feaf0d4..201d5db13 100644 --- a/src/pandroid/app/build.gradle.kts +++ b/src/pandroid/app/build.gradle.kts @@ -21,8 +21,20 @@ android { } buildTypes { - release { + getByName("release") { isMinifyEnabled = false + isShrinkResources = false + isDebuggable = false + signingConfig = signingConfigs.getByName("debug") + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + getByName("debug") { + isMinifyEnabled = false + isShrinkResources = false + isDebuggable = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -41,4 +53,4 @@ dependencies { implementation("androidx.preference:preference:1.2.1") implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("com.google.code.gson:gson:2.10.1") -} \ No newline at end of file +} diff --git a/src/pandroid/app/src/main/AndroidManifest.xml b/src/pandroid/app/src/main/AndroidManifest.xml index 9f7676543..b62764937 100644 --- a/src/pandroid/app/src/main/AndroidManifest.xml +++ b/src/pandroid/app/src/main/AndroidManifest.xml @@ -20,6 +20,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" + android:isGame="true" + android:hardwareAccelerated="true" android:theme="@style/Theme.Pandroid" tools:targetApi="31"> Date: Thu, 1 Feb 2024 11:46:15 -0400 Subject: [PATCH 07/12] Logger (#397) * Initial commit * add shader-jit option * add translate to word "graphics' for ptbr * Native logger * Bonk * fix --------- Co-authored-by: gabriel Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> --- include/logger.hpp | 10 +- src/jni_driver.cpp | 7 ++ src/pandroid/app/src/main/AndroidManifest.xml | 2 + .../com/panda3ds/pandroid/AlberDriver.java | 2 + .../panda3ds/pandroid/app/GameActivity.java | 6 + .../pandroid/app/PandroidApplication.java | 6 + .../app/base/BasePreferenceFragment.java | 9 ++ .../pandroid/app/main/SettingsFragment.java | 2 + .../app/preferences/DeveloperPreferences.java | 49 +++++++++ .../pandroid/app/services/LoggerService.java | 104 ++++++++++++++++++ .../pandroid/data/config/GlobalConfig.java | 4 +- .../pandroid/lang/PipeStreamTask.java | 40 +++++++ .../java/com/panda3ds/pandroid/lang/Task.java | 2 + .../panda3ds/pandroid/utils/FileUtils.java | 19 ++++ .../pandroid/utils/PerformanceMonitor.java | 64 +++++++++++ .../pandroid/view/PandaGlRenderer.java | 12 +- .../pandroid/view/utils/PerformanceView.java | 64 +++++++++++ .../src/main/res/values-pt-rBR/strings.xml | 11 +- .../app/src/main/res/values/strings.xml | 9 ++ .../main/res/xml/developer_preferences.xml | 29 +++++ .../src/main/res/xml/start_preferences.xml | 7 ++ 21 files changed, 454 insertions(+), 4 deletions(-) create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/services/LoggerService.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/PipeStreamTask.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/PerformanceMonitor.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/utils/PerformanceView.java create mode 100644 src/pandroid/app/src/main/res/xml/developer_preferences.xml diff --git a/include/logger.hpp b/include/logger.hpp index 82d904102..e021a685d 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -2,6 +2,10 @@ #include #include +#ifdef __ANDROID__ +#include +#endif + namespace Log { // Our logger class template @@ -12,7 +16,11 @@ namespace Log { std::va_list args; va_start(args, fmt); +#ifdef __ANDROID__ + __android_log_vprint(ANDROID_LOG_DEFAULT, "Panda3DS", fmt, args); +#else std::vprintf(fmt, args); +#endif va_end(args); } }; @@ -81,4 +89,4 @@ namespace Log { #else #define MAKE_LOG_FUNCTION(functionName, logger) MAKE_LOG_FUNCTION_USER(functionName, logger) #endif -} +} \ No newline at end of file diff --git a/src/jni_driver.cpp b/src/jni_driver.cpp index 6eeb727aa..d962f23eb 100644 --- a/src/jni_driver.cpp +++ b/src/jni_driver.cpp @@ -35,6 +35,13 @@ JNIEnv* jniEnv() { extern "C" { +#define MAKE_SETTING(functionName, type, settingName) \ +AlberFunction(void, functionName) (JNIEnv* env, jobject obj, type value) { emulator->getConfig().settingName = value; } + +MAKE_SETTING(setShaderJitEnabled, jboolean, shaderJitEnabled) + +#undef MAKE_SETTING + AlberFunction(void, Setup)(JNIEnv* env, jobject obj) { env->GetJavaVM(&jvm); } AlberFunction(void, Pause)(JNIEnv* env, jobject obj) { emulator->pause(); } AlberFunction(void, Resume)(JNIEnv* env, jobject obj) { emulator->resume(); } diff --git a/src/pandroid/app/src/main/AndroidManifest.xml b/src/pandroid/app/src/main/AndroidManifest.xml index b62764937..c66d37af8 100644 --- a/src/pandroid/app/src/main/AndroidManifest.xml +++ b/src/pandroid/app/src/main/AndroidManifest.xml @@ -48,5 +48,7 @@ + + diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java index 5cff703c7..00b7842b0 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java @@ -22,5 +22,7 @@ public class AlberDriver { public static native void LoadLuaScript(String script); public static native byte[] GetSmdh(); + public static native void setShaderJitEnabled(boolean enable); + static { System.loadLibrary("Alber"); } } \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java index aced6faad..f7050e99c 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java @@ -21,6 +21,7 @@ import com.panda3ds.pandroid.utils.Constants; import com.panda3ds.pandroid.view.PandaGlSurfaceView; import com.panda3ds.pandroid.view.PandaLayoutController; +import com.panda3ds.pandroid.view.utils.PerformanceView; public class GameActivity extends BaseActivity { private final DrawerFragment drawerFragment = new DrawerFragment(); @@ -56,6 +57,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { ((CheckBox) findViewById(R.id.hide_screen_controller)).setChecked(GlobalConfig.get(GlobalConfig.KEY_SCREEN_GAMEPAD_VISIBLE)); getSupportFragmentManager().beginTransaction().replace(R.id.drawer_fragment, drawerFragment).commitNow(); + + if (GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY)) { + PerformanceView view = new PerformanceView(this); + ((FrameLayout) findViewById(R.id.panda_gl_frame)).addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + } } @Override diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/PandroidApplication.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/PandroidApplication.java index 02fbbbcc3..b0cdc935f 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/PandroidApplication.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/PandroidApplication.java @@ -2,11 +2,13 @@ import android.app.Application; import android.content.Context; +import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import com.panda3ds.pandroid.AlberDriver; import com.panda3ds.pandroid.R; +import com.panda3ds.pandroid.app.services.LoggerService; import com.panda3ds.pandroid.data.config.GlobalConfig; import com.panda3ds.pandroid.input.InputMap; import com.panda3ds.pandroid.utils.GameUtils; @@ -24,6 +26,10 @@ public void onCreate() { GameUtils.initialize(); InputMap.initialize(); AlberDriver.Setup(); + + if (GlobalConfig.get(GlobalConfig.KEY_LOGGER_SERVICE)) { + startService(new Intent(this, LoggerService.class)); + } } public static int getThemeId() { diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java index 3cd28f4bf..9482df1df 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java @@ -1,8 +1,13 @@ package com.panda3ds.pandroid.app.base; import android.annotation.SuppressLint; + +import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + import com.panda3ds.pandroid.lang.Function; @@ -15,4 +20,8 @@ protected void setItemClick(String key, Function listener) { return false; }); } + + protected void setActivityTitle(@StringRes int titleId) { + ((AppCompatActivity) requireActivity()).getSupportActionBar().setTitle(titleId); + } } diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java index b3bebf8fc..bfe33a2be 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java @@ -8,6 +8,7 @@ import com.panda3ds.pandroid.app.PreferenceActivity; import com.panda3ds.pandroid.app.base.BasePreferenceFragment; import com.panda3ds.pandroid.app.preferences.AppearancePreferences; +import com.panda3ds.pandroid.app.preferences.DeveloperPreferences; import com.panda3ds.pandroid.app.preferences.InputPreferences; public class SettingsFragment extends BasePreferenceFragment { @@ -16,5 +17,6 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S setPreferencesFromResource(R.xml.start_preferences, rootKey); setItemClick("input", (item) -> PreferenceActivity.launch(requireContext(), InputPreferences.class)); setItemClick("appearance", (item)-> PreferenceActivity.launch(requireContext(), AppearancePreferences.class)); + setItemClick("developer", (item)-> PreferenceActivity.launch(requireContext(), DeveloperPreferences.class)); } } diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java new file mode 100644 index 000000000..f131f0a09 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java @@ -0,0 +1,49 @@ +package com.panda3ds.pandroid.app.preferences; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.preference.SwitchPreference; + +import com.panda3ds.pandroid.R; +import com.panda3ds.pandroid.app.PandroidApplication; +import com.panda3ds.pandroid.app.base.BasePreferenceFragment; +import com.panda3ds.pandroid.app.services.LoggerService; +import com.panda3ds.pandroid.data.config.GlobalConfig; + +public class DeveloperPreferences extends BasePreferenceFragment { + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + setPreferencesFromResource(R.xml.developer_preferences, rootKey); + setActivityTitle(R.string.developer_options); + + setItemClick("performanceMonitor", pref -> GlobalConfig.set(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY, ((SwitchPreference) pref).isChecked())); + setItemClick("shaderJit", pref -> GlobalConfig.set(GlobalConfig.KEY_SHADER_JIT, ((SwitchPreference) pref).isChecked())); + setItemClick("loggerService", pref -> { + boolean checked = ((SwitchPreference) pref).isChecked(); + Context ctx = PandroidApplication.getAppContext(); + if (checked) { + ctx.startService(new Intent(ctx, LoggerService.class)); + } else { + ctx.stopService(new Intent(ctx, LoggerService.class)); + } + GlobalConfig.set(GlobalConfig.KEY_LOGGER_SERVICE, checked); + }); + + refresh(); + } + + @Override + public void onResume() { + super.onResume(); + refresh(); + } + + private void refresh() { + ((SwitchPreference) findPreference("performanceMonitor")).setChecked(GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY)); + ((SwitchPreference) findPreference("loggerService")).setChecked(GlobalConfig.get(GlobalConfig.KEY_LOGGER_SERVICE)); + ((SwitchPreference) findPreference("shaderJit")).setChecked(GlobalConfig.get(GlobalConfig.KEY_SHADER_JIT)); + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/services/LoggerService.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/services/LoggerService.java new file mode 100644 index 000000000..e44f35039 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/services/LoggerService.java @@ -0,0 +1,104 @@ +package com.panda3ds.pandroid.app.services; + +import android.app.Service; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.os.Build; +import android.os.IBinder; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.panda3ds.pandroid.lang.PipeStreamTask; +import com.panda3ds.pandroid.lang.Task; +import com.panda3ds.pandroid.utils.Constants; +import com.panda3ds.pandroid.utils.FileUtils; + +import java.io.OutputStream; +import java.util.Arrays; + +public class LoggerService extends Service { + private static final long MAX_LOG_SIZE = 1024 * 1024 * 4; // 4MB + + private PipeStreamTask errorTask; + private PipeStreamTask outputTask; + private Process logcat; + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + try { + Runtime.getRuntime().exec(new String[]{"logcat", "-c"}).waitFor(); + logcat = Runtime.getRuntime().exec(new String[]{"logcat"}); + String logPath = getExternalMediaDirs()[0].getAbsolutePath(); + FileUtils.createDir(logPath, "logs"); + logPath = logPath + "/logs"; + + if (FileUtils.exists(logPath + "/last.txt")) { + FileUtils.delete(logPath + "/last.txt"); + } + + if (FileUtils.exists(logPath + "/current.txt")) { + FileUtils.rename(logPath + "/current.txt", "last.txt"); + } + + OutputStream stream = FileUtils.getOutputStream(logPath + "/current.txt"); + errorTask = new PipeStreamTask(logcat.getErrorStream(), stream, MAX_LOG_SIZE); + outputTask = new PipeStreamTask(logcat.getInputStream(), stream, MAX_LOG_SIZE); + + errorTask.start(); + outputTask.start(); + + Log.i(Constants.LOG_TAG, "Started logger service"); + logDeviceInfo(); + } catch (Exception e) { + stopSelf(); + Log.e(Constants.LOG_TAG, "Failed to start logger service"); + } + } + + private void logDeviceInfo() { + Log.i(Constants.LOG_TAG, "----------------------"); + Log.i(Constants.LOG_TAG, "Android SDK: " + Build.VERSION.SDK_INT); + Log.i(Constants.LOG_TAG, "Device: " + Build.DEVICE); + Log.i(Constants.LOG_TAG, "Model: " + Build.MANUFACTURER + " " + Build.MODEL); + Log.i(Constants.LOG_TAG, "ABIs: " + Arrays.toString(Build.SUPPORTED_ABIS)); + try { + PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0); + Log.i(Constants.LOG_TAG, ""); + Log.i(Constants.LOG_TAG, "Package: " + info.packageName); + Log.i(Constants.LOG_TAG, "Install location: " + info.installLocation); + Log.i(Constants.LOG_TAG, "App version: " + info.versionName + " (" + info.versionCode + ")"); + } catch (Exception e) { + Log.e(Constants.LOG_TAG, "Error obtaining package info: " + e); + } + Log.i(Constants.LOG_TAG, "----------------------"); + } + + @Override + public void onTaskRemoved(Intent rootIntent) { + stopSelf(); + //This is a time for app save save log file + try { + Thread.sleep(1000); + } catch (Exception e) {} + super.onTaskRemoved(rootIntent); + } + + @Override + public void onDestroy() { + Log.i(Constants.LOG_TAG, "Logger service terminating"); + errorTask.close(); + outputTask.close(); + try { + logcat.destroy(); + } catch (Throwable t) {} + super.onDestroy(); + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/config/GlobalConfig.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/config/GlobalConfig.java index d6dbe3b80..bff1f9e0e 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/config/GlobalConfig.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/config/GlobalConfig.java @@ -5,7 +5,6 @@ import com.panda3ds.pandroid.utils.Constants; import java.io.Serializable; -import java.util.HashMap; import java.util.Map; public class GlobalConfig { @@ -19,6 +18,9 @@ public class GlobalConfig { public static DataModel data; + public static final Key KEY_SHADER_JIT = new Key<>("emu.shader_jit", false); + public static final Key KEY_SHOW_PERFORMANCE_OVERLAY = new Key<>("dev.performanceOverlay", false); + public static final Key KEY_LOGGER_SERVICE = new Key<>("dev.loggerService", false); public static final Key KEY_APP_THEME = new Key<>("app.theme", THEME_ANDROID); public static final Key KEY_SCREEN_GAMEPAD_VISIBLE = new Key<>("app.screen_gamepad.visible", true); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/PipeStreamTask.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/PipeStreamTask.java new file mode 100644 index 000000000..e4bbda986 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/PipeStreamTask.java @@ -0,0 +1,40 @@ +package com.panda3ds.pandroid.lang; + +import java.io.InputStream; +import java.io.OutputStream; + +public class PipeStreamTask extends Task { + private final InputStream input; + private final OutputStream output; + private final long limit; + private long size; + + public PipeStreamTask(InputStream input, OutputStream output, long limit) { + this.input = input; + this.output = output; + this.limit = limit; + } + + @Override + public void run() { + super.run(); + int data; + try { + while ((data = input.read()) != -1) { + output.write(data); + if (++size > limit) { + break; + } + } + } catch (Exception e) {} + close(); + } + + public void close() { + try { + output.flush(); + output.close(); + input.close(); + } catch (Exception e) {} + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Task.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Task.java index 7745883d5..8de344b40 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Task.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Task.java @@ -5,6 +5,8 @@ public Task(Runnable runnable) { super(runnable); } + protected Task() {} + public void runSync() { start(); waitFinish(); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/FileUtils.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/FileUtils.java index 45faf5a47..1746f1c9e 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/FileUtils.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/FileUtils.java @@ -70,6 +70,25 @@ public static boolean exists(String path) { return parseFile(path).exists(); } + public static void rename(String path, String newName){ + parseFile(path).renameTo(newName); + } + + public static void delete(String path) { + DocumentFile file = parseFile(path); + + if (file.exists()) { + if (file.isDirectory()) { + String[] children = listFiles(path); + for (String child : children) { + delete(path + "/" + child); + } + } + + file.delete(); + } + } + public static boolean createDir(String path, String name) { DocumentFile folder = parseFile(path); if (folder.findFile(name) != null) { diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/PerformanceMonitor.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/PerformanceMonitor.java new file mode 100644 index 000000000..23adbf136 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/PerformanceMonitor.java @@ -0,0 +1,64 @@ +package com.panda3ds.pandroid.utils; + +import android.app.ActivityManager; +import android.content.Context; +import android.os.Debug; +import android.os.Process; + +import com.panda3ds.pandroid.app.PandroidApplication; +import com.panda3ds.pandroid.data.config.GlobalConfig; + +public class PerformanceMonitor { + private static int fps = 1; + private static String backend = ""; + private static int frames = 0; + private static long lastUpdate = 0; + private static long totalMemory = 1; + private static long availableMemory = 0; + + public static void initialize(String backendName) { + fps = 1; + backend = backendName; + } + + public static void runFrame() { + if (GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY)) { + frames++; + if (System.currentTimeMillis() - lastUpdate > 1000) { + lastUpdate = System.currentTimeMillis(); + fps = frames; + frames = 0; + try { + Context ctx = PandroidApplication.getAppContext(); + ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); + manager.getMemoryInfo(info); + totalMemory = info.totalMem; + availableMemory = info.availMem; + } catch (Exception e) {} + } + } + } + + public static long getUsedMemory() { + return Math.max(1, totalMemory - availableMemory); + } + + public static long getTotalMemory() { + return totalMemory; + } + + public static long getAvailableMemory() { + return availableMemory; + } + + public static int getFps() { + return fps; + } + + public static String getBackend() { + return backend; + } + + public static void destroy() {} +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/PandaGlRenderer.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/PandaGlRenderer.java index 52e609a33..c39b36b3b 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/PandaGlRenderer.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/PandaGlRenderer.java @@ -7,8 +7,10 @@ import android.opengl.GLSurfaceView; import android.util.Log; import com.panda3ds.pandroid.AlberDriver; +import com.panda3ds.pandroid.data.config.GlobalConfig; import com.panda3ds.pandroid.utils.Constants; import com.panda3ds.pandroid.utils.GameUtils; +import com.panda3ds.pandroid.utils.PerformanceMonitor; import com.panda3ds.pandroid.view.renderer.ConsoleRenderer; import com.panda3ds.pandroid.view.renderer.layout.ConsoleLayout; import com.panda3ds.pandroid.view.renderer.layout.DefaultScreenLayout; @@ -38,9 +40,12 @@ protected void finalize() throws Throwable { if (screenTexture != 0) { glDeleteTextures(1, new int[] {screenTexture}, 0); } - if (screenFbo != 0) { + + if (screenFbo != 0) { glDeleteFramebuffers(1, new int[] {screenFbo}, 0); } + + PerformanceMonitor.destroy(); super.finalize(); } @@ -78,6 +83,7 @@ public void onSurfaceCreated(GL10 unused, EGLConfig config) { glBindFramebuffer(GL_FRAMEBUFFER, 0); AlberDriver.Initialize(); + AlberDriver.setShaderJitEnabled(GlobalConfig.get(GlobalConfig.KEY_SHADER_JIT)); AlberDriver.LoadRom(romPath); // Load the SMDH @@ -92,6 +98,8 @@ public void onSurfaceCreated(GL10 unused, EGLConfig config) { GameUtils.removeGame(game); GameUtils.addGame(GameMetadata.applySMDH(game, smdh)); } + + PerformanceMonitor.initialize(getBackendName()); } public void onDrawFrame(GL10 unused) { @@ -114,6 +122,8 @@ public void onDrawFrame(GL10 unused) { screenHeight - bottomScreen.bottom, GL_COLOR_BUFFER_BIT, GL_LINEAR ); } + + PerformanceMonitor.runFrame(); } public void onSurfaceChanged(GL10 unused, int width, int height) { diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/utils/PerformanceView.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/utils/PerformanceView.java new file mode 100644 index 000000000..e4d7be153 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/utils/PerformanceView.java @@ -0,0 +1,64 @@ +package com.panda3ds.pandroid.view.utils; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.text.Html; +import android.util.AttributeSet; +import android.util.TypedValue; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatTextView; + +import com.panda3ds.pandroid.data.config.GlobalConfig; +import com.panda3ds.pandroid.utils.PerformanceMonitor; + +public class PerformanceView extends AppCompatTextView { + private boolean running = false; + + public PerformanceView(@NonNull Context context) { + this(context, null); + } + + public PerformanceView(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs,0); + } + + public PerformanceView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()); + setPadding(padding,padding,padding,padding); + setTextColor(Color.WHITE); + setShadowLayer(padding,0,0,Color.BLACK); + } + + public void refresh(){ + running = isShown(); + if (!running) { + return; + } + + String debug = ""; + + // Calculate total memory in MB and the current memory usage + int memoryTotalMb = (int) Math.round(PerformanceMonitor.getTotalMemory() / (1024.0 * 1024.0)); + int memoryUsageMb = (int) Math.round(PerformanceMonitor.getUsedMemory() / (1024.0 * 1024.0)); + + debug += "FPS: " + PerformanceMonitor.getFps() + "
"; + debug += "RAM: " + Math.round(((float) memoryUsageMb / memoryTotalMb) * 100) + "% (" + memoryUsageMb + "MB/" + memoryTotalMb + "MB)
"; + debug += "BACKEND: " + PerformanceMonitor.getBackend() + (GlobalConfig.get(GlobalConfig.KEY_SHADER_JIT) ? " + JIT" : "") + "
"; + setText(Html.fromHtml(debug, Html.FROM_HTML_MODE_COMPACT)); + postDelayed(this::refresh, 250); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (!running) { + refresh(); + } + } +} diff --git a/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml b/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml index 065b9e4f0..1198d66b8 100644 --- a/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml @@ -45,4 +45,13 @@ Abrir arquivo Criar novo Executando \"%s\" ... - \ No newline at end of file + Opções de desenvolvedor + Depuração, mostrar fps, etc. + Monitor de desempenho + Mostrar um overlay com fps, memoria, etc. + Depuração + Grave os registros para um arquivo. + Shader Jit + Usar recompilador de shaders. + Gráficos + diff --git a/src/pandroid/app/src/main/res/values/strings.xml b/src/pandroid/app/src/main/res/values/strings.xml index e0de62e18..4c64439c2 100644 --- a/src/pandroid/app/src/main/res/values/strings.xml +++ b/src/pandroid/app/src/main/res/values/strings.xml @@ -46,4 +46,13 @@ Open file Create new Running \"%s\" ... + Developer options + Logger, FPS Counter, etc. + Performance monitor + Show overlay with fps, memory, etc. + Logger + Store application logs to file. + Shader JIT + Use shader recompiler. + Graphics diff --git a/src/pandroid/app/src/main/res/xml/developer_preferences.xml b/src/pandroid/app/src/main/res/xml/developer_preferences.xml new file mode 100644 index 000000000..96ce89065 --- /dev/null +++ b/src/pandroid/app/src/main/res/xml/developer_preferences.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/xml/start_preferences.xml b/src/pandroid/app/src/main/res/xml/start_preferences.xml index 878aa9206..5eeb1954f 100644 --- a/src/pandroid/app/src/main/res/xml/start_preferences.xml +++ b/src/pandroid/app/src/main/res/xml/start_preferences.xml @@ -23,4 +23,11 @@ app:summary="@string/pref_appearance_summary" app:layout="@layout/preference_start_item"/> + + \ No newline at end of file From 362b8e6621f7b604b6b1fb0d5f94eae5e253f21a Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:02:53 +0200 Subject: [PATCH 08/12] Update luv bindings to be disabled on Android --- CMakeLists.txt | 16 ++++++++-------- src/lua.cpp | 8 ++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f92382642..e25483126 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,11 +40,6 @@ option(ENABLE_LUAJIT "Enable scripting with the Lua programming language" ON) option(ENABLE_QT_GUI "Enable the Qt GUI. If not selected then the emulator uses a minimal SDL-based UI instead" OFF) option(BUILD_HYDRA_CORE "Build a Hydra core" OFF) -if(ENABLE_LUAJIT AND ANDROID) - message(STATUS "Enabled LuaJIT on Android build. Automatically disabling it until it works properly") - set(ENABLE_LUAJIT OFF) -endif() - include_directories(${PROJECT_SOURCE_DIR}/include/) include_directories(${PROJECT_SOURCE_DIR}/include/kernel) include_directories (${FMT_INCLUDE_DIR}) @@ -271,8 +266,8 @@ set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp third_party/xxhash/xxhash.c ) -if(ENABLE_LUAJIT) - # Build luv and libuv for TCP Lua server usage +if(ENABLE_LUAJIT AND NOT ANDROID) + # Build luv and libuv for Lua TCP server usage if we're not on Android include_directories(third_party/luv/src) include_directories(third_party/luv/deps/lua-compat-5.3/c-api) include_directories(third_party/libuv/include) @@ -446,7 +441,12 @@ endif() if(ENABLE_LUAJIT) target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_LUA=1") - target_link_libraries(Alber PRIVATE libluajit uv_a) + target_link_libraries(Alber PRIVATE libluajit) + + # If we're not on Android, link libuv too + if (NOT ANDROID) + target_link_libraries(Alber PRIVATE uv_a) + endif() endif() if(ENABLE_OPENGL) diff --git a/src/lua.cpp b/src/lua.cpp index ccfe955d0..09c631735 100644 --- a/src/lua.cpp +++ b/src/lua.cpp @@ -1,9 +1,11 @@ #ifdef PANDA3DS_ENABLE_LUA #include "lua_manager.hpp" +#ifndef __ANDROID__ extern "C" { #include "luv.h" } +#endif void LuaManager::initialize() { L = luaL_newstate(); // Open Lua @@ -13,13 +15,15 @@ void LuaManager::initialize() { initialized = false; return; } - luaL_openlibs(L); + +#ifndef __ANDROID__ lua_pushstring(L, "luv"); luaopen_luv(L); lua_settable(L, LUA_GLOBALSINDEX); - initializeThunks(); +#endif + initializeThunks(); initialized = true; haveScript = false; } From ce63596716a723f7aba8e0f38e3caecd234a9f3b Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:42:04 +0200 Subject: [PATCH 09/12] Do not build libuv shared library --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e25483126..456d6513a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,6 +272,7 @@ if(ENABLE_LUAJIT AND NOT ANDROID) include_directories(third_party/luv/deps/lua-compat-5.3/c-api) include_directories(third_party/libuv/include) set(THIRD_PARTY_SOURCE_FILES ${THIRD_PARTY_SOURCE_FILES} third_party/luv/src/luv.c) + set(LIBUV_BUILD_SHARED OFF) add_subdirectory(third_party/libuv) endif() From 74ea66efc580e7d957489dda366d450b5cc26afb Mon Sep 17 00:00:00 2001 From: Gabriel Machado <97042217+GabrielBRDeveloper@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:11:59 -0400 Subject: [PATCH 10/12] Pandroid: Fix Navigation bar. (#398) * fix navbar transparent * too mutch fixes - Fix Ui Render in android 7. - Fix Navigation bar in android 7 - Rename developer option to advanced option. - Fix crash because setTitle in action bar - New style for switch button * bonk --------- Co-authored-by: gabriel --- .../panda3ds/pandroid/app/GameActivity.java | 4 ++ .../app/base/BasePreferenceFragment.java | 6 ++- .../pandroid/app/main/SettingsFragment.java | 4 +- ...ferences.java => AdvancedPreferences.java} | 6 +-- .../preferences/AppearancePreferences.java | 2 +- .../ControllerMapperPreferences.java | 4 +- .../app/preferences/InputMapPreferences.java | 2 +- .../src/main/res/drawable/color_surface.xml | 8 ++++ .../src/main/res/drawable/switch_thumb.xml | 37 +++++++++++++++++++ .../src/main/res/drawable/switch_track.xml | 19 ++++++++++ .../main/res/layout-land/activity_main.xml | 6 ++- .../main/res/layout/activity_input_map.xml | 3 +- .../app/src/main/res/layout/activity_main.xml | 6 ++- .../main/res/layout/activity_preference.xml | 3 +- .../src/main/res/layout/fragment_search.xml | 8 ++-- .../src/main/res/values-pt-rBR/strings.xml | 4 +- .../app/src/main/res/values-v27/themes.xml | 16 ++++++++ .../app/src/main/res/values-v29/themes.xml | 7 ++++ .../app/src/main/res/values/strings.xml | 4 +- .../app/src/main/res/values/themes.xml | 32 ++++++++++------ ...eferences.xml => advanced_preferences.xml} | 1 + .../src/main/res/xml/start_preferences.xml | 6 +-- 22 files changed, 150 insertions(+), 38 deletions(-) rename src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/{DeveloperPreferences.java => AdvancedPreferences.java} (90%) create mode 100644 src/pandroid/app/src/main/res/drawable/color_surface.xml create mode 100644 src/pandroid/app/src/main/res/drawable/switch_thumb.xml create mode 100644 src/pandroid/app/src/main/res/drawable/switch_track.xml create mode 100644 src/pandroid/app/src/main/res/values-v27/themes.xml create mode 100644 src/pandroid/app/src/main/res/values-v29/themes.xml rename src/pandroid/app/src/main/res/xml/{developer_preferences.xml => advanced_preferences.xml} (96%) diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java index f7050e99c..946ef8834 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/GameActivity.java @@ -1,6 +1,7 @@ package com.panda3ds.pandroid.app; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; @@ -72,6 +73,9 @@ protected void onResume() { InputHandler.reset(); InputHandler.setMotionDeadZone(InputMap.getDeadZone()); InputHandler.setEventListener(inputListener); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + getTheme().applyStyle(R.style.GameActivityNavigationBar, true); + } } @Override diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java index 9482df1df..4f5c57614 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BasePreferenceFragment.java @@ -3,6 +3,7 @@ import android.annotation.SuppressLint; import androidx.annotation.StringRes; +import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -22,6 +23,9 @@ protected void setItemClick(String key, Function listener) { } protected void setActivityTitle(@StringRes int titleId) { - ((AppCompatActivity) requireActivity()).getSupportActionBar().setTitle(titleId); + ActionBar header = ((AppCompatActivity) requireActivity()).getSupportActionBar(); + if (header != null) { + header.setTitle(titleId); + } } } diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java index bfe33a2be..4ac73661d 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/main/SettingsFragment.java @@ -8,7 +8,7 @@ import com.panda3ds.pandroid.app.PreferenceActivity; import com.panda3ds.pandroid.app.base.BasePreferenceFragment; import com.panda3ds.pandroid.app.preferences.AppearancePreferences; -import com.panda3ds.pandroid.app.preferences.DeveloperPreferences; +import com.panda3ds.pandroid.app.preferences.AdvancedPreferences; import com.panda3ds.pandroid.app.preferences.InputPreferences; public class SettingsFragment extends BasePreferenceFragment { @@ -17,6 +17,6 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S setPreferencesFromResource(R.xml.start_preferences, rootKey); setItemClick("input", (item) -> PreferenceActivity.launch(requireContext(), InputPreferences.class)); setItemClick("appearance", (item)-> PreferenceActivity.launch(requireContext(), AppearancePreferences.class)); - setItemClick("developer", (item)-> PreferenceActivity.launch(requireContext(), DeveloperPreferences.class)); + setItemClick("advanced", (item)-> PreferenceActivity.launch(requireContext(), AdvancedPreferences.class)); } } diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AdvancedPreferences.java similarity index 90% rename from src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java rename to src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AdvancedPreferences.java index f131f0a09..fea8aef0f 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/DeveloperPreferences.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AdvancedPreferences.java @@ -13,11 +13,11 @@ import com.panda3ds.pandroid.app.services.LoggerService; import com.panda3ds.pandroid.data.config.GlobalConfig; -public class DeveloperPreferences extends BasePreferenceFragment { +public class AdvancedPreferences extends BasePreferenceFragment { @Override public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { - setPreferencesFromResource(R.xml.developer_preferences, rootKey); - setActivityTitle(R.string.developer_options); + setPreferencesFromResource(R.xml.advanced_preferences, rootKey); + setActivityTitle(R.string.advanced_options); setItemClick("performanceMonitor", pref -> GlobalConfig.set(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY, ((SwitchPreference) pref).isChecked())); setItemClick("shaderJit", pref -> GlobalConfig.set(GlobalConfig.KEY_SHADER_JIT, ((SwitchPreference) pref).isChecked())); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AppearancePreferences.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AppearancePreferences.java index dea4e2613..04c89d9a0 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AppearancePreferences.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/AppearancePreferences.java @@ -15,7 +15,7 @@ public class AppearancePreferences extends BasePreferenceFragment { public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { setPreferencesFromResource(R.xml.appearance_preference, rootKey); - ((BaseActivity) requireActivity()).getSupportActionBar().setTitle(R.string.appearance); + setActivityTitle(R.string.appearance); SingleSelectionPreferences themePreference = findPreference("theme"); themePreference.setSelectedItem(GlobalConfig.get(GlobalConfig.KEY_APP_THEME)); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/ControllerMapperPreferences.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/ControllerMapperPreferences.java index e59adfbea..f643c88f6 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/ControllerMapperPreferences.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/ControllerMapperPreferences.java @@ -37,7 +37,9 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat currentProfile = ControllerProfileManager.get(getArguments().getString("profile")).clone(); - ((BaseActivity) requireActivity()).getSupportActionBar().hide(); + if (((BaseActivity)requireActivity()).getSupportActionBar() != null) { + ((BaseActivity) requireActivity()).getSupportActionBar().hide(); + } mapper = view.findViewById(R.id.mapper); mapper.initialize(this::onLocationChanged, currentProfile); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/InputMapPreferences.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/InputMapPreferences.java index b4d148b9f..10fa10f95 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/InputMapPreferences.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/preferences/InputMapPreferences.java @@ -27,7 +27,7 @@ public class InputMapPreferences extends BasePreferenceFragment implements Activ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { setPreferencesFromResource(R.xml.input_map_preferences, rootKey); - ((BaseActivity) requireActivity()).getSupportActionBar().setTitle(R.string.controller_mapping); + setActivityTitle(R.string.controller_mapping); for (KeyName key : KeyName.values()) { if (key == KeyName.NULL) { diff --git a/src/pandroid/app/src/main/res/drawable/color_surface.xml b/src/pandroid/app/src/main/res/drawable/color_surface.xml new file mode 100644 index 000000000..b8655b87c --- /dev/null +++ b/src/pandroid/app/src/main/res/drawable/color_surface.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/drawable/switch_thumb.xml b/src/pandroid/app/src/main/res/drawable/switch_thumb.xml new file mode 100644 index 000000000..02f1ab021 --- /dev/null +++ b/src/pandroid/app/src/main/res/drawable/switch_thumb.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/drawable/switch_track.xml b/src/pandroid/app/src/main/res/drawable/switch_track.xml new file mode 100644 index 000000000..b665789c6 --- /dev/null +++ b/src/pandroid/app/src/main/res/drawable/switch_track.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/layout-land/activity_main.xml b/src/pandroid/app/src/main/res/layout-land/activity_main.xml index fa4cfbca4..9741809da 100644 --- a/src/pandroid/app/src/main/res/layout-land/activity_main.xml +++ b/src/pandroid/app/src/main/res/layout-land/activity_main.xml @@ -5,7 +5,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".app.MainActivity"> + tools:context=".app.MainActivity" + android:background="?colorSurface"> + style="@style/ThemedNavigationBottom" + android:background="@drawable/color_surface"/> \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/layout/activity_input_map.xml b/src/pandroid/app/src/main/res/layout/activity_input_map.xml index cbacc64e1..79249e62e 100644 --- a/src/pandroid/app/src/main/res/layout/activity_input_map.xml +++ b/src/pandroid/app/src/main/res/layout/activity_input_map.xml @@ -4,7 +4,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:gravity="center"> + android:gravity="center" + android:background="?colorSurface"> + tools:context=".app.MainActivity" + android:background="?colorSurface"> + style="@style/ThemedNavigationBottom" + android:background="@drawable/color_surface"/> \ No newline at end of file diff --git a/src/pandroid/app/src/main/res/layout/activity_preference.xml b/src/pandroid/app/src/main/res/layout/activity_preference.xml index 54b3d364b..401c3d862 100644 --- a/src/pandroid/app/src/main/res/layout/activity_preference.xml +++ b/src/pandroid/app/src/main/res/layout/activity_preference.xml @@ -3,7 +3,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - android:orientation="vertical"> + android:orientation="vertical" + android:background="?colorSurface"> + android:layout_height="match_parent"> + android:layout_height="match_parent" + android:paddingStart="15dp" + android:paddingEnd="15dp"/> diff --git a/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml b/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml index 1198d66b8..eeeb842bf 100644 --- a/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/pandroid/app/src/main/res/values-pt-rBR/strings.xml @@ -45,8 +45,8 @@ Abrir arquivo Criar novo Executando \"%s\" ... - Opções de desenvolvedor - Depuração, mostrar fps, etc. + Opções avançada. + Depuração, mostrar fps, etc. Monitor de desempenho Mostrar um overlay com fps, memoria, etc. Depuração diff --git a/src/pandroid/app/src/main/res/values-v27/themes.xml b/src/pandroid/app/src/main/res/values-v27/themes.xml new file mode 100644 index 000000000..8e960864d --- /dev/null +++ b/src/pandroid/app/src/main/res/values-v27/themes.xml @@ -0,0 +1,16 @@ + + + + + + + + - + diff --git a/src/pandroid/app/src/main/res/xml/developer_preferences.xml b/src/pandroid/app/src/main/res/xml/advanced_preferences.xml similarity index 96% rename from src/pandroid/app/src/main/res/xml/developer_preferences.xml rename to src/pandroid/app/src/main/res/xml/advanced_preferences.xml index 96ce89065..ce77a6e49 100644 --- a/src/pandroid/app/src/main/res/xml/developer_preferences.xml +++ b/src/pandroid/app/src/main/res/xml/advanced_preferences.xml @@ -12,6 +12,7 @@ android:key="loggerService" app:iconSpaceReserved="false" app:title="@string/pref_logger_service_title" + app:defaultValue="true" android:summary="@string/pref_logger_service_summary"/> \ No newline at end of file From b256c89e23b663800dbba4c5cf05545813650a93 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:14:43 +0200 Subject: [PATCH 11/12] [APT] Make logs slightly less cluttered for better debugging --- src/core/services/apt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp index 404a0e590..ddeb18de4 100644 --- a/src/core/services/apt.cpp +++ b/src/core/services/apt.cpp @@ -84,7 +84,7 @@ void APTService::appletUtility(u32 messagePointer) { u32 outputSize = mem.read32(messagePointer + 12); u32 inputPointer = mem.read32(messagePointer + 20); - log("APT::AppletUtility(utility = %d, input size = %x, output size = %x, inputPointer = %08X) (Stubbed)\n", utility, inputSize, outputSize, + log("APT::AppletUtility(utility = %d, input size = %x, output size = %x, inputPointer = %08X)\n", utility, inputSize, outputSize, inputPointer); std::vector out(outputSize); @@ -218,7 +218,7 @@ void APTService::initialize(u32 messagePointer) { } void APTService::inquireNotification(u32 messagePointer) { - log("APT::InquireNotification (STUBBED TO RETURN NONE)\n"); + log("APT::InquireNotification\n"); mem.write32(messagePointer, IPC::responseHeader(0xB, 2, 0)); mem.write32(messagePointer + 4, Result::Success); From b6816195f1ac7c3ca96f44ee7946cf5a67cd33ce Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:22:52 +0530 Subject: [PATCH 12/12] test --- .github/workflows/Android_Build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml index 137577c18..2fc754eaf 100644 --- a/.github/workflows/Android_Build.yml +++ b/.github/workflows/Android_Build.yml @@ -19,6 +19,16 @@ jobs: - name: Set BUILD_TYPE variable run: echo "BUILD_TYPE=${{ matrix.build_type }}" >> $GITHUB_ENV + - name: Restore Gradle Cache + uses: actions/cache@v3 + with: + path: ~/.gradle/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }} + restore-keys: | + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}- + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}- + ${{ runner.os }}-gradle- + - uses: actions/checkout@v2 - name: Fetch submodules run: git submodule update --init --recursive