diff --git a/Makefile.orbis b/Makefile.orbis index be1e90ca10..edf4191d78 100644 --- a/Makefile.orbis +++ b/Makefile.orbis @@ -58,8 +58,8 @@ else BLACKLIST := OBJ := $(filter-out $(BLACKLIST),$(OBJ)) - #OBJ += input/drivers/psp_input.o - #OBJ += input/drivers_joypad/psp_joypad.o + OBJ += input/drivers/ps4_input.o + OBJ += input/drivers_joypad/ps4_joypad.o #OBJ += audio/drivers/psp_audio.o #OBJ += frontend/drivers/platform_orbis.o endif diff --git a/configuration.c b/configuration.c index 871a7cc7b6..034b17bc35 100644 --- a/configuration.c +++ b/configuration.c @@ -214,6 +214,7 @@ enum input_driver_enum INPUT_X, INPUT_WAYLAND, INPUT_DINPUT, + INPUT_PS4, INPUT_PS3, INPUT_PSP, INPUT_PS2, @@ -439,6 +440,8 @@ static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2; static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_RWEBINPUT; #elif defined(_WIN32) static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DINPUT; +#elif defined(ORBIS) +static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS4; #elif defined(__CELLOS_LV2__) static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS3; #elif defined(PSP) || defined(VITA) @@ -829,6 +832,8 @@ const char *config_get_default_input(void) { case INPUT_ANDROID: return "android"; + case INPUT_PS4: + return "ps4"; case INPUT_PS3: return "ps3"; case INPUT_PSP: diff --git a/griffin/griffin.c b/griffin/griffin.c index da3b6e426e..aa2b0deeb3 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -569,6 +569,9 @@ INPUT #elif defined(SN_TARGET_PSP2) || defined(PSP) || defined(VITA) #include "../input/drivers/psp_input.c" #include "../input/drivers_joypad/psp_joypad.c" +#elif defined(ORBIS) +#include "../input/drivers/ps4_input.c" +#include "../input/drivers_joypad/ps4_joypad.c" #elif defined(PS2) #include "../input/drivers/ps2_input.c" #include "../input/drivers_joypad/ps2_joypad.c" diff --git a/input/drivers/ps4_input.c b/input/drivers/ps4_input.c new file mode 100644 index 0000000000..f2ffafc7bc --- /dev/null +++ b/input/drivers/ps4_input.c @@ -0,0 +1,155 @@ +/* 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 + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include + +#include +#include +#include + +#include "../input_driver.h" + +/* TODO/FIXME - + * fix game focus toggle */ + +typedef struct ps4_input +{ + bool blocked; + const input_device_driver_t *joypad; +} ps4_input_t; + +static void ps4_input_poll(void *data) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + + if (ps4 && ps4->joypad) + ps4->joypad->poll(); +} + +static int16_t ps4_input_state(void *data, + rarch_joypad_info_t joypad_info, + const struct retro_keybind **binds, + unsigned port, unsigned device, + unsigned idx, unsigned id) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + return input_joypad_pressed(ps4->joypad, joypad_info, port, binds[port], id); + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(ps4->joypad, joypad_info, port, idx, id, binds[port]); + break; + } + + return 0; +} + +static void ps4_input_free_input(void *data) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + + if (ps4 && ps4->joypad) + ps4->joypad->destroy(); + + free(data); +} + +static void* ps4_input_initialize(const char *joypad_driver) +{ + ps4_input_t *ps4 = (ps4_input_t*)calloc(1, sizeof(*ps4)); + if (!ps4) + return NULL; + + ps4->joypad = input_joypad_init_driver(joypad_driver, ps4); + + return ps4; +} + +static uint64_t ps4_input_get_capabilities(void *data) +{ + (void)data; + + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); +} + +static const input_device_driver_t *ps4_input_get_joypad_driver(void *data) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + if (ps4) + return ps4->joypad; + return NULL; +} + +static void ps4_input_grab_mouse(void *data, bool state) +{ + (void)data; + (void)state; +} + +static bool ps4_input_set_rumble(void *data, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + + if (ps4 && ps4->joypad) + return input_joypad_set_rumble(ps4->joypad, + port, effect, strength); + return false; +} + +static bool ps4_input_keyboard_mapping_is_blocked(void *data) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + if (!ps4) + return false; + return ps4->blocked; +} + +static void ps4_input_keyboard_mapping_set_block(void *data, bool value) +{ + ps4_input_t *ps4 = (ps4_input_t*)data; + if (!ps4) + return; + ps4->blocked = value; +} + +input_driver_t input_ps4 = { + ps4_input_initialize, + ps4_input_poll, + ps4_input_state, + ps4_input_free_input, + NULL, + NULL, + ps4_input_get_capabilities, + "orbis", + ps4_input_grab_mouse, + NULL, + ps4_input_set_rumble, + ps4_input_get_joypad_driver, + NULL, + ps4_input_keyboard_mapping_is_blocked, + ps4_input_keyboard_mapping_set_block, +}; diff --git a/input/drivers_joypad/ps4_joypad.c b/input/drivers_joypad/ps4_joypad.c new file mode 100644 index 0000000000..054bf4773a --- /dev/null +++ b/input/drivers_joypad/ps4_joypad.c @@ -0,0 +1,217 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2013-2014 - CatalystG + * + * 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 +#include + +#include "../input_driver.h" + +#include "../../tasks/tasks_internal.h" + +#include +#include + +#define PS4_MAX_ORBISPADS 16 +#define SCE_USER_SERVICE_MAX_LOGIN_USERS 16 +#define SCE_USER_SERVICE_USER_ID_INVALID 0xFFFFFFFF +#define SCE_ORBISPAD_ERROR_ALREADY_OPENED 0x80920004 + +#define ORBISPAD_L3 0x00000002 +#define ORBISPAD_R3 0x00000004 +#define ORBISPAD_OPTIONS 0x00000008 +#define ORBISPAD_UP 0x00000010 +#define ORBISPAD_RIGHT 0x00000020 +#define ORBISPAD_DOWN 0x00000040 +#define ORBISPAD_LEFT 0x00000080 +#define ORBISPAD_L2 0x00000100 +#define ORBISPAD_R2 0x00000200 +#define ORBISPAD_L1 0x00000400 +#define ORBISPAD_R1 0x00000800 +#define ORBISPAD_TRIANGLE 0x00001000 +#define ORBISPAD_CIRCLE 0x00002000 +#define ORBISPAD_CROSS 0x00004000 +#define ORBISPAD_SQUARE 0x00008000 +#define ORBISPAD_TOUCH_PAD 0x00100000 +#define ORBISPAD_INTERCEPTED 0x80000000 + +typedef struct SceUserServiceLoginUserIdList { + int32_t userId[SCE_USER_SERVICE_MAX_LOGIN_USERS]; +} SceUserServiceLoginUserIdList; + +int sceUserServiceGetLoginUserIdList(SceUserServiceLoginUserIdList* userIdList); + +/* + * Global var's + */ +typedef struct +{ + SceUserServiceUserId userId; + int handle; + bool connected; +} ds_joypad_state; + +static ds_joypad_state ds_joypad_states[PS4_MAX_ORBISPADS]; +static uint64_t pad_state[PS4_MAX_ORBISPADS]; +static int16_t analog_state[PS4_MAX_ORBISPADS][2][2]; +static int16_t num_players = 0; + + +static const char *ps4_joypad_name(unsigned pad) +{ + return "PS4 Controller"; +} + +static bool ps4_joypad_init(void *data) +{ + num_players = 0; + + scePadInit(); + + SceUserServiceLoginUserIdList userIdList; + + int result = sceUserServiceGetLoginUserIdList(&userIdList); + if (result < 0) + { + + for (int i = 0; i < SCE_USER_SERVICE_MAX_LOGIN_USERS; i++) + { + SceUserServiceUserId userId = userIdList.userId[i]; + + if (userId != SCE_USER_SERVICE_USER_ID_INVALID) + { + int index = 0; + + while(index < num_players){ + ds_joypad_states[index].userId = userId; + index++; + } + + if (index == num_players) + { + ds_joypad_states[num_players].handle = scePadOpen(userId, 0, 0, NULL); + if (ds_joypad_states[num_players].handle > 0){ + num_players++; + ds_joypad_states[num_players].connected = true; + ds_joypad_states[num_players].userId = userId; + + bool auto_configure = input_autoconfigure_connect( ps4_joypad_name(i), + NULL, + ps4_joypad.ident, + i, + 0, + 0); + if (!auto_configure) { + input_config_set_device_name(i, ps4_joypad_name(i)); + } + } + } + } + + } + + } + + return true; +} + +static bool ps4_joypad_button(unsigned port_num, uint16_t joykey) +{ + if (port_num >= PS4_MAX_ORBISPADS) + return false; + + return (pad_state[port_num] & (UINT64_C(1) << joykey)); +} + +static void ps4_joypad_get_buttons(unsigned port_num, input_bits_t *state) +{ + BIT256_CLEAR_ALL_PTR(state); +} + +static int16_t ps4_joypad_axis(unsigned port_num, uint32_t joyaxis) +{ + return 0; +} + +static void ps4_joypad_poll(void) +{ + unsigned player; + unsigned players_count = num_players; + ScePadData buttons; + + for (player = 0; player < players_count; player++) + { + unsigned j, k; + unsigned i = player; + unsigned p = player; + + int ret = scePadReadState(ds_joypad_states[player].handle,&buttons); + if (ret != 0) + { + int32_t state_tmp = buttons.buttons; + + pad_state[i] = 0; + + pad_state[i] |= (state_tmp & ORBISPAD_LEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_DOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_RIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_UP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_OPTIONS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0; + //pad_state[i] |= (state_tmp & ORBISPAD_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_TRIANGLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_SQUARE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_CROSS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_CIRCLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_R1) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_L1) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_R2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_L2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_R3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0; + pad_state[i] |= (state_tmp & ORBISPAD_L3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0; + } + } + +} + +static bool ps4_joypad_query_pad(unsigned pad) +{ + return pad < PS4_MAX_ORBISPADS && pad_state[pad]; +} + +static bool ps4_joypad_rumble(unsigned pad, + enum retro_rumble_effect effect, uint16_t strength) +{ + return false; +} + + +static void ps4_joypad_destroy(void) +{ +} + +input_device_driver_t ps4_joypad = { + ps4_joypad_init, + ps4_joypad_query_pad, + ps4_joypad_destroy, + ps4_joypad_button, + ps4_joypad_get_buttons, + ps4_joypad_axis, + ps4_joypad_poll, + ps4_joypad_rumble, + ps4_joypad_name, + "ps4", +}; diff --git a/input/input_driver.c b/input/input_driver.c index 3d9d60f683..86e9ee51c5 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -80,6 +80,9 @@ void fire_connection_listener(unsigned port, input_device_driver_t *driver) } static const input_driver_t *input_drivers[] = { +#ifdef ORBIS + &input_ps4, +#endif #ifdef __CELLOS_LV2__ &input_ps3, #endif @@ -161,6 +164,9 @@ static input_device_driver_t *joypad_drivers[] = { #ifdef _XBOX &xdk_joypad, #endif +#if defined(PS4) + &ps4_joypad, +#endif #if defined(PSP) || defined(VITA) &psp_joypad, #endif diff --git a/input/input_driver.h b/input/input_driver.h index 1ac166478b..2c5c35a7ea 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -805,6 +805,7 @@ extern input_device_driver_t parport_joypad; extern input_device_driver_t udev_joypad; extern input_device_driver_t xinput_joypad; extern input_device_driver_t sdl_joypad; +extern input_device_driver_t ps4_joypad; extern input_device_driver_t ps3_joypad; extern input_device_driver_t psp_joypad; extern input_device_driver_t ps2_joypad; @@ -825,6 +826,7 @@ extern input_driver_t input_android; extern input_driver_t input_sdl; extern input_driver_t input_dinput; extern input_driver_t input_x; +extern input_driver_t input_ps4; extern input_driver_t input_ps3; extern input_driver_t input_psp; extern input_driver_t input_ps2;