From 954c54baee7c0b8a91369b8d1e5b9903b180dcdc Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 12 Mar 2019 13:07:16 -0400 Subject: [PATCH] add device vibration option for cores that support rumble (with initial android implementation) --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + frontend/drivers/platform_unix.c | 2 +- input/drivers/android_input.c | 49 +++++++++++++++++-- intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 4 ++ menu/menu_displaylist.c | 3 ++ menu/menu_setting.c | 16 ++++++ msg_hash.h | 1 + .../retroactivity/RetroActivityCommon.java | 23 +++++++-- retroarch.cfg | 3 ++ 12 files changed, 96 insertions(+), 10 deletions(-) diff --git a/config.def.h b/config.def.h index cc8890caee..563ed9555d 100644 --- a/config.def.h +++ b/config.def.h @@ -821,6 +821,7 @@ static const unsigned midi_volume = 100; static const bool sustained_performance_mode = false; static const bool vibrate_on_keypress = false; +static const bool enable_device_vibration = false; #if defined(HAKCHI) static char buildbot_server_url[] = "http://hakchicloud.com/Libretro_Cores/"; diff --git a/configuration.c b/configuration.c index f9f7d9903e..8aecd689c3 100644 --- a/configuration.c +++ b/configuration.c @@ -1587,6 +1587,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, quit_press_twice, false); SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false); + SETTING_BOOL("enable_device_vibration", &settings->bools.enable_device_vibration, true, enable_device_vibration, false); #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, ozone_collapse_sidebar, false); diff --git a/configuration.h b/configuration.h index 62018ae0c8..f1ea2f6b3b 100644 --- a/configuration.h +++ b/configuration.h @@ -316,6 +316,7 @@ typedef struct settings bool quit_press_twice; bool vibrate_on_keypress; + bool enable_device_vibration; #ifdef HAVE_OZONE bool ozone_collapse_sidebar; #endif diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 6b7c5c17c7..dd1dc6c82a 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -2037,7 +2037,7 @@ static void frontend_unix_init(void *data) GET_METHOD_ID(env, android_app->setScreenOrientation, class, "setScreenOrientation", "(I)V"); GET_METHOD_ID(env, android_app->doVibrate, class, - "doVibrate", "()V"); + "doVibrate", "(III)V"); CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent); diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index a0079e4d5f..03d37de55e 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -425,9 +425,11 @@ static void android_input_poll_main_cmd(void) { JNIEnv *env = (JNIEnv*)jni_thread_getenv(); - if (env && g_android) - CALL_VOID_METHOD(env, g_android->activity->clazz, - g_android->doVibrate); + if (env && g_android && g_android->doVibrate) + { + CALL_VOID_METHOD_PARAM(env, g_android->activity->clazz, + g_android->doVibrate, RETRO_RUMBLE_STRONG, 255, 1); + } break; } } @@ -1630,10 +1632,47 @@ static void android_input_grab_mouse(void *data, bool state) static bool android_input_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength) { + settings_t *settings = config_get_ptr(); + (void)data; (void)port; - (void)effect; - (void)strength; + + if (settings->bools.enable_device_vibration) + { + JNIEnv *env = (JNIEnv*)jni_thread_getenv(); + struct android_app *android_app = (struct android_app*)g_android; + + if (env && g_android && g_android->doVibrate) + { + static uint16_t last_strength_strong = 0; + static uint16_t last_strength_weak = 0; + static uint16_t last_strength = 0; + uint16_t new_strength = 0; + + if (effect == RETRO_RUMBLE_STRONG) + { + new_strength = strength | last_strength_weak; + last_strength_strong = strength; + } + else if (effect == RETRO_RUMBLE_WEAK) + { + new_strength = strength | last_strength_strong; + last_strength_weak = strength; + } + + if (new_strength != last_strength) + { + /* trying to send this value as a JNI param without storing it first was causing 0 to be seen on the other side ?? */ + int strength_final = (255.0f / 65535.0f) * (float)new_strength; + + CALL_VOID_METHOD_PARAM(env, g_android->activity->clazz, + g_android->doVibrate, RETRO_RUMBLE_STRONG, strength_final, 0); + + last_strength = new_strength; + } + } + return true; + } return false; } diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index f6f9d58cc2..4ff5531de8 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1807,3 +1807,5 @@ MSG_HASH(MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO, "help_send_debug_info") MSG_HASH(MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS, "vibrate_on_keypress") +MSG_HASH(MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, + "enable_device_vibration") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index dfaaf03157..b459a7aef4 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -8450,3 +8450,7 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Vibrate on key press" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLE_DEVICE_VIBRATION, + "Enable device vibration (for supported cores)" + ) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 5f38841d74..6eef2af825 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7083,6 +7083,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS, PARSE_ONLY_BOOL, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, + PARSE_ONLY_BOOL, false); if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, PARSE_ONLY_UINT, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 476500d818..2bad35bb7d 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6959,6 +6959,22 @@ static bool setting_append_list( SD_FLAG_NONE ); + CONFIG_BOOL( + list, list_info, + &settings->bools.enable_device_vibration, + MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, + MENU_ENUM_LABEL_VALUE_ENABLE_DEVICE_VIBRATION, + enable_device_vibration, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + CONFIG_UINT( list, list_info, &settings->uints.input_poll_type_behavior, diff --git a/msg_hash.h b/msg_hash.h index d73ebc9a9e..25e7b53a64 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2312,6 +2312,7 @@ enum msg_hash_enums MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, MENU_LABEL(VIBRATE_ON_KEYPRESS), + MENU_LABEL(ENABLE_DEVICE_VIBRATION), MSG_LAST }; diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java index b98aa45ad0..321c653882 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java @@ -18,7 +18,7 @@ import android.os.PowerManager; import android.os.Vibrator; import android.os.VibrationEffect; import android.util.Log; - +import java.lang.Math; import java.util.concurrent.CountDownLatch; /** @@ -35,17 +35,32 @@ public class RetroActivityCommon extends RetroActivityLocation public static int FRONTEND_ORIENTATION_90 = 1; public static int FRONTEND_ORIENTATION_180 = 2; public static int FRONTEND_ORIENTATION_270 = 3; + public static int RETRO_RUMBLE_STRONG = 0; + public static int RETRO_RUMBLE_WEAK = 1; public boolean sustainedPerformanceMode = true; public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - public void doVibrate() + public void doVibrate(int effect, int strength, int oneShot) { Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); + int repeat = 0; + long[] pattern = {16}; + int[] strengths = {strength}; + + if (strength == 0) { + vibrator.cancel(); + return; + } + + if (oneShot > 0) + repeat = -1; + else + pattern[0] = 1000; if (Build.VERSION.SDK_INT >= 26) { - vibrator.vibrate(VibrationEffect.createOneShot(33, VibrationEffect.DEFAULT_AMPLITUDE), new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build()); + vibrator.vibrate(VibrationEffect.createWaveform(pattern, strengths, repeat), new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME).setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build()); }else{ - vibrator.vibrate(33); + vibrator.vibrate(pattern, repeat); } } diff --git a/retroarch.cfg b/retroarch.cfg index cd71491bf2..a996f1c8bd 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -906,3 +906,6 @@ # content_runtime_log = false # vibrate_on_keypress = false + +# Enable device vibration for supported cores +# enable_device_vibration = false