Moved KeyboardConfig and GamepadConfig from DeviceConfig to their

own separate files.
This commit is contained in:
hiker 2014-10-27 13:26:52 +11:00
parent e8f509eefe
commit 99f69f4070
18 changed files with 555 additions and 363 deletions

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -24,10 +24,10 @@
#include <SKeyMap.h>
/** Convert thjis binding to XML attributes. The full XML node is actually
/** Convert this binding to XML attributes. The full XML node is actually
* written by device_config, so we only have to add the attributes here.
*/
void Binding::serialize(std::ofstream& stream) const
void Binding::save(std::ofstream& stream) const
{
stream << "id=\"" << m_id << "\" "
<< "event=\"" << m_type << "\" "
@ -39,7 +39,7 @@ void Binding::serialize(std::ofstream& stream) const
stream << "direction=\"" << m_dir << "\" ";
stream << "range=\"" << m_range << "\" ";
}
} // serialize
} // save
// ----------------------------------------------------------------------------
bool Binding::load(const XMLNode *action)
@ -51,8 +51,10 @@ bool Binding::load(const XMLNode *action)
return false;
}
m_type = (Input::InputType)n;
core::stringw s;
m_character = 0;
// XMLNode only supports stringw, not wchar_t*
core::stringw s;
action->get("character", &s);
if(s.size()>0)
m_character = s[0];

View File

@ -64,7 +64,7 @@ public:
} // set
// ------------------------------------------------------------------------
void serialize (std::ofstream& stream) const;
void save(std::ofstream& stream) const;
bool load(const XMLNode *action);
irr::core::stringw getAsString() const;
};

View File

@ -28,25 +28,35 @@
using namespace irr;
//==== D E V I C E C O N F I G =================================================
DeviceConfig::DeviceConfig(DeviceConfigType type)
{
m_type = type;
m_enabled = true;
m_plugged = 0;
} // DeviceConfig
// ------------------------------------------------------------------------
/** Get a user-readable string describing the bound action.
*/
irr::core::stringw DeviceConfig::getBindingAsString (const PlayerAction action) const
{
irr::core::stringw returnString = "";
irr::core::stringw return_string = "";
if ((action < PA_COUNT) && (action >= 0))
{
returnString = m_bindings[action].getAsString();
return_string = m_bindings[action].getAsString();
}
return returnString;
}
return return_string;
} // getBindingAsString
//------------------------------------------------------------------------------
/** Get an internal unique string describing the bound action.
* \param action The action for which to get the string.
*/
irr::core::stringw DeviceConfig::getMappingIdString (const PlayerAction action) const
{
irr::core::stringw returnString = "";
irr::core::stringw return_string = "";
if ((action < PA_COUNT) && (action >= 0))
{
@ -58,71 +68,76 @@ irr::core::stringw DeviceConfig::getMappingIdString (const PlayerAction action)
switch (type)
{
case Input::IT_KEYBOARD:
returnString += "keyb_";
returnString += id;
return_string += "keyb_";
return_string += id;
break;
case Input::IT_STICKMOTION:
returnString += "stkmo_";
returnString += id;
returnString += "$";
returnString += dir;
returnString += "$";
returnString += range;
return_string += "stkmo_";
return_string += id;
return_string += "$";
return_string += dir;
return_string += "$";
return_string += range;
break;
case Input::IT_STICKBUTTON:
returnString += "stkbt_";
returnString += id;
return_string += "stkbt_";
return_string += id;
break;
case Input::IT_MOUSEMOTION:
returnString += "mousemo_";
returnString += id;
returnString += "$";
returnString += dir;
return_string += "mousemo_";
return_string += id;
return_string += "$";
return_string += dir;
break;
case Input::IT_MOUSEBUTTON:
returnString += "mousebtn_";
returnString += id;
return_string += "mousebtn_";
return_string += id;
break;
case Input::IT_NONE:
returnString += "none";
return_string += "none";
break;
default:
assert(false);
returnString += type;
returnString += "_";
returnString += id;
returnString += "$";
returnString += dir;
return_string += type;
return_string += "_";
return_string += id;
return_string += "$";
return_string += dir;
}
}
return returnString;
}
return return_string;
} // getMappingIdString
//------------------------------------------------------------------------------
irr::core::stringw DeviceConfig::toString ()
{
irr::core::stringw returnString = "";
irr::core::stringw return_string = "";
for (int n = 0; n < PA_COUNT; n++)
{
returnString += KartActionStrings[n].c_str();
returnString += ": ";
returnString += m_bindings[n].getAsString();
returnString += "\n";
return_string += KartActionStrings[n].c_str();
return_string += ": ";
return_string += m_bindings[n].getAsString();
return_string += "\n";
}
return returnString;
}
return return_string;
} // toString
//------------------------------------------------------------------------------
/** Sets the bindings for an action.
* \param action The action to be bound.
* \param type Input type (stick button, stick motion, ...).
* \param id An id for this binding.
* \param direction In which direction the stick is moved.
* \param
*/
void DeviceConfig::setBinding ( const PlayerAction action,
const Input::InputType type,
const int id,
@ -131,32 +146,46 @@ void DeviceConfig::setBinding ( const PlayerAction action,
wchar_t character)
{
m_bindings[action].set(type, id, direction, range, character);
}
} // setBinding
//------------------------------------------------------------------------------
// Don't call this directly unless you are KeyboardDevice or GamepadDevice
/** Searches for a game actions associated with the given input event.
* \note Don't call this directly unless you are KeyboardDevice or
* GamepadDevice.
* \param[out] action the result, only set if method returned true.
* \return whether finding an action associated to this input was
* successful.
*/
bool DeviceConfig::getGameAction(Input::InputType type,
const int id,
int* value, /* inout */
PlayerAction* action /* out */ )
{
return doGetAction(type, id, value, PA_FIRST_GAME_ACTION, PA_LAST_GAME_ACTION, action);
}
return doGetAction(type, id, value, PA_FIRST_GAME_ACTION,
PA_LAST_GAME_ACTION, action);
} // getGameAction
//------------------------------------------------------------------------------
// Don't call this directly unless you are KeyboardDevice or GamepadDevice
/** Searches for a game actions associated with the given input event.
* \note Don't call this directly unless you are KeyboardDevice or
* GamepadDevice.
* \param[out] action The result, only set if method returned true.
* \return Whether finding an action associated to this input
* was successful
*/
bool DeviceConfig::getMenuAction(Input::InputType type,
const int id,
int* value,
PlayerAction* action /* out */ )
{
return doGetAction(type, id, value, PA_FIRST_MENU_ACTION, PA_LAST_MENU_ACTION, action);
}
return doGetAction(type, id, value, PA_FIRST_MENU_ACTION,
PA_LAST_MENU_ACTION, action);
} // getMenuAction
//------------------------------------------------------------------------------
/** internal helper method for DeviceConfig::getGameAction and
* DeviceConfig::getMenuAction
*/
bool DeviceConfig::doGetAction(Input::InputType type,
const int id,
int* value, /* inout */
@ -211,21 +240,23 @@ bool DeviceConfig::doGetAction(Input::InputType type,
} // end for n
return success;
}
} // doGetAction
//------------------------------------------------------------------------------
void DeviceConfig::serialize (std::ofstream& stream)
/** Saves the configuration to a file.
* \param stream The stream to save to.
*/
void DeviceConfig::save (std::ofstream& stream)
{
for(int n = 0; n < PA_COUNT; n++) // Start at 0?
{
stream << " "
<< "<action "
<< "name=\"" << KartActionStrings[n] << "\" ";
m_bindings[n].serialize(stream);
m_bindings[n].save(stream);
stream << "/>\n";
}
} // serialize
} // save
//------------------------------------------------------------------------------
/** Reads a device configuration from input.xml.
@ -274,140 +305,3 @@ bool DeviceConfig::load(const XMLNode *config)
// ---------------------------------------------------------------------------
// KeyboardConfig & GamepadConfig classes really should be in a separate cpp
// file but they are so small that we'll just leave them here for now.
//==== K E Y B O A R D C O N F I G =============================================
void KeyboardConfig::serialize (std::ofstream& stream)
{
stream << "<keyboard>\n\n";
DeviceConfig::serialize(stream);
stream << "</keyboard>\n\n\n";
}
//------------------------------------------------------------------------------
void KeyboardConfig::setDefaultBinds()
{
setBinding(PA_NITRO, Input::IT_KEYBOARD, KEY_KEY_N);
setBinding(PA_ACCEL, Input::IT_KEYBOARD, KEY_UP);
setBinding(PA_BRAKE, Input::IT_KEYBOARD, KEY_DOWN);
setBinding(PA_STEER_LEFT, Input::IT_KEYBOARD, KEY_LEFT);
setBinding(PA_STEER_RIGHT, Input::IT_KEYBOARD, KEY_RIGHT);
setBinding(PA_DRIFT, Input::IT_KEYBOARD, KEY_KEY_V);
setBinding(PA_RESCUE, Input::IT_KEYBOARD, KEY_BACK);
setBinding(PA_FIRE, Input::IT_KEYBOARD, KEY_SPACE);
setBinding(PA_LOOK_BACK, Input::IT_KEYBOARD, KEY_KEY_B);
setBinding(PA_PAUSE_RACE, Input::IT_KEYBOARD, KEY_ESCAPE);
setBinding(PA_MENU_UP, Input::IT_KEYBOARD, KEY_UP);
setBinding(PA_MENU_DOWN, Input::IT_KEYBOARD, KEY_DOWN);
setBinding(PA_MENU_LEFT, Input::IT_KEYBOARD, KEY_LEFT);
setBinding(PA_MENU_RIGHT, Input::IT_KEYBOARD, KEY_RIGHT);
setBinding(PA_MENU_SELECT, Input::IT_KEYBOARD, KEY_RETURN);
setBinding(PA_MENU_CANCEL, Input::IT_KEYBOARD, KEY_BACK);
}
//------------------------------------------------------------------------------
KeyboardConfig::KeyboardConfig() : DeviceConfig(DEVICE_CONFIG_TYPE_KEYBOARD)
{
m_name = "Keyboard";
m_plugged = 1;
setDefaultBinds();
}
//==== G A M E P A D C O N F I G ===============================================
void GamepadConfig::serialize (std::ofstream& stream)
{
stream << "<gamepad name =\"" << m_name.c_str() << "\" enabled=\""
<< (m_enabled ? "true" : "false") << "\">\n\n";
DeviceConfig::serialize(stream);
stream << "</gamepad>\n\n\n";
}
//------------------------------------------------------------------------------
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_STICKMOTION, 1, Input::AD_NEGATIVE);
setBinding(PA_BRAKE, Input::IT_STICKMOTION, 1, Input::AD_POSITIVE);
setBinding(PA_FIRE, Input::IT_STICKBUTTON, 0);
setBinding(PA_NITRO, Input::IT_STICKBUTTON, 1);
setBinding(PA_DRIFT, Input::IT_STICKBUTTON, 2);
setBinding(PA_RESCUE, Input::IT_STICKBUTTON, 3);
setBinding(PA_LOOK_BACK, Input::IT_STICKBUTTON, 4);
setBinding(PA_PAUSE_RACE, Input::IT_STICKBUTTON, 5);
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);
}
//------------------------------------------------------------------------------
GamepadConfig::GamepadConfig ( const std::string &name,
const int axis_count,
const int button_count )
: DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
m_name = name;
m_axis_count = axis_count;
m_button_count = button_count;
m_plugged = 0;
setDefaultBinds();
}
//------------------------------------------------------------------------------
GamepadConfig::GamepadConfig(const XMLNode *config)
: DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
if(!config->get("name", &m_name))
Log::error("DeviceConfig", "Unnamed joystick in config file.");
config->get("enabled", &m_enabled);
m_plugged = 0;
setDefaultBinds();
}
//------------------------------------------------------------------------------
irr::core::stringw GamepadConfig::toString ()
{
irr::core::stringw returnString = "";
returnString += getName().c_str();
returnString += "\n";
returnString += DeviceConfig::toString();
return returnString;
}
//------------------------------------------------------------------------------
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;
}
//------------------------------------------------------------------------------
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;
}

View File

@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef DEVICE_CONFIG_HPP
#define DEVICE_CONFIG_HPP
#ifndef HEADER_DEVICE_CONFIG_HPP
#define HEADER_DEVICE_CONFIG_HPP
#include "input/binding.hpp"
#include "input/input.hpp"
@ -31,13 +31,6 @@
* \ingroup config
*/
enum DeviceConfigType
{
DEVICE_CONFIG_TYPE_GAMEPAD,
DEVICE_CONFIG_TYPE_KEYBOARD
};
//==== D E V I C E C O N F I G =================================================
/**
@ -46,143 +39,94 @@ enum DeviceConfigType
*/
class DeviceConfig : public NoCopy
{
public:
enum DeviceConfigType
{
DEVICE_CONFIG_TYPE_GAMEPAD,
DEVICE_CONFIG_TYPE_KEYBOARD
};
protected:
Binding m_bindings[PA_COUNT];
int m_plugged; //!< How many devices connected to the system which uses this config?
bool m_enabled; //!< If set to false, this device will be ignored. Currently for gamepads only
/** How many devices connected to the system which uses this config? */
int m_plugged;
/** If set to false, this device will be ignored.
* Currently for gamepads only. */
bool m_enabled;
/** Name of this configuratiom. */
std::string m_name;
/** Configuration type. */
DeviceConfigType m_type;
DeviceConfig(DeviceConfigType type)
{
m_type = type;
m_enabled = true;
}
DeviceConfig(DeviceConfigType type);
/**
* \brief internal helper method for DeviceConfig::getGameAction and DeviceConfig::getMenuAction
*/
bool doGetAction(Input::InputType type,
const int id,
int* value, /* inout */
const PlayerAction firstActionToCheck,
const PlayerAction lastActionToCheck,
PlayerAction* action /* out */ );
protected:
/** Those two classes need to be able to call getGameAction. */
friend class GamePadDevice;
friend class KeyboardDevice;
bool getGameAction(Input::InputType type,
const int id,
int* value, /* inout */
PlayerAction* action /* out */);
public:
std::string getName () const { return m_name; };
irr::core::stringw toString ();
DeviceConfigType getType () const { return m_type; }
/** Get a user-readable string describing the bound action */
irr::core::stringw toString();
bool hasBindingFor(const int buttonID) const;
bool hasBindingFor(const int buttonID, PlayerAction from,
PlayerAction to) const;
void setBinding(const PlayerAction action,
const Input::InputType type,
const int id,
Input::AxisDirection direction = Input::AD_NEUTRAL,
Input::AxisRange range = Input::AR_HALF,
wchar_t character=0);
bool getMenuAction(Input::InputType type,
const int id,
int* value,
PlayerAction* action /* out */);
irr::core::stringw getMappingIdString (const PlayerAction action) const;
irr::core::stringw getBindingAsString(const PlayerAction action) const;
/** Get an internal unique string describing the bound action */
irr::core::stringw getMappingIdString (const PlayerAction action) const;
virtual DeviceConfigType getType() const = 0;
virtual void save(std::ofstream& stream);
virtual bool load(const XMLNode *config);
// ------------------------------------------------------------------------
/** Returns the name for this device configuration. */
const std::string& getName() const { return m_name; };
void serialize (std::ofstream& stream);
bool load(const XMLNode *config);
// ------------------------------------------------------------------------
/** Increase ref counter. */
void setPlugged() { m_plugged++; }
void setBinding (const PlayerAction action,
const Input::InputType type,
const int id,
Input::AxisDirection direction = Input::AD_NEUTRAL,
Input::AxisRange range = Input::AR_HALF,
wchar_t character=0);
// ------------------------------------------------------------------------
/** Returns if this config is sed by any devices. */
bool isPlugged() const { return m_plugged > 0; }
void setPlugged () { m_plugged++; }
bool isPlugged () const { return m_plugged > 0; }
int getNumberOfDevices () const { return m_plugged; }
/**
* \brief Searches for a game actions associated with the given input event
* \note Don't call this directly unless you are KeyboardDevice or GamepadDevice
* \param[out] action the result, only set if method returned true
* \return whether finding an action associated to this input was successful
*/
bool getGameAction (Input::InputType type,
const int id,
int* value, /* inout */
PlayerAction* action /* out */);
/**
* \brief Searches for a game actions associated with the given input event
* \note Don't call this directly unless you are KeyboardDevice or GamepadDevice
* \param[out] action the result, only set if method returned true
* \return whether finding an action associated to this input was successful
*/
bool getMenuAction (Input::InputType type,
const int id,
int* value,
PlayerAction* action /* out */);
// ------------------------------------------------------------------------
/** Returns the number of devices using this configuration. */
int getNumberOfDevices() const { return m_plugged; }
// ------------------------------------------------------------------------
/** Returns the binding of a given index. */
Binding& getBinding (int i) {return m_bindings[i];}
bool hasBindingFor(const int buttonID) const;
bool hasBindingFor(const int buttonID, PlayerAction from, PlayerAction to) const;
// ------------------------------------------------------------------------
/** At this time only relevant for gamepads, keyboards are always enabled */
bool isEnabled() const { return m_enabled; }
void setEnabled(bool newValue) { m_enabled = newValue; }
};
//==== K E Y B O A R D C O N F I G =============================================
/**
* \brief specialisation of DeviceConfig for keyboard type devices
* \ingroup config
*/
class KeyboardConfig : public DeviceConfig
{
public:
void setDefaultBinds ();
void serialize (std::ofstream& stream);
KeyboardConfig ();
};
//==== G A M E P A D C O N F I G ===============================================
/**
* \brief specialisation of DeviceConfig for gamepad type devices
* \ingroup config
*/
class GamepadConfig : public DeviceConfig
{
private:
/** Number of axis this device has. */
int m_axis_count;
/** Number of buttons this device has. */
int m_button_count;
public:
irr::core::stringw toString ();
void serialize (std::ofstream& stream);
void setDefaultBinds ();
GamepadConfig (const XMLNode *config);
GamepadConfig (const std::string &name,
const int axis_count=0,
const int button_ount=0);
// ------------------------------------------------------------------------
/** Sets the number of buttons this device has. */
void setNumberOfButtons(int count) { m_button_count = count; }
// ------------------------------------------------------------------------
/** Sets the number of axis this device has. */
void setNumberOfAxis(int count) { m_axis_count = count; }
// ~GamepadConfig();
};
/** Sets this config to be enabled or disabled. */
void setEnabled(bool new_value) { m_enabled = new_value; }
}; // class DeviceConfig
#endif

View File

@ -136,7 +136,7 @@ bool DeviceManager::initialize()
addGamepad(gamepadDevice);
} // end for
if (created) serialize();
if (created) save();
return created;
} // initialize
@ -535,7 +535,7 @@ bool DeviceManager::load()
} // load
// -----------------------------------------------------------------------------
void DeviceManager::serialize()
void DeviceManager::save()
{
static std::string filepath = file_manager->getUserConfigFile(INPUT_FILE_NAME);
if(UserConfigParams::logMisc()) Log::info("Device manager","Serializing input.xml...");
@ -555,17 +555,17 @@ void DeviceManager::serialize()
for(unsigned int n=0; n<m_keyboard_configs.size(); n++)
{
m_keyboard_configs[n].serialize(configfile);
m_keyboard_configs[n].save(configfile);
}
for(unsigned int n=0; n<m_gamepad_configs.size(); n++)
{
m_gamepad_configs[n].serialize(configfile);
m_gamepad_configs[n].save(configfile);
}
configfile << "</input>\n";
configfile.close();
if(UserConfigParams::logMisc()) Log::info("Device manager","Serialization complete.");
} // serialize
} // save
// -----------------------------------------------------------------------------

View File

@ -20,7 +20,9 @@
#define DEVICE_MANAGER_HPP
#include "input/device_config.hpp"
#include "input/gamepad_config.hpp"
#include "input/input_device.hpp"
#include "input/keyboard_config.hpp"
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
@ -162,7 +164,7 @@ public:
void clearLatestUsedDevice();
InputDevice* getLatestUsedDevice();
bool initialize();
void serialize();
void save();
StateManager::ActivePlayer* getSinglePlayer() { return m_single_player; }
void setSinglePlayer(StateManager::ActivePlayer* p) { m_single_player = p; }

View File

@ -0,0 +1,136 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 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 <SKeyMap.h>
#include <assert.h>
using namespace irr;
GamepadConfig::GamepadConfig ( const std::string &name,
const int axis_count,
const int button_count )
: DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
m_name = name;
m_axis_count = axis_count;
m_button_count = button_count;
m_deadzone = 2000;
m_plugged = 0;
setDefaultBinds();
} // GamepadConfig
//------------------------------------------------------------------------------
GamepadConfig::GamepadConfig(const XMLNode *config)
: DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
if(!config->get("name", &m_name))
Log::error("DeviceConfig", "Unnamed joystick in config file.");
config->get("enabled", &m_enabled);
m_plugged = 0;
m_deadzone = 2000;
setDefaultBinds();
} // GamepadConfig(XMLNode)
//------------------------------------------------------------------------------
bool GamepadConfig::load(const XMLNode *config)
{
m_deadzone = 2000;
config->get("deadzone", &m_deadzone);
return DeviceConfig::load(config);
} // load
// ----------------------------------------------------------------------------
void GamepadConfig::save (std::ofstream& stream)
{
stream << "<gamepad name =\"" << m_name.c_str() << "\" enabled=\""
<< (m_enabled ? "true" : "false") << "\n";
stream << " deadzone=\""<<m_deadzone << "\">\n";
DeviceConfig::save(stream);
stream << "</gamepad>\n\n";
} // save
//------------------------------------------------------------------------------
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_STICKMOTION, 1, Input::AD_NEGATIVE);
setBinding(PA_BRAKE, Input::IT_STICKMOTION, 1, Input::AD_POSITIVE);
setBinding(PA_FIRE, Input::IT_STICKBUTTON, 0);
setBinding(PA_NITRO, Input::IT_STICKBUTTON, 1);
setBinding(PA_DRIFT, Input::IT_STICKBUTTON, 2);
setBinding(PA_RESCUE, Input::IT_STICKBUTTON, 3);
setBinding(PA_LOOK_BACK, Input::IT_STICKBUTTON, 4);
setBinding(PA_PAUSE_RACE, Input::IT_STICKBUTTON, 5);
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);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/** 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

View File

@ -0,0 +1,77 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 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.
#ifndef HEADER_GAMEPD_CONFIG_HPP
#define HEADER_GAMEPD_CONFIG_HPP
#include "input/binding.hpp"
#include "input/device_config.hpp"
#include "input/input.hpp"
#include "utils/no_copy.hpp"
#include <iosfwd>
#include <irrString.h>
#include <string>
//==== G A M E P A D C O N F I G ===============================================
/**
* \brief specialisation of DeviceConfig for gamepad type devices
* \ingroup config
*/
class GamepadConfig : public DeviceConfig
{
private:
/** Number of axis this device has. */
int m_axis_count;
/** Number of buttons this device has. */
int m_button_count;
int m_deadzone;
public:
irr::core::stringw toString ();
virtual void save(std::ofstream& stream);
void setDefaultBinds ();
GamepadConfig (const XMLNode *config);
GamepadConfig (const std::string &name,
const int axis_count=0,
const int button_ount=0);
virtual bool load(const XMLNode *config);
// ------------------------------------------------------------------------
/** Sets the number of buttons this device has. */
void setNumberOfButtons(int count) { m_button_count = count; }
// ------------------------------------------------------------------------
/** Sets the number of axis this device has. */
void setNumberOfAxis(int count) { m_axis_count = count; }
// ~GamepadConfig();
// ------------------------------------------------------------------------
/** Returns the type of this configuration. */
virtual DeviceConfig::DeviceConfigType getType() const
{
return DeviceConfig::DEVICE_CONFIG_TYPE_GAMEPAD;
} // getType
};
#endif

View File

@ -19,6 +19,7 @@
#include "input/gamepad_device.hpp"
#include "input/gamepad_config.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/player_controller.hpp"

View File

@ -21,6 +21,7 @@
#include "input/input_device.hpp"
class GamepadConfig;
/**
* \brief specialisation of Inputdevice for gamepad type devices
* \ingroup input

View File

@ -0,0 +1,74 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 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/keyboard_config.hpp"
#include "io/xml_node.hpp"
#include "utils/log.hpp"
#include <SKeyMap.h>
#include <assert.h>
using namespace irr;
// KeyboardConfig & GamepadConfig classes really should be in a separate cpp
// file but they are so small that we'll just leave them here for now.
//==== K E Y B O A R D C O N F I G =============================================
void KeyboardConfig::save(std::ofstream& stream)
{
stream << "<keyboard>\n\n";
DeviceConfig::save(stream);
stream << "</keyboard>\n\n\n";
} // save
//------------------------------------------------------------------------------
void KeyboardConfig::setDefaultBinds()
{
setBinding(PA_NITRO, Input::IT_KEYBOARD, KEY_KEY_N);
setBinding(PA_ACCEL, Input::IT_KEYBOARD, KEY_UP);
setBinding(PA_BRAKE, Input::IT_KEYBOARD, KEY_DOWN);
setBinding(PA_STEER_LEFT, Input::IT_KEYBOARD, KEY_LEFT);
setBinding(PA_STEER_RIGHT, Input::IT_KEYBOARD, KEY_RIGHT);
setBinding(PA_DRIFT, Input::IT_KEYBOARD, KEY_KEY_V);
setBinding(PA_RESCUE, Input::IT_KEYBOARD, KEY_BACK);
setBinding(PA_FIRE, Input::IT_KEYBOARD, KEY_SPACE);
setBinding(PA_LOOK_BACK, Input::IT_KEYBOARD, KEY_KEY_B);
setBinding(PA_PAUSE_RACE, Input::IT_KEYBOARD, KEY_ESCAPE);
setBinding(PA_MENU_UP, Input::IT_KEYBOARD, KEY_UP);
setBinding(PA_MENU_DOWN, Input::IT_KEYBOARD, KEY_DOWN);
setBinding(PA_MENU_LEFT, Input::IT_KEYBOARD, KEY_LEFT);
setBinding(PA_MENU_RIGHT, Input::IT_KEYBOARD, KEY_RIGHT);
setBinding(PA_MENU_SELECT, Input::IT_KEYBOARD, KEY_RETURN);
setBinding(PA_MENU_CANCEL, Input::IT_KEYBOARD, KEY_BACK);
}
//------------------------------------------------------------------------------
KeyboardConfig::KeyboardConfig() : DeviceConfig(DEVICE_CONFIG_TYPE_KEYBOARD)
{
m_name = "Keyboard";
m_plugged = 1;
setDefaultBinds();
}

View File

@ -0,0 +1,55 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 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.
#ifndef HEADER_KEYBOARD_CONFIG_HPP
#define HEADER_KEYBOARD_CONFIG_HPP
#include "input/binding.hpp"
#include "input/device_config.hpp"
#include "input/input.hpp"
#include "utils/no_copy.hpp"
#include <iosfwd>
#include <irrString.h>
#include <string>
//==== K E Y B O A R D C O N F I G =============================================
/**
* \brief specialisation of DeviceConfig for keyboard type devices
* \ingroup config
*/
class KeyboardConfig : public DeviceConfig
{
public:
void setDefaultBinds ();
virtual void save(std::ofstream& stream);
KeyboardConfig ();
// ------------------------------------------------------------------------
/** Returns the type of this configuration. */
virtual DeviceConfigType getType() const
{
return DEVICE_CONFIG_TYPE_GAMEPAD;
} // getType
};
#endif

View File

@ -19,6 +19,7 @@
#include "input/keyboard_device.hpp"
#include "input/keyboard_config.hpp"
// ----------------------------------------------------------------------------
KeyboardDevice::KeyboardDevice(KeyboardConfig *configuration)
{

View File

@ -22,6 +22,8 @@
#include "input/input_device.hpp"
class KeyboardConfig;
/**
* \brief specialisation of InputDevice for keyboard type devices
* \ingroup input

View File

@ -166,7 +166,7 @@ GUIEngine::EventPropagation AddDeviceDialog::processEvent
else if (eventSource == "addkeyboard")
{
input_manager->getDeviceManager()->addEmptyKeyboard();
input_manager->getDeviceManager()->serialize();
input_manager->getDeviceManager()->save();
ModalDialog::dismiss();
((OptionsScreenInput*)GUIEngine::getCurrentScreen())->rebuildDeviceList();

View File

@ -88,8 +88,8 @@ void OptionsScreenInput2::init()
tabBar->getRibbonChildren()[3].setTooltip( _("Players") );
ButtonWidget* deleteBtn = getWidget<ButtonWidget>("delete");
if (m_config->getType() != DEVICE_CONFIG_TYPE_KEYBOARD)
ButtonWidget* delete_button = getWidget<ButtonWidget>("delete");
if (m_config->getType() != DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD)
{
core::stringw label = (m_config->isEnabled()
? //I18N: button to disable a gamepad configuration
@ -101,34 +101,34 @@ void OptionsScreenInput2::init()
// from the original value
core::dimension2d<u32> size =
GUIEngine::getFont()->getDimension(label.c_str());
const int needed = size.Width + deleteBtn->getWidthNeededAroundLabel();
if (deleteBtn->m_w < needed) deleteBtn->m_w = needed;
const int needed = size.Width + delete_button->getWidthNeededAroundLabel();
if (delete_button->m_w < needed) delete_button->m_w = needed;
deleteBtn->setLabel(label);
delete_button->setLabel(label);
}
else
{
deleteBtn->setLabel(_("Delete Configuration"));
delete_button->setLabel(_("Delete Configuration"));
if (input_manager->getDeviceManager()->getKeyboardAmount() < 2)
{
// don't allow deleting the last config
deleteBtn->setDeactivated();
delete_button->setDeactivated();
}
else
{
deleteBtn->setActivated();
delete_button->setActivated();
}
}
// Make the two buttons the same length, not strictly needed but will
// look nicer...
ButtonWidget* backBtn = getWidget<ButtonWidget>("back_to_device_list");
if (backBtn->m_w < deleteBtn->m_w) backBtn->m_w = deleteBtn->m_w;
else deleteBtn->m_w = backBtn->m_w;
if (backBtn->m_w < delete_button->m_w) backBtn->m_w = delete_button->m_w;
else delete_button->m_w = backBtn->m_w;
backBtn->moveIrrlichtElement();
deleteBtn->moveIrrlichtElement();
delete_button->moveIrrlichtElement();
LabelWidget* label = getWidget<LabelWidget>("title");
label->setText( m_config->getName().c_str(), false );
@ -178,24 +178,26 @@ void OptionsScreenInput2::init()
// -----------------------------------------------------------------------------
void OptionsScreenInput2::addListItemSubheader(GUIEngine::ListWidget* actions,
const char* id,
const core::stringw& text)
const char* id,
const core::stringw& text)
{
std::vector<GUIEngine::ListWidget::ListCell> row;
row.push_back(GUIEngine::ListWidget::ListCell(text, -1, 1, false));
row.push_back(GUIEngine::ListWidget::ListCell(L"", -1, 1, false));
actions->addItem(id, row);
}
} // addListItemSubheader
// -----------------------------------------------------------------------------
void OptionsScreenInput2::addListItem(GUIEngine::ListWidget* actions, PlayerAction pa)
void OptionsScreenInput2::addListItem(GUIEngine::ListWidget* actions,
PlayerAction pa)
{
std::vector<GUIEngine::ListWidget::ListCell> row;
row.push_back(GUIEngine::ListWidget::ListCell(core::stringw(KartActionStrings[pa].c_str()), -1, 1, false));
core::stringw s(KartActionStrings[pa].c_str());
row.push_back(GUIEngine::ListWidget::ListCell(s, -1, 1, false));
row.push_back(GUIEngine::ListWidget::ListCell(L"", -1, 1, false));
actions->addItem(KartActionStrings[pa], row);
}
} // addListItem
// -----------------------------------------------------------------------------
@ -280,16 +282,16 @@ void OptionsScreenInput2::updateInputButtons()
bool conflicts_inside = false;
// ---- make sure there are no binding conflicts
// (same key used for two actions)
std::set<irr::core::stringw> currentlyUsedKeys;
std::set<irr::core::stringw> currently_used_keys;
for (PlayerAction action = PA_FIRST_GAME_ACTION;
action <= PA_LAST_GAME_ACTION;
action=PlayerAction(action+1))
{
const irr::core::stringw item = m_config->getMappingIdString(action);
if (currentlyUsedKeys.find(item) == currentlyUsedKeys.end())
if (currently_used_keys.find(item) == currently_used_keys.end())
{
currentlyUsedKeys.insert( item );
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD
currently_used_keys.insert( item );
if (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD
&& conflictsBetweenKbdConfig(action, PA_FIRST_GAME_ACTION,
PA_LAST_GAME_ACTION))
{
@ -322,16 +324,16 @@ void OptionsScreenInput2::updateInputButtons()
// menu keys and game keys can overlap, no problem, so forget game keys
// before checking menu keys
currentlyUsedKeys.clear();
currently_used_keys.clear();
for (PlayerAction action = PA_FIRST_MENU_ACTION;
action <= PA_LAST_MENU_ACTION;
action=PlayerAction(action+1))
{
const irr::core::stringw item = m_config->getBindingAsString(action);
if (currentlyUsedKeys.find(item) == currentlyUsedKeys.end())
if (currently_used_keys.find(item) == currently_used_keys.end())
{
currentlyUsedKeys.insert( item );
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD
currently_used_keys.insert( item );
if (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD
&& conflictsBetweenKbdConfig(action, PA_FIRST_MENU_ACTION,
PA_LAST_MENU_ACTION))
{
@ -339,7 +341,7 @@ void OptionsScreenInput2::updateInputButtons()
actions->markItemBlue (KartActionStrings[action]);
}
}
else
else // existing key
{
// binding conflict!
actions->markItemRed( KartActionStrings[action] );
@ -355,12 +357,11 @@ void OptionsScreenInput2::updateInputButtons()
conflicts_inside = true;
actions->markItemRed( KartActionStrings[others] );
}
}
} // for others < action
//actions->renameItem( KartActionStrings[action],
// _("Binding Conflict!") );
}
}
} // if existing key
} // for action <= PA_LAST_MENU_ACTION;
GUIEngine::Widget* conflict_label =
getWidget<GUIEngine::LabelWidget>("conflict");
@ -385,11 +386,11 @@ static std::string binding_to_set_button;
void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
{
const bool keyboard = (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD&&
const bool keyboard = (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD&&
sensed_input.m_type == Input::IT_KEYBOARD);
const bool gamepad = (sensed_input.m_type == Input::IT_STICKMOTION ||
sensed_input.m_type == Input::IT_STICKBUTTON) &&
m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD;
m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_GAMEPAD;
if (keyboard)
{
@ -487,7 +488,7 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
//if(btn != NULL) btn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// save new binding to file
input_manager->getDeviceManager()->serialize();
input_manager->getDeviceManager()->save();
} // gotSensedInput
@ -548,11 +549,11 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
new PressAKeyDialog(0.4f, 0.4f);
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
if (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD)
{
input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
}
else if (m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD)
else if (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_GAMEPAD)
{
input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
}
@ -567,7 +568,7 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
}
else if (name == "delete")
{
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
if (m_config->getType() == DeviceConfig::DEVICE_CONFIG_TYPE_KEYBOARD)
{
// keyboard configs may be deleted
//I18N: shown before deleting an input configuration
@ -582,11 +583,11 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
else m_config->setEnabled(true);
// update widget label
ButtonWidget* deleteBtn = getWidget<ButtonWidget>("delete");
deleteBtn->setLabel(m_config->isEnabled() ? _("Disable Device")
ButtonWidget* delete_button = getWidget<ButtonWidget>("delete");
delete_button->setLabel(m_config->isEnabled() ? _("Disable Device")
: _("Enable Device") );
input_manager->getDeviceManager()->serialize();
input_manager->getDeviceManager()->save();
}
}
@ -619,7 +620,7 @@ void OptionsScreenInput2::onConfirm()
Log::error("OptionsScreenInput2", "Failed to delete config!");
m_config = NULL;
input_manager->getDeviceManager()->serialize();
input_manager->getDeviceManager()->save();
ModalDialog::dismiss();
StateManager::get()
->replaceTopMostScreen(OptionsScreenInput::getInstance());

View File

@ -48,6 +48,7 @@ class OptionsScreenInput2 : public GUIEngine::Screen,
bool conflictsBetweenKbdConfig(PlayerAction action, PlayerAction from,
PlayerAction to);
/** The configuration to use. */
DeviceConfig* m_config;
void renameRow(GUIEngine::ListWidget* actions,
@ -63,6 +64,7 @@ class OptionsScreenInput2 : public GUIEngine::Screen,
public:
friend class GUIEngine::ScreenSingleton<OptionsScreenInput2>;
/** Sets the configuration to be used. */
void setDevice(DeviceConfig* config) { m_config = config; }
/** \brief implement callback from parent class GUIEngine::Screen */