Initial support for nVidia Shield.

This commit is contained in:
Themaister 2013-07-31 19:04:28 +02:00 committed by twinaphex
parent fa5e58ffb8
commit 222fa8317a
4 changed files with 106 additions and 23 deletions

View File

@ -33,6 +33,12 @@ typedef struct
float dzone_max;
} dpad_values_t;
typedef struct
{
int16_t lx, ly;
int16_t rx, ry;
} analog_t;
#define PRESSED_UP(x, y) ((y <= dzone_min))
#define PRESSED_DOWN(x, y) ((y >= dzone_max))
#define PRESSED_LEFT(x, y) ((x <= dzone_min))
@ -43,7 +49,7 @@ static int state_device_ids[MAX_PADS];
static uint64_t state[MAX_PADS];
static uint64_t keycode_lut[LAST_KEYCODE];
dpad_values_t dpad_state[MAX_PADS];
analog_t analog_state[MAX_PADS];
struct input_pointer
{
@ -61,10 +67,12 @@ enum
AXIS_Z = 11,
AXIS_RZ = 14,
AXIS_HAT_X = 15,
AXIS_HAT_Y = 16
AXIS_HAT_Y = 16,
AXIS_LTRIGGER = 17,
AXIS_RTRIGGER = 18,
};
void (*engine_handle_dpad)(AInputEvent*, size_t, int, char*, size_t, int, bool);
void (*engine_handle_dpad)(AInputEvent*, size_t, int, char*, size_t, int, bool, unsigned);
extern float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
int32_t axis, size_t pointer_index);
@ -183,7 +191,7 @@ void engine_handle_cmd(void)
static void engine_handle_dpad_default(AInputEvent *event,
size_t motion_pointer, int state_id, char *msg, size_t msg_sizeof,
int source, bool debug_enable)
int source, bool debug_enable, unsigned emulation)
{
uint64_t *state_cur = &state[state_id];
float dzone_min = dpad_state[state_id].dzone_min;
@ -194,10 +202,14 @@ static void engine_handle_dpad_default(AInputEvent *event,
*state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
if (emulation == ANALOG_DPAD_LSTICK)
{
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
}
if (debug_enable)
snprintf(msg, msg_sizeof, "Pad %d : x = %.2f, y = %.2f, src %d.\n",
@ -206,7 +218,7 @@ static void engine_handle_dpad_default(AInputEvent *event,
static void engine_handle_dpad_getaxisvalue(AInputEvent *event,
size_t motion_pointer, int state_id, char *msg, size_t msg_sizeof, int source,
bool debug_enable)
bool debug_enable, unsigned emulation)
{
uint64_t *state_cur = &state[state_id];
float dzone_min = dpad_state[state_id].dzone_min;
@ -217,20 +229,23 @@ static void engine_handle_dpad_getaxisvalue(AInputEvent *event,
float rz = AMotionEvent_getAxisValue(event, AXIS_RZ, motion_pointer);
float hatx = AMotionEvent_getAxisValue(event, AXIS_HAT_X, motion_pointer);
float haty = AMotionEvent_getAxisValue(event, AXIS_HAT_Y, motion_pointer);
float ltrig = AMotionEvent_getAxisValue(event, AXIS_LTRIGGER, motion_pointer);
float rtrig = AMotionEvent_getAxisValue(event, AXIS_RTRIGGER, motion_pointer);
*state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_L2) | (1ULL << RETRO_DEVICE_ID_JOYPAD_R2) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
/* On some devices the dpad sends AXIS_HAT_X / AXIS_HAT_Y events, use those first if the returned values are nonzero */
if (fabs(hatx) > 0.0001 || fabs(haty) > 0.0001)
if (fabsf(hatx) > 0.0001f || fabsf(haty) > 0.0001f)
{
*state_cur |= PRESSED_LEFT(hatx, haty) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(hatx, haty) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(hatx, haty) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(hatx, haty) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
}
else
else if (emulation == ANALOG_DPAD_LSTICK)
{
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
@ -238,6 +253,19 @@ static void engine_handle_dpad_getaxisvalue(AInputEvent *event,
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
}
if (ltrig > 0.5f)
*state_cur |= 1ULL << RETRO_DEVICE_ID_JOYPAD_L2;
if (rtrig > 0.5f)
*state_cur |= 1ULL << RETRO_DEVICE_ID_JOYPAD_R2;
if (emulation == ANALOG_DPAD_DUALANALOG)
{
analog_state[state_id].lx = x * 0x7fff;
analog_state[state_id].ly = y * 0x7fff;
analog_state[state_id].rx = z * 0x7fff;
analog_state[state_id].ry = rz * 0x7fff;
}
if (debug_enable)
snprintf(msg, msg_sizeof, "Pad %d : x %.2f, y %.2f, z %.2f, rz %.2f, src %d.\n",
state_id, x, y, z, rz, source);
@ -248,7 +276,7 @@ static void *android_input_init(void)
unsigned i, j, k;
pads_connected = 0;
for(j = 0; j < LAST_KEYCODE; j++)
for (j = 0; j < LAST_KEYCODE; j++)
keycode_lut[j] = 0;
if (!g_settings.input.autodetect_enable)
@ -267,9 +295,9 @@ static void *android_input_init(void)
}
}
for(i = 0; i < MAX_PADS; i++)
for (i = 0; i < MAX_PADS; i++)
{
for(j = 0; j < RARCH_FIRST_META_KEY; j++)
for (j = 0; j < RARCH_FIRST_META_KEY; j++)
{
g_settings.input.binds[i][j].id = i;
g_settings.input.binds[i][j].joykey = 0;
@ -1447,6 +1475,20 @@ static void android_input_set_keybinds(void *data, unsigned device,
keycode_lut[AKEYCODE_BUTTON_L1]|= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_R1]|= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
break;
case DEVICE_NVIDIA_SHIELD:
g_settings.input.device[port] = device;
strlcpy(g_settings.input.device_names[port], "NVIDIA Shield",
sizeof(g_settings.input.device_names[port]));
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_DUALANALOG;
keycode_lut[AKEYCODE_BUTTON_B] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_A] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_BUTTON_Y] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_BUTTON_L1] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_R1] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_BUTTON_THUMBL] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_THUMBR] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
break;
case DEVICE_CCPCREATIONS_WIIUSE_IME:
g_settings.input.device[port] = device;
strlcpy(g_settings.input.device_names[port], "ccpCreations WiiUse IME",
@ -1596,7 +1638,7 @@ static void android_input_poll(void *data)
int predispatched;
msg[0] = 0;
predispatched =AInputQueue_preDispatchEvent(android_app->inputQueue,event);
predispatched = AInputQueue_preDispatchEvent(android_app->inputQueue,event);
if (predispatched)
continue;
@ -1622,10 +1664,24 @@ static void android_input_poll(void *data)
if (state_id < 0)
{
state_id = pads_connected;
state_device_ids[pads_connected++] = id;
if (g_settings.input.autodetect_enable)
input_autodetect_setup(android_app, msg, sizeof(msg), state_id, id, source);
{
bool primary = false;
input_autodetect_setup(android_app, msg, sizeof(msg), state_id, id, source, &primary);
if (primary)
{
RARCH_LOG("Found primary input device.\n");
memmove(state_device_ids + 1, state_device_ids, pads_connected * sizeof(state_device_ids[0]));
state_id = 0;
state_device_ids[0] = id;
pads_connected++;
}
else
state_device_ids[pads_connected++] = id;
}
else
state_device_ids[pads_connected++] = id;
long_msg_enable = true;
}
@ -1677,7 +1733,8 @@ static void android_input_poll(void *data)
if (source & ~(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))
{
if (g_settings.input.dpad_emulation[state_id] != ANALOG_DPAD_NONE)
engine_handle_dpad(event, motion_pointer, state_id, msg, sizeof(msg), source, debug_enable);
engine_handle_dpad(event, motion_pointer, state_id, msg, sizeof(msg), source, debug_enable,
g_settings.input.dpad_emulation[state_id]);
}
else
{
@ -1745,7 +1802,11 @@ static void android_input_poll(void *data)
}
if (msg[0] != 0)
{
msg_queue_clear(g_extern.msg_queue);
msg_queue_push(g_extern.msg_queue, msg, 0, long_msg_enable ? 180 : 30);
RARCH_LOG("Input debug: %s\n", msg);
}
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
processed = 1;
@ -1765,8 +1826,22 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind
{
case RETRO_DEVICE_JOYPAD:
return ((state[port] & binds[port][id].joykey) && (port < pads_connected));
case RETRO_DEVICE_ANALOG:
if (port < pads_connected)
return 0;
switch ((index << 1) || id)
{
case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_X:
return analog_state[port].lx;
case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
return analog_state[port].ly;
case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_X:
return analog_state[port].rx;
case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
return analog_state[port].ry;
}
case RETRO_DEVICE_POINTER:
switch(id)
switch (id)
{
case RETRO_DEVICE_ID_POINTER_X:
return pointer[index].x;
@ -1778,7 +1853,7 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind
return 0;
}
case RARCH_DEVICE_POINTER_SCREEN:
switch(id)
switch (id)
{
case RETRO_DEVICE_ID_POINTER_X:
return pointer[index].full_x;

View File

@ -67,7 +67,7 @@ end:
(*vm)->DetachCurrentThread(vm);
}
void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned port, unsigned id, int source)
void input_autodetect_setup(void *data, char *msg, size_t sizeof_msg, unsigned port, unsigned id, int source, bool *primary)
{
struct android_app *android_app = (struct android_app*)data;
@ -219,6 +219,12 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
device = DEVICE_DEFENDER_GAME_RACER_CLASSIC;
else if (strstr(name_buf, "HOLTEK JC - U912F vibration game"))
device = DEVICE_HOLTEK_JC_U912F;
else if (strstr(name_buf, "NVIDIA Controller"))
{
device = DEVICE_NVIDIA_SHIELD;
port = 0; // Shield is always player 1.
*primary = true;
}
if (strstr(current_ime, "net.obsidianx.android.mogaime"))
{

View File

@ -81,7 +81,7 @@ enum {
#define LAST_KEYCODE AKEYCODE_ASSIST
void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned port, unsigned id, int source);
void input_autodetect_setup(void *data, char *msg, size_t sizeof_msg, unsigned port, unsigned id, int source, bool *primary);
/* Xperia Play externs */
extern unsigned zeus_port;

View File

@ -270,6 +270,7 @@ enum input_devices
DEVICE_GAMEMID,
DEVICE_DEFENDER_GAME_RACER_CLASSIC,
DEVICE_HOLTEK_JC_U912F,
DEVICE_NVIDIA_SHIELD,
#elif defined(GEKKO)
DEVICE_GAMECUBE = 0,
#ifdef HW_RVL
@ -301,6 +302,7 @@ enum analog_dpad_bind_enums
ANALOG_DPAD_NONE = 0,
ANALOG_DPAD_LSTICK,
ANALOG_DPAD_RSTICK,
ANALOG_DPAD_DUALANALOG,
ANALOG_DPAD_LAST
};