\r
void (*mcdTrayOpen)(void);\r
void (*mcdTrayClose)(void);\r
+\r
+ unsigned int ps2; // PS/2 peripherals, e.g. Pico Keyboard\r
} PicoInterface;\r
\r
extern PicoInterface PicoIn;\r
\r
// pico.c\r
#define XPCM_BUFFER_SIZE 64\r
+enum {\r
+ KEY_RELEASED = 0,\r
+ KEY_DOWN,\r
+ KEY_UP,\r
+};\r
+enum {\r
+ SHIFT_RELEASED = 0,\r
+ SHIFT_DOWN,\r
+ SHIFT_UP_HELD_DOWN,\r
+ SHIFT_RELEASED_HELD_DOWN,\r
+ SHIFT_UP\r
+};\r
+typedef struct\r
+{\r
+ uint8_t i;\r
+ uint8_t mode;\r
+ uint8_t neg;\r
+ uint8_t has_read;\r
+ uint8_t caps_lock;\r
+ uint8_t has_caps_lock;\r
+ uint32_t mem;\r
+ uint64_t start_time_keydown;\r
+ uint64_t time_keydown;\r
+ uint8_t key_state;\r
+ uint8_t shift_state;\r
+} picohw_kb;\r
typedef struct\r
{\r
int pen_pos[2];\r
unsigned int reserved[3];\r
unsigned char xpcm_buffer[XPCM_BUFFER_SIZE+4];\r
unsigned char *xpcm_ptr;\r
+ int is_kb_active;\r
+ int inp_mode;\r
+ picohw_kb kb;\r
} picohw_state;\r
extern picohw_state PicoPicohw;\r
\r
*/
#include "../pico_int.h"
#include "../memory.h"
+#include <platform/common/input_pico.h>
+#include <sys/time.h>
/*
void dump(u16 w)
}
*/
+u64 get_ticks(void)
+{
+ struct timeval tv;
+ u64 ret;
+
+ gettimeofday(&tv, NULL);
+
+ ret = (unsigned)tv.tv_sec * 1000;
+ /* approximate /= 1000 */
+ ret += ((unsigned)tv.tv_usec * 4195) >> 22;
+
+ return ret;
+}
+
static u32 PicoRead16_pico(u32 a)
{
u32 d = 0;
case 0x06: d = PicoPicohw.pen_pos[0] & 0xff; break;
case 0x08: d = (PicoPicohw.pen_pos[1] >> 8); break;
case 0x0a: d = PicoPicohw.pen_pos[1] & 0xff; break;
- case 0x0c: d = (1 << (PicoPicohw.page & 7)) - 1; break;
+ case 0x0c: d = (1 << (PicoPicohw.page & 7)) - 1;
+ if (PicoPicohw.is_kb_active) {
+ // Apply 1 of 2 bitmasks, depending on which one preserves the highest set bit.
+ if (PicoPicohw.page % 2 == 0)
+ d &= 0x2a; // 0b00101010
+ else
+ d &= 0x15; // 0b00010101
+ }
+ break;
case 0x10: d = (PicoPicohw.fifo_bytes > 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes); break;
case 0x12: d = (PicoPicohw.fifo_bytes | !PicoPicoPCMBusyN()) ? 0 : 0x8000;
d |= PicoPicohw.r12 & 0x7fff;
elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
}
+static u32 PicoRead8_pico_kb(u32 a)
+{
+ u32 d = 0;
+ if (PicoPicohw.is_kb_active == 0) {
+ elprintf(EL_PICOHW, "kb: r @%06X %04X = %04X\n", SekPc, a, d);
+ return d;
+ }
+
+ PicoPicohw.kb.has_read = 1;
+
+ u32 key_shift = (PicoIn.ps2 & 0xff00) >> 8;
+ u32 key = (PicoIn.ps2 & 0x00ff);
+
+ // The Shift key requires 2 key up events to be registered:
+ // SHIFT_UP_HELD_DOWN to allow the game to register the key down event
+ // for the next held down key(s), and SHIFT_UP when the Shift key
+ // is no longer held down.
+ //
+ // For the second key up event, we need to
+ // override the parsed key code with PEVB_PICO_PS2_LSHIFT,
+ // otherwise it will be zero and the game won't clear its Shift key state.
+ u32 key_code = (key_shift
+ && !key
+ && PicoPicohw.kb.key_state != KEY_UP
+ && PicoPicohw.kb.shift_state != SHIFT_UP_HELD_DOWN)
+ ? key_shift
+ : PicoPicohw.kb.shift_state == SHIFT_UP ? PEVB_PICO_PS2_LSHIFT : key;
+ u32 key_code_7654 = (key_code & 0xf0) >> 4;
+ u32 key_code_3210 = (key_code & 0x0f);
+ switch(PicoPicohw.kb.i) {
+ case 0x0: d = 1; // m5id
+ break;
+ case 0x1: d = 3; // m6id
+ break;
+ case 0x2: d = 4; // data size
+ break;
+ case 0x3: d = 0; // pad1 rldu
+ break;
+ case 0x4: d = 0; // pad2 sacb
+ break;
+ case 0x5: d = 0; // pad3 rxyz
+ break;
+ case 0x6: d = 0; // l&kbtype
+ break;
+ case 0x7: // cap/num/scr
+ if (PicoPicohw.inp_mode == 3) {
+ if (key == PEVB_PICO_PS2_CAPSLOCK && PicoPicohw.kb.has_caps_lock == 1) {
+ PicoPicohw.kb.caps_lock = PicoPicohw.kb.caps_lock == 4 ? 0 : 4;
+ PicoPicohw.kb.has_caps_lock = 0;
+ }
+ d = PicoPicohw.kb.caps_lock;
+ }
+ break;
+ case 0x8:
+ d = 6;
+ if (PicoPicohw.inp_mode == 3) {
+ if (key) {
+ PicoPicohw.kb.key_state = KEY_DOWN;
+ }
+ if (!key) {
+ PicoPicohw.kb.key_state = !PicoPicohw.kb.key_state ? 0 : (PicoPicohw.kb.key_state + 1) % (KEY_UP + 1);
+ PicoPicohw.kb.start_time_keydown = 0;
+ }
+ if (key_shift && !key) {
+ if (PicoPicohw.kb.shift_state < SHIFT_RELEASED_HELD_DOWN) {
+ PicoPicohw.kb.shift_state++;
+ }
+ PicoPicohw.kb.start_time_keydown = 0;
+ }
+ if (!key_shift) {
+ PicoPicohw.kb.shift_state = !PicoPicohw.kb.shift_state ? 0 : (PicoPicohw.kb.shift_state + 1) % (SHIFT_UP + 1);
+ }
+
+ if (PicoPicohw.kb.key_state == KEY_DOWN || PicoPicohw.kb.shift_state == SHIFT_DOWN) {
+ if (PicoPicohw.kb.start_time_keydown == 0) {
+ d |= 8; // Send key down a.k.a. make
+ PicoPicohw.kb.time_keydown = 0;
+ PicoPicohw.kb.start_time_keydown = get_ticks();
+ if (PicoPicohw.kb.key_state == KEY_DOWN)
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: KEY DOWN\n");
+ else
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: SHIFT DOWN\n");
+ }
+ // Simulate key repeat while held down a.k.a. typematic
+ PicoPicohw.kb.time_keydown = get_ticks() - PicoPicohw.kb.start_time_keydown;
+ if (PicoPicohw.kb.time_keydown > 350
+ // Modifier keys don't have typematic
+ && key_code != PEVB_PICO_PS2_CAPSLOCK
+ && key_code != PEVB_PICO_PS2_LSHIFT) {
+ d |= 8; // Send key down a.k.a. make
+ if (PicoPicohw.kb.key_state == KEY_DOWN)
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: KEY DOWN\n");
+ else
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: SHIFT DOWN\n");
+ }
+ }
+ if (PicoPicohw.kb.key_state == KEY_UP
+ || PicoPicohw.kb.shift_state == SHIFT_UP_HELD_DOWN
+ || PicoPicohw.kb.shift_state == SHIFT_UP) {
+ d |= 1; // Send key up a.k.a. break
+ PicoPicohw.kb.start_time_keydown = 0;
+ if (PicoPicohw.kb.key_state == KEY_UP)
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: KEY UP\n");
+ else
+ elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: SHIFT UP\n");
+ }
+ }
+ break;
+ case 0x9: d = key_code_7654; // data 7654
+ break;
+ case 0xa: d = key_code_3210; // data 3210
+ break;
+ case 0xb: d = 0; // ?
+ break;
+ case 0xc: d = 0; // ?
+ break;
+ default:
+ d = 0;
+ break;
+ }
+
+ if (PicoPicohw.kb.neg) {
+ d |= 0xfffffff0;
+ }
+
+ elprintf(EL_PICOHW, "kb: r @%06X %04X = %04X\n", SekPc, a, d);
+ return d;
+}
+
+static u32 PicoRead16_pico_kb(u32 a)
+{
+ u32 d = PicoPicohw.kb.mem;
+
+ elprintf(EL_PICOHW, "kb: r16 @%06X %04X = %04X\n", SekPc, a, d);
+ return d;
+}
+
+static void PicoWrite8_pico_kb(u32 a, u32 d)
+{
+ elprintf(EL_PICOHW, "kb: w @%06X %04X = %04X\n", SekPc, a, d);
+
+ switch(d) {
+ case 0x0:
+ PicoPicohw.kb.neg = 0;
+ PicoPicohw.kb.i++;
+ break;
+ case 0x20:
+ PicoPicohw.kb.neg = 1;
+ if (PicoPicohw.kb.has_read == 1) {
+ PicoPicohw.kb.i++;
+ }
+ break;
+ case 0x40:
+ break;
+ case 0x60:
+ PicoPicohw.kb.mode = !PicoPicohw.kb.mode;
+ PicoPicohw.kb.i = 0;
+ PicoPicohw.kb.has_read = 0;
+ break;
+ default:
+ break;
+ }
+
+ PicoPicohw.kb.mem = (PicoPicohw.kb.mem & 0xff00) | d;
+}
+
+static void PicoWrite16_pico_kb(u32 a, u32 d)
+{
+ elprintf(EL_PICOHW, "kb: w16 @%06X %04X = %04X\n", SekPc, a, d);
+
+ PicoPicohw.kb.mem = d;
+}
PICO_INTERNAL void PicoMemSetupPico(void)
{
cpu68k_map_set(m68k_read16_map, 0x800000, 0x80ffff, PicoRead16_pico, 1);
cpu68k_map_set(m68k_write8_map, 0x800000, 0x80ffff, PicoWrite8_pico, 1);
cpu68k_map_set(m68k_write16_map, 0x800000, 0x80ffff, PicoWrite16_pico, 1);
-}
+ m68k_map_unmap(0x200000, 0x20ffff);
+
+ // map Pico PS/2 Peripheral I/O
+ cpu68k_map_set(m68k_read8_map, 0x200000, 0x20ffff, PicoRead8_pico_kb, 1);
+ cpu68k_map_set(m68k_read16_map, 0x200000, 0x20ffff, PicoRead16_pico_kb, 1);
+ cpu68k_map_set(m68k_write8_map, 0x200000, 0x20ffff, PicoWrite8_pico_kb, 1);
+ cpu68k_map_set(m68k_write16_map, 0x200000, 0x20ffff, PicoWrite16_pico_kb, 1);
+}
}\r
if (events & PEV_PICO_PAD) {\r
if (pico_inp_mode == 2) {\r
+ pico_inp_mode = (PicoPicohw.is_kb_active ? 3 : 0);\r
+ emu_status_msg("Input: %s", pico_inp_mode ? "Keyboard" : "D-Pad");\r
+ } else if (pico_inp_mode == 3) {\r
pico_inp_mode = 0;\r
emu_status_msg("Input: D-Pad");\r
} else {\r
pico_inp_mode = 0;\r
emu_status_msg("Input: D-Pad");\r
}\r
- if (pico_inp_mode == 0)\r
+ if (events & PEV_PICO_SWPS2) {\r
+ PicoPicohw.is_kb_active = !PicoPicohw.is_kb_active;\r
+ if (pico_inp_mode == 3) pico_inp_mode = 0;\r
+ emu_status_msg("Keyboard %sconnected", PicoPicohw.is_kb_active ? "" : "dis");\r
+ }\r
+\r
+ PicoPicohw.inp_mode = pico_inp_mode;\r
+\r
+ if (pico_inp_mode == 0 || pico_inp_mode == 3)\r
return;\r
\r
/* handle other input modes */\r
{\r
static int prev_events = 0;\r
int actions[IN_BINDTYPE_COUNT] = { 0, };\r
+ int actions_pico_ps2[IN_BIND_LAST] = { 0, };\r
int pl_actions[4];\r
int events;\r
\r
in_update(actions);\r
+ in_update_pico_ps2(actions_pico_ps2);\r
+ PicoIn.ps2 = 0;\r
+ for (int i = 0; i < IN_BIND_LAST; i++) {\r
+ if (actions_pico_ps2[i]) {\r
+ unsigned int action = actions_pico_ps2[i];\r
+ if ((action & 0xff) == PEVB_PICO_PS2_LSHIFT) {\r
+ PicoIn.ps2 = (PicoIn.ps2 & 0x00ff) | (action << 8);\r
+ } else {\r
+ PicoIn.ps2 = (PicoIn.ps2 & 0xff00) | action;\r
+ }\r
+ }\r
+ }\r
\r
pl_actions[0] = actions[IN_BINDTYPE_PLAYER12];\r
pl_actions[1] = actions[IN_BINDTYPE_PLAYER12] >> 16;\r
pl_actions[2] = actions[IN_BINDTYPE_PLAYER34];\r
pl_actions[3] = actions[IN_BINDTYPE_PLAYER34] >> 16;\r
\r
- PicoIn.pad[0] = pl_actions[0] & 0xfff;\r
- PicoIn.pad[1] = pl_actions[1] & 0xfff;\r
- PicoIn.pad[2] = pl_actions[2] & 0xfff;\r
- PicoIn.pad[3] = pl_actions[3] & 0xfff;\r
-\r
- if (pl_actions[0] & 0x7000)\r
- do_turbo(&PicoIn.pad[0], pl_actions[0]);\r
- if (pl_actions[1] & 0x7000)\r
- do_turbo(&PicoIn.pad[1], pl_actions[1]);\r
- if (pl_actions[2] & 0x7000)\r
- do_turbo(&PicoIn.pad[2], pl_actions[2]);\r
- if (pl_actions[3] & 0x7000)\r
- do_turbo(&PicoIn.pad[3], pl_actions[3]);\r
-\r
events = actions[IN_BINDTYPE_EMU] & PEV_MASK;\r
\r
+ if (pico_inp_mode == 3) {\r
+ // FIXME: Only passthrough joystick input to avoid collisions\r
+ // with PS/2 bindings. Ideally we should check if the device this\r
+ // input originated from is the same as the device used for\r
+ // PS/2 input, and passthrough if they are different devices.\r
+ PicoIn.pad[0] = pl_actions[0] & 0xf;\r
+ PicoIn.pad[1] = pl_actions[1] & 0xf;\r
+ PicoIn.pad[2] = pl_actions[2] & 0xf;\r
+ PicoIn.pad[3] = pl_actions[3] & 0xf;\r
+\r
+ // Ignore events mapped to bindings that collide with PS/2 peripherals.\r
+ // Note that calls to emu_set_fastforward() should be avoided as well,\r
+ // since fast-forward activates even with parameter set_on = 0.\r
+ events &= ~PEV_MENU;\r
+ } else {\r
+ PicoIn.pad[0] = pl_actions[0] & 0xfff;\r
+ PicoIn.pad[1] = pl_actions[1] & 0xfff;\r
+ PicoIn.pad[2] = pl_actions[2] & 0xfff;\r
+ PicoIn.pad[3] = pl_actions[3] & 0xfff;\r
+\r
+ if (pl_actions[0] & 0x7000)\r
+ do_turbo(&PicoIn.pad[0], pl_actions[0]);\r
+ if (pl_actions[1] & 0x7000)\r
+ do_turbo(&PicoIn.pad[1], pl_actions[1]);\r
+ if (pl_actions[2] & 0x7000)\r
+ do_turbo(&PicoIn.pad[2], pl_actions[2]);\r
+ if (pl_actions[3] & 0x7000)\r
+ do_turbo(&PicoIn.pad[3], pl_actions[3]);\r
+\r
+ if ((events ^ prev_events) & PEV_FF) {\r
+ emu_set_fastforward(events & PEV_FF);\r
+ plat_update_volume(0, 0);\r
+ reset_timing = 1;\r
+ }\r
+ }\r
+\r
// volume is treated in special way and triggered every frame\r
if (events & (PEV_VOL_DOWN|PEV_VOL_UP))\r
plat_update_volume(1, events & PEV_VOL_UP);\r
\r
- if ((events ^ prev_events) & PEV_FF) {\r
- emu_set_fastforward(events & PEV_FF);\r
- plat_update_volume(0, 0);\r
- reset_timing = 1;\r
- }\r
-\r
events &= ~prev_events;\r
\r
if (PicoIn.AHW == PAHW_PICO)\r
#define PEVB_PICO_STORY 19
#define PEVB_PICO_PAD 18
#define PEVB_PICO_PENST 17
-#define PEVB_RESET 16
+#define PEVB_PICO_SWPS2 16
+#define PEVB_RESET 15
#define PEV_VOL_DOWN (1 << PEVB_VOL_DOWN)
#define PEV_VOL_UP (1 << PEVB_VOL_UP)
#define PEV_PICO_STORY (1 << PEVB_PICO_STORY)
#define PEV_PICO_PAD (1 << PEVB_PICO_PAD)
#define PEV_PICO_PENST (1 << PEVB_PICO_PENST)
+#define PEV_PICO_SWPS2 (1 << PEVB_PICO_SWPS2)
#define PEV_RESET (1 << PEVB_RESET)
-#define PEV_MASK 0x7fff0000
+#define PEV_MASK 0x7fff8000
+
+/* Keyboard Pico */
+
+// Blue buttons
+#define PEVB_PICO_PS2_SPACE 0x29
+#define PEVB_PICO_PS2_EXCLAIM 0
+#define PEVB_PICO_PS2_QUOTEDBL 0
+#define PEVB_PICO_PS2_HASH 0
+#define PEVB_PICO_PS2_DOLLAR 0
+#define PEVB_PICO_PS2_AMPERSAND 0
+#define PEVB_PICO_PS2_LEFTPAREN 0
+#define PEVB_PICO_PS2_RIGHTPAREN 0
+#define PEVB_PICO_PS2_ASTERISK 0x7c
+#define PEVB_PICO_PS2_PLUS 0x79
+#define PEVB_PICO_PS2_MINUS 0x4e
+#define PEVB_PICO_PS2_COMMA 0x41
+#define PEVB_PICO_PS2_PERIOD 0x49
+#define PEVB_PICO_PS2_SLASH 0x4a
+#define PEVB_PICO_PS2_1 0x16
+#define PEVB_PICO_PS2_2 0x1e
+#define PEVB_PICO_PS2_3 0x26
+#define PEVB_PICO_PS2_4 0x25
+#define PEVB_PICO_PS2_5 0x2e
+#define PEVB_PICO_PS2_6 0x36
+#define PEVB_PICO_PS2_7 0x3d
+#define PEVB_PICO_PS2_8 0x3e
+#define PEVB_PICO_PS2_9 0x46
+#define PEVB_PICO_PS2_0 0x45
+#define PEVB_PICO_PS2_COLON 0x52
+#define PEVB_PICO_PS2_SEMICOLON 0x4c
+#define PEVB_PICO_PS2_LESS 0
+#define PEVB_PICO_PS2_EQUALS 0x55
+#define PEVB_PICO_PS2_GREATER 0
+#define PEVB_PICO_PS2_QUESTION 0
+#define PEVB_PICO_PS2_AT 0
+#define PEVB_PICO_PS2_DAKUTEN 0x54 // ゛
+#define PEVB_PICO_PS2_LEFTBRACKET 0x5b
+#define PEVB_PICO_PS2_RIGHTBRACKET 0x5d
+#define PEVB_PICO_PS2_CARET 0
+#define PEVB_PICO_PS2_UNDERSCORE 0
+#define PEVB_PICO_PS2_YEN 0x6a // ¥
+#define PEVB_PICO_PS2_RO 0x51 // ろ
+#define PEVB_PICO_PS2_KE 0x52 // け
+
+#define PEVB_PICO_PS2_a 0x1c
+#define PEVB_PICO_PS2_b 0x32
+#define PEVB_PICO_PS2_c 0x21
+#define PEVB_PICO_PS2_d 0x23
+#define PEVB_PICO_PS2_e 0x24
+#define PEVB_PICO_PS2_f 0x2b
+#define PEVB_PICO_PS2_g 0x34
+#define PEVB_PICO_PS2_h 0x33
+#define PEVB_PICO_PS2_i 0x43
+#define PEVB_PICO_PS2_j 0x3b
+#define PEVB_PICO_PS2_k 0x42
+#define PEVB_PICO_PS2_l 0x4b
+#define PEVB_PICO_PS2_m 0x3a
+#define PEVB_PICO_PS2_n 0x31
+#define PEVB_PICO_PS2_o 0x44
+#define PEVB_PICO_PS2_p 0x4d
+#define PEVB_PICO_PS2_q 0x15
+#define PEVB_PICO_PS2_r 0x2d
+#define PEVB_PICO_PS2_s 0x1b
+#define PEVB_PICO_PS2_t 0x2c
+#define PEVB_PICO_PS2_u 0x3c
+#define PEVB_PICO_PS2_v 0x2a
+#define PEVB_PICO_PS2_w 0x1d
+#define PEVB_PICO_PS2_x 0x22
+#define PEVB_PICO_PS2_y 0x35
+#define PEVB_PICO_PS2_z 0x1a
+
+// Green button on top-left
+#define PEVB_PICO_PS2_ESCAPE 0x76
+
+// Orange buttons on left
+#define PEVB_PICO_PS2_CAPSLOCK 0x58
+#define PEVB_PICO_PS2_LSHIFT 0x12
+
+// Green buttons on right
+#define PEVB_PICO_PS2_BACKSPACE 0x66
+#define PEVB_PICO_PS2_INSERT 0x81
+#define PEVB_PICO_PS2_DELETE 0x85
+
+// Red button on bottom-right
+#define PEVB_PICO_PS2_RETURN 0x5a
+
+// Orange buttons on bottom
+#define PEVB_PICO_PS2_SOUND 0x67
+#define PEVB_PICO_PS2_HOME 0x64
+#define PEVB_PICO_PS2_CJK 0x13
+#define PEVB_PICO_PS2_ROMAJI 0x17
#endif /* INCLUDE_c48097f3ff2a6a9af1cce8fd7a9b3f0c */
{ SDLK_F8, IN_BINDTYPE_EMU, PEVB_PICO_STORY },
{ SDLK_F9, IN_BINDTYPE_EMU, PEVB_PICO_PAD },
{ SDLK_F10, IN_BINDTYPE_EMU, PEVB_PICO_PENST },
+ { SDLK_F12, IN_BINDTYPE_EMU, PEVB_PICO_SWPS2 },
{ SDLK_BACKSPACE, IN_BINDTYPE_EMU, PEVB_FF },
+
+ { 0, 0, 0 }
+};
+
+const struct in_default_bind in_sdl_pico_ps2_map[] = {
+ // Blue buttons
+ { SDLK_SPACE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_SPACE },
+ { SDLK_EXCLAIM, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_EXCLAIM },
+ { SDLK_QUOTEDBL, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_QUOTEDBL },
+ { SDLK_HASH, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_HASH },
+ { SDLK_DOLLAR, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_DOLLAR },
+ { SDLK_AMPERSAND, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_AMPERSAND },
+ { SDLK_LEFTPAREN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_LEFTPAREN },
+ { SDLK_RIGHTPAREN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_RIGHTPAREN },
+ { SDLK_ASTERISK, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_ASTERISK },
+ { SDLK_PLUS, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_PLUS },
+ { SDLK_COMMA, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_COMMA },
+ { SDLK_MINUS, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_MINUS },
+ { SDLK_PERIOD, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_PERIOD },
+ { SDLK_SLASH, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_SLASH },
+ { SDLK_0, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_0 },
+ { SDLK_1, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_1 },
+ { SDLK_2, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_2 },
+ { SDLK_3, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_3 },
+ { SDLK_4, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_4 },
+ { SDLK_5, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_5 },
+ { SDLK_6, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_6 },
+ { SDLK_7, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_7 },
+ { SDLK_8, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_8 },
+ { SDLK_9, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_9 },
+ { SDLK_COLON, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_COLON },
+ { SDLK_SEMICOLON, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_SEMICOLON },
+ { SDLK_LESS, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_LESS },
+ { SDLK_EQUALS, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_EQUALS },
+ { SDLK_GREATER, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_GREATER },
+ { SDLK_QUESTION, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_QUESTION },
+ { SDLK_AT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_AT },
+ { SDLK_BACKSLASH, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_DAKUTEN },
+ { SDLK_LEFTBRACKET, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_LEFTBRACKET },
+ { SDLK_RIGHTBRACKET, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_RIGHTBRACKET },
+ { SDLK_CARET, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_CARET },
+ { SDLK_UNDERSCORE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_UNDERSCORE },
+ { SDLK_BACKQUOTE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_YEN },
+ { SDLK_a, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_a },
+ { SDLK_b, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_b },
+ { SDLK_c, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_c },
+ { SDLK_d, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_d },
+ { SDLK_e, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_e },
+ { SDLK_f, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_f },
+ { SDLK_g, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_g },
+ { SDLK_h, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_h },
+ { SDLK_i, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_i },
+ { SDLK_j, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_j },
+ { SDLK_k, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_k },
+ { SDLK_l, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_l },
+ { SDLK_m, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_m },
+ { SDLK_n, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_n },
+ { SDLK_o, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_o },
+ { SDLK_p, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_p },
+ { SDLK_q, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_q },
+ { SDLK_r, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_r },
+ { SDLK_s, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_s },
+ { SDLK_t, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_t },
+ { SDLK_u, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_u },
+ { SDLK_v, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_v },
+ { SDLK_w, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_w },
+ { SDLK_x, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_x },
+ { SDLK_y, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_y },
+ { SDLK_z, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_z },
+ { SDLK_QUOTE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_KE },
+ { SDLK_RSHIFT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_RO },
+
+ // Green button on top-left
+ { SDLK_ESCAPE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_ESCAPE },
+
+ // Orange buttons on left
+ { SDLK_LCTRL, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_CAPSLOCK }, // Also switches english input
+ { SDLK_LSHIFT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_LSHIFT },
+
+ // Green buttons on right
+ { SDLK_BACKSPACE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_BACKSPACE },
+ { SDLK_INSERT, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_INSERT },
+ { SDLK_DELETE, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_DELETE },
+
+ // Red button on bottom-right
+ { SDLK_RETURN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_RETURN },
+
+ // Orange buttons on bottom
+ { SDLK_END, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_SOUND },
+ { SDLK_HOME, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_HOME },
+ { SDLK_PAGEUP, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_CJK }, // CJK Scripts: Hiragana / Katakana / Kanji (Keyboard Pico); Hangul (Kibodeu Piko)
+ { SDLK_PAGEDOWN, IN_BINDTYPE_PICO_PS2, PEVB_PICO_PS2_ROMAJI }, // English Script
+
{ 0, 0, 0 }
};
const struct in_default_bind *in_sdl_defbinds = _in_sdl_defbinds;
{ "Pico Storyware ", PEV_PICO_STORY },
{ "Pico Pad ", PEV_PICO_PAD },
{ "Pico Pen state ", PEV_PICO_PENST },
+ { "Pico Keyboard ", PEV_PICO_SWPS2 },
{ NULL, 0 }
};
in_sdl_platform_data.jmap_size = in_sdl_joy_map_sz,
in_sdl_platform_data.joy_map = in_sdl_joy_map,
in_sdl_platform_data.key_names = in_sdl_key_names,
+ in_sdl_platform_data.pico_ps2_map = in_sdl_pico_ps2_map,
in_sdl_init(&in_sdl_platform_data, plat_sdl_event_handler);
in_probe();
extern const int in_sdl_joy_map_sz;
extern const char * const *in_sdl_key_names;
extern const char *plat_device;
+extern const struct in_default_bind in_sdl_pico_ps2_map[];
void linux_menu_init(void);
-Subproject commit 86a086ed64aadc1e87fc58a90703a07d91c9cdbe
+Subproject commit b047d2e2e6375b5fad2f1b716616a536f7b56dc2