cdrom: partially implement attenuation
[pcsx_rearmed.git] / frontend / common / input.c
index 7bbb39c..a91de8d 100644 (file)
@@ -41,7 +41,7 @@ typedef struct
 
 static in_drv_t in_drivers[IN_DRVID_COUNT];
 static in_dev_t in_devices[IN_MAX_DEVS];
-static int in_dev_count = 0;
+static int in_dev_count = 0;           /* probed + bind devices */
 static int in_have_async_devs = 0;
 static int menu_key_state = 0;
 static int menu_last_used_dev = 0;
@@ -64,12 +64,17 @@ static int *in_alloc_binds(int drv_id, int key_count)
        return binds;
 }
 
-static void in_free(in_dev_t *dev)
+static void in_unprobe(in_dev_t *dev)
 {
        if (dev->probed)
                DRV(dev->drv_id).free(dev->drv_data);
        dev->probed = 0;
        dev->drv_data = NULL;
+}
+
+static void in_free(in_dev_t *dev)
+{
+       in_unprobe(dev);
        free(dev->name);
        dev->name = NULL;
        free(dev->binds);
@@ -223,8 +228,11 @@ void in_probe(void)
        int i;
 
        in_have_async_devs = 0;
+       menu_key_state = 0;
+       menu_last_used_dev = 0;
+
        for (i = 0; i < in_dev_count; i++)
-               in_devices[i].probed = 0;
+               in_unprobe(&in_devices[i]);
 
        for (i = 1; i < IN_DRVID_COUNT; i++)
                in_drivers[i].probe();
@@ -368,6 +376,12 @@ int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms)
                if (result >= 0)
                        break;
 
+               if (result == -2) {
+                       lprintf("input: \"%s\" errored out, removing.\n", in_devices[dev_id].name);
+                       in_unprobe(&in_devices[dev_id]);
+                       break;
+               }
+
                if (timeout_ms >= 0) {
                        unsigned int ticks2 = plat_get_ticks_ms();
                        timeout_ms -= ticks2 - ticks;
@@ -677,22 +691,39 @@ int in_bind_key(int dev_id, int keycode, int mask, int bind_type, int force_unbi
        return 0;
 }
 
-void in_unbind_all(int dev_id, int act_mask, int bind_type)
+/*
+ * Unbind act_mask on binds with type bind_type
+ * - if dev_id_ < 0, affects all devices
+ *   else only affects dev_id_
+ * - if act_mask == -1, unbind all keys
+ *   else only actions in mask
+ */
+void in_unbind_all(int dev_id_, int act_mask, int bind_type)
 {
+       int dev_id = 0, dev_last = IN_MAX_DEVS - 1;
        int i, count;
        in_dev_t *dev;
 
-       if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT)
+       if (dev_id_ >= 0)
+               dev_id = dev_last = dev_id_;
+
+       if (bind_type >= IN_BINDTYPE_COUNT)
                return;
 
-       dev = &in_devices[dev_id];
-       count = dev->key_count;
+       for (; dev_id <= dev_last; dev_id++) {
+               dev = &in_devices[dev_id];
+               count = dev->key_count;
 
-       if (dev->binds == NULL)
-               return;
+               if (dev->binds == NULL)
+                       continue;
 
-       for (i = 0; i < count; i++)
-               dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask;
+               if (act_mask != -1) {
+                       for (i = 0; i < count; i++)
+                               dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask;
+               }
+               else
+                       memset(dev->binds, 0, sizeof(dev->binds[0]) * count * IN_BINDTYPE_COUNT);
+       }
 }
 
 /* returns device id, or -1 on error */
@@ -738,7 +769,7 @@ 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].key_names = DRV(drv_id).get_key_names(&in_devices[i].key_count);
        in_devices[i].drv_id = drv_id;
 
        if (i + 1 > in_dev_count)
@@ -747,32 +778,6 @@ int in_config_parse_dev(const char *name)
        return i;
 }
 
-/*
- * To reduce size of game specific configs, default binds are not saved.
- * So we mark default binds in in_config_start(), override them in in_config_bind_key(),
- * and restore whatever default binds are left in in_config_end().
- */
-void in_config_start(void)
-{
-       int i;
-
-       /* mark all default binds, so they get overwritten by func below */
-       for (i = 0; i < IN_MAX_DEVS; i++) {
-               int n, count, *binds, *def_binds;
-
-               binds = in_devices[i].binds;
-               if (binds == NULL)
-                       continue;
-
-               count = in_devices[i].key_count;
-               def_binds = binds + count * IN_BINDTYPE_COUNT;
-
-               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 acts, int bind_type)
 {
        in_dev_t *dev;
@@ -795,7 +800,6 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type)
                        dev->binds = in_alloc_binds(dev->drv_id, dev->key_count);
                        if (dev->binds == NULL)
                                return -1;
-                       in_config_start();
                }
 
                kc = -1;
@@ -835,37 +839,21 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type)
        return 0;
 }
 
-void in_config_end(void)
+void in_clean_binds(void)
 {
        int i;
 
        for (i = 0; i < IN_MAX_DEVS; i++) {
-               int n, t, ret, count, *binds, *def_binds;
+               int ret, count, *binds, *def_binds;
                in_dev_t *dev = &in_devices[i];
 
-               if (dev->binds == NULL)
+               if (dev->binds == NULL || dev->drv_data == NULL)
                        continue;
 
                count = dev->key_count;
                binds = dev->binds;
                def_binds = binds + count * IN_BINDTYPE_COUNT;
 
-               for (n = 0; n < count; n++) {
-                       int is_default = 1;
-                       for (t = 0; t < IN_BINDTYPE_COUNT; t++)
-                               if (binds[IN_BIND_OFFS(n, t)] == -1)
-                                       binds[IN_BIND_OFFS(n, t)] = 0;
-                               else
-                                       is_default = 0;
-
-                       if (is_default)
-                               for (t = 0; t < IN_BINDTYPE_COUNT; t++)
-                                       binds[IN_BIND_OFFS(n, t)] = def_binds[IN_BIND_OFFS(n, t)];
-               }
-
-               if (dev->drv_data == NULL)
-                       continue;
-
                ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds, def_binds);
                if (ret == 0) {
                        /* no useable binds */
@@ -893,7 +881,8 @@ void in_debug_dump(void)
 
 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 const char * const *
+            in_def_get_key_names(int *count) { return NULL; }
 static void in_def_get_def_binds(int *binds) {}
 static int  in_def_clean_binds(void *drv_data, int *b, int *db) { return 0; }
 static int  in_def_get_config(void *drv_data, int what, int *val) { return -1; }
@@ -915,7 +904,7 @@ void in_init(void)
                in_drivers[i].prefix = "none:";
                in_drivers[i].probe = in_def_probe;
                in_drivers[i].free = in_def_free;
-               in_drivers[i].get_bind_count = in_def_get_bind_count;
+               in_drivers[i].get_key_names = in_def_get_key_names;
                in_drivers[i].get_def_binds = in_def_get_def_binds;
                in_drivers[i].clean_binds = in_def_clean_binds;
                in_drivers[i].get_config = in_def_get_config;