int key_count, t, i;
const int *def_binds;
- key_count = in_get_dev_bind_count(dev_id);
+ 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++)
sprintf(strbind, "bind%d", t);
if (t == 0) strbind[4] = 0;
- count = in_get_dev_bind_count(t);
+ count = in_get_dev_info(t, IN_INFO_BIND_COUNT);
keys_write(fn, strbind, t, binds, no_defaults);
}
char noticeMsg[64] = { 0, };\r
int state_slot = 0;\r
int config_slot = 0, config_slot_current = 0;\r
-int kb_combo_keys = 0, kb_combo_acts = 0; // keys and actions which need button combos\r
int pico_inp_mode = 0;\r
int engineState = PGS_Menu;\r
\r
\r
#undef mk_text_out\r
\r
-#ifdef PSP\r
-#define MAX_COMBO_KEY 23\r
-#else\r
-#define MAX_COMBO_KEY 31\r
-#endif\r
-\r
-// FIXME\r
-void emu_findKeyBindCombos(void)\r
-{\r
- int act, u;\r
-\r
- // find out which keys and actions are combos\r
- kb_combo_keys = kb_combo_acts = 0;\r
- for (act = 0; act < 32; act++)\r
- {\r
- int keyc = 0, keyc2 = 0;\r
- if (act == 16 || act == 17) continue; // player2 flag\r
- if (act > 17)\r
- {\r
- for (u = 0; u <= MAX_COMBO_KEY; u++)\r
- if (currentConfig.KeyBinds[u] & (1 << act)) keyc++;\r
- }\r
- else\r
- {\r
- for (u = 0; u <= MAX_COMBO_KEY; u++)\r
- if ((currentConfig.KeyBinds[u] & 0x30000) == 0 && // pl. 1\r
- (currentConfig.KeyBinds[u] & (1 << act))) keyc++;\r
- for (u = 0; u <= MAX_COMBO_KEY; u++)\r
- if ((currentConfig.KeyBinds[u] & 0x30000) == 1 && // pl. 2\r
- (currentConfig.KeyBinds[u] & (1 << act))) keyc2++;\r
- if (keyc2 > keyc) keyc = keyc2;\r
- }\r
- if (keyc > 1)\r
- {\r
- // loop again and mark those keys and actions as combo\r
- for (u = 0; u <= MAX_COMBO_KEY; u++)\r
- {\r
- if (currentConfig.KeyBinds[u] & (1 << act)) {\r
- kb_combo_keys |= 1 << u;\r
- kb_combo_acts |= 1 << act;\r
- }\r
- }\r
- }\r
- }\r
-\r
- // printf("combo keys/acts: %08x %08x\n", kb_combo_keys, kb_combo_acts);\r
-}\r
-\r
\r
void emu_updateMovie(void)\r
{\r
extern int state_slot;
extern int config_slot, config_slot_current;
extern unsigned char *movie_data;
-extern int kb_combo_keys, kb_combo_acts; // keys and actions which need button combos
extern int pico_inp_mode;
extern char rom_fname_reload[512]; // ROM to try loading on next PGS_ReloadRom
void emu_textOut16(int x, int y, const char *text);
char *emu_makeRomId(void);
void emu_getGameName(char *str150);
-void emu_findKeyBindCombos(void);
void emu_changeFastForward(int set_on);
void emu_RunEventsPico(unsigned int events);
void emu_DoTurbo(int *pad, int acts);
char *name;
int *binds;
int probed:1;
+ int does_combos:1;
} in_dev_t;
static in_drv_t in_drivers[IN_DRVID_COUNT];
/* 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)
+void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, int combos)
{
int i, ret, dupe_count = 0, *binds;
char name[256], *name_end, *tmp;
printf("input: new device #%d \"%s\"\n", i, name);
update:
in_devices[i].probed = 1;
+ in_devices[i].does_combos = combos;
in_devices[i].drv_id = drv_id;
in_devices[i].drv_fd_hnd = drv_fd_hnd;
in_devices[i].drv_data = drv_data;
}
}
+/* 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)
+{
+ int act, u;
+
+ *combo_keys = *combo_acts = 0;
+ for (act = 0; act < sizeof(binds[0]) * 8; act++)
+ {
+ int keyc = 0;
+ for (u = 0; u <= last_key; u++)
+ if (binds[u] & (1 << act))
+ keyc++;
+
+ if (keyc > 1)
+ {
+ // loop again and mark those keys and actions as combo
+ for (u = 0; u <= last_key; u++)
+ {
+ if (binds[u] & (1 << act)) {
+ *combo_keys |= 1 << u;
+ *combo_acts |= 1 << act;
+ }
+ }
+ }
+ }
+}
+
+int in_combos_do(int keys, int *binds, int last_key, int combo_keys, int combo_acts)
+{
+ int i, ret = 0;
+
+ for (i = 0; i <= last_key; i++)
+ {
+ int acts;
+ if (!(keys & (1 << i)))
+ continue;
+
+ acts = binds[i];
+ 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
+ ret |= acts;
+ }
+
+ return ret;
+}
+
void in_probe(void)
{
int i;
{
static int inp_prev = 0;
static int repeats = 0;
- int ret, release = 0, wait = 666;
+ int ret, release = 0, wait = 450;
if (repeats)
wait = autorep_delay_ms;
return in_devices[dev_id].binds + count;
}
-int in_get_dev_bind_count(int dev_id)
+int in_get_dev_info(int dev_id, int what)
{
if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
return 0;
- return in_bind_count(in_devices[dev_id].drv_id);
+ switch (what) {
+ case IN_INFO_BIND_COUNT:
+ return in_bind_count(in_devices[dev_id].drv_id);
+ case IN_INFO_DOES_COMBOS:
+ return in_devices[dev_id].does_combos;
+ }
+
+ return 0;
}
const char *in_get_dev_name(int dev_id, int must_be_active, int skip_pfix)
IN_DRVID_UNKNOWN = 0,
IN_DRVID_GP2X,
IN_DRVID_EVDEV,
- IN_DRVID_COUNT
+ IN_DRVID_COUNT,
+};
+
+enum {
+ IN_INFO_BIND_COUNT = 0,
+ IN_INFO_DOES_COMBOS,
};
typedef struct {
/* to be called by drivers */
-void in_register(const char *nname, int drv_id, int fd_hnd, void *drv_data);
+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_init(void);
void in_probe(void);
int in_update_keycode(int *dev_id, int *is_down, int timeout_ms);
int in_menu_wait_any(int timeout_ms);
int in_menu_wait(int interesting, int autorep_delay_ms);
-int in_get_dev_bind_count(int dev_id);
+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);
if (binds == NULL)\r
return static_buff;\r
\r
- count = in_get_dev_bind_count(dev_id);\r
+ count = in_get_dev_info(dev_id, IN_INFO_BIND_COUNT);\r
for (k = 0; k < count; k++)\r
{\r
const char *xname;\r
if (binds == NULL)\r
return 0;\r
\r
- count = in_get_dev_bind_count(dev_id);\r
+ count = in_get_dev_info(dev_id, IN_INFO_BIND_COUNT);\r
for (k = 0; k < count; k++)\r
{\r
if (!(binds[k] & action_mask))\r
for (is_down = 1; is_down; )\r
kc = in_update_keycode(&dev_id, &is_down, -1);\r
\r
- unbind = count_bound_keys(dev_id, opts[sel].mask, player_idx) >= 2;\r
+ i = count_bound_keys(dev_id, opts[sel].mask, player_idx);\r
+ unbind = (i > 0);\r
+\r
+ /* allow combos if device supports them */\r
+ if (i == 1 && in_get_dev_info(dev_id, IN_INFO_DOES_COMBOS))\r
+ unbind = 0;\r
\r
in_bind_key(dev_id, kc, opts[sel].mask, unbind);\r
if (player_idx >= 0) {\r
keys &= CONFIGURABLE_KEYS;\r
keys2 = keys;\r
\r
-#if 1\r
- /* FIXME: combos, player2 */\r
+ /* FIXME: player2 */\r
allActions[0] = in_update();\r
-#else\r
- for (i = 0; i < 32; i++)\r
- {\r
- if (keys2 & (1 << i))\r
- {\r
- int pl, acts = currentConfig.KeyBinds[i];\r
- if (!acts) continue;\r
- pl = (acts >> 16) & 1;\r
- if (kb_combo_keys & (1 << i))\r
- {\r
- int u = i+1, acts_c = acts & kb_combo_acts;\r
- // let's try to find the other one\r
- if (acts_c) {\r
- for (; u < 32; u++)\r
- if ( (keys2 & (1 << u)) && (currentConfig.KeyBinds[u] & acts_c) ) {\r
- allActions[pl] |= acts_c & currentConfig.KeyBinds[u];\r
- keys2 &= ~((1 << i) | (1 << u));\r
- break;\r
- }\r
- }\r
- // add non-combo actions if combo ones were not found\r
- if (!acts_c || u == 32)\r
- allActions[pl] |= acts & ~kb_combo_acts;\r
- } else {\r
- allActions[pl] |= acts;\r
- }\r
- }\r
- }\r
-#endif\r
\r
PicoPad[0] = allActions[0] & 0xfff;\r
PicoPad[1] = allActions[1] & 0xfff;\r
scaling_update();\r
Pico.m.dirtyPal = 1;\r
oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;\r
- emu_findKeyBindCombos();\r
\r
// pal/ntsc might have changed, reset related stuff\r
target_fps = Pico.m.pal ? 50 : 60;\r
#define IN_PREFIX "gp2x:"
#define IN_GP2X_NBUTTONS 32
+/* note: in_gp2x hadles combos (if 2 btns have the same bind,
+ * both must be pressed for action to happen) */
+static int in_gp2x_combo_keys = 0;
+static int in_gp2x_combo_acts = 0;
+
extern volatile unsigned short *gp2x_memregs; /* from minimal library rlyeh */
enum { BTN_UP = 0, BTN_LEFT = 2, BTN_DOWN = 4, BTN_RIGHT = 6,
static void in_gp2x_probe(void)
{
- in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1);
+ in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, 1);
}
static int in_gp2x_get_bind_count(void)
/* returns bitfield of binds of pressed buttons */
int in_gp2x_update(void *drv_data, int *binds)
{
- int i, value, ret = 0;
+ int i, keys, ret = 0;
+
+ keys = in_gp2x_get_gpio_bits();
- value = in_gp2x_get_gpio_bits();
+ if (keys & in_gp2x_combo_keys)
+ return in_combos_do(keys, binds, BTN_PUSH, in_gp2x_combo_keys, in_gp2x_combo_acts);
- for (i = 0; value; i++) {
- if (value & 1)
+ for (i = 0; keys; i++) {
+ if (keys & 1)
ret |= binds[i];
- value >>= 1;
+ keys >>= 1;
}
return ret;
count++;
}
+ in_combos_find(binds, BTN_PUSH, &in_gp2x_combo_keys, &in_gp2x_combo_acts);
+
return count;
}
{
in_drv_t *drv = vdrv;
+ in_gp2x_combo_keys = in_gp2x_combo_acts = 0;
+
drv->prefix = in_gp2x_prefix;
drv->probe = in_gp2x_probe;
drv->get_bind_count = in_gp2x_get_bind_count;
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);
+ in_register(name, IN_DRVID_EVDEV, fd, dev, 0);
continue;
skip:
case KEY_RIGHT: return PBTN_RIGHT;
case KEY_ENTER:
case BTN_A:
- case BTN_TRIGGER: return PBTN_MOK;
+ case BTN_TRIGGER:
+ return PBTN_MOK;
case KEY_ESC:
case BTN_B:
- case BTN_THUMB: return PBTN_MBACK;
- case KEY_MENU: return PBTN_MENU;
+ case BTN_THUMB:
+ return PBTN_MBACK;
+ case KEY_MENU:
+ return PBTN_MENU;
+ case KEY_LEFTBRACE:
+ return PBTN_L;
+ case KEY_RIGHTBRACE:
+ return PBTN_R;
default: return 0;
}
}
#define CASE_SENSITIVE_FS 1 // CS filesystem
#define DONT_OPEN_MANY_FILES 0
#define REDUCE_IO_CALLS 0
-#define SIMPLE_WRITE_SOUND 0
#define SCREEN_SIZE_FIXED 0
#define SCREEN_WIDTH 320
vidResetMode();\r
Pico.m.dirtyPal = 1;\r
oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;\r
- emu_findKeyBindCombos();\r
\r
// pal/ntsc might have changed, reset related stuff\r
target_fps = Pico.m.pal ? 50 : 60;\r
static unsigned int prevEvents = 0;
int i;
+ /* FIXME: port to input fw */
keys = psp_pad_read(0);
if (keys & PSP_CTRL_HOME)
sceDisplayWaitVblankStart();
keys &= CONFIGURABLE_KEYS;
- for (i = 0; i < 32; i++)
- {
- if (keys & (1 << i))
- {
- int pl, acts = currentConfig.KeyBinds[i];
- if (!acts) continue;
- pl = (acts >> 16) & 1;
- if (kb_combo_keys & (1 << i))
- {
- int u = i+1, acts_c = acts & kb_combo_acts;
- // let's try to find the other one
- if (acts_c) {
- for (; u < 32; u++)
- if ( (keys & (1 << u)) && (currentConfig.KeyBinds[u] & acts_c) ) {
- allActions[pl] |= acts_c & currentConfig.KeyBinds[u];
- keys &= ~((1 << i) | (1 << u));
- break;
- }
- }
- // add non-combo actions if combo ones were not found
- if (!acts_c || u == 32)
- allActions[pl] |= acts & ~kb_combo_acts;
- } else {
- allActions[pl] |= acts;
- }
- }
- }
-
PicoPad[0] = allActions[0] & 0xfff;
PicoPad[1] = allActions[1] & 0xfff;
clearArea(1);
Pico.m.dirtyPal = 1;
oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;
- emu_findKeyBindCombos();
// pal/ntsc might have changed, reset related stuff
target_fps = Pico.m.pal ? 50 : 60;