Beispiel #1
0
QWidget *UserBindsPage::widget()
{
   unsigned p, retro_id;
   unsigned max_users    = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
   QWidget *widget       = new QWidget;
   QGridLayout *layout   = new QGridLayout;
   QComboBox *userCombo  = new QComboBox;
   QStackedWidget *stack = new QStackedWidget;

   for (p = 0; p < max_users; p++)
   {
      userCombo->addItem(QString::number(p));

      QWidget *uWidget = new QWidget();
      FormLayout *form = new FormLayout();

      for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 20; retro_id++)
      {
         char descriptor[300];
         const struct retro_keybind *keybind   = 
            &input_config_binds[p][retro_id];
         const struct retro_keybind *auto_bind = 
            (const struct retro_keybind*)
            input_config_get_bind_auto(p, retro_id);

         input_config_get_bind_string(descriptor,
            keybind, auto_bind, sizeof(descriptor));

         const struct retro_keybind *keyptr =
            &input_config_binds[p][retro_id];

         QString label = msg_hash_to_str(keyptr->enum_idx);

         form->addRow(QString(msg_hash_to_str(keyptr->enum_idx)),
               new QPushButton(QString(descriptor)));
      }

      uWidget->setLayout(form);

      stack->addWidget(uWidget);
   }

   connect(userCombo, SIGNAL(activated(int)),
         stack, SLOT(setCurrentIndex(int)));

   layout->addWidget(userCombo, 0, 0);
   layout->addWidget(stack, 1, 0);

   widget->setLayout(layout);

   return widget;
}
static bool menu_input_key_bind_poll_find_trigger(
      struct menu_bind_state *state,
      struct menu_bind_state *new_state)
{
   unsigned i;
   unsigned max_users   = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));

   if (!state || !new_state)
      return false;

   for (i = 0; i < max_users; i++)
   {
      if (!menu_input_key_bind_poll_find_trigger_pad(
               state, new_state, i))
         continue;

      return true;
   }

   return false;
}
Beispiel #3
0
bool input_autoconfigure_connect(
      const char *name,
      const char *display_name,
      const char *driver,
      unsigned idx,
      unsigned vid,
      unsigned pid)
{
   unsigned i;
   retro_task_t         *task = task_init();
   autoconfig_params_t *state = (autoconfig_params_t*)calloc(1, sizeof(*state));
   settings_t       *settings = config_get_ptr();
   const char *dir_autoconf   = settings ? settings->paths.directory_autoconfig : NULL;
   bool autodetect_enable     = settings ? settings->bools.input_autodetect_enable : false;

   if (!task || !state || !autodetect_enable)
      goto error;

   if (!string_is_empty(name))
      state->name                 = strdup(name);

   if (!string_is_empty(dir_autoconf))
      state->autoconfig_directory = strdup(dir_autoconf);

   state->idx                     = idx;
   state->vid                     = vid;
   state->pid                     = pid;
   state->max_users               = *(
         input_driver_get_uint(INPUT_ACTION_MAX_USERS));

   input_autoconfigure_override_handler(state);

   if (!string_is_empty(state->name))
         input_config_set_device_name(state->idx, state->name);
   input_config_set_pid(state->idx, state->pid);
   input_config_set_vid(state->idx, state->vid);

   for (i = 0; i < RARCH_BIND_LIST_END; i++)
   {
      input_autoconf_binds[state->idx][i].joykey           = NO_BTN;
      input_autoconf_binds[state->idx][i].joyaxis          = AXIS_NONE;
      if (
          !string_is_empty(input_autoconf_binds[state->idx][i].joykey_label))
         free(input_autoconf_binds[state->idx][i].joykey_label);
      if (
          !string_is_empty(input_autoconf_binds[state->idx][i].joyaxis_label))
         free(input_autoconf_binds[state->idx][i].joyaxis_label);
      input_autoconf_binds[state->idx][i].joykey_label      = NULL;
      input_autoconf_binds[state->idx][i].joyaxis_label     = NULL;
   }

   input_autoconfigured[state->idx] = false;

   task->state                      = state;
   task->handler                    = input_autoconfigure_connect_handler;

   task_queue_push(task);

   return true;

error:
   if (state)
   {
      input_autoconfigure_params_free(state);
      free(state);
   }
   if (task)
      free(task);

   return false;
}
/**
 * input_remapping_save_file:
 * @path                     : Path to remapping file (relative path).
 *
 * Saves remapping values to file.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool input_remapping_save_file(const char *path)
{
   bool ret;
   unsigned i, j, k;
   size_t path_size                  = PATH_MAX_LENGTH * sizeof(char);
   char *buf                         = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *remap_file                  = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   config_file_t               *conf = NULL;
   unsigned max_users                = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
   settings_t              *settings = config_get_ptr();

   buf[0] = remap_file[0]            = '\0';

   fill_pathname_join(buf, settings->paths.directory_input_remapping,
         path, path_size);

   fill_pathname_noext(remap_file, buf, ".rmp", path_size);

   free(buf);

   conf = config_file_new(remap_file);

   if (!conf)
   {
      conf = config_file_new(NULL);
      if (!conf)
      {
         free(remap_file);
         return false;
      }
   }

   for (i = 0; i < max_users; i++)
   {
      char s1[64], s2[64], s3[64];
      char btn_ident[RARCH_FIRST_CUSTOM_BIND][128]       = {{0}};
      char key_ident[RARCH_FIRST_CUSTOM_BIND][128]       = {{0}};
      char stk_ident[8][128]                             = {{0}};

      char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = {
         "b", "y", "select", "start",
         "up", "down", "left", "right",
         "a", "x", "l", "r", "l2", "r2",
         "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };

      s1[0] = '\0';
      s2[0] = '\0';

      snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
      snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
      snprintf(s3, sizeof(s1), "input_player%u_stk", i + 1);

      for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
      {

         if(j < RARCH_FIRST_CUSTOM_BIND)
         {
            fill_pathname_join_delim(btn_ident[j], s1,
               key_strings[j], '_', sizeof(btn_ident[j]));
            fill_pathname_join_delim(key_ident[j], s2,
               key_strings[j], '_', sizeof(btn_ident[j]));

            /* only save values that have been modified */
            if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED)
               config_set_int(conf, btn_ident[j], settings->uints.input_remap_ids[i][j]);
            else if (settings->uints.input_remap_ids[i][j] != j && 
                     settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED)
               config_set_int(conf, btn_ident[j], -1);
            else
               config_unset(conf,btn_ident[j]);

            if (settings->uints.input_keymapper_ids[i][j] != RETROK_UNKNOWN)
               config_set_int(conf, key_ident[j], 
                  settings->uints.input_keymapper_ids[i][j]);
         }
         else
         {
            k = j - RARCH_FIRST_CUSTOM_BIND;
            fill_pathname_join_delim(stk_ident[k], s3,
               key_strings[j], '_', sizeof(stk_ident[k]));
            if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED)
               config_set_int(conf, stk_ident[k], 
                  settings->uints.input_remap_ids[i][j]);
            else if(settings->uints.input_remap_ids[i][j] != j && 
               settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED)
               config_set_int(conf, stk_ident[k], 
                  -1);
            else
               config_unset(conf, stk_ident[k]);
         }
      }
      snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
      config_set_int(conf, s1, input_config_get_device(i));
      snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1);
      config_set_int(conf, s1, settings->uints.input_analog_dpad_mode[i]);
   }

   ret = config_file_write(conf, remap_file);
   config_file_free(conf);

   free(remap_file);
   return ret;
}
void input_mapper_poll(input_mapper_t *handle)
{
   unsigned i, j;
   input_bits_t current_input;
   settings_t *settings                       = config_get_ptr();
   unsigned max_users                         =
      *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
   bool key_event[RARCH_CUSTOM_BIND_LIST_END] = { false };
#ifdef HAVE_OVERLAY
   bool poll_overlay = input_overlay_is_alive(overlay_ptr) ? true : false;
#endif

#ifdef HAVE_MENU
   if (menu_driver_is_alive())
      return;
#endif

   memset(handle->keys, 0, sizeof(handle->keys));

   for (i = 0; i < max_users; i++)
   {
      unsigned device  = settings->uints.input_libretro_device[i];
      device          &= RETRO_DEVICE_MASK;

      switch (device)
      {
            /* keyboard to gamepad remapping */
         case RETRO_DEVICE_KEYBOARD:
            BIT256_CLEAR_ALL_PTR(&current_input);
            input_get_state_for_port(settings, i, &current_input);
            for (j = 0; j < RARCH_CUSTOM_BIND_LIST_END; j++)
            {
               unsigned remap_button         = 
                  settings->uints.input_keymapper_ids[i][j];
               bool remap_valid              = remap_button != RETROK_UNKNOWN;

               if (remap_valid)
               {
                  unsigned current_button_value = BIT256_GET(current_input, j);

                  if ((current_button_value == 1) && (j != remap_button))
                  {
                     MAPPER_SET_KEY (handle,
                           remap_button);
                     input_keyboard_event(true,
                           remap_button,
                           0, 0, RETRO_DEVICE_KEYBOARD);
                     key_event[j] = true;
                  }
                  /* key_event tracks if a key is pressed for ANY PLAYER, so we must check 
                     if the key was used by any player before releasing */
                  else if (!key_event[j])
                  {
                     input_keyboard_event(false,
                           remap_button,
                           0, 0, RETRO_DEVICE_KEYBOARD);
                  }
               }
            }
            break;

            /* gamepad remapping */
         case RETRO_DEVICE_JOYPAD:
         case RETRO_DEVICE_ANALOG:
            /* this loop iterates on all users and all buttons, 
             * and checks if a pressed button is assigned to any 
             * other button than the default one, then it sets 
             * the bit on the mapper input bitmap, later on the 
             * original input is cleared in input_state */
            BIT256_CLEAR_ALL(handle->buttons[i]);
            BIT256_CLEAR_ALL_PTR(&current_input);

            for (j = 0; j < 8; j++)
               handle->analog_value[i][j] = 0;

            input_get_state_for_port(settings, i, &current_input);

            for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
            {
               bool remap_valid;
               unsigned remap_button;
               unsigned current_button_value = BIT256_GET(current_input, j);
#ifdef HAVE_OVERLAY
               if (poll_overlay && i == 0)
                  current_button_value |= input_overlay_key_pressed(overlay_ptr, j);
#endif

               remap_button                  =
                  settings->uints.input_remap_ids[i][j];
               remap_valid                   = (current_button_value == 1) &&
                  (j != remap_button) && (remap_button != RARCH_UNMAPPED);

               if (remap_valid)
               {
                  if (remap_button < RARCH_FIRST_CUSTOM_BIND)
                  {
                     BIT256_SET(handle->buttons[i], remap_button);
                  }
                  else if (remap_button >= RARCH_FIRST_CUSTOM_BIND)
                  {
                     int invert = 1;

                     if (remap_button % 2 != 0)
                        invert = -1;

                     handle->analog_value[i][
                        remap_button - RARCH_FIRST_CUSTOM_BIND] = 
                           32767 * invert;
                  }
               }
            }

            for (j = 0; j < 8; j++)
            {
               unsigned k                 = j + RARCH_FIRST_CUSTOM_BIND;
               int16_t current_axis_value = current_input.analogs[j];
               unsigned remap_axis        = 
                  settings->uints.input_remap_ids[i][k];

               if (
                     (abs(current_axis_value) > 
                     *input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD) * 32767) && 
                     (k != remap_axis)         &&
                     (remap_axis != RARCH_UNMAPPED)
                  )
               {
                  if (remap_axis < RARCH_FIRST_CUSTOM_BIND)
                  {
                     BIT256_SET(handle->buttons[i], remap_axis);
                  }
                  else
                  {
                     int invert = 1;

                     if (  (k % 2 == 0 && remap_axis % 2 != 0) || 
                           (k % 2 != 0 && remap_axis % 2 == 0)
                        )
                        invert = -1;

                     handle->analog_value[i][
                        remap_axis - RARCH_FIRST_CUSTOM_BIND] = 
                           current_axis_value * invert;
#if 0
                     RARCH_LOG("axis %d(%d) remapped to axis %d val %d\n",
                           j, k, 
                           remap_axis - RARCH_FIRST_CUSTOM_BIND,
                           current_axis_value);
#endif
                  }
               }

            }
            break;
         default:
            break;
      }
   }
}