1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef ENGINE_CLIENT_INPUT_H |
4 | #define ENGINE_CLIENT_INPUT_H |
5 | |
6 | #include <SDL_events.h> |
7 | #include <SDL_joystick.h> |
8 | #include <engine/console.h> |
9 | |
10 | #include <engine/input.h> |
11 | #include <engine/keys.h> |
12 | |
13 | #include <string> |
14 | #include <vector> |
15 | |
16 | class IEngineGraphics; |
17 | |
18 | class CInput : public IEngineInput |
19 | { |
20 | public: |
21 | class CJoystick : public IJoystick |
22 | { |
23 | friend class CInput; |
24 | |
25 | CInput *m_pInput; |
26 | int m_Index; |
27 | char m_aName[64]; |
28 | char m_aGUID[34]; |
29 | SDL_JoystickID m_InstanceId; |
30 | int m_NumAxes; |
31 | int m_NumButtons; |
32 | int m_NumBalls; |
33 | int m_NumHats; |
34 | SDL_Joystick *m_pDelegate; |
35 | |
36 | CInput *Input() { return m_pInput; } |
37 | |
38 | public: |
39 | CJoystick() {} |
40 | CJoystick(CInput *pInput, int Index, SDL_Joystick *pDelegate); |
41 | virtual ~CJoystick() = default; |
42 | |
43 | int GetIndex() const override { return m_Index; } |
44 | const char *GetName() const override { return m_aName; } |
45 | const char *GetGUID() const { return m_aGUID; } |
46 | SDL_JoystickID GetInstanceId() const { return m_InstanceId; } |
47 | int GetNumAxes() const override { return m_NumAxes; } |
48 | int GetNumButtons() const override { return m_NumButtons; } |
49 | int GetNumBalls() const override { return m_NumBalls; } |
50 | int GetNumHats() const override { return m_NumHats; } |
51 | float GetAxisValue(int Axis) override; |
52 | void GetHatValue(int Hat, int (&HatKeys)[2]) override; |
53 | bool Relative(float *pX, float *pY) override; |
54 | bool Absolute(float *pX, float *pY) override; |
55 | |
56 | static void GetJoystickHatKeys(int Hat, int HatValue, int (&HatKeys)[2]); |
57 | }; |
58 | |
59 | private: |
60 | IEngineGraphics *m_pGraphics; |
61 | IConsole *m_pConsole; |
62 | |
63 | IEngineGraphics *Graphics() { return m_pGraphics; } |
64 | IConsole *Console() { return m_pConsole; } |
65 | |
66 | // joystick |
67 | std::vector<CJoystick> m_vJoysticks; |
68 | CJoystick *m_pActiveJoystick = nullptr; |
69 | void InitJoysticks(); |
70 | bool OpenJoystick(int JoystickIndex); |
71 | void CloseJoysticks(); |
72 | void UpdateActiveJoystick(); |
73 | static void ConchainJoystickGuidChanged(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
74 | float GetJoystickDeadzone(); |
75 | |
76 | bool m_InputGrabbed; |
77 | char *m_pClipboardText; |
78 | |
79 | bool m_MouseFocus; |
80 | #if defined(CONF_PLATFORM_ANDROID) |
81 | ivec2 m_LastMousePos = ivec2(0, 0); // No relative mouse on Android |
82 | int m_NumBackPresses = 0; |
83 | bool m_BackButtonReleased = true; |
84 | int64_t m_LastBackPress = -1; |
85 | #endif |
86 | |
87 | // IME support |
88 | char m_aComposition[MAX_COMPOSITION_ARRAY_SIZE]; |
89 | int m_CompositionCursor; |
90 | int m_CompositionLength; |
91 | std::vector<std::string> m_vCandidates; |
92 | int m_CandidateSelectedIndex; |
93 | |
94 | // events |
95 | std::vector<CEvent> m_vInputEvents; |
96 | int64_t m_LastUpdate; |
97 | float m_UpdateTime; |
98 | void AddKeyEvent(int Key, int Flags); |
99 | void AddTextEvent(const char *pText); |
100 | |
101 | // quick access to input |
102 | uint32_t m_aInputCount[g_MaxKeys]; |
103 | unsigned char m_aInputState[g_MaxKeys]; |
104 | uint32_t m_InputCounter; |
105 | |
106 | void UpdateMouseState(); |
107 | void UpdateJoystickState(); |
108 | void HandleJoystickAxisMotionEvent(const SDL_JoyAxisEvent &Event); |
109 | void HandleJoystickButtonEvent(const SDL_JoyButtonEvent &Event); |
110 | void HandleJoystickHatMotionEvent(const SDL_JoyHatEvent &Event); |
111 | void HandleJoystickAddedEvent(const SDL_JoyDeviceEvent &Event); |
112 | void HandleJoystickRemovedEvent(const SDL_JoyDeviceEvent &Event); |
113 | |
114 | char m_aDropFile[IO_MAX_PATH_LENGTH]; |
115 | |
116 | bool KeyState(int Key) const; |
117 | |
118 | void ProcessSystemMessage(SDL_SysWMmsg *pMsg); |
119 | |
120 | public: |
121 | CInput(); |
122 | |
123 | void Init() override; |
124 | int Update() override; |
125 | void Shutdown() override; |
126 | |
127 | void ConsumeEvents(std::function<void(const CEvent &Event)> Consumer) const override; |
128 | void Clear() override; |
129 | float GetUpdateTime() const override; |
130 | |
131 | bool ModifierIsPressed() const override { return KeyState(Key: KEY_LCTRL) || KeyState(Key: KEY_RCTRL) || KeyState(Key: KEY_LGUI) || KeyState(Key: KEY_RGUI); } |
132 | bool ShiftIsPressed() const override { return KeyState(Key: KEY_LSHIFT) || KeyState(Key: KEY_RSHIFT); } |
133 | bool AltIsPressed() const override { return KeyState(Key: KEY_LALT) || KeyState(Key: KEY_RALT); } |
134 | bool KeyIsPressed(int Key) const override { return KeyState(Key); } |
135 | bool KeyPress(int Key, bool CheckCounter) const override { return CheckCounter ? (m_aInputCount[Key] == m_InputCounter) : m_aInputCount[Key]; } |
136 | |
137 | size_t NumJoysticks() const override { return m_vJoysticks.size(); } |
138 | CJoystick *GetJoystick(size_t Index) override { return &m_vJoysticks[Index]; } |
139 | CJoystick *GetActiveJoystick() override { return m_pActiveJoystick; } |
140 | void SetActiveJoystick(size_t Index) override; |
141 | |
142 | bool MouseRelative(float *pX, float *pY) override; |
143 | void MouseModeAbsolute() override; |
144 | void MouseModeRelative() override; |
145 | void NativeMousePos(int *pX, int *pY) const override; |
146 | bool NativeMousePressed(int Index) override; |
147 | |
148 | const char *GetClipboardText() override; |
149 | void SetClipboardText(const char *pText) override; |
150 | |
151 | void StartTextInput() override; |
152 | void StopTextInput() override; |
153 | const char *GetComposition() const override { return m_aComposition; } |
154 | bool HasComposition() const override { return m_CompositionLength != COMP_LENGTH_INACTIVE; } |
155 | int GetCompositionCursor() const override { return m_CompositionCursor; } |
156 | int GetCompositionLength() const override { return m_CompositionLength; } |
157 | const char *GetCandidate(int Index) const override { return m_vCandidates[Index].c_str(); } |
158 | int GetCandidateCount() const override { return m_vCandidates.size(); } |
159 | int GetCandidateSelectedIndex() const override { return m_CandidateSelectedIndex; } |
160 | void SetCompositionWindowPosition(float X, float Y, float H) override; |
161 | |
162 | bool GetDropFile(char *aBuf, int Len) override; |
163 | }; |
164 | |
165 | #endif |
166 | |