diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 54e784c61d..b68a4af620 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -160,7 +160,8 @@
"${workspaceFolder}/**"
],
"defines": [
- "WIIU"
+ "WIIU",
+ "WIIU_HID"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "/opt/devkitpro/devkitPPC/bin/powerpc-eabi-gcc",
diff --git a/Makefile.common b/Makefile.common
index 9f5f1f0dfd..60fd4b4e36 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1182,12 +1182,6 @@ ifeq ($(TARGET), retroarch_wiiu)
INCLUDE_DIRS += -Iinput/include
OBJ += input/drivers_joypad/wiiu/hidpad_driver.o
OBJ += input/drivers_hid/wiiu_hid.o
- OBJ += input/connect/joypad_connection.o \
- input/common/hid/hid_device_driver.o \
- input/common/hid/device_wiiu_gca.o \
- input/common/hid/device_ds3.o \
- input/common/hid/device_ds4.o \
- input/common/hid/device_null.o
endif
endif
diff --git a/Makefile.wiiu b/Makefile.wiiu
index 1d4d07450a..ac54a772ee 100644
--- a/Makefile.wiiu
+++ b/Makefile.wiiu
@@ -7,6 +7,7 @@ GRIFFIN_BUILD = 0
SALAMANDER_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
WIIU_HID = 1
+HAVE_HID = 1
HAVE_RUNAHEAD = 1
WIIU_LOG_RPX = 0
BUILD_DIR = objs/wiiu
diff --git a/input/common/hid/device_ds3.c b/input/common/hid/device_ds3.c
deleted file mode 100644
index 2c33050cae..0000000000
--- a/input/common/hid/device_ds3.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-#include "hid_device_driver.h"
-
-#define DS3_ACTIVATION_REPORT_ID 0xf4
-#define DS3_RUMBLE_REPORT_ID 0x01
-
-typedef struct ds3_instance {
- void *handle;
- joypad_connection_t *pad;
- int slot;
- bool led_set;
- uint32_t buttons;
- int16_t analog_state[3][2];
- uint16_t motors[2];
- uint8_t data[64];
-} ds3_instance_t;
-
-static uint8_t ds3_activation_packet[] = {
-#if defined(IOS)
- 0x53, 0xF4,
-#elif defined(HAVE_WIIUSB_HID)
- 0x02,
-#endif
- 0x42, 0x0c, 0x00, 0x00
-};
-
-#if defined(WIIU)
-#define PACKET_OFFSET 2
-#elif defined(HAVE_WIIUSB_HID)
-#define PACKET_OFFSET 1
-#else
-#define PACKET_OFFSET 0
-#endif
-
-#define LED_OFFSET 11
-#define MOTOR1_OFFSET 4
-#define MOTOR2_OFFSET 6
-
-static uint8_t ds3_control_packet[] = {
- 0x52, 0x01,
- 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-
-extern pad_connection_interface_t ds3_pad_connection;
-
-static void ds3_update_pad_state(ds3_instance_t *instance)
-{
- uint32_t i, pressed_keys;
-
- static const uint32_t button_mapping[17] =
- {
- RETRO_DEVICE_ID_JOYPAD_SELECT,
- RETRO_DEVICE_ID_JOYPAD_L3,
- RETRO_DEVICE_ID_JOYPAD_R3,
- RETRO_DEVICE_ID_JOYPAD_START,
- RETRO_DEVICE_ID_JOYPAD_UP,
- RETRO_DEVICE_ID_JOYPAD_RIGHT,
- RETRO_DEVICE_ID_JOYPAD_DOWN,
- RETRO_DEVICE_ID_JOYPAD_LEFT,
- RETRO_DEVICE_ID_JOYPAD_L2,
- RETRO_DEVICE_ID_JOYPAD_R2,
- RETRO_DEVICE_ID_JOYPAD_L,
- RETRO_DEVICE_ID_JOYPAD_R,
- RETRO_DEVICE_ID_JOYPAD_X,
- RETRO_DEVICE_ID_JOYPAD_A,
- RETRO_DEVICE_ID_JOYPAD_B,
- RETRO_DEVICE_ID_JOYPAD_Y,
- 16 /* PS button */
- };
-
- instance->buttons = 0;
-
- pressed_keys = instance->data[2] |
- (instance->data[3] << 8) |
- ((instance->data[4] & 0x01) << 16);
-
- for (i = 0; i < 17; i++)
- instance->buttons |= (pressed_keys & (1 << i)) ?
- (1 << button_mapping[i]) : 0;
-}
-
-static void ds3_update_analog_state(ds3_instance_t *instance)
-{
- int pad_axis;
- int16_t interpolated;
- unsigned stick, axis;
-
- for (pad_axis = 0; pad_axis < 4; pad_axis++)
- {
- axis = pad_axis % 2 ? 0 : 1;
- stick = pad_axis / 2;
- interpolated = instance->data[6+pad_axis];
- instance->analog_state[stick][axis] = (interpolated - 128) * 256;
- }
-}
-
-#if defined(WIIU)
-static int32_t ds3_send_activation_packet(ds3_instance_t *instance)
-{
- return HID_SET_REPORT(instance->handle,
- HID_REPORT_FEATURE,
- DS3_ACTIVATION_REPORT_ID,
- ds3_activation_packet,
- sizeof(ds3_activation_packet));
-}
-
-static uint32_t set_protocol(ds3_instance_t *instance, int protocol)
-{
- return HID_SET_PROTOCOL(instance->handle, 1);
-}
-#else
-static int32_t ds3_send_activation_packet(ds3_instance_t *instance)
-{
- HID_SEND_CONTROL(instance->handle,
- ds3_activation_packet, sizeof(ds3_activation_packet));
- return 0;
-}
-
-static uint32_t set_protocol(ds3_instance_t *instance, int protocol)
-{
- return 0;
-}
-#endif
-
-static int32_t ds3_send_control_packet(ds3_instance_t *instance)
-{
- /* TODO/FIXME - C89-incompatible */
- int32_t result = 0;
- uint8_t packet_buffer[sizeof(ds3_control_packet)];
- memcpy(packet_buffer, ds3_control_packet, sizeof(ds3_control_packet));
-
- packet_buffer[LED_OFFSET] = 0;
- if (instance->pad)
- packet_buffer[LED_OFFSET] = 1 << ((instance->slot % 4) + 1);
- packet_buffer[MOTOR1_OFFSET] = instance->motors[1] >> 8;
- packet_buffer[MOTOR2_OFFSET] = instance->motors[0] >> 8;
-
-#if defined(HAVE_WIIUSB_HID)
- packet_buffer[1] = 0x03;
-#endif
-
-#if defined(WIIU)
- result = HID_SET_REPORT(instance->handle,
- HID_REPORT_OUTPUT,
- DS3_RUMBLE_REPORT_ID,
- packet_buffer+PACKET_OFFSET,
- sizeof(ds3_control_packet)-PACKET_OFFSET);
-#else
- HID_SEND_CONTROL(instance->handle,
- packet_buffer+PACKET_OFFSET,
- sizeof(ds3_control_packet)-PACKET_OFFSET);
-#endif /* WIIU */
- return result;
-}
-
-static void *ds3_init(void *handle)
-{
- int errors = 0;
- ds3_instance_t *instance = (ds3_instance_t *)
- malloc(sizeof(ds3_instance_t));
- if (!instance)
- return NULL;
-
- memset(instance, 0, sizeof(ds3_instance_t));
- instance->handle = handle;
-
- /* Setting protocol */
-
- /* this might fail, but we don't care. */
- set_protocol(instance, 1);
-
- /* Sending control packet.. */
- if (ds3_send_control_packet(instance) < 0)
- errors++;
-
- /* Sending activation packet.. */
- if (ds3_send_activation_packet(instance) < 0)
- errors++;
-
- if (errors)
- goto error;
-
- instance->pad = hid_pad_register(instance, &ds3_pad_connection);
- if (!instance->pad)
- goto error;
-
- return instance;
-
-error:
- if (instance)
- free(instance);
- return NULL;
-}
-
-static void ds3_free(void *data)
-{
- ds3_instance_t *instance = (ds3_instance_t *)data;
-
- if (!instance)
- return;
-
- hid_pad_deregister(instance->pad);
- free(instance);
-}
-
-static void ds3_handle_packet(void *data, uint8_t *packet, size_t size)
-{
- ds3_instance_t *instance = (ds3_instance_t *)data;
-
- if (!instance || !instance->pad)
- return;
-
- instance->pad->iface->packet_handler(data, packet, size);
-}
-
-static bool ds3_detect(uint16_t vendor_id, uint16_t product_id)
-{
- return vendor_id == VID_SONY && product_id == PID_SONY_DS3;
-}
-
-hid_device_t ds3_hid_device = {
- ds3_init,
- ds3_free,
- ds3_handle_packet,
- ds3_detect,
- "Sony DualShock 3"
-};
-
-/**
- * pad interface implementation
- */
-
-static void *ds3_pad_init(void *data, uint32_t slot, hid_driver_t *driver)
-{
- ds3_instance_t *pad = (ds3_instance_t *)data;
- pad->slot = slot;
-
- return data;
-}
-
-static void ds3_pad_deinit(void *data)
-{
- ds3_instance_t *pad = (ds3_instance_t *)data;
- if (pad)
- input_autoconfigure_disconnect(pad->slot,
- ds3_pad_connection.get_name(pad));
-}
-
-static void ds3_get_buttons(void *data, input_bits_t *state)
-{
- ds3_instance_t *pad = (ds3_instance_t *)data;
-
- if (pad)
- {
- BITS_COPY16_PTR(state, pad->buttons);
-
- if (pad->buttons & 0x10000)
- BIT256_SET_PTR(state, RARCH_MENU_TOGGLE);
- }
- else
- {
- BIT256_CLEAR_ALL_PTR(state);
- }
-}
-
-static void ds3_packet_handler(void *data, uint8_t *packet, uint16_t size)
-{
- ds3_instance_t *instance = (ds3_instance_t *)data;
-
- if (instance->pad && !instance->led_set)
- {
- ds3_send_control_packet(instance);
- instance->led_set = true;
- }
-
- if (size > sizeof(ds3_control_packet))
- {
- RARCH_ERR("[ds3]: Expecting packet to be %d but was %d\n",
- sizeof(ds3_control_packet), size);
- return;
- }
-
- memcpy(instance->data, packet, size);
- ds3_update_pad_state(instance);
- ds3_update_analog_state(instance);
-}
-
-static void ds3_set_rumble(void *data,
- enum retro_rumble_effect effect, uint16_t strength) { }
-
-static int16_t ds3_get_axis(void *data, unsigned axis)
-{
- axis_data axis_data;
- ds3_instance_t *pad = (ds3_instance_t *)data;
-
- gamepad_read_axis_data(axis, &axis_data);
-
- if (!pad || axis_data.axis >= 4)
- return 0;
-
- return gamepad_get_axis_value(pad->analog_state, &axis_data);
-}
-
-static const char *ds3_get_name(void *data) { return "Sony DualShock 3"; }
-
-static int32_t ds3_button(void *data, uint16_t joykey)
-{
- ds3_instance_t *pad = (ds3_instance_t *)data;
- if (!pad || joykey > 31)
- return 0;
- return pad->buttons & (1 << joykey);
-}
-
-pad_connection_interface_t ds3_pad_connection = {
- ds3_pad_init,
- ds3_pad_deinit,
- ds3_packet_handler,
- ds3_set_rumble,
- ds3_get_buttons,
- ds3_get_axis,
- ds3_get_name,
- ds3_button
-};
diff --git a/input/common/hid/device_ds4.c b/input/common/hid/device_ds4.c
deleted file mode 100644
index c95fca7f2a..0000000000
--- a/input/common/hid/device_ds4.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-#include "hid_device_driver.h"
-
-extern pad_connection_interface_t ds4_pad_connection;
-
-typedef struct ds4_instance
-{
- void *handle;
- joypad_connection_t *pad;
- int slot;
- uint32_t buttons;
- uint16_t motors[2];
- uint8_t data[64];
-} ds4_instance_t;
-
-/**
- * I'm leaving this code in here for posterity, and because maybe it can
- * be used on other platforms. But using the DS4 on the Wii U directly is
- * impossible because it doesn't generate a HID event. Which makes me think
- * it's not a HID device at all--at least, not over USB.
- *
- * I imagine it might be useful in Bluetooth mode, though.
- */
-static void *ds4_init(void *handle)
-{
- ds4_instance_t *instance = (ds4_instance_t *)
- malloc(sizeof(ds4_instance_t));
- if (!instance)
- return NULL;
-
- memset(instance, 0, sizeof(ds4_instance_t));
- instance->handle = handle;
- instance->pad = hid_pad_register(instance, &ds4_pad_connection);
-
- if (!instance->pad)
- {
- free(instance);
- return NULL;
- }
-
- return instance;
-}
-
-static void ds4_free(void *data)
-{
- ds4_instance_t *instance = (ds4_instance_t *)data;
-
- if (!instance)
- return;
-
- hid_pad_deregister(instance->pad);
- free(instance);
-}
-
-static void ds4_handle_packet(void *data, uint8_t *buffer, size_t size)
-{
- ds4_instance_t *instance = (ds4_instance_t *)data;
-
- if (instance && instance->pad)
- instance->pad->iface->packet_handler(instance->pad->data, buffer, size);
-}
-
-static bool ds4_detect(uint16_t vendor_id, uint16_t product_id)
-{
- return vendor_id == VID_SONY && product_id == PID_SONY_DS4;
-}
-
-hid_device_t ds4_hid_device = {
- ds4_init,
- ds4_free,
- ds4_handle_packet,
- ds4_detect,
- "Sony DualShock 4"
-};
-
-static void *ds4_pad_init(void *data, uint32_t slot, hid_driver_t *driver)
-{
- ds4_instance_t *instance = (ds4_instance_t *)data;
-
- if (!instance)
- return NULL;
-
- instance->slot = slot;
- return instance;
-}
-
-static void ds4_packet_handler(void *data, uint8_t *packet, uint16_t size)
-{
-#ifdef DEBUG
- ds4_instance_t *instance = (ds4_instance_t *)data;
- if (!instance)
- return;
- RARCH_LOG_BUFFER(packet, size);
-#endif
-}
-
-static void ds4_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) { }
-static int16_t ds4_get_axis(void *data, unsigned axis) { return 0; }
-static const char *ds4_get_name(void *data) { return "Sony DualShock 4"; }
-static int32_t ds4_button(void *data, uint16_t joykey) { return 0; }
-static void ds4_pad_deinit(void *data) { }
-static void ds4_get_buttons(void *data, input_bits_t *state) { }
-
-pad_connection_interface_t ds4_pad_connection = {
- ds4_pad_init,
- ds4_pad_deinit,
- ds4_packet_handler,
- ds4_set_rumble,
- ds4_get_buttons,
- ds4_get_axis,
- ds4_get_name,
- ds4_button
-};
diff --git a/input/common/hid/device_null.c b/input/common/hid/device_null.c
deleted file mode 100644
index e335a376c6..0000000000
--- a/input/common/hid/device_null.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-#include "hid_device_driver.h"
-
-extern pad_connection_interface_t hid_null_pad_connection;
-
-/*
- * This is the instance data structure for the pad you are implementing.
- * This is a good starting point, but you can add/remove things as makes
- * sense for the pad you're writing for. The pointer to this structure
- * will be passed in as a void pointer to the methods you implement below.
- */
-typedef struct hid_null_instance
-{
- void *handle; /* a handle to the HID subsystem adapter */
- joypad_connection_t *pad; /* a pointer to the joypad connection you assign
- in init() */
- int slot; /* which slot does this pad occupy? */
- uint32_t buttons; /* a bitmap of the digital buttons for the pad */
- uint16_t motors[2]; /* rumble strength, if appropriate */
- uint8_t data[64]; /* a buffer large enough to hold the device's
- max rx packet */
-} hid_null_instance_t;
-
-/**
- * Use the HID_ macros (see input/include/hid_driver.h) to send data packets
- * to the device. When this method returns, the device needs to be in a state
- * where we can read data packets from the device. So, if there's any
- * activation packets (see the ds3 and Wii U GameCube adapter drivers for
- * examples), send them here.
- *
- * While you *can* allocate the retro pad here, it isn't mandatory (see
- * the Wii U GC adapter).
- *
- * If initialization fails, return NULL.
- */
-static void *hid_null_init(void *handle)
-{
- hid_null_instance_t *instance = (hid_null_instance_t *)calloc(1, sizeof(hid_null_instance_t));
- if (!instance)
- return NULL;
-
- memset(instance, 0, sizeof(hid_null_instance_t));
- instance->handle = handle;
- instance->pad = hid_pad_register(instance, &hid_null_pad_connection);
- if (!instance->pad)
- {
- free(instance);
- return NULL;
- }
-
- return instance;
-}
-
-/*
- * Gets called when the pad is disconnected. It must clean up any memory
- * allocated and used by the instance data.
- */
-static void hid_null_free(void *data)
-{
- hid_null_instance_t *instance = (hid_null_instance_t *)data;
-
- if (!instance)
- return;
-
- hid_pad_deregister(instance->pad);
- free(instance);
-}
-
-/**
- * Handle a single packet from the device.
- * For most pads you'd just forward it onto the pad driver (see below).
- * A more complicated example is in the Wii U GC adapter driver.
- */
-static void hid_null_handle_packet(void *data, uint8_t *buffer, size_t size)
-{
- hid_null_instance_t *instance = (hid_null_instance_t *)data;
-
- if (instance && instance->pad)
- instance->pad->iface->packet_handler(instance->pad->data, buffer, size);
-}
-
-/**
- * Return true if the passed in VID and PID are supported by the driver.
- */
-static bool hid_null_detect(uint16_t vendor_id, uint16_t product_id)
-{
- return vendor_id == VID_NONE && product_id == PID_NONE;
-}
-
-/**
- * Assign function pointers to the driver structure.
- */
-hid_device_t null_hid_device = {
- hid_null_init,
- hid_null_free,
- hid_null_handle_packet,
- hid_null_detect,
- "Null HID device"
-};
-
-/**
- * This is called via hid_pad_register(). In the common case where the
- * device only controls one pad, you can simply return the data parameter.
- * But if you need to track multiple pads attached to the same HID device
- * (see: Wii U GC adapter), you can allocate that memory here.
- */
-static void *hid_null_pad_init(void *data, uint32_t slot, hid_driver_t *driver)
-{
- hid_null_instance_t *instance = (hid_null_instance_t *)data;
-
- if (!instance)
- return NULL;
-
- instance->slot = slot;
- return instance;
-}
-
-/**
- * If you allocate any memory in hid_null_pad_init() above, de-allocate it here.
- */
-static void hid_null_pad_deinit(void *data) { }
-
-/**
- * Translate the button data from the pad into the input_bits_t format
- * that RetroArch can use.
- */
-static void hid_null_get_buttons(void *data, input_bits_t *state) { }
-
-/**
- * Handle a single packet for the pad.
- */
-static void hid_null_packet_handler(void *data, uint8_t *packet, uint16_t size)
-{
-#ifdef DEBUG
- hid_null_instance_t *instance = (hid_null_instance_t *)data;
- if (!instance)
- return;
- RARCH_LOG_BUFFER(packet, size);
-#endif
-}
-
-/**
- * If the pad doesn't support rumble, then this can just be a no-op.
- */
-static void hid_null_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) { }
-
-/**
- * Read analog sticks.
- * If the pad doesn't have any analog axis, just return 0 here.
- *
- * The return value must conform to the following characteristics:
- * - (0, 0) is center
- * - (-32768,-32768) is top-left
- * - (32767,32767) is bottom-right
- */
-static int16_t hid_null_get_axis(void *data, unsigned axis) { return 0; }
-
-/**
- * The name the pad will show up as in the UI, also used to auto-assign
- * buttons in input/input_autodetect_builtin.c
- */
-static const char *hid_null_get_name(void *data)
-{
- return "Null HID Pad";
-}
-
-/**
- * Read the state of a single button.
- */
-static int32_t hid_null_button(void *data, uint16_t joykey) { return 0; }
-
-/**
- * Fill in the joypad interface
- */
-pad_connection_interface_t hid_null_pad_connection = {
- hid_null_pad_init,
- hid_null_pad_deinit,
- hid_null_packet_handler,
- hid_null_set_rumble,
- hid_null_get_buttons,
- hid_null_get_axis,
- hid_null_get_name,
- hid_null_button
-};
diff --git a/input/common/hid/device_wiiu_gca.c b/input/common/hid/device_wiiu_gca.c
deleted file mode 100644
index 01e1eccee7..0000000000
--- a/input/common/hid/device_wiiu_gca.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-#include
-#include "hid_device_driver.h"
-
-#ifdef WII
-static uint8_t activation_packet[] = { 0x01, 0x13 };
-#else
-static uint8_t activation_packet[] = { 0x13 };
-#endif
-
-#define GCA_PORT_INITIALIZING 0x00
-#define GCA_PORT_POWERED 0x04
-#define GCA_PORT_CONNECTED 0x10
-#define GCA_WAVEBIRD_CONNECTED 0x22
-
-typedef struct hid_wiiu_gca_instance
-{
- void *handle;
- bool online;
- uint8_t device_state[37];
- joypad_connection_t *pads[4];
-} hid_wiiu_gca_instance_t;
-
-typedef struct gca_pad_data
-{
- void *gca_handle; /* instance handle for the GCA adapter */
- hid_driver_t *driver; /* HID system driver interface */
- uint8_t data[9]; /* pad data */
- uint32_t slot; /* slot this pad occupies */
- uint32_t buttons; /* digital button state */
- int16_t analog_state[3][2]; /* analog state */
-} gca_pad_t;
-
-extern pad_connection_interface_t wiiu_gca_pad_connection;
-
-static void wiiu_gca_unregister_pad(hid_wiiu_gca_instance_t *instance, int slot)
-{
- joypad_connection_t *pad = NULL;
- if (!instance || slot < 0 || slot >= 4 || !instance->pads[slot])
- return;
-
- pad = instance->pads[slot];
- instance->pads[slot] = NULL;
-
- hid_pad_deregister(pad);
-}
-
-static void wiiu_gca_update_pad_state(hid_wiiu_gca_instance_t *instance)
-{
- int i, port;
- unsigned char port_connected;
- joypad_connection_t *pad;
-
- if (!instance || !instance->online)
- return;
-
- /* process each pad */
- for (i = 1; i < 37; i += 9)
- {
- port = i / 9;
- pad = instance->pads[port];
- port_connected = instance->device_state[i];
-
- if (port_connected > GCA_PORT_POWERED)
- {
- if (!pad)
- {
- RARCH_LOG("[gca]: Gamepad at port %d connected.\n", port+1);
- instance->pads[port] = hid_pad_register(
- instance, &wiiu_gca_pad_connection);
- pad = instance->pads[port];
- if (!pad)
- {
- RARCH_ERR("[gca]: Failed to register pad.\n");
- break;
- }
- }
-
- pad->iface->packet_handler(pad->data, &instance->device_state[i], 9);
- }
- else
- {
- if (pad)
- {
- RARCH_LOG("[gca]: Gamepad at port %d disconnected.\n", port+1);
- wiiu_gca_unregister_pad(instance, port);
- }
- }
- }
-}
-
-static void *wiiu_gca_init(void *handle)
-{
- unsigned i;
- hid_wiiu_gca_instance_t *instance = (hid_wiiu_gca_instance_t*)
- malloc(sizeof(hid_wiiu_gca_instance_t));
-
- if (!instance)
- return NULL;
-
- instance->handle = handle;
- instance->online = true;
-
- for (i = 0; i < 37; i++)
- instance->device_state[i] = 0;
- for (i = 0; i < 4; i++)
- instance->pads[i] = NULL;
-
- hid_instance.os_driver->send_control(handle, activation_packet, sizeof(activation_packet));
- hid_instance.os_driver->read(handle, instance->device_state, sizeof(instance->device_state));
-
- return instance;
-}
-
-static void wiiu_gca_free(void *data)
-{
- int i;
- hid_wiiu_gca_instance_t *instance = (hid_wiiu_gca_instance_t *)data;
-
- if (!instance)
- return;
-
- instance->online = false;
-
- for (i = 0; i < 4; i++)
- wiiu_gca_unregister_pad(instance, i);
-
- free(instance);
-}
-
-static void wiiu_gca_handle_packet(void *data, uint8_t *buffer, size_t size)
-{
- hid_wiiu_gca_instance_t *instance = (hid_wiiu_gca_instance_t *)data;
- if (!instance || !instance->online)
- return;
-
- if (size > sizeof(instance->device_state))
- {
- RARCH_WARN("[gca]: packet size %d is too big for buffer of size %d\n",
- size, sizeof(instance->device_state));
- return;
- }
-
- memcpy(instance->device_state, buffer, size);
- wiiu_gca_update_pad_state(instance);
-}
-
-static bool wiiu_gca_detect(uint16_t vendor_id, uint16_t product_id)
-{
- return vendor_id == VID_NINTENDO && product_id == PID_NINTENDO_GCA;
-}
-
-hid_device_t wiiu_gca_hid_device = {
- wiiu_gca_init,
- wiiu_gca_free,
- wiiu_gca_handle_packet,
- wiiu_gca_detect,
- "Wii U Gamecube Adapter"
-};
-
-/**
- * Pad connection interface implementation. This handles each individual
- * GC controller (as opposed to the above that handles the GCA itself).
- */
-
-static void *wiiu_gca_pad_init(void *data, uint32_t slot, hid_driver_t *driver)
-{
- gca_pad_t *pad = (gca_pad_t *)malloc(sizeof(gca_pad_t));
-
- if (!pad)
- return NULL;
-
- memset(pad, 0, sizeof(gca_pad_t));
-
- pad->gca_handle = data;
- pad->driver = driver;
- pad->slot = slot;
-
- return pad;
-}
-
-static void wiiu_gca_pad_deinit(void *data)
-{
- gca_pad_t *pad = (gca_pad_t *)data;
-
- if (!pad)
- return;
-
- input_autoconfigure_disconnect(pad->slot,
- wiiu_gca_pad_connection.get_name(pad));
- free(pad);
-}
-
-static void wiiu_gca_get_buttons(void *data, input_bits_t *state)
-{
- gca_pad_t *pad = (gca_pad_t *)data;
- if (pad)
- {
- BITS_COPY16_PTR(state, pad->buttons);
- }
- else
- {
- BIT256_CLEAR_ALL_PTR(state);
- }
-}
-
-static void update_buttons(gca_pad_t *pad)
-{
- uint32_t i, pressed_keys;
-
- static const uint32_t button_mapping[12] =
- {
- RETRO_DEVICE_ID_JOYPAD_A,
- RETRO_DEVICE_ID_JOYPAD_B,
- RETRO_DEVICE_ID_JOYPAD_X,
- RETRO_DEVICE_ID_JOYPAD_Y,
- RETRO_DEVICE_ID_JOYPAD_LEFT,
- RETRO_DEVICE_ID_JOYPAD_RIGHT,
- RETRO_DEVICE_ID_JOYPAD_DOWN,
- RETRO_DEVICE_ID_JOYPAD_UP,
- RETRO_DEVICE_ID_JOYPAD_START,
- RETRO_DEVICE_ID_JOYPAD_SELECT,
- RETRO_DEVICE_ID_JOYPAD_R,
- RETRO_DEVICE_ID_JOYPAD_L,
- };
-
- if (!pad)
- return;
-
- pressed_keys = pad->data[1] | (pad->data[2] << 8);
- pad->buttons = 0;
-
- for (i = 0; i < 12; i++)
- pad->buttons |= (pressed_keys & (1 << i)) ?
- (1 << button_mapping[i]) : 0;
-}
-
-static void wiiu_gca_update_analog_state(gca_pad_t *pad)
-{
- int pad_axis;
- int16_t interpolated;
- unsigned stick, axis;
-
- /* GameCube analog axis are 8-bit unsigned, where 128/128 is center.
- * So, we subtract 128 to get a signed, 0-based value and then mulitply
- * by 256 to get the 16-bit range RetroArch expects. */
- for (pad_axis = 0; pad_axis < 4; pad_axis++)
- {
- axis = (pad_axis % 2) ? 0 : 1;
- stick = pad_axis / 2;
- interpolated = pad->data[3 + pad_axis];
- /* libretro requires "up" to be negative, so we invert the y axis */
- interpolated = (axis) ?
- ((interpolated - 128) * 256) :
- ((interpolated - 128) * -256);
-
- pad->analog_state[stick][axis] = interpolated;
-#if 0
- RARCH_LOG("%s: %d\n", axes[pad_axis], interpolated);
-#endif
- }
-}
-
-/**
- * The USB packet provides a 9-byte data packet for each pad.
- *
- * byte 0: connection status (0x14 = connected, 0x04 = disconnected)
- * bytes 1-2: digital buttons
- * bytes 3-4: left analog stick x/y
- * bytes 5-6: right analog stick x/y
- * bytes 7-8: L/R analog state (note that these have digital buttons too)
- */
-static void wiiu_gca_packet_handler(void *data, uint8_t *packet, uint16_t size)
-{
- gca_pad_t *pad = (gca_pad_t *)data;
-
- if (!pad || !packet || size > sizeof(pad->data))
- return;
-
- memcpy(pad->data, packet, size);
- update_buttons(pad);
- wiiu_gca_update_analog_state(pad);
-}
-
-static void wiiu_gca_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) { }
-
-static int16_t wiiu_gca_get_axis(void *data, unsigned axis)
-{
- axis_data axis_data;
-
- gca_pad_t *pad = (gca_pad_t *)data;
-
- gamepad_read_axis_data(axis, &axis_data);
-
- if (!pad || axis_data.axis >= 4)
- return 0;
-
- return gamepad_get_axis_value(pad->analog_state, &axis_data);
-}
-
-static const char *wiiu_gca_get_name(void *data)
-{
- return "GameCube Controller";
-}
-
-/**
- * Button bitmask values:
- * 0x0001 - A 0x0010 - left 0x0100 - Start/Pause
- * 0x0002 - B 0x0020 - right 0x0200 - Z
- * 0x0004 - X 0x0040 - down 0x0400 - R
- * 0x0008 - Y 0x0080 - up 0x0800 - L
- */
-
-static int32_t wiiu_gca_button(void *data, uint16_t joykey)
-{
- gca_pad_t *pad = (gca_pad_t *)data;
- if(!pad || joykey > 31)
- return 0;
- return pad->buttons & (1 << joykey);
-}
-
-pad_connection_interface_t wiiu_gca_pad_connection = {
- wiiu_gca_pad_init,
- wiiu_gca_pad_deinit,
- wiiu_gca_packet_handler,
- wiiu_gca_set_rumble,
- wiiu_gca_get_buttons,
- wiiu_gca_get_axis,
- wiiu_gca_get_name,
- wiiu_gca_button
-};
diff --git a/input/common/hid/hid_device_driver.c b/input/common/hid/hid_device_driver.c
deleted file mode 100644
index d9d8bb8d98..0000000000
--- a/input/common/hid/hid_device_driver.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-#include "hid_device_driver.h"
-
-hid_driver_instance_t hid_instance = {0};
-
-hid_device_t *hid_device_list[] =
-{
- &wiiu_gca_hid_device,
- &ds3_hid_device,
-#if 0
- &ds4_hid_device,
-#endif
- NULL /* must be last entry in list */
-};
-
-hid_device_t *hid_device_driver_lookup(
- uint16_t vendor_id, uint16_t product_id)
-{
- int i = 0;
-
- for (i = 0; hid_device_list[i] != NULL; i++)
- {
- if (hid_device_list[i]->detect(vendor_id, product_id))
- return hid_device_list[i];
- }
-
- return NULL;
-}
-
-joypad_connection_t *hid_pad_register(
- void *pad_handle, pad_connection_interface_t *iface)
-{
- int slot;
- joypad_connection_t *result;
-
- if (!pad_handle)
- return NULL;
-
- slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
-
- if (slot < 0)
- {
- RARCH_ERR("[hid]: failed to find a vacant pad.\n");
- return NULL;
- }
-
- result = &(hid_instance.pad_list[slot]);
- result->iface = iface;
- result->data = iface->init(pad_handle, slot, hid_instance.os_driver);
- result->connected = true;
- input_pad_connect(slot, hid_instance.pad_driver);
-
- return result;
-}
-
-void hid_pad_deregister(joypad_connection_t *pad)
-{
- if (!pad)
- return;
-
- if (pad->data)
- {
- pad->iface->deinit(pad->data);
- pad->data = NULL;
- }
-
- pad->iface = NULL;
- pad->connected = false;
-}
-
-static bool init_pad_list(hid_driver_instance_t *instance, unsigned slots)
-{
- if (!instance || slots > MAX_USERS)
- return false;
-
- if (instance->pad_list)
- return true;
-
- /* Initializing pad list.. */
- instance->pad_list = pad_connection_init(slots);
- if (!instance->pad_list)
- return false;
-
- instance->max_slot = slots;
-
- return true;
-}
-
-/**
- * Fill in instance with data from initialized hid subsystem.
- *
- * @argument instance the hid_driver_instance_t struct to fill in
- * @argument hid_driver the HID driver to initialize
- * @argument pad_driver the gamepad driver to handle HID pads
- * detected by the HID driver.
- *
- * @returns true if init is successful, false otherwise.
- */
-bool hid_init(hid_driver_instance_t *instance,
- hid_driver_t *hid_driver,
- input_device_driver_t *pad_driver,
- unsigned slots)
-{
- void *os_driver_data = NULL;
- if (!instance || !hid_driver || !pad_driver || slots > MAX_USERS)
- return false;
-
- /* Initializing HID subsystem driver */
- os_driver_data = hid_driver->init();
- if (!os_driver_data)
- return false;
-
- if (!init_pad_list(instance, slots))
- {
- hid_driver->free(os_driver_data);
- return false;
- }
-
- instance->os_driver_data = os_driver_data;
- instance->os_driver = hid_driver;
- instance->pad_driver = pad_driver;
-
- return true;
-}
-
-/**
- * Tear down the HID system set up by hid_init()
- *
- * @argument instance the hid_driver_instance_t to tear down.
- */
-void hid_deinit(hid_driver_instance_t *instance)
-{
- if (!instance)
- return;
-
- if (instance->os_driver && instance->os_driver_data)
- instance->os_driver->free(instance->os_driver_data);
-
- /* Destroying pad data.. */
- pad_connection_destroy(instance->pad_list);
-
- /* Wiping instance data.. */
- memset(instance, 0, sizeof(hid_driver_instance_t));
-}
diff --git a/input/common/hid/hid_device_driver.h b/input/common/hid/hid_device_driver.h
deleted file mode 100644
index 8e764f0f78..0000000000
--- a/input/common/hid/hid_device_driver.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2017 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * 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.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-#ifndef HID_DEVICE_DRIVER__H
-#define HID_DEVICE_DRIVER__H
-
-#include "../../input_driver.h"
-#include "../../connect/joypad_connection.h"
-#include "../../include/hid_driver.h"
-#include "../../include/gamepad.h"
-#include "../../../verbosity.h"
-#include "../../../tasks/tasks_internal.h"
-
-typedef struct hid_device {
- void *(*init)(void *handle);
- void (*free)(void *data);
- void (*handle_packet)(void *data, uint8_t *buffer, size_t size);
- bool (*detect)(uint16_t vid, uint16_t pid);
- const char *name;
-} hid_device_t;
-
-extern hid_device_t wiiu_gca_hid_device;
-extern hid_device_t ds3_hid_device;
-extern hid_device_t ds4_hid_device;
-extern hid_driver_instance_t hid_instance;
-
-hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id);
-joypad_connection_t *hid_pad_register(void *pad_handle, pad_connection_interface_t *iface);
-void hid_pad_deregister(joypad_connection_t *pad);
-bool hid_init(hid_driver_instance_t *instance, hid_driver_t *hid_driver, input_device_driver_t *pad_driver, unsigned slots);
-void hid_deinit(hid_driver_instance_t *instance);
-
-#endif /* HID_DEVICE_DRIVER__H */
diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c
index cc557cee46..ccb8031d9a 100644
--- a/input/connect/connect_nesusb.c
+++ b/input/connect/connect_nesusb.c
@@ -139,6 +139,14 @@ const char * hidpad_nesusb_get_name(void *data)
return "Generic NES USB Controller";
}
+static int32_t hidpad_nesusb_button(void *data, uint16_t joykey)
+{
+ struct hidpad_nesusb_data *pad = (struct hidpad_nesusb_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_nesusb = {
hidpad_nesusb_init,
hidpad_nesusb_deinit,
@@ -147,4 +155,6 @@ pad_connection_interface_t pad_connection_nesusb = {
hidpad_nesusb_get_buttons,
hidpad_nesusb_get_axis,
hidpad_nesusb_get_name,
+ hidpad_nesusb_button,
+ false,
};
diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c
index 6a324b9491..1dbc079b6a 100644
--- a/input/connect/connect_ps2adapter.c
+++ b/input/connect/connect_ps2adapter.c
@@ -174,6 +174,14 @@ const char * hidpad_ps2adapter_get_name(void *data)
return "PS2/PSX Controller Adapter";
}
+static int32_t hidpad_ps2adapter_button(void *data, uint16_t joykey)
+{
+ struct hidpad_ps2adapter_data *pad = (struct hidpad_ps2adapter_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_ps2adapter = {
hidpad_ps2adapter_init,
hidpad_ps2adapter_deinit,
@@ -182,4 +190,6 @@ pad_connection_interface_t pad_connection_ps2adapter = {
hidpad_ps2adapter_get_buttons,
hidpad_ps2adapter_get_axis,
hidpad_ps2adapter_get_name,
+ hidpad_ps2adapter_button,
+ false,
};
diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c
index 5ea88264ad..68af2e76b5 100644
--- a/input/connect/connect_ps3.c
+++ b/input/connect/connect_ps3.c
@@ -21,148 +21,205 @@
#include
#include "joypad_connection.h"
#include "../input_defines.h"
-#include "../common/hid/hid_device_driver.h"
-
-struct hidpad_ps3_data
-{
- struct pad_connection* connection;
- hid_driver_t *driver;
- uint32_t slot;
- uint32_t buttons;
- uint16_t motors[2];
- uint8_t data[512];
- bool have_led;
-};
-
-/*
- * TODO: give these more meaningful names.
- */
+#include "verbosity.h"
#define DS3_ACTIVATION_REPORT_ID 0xf4
#define DS3_RUMBLE_REPORT_ID 0x01
-static void hidpad_ps3_send_control(struct hidpad_ps3_data* device)
-{
- /* TODO: Can this be modified to turn off motion tracking? */
- static uint8_t report_buffer[] = {
- 0x52, 0x01,
- 0x00, 0xFF, 0x00, 0xFF, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
+typedef struct ds3_instance {
+ hid_driver_t *hid_driver;
+ void *handle;
+ int slot;
+ bool led_set;
+ uint32_t buttons;
+ int16_t analog_state[3][2];
+ uint16_t motors[2];
+ uint8_t data[64];
+} ds3_instance_t;
- /* Turn on the appropriate LED */
- report_buffer[11] = 1 << ((device->slot % 4) + 1);
- /* Set rumble state */
- report_buffer[4] = device->motors[1] >> 8;
- report_buffer[6] = device->motors[0] >> 8;
-#ifdef HAVE_WIIUSB_HID
- report_buffer[1] = 0x03; /* send control message type */
- device->driver->send_control(device->connection, &report_buffer[1], sizeof(report_buffer)-1);
-#elif defined(WIIU)
- device->driver->set_report(device->connection,
- HID_REPORT_OUTPUT,
- DS3_RUMBLE_REPORT_ID,
- report_buffer+2,
- sizeof(report_buffer) - (2*sizeof(uint8_t)));
-#else
- device->driver->send_control(device->connection, report_buffer, sizeof(report_buffer));
+static void ds3_update_pad_state(ds3_instance_t *instance);
+static void ds3_update_analog_state(ds3_instance_t *instance);
+
+static uint8_t ds3_activation_packet[] = {
+#if defined(IOS)
+ 0x53, 0xF4,
+#elif defined(HAVE_WIIUSB_HID)
+ 0x02,
#endif
+ 0x42, 0x0c, 0x00, 0x00
+};
+
+#if defined(WIIU)
+#define PACKET_OFFSET 2
+#elif defined(HAVE_WIIUSB_HID)
+#define PACKET_OFFSET 1
+#else
+#define PACKET_OFFSET 0
+#endif
+
+#define LED_OFFSET 11
+#define MOTOR1_OFFSET 4
+#define MOTOR2_OFFSET 6
+
+static uint8_t ds3_control_packet[] = {
+ 0x52, 0x01,
+ 0x00, 0xff, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+
+
+static int32_t ds3_send_control_packet(void *data, uint32_t slot, hid_driver_t *driver) {
+ int32_t result = 0;
+ uint8_t packet_buffer[64] = {0};
+ memcpy(packet_buffer, ds3_control_packet, sizeof(ds3_control_packet));
+
+ packet_buffer[LED_OFFSET] = 0;
+ packet_buffer[LED_OFFSET] = 1 << ((slot % 4) + 1);
+ packet_buffer[MOTOR1_OFFSET] = 0;
+ packet_buffer[MOTOR2_OFFSET] = 0;
+
+#if defined(HAVE_WIIUSB_HID)
+ packet_buffer[1] = 0x03;
+#endif
+
+#if defined(WIIU)
+ result = driver->set_report(data, HID_REPORT_OUTPUT, DS3_RUMBLE_REPORT_ID, packet_buffer+PACKET_OFFSET, 64-PACKET_OFFSET);
+#else
+ driver->send_control(data, packet_buffer+PACKET_OFFSET, 64-PACKET_OFFSET);
+#endif /* WIIU */
+ return result;
}
-static void* hidpad_ps3_init(void *data, uint32_t slot, hid_driver_t *driver)
+static int32_t ds3_send_activation_packet(void *data, uint32_t slot, hid_driver_t *driver) {
+ #ifdef WIIU
+ return driver->set_report(data, HID_REPORT_FEATURE, DS3_ACTIVATION_REPORT_ID, ds3_activation_packet, sizeof(ds3_activation_packet));
+ #else
+ driver->send_control(data, ds3_activation_packet, sizeof(ds3_activation_packet));
+ return 0;
+ #endif
+}
+
+static void *ds3_pad_init(void *data, uint32_t slot, hid_driver_t *driver)
{
-#if defined(HAVE_WIIUSB_HID) || defined(WIIU)
- /* Special command to enable Sixaxis, first byte defines the message type */
- static uint8_t magic_data[] = {0x02, 0x42, 0x0c, 0x00, 0x00};
-#elif defined(IOS)
- /* Magic packet to start reports. */
- static uint8_t magic_data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00};
-#endif
- struct pad_connection* connection = (struct pad_connection*)data;
- struct hidpad_ps3_data* device = (struct hidpad_ps3_data*)
- calloc(1, sizeof(struct hidpad_ps3_data));
+ ds3_instance_t *instance = (ds3_instance_t *)calloc(1, sizeof(ds3_instance_t));
+ int errors = 0;
- if (!device)
- return NULL;
+ driver->set_protocol(data, 1);
- if (!connection)
+ if (ds3_send_control_packet(data, slot, driver) < 0)
+ errors++;
+
+ /* Sending activation packet.. */
+ if (ds3_send_activation_packet(data, slot, driver) < 0)
+ errors++;
+
+ if (errors)
+ goto error;
+
+ instance->hid_driver = driver;
+ instance->handle = data;
+ instance->slot = slot;
+ instance->led_set = true;
+
+ return instance;
+
+ error:
+ free(instance);
+ return NULL;
+}
+
+static void ds3_pad_deinit(void *data)
+{
+ ds3_instance_t *pad = (ds3_instance_t *)data;
+ if (pad)
+ free(pad);
+}
+
+static void ds3_get_buttons(void *data, input_bits_t *state)
+{
+ ds3_instance_t *pad = (ds3_instance_t *)data;
+
+ if (pad)
{
- free(device);
- return NULL;
+ BITS_COPY16_PTR(state, pad->buttons);
+
+ if (pad->buttons & 0x10000)
+ BIT256_SET_PTR(state, RARCH_MENU_TOGGLE);
+ }
+ else
+ {
+ BIT256_CLEAR_ALL_PTR(state);
+ }
+}
+
+static void ds3_packet_handler(void *data, uint8_t *packet, uint16_t size)
+{
+ ds3_instance_t *instance = (ds3_instance_t *)data;
+ if(!instance) {
+ return;
}
- device->connection = connection;
- device->slot = slot;
- device->driver = driver;
+ if (!instance->led_set)
+ {
+ ds3_send_control_packet(instance->handle, instance->slot, instance->hid_driver);
+ instance->led_set = true;
+ }
-#if defined(IOS) || defined(HAVE_WIIUSB_HID)
- device->driver->send_control(device->connection, magic_data, sizeof(magic_data));
-#endif
+ if (size > sizeof(instance->data))
+ {
+ RARCH_ERR("[ds3]: Expecting packet to be %ld but was %d\n",
+ (long)sizeof(instance->data), size);
+ return;
+ }
-#ifdef WIIU
- device->driver->set_protocol(device->connection, 1);
- hidpad_ps3_send_control(device);
- device->driver->set_report(device->connection,
- HID_REPORT_FEATURE,
- DS3_ACTIVATION_REPORT_ID,
- magic_data+1,
- (sizeof(magic_data) - sizeof(uint8_t)));
-#endif
-
-#ifndef HAVE_WIIUSB_HID
- /* Without this, the digital buttons won't be reported. */
- hidpad_ps3_send_control(device);
-#endif
- return device;
+ memcpy(instance->data, packet, size);
+ ds3_update_pad_state(instance);
+ ds3_update_analog_state(instance);
}
-static void hidpad_ps3_deinit(void *data)
+const char * ds3_get_name(void *data)
{
- struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data;
-
- if (device)
- free(device);
+ (void)data;
+ /* For now we return a single static name */
+ return "PLAYSTATION(R)3 Controller";
}
-static void hidpad_ps3_get_buttons(void *data, input_bits_t *state)
-{
- struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data;
- if ( device )
- {
- /* copy 32 bits : needed for PS button? */
- BITS_COPY32_PTR(state, device->buttons);
- }
- else
- BIT256_CLEAR_ALL_PTR(state);
-}
+static void ds3_set_rumble(void *data,
+ enum retro_rumble_effect effect, uint16_t strength) { }
-static int16_t hidpad_ps3_get_axis(void *data, unsigned axis)
+static int16_t ds3_get_axis(void *data, unsigned axis)
{
- int val;
- struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data;
+ axis_data axis_data;
+ ds3_instance_t *pad = (ds3_instance_t *)data;
- if (!device || axis >= 4)
+ gamepad_read_axis_data(axis, &axis_data);
+
+ if (!pad || axis_data.axis >= 4)
return 0;
- val = device->data[7 + axis];
- val = (val << 8) - 0x8000;
-
- if (abs(val) > 0x1000)
- return val;
- return 0;
+ return gamepad_get_axis_value(pad->analog_state, &axis_data);
}
-static void hidpad_ps3_packet_handler(void *data,
- uint8_t *packet, uint16_t size)
+static int32_t ds3_button(void *data, uint16_t joykey)
+{
+ ds3_instance_t *pad = (ds3_instance_t *)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
+static void ds3_update_pad_state(ds3_instance_t *instance)
{
uint32_t i, pressed_keys;
+
static const uint32_t button_mapping[17] =
{
RETRO_DEVICE_ID_JOYPAD_SELECT,
@@ -181,59 +238,43 @@ static void hidpad_ps3_packet_handler(void *data,
RETRO_DEVICE_ID_JOYPAD_A,
RETRO_DEVICE_ID_JOYPAD_B,
RETRO_DEVICE_ID_JOYPAD_Y,
- 16 /* PS Button */
+ 16 /* PS button */
};
- struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data;
- if (!device)
- return;
+ instance->buttons = 0;
- if (!device->have_led)
+ pressed_keys = instance->data[2] |
+ (instance->data[3] << 8) |
+ ((instance->data[4] & 0x01) << 16);
+
+ for (i = 0; i < 17; i++)
+ instance->buttons |= (pressed_keys & (1 << i)) ?
+ (1 << button_mapping[i]) : 0;
+}
+
+static void ds3_update_analog_state(ds3_instance_t *instance)
+{
+ int pad_axis;
+ int16_t interpolated;
+ unsigned stick, axis;
+
+ for (pad_axis = 0; pad_axis < 4; pad_axis++)
{
- hidpad_ps3_send_control(device);
- device->have_led = true;
+ axis = pad_axis % 2 ? 0 : 1;
+ stick = pad_axis / 2;
+ interpolated = instance->data[6+pad_axis];
+ instance->analog_state[stick][axis] = (interpolated - 128) * 256;
}
-
- memcpy(device->data, packet, size);
-
- device->buttons = 0;
-
- pressed_keys = device->data[3] | (device->data[4] << 8) |
- ((device->data[5] & 1) << 16);
-
- for (i = 0; i < 17; i ++)
- device->buttons |= (pressed_keys & (1 << i)) ?
- (1 << button_mapping[i]) : 0;
-}
-
-static void hidpad_ps3_set_rumble(void *data,
- enum retro_rumble_effect effect, uint16_t strength)
-{
- struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data;
- unsigned idx = (effect == RETRO_RUMBLE_STRONG) ? 0 : 1;
-
- if (!device)
- return;
- if (device->motors[idx] == strength)
- return;
-
- device->motors[idx] = strength;
- hidpad_ps3_send_control(device);
-}
-
-const char * hidpad_ps3_get_name(void *data)
-{
- (void)data;
- /* For now we return a single static name */
- return "PLAYSTATION(R)3 Controller";
}
pad_connection_interface_t pad_connection_ps3 = {
- hidpad_ps3_init,
- hidpad_ps3_deinit,
- hidpad_ps3_packet_handler,
- hidpad_ps3_set_rumble,
- hidpad_ps3_get_buttons,
- hidpad_ps3_get_axis,
- hidpad_ps3_get_name,
-};
+ ds3_pad_init,
+ ds3_pad_deinit,
+ ds3_packet_handler,
+ ds3_set_rumble,
+ ds3_get_buttons,
+ ds3_get_axis,
+ ds3_get_name,
+ ds3_button,
+ false,
+};
\ No newline at end of file
diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c
index 5f9ae933b6..a0a236c662 100644
--- a/input/connect/connect_ps4.c
+++ b/input/connect/connect_ps4.c
@@ -26,7 +26,6 @@
#include "joypad_connection.h"
#include "../input_defines.h"
#include "../../driver.h"
-#include "../common/hid/hid_device_driver.h"
enum connect_ps4_dpad_states
{
@@ -286,6 +285,52 @@ static void hidpad_ps4_set_rumble(void *data,
#endif
}
+static int32_t hidpad_ps4_button(void *data, uint16_t joykey)
+{
+ struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data;
+ struct ps4 *rpt = device ?
+ (struct ps4*)&device->data : NULL;
+ if (!device || !rpt || joykey > 31)
+ return 0;
+
+ switch(joykey) {
+ case RETRO_DEVICE_ID_JOYPAD_R3:
+ return rpt->btn.r3;
+ case RETRO_DEVICE_ID_JOYPAD_L3:
+ return rpt->btn.l3;
+ case RETRO_DEVICE_ID_JOYPAD_START:
+ return rpt->btn.options;
+ case RETRO_DEVICE_ID_JOYPAD_SELECT:
+ return rpt->btn.share;
+ case RETRO_DEVICE_ID_JOYPAD_R2:
+ return rpt->btn.r2;
+ case RETRO_DEVICE_ID_JOYPAD_L2:
+ return rpt->btn.l2;
+ case RETRO_DEVICE_ID_JOYPAD_R:
+ return rpt->btn.r1;
+ case RETRO_DEVICE_ID_JOYPAD_L:
+ return rpt->btn.l1;
+ case RETRO_DEVICE_ID_JOYPAD_X:
+ return rpt->btn.triangle;
+ case RETRO_DEVICE_ID_JOYPAD_A:
+ return rpt->btn.circle;
+ case RETRO_DEVICE_ID_JOYPAD_B:
+ return rpt->btn.cross;
+ case RETRO_DEVICE_ID_JOYPAD_Y:
+ return rpt->btn.square;
+ case RETRO_DEVICE_ID_JOYPAD_LEFT:
+ case RETRO_DEVICE_ID_JOYPAD_RIGHT:
+ case RETRO_DEVICE_ID_JOYPAD_DOWN:
+ case RETRO_DEVICE_ID_JOYPAD_UP:
+ return hidpad_ps4_check_dpad(rpt, joykey);
+ case RARCH_MENU_TOGGLE:
+ return rpt->btn.ps;
+ default:
+ return 0;
+ }
+}
+
+
pad_connection_interface_t pad_connection_ps4 = {
hidpad_ps4_init,
hidpad_ps4_deinit,
@@ -293,5 +338,7 @@ pad_connection_interface_t pad_connection_ps4 = {
hidpad_ps4_set_rumble,
hidpad_ps4_get_buttons,
hidpad_ps4_get_axis,
- NULL,
+ NULL, /* get_name */
+ hidpad_ps4_button,
+ false
};
diff --git a/input/connect/connect_ps4_hori_mini.c b/input/connect/connect_ps4_hori_mini.c
index cd4e529622..31499687da 100644
--- a/input/connect/connect_ps4_hori_mini.c
+++ b/input/connect/connect_ps4_hori_mini.c
@@ -178,6 +178,14 @@ const char * hidpad_ps4_hori_mini_get_name(void *data)
return "HORI mini wired PS4";
}
+static int32_t hidpad_ps4_hori_mini_button(void *data, uint16_t joykey)
+{
+ struct hidpad_ps4_hori_mini_data *pad = (struct hidpad_ps4_hori_mini_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_ps4_hori_mini = {
hidpad_ps4_hori_mini_init,
hidpad_ps4_hori_mini_deinit,
@@ -186,4 +194,6 @@ pad_connection_interface_t pad_connection_ps4_hori_mini = {
hidpad_ps4_hori_mini_get_buttons,
hidpad_ps4_hori_mini_get_axis,
hidpad_ps4_hori_mini_get_name,
+ hidpad_ps4_hori_mini_button, /* button */
+ false
};
diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c
index 27332a149f..094ed4c16a 100644
--- a/input/connect/connect_psxadapter.c
+++ b/input/connect/connect_psxadapter.c
@@ -183,6 +183,14 @@ const char * hidpad_psxadapter_get_name(void *data)
return "PSX to PS3 Controller Adapter";
}
+static int32_t hidpad_psxadapter_button(void *data, uint16_t joykey)
+{
+ struct hidpad_psxadapter_data *pad = (struct hidpad_psxadapter_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_psxadapter = {
hidpad_psxadapter_init,
hidpad_psxadapter_deinit,
@@ -191,4 +199,6 @@ pad_connection_interface_t pad_connection_psxadapter = {
hidpad_psxadapter_get_buttons,
hidpad_psxadapter_get_axis,
hidpad_psxadapter_get_name,
+ hidpad_psxadapter_button,
+ false
};
diff --git a/input/connect/connect_retrode.c b/input/connect/connect_retrode.c
index 58fc31f504..648bf18a01 100644
--- a/input/connect/connect_retrode.c
+++ b/input/connect/connect_retrode.c
@@ -189,6 +189,14 @@ const char * hidpad_retrode_get_name(void *data)
return "Retrode";
}
+static int32_t hidpad_retrode_button(void *data, uint16_t joykey)
+{
+ struct hidpad_retrode_data *pad = (struct hidpad_retrode_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_retrode = {
hidpad_retrode_init,
hidpad_retrode_deinit,
@@ -197,4 +205,6 @@ pad_connection_interface_t pad_connection_retrode = {
hidpad_retrode_get_buttons,
hidpad_retrode_get_axis,
hidpad_retrode_get_name,
+ hidpad_retrode_button,
+ false,
};
diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c
index 13bf4a0d14..39fb9a9340 100644
--- a/input/connect/connect_snesusb.c
+++ b/input/connect/connect_snesusb.c
@@ -140,6 +140,14 @@ const char * hidpad_snesusb_get_name(void *data)
return "Generic SNES USB Controller";
}
+static int32_t hidpad_snesusb_button(void *data, uint16_t joykey)
+{
+ struct hidpad_snesusb_data *pad = (struct hidpad_snesusb_data*)data;
+ if (!pad || joykey > 31)
+ return 0;
+ return pad->buttons & (1 << joykey);
+}
+
pad_connection_interface_t pad_connection_snesusb = {
hidpad_snesusb_init,
hidpad_snesusb_deinit,
@@ -148,4 +156,6 @@ pad_connection_interface_t pad_connection_snesusb = {
hidpad_snesusb_get_buttons,
hidpad_snesusb_get_axis,
hidpad_snesusb_get_name,
+ hidpad_snesusb_button,
+ false
};
diff --git a/input/connect/connect_wii.c b/input/connect/connect_wii.c
index 974e9c61ad..1c7029a56f 100644
--- a/input/connect/connect_wii.c
+++ b/input/connect/connect_wii.c
@@ -26,7 +26,6 @@
#include "joypad_connection.h"
#include "../input_defines.h"
-#include "../common/hid/hid_device_driver.h"
/* wiimote state flags*/
#define WIIMOTE_STATE_DEV_FOUND 0x0001
@@ -723,6 +722,8 @@ static void hidpad_wii_set_rumble(void *data,
(void)strength;
}
+/* TODO: implement hidpad_wii_button(). */
+
pad_connection_interface_t pad_connection_wii = {
hidpad_wii_init,
hidpad_wii_deinit,
@@ -730,5 +731,7 @@ pad_connection_interface_t pad_connection_wii = {
hidpad_wii_set_rumble,
hidpad_wii_get_buttons,
hidpad_wii_get_axis,
- NULL,
+ NULL, /* get_name */
+ NULL, /* button */
+ false,
};
diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c
index 012d29e6d0..2e8bd45615 100644
--- a/input/connect/connect_wiiugca.c
+++ b/input/connect/connect_wiiugca.c
@@ -21,17 +21,45 @@
#include
#include "joypad_connection.h"
#include "../input_defines.h"
-#include "../common/hid/hid_device_driver.h"
+
+#define GCA_MAX_PAD 4
+
+#define GCA_TYPE_DEVICE 0x00
+#define GCA_TYPE_PAD 0x01
+
+#define GCA_PORT_INITIALIZING 0x00
+#define GCA_PORT_POWERED 0x04
+#define GCA_PORT_CONNECTED 0x10
+#define GCA_WAVEBIRD_CONNECTED 0x22
+
+typedef struct hidpad_wiiugca_pad_data gca_pad_data_t;
+typedef struct hidpad_wiiugca_data gca_device_data_t;
+
+struct hidpad_wiiugca_pad_data
+{
+ uint8_t datatype;
+ gca_device_data_t *device_data;
+ joypad_connection_t *joypad;
+ int pad_index;
+ uint32_t buttons;
+ int16_t analog[3][2];
+ uint8_t data[9];
+};
struct hidpad_wiiugca_data
{
- struct pad_connection* connection;
+ uint8_t datatype;
+ void *handle;
hid_driver_t *driver;
+ char connected[GCA_MAX_PAD];
+ gca_pad_data_t pad_data[GCA_MAX_PAD];
uint8_t data[64];
- uint32_t slot;
- uint32_t buttons;
};
+const char *GAMECUBE_PAD = "GameCube controller";
+const char *WAVEBIRD_PAD = "WaveBird controller";
+const char *DEVICE_NAME = "Wii U GC Controller Adapter";
+
static void* hidpad_wiiugca_init(void *data, uint32_t slot, hid_driver_t *driver)
{
#ifdef WIIU
@@ -39,70 +67,79 @@ static void* hidpad_wiiugca_init(void *data, uint32_t slot, hid_driver_t *driver
#else
static uint8_t magic_data[] = {0x01, 0x13}; /* Special command to enable reading */
#endif
- struct pad_connection* connection = (struct pad_connection*)data;
- struct hidpad_wiiugca_data* device = (struct hidpad_wiiugca_data*)
- calloc(1, sizeof(struct hidpad_wiiugca_data));
+ int i;
+ gca_device_data_t * device = (gca_device_data_t *)calloc(1, sizeof(gca_device_data_t));
if (!device)
return NULL;
- if (!connection)
+ if (!data)
{
free(device);
return NULL;
}
- device->connection = connection;
- device->slot = slot;
+ device->handle = data;
+ for(i = 0; i < GCA_MAX_PAD; i++) {
+ device->pad_data[i].datatype = GCA_TYPE_PAD;
+ device->pad_data[i].device_data = device;
+ device->pad_data[i].joypad = NULL;
+ device->pad_data[i].pad_index = i;
+ }
+
device->driver = driver;
- device->driver->send_control(device->connection, magic_data, sizeof(magic_data));
+ device->driver->send_control(device->handle, magic_data, sizeof(magic_data));
return device;
}
-static void hidpad_wiiugca_deinit(void *data)
+static void hidpad_wiiugca_deinit(void *device_data)
{
- struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data;
+ gca_device_data_t *device = (gca_device_data_t *)device_data;
if (device)
free(device);
}
-static void hidpad_wiiugca_get_buttons(void *data, input_bits_t *state)
+static void hidpad_wiiugca_get_buttons(void *pad_data, input_bits_t *state)
{
- struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data;
- if (device)
- {
- BITS_COPY16_PTR(state, device->buttons);
- }
- else
- BIT256_CLEAR_ALL_PTR(state);
+ gca_pad_data_t *pad = (gca_pad_data_t *)pad_data;
+ if (pad) {
+ if(pad->datatype == GCA_TYPE_PAD) {
+ BITS_COPY16_PTR(state, pad->buttons);
+ } else {
+ gca_device_data_t *device = (gca_device_data_t *)pad_data;
+ BITS_COPY16_PTR(state, device->pad_data[0].buttons);
+ }
+ }
+ else
+ {
+ BIT256_CLEAR_ALL_PTR(state);
+ }
}
-static int16_t hidpad_wiiugca_get_axis(void *data, unsigned axis)
+static int16_t hidpad_wiiugca_get_axis(void *pad_data, unsigned axis)
{
- int val;
- struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data;
+ gca_pad_data_t *pad = (gca_pad_data_t *)pad_data;
+ axis_data axis_data;
- if (!device || axis >= 4)
+ gamepad_read_axis_data(axis, &axis_data);
+
+ if (!pad || axis_data.axis >= 4)
return 0;
- val = device->data[5 + axis];
-
- if (axis % 2) /* the Y axis is inverted */
- val = 0x8000 - (val << 8);
- else
- val = (val << 8) - 0x8000;
-
- if (abs(val) > 0x1000)
- return val;
- return 0;
+ if(pad->datatype == GCA_TYPE_PAD)
+ return gamepad_get_axis_value(pad->analog, &axis_data);
+ else {
+ gca_device_data_t *device = (gca_device_data_t *)pad_data;
+ return gamepad_get_axis_value(device->pad_data[0].analog, &axis_data);
+ }
}
-static void hidpad_wiiugca_packet_handler(void *data, uint8_t *packet, uint16_t size)
-{
+static void update_button_state(gca_pad_data_t *pad) {
uint32_t i, pressed_keys;
+
static const uint32_t button_mapping[12] =
{
RETRO_DEVICE_ID_JOYPAD_A,
@@ -118,20 +155,80 @@ static void hidpad_wiiugca_packet_handler(void *data, uint8_t *packet, uint16_t
RETRO_DEVICE_ID_JOYPAD_R,
RETRO_DEVICE_ID_JOYPAD_L,
};
- struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data;
+
+ if (!pad)
+ return;
+
+ pressed_keys = pad->data[1] | (pad->data[2] << 8);
+ pad->buttons = 0;
+
+ for (i = 0; i < 12; i++)
+ pad->buttons |= (pressed_keys & (1 << i)) ?
+ (1 << button_mapping[i]) : 0;
+}
+
+static void update_analog_state(gca_pad_data_t *pad) {
+ int pad_axis;
+ int16_t interpolated;
+ unsigned stick, axis;
+
+ /* GameCube analog axis are 8-bit unsigned, where 128/128 is center.
+ * So, we subtract 128 to get a signed, 0-based value and then mulitply
+ * by 256 to get the 16-bit range RetroArch expects. */
+ for (pad_axis = 0; pad_axis < 4; pad_axis++)
+ {
+ axis = (pad_axis % 2) ? 0 : 1;
+ stick = pad_axis / 2;
+ interpolated = pad->data[3 + pad_axis];
+ /* libretro requires "up" to be negative, so we invert the y axis */
+ interpolated = (axis) ?
+ ((interpolated - 128) * 256) :
+ ((interpolated - 128) * -256);
+
+ pad->analog[stick][axis] = interpolated;
+ }
+}
+
+static void hidpad_wiiugca_pad_packet_handler(gca_pad_data_t *pad, uint8_t *packet, size_t size) {
+ if(size > 9) {
+ return;
+ }
+
+ memcpy(pad->data, packet, size);
+ update_button_state(pad);
+ update_analog_state(pad);
+}
+
+
+
+static void hidpad_wiiugca_packet_handler(void *device_data, uint8_t *packet, uint16_t size)
+{
+ uint32_t i;
+ int port;
+ unsigned char port_connected;
+
+ gca_device_data_t *device = (gca_device_data_t *)device_data;
if (!device)
return;
memcpy(device->data, packet, size);
- device->buttons = 0;
+ for (i = 1; i < 37; i += 9)
+ {
+ port = i / 9;
+ port_connected = device->data[i];
- pressed_keys = device->data[3] | (device->data[4] << 8);
-
- for (i = 0; i < 12; i ++)
- device->buttons |= (pressed_keys & (1 << i)) ?
- (1 << button_mapping[i]) : 0;
+ if (port_connected > GCA_PORT_POWERED)
+ {
+ device->connected[port] = port_connected;
+ hidpad_wiiugca_pad_packet_handler(&device->pad_data[port], &device->data[i], 9);
+ }
+ else
+ {
+ device->connected[port] = 0;
+ }
+ }
}
static void hidpad_wiiugca_set_rumble(void *data,
@@ -142,11 +239,86 @@ static void hidpad_wiiugca_set_rumble(void *data,
(void)strength;
}
-const char *hidpad_wiiugca_get_name(void *data)
+const char *hidpad_wiiugca_get_name(void *pad_data)
{
- (void)data;
+ gca_pad_data_t *pad = (gca_pad_data_t *)pad_data;
+ if(!pad || pad->datatype != GCA_TYPE_PAD) {
+ return DEVICE_NAME;
+ }
+
+ switch(pad->device_data->connected[pad->pad_index]) {
+ case 0:
+ return DEVICE_NAME;
+ case GCA_WAVEBIRD_CONNECTED:
+ return WAVEBIRD_PAD;
+ default:
+ return GAMECUBE_PAD;
+ }
+
/* For now we return a single static name */
- return "Wii U GC Controller Adapter";
+
+}
+
+static int32_t hidpad_wiiugca_button(void *pad_data, uint16_t joykey) {
+ gca_pad_data_t *pad = (gca_pad_data_t *)pad_data;
+
+ if(!pad) return 0;
+
+ if(pad->datatype != GCA_TYPE_PAD) {
+ gca_device_data_t *device = (gca_device_data_t *)pad_data;
+ pad = &device->pad_data[0];
+ }
+
+ if (!pad->device_data || joykey > 31 || pad->joypad == NULL)
+ return 0;
+
+ return pad->buttons & (1 << joykey);
+}
+
+static void *hidpad_wiiugca_pad_init(void *device_data, int pad_index, joypad_connection_t *joypad) {
+ gca_device_data_t *device = (gca_device_data_t *)device_data;
+
+ if(!device || pad_index < 0 || pad_index >= GCA_MAX_PAD || joypad == NULL || device->pad_data[pad_index].joypad != NULL || !device->connected[pad_index]) {
+ return NULL;
+ }
+
+ device->pad_data[pad_index].joypad = joypad;
+ return &device->pad_data[pad_index];
+}
+
+static void hidpad_wiiugca_pad_deinit(void *pad_data) {
+ gca_pad_data_t *pad = (gca_pad_data_t *)pad_data;
+
+ if(!pad) {
+ return;
+ }
+
+ pad->joypad = NULL;
+}
+
+static int8_t hidpad_wiiugca_status(void *device_data, int pad_index) {
+ gca_device_data_t *device = (gca_device_data_t *)device_data;
+ int8_t result = 0;
+
+ if(!device || pad_index < 0 || pad_index >= GCA_MAX_PAD) return 0;
+
+ if(device->connected[pad_index]) {
+ result |= PAD_CONNECT_READY;
+ }
+
+ if(device->pad_data[pad_index].joypad != NULL) {
+ result |= PAD_CONNECT_BOUND;
+ }
+
+ return result;
+}
+
+static joypad_connection_t *hidpad_wiiugca_joypad(void *device_data, int pad_index) {
+ gca_device_data_t *device = (gca_device_data_t *)device_data;
+
+ if(!device || pad_index < 0 || pad_index >= GCA_MAX_PAD) return 0;
+
+ return device->pad_data[pad_index].joypad;
}
pad_connection_interface_t pad_connection_wiiugca = {
@@ -157,4 +329,11 @@ pad_connection_interface_t pad_connection_wiiugca = {
hidpad_wiiugca_get_buttons,
hidpad_wiiugca_get_axis,
hidpad_wiiugca_get_name,
+ hidpad_wiiugca_button,
+ true,
+ GCA_MAX_PAD,
+ hidpad_wiiugca_pad_init,
+ hidpad_wiiugca_pad_deinit,
+ hidpad_wiiugca_status,
+ hidpad_wiiugca_joypad,
};
diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c
index 01e20252c5..51ee3f3ad1 100644
--- a/input/connect/connect_wiiupro.c
+++ b/input/connect/connect_wiiupro.c
@@ -23,7 +23,6 @@
#include "joypad_connection.h"
#include "../input_defines.h"
#include "../../driver.h"
-#include "../common/hid/hid_device_driver.h"
struct wiiupro_buttons
{
@@ -249,6 +248,56 @@ static void hidpad_wiiupro_set_rumble(void *data,
/* TODO */
}
+static int32_t hidpad_wiiupro_button(void *data, uint16_t joykey)
+{
+ struct hidpad_wiiupro_data *device = (struct hidpad_wiiupro_data*)data;
+ struct wiiupro *rpt = device ?
+ (struct wiiupro*)&device->data : NULL;
+
+ if (!device || !rpt)
+ return 0;
+
+ switch(joykey) {
+ case RETRO_DEVICE_ID_JOYPAD_R3:
+ return rpt->btn.r3;
+ case RETRO_DEVICE_ID_JOYPAD_L3:
+ return rpt->btn.l3;
+ case RETRO_DEVICE_ID_JOYPAD_START:
+ return rpt->btn.plus;
+ case RETRO_DEVICE_ID_JOYPAD_SELECT:
+ return rpt->btn.minus;
+ case RETRO_DEVICE_ID_JOYPAD_R2:
+ return rpt->btn.zr;
+ case RETRO_DEVICE_ID_JOYPAD_L2:
+ return rpt->btn.zl;
+ case RETRO_DEVICE_ID_JOYPAD_R:
+ return rpt->btn.r;
+ case RETRO_DEVICE_ID_JOYPAD_L:
+ return rpt->btn.l;
+ case RETRO_DEVICE_ID_JOYPAD_X:
+ return rpt->btn.x;
+ case RETRO_DEVICE_ID_JOYPAD_A:
+ return rpt->btn.a;
+ case RETRO_DEVICE_ID_JOYPAD_B:
+ return rpt->btn.b;
+ case RETRO_DEVICE_ID_JOYPAD_Y:
+ return rpt->btn.y;
+ case RETRO_DEVICE_ID_JOYPAD_LEFT:
+ return rpt->btn.left;
+ case RETRO_DEVICE_ID_JOYPAD_RIGHT:
+ return rpt->btn.right;
+ case RETRO_DEVICE_ID_JOYPAD_DOWN:
+ return rpt->btn.down;
+ case RETRO_DEVICE_ID_JOYPAD_UP:
+ return rpt->btn.up;
+ case RARCH_MENU_TOGGLE:
+ return rpt->btn.home;
+ default:
+ return 0;
+ }
+
+}
+
pad_connection_interface_t pad_connection_wiiupro = {
hidpad_wiiupro_init,
hidpad_wiiupro_deinit,
@@ -256,5 +305,7 @@ pad_connection_interface_t pad_connection_wiiupro = {
hidpad_wiiupro_set_rumble,
hidpad_wiiupro_get_buttons,
hidpad_wiiupro_get_axis,
- NULL,
+ NULL, /* get_name */
+ hidpad_wiiupro_button,
+ false
};
diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c
index 6174c7f45b..077d099e97 100644
--- a/input/connect/joypad_connection.c
+++ b/input/connect/joypad_connection.c
@@ -18,12 +18,33 @@
#include
#include
+#include "../tasks/tasks_internal.h"
#include "../input_driver.h"
#include "../../verbosity.h"
#include "joypad_connection.h"
+
+
+/* we init the hid/vid to 0 because we need to do endian magic that we can't do during the declaration */
+joypad_connection_entry_t pad_map[] = {
+ { "Nintendo RVL-CNT-01", 0, 0, &pad_connection_wii },
+ { "Nintendo RVL-CNT-01-UC", 0, 0, &pad_connection_wiiupro },
+ { "Wireless Controller", 0, 0, &pad_connection_ps4 },
+ { "PLAYSTATION(R)3 Controller", 0, 0, &pad_connection_ps3 },
+ { "PLAYSTATION(R)3 Controller", 0, 0, &pad_connection_ps3 },
+ { "Generic SNES USB Controller", 0, 0, &pad_connection_snesusb },
+ { "Generic NES USB Controller", 0, 0, &pad_connection_nesusb },
+ { "Wii U GC Controller Adapter", 0, 0, &pad_connection_wiiugca },
+ { "PS2/PSX Controller Adapter", 0, 0, &pad_connection_ps2adapter },
+ { "PSX to PS3 Controller Adapter", 0, 0, &pad_connection_psxadapter },
+ { "Mayflash DolphinBar", 0, 0, &pad_connection_wii },
+ { "Retrode", 0, 0, &pad_connection_retrode },
+ { "HORI mini wired PS4", 0, 0, &pad_connection_ps4_hori_mini },
+ { 0, 0}
+};
+
static bool joypad_is_end_of_list(joypad_connection_t *pad)
{
return pad
@@ -93,42 +114,7 @@ joypad_connection_t *pad_connection_init(unsigned pads)
return joyconn;
}
-int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
- const char *name, uint16_t vid, uint16_t pid,
- void *data, hid_driver_t *driver)
-{
-
- static struct
- {
- const char* name;
- uint16_t vid;
- uint16_t pid;
- pad_connection_interface_t *iface;
- } pad_map[] =
- {
- { "Nintendo RVL-CNT-01", 0, 0, &pad_connection_wii },
- { "Nintendo RVL-CNT-01-UC", 0, 0, &pad_connection_wiiupro },
- { "Wireless Controller", 0, 0, &pad_connection_ps4 },
- { "PLAYSTATION(R)3 Controller", 0, 0, &pad_connection_ps3 },
- { "PLAYSTATION(R)3 Controller", 0, 0, &pad_connection_ps3 },
- { "Generic SNES USB Controller", 0, 0, &pad_connection_snesusb },
- { "Generic NES USB Controller", 0, 0, &pad_connection_nesusb },
- { "Wii U GC Controller Adapter", 0, 0, &pad_connection_wiiugca },
- { "PS2/PSX Controller Adapter", 0, 0, &pad_connection_ps2adapter },
- { "PSX to PS3 Controller Adapter", 0, 0, &pad_connection_psxadapter },
- { "Mayflash DolphinBar", 0, 0, &pad_connection_wii },
- { "Retrode", 0, 0, &pad_connection_retrode },
- { "HORI mini wired PS4", 0, 0, &pad_connection_ps4_hori_mini },
- { 0, 0}
- };
- joypad_connection_t *s = NULL;
- int pad = pad_connection_find_vacant_pad(joyconn);
-
- if (pad == -1)
- return -1;
-
- s = &joyconn[pad];
-
+void init_pad_map() {
pad_map[0].vid = VID_NINTENDO;
pad_map[0].pid = PID_NINTENDO_PRO;
pad_map[1].vid = VID_NINTENDO;
@@ -155,66 +141,197 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
pad_map[11].pid = PID_RETRODE;
pad_map[12].vid = VID_HORI_1;
pad_map[12].pid = PID_HORI_MINI_WIRED_PS4;
+}
- if (s)
- {
- unsigned i;
-
- const bool has_name = !string_is_empty(name);
- for (i = 0; name && pad_map[i].name; i++)
+joypad_connection_entry_t *find_connection_entry(int16_t vid, int16_t pid, const char *name) {
+ unsigned i;
+ const bool has_name = !string_is_empty(name);
+
+ if(pad_map[0].vid == 0) {
+ init_pad_map();
+ }
+
+ for(i = 0; pad_map[i].name != NULL; i++) {
+ const char *name_match = has_name ? strstr(pad_map[i].name, name) : NULL;
+ /* The Wii Pro Controller and Wii U pro controller have the same VID/PID, so we have to use the
+ * descriptor string to differentiate them. */
+ if(pad_map[i].vid == VID_NINTENDO && pad_map[i].pid == PID_NINTENDO_PRO)
{
- const char *name_match = has_name ? strstr(pad_map[i].name, name) : NULL;
+ if(!string_is_equal(pad_map[i].name, name))
+ continue;
+ }
- /* Never change, Nintendo. */
- if(pad_map[i].vid == 1406 && pad_map[i].pid == 816)
- {
- if(!string_is_equal(pad_map[i].name, name))
- continue;
- }
-
-#if 0
- RARCH_LOG("[connect] %s\n", pad_map[i].name);
- RARCH_LOG("[connect] VID: Expected: %04x got: %04x\n",
- pad_map[i].vid, vid);
- RARCH_LOG("[connect] PID: Expected: %04x got: %04x\n",
- pad_map[i].pid, pid);
-#endif
-
- if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
- {
- RARCH_DBG("Pad was matched to \"%s\". Setting up an interface.\n", name_match);
- s->iface = pad_map[i].iface;
- s->data = data;
- s->connection = s->iface->init(data, pad, driver);
- s->connected = true;
-#if 0
- RARCH_LOG("%s found \n", pad_map[i].name);
-#endif
- break;
- }
-#if 0
- else
- {
- RARCH_LOG("%s not found \n", pad_map[i].name);
- }
-#endif
- }
-
- /* We failed to find a matching pad,
- * set up one without an interface */
- if (!s->connected)
- {
- RARCH_DBG("Pad was not matched. Setting up without an interface.\n");
- s->iface = NULL;
- s->data = data;
- s->connected = true;
+ if(name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid)) {
+ return &pad_map[i];
}
}
+ return NULL;
+}
+
+void pad_connection_pad_deregister(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *pad_data) {
+ int i;
+
+ RARCH_LOG("pad_connection_pad_deregister\n");
+ RARCH_LOG("joyconn: 0x%08lx iface: 0x%08lx pad_data: 0x%08lx\n", (unsigned long)joyconn, (unsigned long)iface, (unsigned long)pad_data);
+ for(i = 0; !joypad_is_end_of_list(&joyconn[i]); i++) {
+ RARCH_LOG("joyconn[i].connected = %d, joyconn[i].iface == iface = %d\n", joyconn[i].connected, joyconn[i].iface == iface);
+ if(joyconn[i].connected && joyconn[i].iface == iface && iface != NULL) {
+ if(iface->set_rumble) {
+ RARCH_LOG("set_rumble");
+ iface->set_rumble(joyconn[i].connection, RETRO_RUMBLE_STRONG, 0);
+ iface->set_rumble(joyconn[i].connection, RETRO_RUMBLE_WEAK, 0);
+ }
+ RARCH_LOG("deregistering pad");
+ input_autoconfigure_disconnect(i, iface->get_name(joyconn[i].connection));
+ if(iface->multi_pad) {
+ RARCH_LOG("multi-pad cleanup");
+ iface->pad_deinit(&joyconn[i].connection);
+ }
+ RARCH_LOG("zeroing pad %d\n", i);
+ memset(&joyconn[i], 0, sizeof(joypad_connection_t));
+ }
+ }
+}
+
+static int joypad_to_slot(joypad_connection_t *haystack, joypad_connection_t *needle) {
+ int i;
+
+ for(i = 0; !joypad_is_end_of_list(&haystack[i]); i++) {
+ if(&haystack[i] == needle) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void pad_connection_pad_refresh(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *device_data, void *handle, input_device_driver_t *input_driver) {
+ int i, slot;
+ int8_t state;
+ joypad_connection_t *joypad;
+
+ if(!iface->multi_pad || iface->max_pad < 1) {
+ return;
+ }
+
+ for(i = 0; i < iface->max_pad; i++) {
+ state = iface->status(device_data, i);
+ switch(state) {
+ /* The pad slot is bound to a joypad that's no longer connected */
+ case PAD_CONNECT_BOUND:
+ RARCH_LOG("PAD_CONNECT_BOUND (0x%02x)\n", state);
+ joypad = iface->joypad(device_data, i);
+ slot = joypad_to_slot(joyconn, joypad);
+ input_autoconfigure_disconnect(slot, iface->get_name(joypad->connection));
+
+ iface->pad_deinit(joypad->connection);
+ memset(joypad, 0, sizeof(joypad_connection_t));
+ break;
+ /* The joypad is connected but has not been bound */
+ case PAD_CONNECT_READY:
+ slot = pad_connection_find_vacant_pad(joyconn);
+ if(slot >= 0) {
+ joypad = &joyconn[slot];
+ joypad->connection = iface->pad_init(device_data, i, joypad);
+ joypad->data = handle;
+ joypad->iface = iface;
+ joypad->input_driver = input_driver;
+ joypad->connected = true;
+ input_pad_connect(slot, input_driver);
+ }
+ break;
+ default:
+ if(state > 0x03) {
+ RARCH_LOG("Unrecognized state: 0x%02x", state);
+ }
+ break;
+ }
+ }
+}
+
+void pad_connection_pad_register(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *device_data, void *handle, input_device_driver_t *input_driver, int slot) {
+ int i, status;
+ int found_slot;
+ int max_pad;
+ void *connection;
+
+ if(iface->multi_pad && (iface->max_pad <= 1 || !iface->status || !iface->pad_init)) {
+ RARCH_ERR("pad_connection_pad_register: multi-pad driver has incomplete implementation\n");
+ return;
+ }
+
+ max_pad = iface->multi_pad ? iface->max_pad : 1;
+
+ for(i = 0; i < max_pad; i++) {
+ status = iface->multi_pad ? iface->status(device_data, i) : PAD_CONNECT_READY;
+ if(status == PAD_CONNECT_READY) {
+ found_slot = (slot == SLOT_AUTO) ? pad_connection_find_vacant_pad(joyconn) : slot;
+ if(found_slot < 0) {
+ continue;
+ }
+ connection = device_data;
+ if(iface->multi_pad) {
+ RARCH_LOG("pad_connection_pad_register: multi-pad detected, initializing pad %d\n", i);
+ connection = iface->pad_init(device_data, i, &joyconn[found_slot]);
+ }
+
+ joyconn[found_slot].iface = iface;
+ joyconn[found_slot].data = handle;
+ joyconn[found_slot].connection = connection;
+ joyconn[found_slot].input_driver = input_driver;
+ joyconn[found_slot].connected = true;
+
+ RARCH_LOG("connecting pad to slot %d\n", found_slot);
+ input_pad_connect(found_slot, input_driver);
+ }
+ }
+}
+
+int32_t pad_connection_pad_init_entry(joypad_connection_t *joyconn, joypad_connection_entry_t *entry, void *data, hid_driver_t *driver) {
+ joypad_connection_t *conn = NULL;
+ int pad = pad_connection_find_vacant_pad(joyconn);
+
+ if(pad < 0) {
+ return -1;
+ }
+
+ conn = &joyconn[pad];
+ if(!conn) {
+ return -1;
+ }
+
+ if(entry) {
+ conn->iface = entry->iface;
+ conn->data = data;
+ conn->connection = conn->iface->init(data, pad, driver);
+ conn->connected = true;
+ } else {
+ /* We failed to find a matching pad, set up one without an interface */
+ RARCH_DBG("Pad was not matched. Setting up without an interface.\n");
+ conn->iface = NULL;
+ conn->data = data;
+ conn->connected = true;
+ }
+
return pad;
}
+int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
+ const char *name, uint16_t vid, uint16_t pid,
+ void *data, hid_driver_t *driver)
+{
+ joypad_connection_entry_t *entry = NULL;
+
+ if(pad_map[0].vid == 0) {
+ init_pad_map();
+ }
+
+ entry = find_connection_entry(vid, pid, name);
+
+ return pad_connection_pad_init_entry(joyconn, entry, data, driver);
+}
+
void pad_connection_pad_deinit(joypad_connection_t *joyconn, uint32_t pad)
{
if (!joyconn || !joyconn->connected)
@@ -222,6 +339,7 @@ void pad_connection_pad_deinit(joypad_connection_t *joyconn, uint32_t pad)
if (joyconn->iface)
{
+
joyconn->iface->set_rumble(joyconn->connection, RETRO_RUMBLE_STRONG, 0);
joyconn->iface->set_rumble(joyconn->connection, RETRO_RUMBLE_WEAK, 0);
diff --git a/input/connect/joypad_connection.h b/input/connect/joypad_connection.h
index f68eadb5cd..8149205132 100644
--- a/input/connect/joypad_connection.h
+++ b/input/connect/joypad_connection.h
@@ -58,11 +58,19 @@
struct joypad_connection
{
struct pad_connection_interface *iface;
+ input_device_driver_t *input_driver;
void* data;
void* connection;
bool connected;
};
+#define PAD_CONNECT_OFFLINE 0x00 /* the pad is offline and cannot be used */
+#define PAD_CONNECT_READY 0x01 /* the pad is ready but is not bound to a RA slot */
+#define PAD_CONNECT_BOUND 0x02 /* the pad is offline and is bound to a RA slot */
+#define PAD_CONNECT_IN_USE 0x03 /* the pad is ready and is bound to a RA slot */
+
+#define SLOT_AUTO -1
+
typedef struct pad_connection_interface
{
void* (*init)(void *data, uint32_t slot, hid_driver_t *driver);
@@ -73,9 +81,24 @@ typedef struct pad_connection_interface
void (*get_buttons)(void *data, input_bits_t *state);
int16_t (*get_axis)(void *data, unsigned axis);
const char* (*get_name)(void *data);
- int32_t (*button)(void *data, uint16_t joykey);
+ int32_t (*button)(void *data, uint16_t joykey);
+ /* all fields/methods below this point are only required for multi-pad devices */
+ bool multi_pad; /* does the device provide multiple pads? */
+ int8_t max_pad; /* number of pads this device can provide */
+ void* (*pad_init)(void *data, int pad_index, joypad_connection_t *joyconn);
+ void (*pad_deinit)(void *pad_data);
+ /* pad_index is a number from 0 to max_pad-1 */
+ int8_t (*status)(void *data, int pad_index); /* returns a PAD_CONNECT_* state */
+ joypad_connection_t* (*joypad)(void *device_data, int pad_index);
} pad_connection_interface_t;
+typedef struct joypad_connection_entry {
+ const char* name;
+ uint16_t vid;
+ uint16_t pid;
+ pad_connection_interface_t *iface;
+} joypad_connection_entry_t;
+
extern pad_connection_interface_t pad_connection_wii;
extern pad_connection_interface_t pad_connection_wiiupro;
extern pad_connection_interface_t pad_connection_ps3;
@@ -122,4 +145,9 @@ bool pad_connection_rumble(joypad_connection_t *s,
const char* pad_connection_get_name(joypad_connection_t *joyconn,
unsigned idx);
+joypad_connection_entry_t *find_connection_entry(int16_t vid, int16_t pid, const char *name);
+int32_t pad_connection_pad_init_entry(joypad_connection_t *joyconn, joypad_connection_entry_t *entry, void *data, hid_driver_t *driver);
+void pad_connection_pad_register(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *pad_data, void *handle, input_device_driver_t *input_driver, int slot);
+void pad_connection_pad_deregister(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *pad_data);
+void pad_connection_pad_refresh(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *device_data, void *handle, input_device_driver_t *input_driver);
#endif
diff --git a/input/drivers_hid/wiiu_hid.c b/input/drivers_hid/wiiu_hid.c
index 256562a988..3efc2ac0c6 100644
--- a/input/drivers_hid/wiiu_hid.c
+++ b/input/drivers_hid/wiiu_hid.c
@@ -16,6 +16,7 @@
#include "../include/wiiu/hid.h"
#include
+#include
/* TODO/FIXME - static globals */
static wiiu_event_list events;
@@ -31,17 +32,20 @@ static bool wiiu_hid_joypad_query(void *data, unsigned slot)
if (!hid)
return false;
- return slot < HID_MAX_SLOT();
+ return slot < joypad_state.max_slot;
}
static joypad_connection_t *get_pad(wiiu_hid_t *hid, unsigned slot)
{
joypad_connection_t *result;
- if (!wiiu_hid_joypad_query(hid, slot))
+ if (!wiiu_hid_joypad_query(hid, slot)) {
+ RARCH_LOG("wiiu_hid: get_pad: invalid slot: %d", slot);
return NULL;
- result = HID_PAD_CONNECTION_PTR(slot);
- if (!result || !result->connected || !result->iface || !result->data)
+ }
+ result = &joypad_state.pads[slot];
+ if (!result->connected || !result->iface || !result->connection) {
return NULL;
+ }
return result;
}
@@ -49,27 +53,27 @@ static const char *wiiu_hid_joypad_name(void *data, unsigned slot)
{
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
- if (!pad)
+ if (!pad || !pad->iface->get_name)
return NULL;
- return pad->iface->get_name(pad->data);
+ return pad->iface->get_name(pad->connection);
}
static void wiiu_hid_joypad_get_buttons(void *data, unsigned slot, input_bits_t *state)
{
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
- if (pad)
- pad->iface->get_buttons(pad->data, state);
+ if (pad && pad->iface->get_buttons)
+ pad->iface->get_buttons(pad->connection, state);
}
static int16_t wiiu_hid_joypad_button(void *data,
unsigned slot, uint16_t joykey)
{
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
- if (!pad)
+ if (!pad || !pad->iface->button)
return 0;
- return pad->iface->button(pad->data, joykey);
+ return pad->iface->button(pad->connection, joykey);
}
static int16_t wiiu_hid_joypad_axis(void *data, unsigned slot, uint32_t joyaxis)
@@ -79,7 +83,7 @@ static int16_t wiiu_hid_joypad_axis(void *data, unsigned slot, uint32_t joyaxis)
if (!pad)
return 0;
- return pad->iface->get_axis(pad->data, joyaxis);
+ return pad->iface->get_axis(pad->connection, joyaxis);
}
static int16_t wiiu_hid_joypad_state(
@@ -106,10 +110,10 @@ static int16_t wiiu_hid_joypad_state(
? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
if (
(uint16_t)joykey != NO_BTN
- && pad->iface->button(pad->data, (uint16_t)joykey))
+ && pad->iface->button && pad->iface->button(pad->connection, (uint16_t)joykey))
ret |= ( 1 << i);
- else if (joyaxis != AXIS_NONE &&
- ((float)abs(pad->iface->get_axis(pad->data, joyaxis))
+ else if (joyaxis != AXIS_NONE && pad->iface->get_axis &&
+ ((float)abs(pad->iface->get_axis(pad->connection, joyaxis))
/ 0x8000) > joypad_info->axis_threshold)
ret |= (1 << i);
}
@@ -122,10 +126,10 @@ static bool wiiu_hid_joypad_rumble(void *data, unsigned slot,
{
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
- if (!pad)
+ if (!pad || !pad->iface->set_rumble)
return false;
- pad->iface->set_rumble(pad->data, effect, strength);
+ pad->iface->set_rumble(pad->connection, effect, strength);
return false;
}
@@ -363,16 +367,47 @@ static void log_device(HIDDevice *device)
RARCH_LOG(" max_packet_size_tx: %d\n", device->max_packet_size_tx);
}
+static uint8_t try_init_driver_multi(wiiu_adapter_t *adapter, joypad_connection_entry_t *entry) {
+ adapter->pad_driver_data = entry->iface->init(adapter, -1, &wiiu_hid);
+ if(!adapter->pad_driver_data) {
+ return ADAPTER_STATE_DONE;
+ }
+
+ pad_connection_pad_register(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver, SLOT_AUTO);
+ return ADAPTER_STATE_READY;
+}
+
static uint8_t try_init_driver(wiiu_adapter_t *adapter)
{
- adapter->driver_handle = adapter->driver->init(adapter);
- if (!adapter->driver_handle)
- {
- RARCH_ERR("[hid]: Failed to initialize driver: %s\n",
- adapter->driver->name);
- return ADAPTER_STATE_DONE;
+ joypad_connection_entry_t *entry;
+ int slot;
+
+ entry = find_connection_entry(adapter->vendor_id, adapter->product_id, adapter->device_name);
+ if(!entry) {
+ RARCH_LOG("Failed to find entry for vid: 0x%x, pid: 0x%x, name: %s\n", adapter->vendor_id, adapter->product_id, adapter->device_name);
+ return ADAPTER_STATE_DONE;
}
+ adapter->pad_driver = entry->iface;
+
+ if(entry->iface->multi_pad) {
+ return try_init_driver_multi(adapter, entry);
+ }
+ slot = pad_connection_find_vacant_pad(joypad_state.pads);
+ if(slot < 0) {
+ RARCH_LOG("try_init_driver: no slot available\n");
+ return ADAPTER_STATE_DONE;
+ }
+
+ adapter->pad_driver_data = entry->iface->init(adapter, slot, &wiiu_hid);
+ if(!adapter->pad_driver_data) {
+ RARCH_LOG("try_init_driver: pad init failed\n");
+ return ADAPTER_STATE_DONE;
+ }
+
+ RARCH_LOG("driver initialized, registering pad\n");
+ pad_connection_pad_register(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver, slot);
+
return ADAPTER_STATE_READY;
}
@@ -386,35 +421,43 @@ static void synchronized_process_adapters(wiiu_hid_t *hid)
for (adapter = adapters.list; adapter != NULL; adapter = adapter_next)
{
- adapter_next = adapter->next;
+ adapter_next = adapter->next;
- switch(adapter->state)
- {
- case ADAPTER_STATE_NEW:
- adapter->state = try_init_driver(adapter);
- break;
- case ADAPTER_STATE_READY:
- case ADAPTER_STATE_READING:
- case ADAPTER_STATE_DONE:
- break;
- case ADAPTER_STATE_GC:
- /* remove from the list */
- if (!prev)
- adapters.list = adapter->next;
- else
- prev->next = adapter->next;
+ switch(adapter->state)
+ {
+ case ADAPTER_STATE_NEW:
+ adapter->state = try_init_driver(adapter);
+ break;
+ case ADAPTER_STATE_READY:
+ case ADAPTER_STATE_READING:
+ if(adapter->pad_driver && adapter->pad_driver->multi_pad) {
+ pad_connection_pad_refresh(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver);
+ }
+ case ADAPTER_STATE_DONE:
+ break;
+ case ADAPTER_STATE_GC:
+ {
+ RARCH_LOG("ADAPTER_STATE_GC");
+ /* remove from the list */
+ if (!prev)
+ adapters.list = adapter->next;
+ else
+ prev->next = adapter->next;
- /* adapter is no longer valid after this point */
- delete_adapter(adapter);
- /* signal not to update prev ptr since adapter is now invalid */
- keep_prev = true;
- break;
- default:
- RARCH_ERR("[hid]: Invalid adapter state: %d\n", adapter->state);
- break;
- }
- prev = keep_prev ? prev : adapter;
- keep_prev = false;
+ pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
+ /* adapter is no longer valid after this point */
+ delete_adapter(adapter);
+ /* signal not to update prev ptr since adapter is now invalid */
+ keep_prev = true;
+ }
+ break;
+
+ default:
+ RARCH_ERR("[hid]: Invalid adapter state: %d\n", adapter->state);
+ break;
+ }
+ prev = keep_prev ? prev : adapter;
+ keep_prev = false;
}
OSFastMutex_Unlock(&(adapters.lock));
}
@@ -509,9 +552,10 @@ static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event)
goto error;
}
- adapter->hid = hid;
- adapter->driver = event->driver;
- adapter->state = ADAPTER_STATE_NEW;
+ adapter->hid = hid;
+ adapter->vendor_id = event->vendor_id;
+ adapter->product_id = event->product_id;
+ adapter->state = ADAPTER_STATE_NEW;
synchronized_add_to_adapters_list(adapter);
@@ -540,8 +584,7 @@ static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error,
if (error == 0)
{
- adapter->driver->handle_packet(adapter->driver_handle,
- buffer, buffer_size);
+ adapter->pad_driver->packet_handler(adapter->pad_driver_data, buffer, buffer_size);
}
}
}
@@ -553,7 +596,7 @@ static void report_hid_error(const char *msg, wiiu_adapter_t *adapter, int32_t e
int16_t hid_error_code = error & 0xffff;
int16_t error_category = (error >> 16) & 0xffff;
- const char *device = (adapter && adapter->driver) ? adapter->driver->name : "unknown";
+ const char *device = string_is_empty(adapter->device_name) ? "unknown" : adapter->device_name;
switch(hid_error_code)
{
@@ -632,6 +675,7 @@ static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack)
RARCH_LOG("[hid]: shutting down adapter..\n");
adapter = adapters.list;
adapters.list = adapter->next;
+ pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
delete_adapter(adapter);
}
}
@@ -688,8 +732,10 @@ static void wiiu_poll_adapters(wiiu_hid_t *hid)
if (it->state == ADAPTER_STATE_READY)
wiiu_poll_adapter(it);
- if (it->state == ADAPTER_STATE_DONE)
+ if (it->state == ADAPTER_STATE_DONE) {
+ RARCH_LOG("poll_adapters: read done, ready for garbage collection");
it->state = ADAPTER_STATE_GC;
+ }
}
OSFastMutex_Unlock(&(adapters.lock));
@@ -775,8 +821,11 @@ static wiiu_adapter_t *new_adapter(wiiu_attach_event *event)
adapter->handle = event->handle;
adapter->interface_index = event->interface_index;
+ adapter->product_id = event->product_id;
+ adapter->vendor_id = event->vendor_id;
init_cachealigned_buffer(event->max_packet_size_rx, &adapter->rx_buffer, &adapter->rx_size);
init_cachealigned_buffer(event->max_packet_size_tx, &adapter->tx_buffer, &adapter->tx_size);
+ memcpy(adapter->device_name, event->device_name, sizeof(adapter->device_name));
adapter->connected = true;
return adapter;
@@ -797,29 +846,40 @@ static void delete_adapter(wiiu_adapter_t *adapter)
free(adapter->tx_buffer);
adapter->tx_buffer = NULL;
}
- if (adapter->driver && adapter->driver_handle) {
- adapter->driver->free(adapter->driver_handle);
- adapter->driver_handle = NULL;
- adapter->driver = NULL;
+ if(adapter->pad_driver && adapter->pad_driver_data) {
+ adapter->pad_driver->deinit(adapter->pad_driver_data);
+ adapter->pad_driver_data = NULL;
}
free(adapter);
}
+static void get_device_name(HIDDevice *device, wiiu_attach_event *event)
+{
+ int32_t result;
+ uint8_t *name_buffer = alloc_zeroed(4, device->max_packet_size_rx);
+ uint8_t *top = &event->device_name[0];
+
+ if(name_buffer == NULL) {
+ return;
+ }
+ result = HIDGetDescriptor(device->handle, 3, 2, 0, name_buffer, device->max_packet_size_rx, NULL, NULL);
+ if(result > 0) {
+ for(int i = 2; i < result; i += 2) {
+ top[0] = name_buffer[i];
+ top++;
+ }
+ }
+ free(name_buffer);
+}
+
static wiiu_attach_event *new_attach_event(HIDDevice *device)
{
- hid_device_t *driver = hid_device_driver_lookup(device->vid, device->pid);
- if (!driver)
- {
- RARCH_ERR("[hid]: Failed to locate driver for device vid=%04x pid=%04x\n",
- device->vid, device->pid);
- return NULL;
- }
wiiu_attach_event *event = alloc_zeroed(4, sizeof(wiiu_attach_event));
+
if (!event)
return NULL;
- event->driver = driver;
event->handle = device->handle;
event->vendor_id = device->vid;
event->product_id = device->pid;
@@ -830,6 +890,7 @@ static wiiu_attach_event *new_attach_event(HIDDevice *device)
&& device->protocol == 2);
event->max_packet_size_rx = device->max_packet_size_rx;
event->max_packet_size_tx = device->max_packet_size_tx;
+ get_device_name(device, event);
return event;
}
diff --git a/input/drivers_joypad/wiiu/hidpad_driver.c b/input/drivers_joypad/wiiu/hidpad_driver.c
index 454b91d54a..9504acc66e 100644
--- a/input/drivers_joypad/wiiu/hidpad_driver.c
+++ b/input/drivers_joypad/wiiu/hidpad_driver.c
@@ -16,66 +16,52 @@
#include "../../include/wiiu/input.h"
-/* TODO/FIXME - static global variables */
-static bool hidpad_ready = false;
-
-static bool init_hid_driver(void)
-{
- return hid_init(&hid_instance, &wiiu_hid, &hidpad_driver, MAX_USERS);
-}
-
static void hidpad_poll(void)
{
- if (hidpad_ready)
- HID_POLL();
+ if (joypad_state.hid.ready)
+ wiiu_hid.poll(hid_driver_get_data());
}
static void *hidpad_init(void *data)
{
- if(!init_hid_driver())
- {
- RARCH_ERR("Failed to initialize HID driver.\n");
- return NULL;
- }
-
hidpad_poll();
- hidpad_ready = true;
+ joypad_state.hid.ready = true;
return (void*)-1;
}
static bool hidpad_query_pad(unsigned port)
{
- return hidpad_ready && port < MAX_USERS;
+ return joypad_state.hid.ready && port < MAX_USERS;
}
static void hidpad_destroy(void)
{
- hidpad_ready = false;
-
- hid_deinit(&hid_instance);
+ joypad_state.hid.ready = false;
}
static int32_t hidpad_button(unsigned port, uint16_t joykey)
{
if (!hidpad_query_pad(port))
return 0;
- return (HID_BUTTON(port, joykey));
+
+ return wiiu_hid.button(hid_driver_get_data(), port, joykey);
}
static void hidpad_get_buttons(unsigned port, input_bits_t *state)
{
- if (!hidpad_query_pad(port))
- BIT256_CLEAR_ALL_PTR(state);
+ if (!hidpad_query_pad(port))
+ BIT256_CLEAR_ALL_PTR(state);
- HID_GET_BUTTONS(port, state);
+ wiiu_hid.get_buttons(hid_driver_get_data(), port, state);
}
static int16_t hidpad_axis(unsigned port, uint32_t axis)
{
if (!hidpad_query_pad(port))
return 0;
- return HID_AXIS(port, axis);
+
+ return wiiu_hid.axis(hid_driver_get_data(), port, axis);
}
static int16_t hidpad_state(
@@ -99,11 +85,11 @@ static int16_t hidpad_state(
? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
if (
(uint16_t)joykey != NO_BTN
- && HID_BUTTON(port_idx, (uint16_t)joykey)
+ && wiiu_hid.button(hid_driver_get_data(), port_idx, (uint16_t)joykey)
)
ret |= ( 1 << i);
else if (joyaxis != AXIS_NONE &&
- ((float)abs(HID_AXIS(port_idx, joyaxis))
+ ((float)abs(wiiu_hid.axis(hid_driver_get_data(), port_idx, joyaxis))
/ 0x8000) > joypad_info->axis_threshold)
ret |= (1 << i);
}
@@ -116,7 +102,7 @@ static const char *hidpad_name(unsigned port)
if (!hidpad_query_pad(port))
return "N/A";
- return HID_PAD_NAME(port);
+ return wiiu_hid.name(hid_driver_get_data(), port);
}
input_device_driver_t hidpad_driver =
@@ -129,8 +115,8 @@ input_device_driver_t hidpad_driver =
hidpad_get_buttons,
hidpad_axis,
hidpad_poll,
- NULL,
- NULL,
+ NULL, /* set_rumble */
+ NULL, /* set_rumble_gain */
hidpad_name,
"hid"
};
diff --git a/input/drivers_joypad/wiiu/kpad_driver.c b/input/drivers_joypad/wiiu/kpad_driver.c
index 86e8bec846..a7fd8c02c7 100644
--- a/input/drivers_joypad/wiiu/kpad_driver.c
+++ b/input/drivers_joypad/wiiu/kpad_driver.c
@@ -29,34 +29,12 @@
static void kpad_poll(void);
static void kpad_deregister(unsigned channel);
-typedef struct _wiimote_state wiimote_state;
-
-struct _wiimote_state
-{
- uint64_t button_state;
- int16_t analog_state[3][2];
- uint8_t type;
-};
-
-/* static global variables */
-static bool kpad_ready = false;
-static int channel_slot_map[] = { -1, -1, -1, -1 };
-static int poll_failures[WIIU_WIIMOTE_CHANNELS] = { 0, 0, 0, 0 };
-static wiimote_state
-wiimotes[WIIU_WIIMOTE_CHANNELS] = {
- { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE },
- { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE },
- { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE },
- { 0, {{0,0},{0,0},{0,0}}, WIIMOTE_TYPE_NONE },
-};
-
-
static int to_wiimote_channel(unsigned pad)
{
unsigned i;
for (i = 0; i < WIIU_WIIMOTE_CHANNELS; i++)
- if (channel_slot_map[i] == pad)
+ if (joypad_state.kpad.channel_slot_map[i] == pad)
return i;
return -1;
@@ -64,11 +42,11 @@ static int to_wiimote_channel(unsigned pad)
static int get_slot_for_channel(unsigned channel)
{
- int slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
+ int slot = pad_connection_find_vacant_pad(joypad_state.pads);
if (slot >= 0)
{
- channel_slot_map[channel] = slot;
- hid_instance.pad_list[slot].connected = true;
+ joypad_state.kpad.channel_slot_map[channel] = slot;
+ joypad_state.pads[slot].connected = true;
}
return slot;
@@ -76,20 +54,26 @@ static int get_slot_for_channel(unsigned channel)
static void *kpad_init(void *data)
{
+ memset(&joypad_state.kpad, 0, sizeof(joypad_state.kpad));
+
+ for(int i = 0; i < WIIU_WIIMOTE_CHANNELS; i++) {
+ joypad_state.kpad.channel_slot_map[i] = -1;
+ }
+
kpad_poll();
- kpad_ready = true;
+ joypad_state.kpad.ready = true;
return (void*)-1;
}
static bool kpad_query_pad(unsigned pad)
{
- return kpad_ready && pad < MAX_USERS;
+ return joypad_state.kpad.ready && pad < MAX_USERS;
}
static void kpad_destroy(void)
{
- kpad_ready = false;
+ joypad_state.kpad.ready = false;
}
static int32_t kpad_button(unsigned port, uint16_t joykey)
@@ -101,7 +85,7 @@ static int32_t kpad_button(unsigned port, uint16_t joykey)
channel = to_wiimote_channel(port);
if (channel < 0)
return 0;
- return (wiimotes[channel].button_state
+ return (joypad_state.kpad.wiimotes[channel].button_state
& (UINT64_C(1) << joykey));
}
@@ -112,7 +96,7 @@ static void kpad_get_buttons(unsigned port, input_bits_t *state)
if (!kpad_query_pad(port) || channel < 0)
BIT256_CLEAR_ALL_PTR(state);
else
- BITS_COPY16_PTR(state, wiimotes[channel].button_state);
+ BITS_COPY16_PTR(state, joypad_state.kpad.wiimotes[channel].button_state);
}
static int16_t kpad_axis(unsigned port, uint32_t axis)
@@ -125,7 +109,7 @@ static int16_t kpad_axis(unsigned port, uint32_t axis)
pad_functions.read_axis_data(axis, &data);
return pad_functions.get_axis_value(data.axis,
- wiimotes[channel].analog_state,
+ joypad_state.kpad.wiimotes[channel].analog_state,
data.is_negative);
}
@@ -160,7 +144,7 @@ static int16_t kpad_state(
static void kpad_register(unsigned channel, uint8_t device_type)
{
- if (wiimotes[channel].type != device_type)
+ if (joypad_state.kpad.wiimotes[channel].type != device_type)
{
int slot;
@@ -173,7 +157,8 @@ static void kpad_register(unsigned channel, uint8_t device_type)
return;
}
- wiimotes[channel].type = device_type;
+ joypad_state.kpad.wiimotes[channel].type = device_type;
+ joypad_state.pads[slot].input_driver = &kpad_driver;
input_pad_connect(slot, &kpad_driver);
}
}
@@ -184,32 +169,32 @@ static void kpad_poll_one_channel(unsigned channel, KPADData *kpad)
switch(kpad->device_type)
{
case WIIMOTE_TYPE_PRO:
- wiimotes[channel].button_state = kpad->classic.btns_h
+ joypad_state.kpad.wiimotes[channel].button_state = kpad->classic.btns_h
& ~WIIU_PRO_BUTTON_MASK;
- pad_functions.set_axis_value(wiimotes[channel].analog_state,
+ pad_functions.set_axis_value(joypad_state.kpad.wiimotes[channel].analog_state,
WIIU_READ_STICK(kpad->classic.lstick_x),
WIIU_READ_STICK(kpad->classic.lstick_y),
WIIU_READ_STICK(kpad->classic.rstick_x),
WIIU_READ_STICK(kpad->classic.rstick_y), 0, 0);
break;
case WIIMOTE_TYPE_CLASSIC:
- wiimotes[channel].button_state = kpad->classic.btns_h
+ joypad_state.kpad.wiimotes[channel].button_state = kpad->classic.btns_h
& ~CLASSIC_BUTTON_MASK;
- pad_functions.set_axis_value(wiimotes[channel].analog_state,
+ pad_functions.set_axis_value(joypad_state.kpad.wiimotes[channel].analog_state,
WIIU_READ_STICK(kpad->classic.lstick_x),
WIIU_READ_STICK(kpad->classic.lstick_y),
WIIU_READ_STICK(kpad->classic.rstick_x),
WIIU_READ_STICK(kpad->classic.rstick_y), 0, 0);
break;
case WIIMOTE_TYPE_NUNCHUK:
- wiimotes[channel].button_state = kpad->btns_h;
- pad_functions.set_axis_value(wiimotes[channel].analog_state,
+ joypad_state.kpad.wiimotes[channel].button_state = kpad->btns_h;
+ pad_functions.set_axis_value(joypad_state.kpad.wiimotes[channel].analog_state,
WIIU_READ_STICK(kpad->nunchuck.stick_x),
WIIU_READ_STICK(kpad->nunchuck.stick_y), 0, 0, 0, 0);
break;
case WIIMOTE_TYPE_WIIPLUS:
- wiimotes[channel].button_state = kpad->btns_h;
- pad_functions.set_axis_value(wiimotes[channel].analog_state,
+ joypad_state.kpad.wiimotes[channel].button_state = kpad->btns_h;
+ pad_functions.set_axis_value(joypad_state.kpad.wiimotes[channel].analog_state,
0, 0, 0, 0, 0, 0);
break;
}
@@ -217,14 +202,15 @@ static void kpad_poll_one_channel(unsigned channel, KPADData *kpad)
static void kpad_deregister(unsigned channel)
{
- int slot = channel_slot_map[channel];
+ int slot = joypad_state.kpad.channel_slot_map[channel];
if (slot >= 0)
{
input_autoconfigure_disconnect(slot, kpad_driver.name(slot));
- wiimotes[channel].type = WIIMOTE_TYPE_NONE;
- hid_instance.pad_list[slot].connected = false;
- channel_slot_map[channel] = -1;
+ joypad_state.kpad.wiimotes[channel].type = WIIMOTE_TYPE_NONE;
+ joypad_state.pads[slot].connected = false;
+
+ joypad_state.kpad.channel_slot_map[channel] = -1;
}
}
@@ -244,12 +230,12 @@ static void kpad_poll(void)
/* pad disconnects properly. */
if (result == 0)
{
- poll_failures[channel]++;
- if (poll_failures[channel] > 5)
+ joypad_state.kpad.poll_failures[channel]++;
+ if (joypad_state.kpad.poll_failures[channel] > 5)
kpad_deregister(channel);
continue;
}
- poll_failures[channel] = 0;
+ joypad_state.kpad.poll_failures[channel] = 0;
/* Several reads when a device is connected or an attachment added give */
/* bogus results, try to weed them out */
@@ -267,7 +253,7 @@ static const char *kpad_name(unsigned pad)
if (channel < 0)
return "unknown";
- switch(wiimotes[channel].type)
+ switch(joypad_state.kpad.wiimotes[channel].type)
{
case WIIMOTE_TYPE_PRO:
return PAD_NAME_WIIU_PRO;
@@ -280,7 +266,7 @@ static const char *kpad_name(unsigned pad)
case WIIMOTE_TYPE_NONE:
default:
#ifdef DEBUG
- RARCH_LOG("[kpad]: Unknown pad type %d\n", wiimotes[pad].type);
+ RARCH_LOG("[kpad]: Unknown pad type %d\n", joypad_state.kpad.wiimotes[pad].type);
#endif
break;
}
diff --git a/input/drivers_joypad/wiiu/wpad_driver.c b/input/drivers_joypad/wiiu/wpad_driver.c
index 7fb4cf4047..4e30022a15 100644
--- a/input/drivers_joypad/wiiu/wpad_driver.c
+++ b/input/drivers_joypad/wiiu/wpad_driver.c
@@ -27,24 +27,13 @@
#define WPAD_INVALID_CHANNEL -1
-typedef struct _drc_state drc_state;
-struct _drc_state
-{
- uint64_t button_state;
- int16_t analog_state[3][2];
-};
-
-/* TODO/FIXME - static global variables */
-static drc_state gamepads[WIIU_GAMEPAD_CHANNELS] = { 0 };
-static int channel_slot_map[WIIU_GAMEPAD_CHANNELS] = { WPAD_INVALID_CHANNEL, WPAD_INVALID_CHANNEL };
-
static VPADChan to_gamepad_channel(unsigned pad)
{
unsigned i;
for (i = 0; i < WIIU_GAMEPAD_CHANNELS; i++)
{
- if (channel_slot_map[i] == pad)
+ if (joypad_state.wpad.channel_slot_map[i] == pad)
return i;
}
@@ -59,23 +48,23 @@ static void wpad_deregister(unsigned channel)
return;
/* See if Gamepad is already disconnected */
- if (channel_slot_map[channel] == WPAD_INVALID_CHANNEL)
+ if (joypad_state.wpad.channel_slot_map[channel] == WPAD_INVALID_CHANNEL)
return;
/* Sanity check, about to use as unsigned */
- if (channel_slot_map[channel] < 0)
+ if (joypad_state.wpad.channel_slot_map[channel] < 0)
{
- channel_slot_map[channel] = WPAD_INVALID_CHANNEL;
+ joypad_state.wpad.channel_slot_map[channel] = WPAD_INVALID_CHANNEL;
return;
}
- slot = (unsigned)channel_slot_map[channel];
+ slot = (unsigned)joypad_state.wpad.channel_slot_map[channel];
if (slot >= MAX_USERS)
return;
input_autoconfigure_disconnect(slot, wpad_driver.ident);
- hid_instance.pad_list[slot].connected = false;
- channel_slot_map[channel] = WPAD_INVALID_CHANNEL;
+ joypad_state.pads[slot].connected = false;
+ joypad_state.wpad.channel_slot_map[channel] = WPAD_INVALID_CHANNEL;
}
static void wpad_register(unsigned channel)
@@ -87,17 +76,18 @@ static void wpad_register(unsigned channel)
/* Check if gamepad is already handled
Other checks not needed here - about to overwrite
- channel_slot_map entry*/
- if (channel_slot_map[channel] != WPAD_INVALID_CHANNEL)
+ joypad_state.wpad.channel_slot_map entry*/
+ if (joypad_state.wpad.channel_slot_map[channel] != WPAD_INVALID_CHANNEL)
return;
- slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
+ slot = pad_connection_find_vacant_pad(joypad_state.pads);
if(slot < 0)
return;
- hid_instance.pad_list[slot].connected = true;
+ joypad_state.pads[slot].connected = true;
+ joypad_state.pads[slot].input_driver = &wpad_driver;
input_pad_connect(slot, &wpad_driver);
- channel_slot_map[channel] = slot;
+ joypad_state.wpad.channel_slot_map[channel] = slot;
}
static void update_button_state(uint64_t *state, uint32_t held_buttons)
@@ -255,9 +245,9 @@ static void wpad_poll(void)
if (error == VPAD_READ_SUCCESS)
{
- update_button_state(&gamepads[channel].button_state, vpad.hold);
- update_analog_state(gamepads[channel].analog_state, &vpad);
- update_touch_state(gamepads[channel].analog_state, &gamepads[channel].button_state, &vpad, channel);
+ update_button_state(&joypad_state.wpad.pads[channel].button_state, vpad.hold);
+ update_analog_state(joypad_state.wpad.pads[channel].analog_state, &vpad);
+ update_touch_state(joypad_state.wpad.pads[channel].analog_state, &joypad_state.wpad.pads[channel].button_state, &vpad, channel);
check_panic_button(vpad.hold);
}
}
@@ -265,6 +255,10 @@ static void wpad_poll(void)
static void *wpad_init(void *data)
{
+ memset(&joypad_state.wpad, 0, sizeof(joypad_state.wpad));
+ for(int i = 0; i < WIIU_GAMEPAD_CHANNELS; i++) {
+ joypad_state.wpad.channel_slot_map[i] = WPAD_INVALID_CHANNEL;
+ }
wpad_poll();
return (void*)-1;
}
@@ -285,7 +279,7 @@ static int32_t wpad_button(unsigned port, uint16_t joykey)
channel = to_gamepad_channel(port);
if (channel < 0)
return 0;
- return (gamepads[channel].button_state & (UINT64_C(1) << joykey));
+ return (joypad_state.wpad.pads[channel].button_state & (UINT64_C(1) << joykey));
}
static void wpad_get_buttons(unsigned port, input_bits_t *state)
@@ -305,7 +299,7 @@ static void wpad_get_buttons(unsigned port, input_bits_t *state)
return;
}
- BITS_COPY32_PTR(state, gamepads[channel].button_state);
+ BITS_COPY32_PTR(state, joypad_state.wpad.pads[channel].button_state);
}
static int16_t wpad_axis(unsigned port, uint32_t axis)
@@ -322,7 +316,7 @@ static int16_t wpad_axis(unsigned port, uint32_t axis)
pad_functions.read_axis_data(axis, &data);
return pad_functions.get_axis_value(data.axis,
- gamepads[channel].analog_state, data.is_negative);
+ joypad_state.wpad.pads[channel].analog_state, data.is_negative);
}
static int16_t wpad_state(
diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c
index 18eb5db822..43f0b4000a 100644
--- a/input/drivers_joypad/wiiu_joypad.c
+++ b/input/drivers_joypad/wiiu_joypad.c
@@ -16,48 +16,42 @@
#include "../include/wiiu/input.h"
-#include "wiiu_dbg.h"
-extern pad_connection_listener_t wiiu_pad_connection_listener;
-/* TODO/FIXME - static globals */
-static input_device_driver_t *wiiu_pad_drivers[MAX_USERS];
-static bool wiiu_joypad_ready = false;
+static bool ready = false;
+
+wiiu_joypad_t joypad_state = {0};
static void *wiiu_joypad_init(void *data)
{
- set_connection_listener(&wiiu_pad_connection_listener);
- hid_instance.pad_list = pad_connection_init(MAX_USERS);
- hid_instance.max_slot = MAX_USERS;
+ memset(&joypad_state, 0, sizeof(wiiu_joypad_t));
+ joypad_state.pads[MAX_USERS].data = (void *)0xdeadbeef;
+ joypad_state.max_slot = MAX_USERS;
+ input_hid_init_first();
wpad_driver.init(data);
kpad_driver.init(data);
-#ifdef WIIU_HID
hidpad_driver.init(data);
-#endif
+ ready = true;
- wiiu_joypad_ready = true;
-
- return (void*)-1;
+ return (void *)-1;
}
static bool wiiu_joypad_query_pad(unsigned pad)
{
- return wiiu_joypad_ready &&
+ return ready &&
pad < MAX_USERS &&
- wiiu_pad_drivers[pad] &&
- wiiu_pad_drivers[pad]->query_pad(pad);
+ joypad_state.pads[pad].input_driver &&
+ joypad_state.pads[pad].input_driver->query_pad(pad);
}
static void wiiu_joypad_destroy(void)
{
- wiiu_joypad_ready = false;
+ ready = false;
wpad_driver.destroy();
kpad_driver.destroy();
-#ifdef WIIU_HID
hidpad_driver.destroy();
-#endif
}
static int32_t wiiu_joypad_button(unsigned port, uint16_t joykey)
@@ -66,21 +60,21 @@ static int32_t wiiu_joypad_button(unsigned port, uint16_t joykey)
return 0;
if (port >= DEFAULT_MAX_PADS)
return 0;
- return (wiiu_pad_drivers[port]->button(port, joykey));
+ return (joypad_state.pads[port].input_driver->button(port, joykey));
}
static void wiiu_joypad_get_buttons(unsigned port, input_bits_t *state)
{
if (!wiiu_joypad_query_pad(port))
return;
- wiiu_pad_drivers[port]->get_buttons(port, state);
+ joypad_state.pads[port].input_driver->get_buttons(port, state);
}
static int16_t wiiu_joypad_axis(unsigned port, uint32_t joyaxis)
{
if (!wiiu_joypad_query_pad(port))
return 0;
- return wiiu_pad_drivers[port]->axis(port, joyaxis);
+ return joypad_state.pads[port].input_driver->axis(port, joyaxis);
}
static int16_t wiiu_joypad_state(
@@ -106,11 +100,11 @@ static int16_t wiiu_joypad_state(
? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
if (
(uint16_t)joykey != NO_BTN
- && (wiiu_pad_drivers[port]->button(port_idx, (uint16_t)joykey))
+ && (joypad_state.pads[port].input_driver->button(port_idx, (uint16_t)joykey))
)
ret |= ( 1 << i);
else if (joyaxis != AXIS_NONE &&
- ((float)abs(wiiu_pad_drivers[port]->axis(port_idx, joyaxis))
+ ((float)abs(joypad_state.pads[port].input_driver->axis(port_idx, joyaxis))
/ 0x8000) > joypad_info->axis_threshold)
ret |= (1 << i);
}
@@ -122,9 +116,7 @@ static void wiiu_joypad_poll(void)
{
wpad_driver.poll();
kpad_driver.poll();
-#ifdef WIIU_HID
hidpad_driver.poll();
-#endif
}
static const char* wiiu_joypad_name(unsigned pad)
@@ -132,14 +124,7 @@ static const char* wiiu_joypad_name(unsigned pad)
if (!wiiu_joypad_query_pad(pad))
return "N/A";
- return wiiu_pad_drivers[pad]->name(pad);
-}
-
-static void wiiu_joypad_connection_listener(unsigned pad,
- input_device_driver_t *driver)
-{
- if (pad < MAX_USERS)
- wiiu_pad_drivers[pad] = driver;
+ return joypad_state.pads[pad].input_driver->name(pad);
}
input_device_driver_t wiiu_joypad =
@@ -157,8 +142,3 @@ input_device_driver_t wiiu_joypad =
wiiu_joypad_name,
"wiiu",
};
-
-pad_connection_listener_t wiiu_pad_connection_listener =
-{
- wiiu_joypad_connection_listener
-};
diff --git a/input/include/gamepad.h b/input/include/gamepad.h
index a3fd5dff1e..802f0b5718 100644
--- a/input/include/gamepad.h
+++ b/input/include/gamepad.h
@@ -20,11 +20,6 @@
#include "../input_driver.h"
-struct pad_connection_listener_interface
-{
- void (*connected)(unsigned port, input_device_driver_t *driver);
-};
-
typedef struct _axis_data
{
int32_t axis;
diff --git a/input/include/hid_driver.h b/input/include/hid_driver.h
index b7c8a56fd3..127b477d94 100644
--- a/input/include/hid_driver.h
+++ b/input/include/hid_driver.h
@@ -54,31 +54,4 @@ struct hid_driver
int32_t (*read)(void *handle, void *buf, size_t size);
};
-#define HID_GET_BUTTONS(pad, state) hid_instance.os_driver->get_buttons( \
- hid_instance.os_driver_data, pad, state)
-#define HID_BUTTON(pad, key) hid_instance.os_driver->button( \
- hid_instance.os_driver_data, pad, key)
-#define HID_AXIS(pad, a) hid_instance.os_driver->axis( \
- hid_instance.os_driver_data, pad, (a))
-#define HID_PAD_NAME(pad) \
- hid_instance.os_driver->name(hid_instance.os_driver_data, pad)
-#define HID_SET_PROTOCOL(pad, protocol) \
- hid_instance.os_driver->set_protocol(pad, protocol)
-#define HID_SET_REPORT(pad, rpttype, rptid, data, len) \
- hid_instance.os_driver->set_report(pad, rpttype, rptid, data, len)
-#define HID_SEND_CONTROL(pad, data, len) \
- hid_instance.os_driver->send_control(pad, data, len)
-#define HID_POLL() hid_instance.os_driver->poll( \
- hid_instance.os_driver_data)
-#define HID_MAX_SLOT() hid_instance.max_slot
-#define HID_PAD_CONNECTION_PTR(slot) &(hid_instance.pad_list[(slot)])
-
-struct hid_driver_instance {
- hid_driver_t *os_driver;
- void *os_driver_data;
- input_device_driver_t *pad_driver;
- joypad_connection_t *pad_list;
- unsigned max_slot;
-};
-
#endif /* HID_DRIVER_H__ */
diff --git a/input/include/hid_types.h b/input/include/hid_types.h
index 28734e9dd8..a2af1af661 100644
--- a/input/include/hid_types.h
+++ b/input/include/hid_types.h
@@ -19,6 +19,5 @@
#define HID_TYPES_H__
typedef struct hid_driver hid_driver_t;
-typedef struct hid_driver_instance hid_driver_instance_t;
#endif /* HID_TYPES_H__ */
diff --git a/input/include/wiiu/hid.h b/input/include/wiiu/hid.h
index 3d2a44301e..92c82a4344 100644
--- a/input/include/wiiu/hid.h
+++ b/input/include/wiiu/hid.h
@@ -19,7 +19,6 @@
#include "hid_types.h"
#include "input.h"
-#include "../../common/hid/hid_device_driver.h"
#define DEVICE_UNUSED 0
#define DEVICE_USED 1
@@ -52,9 +51,11 @@ struct wiiu_hid {
*/
struct wiiu_adapter {
wiiu_adapter_t *next;
- hid_device_t *driver;
- void *driver_handle;
+ pad_connection_interface_t *pad_driver;
+ void *pad_driver_data;
wiiu_hid_t *hid;
+ uint16_t vendor_id;
+ uint16_t product_id;
uint8_t state;
uint8_t *rx_buffer;
int32_t rx_size;
@@ -62,6 +63,7 @@ struct wiiu_adapter {
int32_t tx_size;
uint32_t handle;
uint8_t interface_index;
+ char device_name[32];
bool connected;
};
@@ -72,7 +74,6 @@ struct wiiu_adapter {
*/
struct wiiu_attach {
wiiu_attach_event *next;
- hid_device_t *driver;
uint32_t type;
uint32_t handle;
uint16_t vendor_id;
@@ -82,6 +83,7 @@ struct wiiu_attach {
uint8_t is_mouse;
uint16_t max_packet_size_rx;
uint16_t max_packet_size_tx;
+ uint8_t device_name[32];
};
struct _wiiu_event_list {
diff --git a/input/include/wiiu/input.h b/input/include/wiiu/input.h
index 401dbaa426..e0c36d2b9e 100644
--- a/input/include/wiiu/input.h
+++ b/input/include/wiiu/input.h
@@ -30,7 +30,6 @@
#include
#include
-#include "../../common/hid/hid_device_driver.h"
#include "../../connect/joypad_connection.h"
#include "../../../retroarch.h"
#include "../../../verbosity.h"
@@ -64,6 +63,45 @@ struct _wiiu_pad_functions {
void (*connect)(unsigned pad, input_device_driver_t *driver);
};
+typedef struct _wiimote_state {
+ uint64_t button_state;
+ int16_t analog_state[3][2];
+ uint8_t type;
+} wiimote_state;
+
+typedef struct _drc_state
+{
+ uint64_t button_state;
+ int16_t analog_state[3][2];
+} drc_state;
+
+typedef struct wiiu_kpad {
+ bool ready;
+ int channel_slot_map[WIIU_WIIMOTE_CHANNELS];
+ int poll_failures[WIIU_WIIMOTE_CHANNELS];
+ wiimote_state wiimotes[WIIU_WIIMOTE_CHANNELS];
+} wiiu_kpad_t;
+
+typedef struct wiiu_wpad {
+ drc_state pads[WIIU_GAMEPAD_CHANNELS];
+ int channel_slot_map[WIIU_GAMEPAD_CHANNELS];
+ bool ready;
+} wiiu_wpad_t;
+
+typedef struct wiiu_hidpad {
+ bool ready;
+} wiiu_hidpad_t;
+
+typedef struct wiiu_joypad {
+ joypad_connection_t pads[MAX_USERS+1];
+ int max_slot;
+
+ wiiu_kpad_t kpad;
+ wiiu_wpad_t wpad;
+ wiiu_hidpad_t hid;
+} wiiu_joypad_t;
+
+extern wiiu_joypad_t joypad_state;
extern wiiu_pad_functions_t pad_functions;
extern input_device_driver_t wiiu_joypad;
extern input_device_driver_t wpad_driver;
diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c
index ed0966c666..2276886b9f 100644
--- a/input/input_autodetect_builtin.c
+++ b/input/input_autodetect_builtin.c
@@ -304,6 +304,28 @@ DECL_AXIS_EX(r_x_minus, -2, "C-stick left") \
DECL_AXIS_EX(r_y_plus, +3, "C-stick up") \
DECL_AXIS_EX(r_y_minus, -3, "C-stick down")
+#define WIIUINPUT_WAVEBIRD_DEFAULT_BINDS \
+DECL_BTN_EX(a, 8, "A") \
+DECL_BTN_EX(b, 0, "B") \
+DECL_BTN_EX(x, 9, "X") \
+DECL_BTN_EX(y, 1, "Y") \
+DECL_BTN_EX(left, 6, "D-Pad Left") \
+DECL_BTN_EX(right, 7, "D-Pad Right") \
+DECL_BTN_EX(down, 5, "D-Pad Down") \
+DECL_BTN_EX(up, 4, "D-Pad Up") \
+DECL_BTN_EX(start, 3, "Start/Pause") \
+DECL_BTN_EX(select, 2, "Z") \
+DECL_BTN_EX(r, 10, "R Trigger") \
+DECL_BTN_EX(l, 11, "L Trigger") \
+DECL_AXIS_EX(l_x_plus, +0, "Analog right") \
+DECL_AXIS_EX(l_x_minus, -0, "Analog left") \
+DECL_AXIS_EX(l_y_plus, +1, "Analog up") \
+DECL_AXIS_EX(l_y_minus, -1, "Analog down") \
+DECL_AXIS_EX(r_x_plus, +2, "C-stick right") \
+DECL_AXIS_EX(r_x_minus, -2, "C-stick left") \
+DECL_AXIS_EX(r_y_plus, +3, "C-stick up") \
+DECL_AXIS_EX(r_y_minus, -3, "C-stick down")
+
#define WIIUINPUT_DS3_DEFAULT_BINDS \
DECL_BTN_EX(menu_toggle, 16, "Playstation") \
DECL_BTN_EX(select, 2, "Select") \
@@ -743,8 +765,9 @@ const char* const input_builtin_autoconfs[] =
DECL_AUTOCONF_DEVICE(PAD_NAME_NUNCHUK, "wiiu", WIIUINPUT_NUNCHUK_DEFAULT_BINDS),
DECL_AUTOCONF_DEVICE(PAD_NAME_CLASSIC, "wiiu", WIIUINPUT_CLASSIC_CONTROLLER_DEFAULT_BINDS),
DECL_AUTOCONF_DEVICE(PAD_NAME_HID, "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
- DECL_AUTOCONF_DEVICE("GameCube Controller", "wiiu", WIIUINPUT_GAMECUBE_DEFAULT_BINDS),
- DECL_AUTOCONF_DEVICE("Sony DualShock 3", "wiiu", WIIUINPUT_DS3_DEFAULT_BINDS),
+ DECL_AUTOCONF_DEVICE("GameCube controller", "wiiu", WIIUINPUT_GAMECUBE_DEFAULT_BINDS),
+ DECL_AUTOCONF_DEVICE("WaveBird controller", "wiiu", WIIUINPUT_WAVEBIRD_DEFAULT_BINDS),
+ DECL_AUTOCONF_DEVICE("PLAYSTATION(R)3 Controller", "wiiu", WIIUINPUT_DS3_DEFAULT_BINDS),
#endif
#ifdef __PS3__
DECL_AUTOCONF_DEVICE("SixAxis Controller", "ps3", PS3INPUT_DEFAULT_BINDS),
diff --git a/input/input_driver.c b/input/input_driver.c
index c13eba5f01..f9eabff8aa 100644
--- a/input/input_driver.c
+++ b/input/input_driver.c
@@ -305,6 +305,9 @@ hid_driver_t *hid_drivers[] = {
#endif
#ifdef HW_RVL
&wiiusb_hid,
+#endif
+#if defined(WIIU)
+ &wiiu_hid,
#endif
&null_hid,
NULL,
@@ -3294,23 +3297,14 @@ void input_overlay_init(void)
}
#endif
-void set_connection_listener(pad_connection_listener_t *listener)
-{
- input_driver_st.pad_connection_listener = listener;
-}
-
void input_pad_connect(unsigned port, input_device_driver_t *driver)
{
- input_driver_state_t *input_st = &input_driver_st;
if (port >= MAX_USERS || !driver)
{
RARCH_ERR("[Input]: input_pad_connect: bad parameters\n");
return;
}
- if (input_st->pad_connection_listener)
- input_st->pad_connection_listener->connected(port, driver);
-
input_autoconfigure_connect(driver->name(port), NULL, driver->ident,
port, 0, 0);
}
diff --git a/input/input_driver.h b/input/input_driver.h
index d372ebc22e..75a70400ac 100644
--- a/input/input_driver.h
+++ b/input/input_driver.h
@@ -389,7 +389,6 @@ typedef struct
#ifdef HAVE_NETWORKGAMEPAD
input_remote_t *remote;
#endif
- pad_connection_listener_t *pad_connection_listener;
char *osk_grid[45]; /* ptr alignment */
int osk_ptr;
@@ -588,7 +587,7 @@ const hid_driver_t *input_hid_init_first(void);
*
* @return Pointer to hid_data struct
**/
-const void *hid_driver_get_data(void);
+void *hid_driver_get_data(void);
/**
* This should be called after we've invoked free() on the HID driver; the
@@ -679,14 +678,6 @@ void input_config_set_device_name_index(unsigned port, unsigned name_index);
*/
void input_config_set_device(unsigned port, unsigned id);
-/**
- * Registers a pad_connection_listener_interface with a function pointer that
- * is called when a joypad is connected. Only used by the wiiu_joypad driver.
- *
- * @param listener a struct that implements pad_connection_listener_interface
- */
-void set_connection_listener(pad_connection_listener_t *listener);
-
/* Clear input_device_info */
void input_config_clear_device_name(unsigned port);
void input_config_clear_device_display_name(unsigned port);
@@ -1037,6 +1028,7 @@ extern hid_driver_t iohidmanager_hid;
extern hid_driver_t btstack_hid;
extern hid_driver_t libusb_hid;
extern hid_driver_t wiiusb_hid;
+extern hid_driver_t wiiu_hid;
#endif /* HAVE_HID */
RETRO_END_DECLS
diff --git a/input/input_types.h b/input/input_types.h
index 4712d90cbe..235bae2626 100644
--- a/input/input_types.h
+++ b/input/input_types.h
@@ -106,9 +106,6 @@ typedef struct input_keyboard_line input_keyboard_line_t;
typedef struct rarch_joypad_info rarch_joypad_info_t;
typedef struct input_driver input_driver_t;
typedef struct input_keyboard_ctx_wait input_keyboard_ctx_wait_t;
-
-typedef struct joypad_connection joypad_connection_t;
-typedef struct pad_connection_listener_interface pad_connection_listener_t;
typedef struct turbo_buttons turbo_buttons_t;
-
+typedef struct joypad_connection joypad_connection_t;
#endif /* __INPUT_TYPES__H */
diff --git a/retroarch.c b/retroarch.c
index 84159e8875..fbe7d52921 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -15434,10 +15434,10 @@ const char* config_get_joypad_driver_options(void)
}
#ifdef HAVE_HID
-const void *hid_driver_get_data(void)
+void *hid_driver_get_data(void)
{
struct rarch_state *p_rarch = &rarch_st;
- return p_rarch->hid_data;
+ return (void *)p_rarch->hid_data;
}
/* This is only to be called after we've invoked free() on the