+static const struct {
+ short code;
+ char btype;
+ char bit;
+} in_evdev_def_binds[] =
+{
+ /* MXYZ SACB RLDU */
+ { KEY_UP, IN_BINDTYPE_PLAYER12, 0 },
+ { KEY_DOWN, IN_BINDTYPE_PLAYER12, 1 },
+ { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 },
+ { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
+ { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */
+ { KEY_KP3, IN_BINDTYPE_PLAYER12, 4 },
+ { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */
+ { KEY_KP2, IN_BINDTYPE_PLAYER12, 5 },
+ { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */
+ { KEY_KP4, IN_BINDTYPE_PLAYER12, 6 },
+ { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 },
+ { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, 7 },
+ { BTN_TL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },
+ { BTN_TR, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },
+ { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU },
+};
+
+#define DEF_BIND_COUNT (sizeof(in_evdev_def_binds) / sizeof(in_evdev_def_binds[0]))
+
+static void in_evdev_get_def_binds(int *binds)
+{
+ int i;
+
+ for (i = 0; i < DEF_BIND_COUNT; i++)
+ binds[IN_BIND_OFFS(in_evdev_def_binds[i].code, in_evdev_def_binds[i].btype)] =
+ 1 << in_evdev_def_binds[i].bit;
+}
+
+/* remove binds of missing keys, count remaining ones */
+static int in_evdev_clean_binds(void *drv_data, int *binds, int *def_binds)
+{
+ int keybits[KEY_CNT / sizeof(int)];
+ in_evdev_t *dev = drv_data;
+ int i, t, ret, offs, count = 0;
+
+ ret = ioctl(dev->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
+ if (ret == -1) {
+ perror("in_evdev: ioctl failed");
+ memset(keybits, 0xff, sizeof(keybits)); /* mark all as good */
+ }
+
+ if (dev->abs_lzone != 0) {
+ KEYBITS_BIT_SET(KEY_LEFT);
+ KEYBITS_BIT_SET(KEY_RIGHT);
+ }
+ if (dev->abs_tzone != 0) {
+ KEYBITS_BIT_SET(KEY_UP);
+ KEYBITS_BIT_SET(KEY_DOWN);
+ }
+
+ for (i = 0; i < KEY_CNT; i++) {
+ for (t = 0; t < IN_BINDTYPE_COUNT; t++) {
+ offs = IN_BIND_OFFS(i, t);
+ if (!KEYBITS_BIT(i))
+ binds[offs] = def_binds[offs] = 0;
+ if (binds[offs])
+ count++;
+ }
+ }
+
+ return count;
+}
+
+void in_evdev_init(void *vdrv)
+{
+ in_drv_t *drv = vdrv;
+
+ drv->prefix = in_evdev_prefix;
+ drv->probe = in_evdev_probe;
+ drv->free = in_evdev_free;
+ drv->get_bind_count = in_evdev_get_bind_count;
+ drv->get_def_binds = in_evdev_get_def_binds;
+ drv->clean_binds = in_evdev_clean_binds;
+ drv->set_blocking = in_evdev_set_blocking;
+ drv->update_keycode = in_evdev_update_keycode;
+ drv->menu_translate = in_evdev_menu_translate;
+ drv->get_key_code = in_evdev_get_key_code;
+ drv->get_key_name = in_evdev_get_key_name;
+}
+