From cbefaaa74afe5f44a9b3ab51a958ad4b8f39cd0d Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 16 Sep 2018 15:01:48 +0200 Subject: [PATCH] Rewrite wiiu joystick driver to better match switch's and add touchscreen support --- src/joystick/wiiu/SDL_sysjoystick.c | 252 ++++++++++++++++++---------- 1 file changed, 165 insertions(+), 87 deletions(-) diff --git a/src/joystick/wiiu/SDL_sysjoystick.c b/src/joystick/wiiu/SDL_sysjoystick.c index 0d2db2a03..97f9261c7 100644 --- a/src/joystick/wiiu/SDL_sysjoystick.c +++ b/src/joystick/wiiu/SDL_sysjoystick.c @@ -11,11 +11,11 @@ freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. + misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ @@ -28,11 +28,14 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" +#include "../../events/SDL_touch_c.h" #include "SDL_assert.h" #include "SDL_events.h" -static VPADButtons button_map[] = { +#define JOYSTICK_COUNT 1 + +static VPADButtons vpad_button_map[] = { VPAD_BUTTON_A, VPAD_BUTTON_B, VPAD_BUTTON_X, VPAD_BUTTON_Y, VPAD_BUTTON_STICK_L, VPAD_BUTTON_STICK_R, VPAD_BUTTON_L, VPAD_BUTTON_R, @@ -44,30 +47,42 @@ static VPADButtons button_map[] = { }; /* Function to scan the system for joysticks. - * Joystick 0 should be the system default joystick. - * This function should return the number of available joysticks, or -1 - * on an unrecoverable fatal error. + * It should return the number of available joysticks, + * or -1 on an unrecoverable fatal error. */ -int SDL_SYS_JoystickInit(void) { - return 1; +int +SDL_SYS_JoystickInit(void) +{ + return JOYSTICK_COUNT; } -/* Function to return the number of joystick devices plugged in right now */ -int SDL_SYS_NumJoysticks(void) { - return 1; +int +SDL_SYS_NumJoysticks(void) +{ + return JOYSTICK_COUNT; } -/* Function to cause any queued joystick insertions to be processed */ -void SDL_SYS_JoystickDetect(void) { } +void +SDL_SYS_JoystickDetect(void) +{ +} /* Function to get the device-dependent name of a joystick */ -const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - return "Nintendo Wii U Gamepad"; +const char * +SDL_SYS_JoystickNameForDeviceIndex(int device_index) +{ + // Gamepad + if (device_index == 0) { + return "WiiU Gamepad"; + } + + return "Unknown"; } -/* Function to get the current instance id of the joystick located at device_index */ -SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) { - return device_index; +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; } /* Function to open a joystick for use. @@ -75,92 +90,155 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) { This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ -int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { - joystick->nbuttons = sizeof(button_map) / sizeof(VPADButtons); - joystick->naxes = 4; - joystick->nhats = 0; - return 0; +int +SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + // Gamepad + if (device_index == 0) { + SDL_AddTouch(0, "WiiU Gamepad Touchscreen"); + joystick->nbuttons = sizeof(vpad_button_map) / sizeof(VPADButtons); + joystick->naxes = 4; + joystick->nhats = 0; + } + + joystick->instance_id = device_index; + + return 0; } -/* Function to query if the joystick is currently attached - * It returns SDL_TRUE if attached, SDL_FALSE otherwise. - */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick) { - return SDL_TRUE; +/* Function to determine if this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + // Gamepad + if (joystick->instance_id == 0) { + return SDL_TRUE; + } + return SDL_FALSE; } - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ -void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { - static int16_t x1_old = 0; - static int16_t y1_old = 0; - static int16_t x2_old = 0; - static int16_t y2_old = 0; +void +SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + // Gamepad + if (joystick->instance_id == 0) + { + static uint16_t last_touch_x = 0; + static uint16_t last_touch_y = 0; + static uint16_t last_touched = 0; - VPADStatus vpad; - VPADReadError error; - VPADRead(0, &vpad, 1, &error); + static int16_t x1_old = 0; + static int16_t y1_old = 0; + static int16_t x2_old = 0; + static int16_t y2_old = 0; - int16_t x1 = (int16_t) ((vpad.leftStick.x) * 0x7ff0); - int16_t y1 = (int16_t) ((vpad.leftStick.y) * 0x7ff0); - int16_t x2 = (int16_t) ((vpad.rightStick.x) * 0x7ff0); - int16_t y2 = (int16_t) ((vpad.rightStick.y) * 0x7ff0); + static uint32_t hold_old = 0; + uint32_t changed; - if(x1 != x1_old) { - SDL_PrivateJoystickAxis(joystick, 0, x1); - x1_old = x1; - } - if(y1 != y1_old) { - SDL_PrivateJoystickAxis(joystick, 1, y1); - y1_old = y1; - } - if(x2 != x2_old) { - SDL_PrivateJoystickAxis(joystick, 2, x2); - x2_old = x2; - } - if(y2 != y2_old) { - SDL_PrivateJoystickAxis(joystick, 3, y2); - y2_old = y2; - } + VPADStatus vpad; + VPADReadError error; + VPADTouchData tpdata; - int i; - for(i = 0; i < joystick->nbuttons; i++) { - SDL_PrivateJoystickButton( - joystick, i, - (vpad.hold & button_map[i]) ? - SDL_PRESSED : SDL_RELEASED - ); - } -} + VPADRead(VPAD_CHAN_0, &vpad, 1, &error); -/* Function to return the stable GUID for a plugged in device */ -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} + // touchscreen + VPADGetTPCalibratedPoint(0, &tpdata, &vpad.tpFiltered1); + if (tpdata.touched) { + // Send an initial touch + SDL_SendTouch(0, 0, SDL_TRUE, + (float) tpdata.x / 1280.0f, + (float) tpdata.y / 720.0f, 1); -/* Function to return the stable GUID for a plugged in device */ -SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = joystick->name; - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; + // Always send the motion + SDL_SendTouchMotion(0, 0, + (float) tpdata.x / 1280.0f, + (float) tpdata.y / 720.0f, 1); + + // Update old values + last_touch_x = tpdata.x; + last_touch_y = tpdata.y; + last_touched = 1; + } else if (last_touched) { + // Finger released from screen + SDL_SendTouch(0, 0, SDL_FALSE, + (float) last_touch_x / 1280.0f, + (float) last_touch_y / 720.0f, 1); + } + + // axys + int16_t x1 = (int16_t) ((vpad.leftStick.x) * 0x7ff0); + int16_t y1 = (int16_t) -((vpad.leftStick.y) * 0x7ff0); + int16_t x2 = (int16_t) ((vpad.rightStick.x) * 0x7ff0); + int16_t y2 = (int16_t) -((vpad.rightStick.y) * 0x7ff0); + + if(x1 != x1_old) { + SDL_PrivateJoystickAxis(joystick, 0, x1); + x1_old = x1; + } + if(y1 != y1_old) { + SDL_PrivateJoystickAxis(joystick, 1, y1); + y1_old = y1; + } + if(x2 != x2_old) { + SDL_PrivateJoystickAxis(joystick, 2, x2); + x2_old = x2; + } + if(y2 != y2_old) { + SDL_PrivateJoystickAxis(joystick, 3, y2); + y2_old = y2; + } + + // buttons + changed = vpad.hold ^ hold_old; + hold_old = vpad.hold; + if (!changed) { + return; + } + for(int i = 0; i < joystick->nbuttons; i++) { + if (changed & vpad_button_map[i]) { + SDL_PrivateJoystickButton( + joystick, (Uint8) i, + (Uint8) ((vpad.hold & vpad_button_map[i]) ? SDL_PRESSED : SDL_RELEASED) + ); + } + } + } } /* Function to close a joystick after use */ -void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { } +void +SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +} /* Function to perform any system-specific joystick related cleanup */ -void SDL_SYS_JoystickQuit(void) { } +void +SDL_SYS_JoystickQuit(void) +{ +} + +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = SDL_SYS_JoystickNameForDeviceIndex(device_index); + SDL_zero(guid); + SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = joystick->name; + SDL_zero(guid); + SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); + return guid; +} #endif