2017-12-24 01:26:58 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <boolean.h>
|
|
|
|
#include <libretro.h>
|
|
|
|
#include <retro_miscellaneous.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../../config.h"
|
|
|
|
#endif
|
|
|
|
|
2018-09-12 17:54:51 +00:00
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
#include <switch.h>
|
2018-10-24 15:23:22 +00:00
|
|
|
|
|
|
|
#define MULTITOUCH_LIMIT 4 /* supports up to this many fingers at once */
|
|
|
|
#define TOUCH_AXIS_MAX 0x7fff /* abstraction of pointer coords */
|
2018-09-12 17:54:51 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-24 01:26:58 +00:00
|
|
|
#include "../input_driver.h"
|
|
|
|
|
|
|
|
#define MAX_PADS 10
|
|
|
|
|
2018-07-15 12:34:02 +00:00
|
|
|
/* TODO/FIXME -
|
|
|
|
* fix game focus toggle */
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
typedef struct switch_input
|
|
|
|
{
|
|
|
|
const input_device_driver_t *joypad;
|
|
|
|
bool blocked;
|
2018-10-01 17:51:56 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBNX
|
2018-10-03 16:50:36 +00:00
|
|
|
uint32_t touch_scale_x;
|
|
|
|
uint32_t touch_scale_y;
|
|
|
|
|
|
|
|
uint32_t touch_half_resolution_x;
|
|
|
|
uint32_t touch_half_resolution_y;
|
|
|
|
|
2018-10-24 15:23:22 +00:00
|
|
|
bool touch_state[MULTITOUCH_LIMIT];
|
|
|
|
uint32_t touch_x[MULTITOUCH_LIMIT];
|
|
|
|
uint32_t touch_y[MULTITOUCH_LIMIT];
|
2018-10-01 17:51:56 +00:00
|
|
|
#endif
|
2017-12-24 01:26:58 +00:00
|
|
|
} switch_input_t;
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static void switch_input_poll(void *data)
|
|
|
|
{
|
2018-10-01 17:51:56 +00:00
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
|
|
|
|
|
|
|
if (sw->joypad)
|
|
|
|
sw->joypad->poll();
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
uint32_t touch_count = hidTouchCount();
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2018-10-24 15:23:22 +00:00
|
|
|
for (int i = 0; i < MULTITOUCH_LIMIT; i++)
|
2018-10-01 17:51:56 +00:00
|
|
|
{
|
2018-10-24 15:23:22 +00:00
|
|
|
sw->touch_state[i] = touch_count > i;
|
|
|
|
|
|
|
|
if (sw->touch_state[i])
|
|
|
|
{
|
|
|
|
touchPosition touch_position;
|
|
|
|
hidTouchRead(&touch_position, i);
|
2018-10-01 17:51:56 +00:00
|
|
|
|
2018-10-24 15:23:22 +00:00
|
|
|
sw->touch_x[i] = touch_position.px;
|
|
|
|
sw->touch_y[i] = touch_position.py;
|
|
|
|
}
|
2018-10-01 17:51:56 +00:00
|
|
|
}
|
|
|
|
#endif
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-01 17:51:56 +00:00
|
|
|
#ifdef HAVE_LIBNX
|
2018-10-03 16:50:36 +00:00
|
|
|
void calc_touch_scaling(switch_input_t *sw, uint32_t x, uint32_t y, uint32_t axis_max)
|
2018-10-01 17:51:56 +00:00
|
|
|
{
|
2018-10-03 16:50:36 +00:00
|
|
|
sw->touch_half_resolution_x = x/2;
|
|
|
|
sw->touch_half_resolution_y = y/2;
|
2018-10-01 17:51:56 +00:00
|
|
|
|
2018-10-03 16:50:36 +00:00
|
|
|
sw->touch_scale_x = axis_max / sw->touch_half_resolution_x;
|
|
|
|
sw->touch_scale_y = axis_max / sw->touch_half_resolution_y;
|
2018-10-01 17:51:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int16_t switch_pointer_device_state(switch_input_t *sw,
|
|
|
|
unsigned id, unsigned idx)
|
|
|
|
{
|
2018-10-24 15:23:22 +00:00
|
|
|
if (idx >= MULTITOUCH_LIMIT)
|
2018-10-01 17:51:56 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
2018-10-24 15:23:22 +00:00
|
|
|
return sw->touch_state[idx];
|
2018-10-01 17:51:56 +00:00
|
|
|
case RETRO_DEVICE_ID_POINTER_X:
|
2018-10-24 15:23:22 +00:00
|
|
|
return ((sw->touch_x[idx] - sw->touch_half_resolution_x) * sw->touch_scale_x);
|
2018-10-01 17:51:56 +00:00
|
|
|
case RETRO_DEVICE_ID_POINTER_Y:
|
2018-10-24 15:23:22 +00:00
|
|
|
return ((sw->touch_y[idx] - sw->touch_half_resolution_y) * sw->touch_scale_y);
|
2018-10-01 17:51:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-12-24 01:26:58 +00:00
|
|
|
static int16_t switch_input_state(void *data,
|
2017-12-28 23:44:41 +00:00
|
|
|
rarch_joypad_info_t joypad_info,
|
|
|
|
const struct retro_keybind **binds,
|
|
|
|
unsigned port, unsigned device,
|
|
|
|
unsigned idx, unsigned id)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
|
|
|
|
|
|
|
if (port > MAX_PADS-1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (device)
|
|
|
|
{
|
|
|
|
case RETRO_DEVICE_JOYPAD:
|
|
|
|
return input_joypad_pressed(sw->joypad,
|
|
|
|
joypad_info, port, binds[port], id);
|
|
|
|
break;
|
|
|
|
case RETRO_DEVICE_ANALOG:
|
|
|
|
if (binds[port])
|
|
|
|
return input_joypad_analog(sw->joypad,
|
|
|
|
joypad_info, port, idx, id, binds[port]);
|
|
|
|
break;
|
2018-10-01 17:51:56 +00:00
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
case RETRO_DEVICE_POINTER:
|
|
|
|
case RARCH_DEVICE_POINTER_SCREEN:
|
|
|
|
return switch_pointer_device_state(sw, id, idx);
|
|
|
|
#endif
|
2017-12-28 23:44:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static void switch_input_free_input(void *data)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
if (sw && sw->joypad)
|
|
|
|
sw->joypad->destroy();
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
free(sw);
|
2018-10-27 17:27:24 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
hidExit();
|
|
|
|
#endif
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static void* switch_input_init(const char *joypad_driver)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) calloc(1, sizeof(*sw));
|
|
|
|
if (!sw)
|
|
|
|
return NULL;
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2018-10-27 17:27:24 +00:00
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
hidInitialize();
|
|
|
|
#endif
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
sw->joypad = input_joypad_init_driver(joypad_driver, sw);
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2018-10-03 16:50:36 +00:00
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
/*
|
|
|
|
Here we assume that the touch screen is always 1280x720
|
|
|
|
Call me back when a Nintendo Switch XL is out
|
|
|
|
*/
|
|
|
|
|
|
|
|
calc_touch_scaling(sw, 1280, 720, TOUCH_AXIS_MAX);
|
|
|
|
#endif
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
return sw;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static uint64_t switch_input_get_capabilities(void *data)
|
|
|
|
{
|
|
|
|
(void) data;
|
2017-12-24 01:26:58 +00:00
|
|
|
|
2018-10-08 12:34:12 +00:00
|
|
|
uint64_t caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG);
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBNX
|
|
|
|
caps |= (1 << RETRO_DEVICE_POINTER);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return caps;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static const input_device_driver_t *switch_input_get_joypad_driver(void *data)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
|
|
|
if (sw)
|
|
|
|
return sw->joypad;
|
|
|
|
return NULL;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static void switch_input_grab_mouse(void *data, bool state)
|
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)state;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool switch_input_set_rumble(void *data, unsigned port,
|
2017-12-28 23:44:41 +00:00
|
|
|
enum retro_rumble_effect effect, uint16_t strength)
|
|
|
|
{
|
2017-12-24 01:26:58 +00:00
|
|
|
(void)data;
|
|
|
|
(void)port;
|
|
|
|
(void)effect;
|
|
|
|
(void)strength;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static bool switch_input_keyboard_mapping_is_blocked(void *data)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
|
|
|
if (!sw)
|
|
|
|
return false;
|
|
|
|
return sw->blocked;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 23:44:41 +00:00
|
|
|
static void switch_input_keyboard_mapping_set_block(void *data, bool value)
|
|
|
|
{
|
|
|
|
switch_input_t *sw = (switch_input_t*) data;
|
|
|
|
if (!sw)
|
|
|
|
return;
|
|
|
|
sw->blocked = value;
|
2017-12-24 01:26:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
input_driver_t input_switch = {
|
|
|
|
switch_input_init,
|
|
|
|
switch_input_poll,
|
|
|
|
switch_input_state,
|
|
|
|
switch_input_free_input,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
switch_input_get_capabilities,
|
|
|
|
"switch",
|
|
|
|
switch_input_grab_mouse,
|
|
|
|
NULL,
|
|
|
|
switch_input_set_rumble,
|
|
|
|
switch_input_get_joypad_driver,
|
|
|
|
NULL,
|
|
|
|
switch_input_keyboard_mapping_is_blocked,
|
|
|
|
switch_input_keyboard_mapping_set_block,
|
|
|
|
};
|