1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2010-2015 SuperTuxKart-Team
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #ifndef HEADER_DEVICE_CONFIG_HPP
20 #define HEADER_DEVICE_CONFIG_HPP
21 
22 #include "input/binding.hpp"
23 #include "input/input.hpp"
24 #include "utils/no_copy.hpp"
25 
26 #include <assert.h>
27 #include <iosfwd>
28 #include <irrString.h>
29 #include <string>
30 
31 /**
32   * \ingroup config
33   */
34 
35 //==== D E V I C E C O N F I G =================================================
36 
37 /**
38   * \brief contains the key bindings information related to one input device
39   * \ingroup config
40   */
41 class DeviceConfig : public NoCopy
42 {
43 
44 private:
45     /** If set to false, this device will be ignored.
46      *  Currently for gamepads only. */
47     bool m_enabled;
48 
49     /** How many devices connected to the system which uses this config? */
50     int m_plugged;
51 
52     /** Internal name of this configuration. */
53     std::string m_name;
54 
55     /** Name of this configuration (given by the user). */
56     irr::core::stringw m_config_name;
57 
58 protected:
59 
60     Binding  m_bindings[PA_COUNT];
61 
62     DeviceConfig();
63 
64     bool doGetAction(Input::InputType    type,
65                      const int           id,
66                      int*                value, /* inout */
67                      const PlayerAction  firstActionToCheck,
68                      const PlayerAction  lastActionToCheck,
69                      PlayerAction*       action /* out */ );
70 protected:
71     /** Those two classes need to be able to call getGameAction. */
72     friend class GamePadDevice;
73     friend class KeyboardDevice;
74     bool getGameAction(Input::InputType       type,
75                        const int              id,
76                        int*                   value, /* inout */
77                        PlayerAction*          action /* out */);
78 
79 public:
80 
~DeviceConfig()81     virtual ~DeviceConfig() {}
82 
83     static DeviceConfig* create(const XMLNode *config);
84     irr::core::stringw toString();
85     bool hasBindingFor(const int buttonID) const;
86     bool hasBindingFor(const int buttonID, PlayerAction from,
87                        PlayerAction to) const;
88     void setBinding(const PlayerAction     action,
89                     const Input::InputType type,
90                     const int              id,
91                     Input::AxisDirection   direction = Input::AD_NEUTRAL,
92                     Input::AxisRange       range     = Input::AR_HALF,
93                     wchar_t                character=0);
94     bool getMenuAction(Input::InputType       type,
95                        const int              id,
96                        int*                   value,
97                        PlayerAction*          action /* out */);
98     irr::core::stringw getMappingIdString (const PlayerAction action) const;
99     virtual irr::core::stringw getBindingAsString(const PlayerAction action) const;
100     virtual bool isGamePad()  const = 0;
101     virtual bool isKeyboard() const = 0;
102 
103     virtual void save(std::ofstream& stream);
104     virtual bool load(const XMLNode *config);
105 
106     // ------------------------------------------------------------------------
107     /** Returns true if this device has analog axis, so that steering values
108      *  will not be affected by time-full-steer delays. */
isAnalog(Input::InputType type,int id) const109     virtual bool isAnalog(Input::InputType type, int id) const { return false;}
110     // ------------------------------------------------------------------------
111     /** Returns true if this device should desensitize its input at values
112      *  close to 0 (to avoid 'oversteering'). */
desensitize() const113     virtual bool desensitize() const { return false;}
114     // ------------------------------------------------------------------------
115     /** Should only be called for gamepads, which has its own implementation.
116      *  of this function. */
getNumberOfButtons() const117     virtual int getNumberOfButtons() const
118     {
119         assert(false); return 0;
120     }   // getNumberOfButtons
121 
122     // ------------------------------------------------------------------------
123     /** Should only be called for gamepads, which has its own implementation.
124      *  of this function. */
getNumberOfAxes() const125     virtual int getNumberOfAxes() const
126     {
127         assert(false); return 0;
128     }   // getNumberOfAxes
129 
130     // ------------------------------------------------------------------------
131     /** Sets the internal name of this device. */
setName(const std::string & name)132     void setName(const std::string &name) { m_name = name; }
133 
134     // ------------------------------------------------------------------------
135     /** Returns the internal name for this device configuration. */
getName() const136     const std::string& getName() const { return m_name; };
137 
138     // ------------------------------------------------------------------------
139     /** Increase ref counter. */
setPlugged()140     void setPlugged() { m_plugged++; }
141 
142     // ------------------------------------------------------------------------
143     /** Returns if this config is sed by any devices. */
isPlugged() const144     bool isPlugged() const { return m_plugged > 0; }
145 
146     // ------------------------------------------------------------------------
147     /** Decrease ref counter. */
unPlugged()148     void unPlugged()
149     {
150         m_plugged--;
151         assert(m_plugged >= 0);
152     }
153 
154     // ------------------------------------------------------------------------
155     /** Returns the number of devices using this configuration. */
getNumberOfDevices() const156     int getNumberOfDevices() const { return m_plugged;     }
157 
158     // ------------------------------------------------------------------------
159     /** Returns the binding of a given index. */
getBinding(int i) const160     const Binding& getBinding(int i) const {return m_bindings[i];}
161 
162     // ------------------------------------------------------------------------
163     /** At this time only relevant for gamepads, keyboards are always enabled */
isEnabled() const164     bool isEnabled() const { return m_enabled; }
165 
166     // ------------------------------------------------------------------------
167     /** Sets this config to be enabled or disabled. */
setEnabled(bool new_value)168     void setEnabled(bool new_value) { m_enabled = new_value; }
169 
170     // ------------------------------------------------------------------------
171     /** Sets the name of this device configuration */
getConfigName() const172     irr::core::stringw getConfigName() const { return m_config_name;  }
173 
174     // ------------------------------------------------------------------------
175     /** Returns the name of this device configuration */
setConfigName(irr::core::stringw config_name)176     void setConfigName( irr::core::stringw config_name ) { m_config_name = config_name; }
177 };   // class DeviceConfig
178 
179 #endif
180