SuperTuxKart
Loading...
Searching...
No Matches
sdl_controller.hpp
1// SuperTuxKart - a fun racing game with go-kart
2// Copyright (C) 2020 SuperTuxKart-Team
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License
6// as published by the Free Software Foundation; either version 3
7// of the License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#ifndef HEADER_SDL_CONTROLLER_HPP
19#define HEADER_SDL_CONTROLLER_HPP
20
21#ifndef SERVER_ONLY
22
23#include <SDL_events.h>
24#include <SDL_gamecontroller.h>
25#include <SDL_joystick.h>
26#include <IEventReceiver.h>
27#include <bitset>
28#include "utils/types.hpp"
29
30#include <SDL_version.h>
31#include <SDL_haptic.h>
32
33class GamePadDevice;
34
36{
37private:
38 SDL_GameController* m_game_controller;
39
40 SDL_Joystick* m_joystick;
41
42 GamePadDevice* m_gamepad;
43
44 SDL_Haptic* m_haptic;
45 int m_auto_center;
46
47 int m_buttons;
48
49 int m_axes;
50
51 int m_hats;
52
53 SDL_JoystickID m_id;
54
55 irr::SEvent m_irr_event;
56
57 int16_t m_prev_axes[irr::SEvent::SJoystickEvent::NUMBER_OF_AXES];
58
59 uint64_t m_last_power_level_time;
60#ifdef ANDROID
61 void handleDirectScanCode(const SDL_Event& event);
62#endif
63
64 void updateAutoCenter(int state);
65public:
66 // ------------------------------------------------------------------------
67 SDLController(int device_id);
68 // ------------------------------------------------------------------------
70 // ------------------------------------------------------------------------
71 const irr::SEvent& getEvent() const { return m_irr_event; }
72 // ------------------------------------------------------------------------
73 SDL_JoystickID getInstanceID() const { return m_id; }
74 // ------------------------------------------------------------------------
75 void handleAxisInputSense(const SDL_Event& event);
76 // ------------------------------------------------------------------------
77 bool handleAxis(const SDL_Event& event)
78 {
79 int axis_idx = event.jaxis.axis;
80 if (axis_idx > m_axes)
81 return false;
82 m_irr_event.JoystickEvent.Axis[axis_idx] = event.jaxis.value;
83 m_prev_axes[axis_idx] = event.jaxis.value;
84 uint32_t value = 1 << axis_idx;
85 m_irr_event.JoystickEvent.AxisChanged = value;
86 return true;
87 } // handleAxis
88 // ------------------------------------------------------------------------
89 bool handleHat(const SDL_Event& event)
90 {
91 if (event.jhat.hat > m_hats)
92 return false;
93 std::bitset<4> new_hat_status;
94 // Up, right, down and left (4 buttons)
95 switch (event.jhat.value)
96 {
97 case SDL_HAT_UP:
98 new_hat_status[0] = true;
99 break;
100 case SDL_HAT_RIGHTUP:
101 new_hat_status[0] = true;
102 new_hat_status[1] = true;
103 break;
104 case SDL_HAT_RIGHT:
105 new_hat_status[1] = true;
106 break;
107 case SDL_HAT_RIGHTDOWN:
108 new_hat_status[1] = true;
109 new_hat_status[2] = true;
110 break;
111 case SDL_HAT_DOWN:
112 new_hat_status[2] = true;
113 break;
114 case SDL_HAT_LEFTDOWN:
115 new_hat_status[2] = true;
116 new_hat_status[3] = true;
117 break;
118 case SDL_HAT_LEFT:
119 new_hat_status[3] = true;
120 break;
121 case SDL_HAT_LEFTUP:
122 new_hat_status[3] = true;
123 new_hat_status[0] = true;
124 break;
125 case SDL_HAT_CENTERED:
126 default:
127 break;
128 }
129 int hat_start = m_buttons - (m_hats * 4) + (event.jhat.hat * 4);
130 std::bitset<irr::SEvent::SJoystickEvent::NUMBER_OF_BUTTONS> states
131 (m_irr_event.JoystickEvent.ButtonStates);
132 for (unsigned i = 0; i < 4; i++)
133 {
134 int hat_button_id = i + hat_start;
135 states[hat_button_id] = new_hat_status[i];
136 }
137 m_irr_event.JoystickEvent.ButtonStates = (irr::u32)states.to_ulong();
138 m_irr_event.JoystickEvent.AxisChanged = 0;
139 return true;
140 } // handleHat
141 // ------------------------------------------------------------------------
142 bool handleButton(const SDL_Event& event)
143 {
144 if (event.jbutton.button > m_buttons)
145 {
146#ifdef ANDROID
147 handleDirectScanCode(event);
148#endif
149 return false;
150 }
151 bool pressed = event.jbutton.state == SDL_PRESSED;
152 std::bitset<irr::SEvent::SJoystickEvent::NUMBER_OF_BUTTONS> states
153 (m_irr_event.JoystickEvent.ButtonStates);
154 states[event.jbutton.button] = pressed;
155 m_irr_event.JoystickEvent.ButtonStates = (irr::u32)states.to_ulong();
156 m_irr_event.JoystickEvent.AxisChanged = 0;
157 return true;
158 } // handleButton
159 // ------------------------------------------------------------------------
160 SDL_GameController* getGameController() const { return m_game_controller; }
161 // ------------------------------------------------------------------------
162 void checkPowerLevel();
163 // ------------------------------------------------------------------------
164 void doRumble(float strength_low, float strength_high, uint32_t duration_ms);
165 GamePadDevice* getGamePadDevice() const { return m_gamepad; }
166};
167
168#endif
169
170#endif
specialisation of Inputdevice for gamepad type devices
Definition: gamepad_device.hpp:33
Definition: sdl_controller.hpp:36
void handleAxisInputSense(const SDL_Event &event)
SDL only sends event when axis moves, so we need to send previously saved event for correct input sen...
Definition: sdl_controller.cpp:229
Declares the general types that are used by the network.