mirror of
https://github.com/libretro/RetroArch
synced 2025-03-16 07:21:03 +00:00
Merge pull request #10646 from QuarkTheAwesome/master
WiiU: Gamepad hotplugging support, theoretical multi-gamepad support, warning fixes
This commit is contained in:
commit
83410572cc
@ -244,7 +244,6 @@ static int32_t wiiu_hid_read(void *data, void *buffer, size_t size)
|
||||
static void start_polling_thread(wiiu_hid_t *hid)
|
||||
{
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2;
|
||||
BOOL result = false;
|
||||
int32_t stack_size = 0x8000;
|
||||
int32_t priority = 10;
|
||||
OSThread *thread = new_thread();
|
||||
@ -557,10 +556,13 @@ static void report_hid_error(const char *msg, wiiu_adapter_t *adapter, int32_t e
|
||||
case -111:
|
||||
RARCH_ERR("[hid]: invalid device handle (%s)\n", device);
|
||||
break;
|
||||
#if 0
|
||||
default:
|
||||
#if 0
|
||||
RARCH_ERR("[hid]: Unknown error (%d:%d: %s)\n",
|
||||
error_category, hid_error_code, device);
|
||||
#else
|
||||
(void)error_category;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ static bool init_hid_driver(void)
|
||||
|
||||
static bool hidpad_init(void *data)
|
||||
{
|
||||
(void *)data;
|
||||
int i;
|
||||
(void)data;
|
||||
|
||||
if(!init_hid_driver())
|
||||
{
|
||||
|
@ -81,10 +81,12 @@ static int get_slot_for_channel(unsigned channel)
|
||||
|
||||
static bool kpad_init(void *data)
|
||||
{
|
||||
(void *)data;
|
||||
(void)data;
|
||||
|
||||
kpad_poll();
|
||||
kpad_ready = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool kpad_query_pad(unsigned pad)
|
||||
|
@ -25,16 +25,80 @@
|
||||
|
||||
#define PANIC_BUTTON_MASK (VPAD_BUTTON_R | VPAD_BUTTON_L | VPAD_BUTTON_STICK_R | VPAD_BUTTON_STICK_L)
|
||||
|
||||
static bool wpad_ready = false;
|
||||
static uint64_t button_state = 0;
|
||||
static int16_t analog_state[3][2];
|
||||
typedef struct _drc_state drc_state;
|
||||
struct _drc_state
|
||||
{
|
||||
uint64_t button_state;
|
||||
int16_t analog_state[3][2];
|
||||
};
|
||||
static drc_state gamepads[WIIU_GAMEPAD_CHANNELS] = { 0 };
|
||||
|
||||
#define WPAD_INVALID_CHANNEL -1
|
||||
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) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return WPAD_INVALID_CHANNEL;
|
||||
}
|
||||
|
||||
static void wpad_deregister(unsigned channel) {
|
||||
unsigned slot;
|
||||
|
||||
if (channel >= WIIU_GAMEPAD_CHANNELS)
|
||||
return;
|
||||
|
||||
/* See if Gamepad is already disconnected */
|
||||
if (channel_slot_map[channel] == WPAD_INVALID_CHANNEL)
|
||||
return;
|
||||
|
||||
/* Sanity check, about to use as unsigned */
|
||||
if (channel_slot_map[channel] < 0) {
|
||||
channel_slot_map[channel] = WPAD_INVALID_CHANNEL;
|
||||
return;
|
||||
}
|
||||
|
||||
slot = (unsigned)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;
|
||||
}
|
||||
|
||||
static void wpad_register(unsigned channel) {
|
||||
int slot;
|
||||
|
||||
if (channel >= WIIU_GAMEPAD_CHANNELS)
|
||||
return;
|
||||
|
||||
/* 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)
|
||||
return;
|
||||
|
||||
slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
|
||||
if(slot < 0)
|
||||
return;
|
||||
|
||||
hid_instance.pad_list[slot].connected = true;
|
||||
input_pad_connect(slot, &wpad_driver);
|
||||
channel_slot_map[channel] = slot;
|
||||
}
|
||||
|
||||
static void update_button_state(uint64_t *state, uint32_t held_buttons)
|
||||
{
|
||||
*state = held_buttons & VPAD_MASK_BUTTONS;
|
||||
}
|
||||
|
||||
static void update_analog_state(int16_t state[3][2], VPADStatus *vpad)
|
||||
static void update_analog_state(int16_t state[3][2], VPADStatus *vpad)
|
||||
{
|
||||
state[RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = WIIU_READ_STICK(vpad->leftStick.x);
|
||||
state[RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = WIIU_READ_STICK(vpad->leftStick.y);
|
||||
@ -51,11 +115,12 @@ static int16_t scale_touchpad(int16_t from_min, int16_t from_max,
|
||||
return (((value - from_min) * to_range) / from_range) + to_min;
|
||||
}
|
||||
|
||||
static void get_calibrated_point(VPADTouchData *point, struct video_viewport *viewport, VPADStatus *vpad)
|
||||
static void get_calibrated_point(VPADTouchData *point,
|
||||
struct video_viewport *viewport, VPADStatus *vpad, unsigned channel)
|
||||
{
|
||||
VPADTouchData calibrated720p = {0};
|
||||
|
||||
VPADGetTPCalibratedPoint(PAD_GAMEPAD, &calibrated720p, &(vpad->tpNormal));
|
||||
VPADGetTPCalibratedPoint(channel, &calibrated720p, &(vpad->tpNormal));
|
||||
point->x = scale_touchpad(12, 1268, 0, viewport->full_width, calibrated720p.x);
|
||||
point->y = scale_touchpad(12, 708, 0, viewport->full_height, calibrated720p.y);
|
||||
}
|
||||
@ -88,9 +153,9 @@ static void apply_clamping(VPADTouchData *point, struct video_viewport *viewport
|
||||
}
|
||||
|
||||
static void get_touch_coordinates(VPADTouchData *point, VPADStatus *vpad,
|
||||
struct video_viewport *viewport, bool *clamped)
|
||||
VPADChan channel, struct video_viewport *viewport, bool *clamped)
|
||||
{
|
||||
get_calibrated_point(point, viewport, vpad);
|
||||
get_calibrated_point(point, viewport, vpad, channel);
|
||||
apply_clamping(point, viewport, clamped);
|
||||
}
|
||||
|
||||
@ -127,7 +192,7 @@ static void log_coords(int16_t x, int16_t y)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void update_touch_state(int16_t state[3][2], uint64_t *buttons, VPADStatus *vpad)
|
||||
static void update_touch_state(int16_t state[3][2], uint64_t *buttons, VPADStatus *vpad, VPADChan channel)
|
||||
{
|
||||
VPADTouchData point = {0};
|
||||
struct video_viewport viewport = {0};
|
||||
@ -140,7 +205,7 @@ static void update_touch_state(int16_t state[3][2], uint64_t *buttons, VPADStatu
|
||||
}
|
||||
|
||||
video_driver_get_viewport_info(&viewport);
|
||||
get_touch_coordinates(&point, vpad, &viewport, &touch_clamped);
|
||||
get_touch_coordinates(&point, vpad, channel, &viewport, &touch_clamped);
|
||||
|
||||
state[WIIU_DEVICE_INDEX_TOUCHPAD][RETRO_DEVICE_ID_ANALOG_X] = scale_touchpad(
|
||||
viewport.x, viewport.x + viewport.width, -0x7fff, 0x7fff, point.x);
|
||||
@ -168,67 +233,90 @@ static void wpad_poll(void)
|
||||
{
|
||||
VPADStatus vpad;
|
||||
VPADReadError error;
|
||||
VPADChan channel;
|
||||
|
||||
VPADRead(PAD_GAMEPAD, &vpad, 1, &error);
|
||||
for (channel = VPAD_CHAN_0; channel < WIIU_GAMEPAD_CHANNELS; channel++) {
|
||||
VPADRead(channel, &vpad, 1, &error);
|
||||
|
||||
if (error)
|
||||
return;
|
||||
if (error == VPAD_READ_SUCCESS || error == VPAD_READ_NO_SAMPLES) {
|
||||
/* Gamepad is connected! */
|
||||
wpad_register(channel);
|
||||
} else if (error == VPAD_READ_INVALID_CONTROLLER) {
|
||||
wpad_deregister(channel);
|
||||
}
|
||||
|
||||
update_button_state(&button_state, vpad.hold);
|
||||
update_analog_state(analog_state, &vpad);
|
||||
update_touch_state(analog_state, &button_state, &vpad);
|
||||
check_panic_button(vpad.hold);
|
||||
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);
|
||||
check_panic_button(vpad.hold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool wpad_init(void *data)
|
||||
{
|
||||
int slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
|
||||
if(slot < 0)
|
||||
return false;
|
||||
|
||||
hid_instance.pad_list[slot].connected = true;
|
||||
input_pad_connect(slot, &wpad_driver);
|
||||
wpad_poll();
|
||||
wpad_ready = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wpad_query_pad(unsigned pad)
|
||||
{
|
||||
return wpad_ready && pad < MAX_USERS;
|
||||
return pad < MAX_USERS && (to_gamepad_channel(pad) != WPAD_INVALID_CHANNEL);
|
||||
}
|
||||
|
||||
static void wpad_destroy(void)
|
||||
{
|
||||
wpad_ready = false;
|
||||
|
||||
}
|
||||
|
||||
static bool wpad_button(unsigned pad, uint16_t button_bit)
|
||||
{
|
||||
VPADChan channel;
|
||||
|
||||
if (!wpad_query_pad(pad))
|
||||
return false;
|
||||
|
||||
return button_state & (UINT64_C(1) << button_bit);
|
||||
channel = to_gamepad_channel(pad);
|
||||
if (channel < 0)
|
||||
return false;
|
||||
|
||||
return gamepads[channel].button_state & (UINT64_C(1) << button_bit);
|
||||
}
|
||||
|
||||
static void wpad_get_buttons(unsigned pad, input_bits_t *state)
|
||||
{
|
||||
if (!wpad_query_pad(pad))
|
||||
VPADChan channel;
|
||||
|
||||
if (!wpad_query_pad(pad)) {
|
||||
BIT256_CLEAR_ALL_PTR(state);
|
||||
else
|
||||
BITS_COPY32_PTR(state, button_state);
|
||||
return;
|
||||
}
|
||||
|
||||
channel = to_gamepad_channel(pad);
|
||||
if (channel < 0) {
|
||||
BIT256_CLEAR_ALL_PTR(state);
|
||||
return;
|
||||
}
|
||||
|
||||
BITS_COPY32_PTR(state, gamepads[channel].button_state);
|
||||
}
|
||||
|
||||
static int16_t wpad_axis(unsigned pad, uint32_t axis)
|
||||
{
|
||||
axis_data data;
|
||||
VPADChan channel;
|
||||
|
||||
if (!wpad_query_pad(pad) || axis == AXIS_NONE)
|
||||
return 0;
|
||||
|
||||
channel = to_gamepad_channel(pad);
|
||||
if (channel < 0)
|
||||
return 0;
|
||||
|
||||
pad_functions.read_axis_data(axis, &data);
|
||||
return pad_functions.get_axis_value(data.axis, analog_state, data.is_negative);
|
||||
return pad_functions.get_axis_value(data.axis, gamepads[channel].analog_state, data.is_negative);
|
||||
}
|
||||
|
||||
static const char *wpad_name(unsigned pad)
|
||||
|
@ -94,13 +94,6 @@ struct _wiiu_adapter_list {
|
||||
wiiu_adapter_t *list;
|
||||
};
|
||||
|
||||
extern wiiu_pad_functions_t pad_functions;
|
||||
extern input_device_driver_t wiiu_joypad;
|
||||
extern input_device_driver_t wpad_driver;
|
||||
extern input_device_driver_t kpad_driver;
|
||||
extern input_device_driver_t hidpad_driver;
|
||||
extern hid_driver_t wiiu_hid;
|
||||
|
||||
static void *alloc_zeroed(size_t alignment, size_t size);
|
||||
static OSThread *new_thread(void);
|
||||
static wiiu_hid_t *new_hid(void);
|
||||
@ -123,9 +116,7 @@ static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event);
|
||||
static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event);
|
||||
static void synchronized_process_adapters(wiiu_hid_t *hid);
|
||||
static void synchronized_add_to_adapters_list(wiiu_adapter_t *adapter);
|
||||
static wiiu_adapter_t *synchronized_remove_from_adapters_list(uint32_t handle);
|
||||
static void synchronized_add_event(wiiu_attach_event *event);
|
||||
static void wiiu_start_read_loop(wiiu_adapter_t *adapter);
|
||||
static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error,
|
||||
uint8_t *buffer, uint32_t buffer_size, void *userdata);
|
||||
static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack);
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <wiiu/vpad.h>
|
||||
#include <wiiu/kpad.h>
|
||||
#include <wiiu/pad_strings.h>
|
||||
#include "hid.h"
|
||||
|
||||
#include "../../common/hid/hid_device_driver.h"
|
||||
#include "../../connect/joypad_connection.h"
|
||||
@ -51,7 +50,7 @@
|
||||
|
||||
#define WIIU_DEVICE_INDEX_TOUCHPAD 2
|
||||
|
||||
#define PAD_GAMEPAD 0
|
||||
#define WIIU_GAMEPAD_CHANNELS 2
|
||||
#define WIIU_WIIMOTE_CHANNELS 4
|
||||
|
||||
#define WIIU_ANALOG_FACTOR 0x7ff0
|
||||
@ -65,4 +64,11 @@ struct _wiiu_pad_functions {
|
||||
void (*connect)(unsigned pad, input_device_driver_t *driver);
|
||||
};
|
||||
|
||||
extern wiiu_pad_functions_t pad_functions;
|
||||
extern input_device_driver_t wiiu_joypad;
|
||||
extern input_device_driver_t wpad_driver;
|
||||
extern input_device_driver_t kpad_driver;
|
||||
extern input_device_driver_t hidpad_driver;
|
||||
extern hid_driver_t wiiu_hid;
|
||||
|
||||
#endif /* __WIIU_INPUT__H */
|
||||
|
@ -103,6 +103,11 @@ typedef enum VPADReadError
|
||||
VPAD_READ_INVALID_CONTROLLER = -2,
|
||||
} VPADReadError;
|
||||
|
||||
typedef enum VPADChan
|
||||
{
|
||||
VPAD_CHAN_0 = 0,
|
||||
} VPADChan;
|
||||
|
||||
typedef struct VPADVec2D
|
||||
{
|
||||
float x;
|
||||
|
Loading…
x
Reference in New Issue
Block a user