Totally reimplemented MFi support

This commit is contained in:
Twinaphex 2015-11-16 02:39:38 +01:00
parent 9fbba11275
commit 57e8cfe1f9
24 changed files with 216 additions and 134 deletions

View File

@ -46,5 +46,5 @@
#endif
#ifdef HAVE_MFI
#include "../input/drivers_hid/mfi_hid.m"
#include "../input/drivers_joypad/mfi_joypad.m"
#endif

View File

@ -1121,6 +1121,7 @@ input_driver_t input_android = {
NULL,
android_input_set_rumble,
android_input_get_joypad_driver,
NULL,
android_input_keyboard_mapping_is_blocked,
android_input_keyboard_mapping_set_block,
};

View File

@ -142,6 +142,11 @@ int32_t cocoa_input_find_any_key(void)
if (apple->joypad)
apple->joypad->poll();
#ifdef HAVE_MFI
if (apple->mfi_joypad)
apple->mfi_joypad->poll();
#endif
for (i = 0; apple_key_name_map[i].hid_id; i++)
if (apple->key_state[apple_key_name_map[i].hid_id])
@ -173,6 +178,11 @@ int32_t cocoa_input_find_any_button(uint32_t port)
if (apple->joypad)
apple->joypad->poll();
#ifdef HAVE_MFI
if (apple->mfi_joypad)
apple->mfi_joypad->poll();
#endif
ret = cocoa_input_find_any_button_ret(apple, apple->buttons[port], port);
@ -197,6 +207,11 @@ int32_t cocoa_input_find_any_axis(uint32_t port)
if (apple && apple->joypad)
apple->joypad->poll();
#ifdef HAVE_MFI
if (apple && apple->mfi_joypad)
apple->mfi_joypad->poll();
#endif
for (i = 0; i < 6; i++)
{
@ -232,6 +247,10 @@ static void *cocoa_input_init(void)
apple->joypad = input_joypad_init_driver(settings->input.joypad_driver, apple);
#ifdef HAVE_MFI
apple->mfi_joypad = input_joypad_init_driver("mfi", apple);
#endif
return apple;
}
@ -251,6 +270,11 @@ static void cocoa_input_poll(void *data)
if (apple->joypad)
apple->joypad->poll();
#ifdef HAVE_MFI
if (apple->mfi_joypad)
apple->mfi_joypad->poll();
#endif
apple->mouse_x_last = apple->mouse_rel_x;
apple->mouse_y_last = apple->mouse_rel_y;
@ -350,10 +374,19 @@ static int16_t cocoa_input_state(void *data,
{
case RETRO_DEVICE_JOYPAD:
return cocoa_input_is_pressed(apple, port, binds[port], id) ||
input_joypad_pressed(apple->joypad, port, binds[port], id);
input_joypad_pressed(apple->joypad, port, binds[port], id)
#ifdef HAVE_MFI
|| input_joypad_pressed(apple->mfi_joypad, port, binds[port], id)
#endif
;
case RETRO_DEVICE_ANALOG:
return input_joypad_analog(apple->joypad, port,
idx, id, binds[port])
#ifdef HAVE_MFI
|| input_joypad_analog(apple->mfi_joypad, port,
idx, id, binds[port]);
#endif
;
case RETRO_DEVICE_KEYBOARD:
return cocoa_keyboard_state(apple, id);
case RETRO_DEVICE_MOUSE:
@ -377,6 +410,10 @@ static bool cocoa_input_key_pressed(void *data, int key)
return true;
if (input_joypad_pressed(apple->joypad, 0, settings->input.binds[0], key))
return true;
#ifdef HAVE_MFI
if (input_joypad_pressed(apple->mfi_joypad, 0, settings->input.binds[0], key))
return true;
#endif
return false;
}
@ -396,6 +433,11 @@ static void cocoa_input_free(void *data)
if (apple->joypad)
apple->joypad->destroy();
#ifdef HAVE_MFI
if (apple->mfi_joypad)
apple->mfi_joypad->destroy();
#endif
free(apple);
}
@ -407,6 +449,11 @@ static bool cocoa_input_set_rumble(void *data,
if (apple && apple->joypad)
return input_joypad_set_rumble(apple->joypad,
port, effect, strength);
#ifdef HAVE_MFI
if (apple && apple->mfi_joypad)
return input_joypad_set_rumble(apple->mfi_joypad,
port, effect, strength);
#endif
return false;
}
@ -429,6 +476,17 @@ static void cocoa_input_grab_mouse(void *data, bool state)
(void)state;
}
#ifdef HAVE_MFI
static const input_device_driver_t *cocoa_input_get_sec_joypad_driver(void *data)
{
cocoa_input_data_t *apple = (cocoa_input_data_t*)data;
if (apple && apple->mfi_joypad)
return apple->mfi_joypad;
return NULL;
}
#endif
static const input_device_driver_t *cocoa_input_get_joypad_driver(void *data)
{
cocoa_input_data_t *apple = (cocoa_input_data_t*)data;
@ -469,6 +527,11 @@ input_driver_t input_cocoa = {
NULL,
cocoa_input_set_rumble,
cocoa_input_get_joypad_driver,
#ifdef HAVE_MFI
cocoa_input_get_sec_joypad_driver,
#else
NULL,
#endif
cocoa_input_keyboard_mapping_is_blocked,
cocoa_input_keyboard_mapping_set_block,
};

View File

@ -59,10 +59,13 @@ typedef struct
int8_t hats[NUM_HATS][2];
#if TARGET_OS_IPHONE
uint32_t mfi_buttons[MAX_USERS];
bool small_keyboard_active;
#endif
#ifdef HAVE_MFI
uint32_t mfi_buttons[MAX_USERS];
const input_device_driver_t *mfi_joypad;
#endif
const input_device_driver_t *joypad;
} cocoa_input_data_t;

View File

@ -165,6 +165,7 @@ input_driver_t input_ctr = {
NULL,
ctr_input_set_rumble,
ctr_input_get_joypad_driver,
NULL,
ctr_input_keyboard_mapping_is_blocked,
ctr_input_keyboard_mapping_set_block,
};

View File

@ -750,6 +750,7 @@ input_driver_t input_dinput = {
NULL,
dinput_set_rumble,
dinput_get_joypad_driver,
NULL,
dinput_keyboard_mapping_is_blocked,
dinput_keyboard_mapping_set_block,
};

View File

@ -176,6 +176,7 @@ input_driver_t input_gx = {
NULL,
gx_input_set_rumble,
gx_input_get_joypad_driver,
NULL,
gx_input_keyboard_mapping_is_blocked,
gx_input_keyboard_mapping_set_block,
};

View File

@ -110,4 +110,5 @@ input_driver_t input_null = {
nullinput_set_rumble,
NULL,
NULL,
NULL,
};

View File

@ -284,6 +284,7 @@ input_driver_t input_ps3 = {
NULL,
ps3_input_set_rumble,
ps3_input_get_joypad_driver,
NULL,
ps3_input_keyboard_mapping_is_blocked,
ps3_input_keyboard_mapping_set_block,
};

View File

@ -184,6 +184,7 @@ input_driver_t input_psp = {
NULL,
psp_input_set_rumble,
psp_input_get_joypad_driver,
NULL,
psp_input_keyboard_mapping_is_blocked,
psp_input_keyboard_mapping_set_block,
};

View File

@ -877,6 +877,7 @@ input_driver_t input_qnx = {
NULL,
qnx_input_set_rumble,
qnx_input_get_joypad_driver,
NULL,
qnx_input_keyboard_mapping_is_blocked,
qnx_input_keyboard_mapping_set_block,
};

View File

@ -268,6 +268,7 @@ input_driver_t input_rwebinput = {
NULL,
rwebinput_set_rumble,
NULL,
NULL,
rwebinput_keyboard_mapping_is_blocked,
rwebinput_keyboard_mapping_set_block,
};

View File

@ -444,6 +444,7 @@ input_driver_t input_sdl = {
NULL,
sdl_set_rumble,
sdl_get_joypad_driver,
NULL,
sdl_keyboard_mapping_is_blocked,
sdl_keyboard_mapping_set_block,
};

View File

@ -444,6 +444,7 @@ input_driver_t input_x = {
NULL,
x_set_rumble,
x_get_joypad_driver,
NULL,
x_keyboard_mapping_is_blocked,
x_keyboard_mapping_set_block,
};

View File

@ -191,6 +191,7 @@ input_driver_t input_xinput = {
NULL,
xdk_input_set_rumble,
xdk_input_get_joypad_driver,
NULL,
xdk_keyboard_mapping_is_blocked,
xdk_keyboard_mapping_set_block,
};

View File

@ -144,4 +144,5 @@ input_driver_t input_xenon360 = {
xenon360_input_set_rumble,
NULL,
NULL,
NULL,
};

View File

@ -764,11 +764,7 @@ static uint64_t btstack_hid_joypad_get_buttons(void *data, unsigned port)
static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey)
{
driver_t *driver = driver_get_ptr();
uint64_t buttons = btstack_hid_joypad_get_buttons(data, port);
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH)
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
#endif
if (joykey == NO_BTN)
return false;
@ -779,11 +775,7 @@ static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey
/* Check the button. */
if ((port < MAX_USERS) && (joykey < 32))
return ((buttons & (1 << joykey)) != 0)
#ifdef HAVE_MFI
|| ((apple->mfi_buttons[port] & (1 << joykey)) != 0)
#endif
;
return ((buttons & (1 << joykey)) != 0);
return false;
}
@ -798,25 +790,14 @@ static bool btstack_hid_joypad_rumble(void *data, unsigned pad,
static int16_t btstack_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis)
{
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH)
driver_t *driver = driver_get_ptr();
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
#endif
btstack_hid_t *hid = (btstack_hid_t*)data;
int16_t val = 0;
if (joyaxis == AXIS_NONE)
return 0;
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH)
if (!apple)
return 0;
#endif
if (AXIS_NEG_GET(joyaxis) < 4)
{
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH)
val += apple->axes[port][AXIS_NEG_GET(joyaxis)];
#endif
val += pad_connection_get_axis(&hid->slots[port], port, AXIS_NEG_GET(joyaxis));
if (val >= 0)
@ -824,9 +805,6 @@ static int16_t btstack_hid_joypad_axis(void *data, unsigned port, uint32_t joyax
}
else if(AXIS_POS_GET(joyaxis) < 4)
{
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH)
val += apple->axes[port][AXIS_POS_GET(joyaxis)];
#endif
val += pad_connection_get_axis(&hid->slots[port], port, AXIS_POS_GET(joyaxis));
if (val <= 0)
@ -872,9 +850,6 @@ error:
static void btstack_hid_poll(void *data)
{
(void)data;
#ifdef HAVE_MFI
apple_gamecontroller_poll_all();
#endif
}
hid_driver_t btstack_hid = {

View File

@ -24,7 +24,6 @@
#include <AvailabilityMacros.h>
#import <GameController/GameController.h>
#include "mfi_hid.h"
#include "../drivers/cocoa_input.h"
#include "../connect/joypad_connection.h"
@ -121,7 +120,7 @@ static void apple_gamecontroller_joypad_register(GCGamepad *gamepad)
driver_t *driver = driver_get_ptr();
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
gamepad.valueChangedHandler = ^(GCGamepad *updateGamepad, GCControllerElement *element) {
apple_gamecontroller_poll(updateGamepad.controller);
apple_gamecontroller_joypad_poll_internal(updateGamepad.controller);
};
gamepad.controller.controllerPausedHandler = ^(GCController *controller) {
@ -173,8 +172,11 @@ static void apple_gamecontroller_joypad_disconnect(GCController* controller)
pad_connection_pad_deinit(&slots[pad], pad);
}
static bool linuxraw_joypad_init(void *data)
bool apple_gamecontroller_joypad_init(void *data)
{
static bool inited = false;
if (inited)
return true;
if (!apple_gamecontroller_available())
return false;
@ -194,100 +196,92 @@ static bool linuxraw_joypad_init(void *data)
} ];
#endif
return true;
return true;
}
static void linuxraw_joypad_destroy(void)
static void apple_gamecontroller_joypad_destroy(void)
{
unsigned i;
for (i = 0; i < MAX_USERS; i++)
{
if (linuxraw_pads[i].fd >= 0)
close(linuxraw_pads[i].fd);
}
memset(linuxraw_pads, 0, sizeof(linuxraw_pads));
for (i = 0; i < MAX_USERS; i++)
linuxraw_pads[i].fd = -1;
if (g_notify >= 0)
close(g_notify);
g_notify = -1;
if (g_epoll >= 0)
close(g_epoll);
g_epoll = -1;
g_hotplug = false;
}
static bool linuxraw_joypad_button(unsigned port, uint16_t joykey)
static bool apple_gamecontroller_joypad_button(unsigned port, uint16_t joykey)
{
const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port];
if (!pad)
return false;
return joykey < NUM_BUTTONS && BIT64_GET(pad->buttons, joykey);
driver_t *driver = driver_get_ptr();
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
if (joykey == NO_BTN)
return false;
/* Check hat. */
if (GET_HAT_DIR(joykey))
return false;
/* Check the button. */
if ((port < MAX_USERS) && (joykey < 32))
return ((apple->mfi_buttons[port] & (1 << joykey)) != 0);
;
return false;
}
static uint64_t linuxraw_joypad_get_buttons(unsigned port)
static uint64_t apple_gamecontroller_joypad_get_buttons(unsigned port)
{
const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port];
if (!pad)
driver_t *driver = driver_get_ptr();
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
if (!apple)
return 0;
return pad->buttons;
return apple->mfi_buttons;
}
static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis)
static int16_t apple_gamecontroller_joypad_axis(unsigned port, uint32_t joyaxis)
{
int16_t val = 0;
const struct linuxraw_joypad *pad = NULL;
if (joyaxis == AXIS_NONE)
return 0;
pad = (const struct linuxraw_joypad*)&linuxraw_pads[port];
if (AXIS_NEG_GET(joyaxis) < NUM_AXES)
{
val = pad->axes[AXIS_NEG_GET(joyaxis)];
if (val > 0)
val = 0;
/* Kernel returns values in range [-0x7fff, 0x7fff]. */
}
else if (AXIS_POS_GET(joyaxis) < NUM_AXES)
{
val = pad->axes[AXIS_POS_GET(joyaxis)];
if (val < 0)
val = 0;
}
return val;
driver_t *driver = driver_get_ptr();
cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data;
int16_t val = 0;
if (joyaxis == AXIS_NONE)
return 0;
if (!apple)
return 0;
if (AXIS_NEG_GET(joyaxis) < 4)
{
val += apple->axes[port][AXIS_NEG_GET(joyaxis)];
if (val >= 0)
val = 0;
}
else if(AXIS_POS_GET(joyaxis) < 4)
{
val += apple->axes[port][AXIS_POS_GET(joyaxis)];
if (val <= 0)
val = 0;
}
return val;
}
static bool linuxraw_joypad_query_pad(unsigned pad)
static bool apple_gamecontroller_joypad_query_pad(unsigned pad)
{
return pad < MAX_USERS && linuxraw_pads[pad].fd >= 0;
return pad < MAX_USERS;
}
static const char *linuxraw_joypad_name(unsigned pad)
static const char *apple_gamecontroller_joypad_name(unsigned pad)
{
if (pad >= MAX_USERS)
return NULL;
return *linuxraw_pads[pad].ident ? linuxraw_pads[pad].ident : NULL;
return "MFi pad";
}
input_device_driver_t linuxraw_mfi = {
linuxraw_joypad_init,
linuxraw_joypad_query_pad,
linuxraw_joypad_destroy,
linuxraw_joypad_button,
linuxraw_joypad_get_buttons,
linuxraw_joypad_axis,
input_device_driver_t mfi_joypad = {
apple_gamecontroller_joypad_init,
apple_gamecontroller_joypad_query_pad,
apple_gamecontroller_joypad_destroy,
apple_gamecontroller_joypad_button,
apple_gamecontroller_joypad_get_buttons,
apple_gamecontroller_joypad_axis,
apple_gamecontroller_joypad_poll,
NULL,
linuxraw_joypad_name,
apple_gamecontroller_joypad_name,
"mfi",
};

View File

@ -216,6 +216,16 @@ const input_device_driver_t *input_driver_get_joypad_driver(void)
return NULL;
}
const input_device_driver_t *input_driver_get_sec_joypad_driver(void)
{
driver_t *driver = driver_get_ptr();
const input_driver_t *input = input_get_ptr(driver);
if (input->get_sec_joypad_driver)
return input->get_sec_joypad_driver(driver->input_data);
return NULL;
}
uint64_t input_driver_get_capabilities(void)
{
driver_t *driver = driver_get_ptr();

View File

@ -88,6 +88,7 @@ typedef struct input_driver
bool (*set_rumble)(void *data, unsigned port,
enum retro_rumble_effect effect, uint16_t state);
const input_device_driver_t *(*get_joypad_driver)(void *data);
const input_device_driver_t *(*get_sec_joypad_driver)(void *data);
bool (*keyboard_mapping_is_blocked)(void *data);
void (*keyboard_mapping_set_block)(void *data, bool value);
} input_driver_t;
@ -160,6 +161,8 @@ uint64_t input_driver_get_capabilities(void);
const input_device_driver_t * input_driver_get_joypad_driver(void);
const input_device_driver_t * input_driver_get_sec_joypad_driver(void);
bool input_driver_grab_mouse(bool state);
bool input_driver_grab_stdin(void);

View File

@ -61,6 +61,9 @@ static input_device_driver_t *joypad_drivers[] = {
#endif
#ifdef __QNX__
&qnx_joypad,
#endif
#ifdef HAVE_MFI
&mfi_joypad,
#endif
&hid_joypad,
&null_joypad,

View File

@ -57,6 +57,7 @@ extern input_device_driver_t hid_joypad;
extern input_device_driver_t android_joypad;
extern input_device_driver_t qnx_joypad;
extern input_device_driver_t null_joypad;
extern input_device_driver_t mfi_joypad;
/**
* joypad_driver_find_handle:

View File

@ -424,11 +424,42 @@ void menu_input_st_cheat_callback(void *userdata, const char *str)
menu_input_key_end_line();
}
static void menu_input_key_bind_poll_bind_state_internal(const input_device_driver_t *joypad,
struct menu_bind_state *state, unsigned port, bool timed_out)
{
unsigned b, a, h;
if (!joypad)
return;
if (joypad->poll)
joypad->poll();
/* poll only the relevant port */
/* for (i = 0; i < settings->input.max_users; i++) */
for (b = 0; b < MENU_MAX_BUTTONS; b++)
state->state[port].buttons[b] = input_joypad_button_raw(joypad, port, b);
for (a = 0; a < MENU_MAX_AXES; a++)
state->state[port].axes[a] = input_joypad_axis_raw(joypad, port, a);
for (h = 0; h < MENU_MAX_HATS; h++)
{
if (input_joypad_hat_raw(joypad, port, HAT_UP_MASK, h))
state->state[port].hats[h] |= HAT_UP_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_DOWN_MASK, h))
state->state[port].hats[h] |= HAT_DOWN_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_LEFT_MASK, h))
state->state[port].hats[h] |= HAT_LEFT_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_RIGHT_MASK, h))
state->state[port].hats[h] |= HAT_RIGHT_MASK;
}
}
static void menu_input_key_bind_poll_bind_state(struct menu_bind_state *state, unsigned port,
bool timed_out)
{
unsigned b, a, h;
const input_device_driver_t *joypad = input_driver_get_joypad_driver();
const input_device_driver_t *sec_joypad = input_driver_get_sec_joypad_driver();
if (!state)
return;
@ -436,48 +467,33 @@ static void menu_input_key_bind_poll_bind_state(struct menu_bind_state *state, u
memset(state->state, 0, sizeof(state->state));
state->skip = timed_out || input_driver_state(NULL, 0,
RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN);
if (!joypad)
return;
if (joypad->poll)
joypad->poll();
/* poll only the relevant port */
/* for (i = 0; i < settings->input.max_users; i++) */
for (b = 0; b < MENU_MAX_BUTTONS; b++)
state->state[port].buttons[b] = input_joypad_button_raw(joypad, port, b);
for (a = 0; a < MENU_MAX_AXES; a++)
state->state[port].axes[a] = input_joypad_axis_raw(joypad, port, a);
for (h = 0; h < MENU_MAX_HATS; h++)
{
if (input_joypad_hat_raw(joypad, port, HAT_UP_MASK, h))
state->state[port].hats[h] |= HAT_UP_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_DOWN_MASK, h))
state->state[port].hats[h] |= HAT_DOWN_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_LEFT_MASK, h))
state->state[port].hats[h] |= HAT_LEFT_MASK;
if (input_joypad_hat_raw(joypad, port, HAT_RIGHT_MASK, h))
state->state[port].hats[h] |= HAT_RIGHT_MASK;
}
menu_input_key_bind_poll_bind_state_internal(joypad, state, port, timed_out);
if (sec_joypad)
menu_input_key_bind_poll_bind_state_internal(sec_joypad, state, port, timed_out);
}
static void menu_input_key_bind_poll_bind_get_rested_axes(
struct menu_bind_state *state, unsigned port)
{
unsigned a;
const input_device_driver_t *joypad = input_driver_get_joypad_driver();
const input_device_driver_t *joypad = input_driver_get_joypad_driver();
const input_device_driver_t *sec_joypad = input_driver_get_sec_joypad_driver();
if (!state || !joypad)
return;
/* poll only the relevant port */
/*for (i = 0; i < settings->input.max_users; i++)*/
for (a = 0; a < MENU_MAX_AXES; a++)
state->axis_state[port].rested_axes[a] =
input_joypad_axis_raw(joypad, port, a);
state->axis_state[port].rested_axes[a] = input_joypad_axis_raw(joypad, port, a);
if (sec_joypad)
{
/* poll only the relevant port */
for (a = 0; a < MENU_MAX_AXES; a++)
state->axis_state[port].rested_axes[a] = input_joypad_axis_raw(sec_joypad, port, a);
}
}
static bool menu_input_key_bind_poll_find_trigger_pad(struct menu_bind_state *state,

View File

@ -295,9 +295,10 @@ enum
iterate_observer = CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting,
true, 0, rarch_draw_observer, 0);
CFRunLoopAddObserver(CFRunLoopGetMain(), iterate_observer, kCFRunLoopCommonModes);
#ifdef HAVE_MFI
apple_gamecontroller_init();
extern bool apple_gamecontroller_joypad_init(void *data);
apple_gamecontroller_joypad_init(NULL);
#endif
}