stk-code_catmod/src/input/gamepad_config.cpp

302 lines
12 KiB
C++

//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "input/gamepad_config.hpp"
#include "io/xml_node.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <SKeyMap.h>
#include <assert.h>
using namespace irr;
GamepadConfig::GamepadConfig( const std::string &name,
const int axis_count,
const int button_count )
: DeviceConfig()
{
setName(name);
m_axis_count = axis_count;
m_button_count = button_count;
m_deadzone = 4096;
m_is_analog = true;
m_desensitize = false;
setDefaultBinds();
detectType();
} // GamepadConfig
//------------------------------------------------------------------------------
GamepadConfig::GamepadConfig() : DeviceConfig()
{
m_axis_count = 0;
m_button_count = 0;
m_deadzone = 4096;
m_is_analog = true;
m_desensitize = false;
setDefaultBinds();
} // GamepadConfig
//------------------------------------------------------------------------------
/** Loads this configuration from the given XML node.
* \param config The XML tree.
* \return False in case of an error.
*/
bool GamepadConfig::load(const XMLNode *config)
{
config->get("deadzone", &m_deadzone );
config->get("analog", &m_is_analog );
config->get("desensitize", &m_desensitize );
bool ok = DeviceConfig::load(config);
if(getName()=="")
{
Log::error("DeviceConfig", "Unnamed joystick in config file.");
return false;
}
detectType();
return ok;
} // load
// ----------------------------------------------------------------------------
/** Saves the configuration to a file. It writes the name for a gamepad
* config, saves the device specific parameters, and calls
* DeviceConfig::save() to save the rest.
* \param stream The stream to save to.
*/
void GamepadConfig::save (std::ofstream& stream)
{
stream << "<gamepad name =\"" << getName()
<< "\" deadzone=\"" << m_deadzone
<< "\" desensitize=\"" << m_desensitize
<< "\" analog=\"" << m_is_analog<<"\"\n";
stream << " ";
DeviceConfig::save(stream);
stream << "</gamepad>\n\n";
} // save
//-----------------------------------------------------------------------------
/** Try to identify a gamepad type (e.g. 'xbox'), so that better defaults
* and button names can be set. Atm the gamepad name is used.
*/
void GamepadConfig::detectType()
{
m_type = GP_UNIDENTIFIED;
std::string lower = StringUtils::toLowerCase(getName());
// xbox appears to be xbox 360
if(lower.find("xbox")!=std::string::npos)
{
m_type = GP_XBOX360;
return;
}
// The original xbox gamepad
if(lower.find("x-box")!=std::string::npos)
{
m_type = GP_XBOX_ORIGINAL;
return;
}
} // detectType
//------------------------------------------------------------------------------
void GamepadConfig::setDefaultBinds ()
{
setBinding(PA_STEER_LEFT, Input::IT_STICKMOTION, 0, Input::AD_NEGATIVE);
setBinding(PA_STEER_RIGHT, Input::IT_STICKMOTION, 0, Input::AD_POSITIVE);
setBinding(PA_ACCEL, Input::IT_STICKBUTTON, 0, Input::AD_NEGATIVE);
setBinding(PA_BRAKE, Input::IT_STICKBUTTON, 3, Input::AD_POSITIVE);
setBinding(PA_FIRE, Input::IT_STICKBUTTON, 1);
setBinding(PA_NITRO, Input::IT_STICKBUTTON, 4);
setBinding(PA_DRIFT, Input::IT_STICKBUTTON, 5);
setBinding(PA_RESCUE, Input::IT_STICKBUTTON, 8);
setBinding(PA_LOOK_BACK, Input::IT_STICKBUTTON, 6);
setBinding(PA_PAUSE_RACE, Input::IT_STICKBUTTON, 9);
setBinding(PA_MENU_UP, Input::IT_STICKMOTION, 1, Input::AD_NEGATIVE);
setBinding(PA_MENU_DOWN, Input::IT_STICKMOTION, 1, Input::AD_POSITIVE);
setBinding(PA_MENU_LEFT, Input::IT_STICKMOTION, 0, Input::AD_NEGATIVE);
setBinding(PA_MENU_RIGHT, Input::IT_STICKMOTION, 0, Input::AD_POSITIVE);
setBinding(PA_MENU_SELECT, Input::IT_STICKBUTTON, 0);
setBinding(PA_MENU_CANCEL, Input::IT_STICKBUTTON, 3);
} // setDefaultBinds
//------------------------------------------------------------------------------
core::stringw GamepadConfig::getBindingAsString(const PlayerAction action) const
{
// Default names if gamepad is not identified
if(m_type==GP_UNIDENTIFIED) return DeviceConfig::getBindingAsString(action);
const Binding &b = getBinding(action);
int id = b.getId();
Input::AxisDirection ad = b.getDirection();
Input::InputType it = b.getType();
// XBOX-360 controller
// -------------------
if(m_type==GP_XBOX_ORIGINAL)
{
// Handle only the differences to the xbox 360 controller, the rest
// will 'fall trough' to the xbox 360 code below
if(it==Input::IT_STICKBUTTON)
{
switch(id)
{
// I18N: Name of the black button on xbox controller
case 2: return _("Black");
case 3: return "X";
case 4: return "Y";
// I18N: Name of the white button on xbox controller
case 5: return _("White");
}
}
if(it==Input::IT_STICKMOTION)
{
switch(id)
{
// I18N: name of buttons on gamepads
case 2: return _("Left trigger");
// I18N: name of buttons on gamepads
case 3: return (ad == Input::AD_POSITIVE) ? _("Right thumb right")
// I18N: name of buttons on gamepads
: _("Right thumb left");
case // I18N: name of buttons on gamepads
4: return (ad == Input::AD_POSITIVE) ? _("Right thumb down")
// I18N: name of buttons on gamepads
: _("Right thumb up");
// I18N: name of buttons on gamepads
case 5: return _("Right trigger");
// I18N: name of buttons on gamepads
case 6: return (ad == Input::AD_POSITIVE) ? _("DPad right")
// I18N: name of buttons on gamepads
: _("DPad left");
// I18N: name of buttons on gamepads
case 7: return (ad == Input::AD_POSITIVE) ? _("DPad down")
// I18N: name of buttons on gamepads
: _("DPad up");
} // switch
} // stickmotion
} // xbox (original)
if(m_type==GP_XBOX360 || m_type==GP_XBOX_ORIGINAL)
{
if(it==Input::IT_STICKBUTTON)
{
switch(id)
{
case 0: return "A";
case 1: return "B";
case 2: return "X";
case 3: return "Y";
// I18N: name of buttons on gamepads
case 4: return _("Left bumper");
// I18N: name of buttons on gamepads
case 5: return _("Right bumper");
// I18N: name of buttons on gamepads
case 6: return _("Back");
// I18N: name of buttons on gamepads
case 7: return _("Start");
// I18N: name of buttons on gamepads
case 8: return _("Left thumb button");
// I18N: name of buttons on gamepads
case 9: return _("Right thumb button");
default: return DeviceConfig::getBindingAsString(action);
} // switch
} // if IT_STICKBUTTON
if(it==Input::IT_STICKMOTION)
{
switch(id)
{
// I18N: name of stick on gamepads
case 0: return (ad==Input::AD_POSITIVE) ? _("Left thumb right")
// I18N: name of stick on gamepads
: _("Left thumb left");
// I18N: name of stick on gamepads
case 1: return (ad==Input::AD_POSITIVE) ? _("Left thumb down")
// I18N: name of stick on gamepads
: _("Left thumb up");
// I18N: name of stick on gamepads
case 2: return (ad==Input::AD_POSITIVE) ? _("Left trigger")
// I18N: name of stick on gamepads
: _("Right trigger");
// I18N: name of stick on gamepads
case 3: return (ad==Input::AD_POSITIVE) ? _("Right thumb down")
// I18N: name of stick on gamepads
: _("Right thumb up");
// I18N: name of stick on gamepads
case 4: return (ad==Input::AD_POSITIVE) ? _("Right thumb right")
// I18N: name of stick on gamepads
: _("Right thumb left");
// I18N: name of buttons on gamepads
case Input::HAT_H_ID: return (ad == Input::AD_POSITIVE) ? _("DPad up")
// I18N: name of buttons on gamepads
: _("DPad down");
// I18N: name of buttons on gamepads
case Input::HAT_V_ID: return (ad == Input::AD_POSITIVE) ? _("DPad right")
// I18N: name of buttons on gamepads
: _("DPad left");
} // switch
}
} // xbox
// Offer a fallback ... just in case
Log::warn("GamepadConfig", "Missing action string for pad '%s' action '%d'",
getName().c_str(), action);
return DeviceConfig::getBindingAsString(action);
} // getBindingAsString
//------------------------------------------------------------------------------
/** Converts the configuration to a string.
*/
irr::core::stringw GamepadConfig::toString()
{
irr::core::stringw returnString = "";
returnString += getName().c_str();
returnString += "\n";
returnString += DeviceConfig::toString();
return returnString;
} // toString
//------------------------------------------------------------------------------
bool DeviceConfig::hasBindingFor(const int button_id) const
{
for (int n=0; n<PA_COUNT; n++)
{
if (m_bindings[n].getId() == button_id) return true;
}
return false;
} // hasBindingFor
//------------------------------------------------------------------------------
bool DeviceConfig::hasBindingFor(const int button_id, PlayerAction from,
PlayerAction to) const
{
for (int n=from; n<=to; n++)
{
if (m_bindings[n].getId() == button_id) return true;
}
return false;
} // hasBindingFor