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 | bool m_MouseDoubleClick; |
81 | #if defined(CONF_PLATFORM_ANDROID) // No relative mouse on Android |
82 | ivec2 m_LastMousePos = ivec2(0, 0); |
83 | #endif |
84 | |
85 | // IME support |
86 | char m_aComposition[MAX_COMPOSITION_ARRAY_SIZE]; |
87 | int m_CompositionCursor; |
88 | int m_CompositionLength; |
89 | std::vector<std::string> m_vCandidates; |
90 | int m_CandidateSelectedIndex; |
91 | |
92 | void AddEvent(char *pText, int Key, int Flags); |
93 | void Clear() override; |
94 | bool IsEventValid(const CEvent &Event) const override { return Event.m_InputCount == m_InputCounter; } |
95 | |
96 | // quick access to input |
97 | unsigned short m_aInputCount[g_MaxKeys]; // tw-KEY |
98 | unsigned char m_aInputState[g_MaxKeys]; // SDL_SCANCODE |
99 | int m_InputCounter; |
100 | |
101 | void UpdateMouseState(); |
102 | void UpdateJoystickState(); |
103 | void HandleJoystickAxisMotionEvent(const SDL_JoyAxisEvent &Event); |
104 | void HandleJoystickButtonEvent(const SDL_JoyButtonEvent &Event); |
105 | void HandleJoystickHatMotionEvent(const SDL_JoyHatEvent &Event); |
106 | void HandleJoystickAddedEvent(const SDL_JoyDeviceEvent &Event); |
107 | void HandleJoystickRemovedEvent(const SDL_JoyDeviceEvent &Event); |
108 | |
109 | char m_aDropFile[IO_MAX_PATH_LENGTH]; |
110 | |
111 | bool KeyState(int Key) const; |
112 | |
113 | void ProcessSystemMessage(SDL_SysWMmsg *pMsg); |
114 | |
115 | public: |
116 | CInput(); |
117 | |
118 | void Init() override; |
119 | int Update() override; |
120 | void Shutdown() override; |
121 | |
122 | bool ModifierIsPressed() const override { return KeyState(Key: KEY_LCTRL) || KeyState(Key: KEY_RCTRL) || KeyState(Key: KEY_LGUI) || KeyState(Key: KEY_RGUI); } |
123 | bool ShiftIsPressed() const override { return KeyState(Key: KEY_LSHIFT) || KeyState(Key: KEY_RSHIFT); } |
124 | bool AltIsPressed() const override { return KeyState(Key: KEY_LALT) || KeyState(Key: KEY_RALT); } |
125 | bool KeyIsPressed(int Key) const override { return KeyState(Key); } |
126 | bool KeyPress(int Key, bool CheckCounter) const override { return CheckCounter ? (m_aInputCount[Key] == m_InputCounter) : m_aInputCount[Key]; } |
127 | |
128 | size_t NumJoysticks() const override { return m_vJoysticks.size(); } |
129 | CJoystick *GetJoystick(size_t Index) override { return &m_vJoysticks[Index]; } |
130 | CJoystick *GetActiveJoystick() override { return m_pActiveJoystick; } |
131 | void SetActiveJoystick(size_t Index) override; |
132 | |
133 | bool MouseRelative(float *pX, float *pY) override; |
134 | void MouseModeAbsolute() override; |
135 | void MouseModeRelative() override; |
136 | void NativeMousePos(int *pX, int *pY) const override; |
137 | bool NativeMousePressed(int Index) override; |
138 | bool MouseDoubleClick() override; |
139 | |
140 | const char *GetClipboardText() override; |
141 | void SetClipboardText(const char *pText) override; |
142 | |
143 | void StartTextInput() override; |
144 | void StopTextInput() override; |
145 | const char *GetComposition() const override { return m_aComposition; } |
146 | bool HasComposition() const override { return m_CompositionLength != COMP_LENGTH_INACTIVE; } |
147 | int GetCompositionCursor() const override { return m_CompositionCursor; } |
148 | int GetCompositionLength() const override { return m_CompositionLength; } |
149 | const char *GetCandidate(int Index) const override { return m_vCandidates[Index].c_str(); } |
150 | int GetCandidateCount() const override { return m_vCandidates.size(); } |
151 | int GetCandidateSelectedIndex() const override { return m_CandidateSelectedIndex; } |
152 | void SetCompositionWindowPosition(float X, float Y, float H) override; |
153 | |
154 | bool GetDropFile(char *aBuf, int Len) override; |
155 | }; |
156 | |
157 | #endif |
158 | |