Translated using Weblate (Chinese (Simplified))
[oweals/minetest.git] / src / client / joystick_controller.h
1 /*
2 Minetest
3 Copyright (C) 2016 est31, <MTest31@outlook.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21
22 #include "irrlichttypes_extrabloated.h"
23 #include "keys.h"
24 #include <bitset>
25 #include <vector>
26
27 enum JoystickAxis {
28         JA_SIDEWARD_MOVE,
29         JA_FORWARD_MOVE,
30
31         JA_FRUSTUM_HORIZONTAL,
32         JA_FRUSTUM_VERTICAL,
33
34         // To know the count of enum values
35         JA_COUNT,
36 };
37
38 struct JoystickAxisLayout {
39         u16 axis_id;
40         // -1 if to invert, 1 if to keep it.
41         int invert;
42 };
43
44
45 struct JoystickCombination {
46
47         virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const=0;
48
49         GameKeyType key;
50 };
51
52 struct JoystickButtonCmb : public JoystickCombination {
53
54         JoystickButtonCmb() = default;
55
56         JoystickButtonCmb(GameKeyType key, u32 filter_mask, u32 compare_mask) :
57                 filter_mask(filter_mask),
58                 compare_mask(compare_mask)
59         {
60                 this->key = key;
61         }
62
63         virtual ~JoystickButtonCmb() = default;
64
65         virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const;
66
67         u32 filter_mask;
68         u32 compare_mask;
69 };
70
71 struct JoystickAxisCmb : public JoystickCombination {
72
73         JoystickAxisCmb() = default;
74
75         JoystickAxisCmb(GameKeyType key, u16 axis_to_compare, int direction, s16 thresh) :
76                 axis_to_compare(axis_to_compare),
77                 direction(direction),
78                 thresh(thresh)
79         {
80                 this->key = key;
81         }
82
83         virtual ~JoystickAxisCmb() = default;
84
85         bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const override;
86
87         u16 axis_to_compare;
88
89         // if -1, thresh must be smaller than the axis value in order to trigger
90         // if  1, thresh must be bigger  than the axis value in order to trigger
91         int direction;
92         s16 thresh;
93 };
94
95 struct JoystickLayout {
96         std::vector<JoystickButtonCmb> button_keys;
97         std::vector<JoystickAxisCmb> axis_keys;
98         JoystickAxisLayout axes[JA_COUNT];
99         s16 axes_dead_border;
100 };
101
102 class JoystickController {
103
104 public:
105         JoystickController();
106
107         void onJoystickConnect(const std::vector<irr::SJoystickInfo> &joystick_infos);
108
109         bool handleEvent(const irr::SEvent::SJoystickEvent &ev);
110         void clear();
111
112         bool wasKeyDown(GameKeyType b)
113         {
114                 bool r = m_past_pressed_keys[b];
115                 m_past_pressed_keys[b] = false;
116                 return r;
117         }
118         bool getWasKeyDown(GameKeyType b)
119         {
120                 return m_past_pressed_keys[b];
121         }
122         void clearWasKeyDown(GameKeyType b)
123         {
124                 m_past_pressed_keys[b] = false;
125         }
126
127         bool wasKeyReleased(GameKeyType b)
128         {
129                 bool r = m_past_released_keys[b];
130                 m_past_released_keys[b] = false;
131                 return r;
132         }
133         bool getWasKeyReleased(GameKeyType b)
134         {
135                 return m_past_pressed_keys[b];
136         }
137         void clearWasKeyReleased(GameKeyType b)
138         {
139                 m_past_pressed_keys[b] = false;
140         }
141
142         bool isKeyDown(GameKeyType b)
143         {
144                 return m_pressed_keys[b];
145         }
146
147         s16 getAxis(JoystickAxis axis)
148         {
149                 return m_axes_vals[axis];
150         }
151
152         s16 getAxisWithoutDead(JoystickAxis axis);
153
154         f32 doubling_dtime;
155
156 private:
157         void setLayoutFromControllerName(const std::string &name);
158
159         JoystickLayout m_layout;
160
161         s16 m_axes_vals[JA_COUNT];
162
163         u8 m_joystick_id = 0;
164
165         std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_pressed_keys;
166
167         f32 m_internal_time;
168
169         f32 m_past_pressed_time[KeyType::INTERNAL_ENUM_COUNT];
170
171         std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_pressed_keys;
172         std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_released_keys;
173 };