From aa4e494c08075f5d048e8e3d6e0f7426d88d0f0a Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 2 Sep 2026 00:29:58 +0200 Subject: [android] Replace Oboe audio with SDL3 audio (#4338) Supersedes #4335. Replaces the Oboe audio backend with SDL3, since we already support it. A few caveats: - SDL defines a JVM OnLoad method already, so we have to instead hijack NativeLibrary for id_cache initialization - This also means some internal fields in Double/Integer/Boolean (namely `value`) can't be accessed, so I switched those to methods for now. - SDL Java sources are pulled in from the CI package. - Since we can't use SDLActivity, `SDL.setupJNI()` handles everything Signed-off-by: crueter - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4338 Reviewed-by: Lizzie and Samuel Reviewed-by: MaranBr --- src/common/android/android_common.cpp | 8 +- src/common/android/id_cache.cpp | 380 +++++++++++++++++----------------- src/common/android/id_cache.h | 7 +- src/common/settings_enums.h | 6 +- 4 files changed, 199 insertions(+), 202 deletions(-) (limited to 'src/common') diff --git a/src/common/android/android_common.cpp b/src/common/android/android_common.cpp index a1cf081695..5041579e0e 100644 --- a/src/common/android/android_common.cpp +++ b/src/common/android/android_common.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include "android_common.h" @@ -51,7 +51,7 @@ jstring ToJString(JNIEnv* env, std::u16string_view str) { } double GetJDouble(JNIEnv* env, jobject jdouble) { - return env->GetDoubleField(jdouble, GetDoubleValueField()); + return env->CallDoubleMethod(jdouble, GetDoubleValueMethod()); } jobject ToJDouble(JNIEnv* env, double value) { @@ -59,7 +59,7 @@ jobject ToJDouble(JNIEnv* env, double value) { } s32 GetJInteger(JNIEnv* env, jobject jinteger) { - return env->GetIntField(jinteger, GetIntegerValueField()); + return env->CallIntMethod(jinteger, GetIntegerValueMethod()); } jobject ToJInteger(JNIEnv* env, s32 value) { @@ -67,7 +67,7 @@ jobject ToJInteger(JNIEnv* env, s32 value) { } bool GetJBoolean(JNIEnv* env, jobject jboolean) { - return env->GetBooleanField(jboolean, GetBooleanValueField()); + return env->CallBooleanMethod(jboolean, GetBooleanValueMethod()); } jobject ToJBoolean(JNIEnv* env, bool value) { diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp index 0fb358f6e4..3da532703a 100644 --- a/src/common/android/id_cache.cpp +++ b/src/common/android/id_cache.cpp @@ -63,15 +63,15 @@ static jfieldID s_patch_title_id_field; static jclass s_double_class; static jmethodID s_double_constructor; -static jfieldID s_double_value_field; +static jmethodID s_double_value_method; static jclass s_integer_class; static jmethodID s_integer_constructor; -static jfieldID s_integer_value_field; +static jmethodID s_integer_value_method; static jclass s_boolean_class; static jmethodID s_boolean_constructor; -static jfieldID s_boolean_value_field; +static jmethodID s_boolean_value_method; static jclass s_player_input_class; static jmethodID s_player_input_constructor; @@ -103,7 +103,6 @@ static jmethodID s_clear_chat; static constexpr jint JNI_VERSION = JNI_VERSION_1_6; namespace Common::Android { - JNIEnv *GetEnvForThread() { thread_local static struct OwnedEnv { OwnedEnv() { @@ -299,8 +298,8 @@ namespace Common::Android { return s_double_constructor; } - jfieldID GetDoubleValueField() { - return s_double_value_field; + jmethodID GetDoubleValueMethod() { + return s_double_value_method; } jclass GetIntegerClass() { @@ -311,8 +310,8 @@ namespace Common::Android { return s_integer_constructor; } - jfieldID GetIntegerValueField() { - return s_integer_value_field; + jmethodID GetIntegerValueMethod() { + return s_integer_value_method; } jclass GetBooleanClass() { @@ -323,8 +322,8 @@ namespace Common::Android { return s_boolean_constructor; } - jfieldID GetBooleanValueField() { - return s_boolean_value_field; + jmethodID GetBooleanValueMethod() { + return s_boolean_value_method; } jclass GetPlayerInputClass() { @@ -429,188 +428,6 @@ namespace Common::Android { jint InitFFmpegOnLoad(JavaVM *vm); - jint JNI_OnLoad(JavaVM *vm, void *reserved) { - s_java_vm = vm; - InitFFmpegOnLoad(vm); - - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) - return JNI_ERR; - - // Initialize Java classes - const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); - s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class)); - s_disk_cache_progress_class = reinterpret_cast(env->NewGlobalRef( - env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress"))); - s_load_callback_stage_class = reinterpret_cast(env->NewGlobalRef(env->FindClass( - "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage"))); - - const jclass game_dir_class = env->FindClass("org/yuzu/yuzu_emu/model/GameDir"); - s_game_dir_class = reinterpret_cast(env->NewGlobalRef(game_dir_class)); - s_game_dir_constructor = env->GetMethodID(game_dir_class, "", - "(Ljava/lang/String;Z)V"); - env->DeleteLocalRef(game_dir_class); - - // Initialize methods - s_exit_emulation_activity = - env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); - s_disk_cache_load_progress = - env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V"); - s_copy_to_storage = env->GetStaticMethodID(s_native_library_class, "copyFileToStorage", - "(Ljava/lang/String;Ljava/lang/String;)Z"); - s_file_exists = env->GetStaticMethodID(s_native_library_class, "exists", - "(Ljava/lang/String;)Z"); - s_file_extension = env->GetStaticMethodID(s_native_library_class, "getFileExtension", - "(Ljava/lang/String;)Ljava/lang/String;"); - s_on_emulation_started = - env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); - s_on_emulation_stopped = - env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); - s_on_program_changed = - env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V"); - - const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); - s_game_class = reinterpret_cast(env->NewGlobalRef(game_class)); - s_game_constructor = env->GetMethodID(game_class, "", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" - "String;Ljava/lang/String;Ljava/lang/String;Z)V"); - s_game_title_field = env->GetFieldID(game_class, "title", "Ljava/lang/String;"); - s_game_path_field = env->GetFieldID(game_class, "path", "Ljava/lang/String;"); - s_game_program_id_field = env->GetFieldID(game_class, "programId", "Ljava/lang/String;"); - s_game_developer_field = env->GetFieldID(game_class, "developer", "Ljava/lang/String;"); - s_game_version_field = env->GetFieldID(game_class, "version", "Ljava/lang/String;"); - s_game_is_homebrew_field = env->GetFieldID(game_class, "isHomebrew", "Z"); - env->DeleteLocalRef(game_class); - - const jclass string_class = env->FindClass("java/lang/String"); - s_string_class = reinterpret_cast(env->NewGlobalRef(string_class)); - env->DeleteLocalRef(string_class); - - const jclass pair_class = env->FindClass("kotlin/Pair"); - s_pair_class = reinterpret_cast(env->NewGlobalRef(pair_class)); - s_pair_constructor = - env->GetMethodID(pair_class, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); - s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;"); - s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;"); - env->DeleteLocalRef(pair_class); - - const jclass overlay_control_data_class = - env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData"); - s_overlay_control_data_class = - reinterpret_cast(env->NewGlobalRef(overlay_control_data_class)); - s_overlay_control_data_constructor = - env->GetMethodID(overlay_control_data_class, "", - "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;F)V"); - s_overlay_control_data_id_field = - env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;"); - s_overlay_control_data_enabled_field = - env->GetFieldID(overlay_control_data_class, "enabled", "Z"); - s_overlay_control_data_landscape_position_field = - env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;"); - s_overlay_control_data_portrait_position_field = - env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;"); - s_overlay_control_data_foldable_position_field = - env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;"); - s_overlay_control_data_individual_scale_field = - env->GetFieldID(overlay_control_data_class, "individualScale", "F"); - env->DeleteLocalRef(overlay_control_data_class); - - const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch"); - s_patch_class = reinterpret_cast(env->NewGlobalRef(patch_class)); - s_patch_constructor = env->GetMethodID( - patch_class, "", - "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;JI)V"); - s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z"); - s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;"); - s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;"); - s_patch_type_field = env->GetFieldID(patch_class, "type", "I"); - s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;"); - s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;"); - env->DeleteLocalRef(patch_class); - - const jclass double_class = env->FindClass("java/lang/Double"); - s_double_class = reinterpret_cast(env->NewGlobalRef(double_class)); - s_double_constructor = env->GetMethodID(double_class, "", "(D)V"); - s_double_value_field = env->GetFieldID(double_class, "value", "D"); - env->DeleteLocalRef(double_class); - - const jclass int_class = env->FindClass("java/lang/Integer"); - s_integer_class = reinterpret_cast(env->NewGlobalRef(int_class)); - s_integer_constructor = env->GetMethodID(int_class, "", "(I)V"); - s_integer_value_field = env->GetFieldID(int_class, "value", "I"); - env->DeleteLocalRef(int_class); - - const jclass boolean_class = env->FindClass("java/lang/Boolean"); - s_boolean_class = reinterpret_cast(env->NewGlobalRef(boolean_class)); - s_boolean_constructor = env->GetMethodID(boolean_class, "", "(Z)V"); - s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z"); - env->DeleteLocalRef(boolean_class); - - const jclass player_input_class = - env->FindClass("org/yuzu/yuzu_emu/features/input/model/PlayerInput"); - s_player_input_class = reinterpret_cast(env->NewGlobalRef(player_input_class)); - s_player_input_constructor = env->GetMethodID( - player_input_class, "", - "(Z[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZIJJJJLjava/lang/String;Z)V"); - s_player_input_connected_field = env->GetFieldID(player_input_class, "connected", "Z"); - s_player_input_buttons_field = - env->GetFieldID(player_input_class, "buttons", "[Ljava/lang/String;"); - s_player_input_analogs_field = - env->GetFieldID(player_input_class, "analogs", "[Ljava/lang/String;"); - s_player_input_motions_field = - env->GetFieldID(player_input_class, "motions", "[Ljava/lang/String;"); - s_player_input_vibration_enabled_field = - env->GetFieldID(player_input_class, "vibrationEnabled", "Z"); - s_player_input_vibration_strength_field = - env->GetFieldID(player_input_class, "vibrationStrength", "I"); - s_player_input_body_color_left_field = - env->GetFieldID(player_input_class, "bodyColorLeft", "J"); - s_player_input_body_color_right_field = - env->GetFieldID(player_input_class, "bodyColorRight", "J"); - s_player_input_button_color_left_field = - env->GetFieldID(player_input_class, "buttonColorLeft", "J"); - s_player_input_button_color_right_field = - env->GetFieldID(player_input_class, "buttonColorRight", "J"); - s_player_input_profile_name_field = - env->GetFieldID(player_input_class, "profileName", "Ljava/lang/String;"); - s_player_input_use_system_vibrator_field = - env->GetFieldID(player_input_class, "useSystemVibrator", "Z"); - env->DeleteLocalRef(player_input_class); - - const jclass yuzu_input_device_interface = - env->FindClass("org/yuzu/yuzu_emu/features/input/YuzuInputDevice"); - s_yuzu_input_device_interface = - reinterpret_cast(env->NewGlobalRef(yuzu_input_device_interface)); - s_yuzu_input_device_get_name = - env->GetMethodID(yuzu_input_device_interface, "getName", "()Ljava/lang/String;"); - s_yuzu_input_device_get_guid = - env->GetMethodID(yuzu_input_device_interface, "getGUID", "()Ljava/lang/String;"); - s_yuzu_input_device_get_port = env->GetMethodID(yuzu_input_device_interface, "getPort", - "()I"); - s_yuzu_input_device_get_supports_vibration = - env->GetMethodID(yuzu_input_device_interface, "getSupportsVibration", "()Z"); - s_yuzu_input_device_vibrate = env->GetMethodID(yuzu_input_device_interface, "vibrate", - "(F)V"); - s_yuzu_input_device_get_axes = - env->GetMethodID(yuzu_input_device_interface, "getAxes", "()[Ljava/lang/Integer;"); - s_yuzu_input_device_has_keys = - env->GetMethodID(yuzu_input_device_interface, "hasKeys", "([I)[Z"); - env->DeleteLocalRef(yuzu_input_device_interface); - s_add_netplay_message = env->GetStaticMethodID(s_native_library_class, "addNetPlayMessage", - "(ILjava/lang/String;)V"); - s_clear_chat = env->GetStaticMethodID(s_native_library_class, "clearChat", "()V"); - - - // Initialize Android Storage - Common::FS::Android::RegisterCallbacks(env, s_native_library_class); - - // Initialize applets - Common::Android::SoftwareKeyboard::InitJNI(env); - Common::Android::WebBrowser::InitJNI(env); - - return JNI_VERSION; - } - void JNI_OnUnload(JavaVM *vm, void *reserved) { JNIEnv *env; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) { @@ -645,4 +462,183 @@ namespace Common::Android { } #endif +void Initialize(JavaVM* vm, JNIEnv *env) { + s_java_vm = vm; + InitFFmpegOnLoad(vm); + + if (env->ExceptionCheck()) { + env->ExceptionClear(); + } + + // Initialize Java classes + const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); + s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class)); + s_disk_cache_progress_class = reinterpret_cast(env->NewGlobalRef( + env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress"))); + s_load_callback_stage_class = reinterpret_cast(env->NewGlobalRef(env->FindClass( + "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage"))); + + const jclass game_dir_class = env->FindClass("org/yuzu/yuzu_emu/model/GameDir"); + s_game_dir_class = reinterpret_cast(env->NewGlobalRef(game_dir_class)); + s_game_dir_constructor = env->GetMethodID(game_dir_class, "", + "(Ljava/lang/String;Z)V"); + env->DeleteLocalRef(game_dir_class); + + // Initialize methods + s_exit_emulation_activity = + env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); + s_disk_cache_load_progress = + env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V"); + s_copy_to_storage = env->GetStaticMethodID(s_native_library_class, "copyFileToStorage", + "(Ljava/lang/String;Ljava/lang/String;)Z"); + s_file_exists = env->GetStaticMethodID(s_native_library_class, "exists", + "(Ljava/lang/String;)Z"); + s_file_extension = env->GetStaticMethodID(s_native_library_class, "getFileExtension", + "(Ljava/lang/String;)Ljava/lang/String;"); + s_on_emulation_started = + env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); + s_on_emulation_stopped = + env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); + s_on_program_changed = + env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V"); + + const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); + s_game_class = reinterpret_cast(env->NewGlobalRef(game_class)); + s_game_constructor = env->GetMethodID(game_class, "", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" + "String;Ljava/lang/String;Ljava/lang/String;Z)V"); + s_game_title_field = env->GetFieldID(game_class, "title", "Ljava/lang/String;"); + s_game_path_field = env->GetFieldID(game_class, "path", "Ljava/lang/String;"); + s_game_program_id_field = env->GetFieldID(game_class, "programId", "Ljava/lang/String;"); + s_game_developer_field = env->GetFieldID(game_class, "developer", "Ljava/lang/String;"); + s_game_version_field = env->GetFieldID(game_class, "version", "Ljava/lang/String;"); + s_game_is_homebrew_field = env->GetFieldID(game_class, "isHomebrew", "Z"); + env->DeleteLocalRef(game_class); + + const jclass string_class = env->FindClass("java/lang/String"); + s_string_class = reinterpret_cast(env->NewGlobalRef(string_class)); + env->DeleteLocalRef(string_class); + + const jclass pair_class = env->FindClass("kotlin/Pair"); + s_pair_class = reinterpret_cast(env->NewGlobalRef(pair_class)); + s_pair_constructor = + env->GetMethodID(pair_class, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;"); + s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;"); + env->DeleteLocalRef(pair_class); + + const jclass overlay_control_data_class = + env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData"); + s_overlay_control_data_class = + reinterpret_cast(env->NewGlobalRef(overlay_control_data_class)); + s_overlay_control_data_constructor = + env->GetMethodID(overlay_control_data_class, "", + "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;F)V"); + s_overlay_control_data_id_field = + env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;"); + s_overlay_control_data_enabled_field = + env->GetFieldID(overlay_control_data_class, "enabled", "Z"); + s_overlay_control_data_landscape_position_field = + env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;"); + s_overlay_control_data_portrait_position_field = + env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;"); + s_overlay_control_data_foldable_position_field = + env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;"); + s_overlay_control_data_individual_scale_field = + env->GetFieldID(overlay_control_data_class, "individualScale", "F"); + env->DeleteLocalRef(overlay_control_data_class); + + const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch"); + s_patch_class = reinterpret_cast(env->NewGlobalRef(patch_class)); + s_patch_constructor = env->GetMethodID( + patch_class, "", + "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;JI)V"); + s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z"); + s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;"); + s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;"); + s_patch_type_field = env->GetFieldID(patch_class, "type", "I"); + s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;"); + s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;"); + env->DeleteLocalRef(patch_class); + + const jclass double_class = env->FindClass("java/lang/Double"); + s_double_class = reinterpret_cast(env->NewGlobalRef(double_class)); + s_double_constructor = env->GetMethodID(double_class, "", "(D)V"); + s_double_value_method = env->GetMethodID(double_class, "doubleValue", "()D"); + env->DeleteLocalRef(double_class); + + const jclass int_class = env->FindClass("java/lang/Integer"); + s_integer_class = reinterpret_cast(env->NewGlobalRef(int_class)); + s_integer_constructor = env->GetMethodID(int_class, "", "(I)V"); + s_integer_value_method = env->GetMethodID(int_class, "intValue", "()I"); + env->DeleteLocalRef(int_class); + + const jclass boolean_class = env->FindClass("java/lang/Boolean"); + s_boolean_class = reinterpret_cast(env->NewGlobalRef(boolean_class)); + s_boolean_constructor = env->GetMethodID(boolean_class, "", "(Z)V"); + s_boolean_value_method = env->GetMethodID(boolean_class, "booleanValue", "()Z"); + env->DeleteLocalRef(boolean_class); + + const jclass player_input_class = + env->FindClass("org/yuzu/yuzu_emu/features/input/model/PlayerInput"); + s_player_input_class = reinterpret_cast(env->NewGlobalRef(player_input_class)); + s_player_input_constructor = env->GetMethodID( + player_input_class, "", + "(Z[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZIJJJJLjava/lang/String;Z)V"); + s_player_input_connected_field = env->GetFieldID(player_input_class, "connected", "Z"); + s_player_input_buttons_field = + env->GetFieldID(player_input_class, "buttons", "[Ljava/lang/String;"); + s_player_input_analogs_field = + env->GetFieldID(player_input_class, "analogs", "[Ljava/lang/String;"); + s_player_input_motions_field = + env->GetFieldID(player_input_class, "motions", "[Ljava/lang/String;"); + s_player_input_vibration_enabled_field = + env->GetFieldID(player_input_class, "vibrationEnabled", "Z"); + s_player_input_vibration_strength_field = + env->GetFieldID(player_input_class, "vibrationStrength", "I"); + s_player_input_body_color_left_field = + env->GetFieldID(player_input_class, "bodyColorLeft", "J"); + s_player_input_body_color_right_field = + env->GetFieldID(player_input_class, "bodyColorRight", "J"); + s_player_input_button_color_left_field = + env->GetFieldID(player_input_class, "buttonColorLeft", "J"); + s_player_input_button_color_right_field = + env->GetFieldID(player_input_class, "buttonColorRight", "J"); + s_player_input_profile_name_field = + env->GetFieldID(player_input_class, "profileName", "Ljava/lang/String;"); + s_player_input_use_system_vibrator_field = + env->GetFieldID(player_input_class, "useSystemVibrator", "Z"); + env->DeleteLocalRef(player_input_class); + + const jclass yuzu_input_device_interface = + env->FindClass("org/yuzu/yuzu_emu/features/input/YuzuInputDevice"); + s_yuzu_input_device_interface = + reinterpret_cast(env->NewGlobalRef(yuzu_input_device_interface)); + s_yuzu_input_device_get_name = + env->GetMethodID(yuzu_input_device_interface, "getName", "()Ljava/lang/String;"); + s_yuzu_input_device_get_guid = + env->GetMethodID(yuzu_input_device_interface, "getGUID", "()Ljava/lang/String;"); + s_yuzu_input_device_get_port = env->GetMethodID(yuzu_input_device_interface, "getPort", + "()I"); + s_yuzu_input_device_get_supports_vibration = + env->GetMethodID(yuzu_input_device_interface, "getSupportsVibration", "()Z"); + s_yuzu_input_device_vibrate = env->GetMethodID(yuzu_input_device_interface, "vibrate", + "(F)V"); + s_yuzu_input_device_get_axes = + env->GetMethodID(yuzu_input_device_interface, "getAxes", "()[Ljava/lang/Integer;"); + s_yuzu_input_device_has_keys = + env->GetMethodID(yuzu_input_device_interface, "hasKeys", "([I)[Z"); + env->DeleteLocalRef(yuzu_input_device_interface); + s_add_netplay_message = env->GetStaticMethodID(s_native_library_class, "addNetPlayMessage", + "(ILjava/lang/String;)V"); + s_clear_chat = env->GetStaticMethodID(s_native_library_class, "clearChat", "()V"); + + // Initialize Android Storage + Common::FS::Android::RegisterCallbacks(env, s_native_library_class); + + // Initialize applets + Common::Android::SoftwareKeyboard::InitJNI(env); + Common::Android::WebBrowser::InitJNI(env); +} + } // namespace Common::Android diff --git a/src/common/android/id_cache.h b/src/common/android/id_cache.h index 6e47acb746..6da385d521 100644 --- a/src/common/android/id_cache.h +++ b/src/common/android/id_cache.h @@ -11,6 +11,7 @@ namespace Common::Android { +void Initialize(JavaVM* vm, JNIEnv *env); JNIEnv* GetEnvForThread(); /** @@ -80,15 +81,15 @@ jfieldID GetPatchTitleIdField(); jclass GetDoubleClass(); jmethodID GetDoubleConstructor(); -jfieldID GetDoubleValueField(); +jmethodID GetDoubleValueMethod(); jclass GetIntegerClass(); jmethodID GetIntegerConstructor(); -jfieldID GetIntegerValueField(); +jmethodID GetIntegerValueMethod(); jclass GetBooleanClass(); jmethodID GetBooleanConstructor(); -jfieldID GetBooleanValueField(); +jmethodID GetBooleanValueMethod(); jclass GetPlayerInputClass(); jmethodID GetPlayerInputConstructor(); diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index a43df6924c..4b406f4c35 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -92,14 +92,14 @@ struct EnumMetadata { // AudioEngine must be specified discretely due to having existing but slightly different // canonicalizations // TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id -enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, Oboe, }; +enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, }; template<> inline std::vector> EnumMetadata::Canonicalizations() { return { {"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl3", AudioEngine::Sdl3}, - {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe}, + {"null", AudioEngine::Null}, }; } /// @brief This is just a sufficiently large number that is more than the number of other enums declared here @@ -113,7 +113,7 @@ inline AudioEngine EnumMetadata::GetFirst() { } template<> inline AudioEngine EnumMetadata::GetLast() { - return AudioEngine::Oboe; + return AudioEngine::Null; } ENUM(AudioMode, Mono, Stereo, Surround); -- cgit v1.2.3