diff --git a/Makefile.common b/Makefile.common index 8490a0cb8b..c0e54a63c0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1190,6 +1190,7 @@ ifeq ($(HAVE_HID), 1) input/connect/connect_psxadapter.o \ input/connect/connect_ps3.o \ input/connect/connect_ps4.o \ + input/connect/connect_ps4_hori_mini.o \ input/connect/connect_wii.o \ input/connect/connect_retrode.o \ input/connect/connect_nesusb.o \ diff --git a/griffin/griffin.c b/griffin/griffin.c index d645f710e0..9d8c02a606 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -808,6 +808,7 @@ INPUT (HID) #include "../input/connect/connect_ps2adapter.c" #include "../input/connect/connect_psxadapter.c" #include "../input/connect/connect_retrode.c" +#include "../input/connect/connect_ps4_hori_mini.c" #endif /*============================================================ diff --git a/input/connect/connect_ps4_hori_mini.c b/input/connect/connect_ps4_hori_mini.c new file mode 100644 index 0000000000..eda89d6a7c --- /dev/null +++ b/input/connect/connect_ps4_hori_mini.c @@ -0,0 +1,188 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013-2014 - Jason Fetters + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <string.h> +#include <stdlib.h> + +#include <boolean.h> +#include "joypad_connection.h" +#include "../input_defines.h" + +struct hidpad_ps4_hori_mini_data +{ + struct pad_connection* connection; + uint32_t slot; + uint32_t buttons; + uint8_t data[512]; +}; + +static void* hidpad_ps4_hori_mini_init(void *data, uint32_t slot, hid_driver_t *driver) +{ + struct pad_connection* connection = (struct pad_connection*)data; + struct hidpad_ps4_hori_mini_data* device = (struct hidpad_ps4_hori_mini_data*) + calloc(1, sizeof(struct hidpad_ps4_hori_mini_data)); + + if (!device) + return NULL; + + if (!connection) + { + free(device); + return NULL; + } + + device->connection = connection; + device->slot = slot; + + return device; +} + +static void hidpad_ps4_hori_mini_deinit(void *data) +{ + struct hidpad_ps4_hori_mini_data *device = (struct hidpad_ps4_hori_mini_data*)data; + + if (device) + free(device); +} + +static void hidpad_ps4_hori_mini_get_buttons(void *data, input_bits_t *state) +{ + struct hidpad_ps4_hori_mini_data *device = (struct hidpad_ps4_hori_mini_data*)data; + if ( device ) + { + /* copy 32 bits : needed for PS button? */ + BITS_COPY32_PTR(state, device->buttons); + } + else + BIT256_CLEAR_ALL_PTR(state); +} + +static int16_t hidpad_ps4_hori_mini_get_axis(void *data, unsigned axis) +{ + int val; + struct hidpad_ps4_hori_mini_data *device = (struct hidpad_ps4_hori_mini_data*)data; + + if (!device || axis >= 4) + return 0; + + val = device->data[2 + axis]; + + val = (val << 8) - 0x8000; + + if (abs(val) > 0x1000) + return val; + return 0; +} + +static void hidpad_ps4_hori_mini_packet_handler(void *data, + uint8_t *packet, uint16_t size) +{ + uint32_t i, pressed_keys; + static const uint32_t button_mapping[15] = + { + RETRO_DEVICE_ID_JOYPAD_Y, + RETRO_DEVICE_ID_JOYPAD_B, + RETRO_DEVICE_ID_JOYPAD_A, + RETRO_DEVICE_ID_JOYPAD_X, + RETRO_DEVICE_ID_JOYPAD_L, + RETRO_DEVICE_ID_JOYPAD_R, + RETRO_DEVICE_ID_JOYPAD_L2, + RETRO_DEVICE_ID_JOYPAD_R2, + RETRO_DEVICE_ID_JOYPAD_SELECT, + RETRO_DEVICE_ID_JOYPAD_START, + RETRO_DEVICE_ID_JOYPAD_L3, + RETRO_DEVICE_ID_JOYPAD_R3, + 16, + 17, + 18 + }; + struct hidpad_ps4_hori_mini_data *device = (struct hidpad_ps4_hori_mini_data*)data; + + if (!device) + return; + + memcpy(device->data, packet, size); + + device->buttons = 0; + + uint8_t dpad = device->data[6] & 0xF; + switch(dpad) + { + case 0: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_UP); + break; + case 1: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_UP); + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT); + break; + case 2: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT); + break; + case 3: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT); + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_DOWN); + break; + case 4: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_DOWN); + break; + case 5: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_DOWN); + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_LEFT); + break; + case 6: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_LEFT); + break; + case 7: + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_LEFT); + device->buttons |= (1 << RETRO_DEVICE_ID_JOYPAD_UP); + break; + } + + pressed_keys = ((device->data[6] & 0xF0) >> 4) | + (device->data[7] << 4) | + (device->data[8] << 12); + + for (i = 0; i < 15; i++) { + device->buttons |= (pressed_keys & (1 << i)) ? + (1 << button_mapping[i]) : 0; + } +} + +static void hidpad_ps4_hori_mini_set_rumble(void *data, + enum retro_rumble_effect effect, uint16_t strength) +{ + (void)data; + (void)effect; + (void)strength; +} + +const char * hidpad_ps4_hori_mini_get_name(void *data) +{ + (void)data; + /* For now we return a single static name */ + return "HORI mini wired PS4"; +} + +pad_connection_interface_t pad_connection_ps4_hori_mini = { + hidpad_ps4_hori_mini_init, + hidpad_ps4_hori_mini_deinit, + hidpad_ps4_hori_mini_packet_handler, + hidpad_ps4_hori_mini_set_rumble, + hidpad_ps4_hori_mini_get_buttons, + hidpad_ps4_hori_mini_get_axis, + hidpad_ps4_hori_mini_get_name, +}; diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 6e706a5e18..f7f92369ea 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -118,6 +118,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn, { "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; @@ -152,6 +153,8 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn, pad_map[10].pid = 774; pad_map[11].vid = VID_RETRODE; pad_map[11].pid = PID_RETRODE; + pad_map[12].vid = VID_HORI_1; + pad_map[12].pid = PID_HORI_MINI_WIRED_PS4; if (s) { diff --git a/input/connect/joypad_connection.h b/input/connect/joypad_connection.h index ea45d53a93..9489fe4836 100644 --- a/input/connect/joypad_connection.h +++ b/input/connect/joypad_connection.h @@ -40,6 +40,7 @@ #define VID_PS3_CLONE SWAP_IF_BIG(0x0313) #define VID_SNES_CLONE SWAP_IF_BIG(0x081f) #define VID_RETRODE SWAP_IF_BIG(0x0403) +#define VID_HORI_1 SWAP_IF_BIG(0x0f0d) #define PID_NONE 0x0000 #define PID_NINTENDO_PRO SWAP_IF_BIG(0x0330) @@ -52,6 +53,7 @@ #define PID_PCS_PS2PSX SWAP_IF_BIG(0x0001) #define PID_PCS_PSX2PS3 SWAP_IF_BIG(0x0003) #define PID_RETRODE SWAP_IF_BIG(0x97c1) +#define PID_HORI_MINI_WIRED_PS4 SWAP_IF_BIG(0x00ee) struct joypad_connection { @@ -83,6 +85,7 @@ extern pad_connection_interface_t pad_connection_wiiugca; extern pad_connection_interface_t pad_connection_ps2adapter; extern pad_connection_interface_t pad_connection_psxadapter; extern pad_connection_interface_t pad_connection_retrode; +extern pad_connection_interface_t pad_connection_ps4_hori_mini; int32_t pad_connection_pad_init(joypad_connection_t *joyconn, const char* name, uint16_t vid, uint16_t pid,