[WiiU] DRC touch support as pointer device

Allow using the Gamepad's touch screen as a RETRO_DEVICE_POINTER.
Methodology could use some work, had to add an extra axis to
joypad in order to get the data transferred into the input driver.
Feel free to change this.
Needs to emulate RETRO_DEVICE_LIGHTGUN to really be useful.
Potential for Wiimote IR in future.

Partially addresses libretro/RetroArch#5294
This commit is contained in:
Ash 2017-08-19 17:40:56 +10:00
parent 7d259b4eaa
commit 6b5aef09a1
No known key found for this signature in database
GPG Key ID: F8C85A8C836C0A7E
3 changed files with 76 additions and 15 deletions

View File

@ -22,6 +22,7 @@
#include <retro_miscellaneous.h>
#include <wiiu/nsyskbd.h>
#include <wiiu/vpad.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -96,18 +97,37 @@ void kb_key_callback(KBDKeyEvent *key)
RETRO_DEVICE_KEYBOARD);
}
/* TODO: emulate a relative mouse. This is suprisingly
hard to get working nicely.
*/
static int16_t wiiu_pointer_device_state(wiiu_input_t* wiiu, unsigned id)
{
switch (id)
{
case RETRO_DEVICE_ID_POINTER_PRESSED:
return wiiu->joypad->get_buttons(0) & VPAD_BUTTON_TOUCH;
case RETRO_DEVICE_ID_POINTER_X:
return wiiu->joypad->axis(0, 0xFFFF0004UL);
case RETRO_DEVICE_ID_POINTER_Y:
return wiiu->joypad->axis(0, 0xFFFF0005UL);
}
return 0;
}
static void wiiu_input_poll(void *data)
{
wiiu_input_t *wiiu = (wiiu_input_t*)data;
if (wiiu && wiiu->joypad)
wiiu->joypad->poll();
wiiu->joypad->poll();
}
static bool wiiu_key_pressed(int key)
{
bool ret = false;
if (key >= RETROK_LAST)
return false;
@ -127,7 +147,7 @@ static int16_t wiiu_input_state(void *data,
if(!wiiu || !(port < MAX_PADS) || !binds || !binds[port])
return 0;
switch (device)
{
case RETRO_DEVICE_JOYPAD:
@ -140,6 +160,9 @@ static int16_t wiiu_input_state(void *data,
return input_joypad_analog(wiiu->joypad,
joypad_info, port, idx, id, binds[port]);
break;
case RETRO_DEVICE_POINTER:
case RARCH_DEVICE_POINTER_SCREEN:
return wiiu_pointer_device_state(wiiu, id);
}
return 0;
@ -151,7 +174,7 @@ static void wiiu_input_free_input(void *data)
if (wiiu && wiiu->joypad)
wiiu->joypad->destroy();
KBDTeardown();
free(data);
@ -165,10 +188,10 @@ static void* wiiu_input_init(const char *joypad_driver)
DEBUG_STR(joypad_driver);
wiiu->joypad = input_joypad_init_driver(joypad_driver, wiiu);
KBDSetup(&kb_connection_callback,
&kb_disconnection_callback,&kb_key_callback);
input_keymaps_init_keyboard_lut(rarch_key_map_wiiu);
return wiiu;
@ -186,9 +209,10 @@ static uint64_t wiiu_input_get_capabilities(void *data)
{
(void)data;
return (1 << RETRO_DEVICE_JOYPAD) |
(1 << RETRO_DEVICE_ANALOG) |
(1 << RETRO_DEVICE_KEYBOARD);
return (1 << RETRO_DEVICE_JOYPAD) |
(1 << RETRO_DEVICE_ANALOG) |
(1 << RETRO_DEVICE_KEYBOARD) |
(1 << RETRO_DEVICE_POINTER);
}
static const input_device_driver_t *wiiu_input_get_joypad_driver(void *data)

View File

@ -29,6 +29,7 @@
#include "../../tasks/tasks_internal.h"
#include "../../retroarch.h"
#include "../../command.h"
#include "../../gfx/video_driver.h"
#include "string.h"
#include "wiiu_dbg.h"
@ -57,7 +58,8 @@ static uint8_t pad_type[KPAD_COUNT] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE,
static uint8_t hid_status[HID_COUNT];
static InputData hid_data[HID_COUNT];
static int16_t analog_state[MAX_PADS][2][2];
/* 3 axis - one for touch/future IR support? */
static int16_t analog_state[MAX_PADS][3][2];
static bool wiiu_pad_inited = false;
static char hidName[HID_COUNT][255];
@ -135,12 +137,12 @@ static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis)
if (joyaxis == AXIS_NONE || port_num >= MAX_PADS)
return 0;
if (AXIS_NEG_GET(joyaxis) < 4)
if (AXIS_NEG_GET(joyaxis) < 6)
{
axis = AXIS_NEG_GET(joyaxis);
is_neg = true;
}
else if (AXIS_POS_GET(joyaxis) < 4)
else if (AXIS_POS_GET(joyaxis) < 6)
{
axis = AXIS_POS_GET(joyaxis);
is_pos = true;
@ -163,6 +165,14 @@ static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis)
case 3:
val = analog_state[port_num][1][1];
break;
case 4:
val = analog_state[port_num][2][0];
break;
case 5:
val = analog_state[port_num][2][1];
break;
}
if (is_neg && val > 0)
@ -173,6 +183,12 @@ static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis)
return val;
}
static float scaleTP(float oldMin, float oldMax, float newMin, float newMax, float val) {
float oldRange = (oldMax - oldMin);
float newRange = (newMax - newMin);
return (((val - oldMin) * newRange) / oldRange) + newMin;
}
static void wiiu_joypad_poll(void)
{
int i, c, result;
@ -183,7 +199,7 @@ static void wiiu_joypad_poll(void)
if (!vpadError)
{
pad_state[0] = vpad.hold & ~0x7F800000; /* clear out emulated analog sticks */
pad_state[0] = vpad.hold & VPAD_MASK_BUTTONS; /* buttons only */
analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = vpad.leftStick.x * 0x7FF0;
analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = vpad.leftStick.y * 0x7FF0;
analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] = vpad.rightStick.x * 0x7FF0;
@ -191,8 +207,28 @@ static void wiiu_joypad_poll(void)
BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
if ((vpad.tpNormal.touched) && (vpad.tpNormal.x > 200) && (vpad.tpNormal.validity) == 0)
BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
/* You can only call VPADData once every loop, else the second one
won't get any data. Thus; I had to hack touch support into the existing
joystick API. Woo-hoo? Misplaced requests for touch axis are filtered
out in wiiu_input.
*/
if (vpad.tpNormal.touched && vpad.tpNormal.validity == VPAD_VALID) {
struct video_viewport vp = {0};
video_driver_get_viewport_info(&vp);
VPADTouchData cal = {0};
/* Calibrates data to a 720p screen, seems to clamp outer 12px */
VPADGetTPCalibratedPoint(0, &cal, &(vpad.tpNormal));
/* Calibrate to viewport and save as axis 2 (idx 4,5) */
analog_state[0][2][0] = (int16_t)scaleTP(12.0f, 1268.0f, 0.0f, (float)(vp.full_width), (float)cal.x);
analog_state[0][2][1] = (int16_t)scaleTP(12.0f, 708.0f, 0.0f, (float)(vp.full_height), (float)cal.y);
/* Emulating a button for touch; lets people assign it to menu
for that traditional RetroArch Wii U feel */
pad_state[0] |= VPAD_BUTTON_TOUCH;
} else {
/* This is probably 0 anyway */
pad_state[0] &= ~VPAD_BUTTON_TOUCH;
}
/* panic button */
if ((vpad.hold & (VPAD_BUTTON_R | VPAD_BUTTON_L | VPAD_BUTTON_STICK_R | VPAD_BUTTON_STICK_L))

View File

@ -225,6 +225,7 @@ IMPORT_BEGIN(vpad);
IMPORT(VPADRead);
IMPORT(VPADInit);
IMPORT(VPADGetTPCalibratedPoint);
IMPORT_END();