From: notaz Date: Sat, 25 Jul 2009 17:14:06 +0000 (+0000) Subject: input: get rid of pl2 flag, use 'bind types' instead X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=commitdiff_plain;h=8e77275edade55d89b0723a60ab4ef1e2ec288de input: get rid of pl2 flag, use 'bind types' instead git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@713 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/common/config.c b/common/config.c index 4f80c86..e47a401 100644 --- a/common/config.c +++ b/common/config.c @@ -107,40 +107,53 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def) static void keys_write(FILE *fn, const char *bind_str, int dev_id, const int *binds, int no_defaults) { char act[48]; - int key_count, t, i; + int key_count, k, i; const int *def_binds; key_count = in_get_dev_info(dev_id, IN_INFO_BIND_COUNT); def_binds = in_get_dev_def_binds(dev_id); - for (t = 0; t < key_count; t++) + for (k = 0; k < key_count; k++) { const char *name; + int t, mask; act[0] = act[31] = 0; - if (no_defaults && binds[t] == def_binds[t]) - continue; + for (t = 0; t < IN_BINDTYPE_COUNT; t++) + if (binds[IN_BIND_OFFS(k, t)] != def_binds[IN_BIND_OFFS(k, t)]) + break; - name = in_get_key_name(dev_id, t); -#ifdef __GP2X__ - if (strcmp(name, "SELECT") == 0) continue; -#endif + if (no_defaults && t == IN_BINDTYPE_COUNT) + continue; /* no change from defaults */ + + name = in_get_key_name(dev_id, k); - if (binds[t] == 0 && def_binds[t] != 0) { + for (t = 0; t < IN_BINDTYPE_COUNT; t++) + if (binds[IN_BIND_OFFS(k, t)] != 0 || def_binds[IN_BIND_OFFS(k, t)] == 0) + break; + + if (t == IN_BINDTYPE_COUNT) { + /* key has default bind removed */ fprintf(fn, "%s %s =" NL, bind_str, name); continue; } for (i = 0; i < sizeof(me_ctrl_actions) / sizeof(me_ctrl_actions[0]); i++) { - if (me_ctrl_actions[i].mask & binds[t]) { + mask = me_ctrl_actions[i].mask; + if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) { + strncpy(act, me_ctrl_actions[i].name, 31); + fprintf(fn, "%s %s = player1 %s" NL, bind_str, name, mystrip(act)); + } + mask = me_ctrl_actions[i].mask << 16; + if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) { strncpy(act, me_ctrl_actions[i].name, 31); - fprintf(fn, "%s %s = player%i %s" NL, bind_str, name, - ((binds[t]>>16)&1)+1, mystrip(act)); + fprintf(fn, "%s %s = player2 %s" NL, bind_str, name, mystrip(act)); } } for (i = 0; emuctrl_actions[i].name != NULL; i++) { - if (emuctrl_actions[i].mask & binds[t]) { + mask = emuctrl_actions[i].mask; + if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]) { strncpy(act, emuctrl_actions[i].name, 31); fprintf(fn, "%s %s = %s" NL, bind_str, name, mystrip(act)); } @@ -613,28 +626,35 @@ static int custom_read(menu_entry *me, const char *var, const char *val) static unsigned int keys_encountered = 0; -static int parse_bind_val(const char *val) +static int parse_bind_val(const char *val, int *type) { int i; + *type = IN_BINDTYPE_NONE; if (val[0] == 0) return 0; if (strncasecmp(val, "player", 6) == 0) { - unsigned int player; + int player, shift = 0; player = atoi(val + 6) - 1; + if (player > 1) return -1; + if (player == 1) + shift = 16; + *type = IN_BINDTYPE_PLAYER12; for (i = 0; i < sizeof(me_ctrl_actions) / sizeof(me_ctrl_actions[0]); i++) { if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0) - return me_ctrl_actions[i].mask | (player<<16); + return me_ctrl_actions[i].mask << shift; } } for (i = 0; emuctrl_actions[i].name != NULL; i++) { - if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) + if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) { + *type = IN_BINDTYPE_EMU; return emuctrl_actions[i].mask; + } } return -1; @@ -642,15 +662,15 @@ static int parse_bind_val(const char *val) static void keys_parse(const char *key, const char *val, int dev_id) { - int binds; + int acts, type; - binds = parse_bind_val(val); - if (binds == -1) { + acts = parse_bind_val(val, &type); + if (acts == -1) { lprintf("config: unhandled action \"%s\"\n", val); return; } - in_config_bind_key(dev_id, key, binds); + in_config_bind_key(dev_id, key, acts, type); } static int get_numvar_num(const char *var) diff --git a/common/emu.c b/common/emu.c index 141356a..c5686fd 100644 --- a/common/emu.c +++ b/common/emu.c @@ -1099,31 +1099,37 @@ static void run_events_ui(unsigned int which) void emu_update_input(void) { - unsigned int allActions[2] = { 0, 0 }, events; - static unsigned int prevEvents = 0; + static int prev_events = 0; + int actions[IN_BINDTYPE_COUNT] = { 0, }; + int pl_actions[2]; + int events; - /* FIXME: player2 */ - allActions[0] = in_update(); + in_update(actions); - PicoPad[0] = allActions[0] & 0xfff; - PicoPad[1] = allActions[1] & 0xfff; + pl_actions[0] = actions[IN_BINDTYPE_PLAYER12]; + pl_actions[1] = actions[IN_BINDTYPE_PLAYER12] >> 16; - if (allActions[0] & 0x7000) do_turbo(&PicoPad[0], allActions[0]); - if (allActions[1] & 0x7000) do_turbo(&PicoPad[1], allActions[1]); + PicoPad[0] = pl_actions[0] & 0xfff; + PicoPad[1] = pl_actions[1] & 0xfff; - events = (allActions[0] | allActions[1]) & PEV_MASK; + if (pl_actions[0] & 0x7000) + do_turbo(&PicoPad[0], pl_actions[0]); + if (pl_actions[1] & 0x7000) + do_turbo(&PicoPad[1], pl_actions[1]); + + events = actions[IN_BINDTYPE_EMU] & PEV_MASK; // volume is treated in special way and triggered every frame if (events & (PEV_VOL_DOWN|PEV_VOL_UP)) plat_update_volume(1, events & PEV_VOL_UP); - if ((events ^ prevEvents) & PEV_FF) { + if ((events ^ prev_events) & PEV_FF) { emu_set_fastforward(events & PEV_FF); plat_update_volume(0, 0); reset_timing = 1; } - events &= ~prevEvents; + events &= ~prev_events; if (PicoAHW == PAHW_PICO) run_events_pico(events); @@ -1132,7 +1138,7 @@ void emu_update_input(void) if (movie_data) update_movie(); - prevEvents = (allActions[0] | allActions[1]) & PEV_MASK; + prev_events = actions[IN_BINDTYPE_EMU] & PEV_MASK; } static void mkdir_path(char *path_with_reserve, int pos, const char *name) diff --git a/common/input.c b/common/input.c index 920d11d..f26e125 100644 --- a/common/input.c +++ b/common/input.c @@ -13,7 +13,8 @@ typedef struct int drv_fd_hnd; void *drv_data; char *name; - int *binds; + int key_count; + int *binds; /* total = key_count * bindtypes * 2 */ int probed:1; int does_combos:1; } in_dev_t; @@ -28,29 +29,17 @@ static int menu_last_used_dev = 0; #define DRV(id) in_drivers[(unsigned)(id) < IN_DRVID_COUNT ? (id) : 0] -static int in_bind_count(int drv_id) -{ - int count = DRV(drv_id).get_bind_count(); - if (count <= 0) - printf("input: failed to get bind count for drv %d\n", drv_id); - - return count; -} - -static int *in_alloc_binds(int drv_id) +static int *in_alloc_binds(int drv_id, int key_count) { - int count, *binds; - - count = in_bind_count(drv_id); - if (count <= 0) - return NULL; + int *binds; - binds = calloc(count * 2, sizeof(binds[0])); + binds = calloc(key_count * IN_BINDTYPE_COUNT * 2, sizeof(binds[0])); if (binds == NULL) return NULL; - DRV(drv_id).get_def_binds(binds + count); - memcpy(binds, binds + count, count * sizeof(binds[0])); + DRV(drv_id).get_def_binds(binds + key_count * IN_BINDTYPE_COUNT); + memcpy(binds, binds + key_count * IN_BINDTYPE_COUNT, + sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT); return binds; } @@ -69,7 +58,8 @@ static void in_free(in_dev_t *dev) /* to be called by drivers * async devices must set drv_fd_hnd to -1 */ -void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, int combos) +void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, + int key_count, int combos) { int i, ret, dupe_count = 0, *binds; char name[256], *name_end, *tmp; @@ -109,7 +99,7 @@ void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, if (tmp == NULL) return; - binds = in_alloc_binds(drv_id); + binds = in_alloc_binds(drv_id, key_count); if (binds == NULL) { free(tmp); return; @@ -117,6 +107,7 @@ void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, in_devices[i].name = tmp; in_devices[i].binds = binds; + in_devices[i].key_count = key_count; if (i + 1 > in_dev_count) in_dev_count = i + 1; @@ -129,7 +120,8 @@ update: in_devices[i].drv_data = drv_data; if (in_devices[i].binds != NULL) { - ret = DRV(drv_id).clean_binds(drv_data, in_devices[i].binds); + ret = DRV(drv_id).clean_binds(drv_data, in_devices[i].binds, + in_devices[i].binds + key_count * IN_BINDTYPE_COUNT); if (ret == 0) { /* no useable binds */ free(in_devices[i].binds); @@ -138,8 +130,9 @@ update: } } -/* key combo handling, to be called by drivers that support it */ -void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts) +/* key combo handling, to be called by drivers that support it. + * Only care about IN_BINDTYPE_EMU */ +void in_combos_find(const int *binds, int last_key, int *combo_keys, int *combo_acts) { int act, u; @@ -148,7 +141,7 @@ void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts) { int keyc = 0; for (u = 0; u <= last_key; u++) - if (binds[u] & (1 << act)) + if (binds[IN_BIND_OFFS(u, IN_BINDTYPE_EMU)] & (1 << act)) keyc++; if (keyc > 1) @@ -156,7 +149,7 @@ void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts) // loop again and mark those keys and actions as combo for (u = 0; u <= last_key; u++) { - if (binds[u] & (1 << act)) { + if (binds[IN_BIND_OFFS(u, IN_BINDTYPE_EMU)] & (1 << act)) { *combo_keys |= 1 << u; *combo_acts |= 1 << act; } @@ -165,38 +158,40 @@ void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts) } } -int in_combos_do(int keys, int *binds, int last_key, int combo_keys, int combo_acts) +int in_combos_do(int keys, const int *binds, int last_key, int combo_keys, int combo_acts) { int i, ret = 0; for (i = 0; i <= last_key; i++) { - int acts; + int acts, acts_c, u; + if (!(keys & (1 << i))) continue; - acts = binds[i]; + acts = binds[IN_BIND_OFFS(i, IN_BINDTYPE_EMU)]; if (!acts) continue; - if (combo_keys & (1 << i)) - { - int acts_c = acts & combo_acts; - int u = last_key; - if (acts_c) { - // let's try to find the other one - for (u = i + 1; u <= last_key; u++) - if ( (keys & (1 << u)) && (binds[u] & acts_c) ) { - ret |= acts_c & binds[u]; - keys &= ~((1 << i) | (1 << u)); - break; - } - } - // add non-combo actions if combo ones were not found - if (u >= last_key) - ret |= acts & ~combo_acts; - } else + if (!(combo_keys & (1 << i))) { ret |= acts; + continue; + } + + acts_c = acts & combo_acts; + u = last_key; + if (acts_c) { + // let's try to find the other one + for (u = i + 1; u <= last_key; u++) + if ( (keys & (1 << u)) && (binds[IN_BIND_OFFS(u, IN_BINDTYPE_EMU)] & acts_c) ) { + ret |= acts_c & binds[IN_BIND_OFFS(u, IN_BINDTYPE_EMU)]; + keys &= ~((1 << i) | (1 << u)); + break; + } + } + // add non-combo actions if combo ones were not found + if (u >= last_key) + ret |= acts & ~combo_acts; } return ret; @@ -235,9 +230,9 @@ void in_probe(void) } /* async update */ -int in_update(void) +int in_update(int *result) { - int i, result = 0; + int i, ret = 0; for (i = 0; i < in_dev_count; i++) { in_dev_t *dev = &in_devices[i]; @@ -245,19 +240,19 @@ int in_update(void) switch (dev->drv_id) { #ifdef IN_EVDEV case IN_DRVID_EVDEV: - result |= in_evdev_update(dev->drv_data, dev->binds); + ret |= in_evdev_update(dev->drv_data, dev->binds, result); break; #endif #ifdef IN_GP2X case IN_DRVID_GP2X: - result |= in_gp2x_update(dev->drv_data, dev->binds); + ret |= in_gp2x_update(dev->drv_data, dev->binds, result); break; #endif } } } - return result; + return ret; } void in_set_blocking(int is_blocking) @@ -464,13 +459,10 @@ const int *in_get_dev_binds(int dev_id) const int *in_get_dev_def_binds(int dev_id) { - int count; - if (dev_id < 0 || dev_id >= IN_MAX_DEVS) return NULL; - count = in_bind_count(in_devices[dev_id].drv_id); - return in_devices[dev_id].binds + count; + return in_devices[dev_id].binds + in_devices[dev_id].key_count * IN_BINDTYPE_COUNT; } int in_get_dev_info(int dev_id, int what) @@ -480,7 +472,7 @@ int in_get_dev_info(int dev_id, int what) switch (what) { case IN_INFO_BIND_COUNT: - return in_bind_count(in_devices[dev_id].drv_id); + return in_devices[dev_id].key_count; case IN_INFO_DOES_COMBOS: return in_devices[dev_id].does_combos; } @@ -538,33 +530,35 @@ const char *in_get_key_name(int dev_id, int keycode) return xname; } -int in_bind_key(int dev_id, int keycode, int mask, int force_unbind) +int in_bind_key(int dev_id, int keycode, int bind_type, int mask, int force_unbind) { int ret, count; in_dev_t *dev; - if (dev_id < 0 || dev_id >= IN_MAX_DEVS) + if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT) return -1; + dev = &in_devices[dev_id]; + count = dev->key_count; if (dev->binds == NULL) { if (force_unbind) return 0; - dev->binds = in_alloc_binds(dev->drv_id); + dev->binds = in_alloc_binds(dev->drv_id, count); if (dev->binds == NULL) return -1; } - count = in_bind_count(dev->drv_id); if (keycode < 0 || keycode >= count) return -1; if (force_unbind) - dev->binds[keycode] &= ~mask; + dev->binds[IN_BIND_OFFS(keycode, bind_type)] &= ~mask; else - dev->binds[keycode] ^= mask; + dev->binds[IN_BIND_OFFS(keycode, bind_type)] ^= mask; - ret = DRV(dev->drv_id).clean_binds(dev->drv_data, dev->binds); + ret = DRV(dev->drv_id).clean_binds(dev->drv_data, dev->binds, + dev->binds + count * IN_BINDTYPE_COUNT); if (ret == 0) { free(dev->binds); dev->binds = NULL; @@ -616,9 +610,11 @@ int in_config_parse_dev(const char *name) if (in_devices[i].name == NULL) return -1; + in_devices[i].key_count = DRV(drv_id).get_bind_count(); + in_devices[i].drv_id = drv_id; + if (i + 1 > in_dev_count) in_dev_count = i + 1; - in_devices[i].drv_id = drv_id; return i; } @@ -640,26 +636,24 @@ void in_config_start(void) if (binds == NULL) continue; - count = in_bind_count(in_devices[i].drv_id); - def_binds = binds + count; + count = in_devices[i].key_count; + def_binds = binds + count * IN_BINDTYPE_COUNT; - for (n = 0; n < count; n++) + for (n = 0; n < count * IN_BINDTYPE_COUNT; n++) if (binds[n] == def_binds[n]) binds[n] = -1; } } -int in_config_bind_key(int dev_id, const char *key, int binds) +int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) { - int count, kc; in_dev_t *dev; + int i, offs, kc; - if (dev_id < 0 || dev_id >= IN_MAX_DEVS) + if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT) return -1; dev = &in_devices[dev_id]; - count = in_bind_count(dev->drv_id); - /* maybe a raw code? */ if (key[0] == '\\' && key[1] == 'x') { char *p = NULL; @@ -670,7 +664,7 @@ int in_config_bind_key(int dev_id, const char *key, int binds) else { /* device specific key name */ if (dev->binds == NULL) { - dev->binds = in_alloc_binds(dev->drv_id); + dev->binds = in_alloc_binds(dev->drv_id, dev->key_count); if (dev->binds == NULL) return -1; in_config_start(); @@ -683,15 +677,21 @@ int in_config_bind_key(int dev_id, const char *key, int binds) } } - if (kc < 0 || kc >= count) { + if (kc < 0 || kc >= dev->key_count) { printf("input: bad key: %s\n", key); return -1; } - if (dev->binds[kc] == -1) - dev->binds[kc] = 0; - dev->binds[kc] |= binds; + if (bind_type == IN_BINDTYPE_NONE) { + for (i = 0; i < IN_BINDTYPE_COUNT; i++) + dev->binds[IN_BIND_OFFS(kc, i)] = 0; + return 0; + } + offs = IN_BIND_OFFS(kc, bind_type); + if (dev->binds[offs] == -1) + dev->binds[offs] = 0; + dev->binds[offs] |= acts; return 0; } @@ -706,18 +706,18 @@ void in_config_end(void) if (dev->binds == NULL) continue; - count = in_bind_count(dev->drv_id); + count = dev->key_count; binds = dev->binds; - def_binds = binds + count; + def_binds = binds + count * IN_BINDTYPE_COUNT; - for (n = 0; n < count; n++) + for (n = 0; n < count * IN_BINDTYPE_COUNT; n++) if (binds[n] == -1) binds[n] = def_binds[n]; if (dev->drv_data == NULL) continue; - ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds); + ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds, def_binds); if (ret == 0) { /* no useable binds */ free(dev->binds); @@ -746,7 +746,7 @@ static void in_def_probe(void) {} static void in_def_free(void *drv_data) {} static int in_def_get_bind_count(void) { return 0; } static void in_def_get_def_binds(int *binds) {} -static int in_def_clean_binds(void *drv_data, int *binds) { return 0; } +static int in_def_clean_binds(void *drv_data, int *b, int *db) { return 0; } static void in_def_set_blocking(void *data, int y) {} static int in_def_update_keycode(void *drv_data, int *is_down) { return 0; } static int in_def_menu_translate(int keycode) { return keycode; } diff --git a/common/input.h b/common/input.h index 9bc28c9..390f411 100644 --- a/common/input.h +++ b/common/input.h @@ -58,13 +58,23 @@ enum { IN_INFO_DOES_COMBOS, }; +enum { + IN_BINDTYPE_NONE = -1, + IN_BINDTYPE_EMU = 0, + IN_BINDTYPE_PLAYER12, + IN_BINDTYPE_COUNT +}; + +#define IN_BIND_OFFS(key, btype) \ + ((key) * IN_BINDTYPE_COUNT + (btype)) + typedef struct { const char *prefix; void (*probe)(void); void (*free)(void *drv_data); int (*get_bind_count)(void); void (*get_def_binds)(int *binds); - int (*clean_binds)(void *drv_data, int *binds); + int (*clean_binds)(void *drv_data, int *binds, int *def_finds); void (*set_blocking)(void *data, int y); int (*update_keycode)(void *drv_data, int *is_down); int (*menu_translate)(int keycode); @@ -74,13 +84,14 @@ typedef struct { /* to be called by drivers */ -void in_register(const char *nname, int drv_id, int fd_hnd, void *drv_data, int combos); -void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts); -int in_combos_do(int keys, int *binds, int last_key, int combo_keys, int combo_acts); +void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, + int key_count, int combos); +void in_combos_find(const int *binds, int last_key, int *combo_keys, int *combo_acts); +int in_combos_do(int keys, const int *binds, int last_key, int combo_keys, int combo_acts); void in_init(void); void in_probe(void); -int in_update(void); +int in_update(int *result); void in_set_blocking(int is_blocking); int in_update_keycode(int *dev_id, int *is_down, int timeout_ms); int in_menu_wait_any(int timeout_ms); @@ -88,9 +99,9 @@ int in_menu_wait(int interesting, int autorep_delay_ms); int in_get_dev_info(int dev_id, int what); void in_config_start(void); int in_config_parse_dev(const char *dev_name); -int in_config_bind_key(int dev_id, const char *key, int mask); +int in_config_bind_key(int dev_id, const char *key, int binds, int bind_type); void in_config_end(void); -int in_bind_key(int dev_id, int keycode, int mask, int force_unbind); +int in_bind_key(int dev_id, int keycode, int bind_type, int mask, int force_unbind); void in_debug_dump(void); const int *in_get_dev_binds(int dev_id); diff --git a/common/menu.c b/common/menu.c index 221a3b8..c74d314 100644 --- a/common/menu.c +++ b/common/menu.c @@ -328,7 +328,7 @@ static void me_draw(const menu_entry *entries, int sel) { const menu_entry *ent; int x, y, w = 0, h = 0; - int offs, opt_offs = 27 * me_mfont_w; + int offs, col2_offs = 27 * me_mfont_w; const char *name; int asel = 0; int i, n; @@ -353,9 +353,9 @@ static void me_draw(const menu_entry *entries, int sel) if (ent->beh != MB_NONE) { - if (wt > opt_offs) - opt_offs = wt + me_mfont_w; - wt = opt_offs; + if (wt > col2_offs) + col2_offs = wt + me_mfont_w; + wt = col2_offs; switch (ent->beh) { case MB_NONE: break; @@ -415,10 +415,10 @@ static void me_draw(const menu_entry *entries, int sel) case MB_NONE: break; case MB_OPT_ONOFF: - text_out16(x + opt_offs, y, (*(int *)ent->var & ent->mask) ? "ON" : "OFF"); + text_out16(x + col2_offs, y, (*(int *)ent->var & ent->mask) ? "ON" : "OFF"); break; case MB_OPT_RANGE: - text_out16(x + opt_offs, y, "%i", *(int *)ent->var); + text_out16(x + col2_offs, y, "%i", *(int *)ent->var); break; case MB_OPT_CUSTOM: case MB_OPT_CUSTONOFF: @@ -428,7 +428,7 @@ static void me_draw(const menu_entry *entries, int sel) if (ent->generate_name) name = ent->generate_name(ent->id, &offs); if (name != NULL) - text_out16(x + opt_offs + offs * me_mfont_w, y, "%s", name); + text_out16(x + col2_offs + offs * me_mfont_w, y, "%s", name); break; } @@ -1084,8 +1084,8 @@ static int menu_loop_savestate(int is_loading) static char *action_binds(int player_idx, int action_mask, int dev_id) { + int k, count, can_combo, type; const int *binds; - int k, count; static_buff[0] = 0; @@ -1094,21 +1094,30 @@ static char *action_binds(int player_idx, int action_mask, int dev_id) return static_buff; count = in_get_dev_info(dev_id, IN_INFO_BIND_COUNT); + can_combo = in_get_dev_info(dev_id, IN_INFO_DOES_COMBOS); + + type = IN_BINDTYPE_EMU; + if (player_idx >= 0) { + can_combo = 0; + type = IN_BINDTYPE_PLAYER12; + } + if (player_idx == 1) + action_mask <<= 16; + for (k = 0; k < count; k++) { const char *xname; int len; - if (!(binds[k] & action_mask)) - continue; - if (player_idx >= 0 && ((binds[k] >> 16) & 3) != player_idx) + if (!(binds[IN_BIND_OFFS(k, type)] & action_mask)) continue; xname = in_get_key_name(dev_id, k); len = strlen(static_buff); if (len) { - strncat(static_buff, " + ", sizeof(static_buff) - len - 1); - len += 3; + strncat(static_buff, can_combo ? " + " : ", ", + sizeof(static_buff) - len - 1); + len += can_combo ? 3 : 2; } strncat(static_buff, xname, sizeof(static_buff) - len - 1); } @@ -1116,7 +1125,7 @@ static char *action_binds(int player_idx, int action_mask, int dev_id) return static_buff; } -static int count_bound_keys(int dev_id, int action_mask, int player_idx) +static int count_bound_keys(int dev_id, int action_mask, int bindtype) { const int *binds; int k, keys = 0; @@ -1129,13 +1138,8 @@ static int count_bound_keys(int dev_id, int action_mask, int player_idx) count = in_get_dev_info(dev_id, IN_INFO_BIND_COUNT); for (k = 0; k < count; k++) { - if (!(binds[k] & action_mask)) - continue; - - if (player_idx >= 0 && ((binds[k] >> 16) & 3) != player_idx) - continue; - - keys++; + if (binds[IN_BIND_OFFS(k, bindtype)] & action_mask) + keys++; } return keys; @@ -1191,7 +1195,8 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx) { int i, sel = 0, menu_sel_max = opt_cnt - 1; - int dev_id, dev_count, kc, is_down, mkey, unbind; + int dev_id, dev_count, kc, is_down, mkey; + int unbind, bindtype, mask; for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) { if (in_get_dev_name(i, 1, 0) != NULL) { @@ -1244,19 +1249,20 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ for (is_down = 1; is_down; ) kc = in_update_keycode(&dev_id, &is_down, -1); - i = count_bound_keys(dev_id, opts[sel].mask, player_idx); + bindtype = player_idx >= 0 ? IN_BINDTYPE_PLAYER12 : IN_BINDTYPE_EMU; + mask = opts[sel].mask; + if (player_idx == 1) + mask <<= 16; + + i = count_bound_keys(dev_id, mask, bindtype); unbind = (i > 0); /* allow combos if device supports them */ - if (i == 1 && in_get_dev_info(dev_id, IN_INFO_DOES_COMBOS)) + if (i == 1 && bindtype == IN_BINDTYPE_EMU && + in_get_dev_info(dev_id, IN_INFO_DOES_COMBOS)) unbind = 0; - in_bind_key(dev_id, kc, opts[sel].mask, unbind); - if (player_idx >= 0) { - /* FIXME */ - in_bind_key(dev_id, kc, 3 << 16, 1); - in_bind_key(dev_id, kc, player_idx << 16, 0); - } + in_bind_key(dev_id, kc, bindtype, mask, unbind); } } @@ -1280,10 +1286,6 @@ me_bind_action me_ctrl_actions[15] = { "Z ", 0x0100 } }; -// player2_flag, reserved, ?, ?, -// ?, ?, fast forward, menu -// "NEXT SAVE SLOT", "PREV SAVE SLOT", "SWITCH RENDERER", "SAVE STATE", -// "LOAD STATE", "VOLUME UP", "VOLUME DOWN", "DONE" me_bind_action emuctrl_actions[] = { { "Load State ", PEV_STATE_LOAD }, diff --git a/gp2x/in_gp2x.c b/gp2x/in_gp2x.c index f0da436..51c9bf5 100644 --- a/gp2x/in_gp2x.c +++ b/gp2x/in_gp2x.c @@ -113,7 +113,8 @@ static void in_gp2x_probe(void) return; } - in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, 1); + in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, + IN_GP2X_NBUTTONS, 1); } static void in_gp2x_free(void *drv_data) @@ -129,23 +130,29 @@ static int in_gp2x_get_bind_count(void) return IN_GP2X_NBUTTONS; } -/* returns bitfield of binds of pressed buttons */ -int in_gp2x_update(void *drv_data, int *binds) +/* ORs result with pressed buttons */ +int in_gp2x_update(void *drv_data, const int *binds, int *result) { - int i, keys, ret = 0; + int type_start = 0; + int i, t, keys; keys = in_gp2x_get_bits(); - if (keys & in_gp2x_combo_keys) - return in_combos_do(keys, binds, BTN_PUSH, in_gp2x_combo_keys, in_gp2x_combo_acts); + if (keys & in_gp2x_combo_keys) { + result[IN_BINDTYPE_EMU] = in_combos_do(keys, binds, BTN_PUSH, + in_gp2x_combo_keys, in_gp2x_combo_acts); + type_start = IN_BINDTYPE_PLAYER12; + } + + for (i = 0; keys; i++, keys >>= 1) { + if (!(keys & 1)) + continue; - for (i = 0; keys; i++) { - if (keys & 1) - ret |= binds[i]; - keys >>= 1; + for (t = type_start; t < IN_BINDTYPE_COUNT; t++) + result[t] |= binds[IN_BIND_OFFS(i, t)]; } - return ret; + return 0; } int in_gp2x_update_keycode(void *data, int *is_down) @@ -237,24 +244,25 @@ static const char *in_gp2x_get_key_name(int keycode) static const struct { short code; - short bit; + char btype; + char bit; } in_gp2x_def_binds[] = { /* MXYZ SACB RLDU */ - { BTN_UP, 0 }, - { BTN_DOWN, 1 }, - { BTN_LEFT, 2 }, - { BTN_RIGHT, 3 }, - { BTN_X, 4 }, /* B */ - { BTN_B, 5 }, /* C */ - { BTN_A, 6 }, /* A */ - { BTN_START, 7 }, - { BTN_SELECT, 23 }, /* menu */ - { BTN_Y, 26 }, /* switch rend */ - { BTN_L, 27 }, /* save state */ - { BTN_R, 28 }, /* load state */ - { BTN_VOL_UP, 29 }, /* vol up */ - { BTN_VOL_DOWN, 30 }, /* vol down */ + { BTN_UP, IN_BINDTYPE_PLAYER12, 0 }, + { BTN_DOWN, IN_BINDTYPE_PLAYER12, 1 }, + { BTN_LEFT, IN_BINDTYPE_PLAYER12, 2 }, + { BTN_RIGHT, IN_BINDTYPE_PLAYER12, 3 }, + { BTN_X, IN_BINDTYPE_PLAYER12, 4 }, /* B */ + { BTN_B, IN_BINDTYPE_PLAYER12, 5 }, /* C */ + { BTN_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */ + { BTN_START, IN_BINDTYPE_PLAYER12, 7 }, + { BTN_SELECT, IN_BINDTYPE_EMU, PEVB_MENU }, + { BTN_Y, IN_BINDTYPE_EMU, PEVB_SWITCH_RND }, + { BTN_L, IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, + { BTN_R, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, + { BTN_VOL_UP, IN_BINDTYPE_EMU, PEVB_VOL_UP }, + { BTN_VOL_DOWN, IN_BINDTYPE_EMU, PEVB_VOL_DOWN }, }; #define DEF_BIND_COUNT (sizeof(in_gp2x_def_binds) / sizeof(in_gp2x_def_binds[0])) @@ -264,39 +272,46 @@ static void in_gp2x_get_def_binds(int *binds) int i; for (i = 0; i < DEF_BIND_COUNT; i++) - binds[in_gp2x_def_binds[i].code] = 1 << in_gp2x_def_binds[i].bit; + binds[IN_BIND_OFFS(in_gp2x_def_binds[i].code, in_gp2x_def_binds[i].btype)] = + 1 << in_gp2x_def_binds[i].bit; } /* remove binds of missing keys, count remaining ones */ -static int in_gp2x_clean_binds(void *drv_data, int *binds) +static int in_gp2x_clean_binds(void *drv_data, int *binds, int *def_binds) { int i, count = 0, have_vol = 0, have_menu = 0; for (i = 0; i < IN_GP2X_NBUTTONS; i++) { - if (in_gp2x_keys[i] == NULL) - binds[i] = binds[i + IN_GP2X_NBUTTONS] = 0; - if (binds[i]) { - count++; - if (binds[i] & ((1 << 29)|(1 << 30))) - have_vol = 1; - if (binds[i] & (1 << 23)) - have_menu = 1; + int t, eb, offs; + for (t = 0; t < IN_BINDTYPE_COUNT; t++) { + offs = IN_BIND_OFFS(i, t); + if (in_gp2x_keys[i] == NULL) + binds[offs] = def_binds[offs] = 0; + if (binds[offs]) + count++; } + eb = binds[IN_BIND_OFFS(i, IN_BINDTYPE_EMU)]; + if (eb & (PEV_VOL_DOWN|PEV_VOL_UP)) + have_vol = 1; + if (eb & PEV_MENU) + have_menu = 1; } /* autobind some important keys, if they are unbound */ if (!have_vol && binds[BTN_VOL_UP] == 0 && binds[BTN_VOL_DOWN] == 0) { - binds[BTN_VOL_UP] = 1 << 29; - binds[BTN_VOL_DOWN] = 1 << 30; + binds[IN_BIND_OFFS(BTN_VOL_UP, IN_BINDTYPE_EMU)] = PEV_VOL_UP; + binds[IN_BIND_OFFS(BTN_VOL_DOWN, IN_BINDTYPE_EMU)] = PEV_VOL_DOWN; + count += 2; } - if (!have_menu && binds[BTN_SELECT] == 0) - binds[BTN_SELECT] = 1 << 23; + if (!have_menu) { + binds[IN_BIND_OFFS(BTN_SELECT, IN_BINDTYPE_EMU)] = PEV_MENU; + count++; + } in_combos_find(binds, BTN_PUSH, &in_gp2x_combo_keys, &in_gp2x_combo_acts); return count; - } void in_gp2x_init(void *vdrv) diff --git a/gp2x/in_gp2x.h b/gp2x/in_gp2x.h index 30af5c3..aa009bb 100644 --- a/gp2x/in_gp2x.h +++ b/gp2x/in_gp2x.h @@ -1,3 +1,3 @@ void in_gp2x_init(void *vdrv); -int in_gp2x_update(void *drv_data, int *binds); +int in_gp2x_update(void *drv_data, const int *binds, int *result); diff --git a/linux/in_evdev.c b/linux/in_evdev.c index 7795b69..74f81c7 100644 --- a/linux/in_evdev.c +++ b/linux/in_evdev.c @@ -14,7 +14,6 @@ typedef struct { int fd; - int prev_update; int abs_lzone; int abs_rzone; int abs_tzone; @@ -23,6 +22,10 @@ typedef struct { int abs_lasty; } in_evdev_t; +#ifndef KEY_CNT +#define KEY_CNT (KEY_MAX + 1) +#endif + #define KEYBITS_BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \ (1 << ((x) & (sizeof(keybits[0])*8-1)))) @@ -30,7 +33,7 @@ typedef struct { (1 << ((x) & (sizeof(keybits[0])*8-1)))) static const char * const in_evdev_prefix = "evdev:"; -static const char * const in_evdev_keys[KEY_MAX + 1] = { +static const char * const in_evdev_keys[KEY_CNT] = { [0 ... KEY_MAX] = NULL, [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc", [KEY_1] = "1", [KEY_2] = "2", @@ -123,7 +126,7 @@ static void in_evdev_probe(void) for (i = 0;; i++) { - int keybits[(KEY_MAX+1)/sizeof(int)], absbits[(ABS_MAX+1)/sizeof(int)]; + int keybits[KEY_CNT / sizeof(int)], absbits[(ABS_MAX+1)/sizeof(int)]; int support = 0, count = 0; in_evdev_t *dev; int u, ret, fd; @@ -131,8 +134,11 @@ static void in_evdev_probe(void) snprintf(name, sizeof(name), "/dev/input/event%d", i); fd = open(name, O_RDONLY|O_NONBLOCK); - if (fd == -1) + if (fd == -1) { + if (errno == EACCES) + continue; /* maybe we can access next one */ break; + } /* check supported events */ ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support); @@ -151,7 +157,7 @@ static void in_evdev_probe(void) } /* check for interesting keys */ - for (u = 0; u < KEY_MAX + 1; u++) { + for (u = 0; u < KEY_CNT; u++) { if (KEYBITS_BIT(u) && u != KEY_POWER && u != KEY_SLEEP) count++; } @@ -194,7 +200,7 @@ no_abs: ioctl(fd, EVIOCGNAME(sizeof(name)-6), name+6); printf("in_evdev: found \"%s\" with %d events (type %08x)\n", name+6, count, support); - in_register(name, IN_DRVID_EVDEV, fd, dev, 0); + in_register(name, IN_DRVID_EVDEV, fd, dev, KEY_CNT, 0); continue; skip: @@ -213,17 +219,24 @@ static void in_evdev_free(void *drv_data) static int in_evdev_get_bind_count(void) { - return KEY_MAX + 1; + return KEY_CNT; } -/* returns bitfield of binds of pressed buttons */ -int in_evdev_update(void *drv_data, int *binds) +static void or_binds(const int *binds, int key, int *result) +{ + int t; + for (t = 0; t < IN_BINDTYPE_COUNT; t++) + result[t] |= binds[IN_BIND_OFFS(key, t)]; +} + +/* ORs result with binds of pressed buttons + * XXX: should measure performance hit of this func, might need to optimize */ +int in_evdev_update(void *drv_data, const int *binds, int *result) { struct input_event ev[16]; struct input_absinfo ainfo; - int keybits[(KEY_MAX+1)/sizeof(int)]; + int keybits[KEY_CNT / sizeof(int)]; in_evdev_t *dev = drv_data; - int result = 0, changed = 0; int rd, ret, u; while (1) { @@ -233,43 +246,36 @@ int in_evdev_update(void *drv_data, int *binds) perror("in_evdev: read failed"); break; } - - changed = 1; } - if (!changed) - return dev->prev_update; - ret = ioctl(dev->fd, EVIOCGKEY(sizeof(keybits)), keybits); if (ret == -1) { perror("in_evdev: ioctl failed"); - return 0; + return -1; } - for (u = 0; u < KEY_MAX + 1; u++) { - if (KEYBITS_BIT(u)) { - result |= binds[u]; - } + for (u = 0; u < KEY_CNT; u++) { + if (KEYBITS_BIT(u)) + or_binds(binds, u, result); } /* map X and Y absolute to UDLR */ if (dev->abs_lzone != 0) { ret = ioctl(dev->fd, EVIOCGABS(ABS_X), &ainfo); if (ret != -1) { - if (ainfo.value < dev->abs_lzone) result |= binds[KEY_LEFT]; - if (ainfo.value > dev->abs_rzone) result |= binds[KEY_RIGHT]; + if (ainfo.value < dev->abs_lzone) or_binds(binds, KEY_LEFT, result); + if (ainfo.value > dev->abs_rzone) or_binds(binds, KEY_RIGHT, result); } } if (dev->abs_tzone != 0) { ret = ioctl(dev->fd, EVIOCGABS(ABS_Y), &ainfo); if (ret != -1) { - if (ainfo.value < dev->abs_tzone) result |= binds[KEY_UP]; - if (ainfo.value > dev->abs_bzone) result |= binds[KEY_DOWN]; + if (ainfo.value < dev->abs_tzone) or_binds(binds, KEY_UP, result); + if (ainfo.value > dev->abs_bzone) or_binds(binds, KEY_DOWN, result); } } - dev->prev_update = result; - return result; + return 0; } static void in_evdev_set_blocking(void *drv_data, int y) @@ -278,8 +284,6 @@ static void in_evdev_set_blocking(void *drv_data, int y) long flags; int ret; - dev->prev_update = 0; - flags = (long)fcntl(dev->fd, F_GETFL); if ((int)flags == -1) { perror("in_evdev: F_GETFL fcntl failed"); @@ -403,7 +407,7 @@ static int in_evdev_get_key_code(const char *key_name) { int i; - for (i = 0; i < KEY_MAX + 1; i++) { + for (i = 0; i < KEY_CNT; i++) { const char *k = in_evdev_keys[i]; if (k != NULL && strcasecmp(k, key_name) == 0) return i; @@ -425,24 +429,25 @@ static const char *in_evdev_get_key_name(int keycode) static const struct { short code; - short bit; + char btype; + char bit; } in_evdev_def_binds[] = { /* MXYZ SACB RLDU */ - { KEY_UP, 0 }, - { KEY_DOWN, 1 }, - { KEY_LEFT, 2 }, - { KEY_RIGHT, 3 }, - { KEY_S, 4 }, /* B */ - { BTN_B, 4 }, - { KEY_D, 5 }, /* C */ - { BTN_A, 5 }, - { KEY_A, 6 }, /* A */ - { BTN_Y, 6 }, - { KEY_ENTER, 7 }, - { BTN_START, 7 }, - { BTN_TL, PEVB_STATE_LOAD }, - { BTN_TR, PEVB_STATE_SAVE }, + { 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 */ + { BTN_B, IN_BINDTYPE_PLAYER12, 4 }, + { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */ + { BTN_A, IN_BINDTYPE_PLAYER12, 5 }, + { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */ + { BTN_Y, IN_BINDTYPE_PLAYER12, 6 }, + { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 }, + { BTN_START, IN_BINDTYPE_PLAYER12, 7 }, + { BTN_TL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, + { BTN_TR, IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, }; #define DEF_BIND_COUNT (sizeof(in_evdev_def_binds) / sizeof(in_evdev_def_binds[0])) @@ -452,15 +457,16 @@ static void in_evdev_get_def_binds(int *binds) int i; for (i = 0; i < DEF_BIND_COUNT; i++) - binds[in_evdev_def_binds[i].code] = 1 << in_evdev_def_binds[i].bit; + 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) +static int in_evdev_clean_binds(void *drv_data, int *binds, int *def_binds) { - int keybits[(KEY_MAX+1)/sizeof(int)]; + int keybits[KEY_CNT / sizeof(int)]; in_evdev_t *dev = drv_data; - int i, ret, count = 0; + int i, t, ret, offs, count = 0; ret = ioctl(dev->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits); if (ret == -1) { @@ -477,11 +483,14 @@ static int in_evdev_clean_binds(void *drv_data, int *binds) KEYBITS_BIT_SET(KEY_DOWN); } - for (i = 0; i < KEY_MAX + 1; i++) { - if (!KEYBITS_BIT(i)) - binds[i] = binds[i + KEY_MAX + 1] = 0; - if (binds[i]) - count++; + 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; diff --git a/linux/in_evdev.h b/linux/in_evdev.h index 84392c6..2c24c2e 100644 --- a/linux/in_evdev.h +++ b/linux/in_evdev.h @@ -1,4 +1,4 @@ void in_evdev_init(void *vdrv); -int in_evdev_update(void *drv_data, int *binds); +int in_evdev_update(void *drv_data, const int *binds, int *result); diff --git a/linux/port_config.h b/linux/port_config.h index 283dc08..fc2e118 100644 --- a/linux/port_config.h +++ b/linux/port_config.h @@ -26,7 +26,7 @@ #define SIMPLE_WRITE_SOUND 0 #define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo -#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_SRAMIO|EL_EEPROM|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) +#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)