input.cpp 18.7 KB
Newer Older
1
2
3
4
//****************************************
// by Benjamin 'Albsi' Albsmeier
// input/input.cpp for GDW SS15
//****************************************
5
#include "input/input.hpp"
6
#include <util/config.hpp>
7
8

namespace gdw{
9
10
11
12
13
14
15
	input::input(engine& engine):engine_(engine),
								mousePos_(0,0),
								oldMousePos_(0,0),
								pos_(0,0),
								mouseWheel_(0,0),
								controllers_(),
								mappings_(){
16
		keyState_ = SDL_GetKeyboardState(NULL);
17
		controllerDB_ = engine.asset_manager().load(engine.asset_manager().native_name(controllerDBPath_));
18
19
20
21
22
23
24
25
26

		ccursor = getCCursorFromName(engine_.getConfig().get<std::string>("controller_cursor","RIGHT"));
		controllerUse = engine_.getConfig().get<bool>("use_controller",false);

		windowWidth_ = engine_.getConfig().get<int>("width",800);
		windowHeight_ = engine_.getConfig().get<int>("height",600);

		//SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR));
		if(controllerUse)SDL_ShowCursor(SDL_FALSE);
27
28
29
30
	}

	input::~input(){}

31
32
	void input::update(const SDL_Event &e){
		switch(e.type){
33
34
35
36
37
38
39
40
41
42
43
			//KEYBOARD
			case SDL_KEYDOWN: keyDown(e.key); break;
			case SDL_KEYUP: keyUp(e.key); break;
			//MOUSE
			case SDL_MOUSEBUTTONDOWN: mouseDown(e.button); break;
			case SDL_MOUSEBUTTONUP: mouseUp(e.button); break;
			case SDL_MOUSEMOTION: mouseMotion(e.motion); break;
			case SDL_MOUSEWHEEL: mouseWheel(e.wheel); break;
			//CONTROLLER
			case SDL_CONTROLLERBUTTONDOWN: controllerDown(e.cbutton); break;
			case SDL_CONTROLLERBUTTONUP: controllerUp(e.cbutton); break;
44
45
			case SDL_CONTROLLERDEVICEADDED: controllerAdded(e.cdevice); break;
			case SDL_CONTROLLERDEVICEREMOVED: controllerRemoved(e.cdevice); break;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
			case SDL_CONTROLLERDEVICEREMAPPED: controllerRemapped(e.cdevice); break;
			case SDL_CONTROLLERAXISMOTION: controllerAxis(e.caxis); break;
			//TEXTINPUT
			case SDL_TEXTEDITING: textEdit(e.edit); break;
			case SDL_TEXTINPUT: textInput(e.text); break;
			//TOUCH
			case SDL_FINGERMOTION: touchMotion(e.tfinger); break;
			case SDL_FINGERDOWN: touchDown(e.tfinger); break;
			case SDL_FINGERUP: touchUp(e.tfinger); break;
			case SDL_MULTIGESTURE: touchGesture(e.mgesture); break;
			case SDL_DOLLARGESTURE: touchComplexGesture(e.dgesture); break;
			case SDL_DOLLARRECORD: touchGestureRecord(e.dgesture); break;
			//JOYSTICK
			case SDL_JOYDEVICEADDED: joyAdded(e.jdevice); break;
			case SDL_JOYDEVICEREMOVED: joyRemoved(e.jdevice); break;
			case SDL_JOYHATMOTION: joyHat(e.jhat); break;
			case SDL_JOYBUTTONDOWN: joyDown(e.jbutton); break;
			case SDL_JOYBUTTONUP: joyUp(e.jbutton); break;
			case SDL_JOYBALLMOTION: joyBall(e.jball); break;
			case SDL_JOYAXISMOTION: joyAxis(e.jaxis); break;
			//DROP
			case SDL_DROPFILE: drop(e.drop); break;
		}
	}
70

71
	void input::keyDown(const SDL_KeyboardEvent &e){
72
73
74
75
76
		auto it = keyMap_.find(e.keysym.sym);
		if(it == keyMap_.end()){
			keyMap_.emplace(e.keysym.sym, 1);
		}else{
			++keyMap_.at(it->first);
77
78
		}
	}
79

80
	void input::keyUp(const SDL_KeyboardEvent &e){
81
82
83
84
		auto it = keyMap_.find(e.keysym.sym);
		if(it != keyMap_.end()){
			keyMap_.erase(it);
		}
85
86
		keyReleasedMap_.emplace(e.keysym.sym, 1);
	}
87

88
	void input::mouseDown(const SDL_MouseButtonEvent &e){
89
		mousePressedMap_.emplace(e.button, 1);
90
	}
91

92
93
94
	void input::mouseUp(const SDL_MouseButtonEvent &e){
		mouseReleasedMap_.emplace(e.button, 1);
	}
95

96
97
98
99
100
101
102
103
104
	void input::mouseMotion(const SDL_MouseMotionEvent &e){
		mousePos_.x = e.x;
		mousePos_.y = e.y;
	}

	void input::mouseWheel(const SDL_MouseWheelEvent &e){
		mouseWheel_.x = e.x;
		mouseWheel_.y = e.y;
	}
105

106
	void input::controllerDown(const SDL_ControllerButtonEvent &e){
107
108
109
		auto it = controllers_.find(e.which);
		if(it != controllers_.end()){
			controllers_.at(it->first).controllerMap.emplace(e.button, true);
110
111
		}
	}
112

113
	void input::controllerUp(const SDL_ControllerButtonEvent &e){
114
115
116
		auto it = controllers_.find(e.which);
		if(it != controllers_.end()){
			controllers_.at(it->first).controllerReleasedMap.emplace(e.button, true);
117
118
119
		}
	}

120
	void input::controllerAdded(const SDL_ControllerDeviceEvent &e){
121
122
123
		if(SDL_IsGameController(e.which)){
			controller c;
			c.sdlController = SDL_GameControllerOpen(e.which);
124
125
			c.controllerNr = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(c.sdlController));
			usedControllers_.emplace(c.controllerNr, true);
126
127
128
129
			c.active = true;
			if(controllerDB_){
				std::vector<char> controllerDBVec(controllerDB_->content());
				if(SDL_GameControllerAddMapping(&controllerDBVec[0]) == -1){
130
					log << "input: can't load controllerDB" << std::endl << SDL_GetError() << std::endl;
131
132
				}
			}
133
			controllers_.emplace(c.controllerNr, c);
134
135
136
		}
	}

137
	void input::controllerRemoved(const SDL_ControllerDeviceEvent &e){
138
139
140
141
142
143
144
145
146
147
148
149
		std::unordered_map<int, bool>::iterator usedIt = usedControllers_.find(e.which);
		if(usedIt != usedControllers_.end()){
			usedControllers_.at(usedIt->first) = false;
		}else{
			usedControllers_.emplace(e.which, false);
		}

		std::unordered_map<int, controller>::iterator it = controllers_.find(e.which);
		if(it != controllers_.end()){
			SDL_GameControllerClose(controllers_.at(it->first).sdlController);
			controllers_.erase(it);
		}
150
151
152
	}

	void input::calcPosition(float delta){
153
154
155
156
		for(auto it:controllers_){
			for(int i=SDL_CONTROLLER_AXIS_INVALID+1; i<SDL_CONTROLLER_AXIS_MAX; ++i){
				float f = SDL_GameControllerGetAxis(
					controllers_.at(it.first).sdlController, SDL_GameControllerAxis(i)) / controllerAxisMax_;
157
				if(!(f < controllerAxisDeadZone_ && f > -controllerAxisDeadZone_)){
158
159
					auto axisIt = controllers_.at(it.first).axisMap.find(i);
					if(axisIt == controllers_.at(it.first).axisMap.end()){
160
161
162
						axisStruct as;
						as.down = 1;
						as.changed = true;
163
						controllers_.at(it.first).axisMap.emplace(i, as);
164
					}else{
165
166
						++controllers_.at(it.first).axisMap.at(axisIt->first).down;
						controllers_.at(it.first).axisMap.at(axisIt->first).changed = true;
167
168
169
170
					}
				}
			}
		}
171

172
173
		pos_.x = mousePos_.x;
		pos_.y = mousePos_.y;
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
		if(ccursor != controllerCursor::none){
			if(controllerUse){
				float speed = controllerSpeed_ * delta;
				if(ccursor == controllerCursor::left){
					pos_.x += controllerAxis(SDL_CONTROLLER_AXIS_LEFTX) * speed;
					pos_.y += controllerAxis(SDL_CONTROLLER_AXIS_LEFTY) * speed;;
				}else if(ccursor == controllerCursor::right){
					pos_.x += controllerAxis(SDL_CONTROLLER_AXIS_RIGHTX) * speed;;
					pos_.y += controllerAxis(SDL_CONTROLLER_AXIS_RIGHTY) * speed;;
				}
			}
			pos_.x = pos_.x <= windowWidth_ ? pos_.x : windowWidth_;
			pos_.x = pos_.x >= 0.f ? pos_.x : 0.f;
			pos_.y = pos_.y <= windowHeight_ ? pos_.y : windowHeight_;
			pos_.y = pos_.y >= 0.f ? pos_.y : 0.f;
		}
	}

	int input::firstController(){
		if(usedControllers_.size() < 1)return -1;
194
195
196
		for (auto& it:usedControllers_){
			if(it.second == true){
				return it.first;
197
198
199
			}
		}
		return -1;
200
201
	}

202
	//RESET
203
204
205
	void input::reset(){
		mouseWheel_.x = 0;
		mouseWheel_.y = 0;
206
207
		oldMousePos_.x = mousePos_.x;
		oldMousePos_.y = mousePos_.y;
208

209
		mousePressedMap_.clear();
210
		mouseReleasedMap_.clear();
211

212
213
		for(auto it:keyMap_){
			++keyMap_.at(it.first);
214
		}
215
		keyReleasedMap_.clear();
216

217
218
219
220
221
222
223
224
225
226
227
		for(auto it:controllers_){
			controllers_.at(it.first).controllerReleasedMap.clear();
			controllers_.at(it.first).controllerMap.clear();
			for (auto axisIt:controllers_.at(it.first).axisMap){
				if(!axisIt.second.changed && axisIt.second.down > 0){
					axisIt.second.released = true;
					axisIt.second.down = 0;
				}else{
					if(axisIt.second.released)axisIt.second.released = false;
				}
				axisIt.second.changed = false;
228
229
			}
		}
230
231
	}

Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
232
	//MAPPING
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
	bool input::addMapping(std::string name){
		bool ok = false;
		inputMappingStruct ims;
		std::string s = engine_.getConfig().get<std::string>(name + "_key1","none");
		if(s != "none"){
			ims.keyCode1 = getKeyFromName(s);
			ims.type += key1;
			ok = true;
		}
		s = engine_.getConfig().get<std::string>(name + "_key2","none");
		if(s != "none"){
			ims.keyCode2 = getKeyFromName(s);
			ims.type += key2;
			ok = true;
		}
		s = engine_.getConfig().get<std::string>(name + "_mouse_button","none");
		if(s != "none"){
			ims.mbuttonCode = getMButtonFromName(s);
			ims.type += mbutton;
			ok = true;
		}
		s = engine_.getConfig().get<std::string>(name + "_controller_button","none");
		if(s != "none"){
			ims.cbuttonCode = getCButtonFromName(s);
			ims.type += cbutton;
			ok = true;
		}
		s = engine_.getConfig().get<std::string>(name + "_controller_axis","none");
		if(s != "none"){
			ims.caxisCode = getCAxisFromName(s);
			ims.type += caxis;
			ok = true;
		}
		mappings_.emplace(name, ims);
		return ok;
	}

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
	void input::printMapping(){
		log << "input: print mappings:" << std::endl;
		for(auto it:mappings_){
			log << "input: name: " << it.first << std::endl;
			if(it.second.keyCode1 != 0)log << "input:      key1: " << SDL_GetKeyName(it.second.keyCode1) << std::endl;
			if(it.second.keyCode2 != 0)log << "input:      key2: " << SDL_GetKeyName(it.second.keyCode2) << std::endl;
			if(it.second.mbuttonCode != -1)log << "input:      mouse button: " << getMouseButtonName(it.second.mbuttonCode) << std::endl;
			if(it.second.cbuttonCode != -1)log << "input:      controller button: " << SDL_GameControllerGetStringForButton(it.second.cbuttonCode) << std::endl;
			if(it.second.caxisCode != -1)log << "input:      controller axis: " << SDL_GameControllerGetStringForAxis(it.second.caxisCode) << std::endl;
			if(it.second.negativAxis)log << "input:      negativ axis" << std::endl;
		}
	}

	std::string input::getMouseButtonName(int id){
		switch(id){
			case SDL_BUTTON_LEFT: return "left";
			case SDL_BUTTON_RIGHT: return "right";
			case SDL_BUTTON_MIDDLE: return "middle";
			case SDL_BUTTON_X1: return "mouse4";
			case SDL_BUTTON_X2: return "mouse5";
		}
		return "none";
	}


295
	int input::getKeyCodeByMapping(std::string id, int nr){
296
		auto it = mappings_.find(id);
297
		if(it == mappings_.end())return 0;
298
		if(nr == 1){
299
			return (mappings_.at(it->first).type & key1) !=0? mappings_.at(it->first).keyCode1 : 0;
300
		}else if(nr == 2){
301
			return (mappings_.at(it->first).type & key2) !=0? mappings_.at(it->first).keyCode2 : 0;
302
303
		}
		return 0;
304
305
	}

306
	int input::getMButtonCodeByMapping(std::string id){
307
		auto it = mappings_.find(id);
308
		if(it == mappings_.end())return -1;
309
		return (mappings_.at(it->first).type & mbutton) !=0? mappings_.at(it->first).mbuttonCode : -1;
310
311
	}

312
	SDL_GameControllerButton input::getCButtonCodeByMapping(std::string id){
313
		auto it = mappings_.find(id);
314
		if(it == mappings_.end())return SDL_CONTROLLER_BUTTON_INVALID;
315
		return (mappings_.at(it->first).type & cbutton) !=0? mappings_.at(it->first).cbuttonCode : SDL_CONTROLLER_BUTTON_INVALID;
316
317
	}

318
	SDL_GameControllerAxis input::getCAxisCodeByMapping(std::string id){
319
		auto it = mappings_.find(id);
320
		if(it == mappings_.end())return SDL_CONTROLLER_AXIS_INVALID;
321
		return (mappings_.at(it->first).type & caxis) !=0? mappings_.at(it->first).caxisCode : SDL_CONTROLLER_AXIS_INVALID;
322
	}
323

324
325
	int input::getMButtonFromName(std::string name){
		if(name == "Left" || name == "left" || name == "LEFT"){
326
			return SDL_BUTTON_LEFT;
327
		}else if(name == "Right" || name == "right" || name == "RIGHT"){
328
			return SDL_BUTTON_RIGHT;
329
		}else if(name == "Middle" || name == "middle" || name == "MIDDLE"){
330
			return SDL_BUTTON_MIDDLE;
331
		}else if(name == "Mouse4" || name == "mouse4" || name == "MOUSE4"){
332
			return SDL_BUTTON_X1;
333
		}else if(name == "Mouse5" || name == "mouse5" || name == "MOUSE5"){
334
335
336
337
338
339
340
341
342
343
			return SDL_BUTTON_X2;
		}else{
			return -1;
		}
	}

	int input::getKeyFromName(std::string name){
		return SDL_GetKeyFromName(name.c_str());
	}

344
345
346
347
348
349
350
351
352
353
354
355
356
357
	SDL_GameControllerButton input::getCButtonFromName(std::string name){
		if(name == "LEFT" || name == "left" || name == "Left"){
			return SDL_CONTROLLER_BUTTON_DPAD_LEFT;
		}else if(name == "RIGHT" || name == "right" || name == "Right"){
			return SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
		}else if(name == "UP" || name == "up" || name == "Up"){
			return SDL_CONTROLLER_BUTTON_DPAD_UP;
		}else if(name == "DOWN" || name == "down" || name == "Down"){
			return SDL_CONTROLLER_BUTTON_DPAD_DOWN;
		}
		return SDL_GameControllerGetButtonFromString(name.c_str());
	}

	SDL_GameControllerAxis input::getCAxisFromName(std::string name){
358
359
		//return SDL_GameControllerGetAxisFromString(name.c_str());
		return SDL_CONTROLLER_AXIS_INVALID;
360
361
	}

362
363
364
365
366
367
368
369
370
	controllerCursor input::getCCursorFromName(std::string name){
		if(name == "LEFT" || name == "left" || name == "Left"){
			return controllerCursor::left;
		}else if(name == "RIGHT" || name == "right" || name == "Right"){
			return controllerCursor::right;
		}
		return controllerCursor::none;
	}

371
	//RETURN
372
	bool input::isPressed(std::string id){
373
		auto it = mappings_.find(id);
374
		if(it == mappings_.end())return false;
375
376
		if((mappings_.at(it->first).type & key1) != 0){
			if(isKeyPressed(mappings_.at(it->first).keyCode1)){
377
378
379
				return true;
			}
		}
380
381
		if((mappings_.at(it->first).type & key2) != 0){
			if(isKeyPressed(mappings_.at(it->first).keyCode2)){
382
383
384
				return true;
			}
		}
385
386
		if((mappings_.at(it->first).type & mbutton) != 0){
			if(isMouseButtonPressed(mappings_.at(it->first).mbuttonCode)){
387
388
389
				return true;
			}
		}
390
391
		if((mappings_.at(it->first).type & cbutton) != 0){
			if(isControllerButtonPressed(mappings_.at(it->first).cbuttonCode)){
392
393
394
				return true;
			}
		}
395
		if(controllers_.size() > 0){
396
397
398
399
400
401
402
			if((mappings_.at(it->first).type & caxis) != 0){
				auto conIt = controllers_.find(firstController());
				if(conIt != controllers_.end()){
					auto axisIt = controllers_.at(conIt->first).axisMap.find(mappings_.at(it->first).caxisCode);
					if(controllers_.at(conIt->first).axisMap.at(axisIt->first).down == 1){
						return true;
					}
403
				}
404
			}
405
		}
406
407
408
		return false;
	}

409
	bool input::isDown(std::string id){
410
		auto it = mappings_.find(id);
411
		if(it == mappings_.end())return false;
412
413
		if((mappings_.at(it->first).type & key1) != 0){
			if(isKeyDown(mappings_.at(it->first).keyCode1)){
414
415
416
				return true;
			}
		}
417
418
		if((mappings_.at(it->first).type & key2) != 0){
			if(isKeyDown(mappings_.at(it->first).keyCode2)){
419
420
421
				return true;
			}
		}
422
423
		if((mappings_.at(it->first).type & mbutton) != 0){
			if(isMouseButtonDown(mappings_.at(it->first).mbuttonCode)){
424
425
426
				return true;
			}
		}
427
428
		if((mappings_.at(it->first).type & cbutton) != 0){
			if(isControllerButtonDown(mappings_.at(it->first).cbuttonCode)){
429
430
431
				return true;
			}
		}
432
433
434
		if((mappings_.at(it->first).type & caxis) != 0){
			if(!mappings_.at(it->first).negativAxis){
				if(controllerAxis(mappings_.at(it->first).caxisCode) > controllerAxisDeadZone_){
435
436
437
					return true;
				}
			}else{
438
				if(controllerAxis(mappings_.at(it->first).caxisCode) < -controllerAxisDeadZone_){
439
440
					return true;
				}
441
			}
442
		}
443
444
445
		return false;
	}

446
	bool input::isReleased(std::string id){
447
		auto it = mappings_.find(id);
448
		if(it == mappings_.end())return false;
449
450
		if((mappings_.at(it->first).type & key1) != 0){
			if(isKeyReleased(mappings_.at(it->first).keyCode1)){
451
452
453
				return true;
			}
		}
454
455
		if((mappings_.at(it->first).type & key2) != 0){
			if(isKeyReleased(mappings_.at(it->first).keyCode2)){
456
457
458
				return true;
			}
		}
459
460
		if((mappings_.at(it->first).type & mbutton) != 0){
			if(isMouseButtonReleased(mappings_.at(it->first).mbuttonCode)){
461
462
463
				return true;
			}
		}
464
465
		if((mappings_.at(it->first).type & cbutton) != 0){
			if(isControllerButtonReleased(mappings_.at(it->first).cbuttonCode)){
466
467
468
				return true;
			}
		}
469
		if(controllers_.size() > 0){
470
471
472
473
474
475
476
			if((mappings_.at(it->first).type & caxis) != 0){
				auto conIt = controllers_.find(firstController());
				if(conIt != controllers_.end()){
					auto axisIt = controllers_.at(conIt->first).axisMap.find(mappings_.at(it->first).caxisCode);
					if(controllers_.at(conIt->first).axisMap.at(axisIt->first).released){
						return true;
					}
477
				}
478
			}
479
		}
480
481
482
		return false;
	}

483
	int input::isKeyDown(SDL_Keycode key){
484
		return keyState_[SDL_GetScancodeFromKey(key)];
485
486
	}

487
	int input::isKeyDown(std::string key){
488
489
490
491
492
493
494
495
496
		return isKeyDown(getKeyCodeByMapping(key, 1)) || isKeyDown(getKeyCodeByMapping(key, 2));
	}

	bool input::isKeyPressed(SDL_Keycode key){
		auto it = keyMap_.find(key);
		if(it != keyMap_.end())return keyMap_.at(it->first) == 1;
		return false;
	}

497
	bool input::isKeyPressed(std::string key){
498
499
500
501
502
503
504
505
506
		return isKeyPressed(getKeyCodeByMapping(key, 1)) || isKeyPressed(getKeyCodeByMapping(key, 2));
	}

	bool input::isKeyReleased(SDL_Keycode key){
		auto it = keyReleasedMap_.find(key);
		if(it != keyReleasedMap_.end())return keyReleasedMap_.at(it->first);
		return false;
	}

507
	bool input::isKeyReleased(std::string key){
508
509
510
511
512
513
514
		return isKeyReleased(getKeyCodeByMapping(key, 1)) || isKeyReleased(getKeyCodeByMapping(key, 2));
	}

	bool input::isMouseButtonPressed(int button){
		auto it = mousePressedMap_.find(button);
		if(it != mousePressedMap_.end())return mousePressedMap_.at(it->first);
		return false;
515
516
	}

517
	bool input::isMouseButtonPressed(std::string button){
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
518
		int c = getMButtonCodeByMapping(button);
519
520
521
		return c != -1?isMouseButtonPressed(c):false;
	}

522
523
524
525
	bool input::isMouseButtonDown(int button){
		return SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(button);
	}

526
	bool input::isMouseButtonDown(std::string button){
527
528
529
530
		int c = getMButtonCodeByMapping(button);
		return c != -1?isMouseButtonDown(c):false;
	}

531
	bool input::isMouseButtonReleased(std::string button){
Benjamin 'Albsi' Albsmeier's avatar
Benjamin 'Albsi' Albsmeier committed
532
		int c = getMButtonCodeByMapping(button);
533
534
535
		return c != -1?isMouseButtonReleased(c):false;
	}

536
537
538
539
540
541
542
	bool input::isMouseButtonReleased(int button){
		auto it = mouseReleasedMap_.find(button);
		if(it != mouseReleasedMap_.end())return mouseReleasedMap_.at(it->first);
		return false;
	}

	bool input::isControllerButtonPressed(SDL_GameControllerButton button, int nr){
543
544
		if(nr == -1)nr = firstController();
		if(nr == -1)return false;
545
		auto it = controllers_.find(nr);
546
		if(controllers_.size()>0){
547
548
			auto btnIt = controllers_.at(it->first).controllerMap.find(button);
			return controllers_.at(it->first).controllerMap.at(btnIt->first);
549
550
		}
		return false;
551
552
	}

553
	bool input::isControllerButtonDown(SDL_GameControllerButton button, int nr){
554
555
		if(nr == -1)nr = firstController();
		if(nr == -1)return false;
556
		auto it = controllers_.find(nr);
557
		if(controllers_.size()>0){
558
			return SDL_GameControllerGetButton(controllers_.at(it->first).sdlController, button);
559
560
		}
		return false;
561
562
	}

563
	bool input::isControllerButtonReleased(SDL_GameControllerButton button, int nr){
564
565
		if(nr == -1)nr = firstController();
		if(nr == -1)return false;
566
		auto it = controllers_.find(nr);
567
		if(controllers_.size()>0){
568
569
			auto btnIt = controllers_.at(it->first).controllerReleasedMap.find(button);
			return btnIt->second;
570
571
		}
		return false;
572
573
	}

574
	float input::controllerAxis(SDL_GameControllerAxis axis, int nr){
575
576
		if(nr == -1)nr = firstController();
		if(nr == -1)return 0.f;
577
		auto it = controllers_.find(nr);
578
		if(controllers_.size() > 0){
579
580
			if(controllers_.at(it->first).active){
				float f = SDL_GameControllerGetAxis(controllers_.at(it->first).sdlController, axis) / controllerAxisMax_;
581
				return !(f < controllerAxisDeadZone_ && f > -controllerAxisDeadZone_)? f:0.f;;
582
			}
583
		}
584
585
		return 0.f;
	}
586

587
588
589
590
	bool input::isController(int id){
		auto it = controllers_.find(id);
		return SDL_IsGameController(id) && it != controllers_.end();
	}
591
}