CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Input/InputState.h
Views: 1401
1
#pragma once
2
3
// For more detailed and configurable input, implement NativeTouch, NativeKey and NativeAxis and do your
4
// own mapping. Might later move the mapping system from PPSSPP to native.
5
6
#include <unordered_map>
7
#include <vector>
8
#include <string>
9
10
#include "Common/Input/KeyCodes.h"
11
#include "Common/Log.h"
12
13
// Default device IDs
14
15
enum InputDeviceID {
16
DEVICE_ID_ANY = -1, // Represents any device ID
17
DEVICE_ID_DEFAULT = 0, // Old Android
18
DEVICE_ID_KEYBOARD = 1, // PC keyboard, android keyboards
19
DEVICE_ID_MOUSE = 2, // PC mouse only (not touchscreen!)
20
DEVICE_ID_PAD_0 = 10, // Generic joypads
21
DEVICE_ID_PAD_1 = 11, // these should stay as contiguous numbers
22
DEVICE_ID_PAD_2 = 12,
23
DEVICE_ID_PAD_3 = 13,
24
DEVICE_ID_PAD_4 = 14,
25
DEVICE_ID_PAD_5 = 15,
26
DEVICE_ID_PAD_6 = 16,
27
DEVICE_ID_PAD_7 = 17,
28
DEVICE_ID_PAD_8 = 18,
29
DEVICE_ID_PAD_9 = 19,
30
DEVICE_ID_XINPUT_0 = 20, // XInput joypads
31
DEVICE_ID_XINPUT_1 = 21,
32
DEVICE_ID_XINPUT_2 = 22,
33
DEVICE_ID_XINPUT_3 = 23,
34
DEVICE_ID_ACCELEROMETER = 30, // no longer used
35
DEVICE_ID_XR_CONTROLLER_LEFT = 40,
36
DEVICE_ID_XR_CONTROLLER_RIGHT = 41,
37
DEVICE_ID_TOUCH = 42,
38
DEVICE_ID_COUNT,
39
};
40
41
inline InputDeviceID operator +(InputDeviceID deviceID, int addend) {
42
return (InputDeviceID)((int)deviceID + addend);
43
}
44
45
//number of contiguous generic joypad IDs
46
const int MAX_NUM_PADS = 10;
47
48
const char *GetDeviceName(int deviceId);
49
50
#ifndef MAX_KEYQUEUESIZE
51
#define MAX_KEYQUEUESIZE 20
52
#endif
53
54
// Represents a single bindable key
55
static const int AXIS_BIND_NKCODE_START = 4000;
56
57
inline int TranslateKeyCodeToAxis(int keyCode, int *direction) {
58
if (keyCode < AXIS_BIND_NKCODE_START)
59
return 0;
60
int k = keyCode - AXIS_BIND_NKCODE_START;
61
// Even/odd for direction.
62
if (direction)
63
*direction = k & 1 ? -1 : 1;
64
return k / 2;
65
}
66
67
class InputMapping {
68
private:
69
static inline int TranslateKeyCodeFromAxis(int axisId, int direction) {
70
return AXIS_BIND_NKCODE_START + axisId * 2 + (direction < 0 ? 1 : 0);
71
}
72
public:
73
InputMapping() : deviceId(DEVICE_ID_DEFAULT), keyCode(0) {}
74
// From a key mapping
75
InputMapping(InputDeviceID _deviceId, int key) : deviceId(_deviceId), keyCode(key) {}
76
// From an axis
77
InputMapping(InputDeviceID _deviceId, int axis, int direction) : deviceId(_deviceId), keyCode(TranslateKeyCodeFromAxis(axis, direction)) {
78
_dbg_assert_(direction != 0);
79
}
80
81
static InputMapping FromConfigString(std::string_view str);
82
std::string ToConfigString() const;
83
84
InputDeviceID deviceId;
85
int keyCode; // Can also represent an axis with direction, if encoded properly.
86
87
bool IsAxis() const {
88
return keyCode >= AXIS_BIND_NKCODE_START;
89
}
90
91
int Axis(int *direction) const {
92
_dbg_assert_(IsAxis());
93
return TranslateKeyCodeToAxis(keyCode, direction);
94
}
95
96
InputMapping FlipDirection() const {
97
_dbg_assert_(IsAxis());
98
InputMapping other = *this;
99
other.keyCode ^= 1;
100
return other;
101
}
102
103
// If you want to use std::find and match ANY, you need to perform an explicit search for that.
104
bool operator < (const InputMapping &other) const {
105
if (deviceId < other.deviceId) return true;
106
if (deviceId > other.deviceId) return false;
107
if (keyCode < other.keyCode) return true;
108
return false;
109
}
110
// Needed for composition.
111
bool operator > (const InputMapping &other) const {
112
if (deviceId > other.deviceId) return true;
113
if (deviceId < other.deviceId) return false;
114
if (keyCode > other.keyCode) return true;
115
return false;
116
}
117
118
// This one is iffy with the != ANY checks. Should probably be a named method.
119
bool operator == (const InputMapping &other) const {
120
if (deviceId != other.deviceId && deviceId != DEVICE_ID_ANY && other.deviceId != DEVICE_ID_ANY) return false;
121
if (keyCode != other.keyCode) return false;
122
return true;
123
}
124
bool operator != (const InputMapping &other) const {
125
return !(*this == other);
126
}
127
128
void FormatDebug(char *buffer, size_t bufSize) const;
129
};
130
131
enum {
132
TOUCH_MOVE = 1 << 0,
133
TOUCH_DOWN = 1 << 1,
134
TOUCH_UP = 1 << 2,
135
TOUCH_CANCEL = 1 << 3, // Sent by scrollviews to their children when they detect a scroll
136
TOUCH_WHEEL = 1 << 4, // Scrollwheel event. Usually only affects Y but can potentially affect X.
137
TOUCH_MOUSE = 1 << 5, // Identifies that this touch event came from a mouse
138
TOUCH_RELEASE_ALL = 1 << 6, // Useful for app focus switches when events may be lost.
139
140
// These are the Android getToolType() codes, shifted by 10.
141
TOUCH_TOOL_MASK = 7 << 10,
142
TOUCH_TOOL_UNKNOWN = 0 << 10,
143
TOUCH_TOOL_FINGER = 1 << 10,
144
TOUCH_TOOL_STYLUS = 2 << 10,
145
TOUCH_TOOL_MOUSE = 3 << 10,
146
TOUCH_TOOL_ERASER = 4 << 10,
147
};
148
149
// Used for asynchronous touch input.
150
// DOWN is always on its own.
151
// MOVE and UP can be combined.
152
struct TouchInput {
153
float x;
154
float y;
155
int id; // Needs to be <= GestureDetector::MAX_PTRS (10.)
156
int flags;
157
double timestamp;
158
};
159
160
#undef KEY_DOWN
161
#undef KEY_UP
162
163
enum {
164
KEY_DOWN = 1 << 0,
165
KEY_UP = 1 << 1,
166
KEY_HASWHEELDELTA = 1 << 2,
167
KEY_IS_REPEAT = 1 << 3,
168
KEY_CHAR = 1 << 4, // Unicode character input. Cannot detect keyups of these so KEY_DOWN and KEY_UP are zero when this is set.
169
};
170
171
struct KeyInput {
172
KeyInput() {}
173
KeyInput(InputDeviceID devId, InputKeyCode code, int fl) : deviceId(devId), keyCode(code), flags(fl) {}
174
KeyInput(InputDeviceID devId, int unicode) : deviceId(devId), unicodeChar(unicode), flags(KEY_CHAR) {}
175
InputDeviceID deviceId;
176
union {
177
InputKeyCode keyCode; // Android keycodes are the canonical keycodes, everyone else map to them.
178
int unicodeChar; // for KEY_CHAR
179
};
180
int flags;
181
};
182
183
struct AxisInput {
184
InputDeviceID deviceId;
185
InputAxis axisId;
186
float value;
187
};
188
189
// Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest..
190
extern std::vector<InputMapping> dpadKeys;
191
extern std::vector<InputMapping> confirmKeys;
192
extern std::vector<InputMapping> cancelKeys;
193
extern std::vector<InputMapping> infoKeys;
194
extern std::vector<InputMapping> tabLeftKeys;
195
extern std::vector<InputMapping> tabRightKeys;
196
void SetDPadKeys(const std::vector<InputMapping> &leftKey, const std::vector<InputMapping> &rightKey,
197
const std::vector<InputMapping> &upKey, const std::vector<InputMapping> &downKey);
198
void SetConfirmCancelKeys(const std::vector<InputMapping> &confirm, const std::vector<InputMapping> &cancel);
199
void SetTabLeftRightKeys(const std::vector<InputMapping> &tabLeft, const std::vector<InputMapping> &tabRight);
200
void SetInfoKeys(const std::vector<InputMapping> &info);
201
202
// 0 means unknown (attempt autodetect), -1 means flip, 1 means original direction.
203
void SetAnalogFlipY(const std::unordered_map<InputDeviceID, int> &flipYByDeviceId);
204
int GetAnalogYDirection(InputDeviceID deviceId);
205
206