input.hpp 10.5 KB
Newer Older
1
2
3
//****************************************
// by Benjamin 'Albsi' Albsmeier
// input/input.hpp for GDW SS15
4
// mouse, keyboard input
5
//****************************************
6
#include <memory>
7
#include <map>
8
#include <unordered_map>
9
#include <vector>
10
11
#include <SDL.h>
#include <glm/glm.hpp>
12
13
#include <asset/asset.hpp>
#include <core/engine.hpp>
14
#include <util/logger.hpp>
15
16
17
18
19

#ifndef __INPUT_HPP__
#define __INPUT_HPP__

namespace gdw{
20
21
22
23
24
25
	struct axisStruct{
		bool changed = false;
		int down = 0;
		bool released = false;
	};

26
27
28
	struct controller {
		SDL_GameController *sdlController;
		int controllerNr = -1;
29
30
		std::unordered_map<int, bool> controllerMap;
		std::unordered_map<int, bool> controllerReleasedMap;
31
		std::unordered_map<int, axisStruct> axisMap;
32
		bool active = false;
33
34
	};

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
35
36
	//if you add here, add also a mapping in makeMapping() in input.cpp
	enum class inputMapping {
37
38
39
40
41
		state_switch,
		player_move_left,
		player_move_right,
		beam_normal,
		beam_inverse,
Jerry's avatar
Jerry committed
42
43
		place_item,
		button_click
44
45
	};

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
46
	struct inputMappingStruct {
47
		unsigned int type = 0;
48
		bool negativAxis = false;
49
50
		SDL_Keycode keyCode1 = 0;
		SDL_Keycode keyCode2 = 0;
51
52
53
		int mbuttonCode = -1;
		SDL_GameControllerButton cbuttonCode = SDL_CONTROLLER_BUTTON_INVALID;
		SDL_GameControllerAxis caxisCode = SDL_CONTROLLER_AXIS_INVALID;
54
55
	};

56
57
58
59
60
61
	enum class controllerCursor {
		none,
		left,
		right
	};

62
63
	class engine;
	class input{
64
		private:
65
			std::string controllerDBPath_ = "input/gamecontrollerdb.txt";
66
67
			static float constexpr controllerAxisMax_ = 32767.f;
			static float constexpr controllerAxisDeadZone_ = .3f;
68
			static float constexpr controllerSpeed_ = 800.f;
69

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
70
			/**inputMappingStruct.type for key*/
71
72
			static unsigned int constexpr key1 = 0x01;
			static unsigned int constexpr key2 = 0x02;
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
73
			/**inputMappingStruct.type for mouse button*/
74
			static unsigned int constexpr mbutton = 0x04;
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
75
			/**inputMappingStruct.type for controller button*/
76
			static unsigned int constexpr cbutton = 0x08;
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
77
			/**inputMappingStruct.type for controller axis*/
78
			static unsigned int constexpr caxis = 0x10;
79
80
81
82
		public:
			input(engine& engine);
			~input();

83
			/**updates the keys and computes the SDL_Events
84
			*  should called for every event*/
85
			void update(const SDL_Event &event);
86
87

			/**resets some data
88
			*  should called once per game loop, at the end*/
89
			void reset();
90

91
92
93

			void calcPosition(float delta);

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
94
95
96
97
98
99
100
101
			/**Returns true every frame, as long as it is down - NOT FOR MULTI CONTROLLER*/
			bool isPressed(inputMapping id);

			/**Returns true once it is pressed - NOT FOR MULTI CONTROLLER*/
			bool isDown(inputMapping id);

			/**Returns true once it is released - NOT FOR MULTI CONTROLLER*/
			bool isReleased(inputMapping id);
102

103
			/**Returns true every frame, as long as the key is down.*/
104
		private:
105
			int isKeyDown(SDL_Keycode key) noexcept {return keyState_[SDL_GetScancodeFromKey(key)];};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
106
			int isKeyDown(inputMapping key) noexcept {return isKeyDown(getKeyCodeByMapping(key, 1)) || isKeyDown(getKeyCodeByMapping(key, 2));};
107
108

			/**Returns true once the key is pressed*/
109
			bool isKeyPressed(SDL_Keycode key) noexcept {return keyMap_[key]==1;};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
110
			bool isKeyPressed(inputMapping key) noexcept {return isKeyPressed(getKeyCodeByMapping(key, 1)) || isKeyPressed(getKeyCodeByMapping(key, 2));};
111
112

			/**Returns true once the key is released*/
113
			bool isKeyReleased(SDL_Keycode key) noexcept {return keyReleasedMap_[key] && !keyState_[SDL_GetScancodeFromKey(key)];};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
114
			bool isKeyReleased(inputMapping key) noexcept {return isKeyReleased(getKeyCodeByMapping(key, 1)) || isKeyReleased(getKeyCodeByMapping(key, 2));};
115

116
			/**Returns true every frame, as long as the mouse button is down.*/
117
			bool isMouseButtonDown(int button) noexcept {return SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(button);};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
118
			bool isMouseButtonDown(inputMapping button);
119
120

			/**Returns true once the mouse button is pressed*/
121
			bool isMouseButtonPressed(int button) noexcept {return mouseMap_[button]==1;};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
122
			bool isMouseButtonPressed(inputMapping button);
123
124

			/**Returns true once the mouse button is released*/
125
			bool isMouseButtonReleased(int button) noexcept {return mouseReleasedMap_[button];};
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
126
			bool isMouseButtonReleased(inputMapping button);
127

128
		public:
129
130
			/**Returns a glm::vec2 with the x and y motion of the mouse wheel
			*  y is the motion a nomal mouse wheel can perform*/
131
			glm::vec2 mouseWheel()noexcept{return mousePos_;};
132
133

			/**x motion of the mouse wheel*/
134
			int mouseWheelX()noexcept{return mouseWheel_.x;};
135
136

			/**y motion of the mouse wheel*/
137
138
			int mouseWheelY()noexcept{return mouseWheel_.y;};

139
			/**returns a glm::vec2 with the x and y position of the mouse cursor*/
140
			glm::vec2 mousePos()noexcept{return mousePos_;};
141
142

			/**returns x position of the mouse cursor*/
143
			int mousePosX()noexcept{return mousePos_.x;};
144
145

			/**returns y position of the mouse cursor*/
146
			int mousePosY()noexcept{return mousePos_.y;};
147

148
			/**Returns true every frame, as long as the controller button is down.*/
149
		private:
150
			bool isControllerButtonDown(SDL_GameControllerButton button, int nr = 0);
151
		public:
152
			bool isControllerButtonDown(inputMapping button, int nr = 0) noexcept {return isControllerButtonDown(getCButtonCodeByMapping(button), nr);};
153
154

			/**Returns true once the controller button is pressed*/
155
		private:
156
			bool isControllerButtonPressed(SDL_GameControllerButton button, int nr = 0);
157
		public:
158
			bool isControllerButtonPressed(inputMapping button, int nr = 0) noexcept {return isControllerButtonPressed(getCButtonCodeByMapping(button), nr);};
159
160

			/**Returns true once the controller button is released*/
161
		private:
162
			bool isControllerButtonReleased(SDL_GameControllerButton button, int nr = 0);
163
		public:
164
			bool isControllerButtonReleased(inputMapping button, int nr = 0) noexcept {return isControllerButtonReleased(getCButtonCodeByMapping(button), nr);};
165
166

			/**Returns the value of that axis as a float between -1 and 1*/
167
		private:
168
			float controllerAxis(SDL_GameControllerAxis axis, int nr = 0);
169
		public:
170
			float controllerAxis(inputMapping axis, int nr = 0) noexcept {return controllerAxis(getCAxisCodeByMapping(axis), nr);};
171
172

			/**Returns number of aktiv controllers*/
173
			int controllerCount() noexcept {return controllers_.size();};
174
175
176

			/**Returns true if a controller exists with that id*/
			bool isController(int id) noexcept {return SDL_IsGameController(id) && controllers_[id].active;};
177
		private:
178
			std::shared_ptr<const asset> controllerDB_;
179
180
			std::unordered_map<int, controller> controllers_;

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
181
182
183
			std::map<gdw::inputMapping, gdw::inputMappingStruct> mappings_;
			void makeMappings();
			bool isMappingOk(inputMappingStruct mapping, std::string name);
184

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
185
186
187
188
			SDL_Keycode getKeyCodeByMapping(inputMapping id, int nr);
			int getMButtonCodeByMapping(inputMapping id);
			SDL_GameControllerButton getCButtonCodeByMapping(inputMapping id);
			SDL_GameControllerAxis getCAxisCodeByMapping(inputMapping id);
189
190

			int getMButtonFromName(std::string name);
191
			SDL_Keycode getKeyFromName(std::string name);
192
193
			SDL_GameControllerButton getCButtonFromName(std::string name);
			SDL_GameControllerAxis getCAxisFromName(std::string name);
194

195
196
197
			int firstController();
			std::unordered_map<int, bool> usedControllers_;

198
199
200
201
			controller controller_;
			engine &engine_;

			glm::vec2 mousePos_;
202
			glm::vec2 oldMousePos_;
203
			glm::vec2 mouseWheel_;
204
205
206
207
208
209
210
211
212
			glm::vec2 pos_;

			int windowWidth_ = 800;
			int windowHeight_ = 600;

			bool controllerUse = false;

			controllerCursor getCCursorFromName(std::string name);
			controllerCursor ccursor = controllerCursor::none;
213
214
215

			const Uint8 *keyState_;

216
217
218
219
220
221
222
			std::unordered_map<int, int> mouseMap_;
			std::unordered_map<int, int> mouseReleasedMap_;
			std::unordered_map<int, int> keyMap_;
			std::unordered_map<int, int> keyReleasedMap_;
			std::unordered_map<int, int>::iterator mouseIt_;
			std::unordered_map<int, int>::iterator keyIt_;
			std::unordered_map<int, bool>::iterator controllerIt_;
223
			std::unordered_map<int, axisStruct>::iterator caxisIt_;
224
225
226
227
228
229
230
231
232
233
234
235

			//KEYBOARD
			void keyDown(const SDL_KeyboardEvent &e);
			void keyUp(const SDL_KeyboardEvent &e);
			//MOUSE
			void mouseDown(const SDL_MouseButtonEvent &e);
			void mouseUp(const SDL_MouseButtonEvent &e);
			void mouseMotion(const SDL_MouseMotionEvent &e);
			void mouseWheel(const SDL_MouseWheelEvent &e);
			//CONTROLLER
			void controllerUp(const SDL_ControllerButtonEvent &e);
			void controllerDown(const SDL_ControllerButtonEvent &e);
236
237
238
			void controllerAdded(const SDL_ControllerDeviceEvent &e);
			void controllerRemoved(const SDL_ControllerDeviceEvent &e);
			void controllerRemapped(const SDL_ControllerDeviceEvent &e) noexcept {log << "[input] controllerRemapped was triggerd but is not handelt" << std::endl;};
239
			void controllerAxis(const SDL_ControllerAxisEvent &e) noexcept {/*handelt on another way, see: float controllerAxis(SDL_GameControllerAxis axis, int nr)*/};
240
			//TEXTINPUT
241
242
			void textEdit(const SDL_TextEditingEvent &e) noexcept {log << "[input] textInput was triggerd but is not handelt" << std::endl;};
			void textInput(const SDL_TextInputEvent &e) noexcept {/*spams the log on every key input - not handelt*/};
243
			//TOUCH
244
245
246
247
248
249
			void touchMotion(const SDL_TouchFingerEvent &e) noexcept {log << "[input] touchMotion was triggerd but is not handelt" << std::endl;};
			void touchDown(const SDL_TouchFingerEvent &e) noexcept {log << "[input] touchDown was triggerd but is not handelt" << std::endl;};
			void touchUp(const SDL_TouchFingerEvent &e) noexcept {log << "[input] touchUp was triggerd but is not handelt" << std::endl;};
			void touchGesture(const SDL_MultiGestureEvent &e) noexcept {log << "[input] touchGesture was triggerd but is not handelt" << std::endl;};
			void touchComplexGesture(const SDL_DollarGestureEvent &e) noexcept {log << "[input] touchComplexGesture was triggerd but is not handelt" << std::endl;};
			void touchGestureRecord(const SDL_DollarGestureEvent &e) noexcept {log << "[input] touchGestureRecord was triggerd but is not handelt" << std::endl;};
250
			//JOYSTICK
251
252
253
254
255
256
257
			void joyAdded(const SDL_JoyDeviceEvent &e) noexcept {/*controllerAdded*/};
			void joyRemoved(const SDL_JoyDeviceEvent &e) noexcept {/*controllerRemoved*/};
			void joyHat(const SDL_JoyHatEvent &e) noexcept {/*controllerDown / controllerUp*/};
			void joyDown(const SDL_JoyButtonEvent &e) noexcept {/*controllerDown*/};
			void joyUp(const SDL_JoyButtonEvent &e) noexcept {/*controllerUp*/};
			void joyBall(const SDL_JoyBallEvent &e) noexcept {log << "[input] joyBall was triggerd but is not handelt" << std::endl;};
			void joyAxis(const SDL_JoyAxisEvent &e) noexcept {/*controllerAxis*/};
258
			//DROP
259
			void drop(const SDL_DropEvent &e) noexcept {log << "[input] drop was triggerd but is not handelt" << std::endl;};
260
261
262
263
	};
}

#endif