diff --git a/Makefile.griffin b/Makefile.griffin index a5ab7229d9..945b9ad5e9 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -271,7 +271,7 @@ else ifeq ($(platform), vita) PLATCFLAGS := -mfloat-abi=hard -fsingle-precision-constant \ -mword-relocations -fno-unwind-tables -fno-asynchronous-unwind-tables -ftree-vectorize -fno-optimize-sibling-calls LIBS += -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ - -lSceSysmodule_stub -lSceCtrl_stub -lSceTouch_stub -lSceAudio_stub -lSceFiber_stub\ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub -lSceFiber_stub\ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceMotion_stub -lSceAppMgr_stub -lpng -lm -lc diff --git a/Makefile.vita b/Makefile.vita index abc953ccec..ae79600c32 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -116,7 +116,7 @@ endif CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions VITA_LIBS := -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub \ - -lSceSysmodule_stub -lSceCtrl_stub -lSceTouch_stub -lSceAudio_stub \ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub \ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lpthread -lpng -lz diff --git a/Makefile.vita.salamander b/Makefile.vita.salamander index 20160de36e..f479726e6d 100644 --- a/Makefile.vita.salamander +++ b/Makefile.vita.salamander @@ -22,7 +22,7 @@ RARCH_DEFINES = -DVITA -DIS_SALAMANDER -DRARCH_CONSOLE LIBDIR = LDFLAGS = LIBS = -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ - -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lSceFiber_stub\ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceAudio_stub -lSceFiber_stub\ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceMotion_stub -lSceAppMgr_stub -lfreetype -lpng -lm -lc diff --git a/input/drivers/psp_input.c b/input/drivers/psp_input.c index 6ee849ec17..0116718805 100644 --- a/input/drivers/psp_input.c +++ b/input/drivers/psp_input.c @@ -27,6 +27,13 @@ #include #elif defined(VITA) #include +#include +#include +#define VITA_NUM_SCANCODES 115 /* size of rarch_key_map_vita */ +#define VITA_MAX_SCANCODE 0xE7 +#define VITA_NUM_MODIFIERS 11 /* number of modifiers reported */ +#define MOUSE_MAX_X 960 +#define MOUSE_MAX_Y 544 #elif defined(PSP) #include #endif @@ -42,6 +49,23 @@ #include "../../defines/psp_defines.h" #include "../input_driver.h" +#ifdef VITA +#include "../input_keymaps.h" +uint8_t modifier_lut[VITA_NUM_MODIFIERS][2] = +{ + { 0xE0, 0x01 }, /* LCTRL */ + { 0xE4, 0x10 }, /* RCTRL */ + { 0xE1, 0x02 }, /* LSHIFT */ + { 0xE5, 0x20 }, /* RSHIFT */ + { 0xE2, 0x04 }, /* LALT */ + { 0xE6, 0x40 }, /* RALT */ + { 0xE3, 0x08 }, /* LGUI */ + { 0xE7, 0x80 }, /* RGUI */ + { 0x53, 0x01 }, /* NUMLOCK */ + { 0x39, 0x02 }, /* CAPSLOCK */ + { 0x47, 0x04 } /* SCROLLOCK */ +}; +#endif /* TODO/FIXME - * fix game focus toggle */ @@ -50,6 +74,20 @@ typedef struct psp_input { bool blocked; const input_device_driver_t *joypad; +#ifdef VITA + int keyboard_hid_handle; + uint8_t prev_keys[6]; + bool keyboard_state[VITA_MAX_SCANCODE + 1]; + + int mouse_hid_handle; + int32_t mouse_x; + int32_t mouse_y; + int32_t mouse_x_delta; + int32_t mouse_y_delta; + bool mouse_button_left; + bool mouse_button_right; + bool mouse_button_middle; +#endif } psp_input_t; static void psp_input_poll(void *data) @@ -58,8 +96,206 @@ static void psp_input_poll(void *data) if (psp && psp->joypad) psp->joypad->poll(); + +#ifdef VITA + unsigned int i = 0; + int key_sym = 0; + unsigned key_code = 0; + uint8_t mod_code = 0; + uint16_t mod = 0; + uint8_t modifiers[2] = { 0, 0 }; + bool key_held = false; + int numReports = 0; + int mouse_velocity_x = 0; + int mouse_velocity_y = 0; + SceHidKeyboardReport k_reports[SCE_HID_MAX_REPORT]; + SceHidMouseReport m_reports[SCE_HID_MAX_REPORT]; + + if (psp->keyboard_hid_handle > 0) + { + numReports = sceHidKeyboardRead(psp->keyboard_hid_handle, (SceHidKeyboardReport**)&k_reports, SCE_HID_MAX_REPORT); + + if (numReports < 0) { + psp->keyboard_hid_handle = 0; + } + else if (numReports) { + modifiers[0] = k_reports[numReports - 1].modifiers[0]; + modifiers[1] = k_reports[numReports - 1].modifiers[1]; + mod = 0; + if (modifiers[0] & 0x11) + mod |= RETROKMOD_CTRL; + if (modifiers[0] & 0x22) + mod |= RETROKMOD_SHIFT; + if (modifiers[0] & 0x44) + mod |= RETROKMOD_ALT; + if (modifiers[0] & 0x88) + mod |= RETROKMOD_META; + if (modifiers[1] & 0x01) + mod |= RETROKMOD_NUMLOCK; + if (modifiers[1] & 0x02) + mod |= RETROKMOD_CAPSLOCK; + if (modifiers[1] & 0x04) + mod |= RETROKMOD_SCROLLOCK; + + for (i = 0; i < VITA_NUM_MODIFIERS; i++) + { + key_sym = (int) modifier_lut[i][0]; + mod_code = modifier_lut[i][1]; + key_code = input_keymaps_translate_keysym_to_rk(key_sym); + if (i < 8) + { + key_held = (modifiers[0] & mod_code); + } + else + { + key_held = (modifiers[1] & mod_code); + } + + if (key_held && !(psp->keyboard_state[key_sym])) + { + psp->keyboard_state[key_sym] = true; + input_keyboard_event(true, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + else if (!key_held && (psp->keyboard_state[key_sym])) + { + psp->keyboard_state[key_sym] = false; + input_keyboard_event(false, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + } + + for (i = 0; i < 6; i++) + { + key_sym = k_reports[numReports - 1].keycodes[i]; + + if (key_sym != psp->prev_keys[i]) + { + if (psp->prev_keys[i]) + { + psp->keyboard_state[psp->prev_keys[i]] = false; + key_code = input_keymaps_translate_keysym_to_rk(psp->prev_keys[i]); + input_keyboard_event(false, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + if (key_sym) + { + psp->keyboard_state[key_sym] = true; + key_code = input_keymaps_translate_keysym_to_rk(key_sym); + input_keyboard_event(true, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + psp->prev_keys[i] = key_sym; + } + } + } + } + + if (psp->mouse_hid_handle > 0) + { + numReports = sceHidMouseRead(psp->mouse_hid_handle, (SceHidMouseReport**)&m_reports, SCE_HID_MAX_REPORT); + if (numReports > 0) + { + for (i = 0; i <= numReports - 1; i++) + { + uint8_t buttons = m_reports[i].buttons; + + if (buttons & 0x1) + { + psp->mouse_button_left = true; + } + else + { + psp->mouse_button_left = false; + } + + if (buttons & 0x2) + { + psp->mouse_button_right = true; + } + else + { + psp->mouse_button_right = false; + } + + if (buttons & 0x4) + { + psp->mouse_button_middle = true; + } + else + { + psp->mouse_button_middle = false; + } + + mouse_velocity_x += m_reports[i].rel_x; + mouse_velocity_y += m_reports[i].rel_y; + } + } + } + psp->mouse_x_delta = mouse_velocity_x; + psp->mouse_y_delta = mouse_velocity_y; + psp->mouse_x += mouse_velocity_x; + psp->mouse_y += mouse_velocity_y; + if (psp->mouse_x < 0) + { + psp->mouse_x = 0; + } + else if (psp->mouse_x > MOUSE_MAX_X) + { + psp->mouse_x = MOUSE_MAX_X; + } + + if (psp->mouse_y < 0) + { + psp->mouse_y = 0; + } + else if (psp->mouse_y > MOUSE_MAX_Y) + { + psp->mouse_y = MOUSE_MAX_Y; + } +#endif } +#ifdef VITA +static int16_t psp_input_mouse_state(psp_input_t *psp, unsigned id, bool screen) +{ + int val = 0; + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_LEFT: + val = psp->mouse_button_left; + break; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + val = psp->mouse_button_right; + break; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + val = psp->mouse_button_middle; + break; + case RETRO_DEVICE_ID_MOUSE_X: + if (screen) + { + val = psp->mouse_x; + } + else + { + val = psp->mouse_x_delta; + psp->mouse_x_delta = 0; /* flush delta after it has been read */ + } + break; + case RETRO_DEVICE_ID_MOUSE_Y: + if (screen) + { + val = psp->mouse_y; + } + else + { + val = psp->mouse_y_delta; + psp->mouse_y_delta = 0; /* flush delta after it has been read */ + } + break; + } + + return val; +} +#endif + + static int16_t psp_input_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, @@ -81,6 +317,17 @@ static int16_t psp_input_state(void *data, if (binds[port]) return input_joypad_analog(psp->joypad, joypad_info, port, idx, id, binds[port]); break; +#ifdef VITA + case RETRO_DEVICE_KEYBOARD: + return ((id < RETROK_LAST) && psp->keyboard_state[rarch_keysym_lut[(enum retro_key)id]]); + break; + case RETRO_DEVICE_MOUSE: + return psp_input_mouse_state(psp, id, false); + break; + case RARCH_DEVICE_MOUSE_SCREEN: + return psp_input_mouse_state(psp, id, true); + break; +#endif } return 0; @@ -104,6 +351,21 @@ static void* psp_input_initialize(const char *joypad_driver) psp->joypad = input_joypad_init_driver(joypad_driver, psp); +#ifdef VITA + sceHidKeyboardEnumerate(&(psp->keyboard_hid_handle), 1); + sceHidMouseEnumerate(&(psp->mouse_hid_handle), 1); + + input_keymaps_init_keyboard_lut(rarch_key_map_vita); + unsigned int i; + for (i = 0; i <= VITA_MAX_SCANCODE; i++) { + psp->keyboard_state[i] = false; + } + for (i = 0; i < 6; i++) { + psp->prev_keys[i] = 0; + } + psp->mouse_x = 0; + psp->mouse_y = 0; +#endif return psp; } @@ -111,7 +373,13 @@ static uint64_t psp_input_get_capabilities(void *data) { (void)data; - return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); + uint64_t caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); + +#ifdef VITA + caps |= (1 << RETRO_DEVICE_KEYBOARD) | (1 << RETRO_DEVICE_MOUSE); +#endif + + return caps; } static const input_device_driver_t *psp_input_get_joypad_driver(void *data) diff --git a/input/input_keymaps.c b/input/input_keymaps.c index a92bf60256..b0ec268640 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -411,6 +411,147 @@ const struct rarch_key_map rarch_key_map_switch[] = { }; #endif +#ifdef VITA +// Vita scancodes are identical to USB 2.0 standard, e.g. SDL2 +const struct rarch_key_map rarch_key_map_vita[] = { + { 0x02A, RETROK_BACKSPACE }, + { 0x02B, RETROK_TAB }, + { 0x09C, RETROK_CLEAR }, + { 0x028, RETROK_RETURN }, + { 0x048, RETROK_PAUSE }, + { 0x029, RETROK_ESCAPE }, + { 0x02C, RETROK_SPACE }, + /*{ ?, RETROK_EXCLAIM },*/ + /*{ ?, RETROK_QUOTEDBL },*/ + /*{ ?, RETROK_HASH },*/ + /*{ ?, RETROK_DOLLAR },*/ + /*{ ?, RETROK_AMPERSAND },*/ + { 0x034, RETROK_QUOTE }, + /*{ ?, RETROK_LEFTPAREN },*/ + /*{ ?, RETROK_RIGHTPAREN },*/ + /*{ ?, RETROK_ASTERISK },*/ + /*{ ?, RETROK_PLUS },*/ + { 0x036, RETROK_COMMA }, + { 0x02D, RETROK_MINUS }, + { 0x037, RETROK_PERIOD }, + { 0x038, RETROK_SLASH }, + { 0x027, RETROK_0 }, + { 0x01E, RETROK_1 }, + { 0x01F, RETROK_2 }, + { 0x020, RETROK_3 }, + { 0x021, RETROK_4 }, + { 0x022, RETROK_5 }, + { 0x023, RETROK_6 }, + { 0x024, RETROK_7 }, + { 0x025, RETROK_8 }, + { 0x026, RETROK_9 }, + /*{ ?, RETROK_COLON },*/ + { 0x033, RETROK_SEMICOLON }, + /*{ ?, RETROK_OEM_102 },*/ + { 0x02E, RETROK_EQUALS }, + /*{ ?, RETROK_GREATER },*/ + /*{ ?, RETROK_QUESTION },*/ + /*{ ?, RETROK_AT },*/ + { 0x02F, RETROK_LEFTBRACKET }, + { 0x031, RETROK_BACKSLASH }, + { 0x030, RETROK_RIGHTBRACKET }, + /*{ ?, RETROK_CARET },*/ + /*{ ?, RETROK_UNDERSCORE },*/ + { 0x035, RETROK_BACKQUOTE }, + { 0x004, RETROK_a }, + { 0x005, RETROK_b }, + { 0x006, RETROK_c }, + { 0x007, RETROK_d }, + { 0x008, RETROK_e }, + { 0x009, RETROK_f }, + { 0x00A, RETROK_g }, + { 0x00B, RETROK_h }, + { 0x00C, RETROK_i }, + { 0x00D, RETROK_j }, + { 0x00E, RETROK_k }, + { 0x00F, RETROK_l }, + { 0x010, RETROK_m }, + { 0x011, RETROK_n }, + { 0x012, RETROK_o }, + { 0x013, RETROK_p }, + { 0x014, RETROK_q }, + { 0x015, RETROK_r }, + { 0x016, RETROK_s }, + { 0x017, RETROK_t }, + { 0x018, RETROK_u }, + { 0x019, RETROK_v }, + { 0x01A, RETROK_w }, + { 0x01B, RETROK_x }, + { 0x01C, RETROK_y }, + { 0x01D, RETROK_z }, + { 0x04C, RETROK_DELETE }, + { 0x062, RETROK_KP0 }, + { 0x059, RETROK_KP1 }, + { 0x05A, RETROK_KP2 }, + { 0x05B, RETROK_KP3 }, + { 0x05C, RETROK_KP4 }, + { 0x05D, RETROK_KP5 }, + { 0x05E, RETROK_KP6 }, + { 0x05F, RETROK_KP7 }, + { 0x060, RETROK_KP8 }, + { 0x061, RETROK_KP9 }, + { 0x063, RETROK_KP_PERIOD }, + { 0x054, RETROK_KP_DIVIDE }, + { 0x055, RETROK_KP_MULTIPLY }, + { 0x056, RETROK_KP_MINUS }, + { 0x057, RETROK_KP_PLUS }, + { 0x058, RETROK_KP_ENTER }, + { 0x067, RETROK_KP_EQUALS }, + { 0x052, RETROK_UP }, + { 0x051, RETROK_DOWN }, + { 0x04F, RETROK_RIGHT }, + { 0x050, RETROK_LEFT }, + { 0x049, RETROK_INSERT }, + { 0x04A, RETROK_HOME }, + { 0x04D, RETROK_END }, + { 0x04B, RETROK_PAGEUP }, + { 0x04E, RETROK_PAGEDOWN }, + { 0x03A, RETROK_F1 }, + { 0x03B, RETROK_F2 }, + { 0x03C, RETROK_F3 }, + { 0x03D, RETROK_F4 }, + { 0x03E, RETROK_F5 }, + { 0x03F, RETROK_F6 }, + { 0x040, RETROK_F7 }, + { 0x041, RETROK_F8 }, + { 0x042, RETROK_F9 }, + { 0x043, RETROK_F10 }, + { 0x044, RETROK_F11 }, + { 0x045, RETROK_F12 }, + { 0x068, RETROK_F13 }, + { 0x069, RETROK_F14 }, + { 0x06A, RETROK_F15 }, + { 0x053, RETROK_NUMLOCK }, + { 0x039, RETROK_CAPSLOCK }, + { 0x047, RETROK_SCROLLOCK }, + { 0x0E5, RETROK_RSHIFT }, + { 0x0E1, RETROK_LSHIFT }, + { 0x0E4, RETROK_RCTRL }, + { 0x0E0, RETROK_LCTRL }, + { 0x0E6, RETROK_RALT }, + { 0x0E2, RETROK_LALT }, + /* { ?, RETROK_RMETA }, */ + /* { ?, RETROK_LMETA }, */ + { 0x0E3, RETROK_LSUPER }, + { 0x0E7, RETROK_RSUPER }, + /* { ?, RETROK_MODE },*/ + { 0x075, RETROK_HELP }, + { 0x046, RETROK_PRINT }, + { 0x09A, RETROK_SYSREQ }, + { 0x048, RETROK_BREAK }, + { 0x076, RETROK_MENU }, + { 0x066, RETROK_POWER }, + /*{ ?, RETROK_EURO },*/ + { 0x07A, RETROK_UNDO }, + { 0, RETROK_UNKNOWN }, +}; +#endif + #if defined(HAVE_SDL) || defined(HAVE_SDL2) const struct rarch_key_map rarch_key_map_sdl[] = { { SDLK_BACKSPACE, RETROK_BACKSPACE }, diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 69fe66d6fc..fa8394ef00 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -68,6 +68,9 @@ extern const struct rarch_key_map rarch_key_map_winraw[]; #ifdef HAVE_LIBNX extern const struct rarch_key_map rarch_key_map_switch[]; #endif +#ifdef VITA +extern const struct rarch_key_map rarch_key_map_vita[]; +#endif /** * input_keymaps_init_keyboard_lut: