(Android) Backport 2020e9ce6a -

* Gingerbread support
* Touchpads support
* builtin Xperia Play autoconfig profile
This commit is contained in:
libretroadmin 2022-07-08 21:03:19 +02:00
parent ef022ffe90
commit 14afdf0e87
2 changed files with 180 additions and 13 deletions

View File

@ -167,6 +167,10 @@ bool (*engine_lookup_name)(char *buf,
int *vendorId, int *productId, size_t size, int id);
void (*engine_handle_dpad)(struct android_app *, AInputEvent*, int, int);
static void android_input_poll_input_gingerbread(android_input_t *android, bool vibrate_on_keypress);
static void android_input_poll_input_default(android_input_t *android, bool vibrate_on_keypress);
static void (*android_input_poll_input)(android_input_t *android, bool vibrate_on_keypress);
static bool android_input_set_sensor_state(void *data, unsigned port,
enum retro_sensor_action action, unsigned event_rate);
@ -541,11 +545,16 @@ static void *android_input_init(const char *joypad_driver)
frontend_android_get_version_sdk(&sdk);
if (sdk >= 19)
engine_lookup_name = android_input_lookup_name;
engine_lookup_name = android_input_lookup_name;
else
engine_lookup_name = android_input_lookup_name_prekitkat;
engine_lookup_name = android_input_lookup_name_prekitkat;
engine_handle_dpad = engine_handle_dpad_default;
engine_handle_dpad = engine_handle_dpad_default;
if (sdk > 10)
android_input_poll_input = android_input_poll_input_default;
else
android_input_poll_input = android_input_poll_input_gingerbread;
if (!android_input_init_handle())
{
@ -1035,7 +1044,7 @@ static void handle_hotplug(android_input_t *android,
strstr(device_model, "Xperia Play") ||
strstr(device_model, "Play") ||
strstr(device_model, "SO-01D")
) && (
) || (
strstr(device_name, "keypad-game-zeus") ||
strstr(device_name, "keypad-zeus") ||
strstr(device_name, "Android Gamepad")
@ -1186,14 +1195,146 @@ static void handle_hotplug(android_input_t *android,
static int android_input_get_id(AInputEvent *event)
{
int id = AInputEvent_getDeviceId(event);
if (id == pad_id2)
id = pad_id1;
return pad_id1;
return id;
}
static void android_input_poll_input(android_input_t *android,
struct TOUCHSTATE
{
int down;
int x;
int y;
};
static void engine_handle_touchpad(
struct android_app *android, AInputEvent *event, int port)
{
unsigned n;
static struct TOUCHSTATE touchstate[64];
int pointer_count = AMotionEvent_getPointerCount(event);
for(n = 0; n < pointer_count; ++n)
{
int pointer_id = AMotionEvent_getPointerId(event, n);
int action = AMOTION_EVENT_ACTION_MASK
& AMotionEvent_getAction(event);
int raw_action = AMotionEvent_getAction(event);
if( action == AMOTION_EVENT_ACTION_POINTER_DOWN
|| action == AMOTION_EVENT_ACTION_POINTER_UP )
{
int pointer_index = (AMotionEvent_getAction( event ) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
pointer_id = AMotionEvent_getPointerId( event, pointer_index);
}
if( action == AMOTION_EVENT_ACTION_DOWN
|| action == AMOTION_EVENT_ACTION_POINTER_DOWN )
touchstate[pointer_id].down = 1;
else if( action == AMOTION_EVENT_ACTION_UP
|| action == AMOTION_EVENT_ACTION_POINTER_UP
|| action == AMOTION_EVENT_ACTION_CANCEL )
touchstate[pointer_id].down = 0;
if (touchstate[pointer_id].down)
{
int x = touchstate[pointer_id].x = AMotionEvent_getX(event, n);
int y = touchstate[pointer_id].y = AMotionEvent_getY(event, n);
if (x < 360)
{
android->analog_state[port][0] =
(int16_t)((x / 180.0 - 1.0f) * 32767.0f);
android->analog_state[port][1] =
(int16_t)((y / 180.0 - 1.0f) * 32767.0f);
}
else if (x >= 606)
{
x -= 606;
android->analog_state[port][2] =
(int16_t)((x / 180.0 - 1.0f) * 32767.0f);
android->analog_state[port][3] =
(int16_t)((y / 180.0 - 1.0f) * 32767.0f);
}
}
else
{
if (touchstate[pointer_id].x < 360)
{
android->analog_state[port][0] = 0.0f;
android->analog_state[port][1] = 0.0f;
}
else if (touchstate[pointer_id].x >= 606)
{
android->analog_state[port][2] = 0.0f;
android->analog_state[port][3] = 0.0f;
}
}
}
}
static void android_input_poll_input_gingerbread(
android_input_t *android,
bool vibrate_on_keypress)
{
AInputEvent *event = NULL;
struct android_app *android_app = (struct android_app*)g_android;
/* Read all pending events. */
if (AInputQueue_getEvent(android_app->inputQueue, &event) >= 0)
{
int source, type_event, id, port;
int32_t handled = 0;
if (AInputQueue_preDispatchEvent(android_app->inputQueue, event))
return;
source = AInputEvent_getSource(event);
type_event = AInputEvent_getType(event);
id = android_input_get_id(event);
port = android_input_get_id_port(android, id, source);
if (port < 0 && !android_is_keyboard_id(id))
port = android_input_recover_port(android, id);
if (port < 0 && !android_is_keyboard_id(id))
handle_hotplug(android, android_app,
&port, id, source);
switch (type_event)
{
case AINPUT_EVENT_TYPE_MOTION:
if ((source & AINPUT_SOURCE_TOUCHPAD))
engine_handle_touchpad(android_app, event, port);
/* Only handle events from a touchscreen or mouse */
else if ((source & (AINPUT_SOURCE_TOUCHSCREEN
| AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_MOUSE)))
android_input_poll_event_type_motion(android, event,
port, source, vibrate_on_keypress);
else
engine_handle_dpad(android_app, event, port, source);
handled = 1;
break;
case AINPUT_EVENT_TYPE_KEY:
{
int keycode = AKeyEvent_getKeyCode(event);
if (android_is_keyboard_id(id))
{
android_input_poll_event_type_keyboard(
event, keycode, &handled);
android_input_poll_event_type_key(
android_app, event, ANDROID_KEYBOARD_PORT,
keycode, source, type_event, &handled);
}
else
android_input_poll_event_type_key(android_app,
event, port, keycode, source, type_event, &handled);
}
break;
}
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
}
}
static void android_input_poll_input_default(android_input_t *android,
bool vibrate_on_keypress)
{
AInputEvent *event = NULL;
@ -1212,18 +1353,20 @@ static void android_input_poll_input(android_input_t *android,
int id = android_input_get_id(event);
int port = android_input_get_id_port(android, id, source);
if (port < 0 && !android_is_keyboard_id(id))
port = android_input_recover_port(android, id);
if (port < 0 && !android_is_keyboard_id(id))
port = android_input_recover_port(android, id);
if (port < 0 && !android_is_keyboard_id(id))
handle_hotplug(android, android_app,
&port, id, source);
&port, id, source);
switch (type_event)
{
case AINPUT_EVENT_TYPE_MOTION:
if ((source & AINPUT_SOURCE_TOUCHPAD))
engine_handle_touchpad(android_app, event, port);
/* Only handle events from a touchscreen or mouse */
if ((source & (AINPUT_SOURCE_TOUCHSCREEN
else if ((source & (AINPUT_SOURCE_TOUCHSCREEN
| AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_MOUSE)))
android_input_poll_event_type_motion(android, event,
port, source, vibrate_on_keypress);
@ -1247,7 +1390,7 @@ static void android_input_poll_input(android_input_t *android,
}
else
android_input_poll_event_type_key(android_app,
event, port, keycode, source, type_event, &handled);
event, port, keycode, source, type_event, &handled);
}
break;
}

View File

@ -120,6 +120,29 @@ DECL_AXIS(r_x_plus, +2) \
DECL_AXIS(r_x_minus, -2) \
DECL_AXIS(r_y_plus, -3) \
DECL_AXIS(r_y_minus, +3)
#define XPERIA_PLAY_DEFAULT_BINDS \
DECL_BTN_EX(a, 4, "Circle") \
DECL_BTN_EX(b, 23, "Cross") \
DECL_BTN_EX(x, 100, "Triangle") \
DECL_BTN_EX(y, 99, "Square") \
DECL_BTN_EX(start, 108, "Start") \
DECL_BTN_EX(select, 109, "Select") \
DECL_BTN_EX(up, 19, "D-Pad Up") \
DECL_BTN_EX(down, 20, "D-Pad Down") \
DECL_BTN_EX(left, 21, "D-Pad Left") \
DECL_BTN_EX(right, 22, "D-Pad Right") \
DECL_BTN_EX(l, 102, "L") \
DECL_BTN_EX(r, 103, "R") \
DECL_BTN_EX(menu_toggle, 82, "Menu") \
DECL_AXIS(l_x_plus, +0) \
DECL_AXIS(l_x_minus, -0) \
DECL_AXIS(l_y_plus, -1) \
DECL_AXIS(l_y_minus, +1) \
DECL_AXIS(r_x_plus, +2) \
DECL_AXIS(r_x_minus, -2) \
DECL_AXIS(r_y_plus, -3) \
DECL_AXIS(r_y_minus, +3)
#endif
#ifdef __QNX__
@ -726,6 +749,7 @@ const char* const input_builtin_autoconfs[] =
#endif
#if defined(ANDROID)
DECL_AUTOCONF_DEVICE("Android Gamepad", "android", ANDROID_DEFAULT_BINDS),
DECL_AUTOCONF_DEVICE("XPERIA Play", "android", XPERIA_PLAY_DEFAULT_BINDS),
#endif
#ifdef __QNX__
DECL_AUTOCONF_DEVICE("QNX Controller", "qnx", QNX_DEFAULT_BINDS),