2012-04-21 23:13:50 +02:00
|
|
|
/* RetroArch - A frontend for libretro.
|
2014-01-01 01:50:59 +01:00
|
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
2017-01-22 13:40:32 +01:00
|
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
2015-01-07 17:46:50 +01:00
|
|
|
* Copyright (C) 2012-2015 - Michael Lelli
|
2017-12-11 23:55:31 -08:00
|
|
|
*
|
2012-04-21 23:13:50 +02:00
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
2011-12-14 13:20:22 +01:00
|
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
2012-04-21 23:13:50 +02:00
|
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
2011-12-14 13:20:22 +01:00
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
2012-04-21 23:31:57 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
2011-12-14 13:20:22 +01:00
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2015-06-19 03:45:23 +02:00
|
|
|
#include <stdlib.h>
|
2012-01-03 12:11:02 +01:00
|
|
|
#include <string.h>
|
2012-07-26 01:28:57 -04:00
|
|
|
#include <math.h>
|
2011-12-14 13:20:22 +01:00
|
|
|
|
2015-06-19 03:45:23 +02:00
|
|
|
#include <boolean.h>
|
2015-11-24 00:05:37 +01:00
|
|
|
#include <retro_miscellaneous.h>
|
2012-07-26 01:28:57 -04:00
|
|
|
|
2016-05-10 19:03:53 +02:00
|
|
|
#include <libretro.h>
|
|
|
|
|
2019-07-19 12:55:38 +02:00
|
|
|
#include "../../config.def.h"
|
2011-12-14 13:20:22 +01:00
|
|
|
|
2019-07-19 12:55:38 +02:00
|
|
|
#include "../input_driver.h"
|
2013-03-16 17:51:45 +01:00
|
|
|
|
2019-02-03 15:49:35 -08:00
|
|
|
/* TODO/FIXME -
|
2018-07-15 14:34:02 +02:00
|
|
|
* fix game focus toggle */
|
|
|
|
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
/* gx joypad functions */
|
|
|
|
bool gxpad_mousevalid(unsigned port);
|
|
|
|
void gx_joypad_read_mouse(unsigned port, int *irx, int *iry, uint32_t *button);
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int x_abs, y_abs;
|
|
|
|
int x_last, y_last;
|
|
|
|
uint32_t button;
|
|
|
|
} gx_input_mouse_t;
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2019-09-15 00:46:02 +02:00
|
|
|
|
2013-11-01 16:33:32 +01:00
|
|
|
typedef struct gx_input
|
|
|
|
{
|
2015-04-14 16:37:59 +02:00
|
|
|
const input_device_driver_t *joypad;
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
int mouse_max;
|
|
|
|
gx_input_mouse_t *mouse;
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2013-11-01 16:33:32 +01:00
|
|
|
} gx_input_t;
|
2012-04-11 04:22:41 +02:00
|
|
|
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
static int16_t gx_lightgun_state(gx_input_t *gx, unsigned id, uint16_t joy_idx)
|
|
|
|
{
|
|
|
|
struct video_viewport vp = {0};
|
|
|
|
video_driver_get_viewport_info(&vp);
|
|
|
|
int16_t res_x = 0;
|
|
|
|
int16_t res_y = 0;
|
|
|
|
int16_t res_screen_x = 0;
|
|
|
|
int16_t res_screen_y = 0;
|
|
|
|
int16_t x = 0;
|
|
|
|
int16_t y = 0;
|
|
|
|
|
|
|
|
vp.x = 0;
|
|
|
|
vp.y = 0;
|
|
|
|
vp.width = 0;
|
|
|
|
vp.height = 0;
|
|
|
|
vp.full_width = 0;
|
|
|
|
vp.full_height = 0;
|
|
|
|
|
|
|
|
x = gx->mouse[joy_idx].x_abs;
|
|
|
|
y = gx->mouse[joy_idx].y_abs;
|
|
|
|
|
|
|
|
if (!(video_driver_translate_coord_viewport_wrap(&vp, x, y,
|
|
|
|
&res_x, &res_y, &res_screen_x, &res_screen_y)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
|
|
|
return res_screen_x;
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
|
|
|
return res_screen_y;
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_TRIGGER);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_AUX_A);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_AUX_B);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_AUX_C);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_START);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_LIGHTGUN_SELECT);
|
|
|
|
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
|
|
|
return !gxpad_mousevalid(joy_idx);
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int16_t gx_mouse_state(gx_input_t *gx, unsigned id, uint16_t joy_idx)
|
|
|
|
{
|
2020-02-23 06:05:23 +01:00
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
unsigned input_mouse_scale = settings->uints.input_mouse_scale;
|
|
|
|
int x_scale = input_mouse_scale;
|
|
|
|
int y_scale = input_mouse_scale;
|
|
|
|
int x = (gx->mouse[joy_idx].x_abs
|
|
|
|
- gx->mouse[joy_idx].x_last) * x_scale;
|
|
|
|
int y = (gx->mouse[joy_idx].y_abs
|
|
|
|
- gx->mouse[joy_idx].y_last) * y_scale;
|
2019-09-15 00:46:02 +02:00
|
|
|
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case RETRO_DEVICE_ID_MOUSE_X:
|
|
|
|
return x;
|
|
|
|
case RETRO_DEVICE_ID_MOUSE_Y:
|
|
|
|
return y;
|
|
|
|
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_MOUSE_LEFT);
|
|
|
|
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
|
|
|
return gx->mouse[joy_idx].button & (1 << RETRO_DEVICE_ID_MOUSE_RIGHT);
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2019-09-15 00:46:02 +02:00
|
|
|
|
2017-01-10 17:40:21 +01:00
|
|
|
static int16_t gx_input_state(void *data,
|
2020-02-27 07:33:14 +01:00
|
|
|
rarch_joypad_info_t *joypad_info,
|
2017-01-10 17:40:21 +01:00
|
|
|
const struct retro_keybind **binds,
|
2012-04-10 01:00:25 +02:00
|
|
|
unsigned port, unsigned device,
|
2014-10-20 20:31:00 +02:00
|
|
|
unsigned idx, unsigned id)
|
2011-12-14 13:20:22 +01:00
|
|
|
{
|
2017-01-10 03:44:53 +01:00
|
|
|
gx_input_t *gx = (gx_input_t*)data;
|
|
|
|
|
2019-07-19 12:55:38 +02:00
|
|
|
if (port >= DEFAULT_MAX_PADS || !gx)
|
2012-07-26 01:28:57 -04:00
|
|
|
return 0;
|
2011-12-14 13:20:22 +01:00
|
|
|
|
2013-07-04 14:52:53 -04:00
|
|
|
switch (device)
|
|
|
|
{
|
|
|
|
case RETRO_DEVICE_JOYPAD:
|
2019-06-23 06:09:45 +02:00
|
|
|
if (id == RETRO_DEVICE_ID_JOYPAD_MASK)
|
|
|
|
{
|
|
|
|
unsigned i;
|
2019-07-22 01:20:00 +02:00
|
|
|
int16_t ret = 0;
|
2019-06-23 06:09:45 +02:00
|
|
|
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
|
|
|
|
{
|
2020-06-12 18:28:07 +02:00
|
|
|
if (binds[port][i].valid)
|
|
|
|
{
|
|
|
|
if (
|
|
|
|
button_is_pressed(
|
|
|
|
gx->joypad, joypad_info, binds[port],
|
|
|
|
port, i))
|
|
|
|
ret |= (1 << i);
|
|
|
|
}
|
2019-06-23 06:09:45 +02:00
|
|
|
}
|
2019-07-22 01:20:00 +02:00
|
|
|
|
|
|
|
return ret;
|
2019-06-23 06:09:45 +02:00
|
|
|
}
|
2019-06-23 18:20:48 +02:00
|
|
|
else
|
|
|
|
{
|
2020-06-12 18:28:07 +02:00
|
|
|
if (binds[port][id].valid)
|
|
|
|
if (
|
|
|
|
button_is_pressed(gx->joypad, joypad_info, binds[port],
|
|
|
|
port, id))
|
|
|
|
return 1;
|
2019-06-23 18:20:48 +02:00
|
|
|
}
|
2019-07-22 01:20:00 +02:00
|
|
|
break;
|
2013-07-04 14:52:53 -04:00
|
|
|
case RETRO_DEVICE_ANALOG:
|
2016-10-26 10:29:26 +02:00
|
|
|
if (binds[port])
|
2017-09-27 23:16:37 +02:00
|
|
|
return input_joypad_analog(gx->joypad,
|
|
|
|
joypad_info, port, idx, id, binds[port]);
|
2016-10-26 10:29:26 +02:00
|
|
|
break;
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
case RETRO_DEVICE_MOUSE:
|
2020-02-27 23:32:18 +01:00
|
|
|
return gx_mouse_state(gx, id, joypad_info->joy_idx);
|
2019-09-15 00:46:02 +02:00
|
|
|
|
|
|
|
case RETRO_DEVICE_LIGHTGUN:
|
2020-02-27 23:32:18 +01:00
|
|
|
return gx_lightgun_state(gx, id, joypad_info->joy_idx);
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2013-07-04 14:52:53 -04:00
|
|
|
}
|
2014-10-05 18:00:43 +02:00
|
|
|
|
|
|
|
return 0;
|
2011-12-14 13:20:22 +01:00
|
|
|
}
|
|
|
|
|
2012-11-27 01:23:10 +01:00
|
|
|
static void gx_input_free_input(void *data)
|
2011-12-14 13:20:22 +01:00
|
|
|
{
|
2014-06-09 21:17:43 +02:00
|
|
|
gx_input_t *gx = (gx_input_t*)data;
|
2011-12-14 13:20:22 +01:00
|
|
|
|
2014-09-15 08:17:16 -04:00
|
|
|
if (!gx)
|
|
|
|
return;
|
|
|
|
|
2014-06-09 21:17:43 +02:00
|
|
|
if (gx->joypad)
|
|
|
|
gx->joypad->destroy();
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
if(gx->mouse)
|
|
|
|
free(gx->mouse);
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2014-09-15 08:17:16 -04:00
|
|
|
free(gx);
|
2012-08-28 22:58:21 -04:00
|
|
|
}
|
|
|
|
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
static inline int gx_count_mouse(gx_input_t *gx)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
if(gx)
|
|
|
|
{
|
|
|
|
for(int i=0; i<DEFAULT_MAX_PADS; i++)
|
|
|
|
{
|
|
|
|
if(gx->joypad->name(i))
|
|
|
|
{
|
|
|
|
if(!strcmp(gx->joypad->name(i), "Wiimote Controller"))
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2019-09-15 00:46:02 +02:00
|
|
|
|
2017-01-10 17:59:48 +01:00
|
|
|
static void *gx_input_init(const char *joypad_driver)
|
2014-06-09 21:17:43 +02:00
|
|
|
{
|
2014-06-09 23:50:59 +02:00
|
|
|
gx_input_t *gx = (gx_input_t*)calloc(1, sizeof(*gx));
|
|
|
|
if (!gx)
|
|
|
|
return NULL;
|
|
|
|
|
2017-01-10 17:59:48 +01:00
|
|
|
gx->joypad = input_joypad_init_driver(joypad_driver, gx);
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
/* Allocate at least 1 mouse at startup */
|
|
|
|
gx->mouse_max = 1;
|
|
|
|
gx->mouse = (gx_input_mouse_t*) calloc(gx->mouse_max, sizeof(gx_input_mouse_t));
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2014-06-09 23:50:59 +02:00
|
|
|
return gx;
|
|
|
|
}
|
|
|
|
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
static void gx_input_poll_mouse(gx_input_t *gx)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
count = gx_count_mouse(gx);
|
|
|
|
|
|
|
|
if(gx && count > 0)
|
|
|
|
{
|
|
|
|
if(count != gx->mouse_max)
|
|
|
|
{
|
|
|
|
gx_input_mouse_t* tmp = NULL;
|
|
|
|
|
|
|
|
tmp = (gx_input_mouse_t*)realloc(gx->mouse, count * sizeof(gx_input_mouse_t));
|
|
|
|
if(!tmp)
|
|
|
|
{
|
|
|
|
free(gx->mouse);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gx->mouse = tmp;
|
|
|
|
gx->mouse_max = count;
|
|
|
|
|
|
|
|
for(int i=0; i<gx->mouse_max; i++)
|
|
|
|
{
|
|
|
|
gx->mouse[i].x_last = 0;
|
|
|
|
gx->mouse[i].y_last = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned i=0; i<gx->mouse_max; i++)
|
|
|
|
{
|
|
|
|
gx->mouse[i].x_last = gx->mouse[i].x_abs;
|
|
|
|
gx->mouse[i].y_last = gx->mouse[i].y_abs;
|
|
|
|
gx_joypad_read_mouse(i, &gx->mouse[i].x_abs, &gx->mouse[i].y_abs, &gx->mouse[i].button);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2019-09-15 00:46:02 +02:00
|
|
|
|
2012-08-09 03:54:27 +02:00
|
|
|
static void gx_input_poll(void *data)
|
2012-07-26 01:28:57 -04:00
|
|
|
{
|
2013-11-01 16:33:32 +01:00
|
|
|
gx_input_t *gx = (gx_input_t*)data;
|
2012-12-15 05:46:49 +01:00
|
|
|
|
2014-10-05 18:00:43 +02:00
|
|
|
if (gx && gx->joypad)
|
2019-09-15 00:46:02 +02:00
|
|
|
{
|
2014-10-05 18:00:43 +02:00
|
|
|
gx->joypad->poll();
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
if(gx->mouse)
|
|
|
|
gx_input_poll_mouse(gx);
|
2019-09-19 15:13:22 +02:00
|
|
|
#endif
|
2019-09-15 00:46:02 +02:00
|
|
|
}
|
2011-12-14 13:20:22 +01:00
|
|
|
}
|
|
|
|
|
2013-11-02 21:16:57 +01:00
|
|
|
static uint64_t gx_input_get_capabilities(void *data)
|
|
|
|
{
|
2014-10-05 18:00:43 +02:00
|
|
|
(void)data;
|
2019-09-19 15:13:22 +02:00
|
|
|
#ifdef HW_RVL
|
2019-09-15 00:46:02 +02:00
|
|
|
return (1 << RETRO_DEVICE_JOYPAD) |
|
|
|
|
(1 << RETRO_DEVICE_ANALOG) |
|
|
|
|
(1 << RETRO_DEVICE_MOUSE) |
|
|
|
|
(1 << RETRO_DEVICE_LIGHTGUN);
|
2019-09-19 15:13:22 +02:00
|
|
|
#else
|
|
|
|
return (1 << RETRO_DEVICE_JOYPAD) |
|
|
|
|
(1 << RETRO_DEVICE_ANALOG);
|
|
|
|
#endif
|
2013-11-02 21:16:57 +01:00
|
|
|
}
|
|
|
|
|
2015-04-14 16:37:59 +02:00
|
|
|
static const input_device_driver_t *gx_input_get_joypad_driver(void *data)
|
2013-12-22 19:47:33 -05:00
|
|
|
{
|
2014-10-18 00:53:56 -05:00
|
|
|
gx_input_t *gx = (gx_input_t*)data;
|
2015-01-11 01:29:19 +01:00
|
|
|
if (!gx)
|
|
|
|
return NULL;
|
|
|
|
return gx->joypad;
|
2013-12-22 19:47:33 -05:00
|
|
|
}
|
2012-07-25 21:02:01 +02:00
|
|
|
|
2015-03-24 07:51:50 +01:00
|
|
|
static void gx_input_grab_mouse(void *data, bool state)
|
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)state;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool gx_input_set_rumble(void *data, unsigned port,
|
|
|
|
enum retro_rumble_effect effect, uint16_t strength)
|
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)port;
|
|
|
|
(void)effect;
|
|
|
|
(void)strength;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-11 07:06:20 +02:00
|
|
|
input_driver_t input_gx = {
|
2013-11-02 21:16:57 +01:00
|
|
|
gx_input_init,
|
|
|
|
gx_input_poll,
|
|
|
|
gx_input_state,
|
|
|
|
gx_input_free_input,
|
2014-06-09 23:21:48 +02:00
|
|
|
NULL,
|
2013-11-03 00:27:58 +01:00
|
|
|
NULL,
|
2013-11-02 21:16:57 +01:00
|
|
|
gx_input_get_capabilities,
|
|
|
|
"gx",
|
2013-12-22 19:47:33 -05:00
|
|
|
|
2015-03-24 07:51:50 +01:00
|
|
|
gx_input_grab_mouse,
|
2015-05-19 19:33:58 +02:00
|
|
|
NULL,
|
2015-03-24 07:51:50 +01:00
|
|
|
gx_input_set_rumble,
|
2013-12-22 19:47:33 -05:00
|
|
|
gx_input_get_joypad_driver,
|
2015-11-16 02:39:38 +01:00
|
|
|
NULL,
|
2019-07-27 02:21:24 +02:00
|
|
|
false
|
2013-12-22 19:47:33 -05:00
|
|
|
};
|