File: KeyInput.cpp

package info (click to toggle)
spring 104.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 47,512 kB
  • sloc: cpp: 391,093; ansic: 79,943; python: 12,356; java: 12,201; awk: 5,889; sh: 1,826; xml: 655; makefile: 486; perl: 405; php: 211; objc: 194; sed: 2
file content (103 lines) | stat: -rw-r--r-- 2,369 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#include <cctype>

#include <SDL_keyboard.h>
#include <SDL_keycode.h>
#include <SDL_events.h>
#include <SDL_stdinc.h>

#include "KeyInput.h"

#include "System/Log/ILog.h"
/**
* @brief keys
*
* Array of possible keys, and which are being pressed
*/
static std::map<int, bool> keys;
static SDL_Keymod keyMods;


namespace KeyInput {
	bool IsKeyPressed(int idx) {
		auto it = keys.find(idx);
		if (it != keys.end())
			return (it->second != 0);
		return false;
	}

	void SetKeyModState(int mod, bool pressed) {
		if (pressed) {
			keyMods = SDL_Keymod(keyMods | mod);
		} else {
			keyMods = SDL_Keymod(keyMods & ~mod);
		}
	}

	bool GetKeyModState(int mod) {
		return (keyMods & mod);
	}

	/**
	* Tests SDL keystates and sets values in key array
	*/
	void Update(int currKeycode, int fakeMetaKey)
	{
		int numKeys = 0;
		auto state = SDL_GetKeyboardState(&numKeys);
		for (int i = 0; i < numKeys; ++i) {
			auto scancode = (SDL_Scancode)i;
			auto keycode  = SDL_GetKeyFromScancode(scancode);
			keys[keycode] = (state[scancode] != 0);
		}

		keyMods = SDL_GetModState();
		SetKeyModState(KMOD_GUI, keys[fakeMetaKey]);

		keys[SDLK_LALT]   = GetKeyModState(KMOD_ALT);
		keys[SDLK_LCTRL]  = GetKeyModState(KMOD_CTRL);
		keys[SDLK_LGUI]   = GetKeyModState(KMOD_GUI);
		keys[SDLK_LSHIFT] = GetKeyModState(KMOD_SHIFT);
	}

	const std::map<int,bool>& GetPressedKeys()
	{
		return keys;
	}

	int GetNormalizedKeySymbol(int sym)
	{
		if (sym <= SDLK_DELETE) {
			sym = tolower(sym);
		}
		else if (sym == SDLK_RSHIFT) { sym = SDLK_LSHIFT; }
		else if (sym == SDLK_RCTRL)  { sym = SDLK_LCTRL;  }
		else if (sym == SDLK_RGUI)   { sym = SDLK_LGUI;   }
		else if (sym == SDLK_RALT)   { sym = SDLK_LALT;   }

		return sym;
	}

	void ReleaseAllKeys()
	{
		for (auto key: keys) {
			auto keycode  = (SDL_Keycode)key.first;
			auto scancode = SDL_GetScancodeFromKey(keycode);

			if (keycode == SDLK_NUMLOCKCLEAR || keycode == SDLK_CAPSLOCK || keycode == SDLK_SCROLLLOCK)
				continue;

			if (!KeyInput::IsKeyPressed(keycode))
				continue;

			SDL_Event event;
			event.type = event.key.type = SDL_KEYUP;
			event.key.state = SDL_RELEASED;
			event.key.keysym.sym = keycode;
			event.key.keysym.mod = 0;
			event.key.keysym.scancode = scancode;
			SDL_PushEvent(&event);
		}
	}
} // namespace KeyInput