void
JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
{
  Uint8 changed = hat_state ^ jhat.value;

  if (wait_for_joystick >= 0)
  {
    if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
      bind_joyhat(jhat.which, SDL_HAT_UP, Control(wait_for_joystick));

    if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
      bind_joyhat(jhat.which, SDL_HAT_DOWN, Control(wait_for_joystick));

    if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
      bind_joyhat(jhat.which, SDL_HAT_LEFT, Control(wait_for_joystick));

    if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
      bind_joyhat(jhat.which, SDL_HAT_RIGHT, Control(wait_for_joystick));

    MenuStorage::get_joystick_options_menu()->update();
    wait_for_joystick = -1;
  }
  else
  {
    if (changed & SDL_HAT_UP)
    {
      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP));
      if (it != joy_hat_map.end())
        set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
    }

    if (changed & SDL_HAT_DOWN)
    {
      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN));
      if (it != joy_hat_map.end())
        set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
    }

    if (changed & SDL_HAT_LEFT)
    {
      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT));
      if (it != joy_hat_map.end())
        set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
    }

    if (changed & SDL_HAT_RIGHT)
    {
      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT));
      if (it != joy_hat_map.end())
        set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
    }
  }

  hat_state = jhat.value;
}
void
JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat)
{
  Uint8 changed = hat_state ^ jhat.value;

  if (wait_for_joystick >= 0)
  {
    if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
      m_joystick_config.bind_joyhat(static_cast<JoystickConfig::JoyId>(jhat.which), SDL_HAT_UP, Controller::Control(wait_for_joystick));

    if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
      m_joystick_config.bind_joyhat(static_cast<JoystickConfig::JoyId>(jhat.which), SDL_HAT_DOWN, Controller::Control(wait_for_joystick));

    if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
      m_joystick_config.bind_joyhat(static_cast<JoystickConfig::JoyId>(jhat.which), SDL_HAT_LEFT, Controller::Control(wait_for_joystick));

    if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
      m_joystick_config.bind_joyhat(static_cast<JoystickConfig::JoyId>(jhat.which), SDL_HAT_RIGHT, Controller::Control(wait_for_joystick));

    MenuManager::instance().refresh();
    wait_for_joystick = -1;
  }
  else
  {
    if (changed & SDL_HAT_UP)
    {
      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP));
      if (it != m_joystick_config.joy_hat_map.end())
        set_joy_controls(it->second, (jhat.value & SDL_HAT_UP) != 0);
    }

    if (changed & SDL_HAT_DOWN)
    {
      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN));
      if (it != m_joystick_config.joy_hat_map.end())
        set_joy_controls(it->second, (jhat.value & SDL_HAT_DOWN) != 0);
    }

    if (changed & SDL_HAT_LEFT)
    {
      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT));
      if (it != m_joystick_config.joy_hat_map.end())
        set_joy_controls(it->second, (jhat.value & SDL_HAT_LEFT) != 0);
    }

    if (changed & SDL_HAT_RIGHT)
    {
      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT));
      if (it != m_joystick_config.joy_hat_map.end())
        set_joy_controls(it->second, (jhat.value & SDL_HAT_RIGHT) != 0);
    }
  }

  hat_state = jhat.value;
}
void
JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis)
{
  if (wait_for_joystick >= 0)
  {
    if (abs(jaxis.value) > m_joystick_config.dead_zone) {
      if (jaxis.value < 0)
        m_joystick_config.bind_joyaxis(static_cast<JoystickConfig::JoyId>(jaxis.which), -(jaxis.axis + 1), Controller::Control(wait_for_joystick));
      else
        m_joystick_config.bind_joyaxis(static_cast<JoystickConfig::JoyId>(jaxis.which), jaxis.axis + 1, Controller::Control(wait_for_joystick));

      MenuManager::instance().refresh();
      wait_for_joystick = -1;
    }
  }
  else
  {
    // Split the axis into left and right, so that both can be
    // mapped separately (needed for jump/down vs up/down)
    int axis = jaxis.axis + 1;

    auto left = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, -axis));
    auto right = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, axis));

    if(left == m_joystick_config.joy_axis_map.end()) {
      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
    } else {
      if (jaxis.value < -m_joystick_config.dead_zone)
        set_joy_controls(left->second,  true);
      else
        set_joy_controls(left->second, false);
    }

    if(right == m_joystick_config.joy_axis_map.end()) {
      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
    } else {
      if (jaxis.value > m_joystick_config.dead_zone)
        set_joy_controls(right->second, true);
      else
        set_joy_controls(right->second, false);
    }
  }
}
void
JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
{
  if (wait_for_joystick >= 0)
  {
    if (abs(jaxis.value) > dead_zone) {
      if (jaxis.value < 0)
        bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Control(wait_for_joystick));
      else
        bind_joyaxis(jaxis.which, jaxis.axis + 1, Control(wait_for_joystick));

      MenuStorage::get_joystick_options_menu()->update();
      wait_for_joystick = -1;
    }
  }
  else
  {
    // Split the axis into left and right, so that both can be
    // mapped separately (needed for jump/down vs up/down)
    int axis = jaxis.axis + 1;

    AxisMap::iterator left  = joy_axis_map.find(std::make_pair(jaxis.which, -axis));
    AxisMap::iterator right = joy_axis_map.find(std::make_pair(jaxis.which, axis));

    if(left == joy_axis_map.end()) {
      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
    } else {
      if (jaxis.value < -dead_zone)
        set_joy_controls(left->second,  true);
      else if (jaxis.value > dead_zone)
        set_joy_controls(left->second, false);
      else
        set_joy_controls(left->second, false);
    }

    if(right == joy_axis_map.end()) {
      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
    } else {
      if (jaxis.value < -dead_zone)
        set_joy_controls(right->second, false);
      else if (jaxis.value > dead_zone)
        set_joy_controls(right->second, true);
      else
        set_joy_controls(right->second, false);
    }
  }
}
void
JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
{
  if(wait_for_joystick >= 0) 
  {
    if(jbutton.state == SDL_PRESSED)
    {
      bind_joybutton(jbutton.which, jbutton.button, (Control)wait_for_joystick);
      MenuStorage::get_joystick_options_menu()->update();
      reset();
      wait_for_joystick = -1;
    }
  } 
  else 
  {
    ButtonMap::iterator i = joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
    if(i == joy_button_map.end()) {
      log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
    } else {
      set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
    }
  }
}
void
JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
{
  if(wait_for_joystick >= 0)
  {
    if(jbutton.state == SDL_PRESSED)
    {
      m_joystick_config.bind_joybutton(static_cast<JoystickConfig::JoyId>(jbutton.which), jbutton.button, static_cast<Controller::Control>(wait_for_joystick));
      MenuManager::instance().refresh();
      parent->reset();
      wait_for_joystick = -1;
    }
  }
  else
  {
    auto i = m_joystick_config.joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
    if(i == m_joystick_config.joy_button_map.end()) {
      log_debug << "Unmapped joybutton " << static_cast<int>(jbutton.button) << " pressed" << std::endl;
    } else {
      set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
    }
  }
}