static int in_probe_dev_id;
static int menu_key_state = 0;
static int menu_last_used_dev = 0;
+static int menu_key_prev = 0;
+static int menu_key_mask = 0;
+static int menu_key_repeat = 0;
#define DRV(id) in_drivers[id]
static int *in_alloc_binds(int drv_id, int key_count)
{
const struct in_default_bind *defbinds;
- int *binds;
+ int *binds, *binds_d;
int i;
binds = calloc(key_count * IN_BINDTYPE_COUNT * 2, sizeof(binds[0]));
if (binds == NULL)
return NULL;
+ binds_d = binds + key_count * IN_BINDTYPE_COUNT;
+
+ /* always have a copy of defbinds */
defbinds = DRV(drv_id).defbinds;
if (defbinds != NULL) {
for (i = 0; ; i++) {
- if (defbinds[i].bit == 0 && defbinds[i].btype == 0
+ if (defbinds[i].code == 0 && defbinds[i].btype == 0
&& defbinds[i].bit == 0)
break;
- binds[IN_BIND_OFFS(defbinds[i].code, defbinds[i].btype)] =
+
+ binds_d[IN_BIND_OFFS(defbinds[i].code, defbinds[i].btype)] |=
1 << defbinds[i].bit;
}
-
- /* always have a copy of defbinds */
- memcpy(binds + key_count * IN_BINDTYPE_COUNT, binds,
- sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT);
}
return binds;
return;
}
+ memcpy(binds, binds + key_count * IN_BINDTYPE_COUNT,
+ sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT);
+
in_devices[i].name = tmp;
in_devices[i].binds = binds;
in_devices[i].key_count = key_count;
{
int keys_old = menu_key_state;
int ret;
+ int dev_id = 0;
- while (1)
- {
- int code, is_down = 0, dev_id = 0;
+ menu_key_prev = menu_key_state;
- code = in_update_keycode(&dev_id, &is_down, charcode, timeout_ms);
- if (code < 0)
- break;
+ in_update_keycode(&dev_id, NULL, charcode, timeout_ms);
- if (keys_old != menu_key_state) {
- menu_last_used_dev = dev_id;
- break;
- }
- }
+ if (keys_old != menu_key_state)
+ menu_last_used_dev = dev_id;
ret = menu_key_state;
- menu_key_state &= ~PBTN_CHAR;
+ if (ret == 0)
+ menu_key_mask = menu_key_prev = 0;
+ else if (ret != menu_key_prev)
+ menu_key_mask = menu_key_prev;
+
return ret;
}
/* wait for menu input, do autorepeat */
int in_menu_wait(int interesting, char *charcode, int autorep_delay_ms)
{
- static int inp_prev = 0;
- static int repeats = 0;
- int ret, release = 0, wait = 450;
+ int ret, wait = 450;
- if (repeats)
+ if (menu_key_repeat)
wait = autorep_delay_ms;
- ret = in_menu_wait_any(charcode, wait);
- if (ret == inp_prev)
- repeats++;
-
- while (!(ret & interesting)) {
- ret = in_menu_wait_any(charcode, -1);
- release = 1;
- }
-
- if (release || ret != inp_prev)
- repeats = 0;
-
- inp_prev = ret;
+ /* wait until either key repeat or a new key has been pressed */
+#ifdef SDL_REDRAW_EVT
+ interesting |= PBTN_RDRAW;
+#endif
+ do {
+ ret = in_menu_wait_any(charcode, wait);
+ if (ret == 0 || ret != menu_key_prev)
+ menu_key_repeat = 0;
+ else
+ menu_key_repeat++;
+ wait = -1;
+ /* mask away all old keys if an additional new key is pressed */
+ /* XXX what if old and new keys share bits (PBTN_CHAR)? */
+ ret &= ~menu_key_mask;
+ } while (!(ret & interesting));
/* we don't need diagonals in menus */
- if ((ret & PBTN_UP) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT;
- if ((ret & PBTN_UP) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT;
- if ((ret & PBTN_DOWN) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT;
- if ((ret & PBTN_DOWN) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT;
+ if (ret & (PBTN_UP|PBTN_DOWN)) ret &= ~(PBTN_LEFT|PBTN_RIGHT);
return ret;
}
in_dev_t *dev = get_dev(dev_id);
if (dev == NULL)
return NULL;
+ if (dev->binds == NULL)
+ return NULL;
return dev->binds + dev->key_count * IN_BINDTYPE_COUNT;
}
}
}
- menu_key_state = 0;
-
/* flush events */
do {
ret = in_update_keycode(NULL, NULL, NULL, 0);
} while (ret >= 0);
+ menu_key_state = 0;
+
return 0;
}
}
if (drv_id < 0) {
- lprintf("input: missing driver for %s\n", name);
+ lprintf("input: missing driver for '%s'\n", name);
return -1;
}
for (i = 0; i < IN_MAX_DEVS; i++)
if (in_devices[i].name == NULL) break;
if (i >= IN_MAX_DEVS) {
- lprintf("input: too many devices, can't add %s\n", name);
+ lprintf("input: too many devices, can't add '%s'\n",
+ name);
return -1;
}
}
if (in_devices[i].name == NULL)
return -1;
- in_devices[i].key_names = DRV(drv_id).get_key_names(&in_devices[i].key_count);
+ in_devices[i].key_names = DRV(drv_id).get_key_names(&DRV(drv_id),
+ &in_devices[i].key_count);
in_devices[i].drv_id = drv_id;
if (i + 1 > in_dev_count)
}
if (kc < 0 || kc >= dev->key_count) {
- lprintf("input: bad key: %s\n", key);
+ lprintf("input: bad key: '%s' for device '%s'\n",
+ key, dev->name);
return -1;
}
in_dev_t *d = &in_devices[i];
if (!d->probed && d->name == NULL && d->binds == NULL)
continue;
- lprintf("%d %3d %6c %5c %s\n", i, d->drv_id, d->probed ? 'y' : 'n',
+ lprintf("%d %3d %6c %5c %s\n", i, d->drv_id,
+ d->probed ? 'y' : 'n',
d->binds ? 'y' : 'n', d->name);
+#if 0
+ if (d->binds) {
+ int kc, o, t, h;
+ for (kc = 0; kc < d->key_count; kc++) {
+ o = IN_BIND_OFFS(kc, 0);
+ for (t = h = 0; t < IN_BINDTYPE_COUNT; t++)
+ h |= d->binds[o + t];
+ if (h == 0)
+ continue;
+ lprintf(" [%3d] =", kc);
+ for (t = 0; t < IN_BINDTYPE_COUNT; t++)
+ printf(" %x", d->binds[o + t]);
+ printf("\n");
+ }
+ }
+#endif
}
}