1 //  SuperTuxKart - a fun racing game with go-kart
2 //
3 //  Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
4 //  Copyright (C) 2006-2015 SuperTuxKart-Team
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 3
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 #ifndef HEADER_INPUT_MANAGER_HPP
21 #define HEADER_INPUT_MANAGER_HPP
22 
23 #include <map>
24 #include <memory>
25 #include <string>
26 #include <vector>
27 #include <set>
28 
29 #include "guiengine/event_handler.hpp"
30 #include "input/input.hpp"
31 #include "utils/no_copy.hpp"
32 
33 #ifndef SERVER_ONLY
34 #include <SDL_events.h>
35 #endif
36 
37 class DeviceManager;
38 class SDLController;
39 
40 /**
41   * \brief Class to handle input.
42   * \ingroup input
43   */
44 class InputManager: public NoCopy
45 {
46 public:
47     enum InputDriverMode
48     {
49         MENU = 0,
50         INGAME,
51         INPUT_SENSE_KEYBOARD,
52         INPUT_SENSE_GAMEPAD,
53         BOOTSTRAP
54     };
55 
56     // to put a delay before a new gamepad axis move is considered in menu
57     bool m_timer_in_use;
58     float m_timer;
59 
60 private:
61 
62     DeviceManager  *m_device_manager;
63     std::set<std::tuple<int, int>>   m_sensed_input_high_gamepad;
64     std::set<int>   m_sensed_input_high_kbd;
65     std::set<int>   m_sensed_input_zero_gamepad;
66 
67     InputDriverMode  m_mode;
68 
69     /** When at true, only the master player can play with menus */
70     bool m_master_player_only;
71 
72     /* Helper values to store and track the relative mouse movements. If these
73     * values exceed the deadzone value the input is reported to the game. This
74     * makes the mouse behave like an analog axis on a gamepad/joystick.
75     */
76     int m_mouse_val_x, m_mouse_val_y;
77 
78     void   handleStaticAction(int id0, int value);
79     void   inputSensing(Input::InputType type, int deviceID, int btnID,
80                         Input::AxisDirection axisDirection,  int value);
81 
82 #ifndef SERVER_ONLY
83     std::map<int, std::unique_ptr<SDLController> > m_sdl_controller;
84 #endif
85 
86 public:
87            InputManager();
88           ~InputManager();
89     // void   initGamePadDevices();
90 
91     //void   input();
92     GUIEngine::EventPropagation   input(const irr::SEvent& event);
93 
getDeviceManager()94     DeviceManager* getDeviceManager() { return m_device_manager; }
95 
96     void   setMode(InputDriverMode);
97     bool   isInMode(InputDriverMode);
getMode()98     InputDriverMode getMode() { return m_mode; }
99 
100     /** When this mode is enabled, only the master player will be able to play
101      *  with menus (only works in 'assign' mode) */
102     void   setMasterPlayerOnly(bool enabled);
103 
104     /** Returns whether only the master player should be allowed to perform
105      *  changes in menus. */
106     bool    masterPlayerOnly() const;
107 
108     void   update(float dt);
109 
110     /** Returns the ID of the player that plays with the keyboard,
111      *  or -1 if none. */
112     int    getPlayerKeyboardID() const;
113 #ifdef SERVER_ONLY
getGamepadCount() const114     size_t getGamepadCount() const { return 0; }
115 #else
116     /** Returns number of active connected gamepad (with SDL), notice the
117      *  disconnected gamepad will not be removed from device manager to allow
118      *  re-plugging later with the same ID. */
getGamepadCount() const119     size_t getGamepadCount() const { return m_sdl_controller.size(); }
120     /** Returns irrlicht joystick for gamepad visualization. */
121     const irr::SEvent& getEventForGamePad(unsigned i) const;
122 
123     void   handleJoystick(SDL_Event& event);
124 #endif
125 
126     void   dispatchInput(Input::InputType, int deviceID, int btnID,
127                          Input::AxisDirection direction, int value,
128                          bool shift_mask = false);
129     void   addJoystick();
130 };
131 
132 extern InputManager *input_manager;
133 
134 #endif
135