From 7e4c661a2732e77cb004bd3c47e32ef1a1a9a639 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 2 Jan 2009 19:43:56 +0000 Subject: [PATCH] starting input layer integration work git-svn-id: file:///home/notaz/opt/svn/PicoDrive@628 be3aeb3a-fb24-0410-a615-afba39da0efa --- platform/common/common.h | 2 +- platform/common/config.c | 179 +++++++++++++++++++++-------- platform/gp2x/emu.c | 10 ++ platform/gp2x/main.c | 4 + platform/gp2x/menu.c | 236 +++++++++++++++++---------------------- platform/linux/Makefile | 6 +- 6 files changed, 255 insertions(+), 182 deletions(-) diff --git a/platform/common/common.h b/platform/common/common.h index 88983ce..6a49bf5 100644 --- a/platform/common/common.h +++ b/platform/common/common.h @@ -15,7 +15,7 @@ #define PBTN_L GP2X_L #define PBTN_R GP2X_R -unsigned long wait_for_input(unsigned long interesting); +int wait_for_input(int interesting); void gp2x_pd_clone_buffer2(void); void menu_darken_bg(void *dst, int pixels, int darker); void menu_flip(void); diff --git a/platform/common/config.c b/platform/common/config.c index 2704aca..9e7b1a7 100644 --- a/platform/common/config.c +++ b/platform/common/config.c @@ -10,6 +10,7 @@ #include #endif #include "config.h" +#include "input.h" #include "lprintf.h" static char *mystrip(char *str); @@ -218,31 +219,30 @@ static const char *joyKeyNames[32] = }; #endif -static void keys_write(FILE *fn, const char *bind_str, const int binds[32], - const int def_binds[32], const char * const names[32], int key_count, int no_defaults) +static void keys_write(FILE *fn, const char *bind_str, int dev_id, const int *binds, int no_defaults) { - int t, i; - char act[48], name[32]; + char act[48]; + int key_count, t, i; + const int *def_binds; + + key_count = in_get_dev_bind_count(dev_id); + def_binds = in_get_dev_def_binds(dev_id); for (t = 0; t < key_count; t++) { + const char *name; act[0] = act[31] = 0; + if (no_defaults && binds[t] == def_binds[t]) continue; + + name = in_get_key_name(dev_id, t); #ifdef __GP2X__ - if (strcmp(names[t], "SELECT") == 0) continue; + if (strcmp(name, "SELECT") == 0) continue; #endif - if (t >= 32 || names[t] == NULL || strcmp(names[t], "???") == 0) { - if ((t >= '0' && t <= '9') || (t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z')) - sprintf(name, "%c", t); - else - sprintf(name, "\\x%02x", t); - } - else - strcpy(name, names[t]); if (binds[t] == 0 && def_binds[t] != 0) { - fprintf(fn, "%s %s =" NL, bind_str, name); // no binds + fprintf(fn, "%s %s =" NL, bind_str, name); continue; } @@ -397,7 +397,37 @@ write: } } - // save key config + /* input: save device names */ + for (t = 0; t < IN_MAX_DEVS; t++) + { + const int *binds = in_get_dev_binds(t); + const char *name = in_get_dev_name(t); + if (binds == NULL || name == NULL) + continue; + + fprintf(fn, "input%d = %s" NL, t, name); + } + + /* input: save binds */ + for (t = 0; t < IN_MAX_DEVS; t++) + { + const int *binds = in_get_dev_binds(t); + const char *name = in_get_dev_name(t); + char strbind[16]; + int count; + + if (binds == NULL || name == NULL) + continue; + + sprintf(strbind, "bind%d", t); + if (t == 0) strbind[4] = 0; + + count = in_get_dev_bind_count(t); + keys_write(fn, strbind, t, binds, no_defaults); + } + +#if 0 + /* old stuff */ keys_write(fn, "bind", currentConfig.KeyBinds, defaultConfig.KeyBinds, keyNames, PLAT_MAX_KEYS, no_defaults); #if PLAT_HAVE_JOY keys_write(fn, "bind_joy0", currentConfig.JoyBinds[0], defaultConfig.JoyBinds[0], joyKeyNames, 32, 1); @@ -405,6 +435,7 @@ write: keys_write(fn, "bind_joy2", currentConfig.JoyBinds[2], defaultConfig.JoyBinds[2], joyKeyNames, 32, 1); keys_write(fn, "bind_joy3", currentConfig.JoyBinds[3], defaultConfig.JoyBinds[3], joyKeyNames, 32, 1); #endif +#endif #ifndef PSP if (section == NULL) @@ -702,12 +733,45 @@ static int custom_read(menu_entry *me, const char *var, const char *val) static unsigned int keys_encountered = 0; -static void keys_parse(const char *var, const char *val, int binds[32], - const char * const names[32], int max_keys) +static int parse_bind_val(const char *val) +{ + int i; + + if (val[0] == 0) + return 0; + + if (strncasecmp(val, "player", 6) == 0) + { + unsigned int player; + player = atoi(val + 6) - 1; + if (player > 1) + return -1; + + 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); + } + } + for (i = 0; emuctrl_actions[i].name != NULL; i++) { + if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) + return emuctrl_actions[i].mask; + } + + return -1; +} + +static void keys_parse(const char *key, const char *val, int dev_id) { - int t, i; - unsigned int player; + int binds; + binds = parse_bind_val(val); + if (binds == -1) { + lprintf("config: unhandled action \"%s\"\n", val); + return; + } + + in_config_bind_key(dev_id, key, binds); +/* for (t = 0; t < 32; t++) { if (names[t] && strcmp(names[t], var) == 0) break; @@ -734,29 +798,7 @@ static void keys_parse(const char *var, const char *val, int binds[32], binds[t] = 0; keys_encountered |= 1< 1) goto fail; - 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) { - binds[t] |= me_ctrl_actions[i].mask | (player<<16); - return; - } - } - } - for (i = 0; emuctrl_actions[i].name != NULL; i++) { - if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) { - binds[t] |= emuctrl_actions[i].mask; - return; - } - } - -fail: - lprintf("unhandled action \"%s\"\n", val); - return; +*/ } @@ -767,6 +809,24 @@ fail: } \ } +static int get_numvar_num(const char *var) +{ + char *p = NULL; + int num; + + if (var[0] == ' ') + return 0; + + num = strtoul(var, &p, 10); + if (*p == 0 || *p == ' ') + return num; + + return -1; +} + +/* map dev number in confing to input dev number */ +static unsigned char input_dev_map[IN_MAX_DEVS]; + static void parse(const char *var, const char *val) { menu_entry *me; @@ -780,12 +840,38 @@ static void parse(const char *var, const char *val) return; } + /* input: device name */ + if (strncasecmp(var, "input", 5) == 0) { + int num = get_numvar_num(var + 5); + if (num >= 0 && num < IN_MAX_DEVS) + input_dev_map[num] = in_config_parse_dev(val); + else + printf("failed to parse: %s\n", var); + return; + } + // key binds - if (strncasecmp(var, "bind ", 5) == 0) { - keys_parse(var + 5, val, currentConfig.KeyBinds, keyNames, PLAT_MAX_KEYS); + if (strncasecmp(var, "bind", 4) == 0) { + const char *p = var + 4; + int num = get_numvar_num(p); + if (num < 0 || num >= IN_MAX_DEVS) { + printf("failed to parse: %s\n", var); + return; + } + + num = input_dev_map[num]; + if (num < 0 || num >= IN_MAX_DEVS) { + printf("invalid device id: %s\n", var); + return; + } + + while (*p && *p != ' ') p++; + while (*p && *p == ' ') p++; + keys_parse(p, val, num); return; } -#if PLAT_HAVE_JOY + +#if 0//PLAT_HAVE_JOY try_joy_parse(0) try_joy_parse(1) try_joy_parse(2) @@ -854,7 +940,9 @@ int config_readsect(const char *fname, const char *section) } keys_encountered = 0; + memset(input_dev_map, 0xff, sizeof(input_dev_map)); + in_config_start(); while (!feof(f)) { ret = config_get_var_val(f, line, sizeof(line), &var, &val); @@ -863,6 +951,7 @@ int config_readsect(const char *fname, const char *section) parse(var, val); } + in_config_end(); fclose(f); return 0; diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index aef34b0..a19329d 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -22,6 +22,7 @@ #include "../common/fonts.h" #include "../common/emu.h" #include "../common/config.h" +#include "../common/input.h" #include "../linux/sndout_oss.h" #include "cpuctrl.h" @@ -580,6 +581,14 @@ static void updateKeys(void) keys &= CONFIGURABLE_KEYS; keys2 = keys; +#if 1 + { + /* FIXME: combos */ + int acts = in_update(); + int pl = (acts >> 16) & 1; + allActions[pl] |= acts; + } +#else for (i = 0; i < 32; i++) { if (keys2 & (1 << i)) @@ -607,6 +616,7 @@ static void updateKeys(void) } } } +#endif // add joy inputs if (num_of_joys > 0) diff --git a/platform/gp2x/main.c b/platform/gp2x/main.c index bdf90d5..d8d82af 100644 --- a/platform/gp2x/main.c +++ b/platform/gp2x/main.c @@ -15,6 +15,7 @@ #include "../common/menu.h" #include "../common/emu.h" #include "../common/config.h" +#include "../common/input.h" #include "emu.h" #include "940ctl.h" #include "version.h" @@ -88,10 +89,13 @@ int main(int argc, char *argv[]) { g_argv = argv; + in_init(); emu_prepareDefaultConfig(); emu_ReadConfig(0, 0); config_readlrom(PicoConfigFile); + in_probe(); + in_debug_dump(); gp2x_init(); if (currentConfig.EmuOpt&0x10) { int ret = mmuhack(); diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index ff8cd99..0b3187c 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -18,6 +18,8 @@ #include "../common/menu.h" #include "../common/arm_utils.h" #include "../common/readpng.h" +#include "../common/common.h" +#include "../common/input.h" #include "version.h" #include @@ -40,26 +42,25 @@ const char * const keyNames[] = { void menu_darken_bg(void *dst, int pixels, int darker); static void menu_prepare_bg(int use_game_bg); -static unsigned long inp_prev = 0; -static int inp_prevjoy = 0; - -unsigned long wait_for_input(unsigned long interesting) +/* wait for input, do autorepeat */ +int wait_for_input(int interesting) { - unsigned long ret; + static int inp_prev = 0; static int repeats = 0, wait = 20; - int release = 0, i; + int ret, release = 0, i; if (repeats == 2) wait = 3; else if (repeats == 4) wait = 2; else if (repeats == 6) wait = 1; - for (i = 0; i < wait && inp_prev == gp2x_joystick_read(1); i++) { + for (i = 0; i < wait; i++) { + ret = in_update_menu(30); + if (ret != inp_prev) break; if (i == 0) repeats++; - usleep(30000); } - while ( !((ret = gp2x_joystick_read(1)) & interesting) ) { - usleep(50000); + while (!(ret & interesting)) { + ret = in_update_menu(0); release = 1; } @@ -67,67 +68,15 @@ unsigned long wait_for_input(unsigned long interesting) repeats = 0; wait = 20; } - if (wait > 6 && (ret&(GP2X_UP|GP2X_LEFT|GP2X_DOWN|GP2X_RIGHT|GP2X_L|GP2X_R))) + if (wait > 6 && (ret & (PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT))) wait = 6; inp_prev = ret; - inp_prevjoy = 0; // we don't need diagonals in menus - if ((ret&GP2X_UP) && (ret&GP2X_LEFT)) ret &= ~GP2X_LEFT; - if ((ret&GP2X_UP) && (ret&GP2X_RIGHT)) ret &= ~GP2X_RIGHT; - if ((ret&GP2X_DOWN) && (ret&GP2X_LEFT)) ret &= ~GP2X_LEFT; - if ((ret&GP2X_DOWN) && (ret&GP2X_RIGHT)) ret &= ~GP2X_RIGHT; - - return ret; -} - -static unsigned long input2_read(unsigned long interesting, int *joy) -{ - unsigned long ret; - int i; - - do - { - *joy = 0; - if ((ret = gp2x_joystick_read(0) & interesting)) break; - usbjoy_update(); - for (i = 0; i < num_of_joys; i++) { - ret = usbjoy_check2(i); - if (ret) { *joy = i + 1; break; } - } - if (ret) break; - } - while(0); - - return ret; -} - -// similar to wait_for_input(), but returns joy num -static unsigned long wait_for_input_usbjoy(unsigned long interesting, int *joy) -{ - unsigned long ret; - const int wait = 300*1000; - int i; - - if (inp_prevjoy == 0) inp_prev &= interesting; - for (i = 0; i < 6; i++) { - ret = input2_read(interesting, joy); - if (*joy != inp_prevjoy || ret != inp_prev) break; - usleep(wait/6); - } - - while ( !(ret = input2_read(interesting, joy)) ) { - usleep(50000); - } - - inp_prev = ret; - inp_prevjoy = *joy; - - // handle only 1 event at a time - for (i = 1; i != 0; i <<= 1) - if (ret & i) { ret &= i; break; } - // ... but allow select - ret |= inp_prev & GP2X_SELECT; + 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; return ret; } @@ -626,10 +575,41 @@ static char *usb_joy_key_name(int joy, int num) static char *action_binds(int player_idx, int action_mask) { - static char strkeys[32*5]; - int joy, i; + static char strkeys[32]; + int d, k, d_prev = -1; strkeys[0] = 0; + + for (d = 0; d < IN_MAX_DEVS; d++) + { + const int *binds; + int count; + + binds = in_get_dev_binds(d); + if (binds == NULL) + continue; + + count = in_get_dev_bind_count(d); + for (k = 0; k < count; k++) + { + const char *xname; + char prefix[16]; + if (!(binds[k] & action_mask)) + continue; + + if (player_idx >= 0 && ((binds[k] >> 16) & 3) != player_idx) + continue; + + xname = in_get_key_name(d, k); + if (strkeys[0]) + strncat(strkeys, d == d_prev ? " + " : ", ", sizeof(strkeys)); + if (d) sprintf(prefix, "%d: ", d); + if (d) strncat(strkeys, prefix, sizeof(strkeys)); + strncat(strkeys, xname, sizeof(strkeys)); + d_prev = d; + } + } +#if 0 for (i = 0; i < 32; i++) // i is key index { if (currentConfig.KeyBinds[i] & action_mask) @@ -654,6 +634,8 @@ static char *action_binds(int player_idx, int action_mask) } } } +#endif + // limit.. strkeys[20] = 0; @@ -689,28 +671,33 @@ static void unbind_action(int action, int pl_idx, int joy) } } -static int count_bound_keys(int action, int pl_idx, int joy) +static int count_bound_keys(int dev_id, int action_mask, int player_idx) { - int i, keys = 0; + const int *binds; + int k, keys = 0; + int count; - if (joy) - { - for (i = 0; i < 32; i++) { - if (pl_idx >= 0 && (currentConfig.JoyBinds[joy-1][i]&0x30000) != (pl_idx<<16)) continue; - if (currentConfig.JoyBinds[joy-1][i] & action) keys++; - } - } - else + binds = in_get_dev_binds(dev_id); + if (binds == NULL) + return 0; + + count = in_get_dev_bind_count(dev_id); + for (k = 0; k < count; k++) { - for (i = 0; i < 32; i++) { - if (pl_idx >= 0 && (currentConfig.KeyBinds[i]&0x30000) != (pl_idx<<16)) continue; - if (currentConfig.KeyBinds[i] & action) keys++; - } + if (!(binds[k] & action_mask)) + continue; + + if (player_idx >= 0 && ((binds[k] >> 16) & 3) != player_idx) + continue; + + keys++; } + return keys; } -static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel) +static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, + int sel, int is_bind) { int x, y, tl_y = 30, i; @@ -732,9 +719,7 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ text_out16(x, y, "Done"); if (sel < opt_cnt) { - text_out16(30, 195, "Press a button to bind/unbind"); - text_out16(30, 205, "Use SELECT to clear"); - text_out16(30, 215, "To bind UP/DOWN, hold SELECT"); + text_out16(30, 205, is_bind ? "Press a button to bind/unbind" : "Press B to define"); text_out16(30, 225, "Select \"Done\" to exit"); } else { text_out16(30, 205, "Use Options -> Save cfg"); @@ -746,56 +731,39 @@ 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 joy = 0, sel = 0, menu_sel_max = opt_cnt, prev_select = 0, i; - unsigned long inp = 0; + int sel = 0, menu_sel_max = opt_cnt; + int kc, dev_id, is_down, mkey, unbind; for (;;) { - draw_key_config(opts, opt_cnt, player_idx, sel); - inp = wait_for_input_usbjoy(CONFIGURABLE_KEYS, &joy); - // printf("got %08lX from joy %i\n", inp, joy); - if (joy == 0) - { - if (!(inp & GP2X_SELECT)) { - prev_select = 0; - if(inp & GP2X_UP ) { sel--; if (sel < 0) sel = menu_sel_max; continue; } - if(inp & GP2X_DOWN) { sel++; if (sel > menu_sel_max) sel = 0; continue; } - } - if (sel >= opt_cnt) { - if (inp & (GP2X_B|GP2X_X)) break; - else continue; - } - // if we are here, we want to bind/unbind something - if ((inp & GP2X_SELECT) && !prev_select) - unbind_action(opts[sel].mask, player_idx, -1); - prev_select = inp & GP2X_SELECT; - inp &= CONFIGURABLE_KEYS; - inp &= ~GP2X_SELECT; - for (i = 0; i < 32; i++) - if (inp & (1 << i)) { - if (count_bound_keys(opts[sel].mask, player_idx, 0) >= 2) - currentConfig.KeyBinds[i] &= ~opts[sel].mask; // allow to unbind only - else currentConfig.KeyBinds[i] ^= opts[sel].mask; - if (player_idx >= 0 && (currentConfig.KeyBinds[i] & opts[sel].mask)) { - currentConfig.KeyBinds[i] &= ~(3 << 16); - currentConfig.KeyBinds[i] |= player_idx << 16; - } - } + draw_key_config(opts, opt_cnt, player_idx, sel, 0); + mkey = wait_for_input(PBTN_UP|PBTN_DOWN|PBTN_SOUTH|PBTN_EAST); + switch (mkey) { + case PBTN_UP: sel--; if (sel < 0) sel = menu_sel_max; continue; + case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue; + case PBTN_SOUTH: + if (sel >= opt_cnt) + return; + continue; + case PBTN_EAST: + if (sel >= opt_cnt) + return; + break; + default:continue; } - else if (sel < opt_cnt) - { - for (i = 0; i < 32; i++) - if (inp & (1 << i)) { - int *bind = ¤tConfig.JoyBinds[joy-1][i]; - if ((*bind & opts[sel].mask) && (player_idx < 0 || player_idx == ((*bind>>16)&3))) - *bind &= ~opts[sel].mask; - else { - // override - unbind_action(opts[sel].mask, player_idx, joy); - *bind = opts[sel].mask; - if (player_idx > 0) *bind |= player_idx << 16; - } - } + + draw_key_config(opts, opt_cnt, player_idx, sel, 1); + //inp = wait_for_input_usbjoy(CONFIGURABLE_KEYS, &joy); + for (is_down = 0; is_down == 0; ) + kc = in_update_keycode(&dev_id, &is_down, 0); + + unbind = count_bound_keys(dev_id, opts[sel].mask, player_idx) >= 2; + + 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); } } } @@ -1654,10 +1622,12 @@ static void menu_gfx_prepare(void) void menu_loop(void) { + in_set_blocking(1); menu_gfx_prepare(); menu_loop_root(); + in_set_blocking(0); menuErrorMsg[0] = 0; } diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 8000a0d..b25264b 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -7,7 +7,7 @@ use_musashi = 1 # profile = 1 -DEFINC = -I../.. -I. -D__GP2X__ -D_UNZIP_SUPPORT -DIO_STATS # -DBENCHMARK +DEFINC = -I../.. -I. -D__GP2X__ -D_UNZIP_SUPPORT -DIO_STATS -DIN_EVDEV # -DBENCHMARK GCC = gcc STRIP = strip AS = gcc @@ -28,11 +28,11 @@ LDFLAGS += `pkg-config --libs gthread-2.0` # frontend OBJS += platform/gp2x/main.o platform/gp2x/menu.o platform/gp2x/emu.o usbjoy.o blit.o \ - sndout_oss.o gp2x.o 940ctl_ym2612.o log_io.o + in_evdev.o sndout_oss.o gp2x.o 940ctl_ym2612.o log_io.o # common OBJS += platform/common/emu.o platform/common/menu.o platform/common/config.o platform/common/fonts.o \ - platform/common/readpng.o platform/common/mp3_helix.o + platform/common/readpng.o platform/common/input.o platform/common/mp3_helix.o # Pico OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ -- 2.39.2