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/UI/GamepadEmu.h
Views: 1401
1
// Copyright (c) 2012- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
#include "Common/Input/InputState.h"
21
#include "Common/Render/DrawBuffer.h"
22
23
#include "Common/UI/View.h"
24
#include "Common/UI/ViewGroup.h"
25
#include "Core/CoreParameter.h"
26
#include "Core/HLE/sceCtrl.h"
27
#include "UI/EmuScreen.h"
28
29
class GamepadView : public UI::View {
30
public:
31
GamepadView(const char *key, UI::LayoutParams *layoutParams);
32
33
bool Key(const KeyInput &input) override {
34
return false;
35
}
36
std::string DescribeText() const override;
37
38
protected:
39
std::string key_;
40
};
41
42
class MultiTouchButton : public GamepadView {
43
public:
44
MultiTouchButton(const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
45
: GamepadView(key, layoutParams), scale_(scale), bgImg_(bgImg), bgDownImg_(bgDownImg), img_(img) {
46
}
47
48
bool Touch(const TouchInput &input) override;
49
void Draw(UIContext &dc) override;
50
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
51
virtual bool IsDown() { return pointerDownMask_ != 0; }
52
// chainable
53
MultiTouchButton *FlipImageH(bool flip) { flipImageH_ = flip; return this; }
54
MultiTouchButton *SetAngle(float angle) { angle_ = angle; bgAngle_ = angle; return this; }
55
MultiTouchButton *SetAngle(float angle, float bgAngle) { angle_ = angle; bgAngle_ = bgAngle; return this; }
56
57
protected:
58
uint32_t pointerDownMask_ = 0;
59
float scale_;
60
61
private:
62
ImageID bgImg_;
63
ImageID bgDownImg_;
64
ImageID img_;
65
float bgAngle_ = 0.0f;
66
float angle_ = 0.0f;
67
bool flipImageH_ = false;
68
};
69
70
class BoolButton : public MultiTouchButton {
71
public:
72
BoolButton(bool *value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
73
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), value_(value) {
74
75
}
76
bool Touch(const TouchInput &input) override;
77
bool IsDown() override { return *value_; }
78
79
UI::Event OnChange;
80
81
private:
82
bool *value_;
83
};
84
85
class PSPButton : public MultiTouchButton {
86
public:
87
PSPButton(int pspButtonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
88
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) {
89
}
90
bool Touch(const TouchInput &input) override;
91
bool IsDown() override;
92
93
private:
94
int pspButtonBit_;
95
};
96
97
class PSPDpad : public GamepadView {
98
public:
99
PSPDpad(ImageID arrowIndex, const char *key, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams);
100
101
bool Touch(const TouchInput &input) override;
102
void Draw(UIContext &dc) override;
103
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
104
105
private:
106
void ProcessTouch(float x, float y, bool down);
107
ImageID arrowIndex_;
108
ImageID arrowDownIndex_;
109
ImageID overlayIndex_;
110
111
float scale_;
112
float spacing_;
113
114
int dragPointerId_;
115
int down_;
116
};
117
118
class PSPStick : public GamepadView {
119
public:
120
PSPStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams);
121
122
bool Touch(const TouchInput &input) override;
123
void Draw(UIContext &dc) override;
124
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
125
126
protected:
127
int dragPointerId_;
128
ImageID bgImg_;
129
ImageID stickImageIndex_;
130
ImageID stickDownImg_;
131
132
int stick_;
133
float stick_size_;
134
float scale_;
135
136
float centerX_;
137
float centerY_;
138
139
private:
140
void ProcessTouch(float x, float y, bool down);
141
};
142
143
class PSPCustomStick : public PSPStick {
144
public:
145
PSPCustomStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams);
146
147
bool Touch(const TouchInput &input) override;
148
void Draw(UIContext &dc) override;
149
150
private:
151
void ProcessTouch(float x, float y, bool down);
152
153
float posX_ = 0.0f;
154
float posY_ = 0.0f;
155
};
156
157
//initializes the layout from Config. if a default layout does not exist,
158
//it sets up default values
159
void InitPadLayout(float xres, float yres, float globalScale = 1.15f);
160
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause, bool showPauseButton, ControlMapper* controllMapper);
161
162
const int D_pad_Radius = 50;
163
const int baseActionButtonSpacing = 60;
164
165
class CustomButton : public MultiTouchButton {
166
public:
167
CustomButton(uint64_t pspButtonBit, const char *key, bool toggle, bool repeat, ControlMapper* controllMapper, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, bool invertedContextDimension, UI::LayoutParams *layoutParams)
168
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), repeat_(repeat), controlMapper_(controllMapper), on_(false), invertedContextDimension_(invertedContextDimension) {
169
}
170
bool Touch(const TouchInput &input) override;
171
void Update() override;
172
bool IsDown() override;
173
174
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
175
private:
176
uint64_t pspButtonBit_;
177
bool toggle_;
178
bool repeat_;
179
int pressedFrames_ = 0;
180
ControlMapper* controlMapper_;
181
bool on_;
182
bool invertedContextDimension_; // Swap width and height
183
};
184
185
class GestureGamepad : public UI::View {
186
public:
187
GestureGamepad(ControlMapper* controllMapper) : controlMapper_(controllMapper) {};
188
189
bool Touch(const TouchInput &input) override;
190
void Update() override;
191
void Draw(UIContext &dc) override;
192
193
protected:
194
195
float lastX_ = 0.0f;
196
float lastY_ = 0.0f;
197
float deltaX_ = 0.0f;
198
float deltaY_ = 0.0f;
199
float downX_;
200
float downY_;
201
float lastTapRelease_ = 0.0f;
202
float lastTouchDown_ = 0.0f;
203
int dragPointerId_ = -1;
204
bool swipeLeftReleased_ = true;
205
bool swipeRightReleased_ = true;
206
bool swipeUpReleased_ = true;
207
bool swipeDownReleased_ = true;
208
bool haveDoubleTapped_ = false;
209
ControlMapper* controlMapper_;
210
};
211
212
// Just edit this to add new image, shape or button function
213
namespace CustomKeyData {
214
// Image list
215
struct keyImage {
216
ImageID i; // ImageID
217
float r; // Rotation angle in degree
218
};
219
static const keyImage customKeyImages[] = {
220
{ ImageID("I_1"), 0.0f },
221
{ ImageID("I_2"), 0.0f },
222
{ ImageID("I_3"), 0.0f },
223
{ ImageID("I_4"), 0.0f },
224
{ ImageID("I_5"), 0.0f },
225
{ ImageID("I_6"), 0.0f },
226
{ ImageID("I_A"), 0.0f },
227
{ ImageID("I_B"), 0.0f },
228
{ ImageID("I_C"), 0.0f },
229
{ ImageID("I_D"), 0.0f },
230
{ ImageID("I_E"), 0.0f },
231
{ ImageID("I_F"), 0.0f },
232
{ ImageID("I_CIRCLE"), 0.0f },
233
{ ImageID("I_CROSS"), 0.0f },
234
{ ImageID("I_SQUARE"), 0.0f },
235
{ ImageID("I_TRIANGLE"), 0.0f },
236
{ ImageID("I_L"), 0.0f },
237
{ ImageID("I_R"), 0.0f },
238
{ ImageID("I_START"), 0.0f },
239
{ ImageID("I_SELECT"), 0.0f },
240
{ ImageID("I_CROSS"), 45.0f },
241
{ ImageID("I_SQUARE"), 45.0f },
242
{ ImageID("I_TRIANGLE"), 180.0f },
243
{ ImageID("I_ARROW"), 90.0f},
244
{ ImageID("I_ARROW"), 270.0f},
245
{ ImageID("I_ARROW"), 0.0f},
246
{ ImageID("I_ARROW"), 180.0f},
247
{ ImageID("I_GEAR"), 0.0f},
248
{ ImageID("I_ROTATE_LEFT"), 0.0f},
249
{ ImageID("I_ROTATE_RIGHT"), 0.0f},
250
{ ImageID("I_ARROW_LEFT"), 0.0f},
251
{ ImageID("I_ARROW_RIGHT"), 0.0f},
252
{ ImageID("I_ARROW_UP"), 0.0f},
253
{ ImageID("I_ARROW_DOWN"), 0.0f},
254
{ ImageID("I_THREE_DOTS"), 0.0f},
255
{ ImageID("I_EMPTY"), 0.0f},
256
};
257
258
// Shape list
259
struct keyShape {
260
ImageID i; // ImageID
261
ImageID l; // ImageID line version
262
float r; // Rotation angle in dregree
263
bool f; // Flip Horizontally
264
bool d; // Invert height and width for context dimension (for example for 90 degree rot)
265
};
266
static const keyShape customKeyShapes[] = {
267
{ ImageID("I_ROUND"), ImageID("I_ROUND_LINE"), 0.0f, false, false },
268
{ ImageID("I_RECT"), ImageID("I_RECT_LINE"), 0.0f, false, false },
269
{ ImageID("I_RECT"), ImageID("I_RECT_LINE"), 90.0f, false, true },
270
{ ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, false, false },
271
{ ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, true, false },
272
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 270.0f, false, true },
273
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 90.0f, false, true },
274
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 180.0f, false, false },
275
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 0.0f, false, false },
276
{ ImageID("I_SQUARE_SHAPE"), ImageID("I_SQUARE_SHAPE_LINE"), 0.0f, false, false },
277
{ ImageID("I_EMPTY"), ImageID("I_EMPTY"), 0.0f, false, false },
278
};
279
280
// Button list
281
struct keyList {
282
ImageID i; // UI ImageID
283
uint32_t c; // Key code
284
};
285
static const keyList customKeyList[] = {
286
{ ImageID("I_SQUARE"), CTRL_SQUARE },
287
{ ImageID("I_TRIANGLE"), CTRL_TRIANGLE },
288
{ ImageID("I_CIRCLE"), CTRL_CIRCLE },
289
{ ImageID("I_CROSS"), CTRL_CROSS },
290
{ ImageID::invalid(), CTRL_UP },
291
{ ImageID::invalid(), CTRL_DOWN },
292
{ ImageID::invalid(), CTRL_LEFT },
293
{ ImageID::invalid(), CTRL_RIGHT },
294
{ ImageID("I_START"), CTRL_START },
295
{ ImageID("I_SELECT"), CTRL_SELECT },
296
{ ImageID("I_L"), CTRL_LTRIGGER },
297
{ ImageID("I_R"), CTRL_RTRIGGER },
298
{ ImageID::invalid(), VIRTKEY_RAPID_FIRE },
299
{ ImageID::invalid(), VIRTKEY_FASTFORWARD },
300
{ ImageID::invalid(), VIRTKEY_SPEED_TOGGLE },
301
{ ImageID::invalid(), VIRTKEY_REWIND },
302
{ ImageID::invalid(), VIRTKEY_SAVE_STATE },
303
{ ImageID::invalid(), VIRTKEY_LOAD_STATE },
304
{ ImageID::invalid(), VIRTKEY_NEXT_SLOT },
305
#if !defined(MOBILE_DEVICE)
306
{ ImageID::invalid(), VIRTKEY_TOGGLE_FULLSCREEN },
307
#endif
308
{ ImageID::invalid(), VIRTKEY_SPEED_CUSTOM1 },
309
{ ImageID::invalid(), VIRTKEY_SPEED_CUSTOM2 },
310
{ ImageID::invalid(), VIRTKEY_TEXTURE_DUMP },
311
{ ImageID::invalid(), VIRTKEY_TEXTURE_REPLACE },
312
{ ImageID::invalid(), VIRTKEY_SCREENSHOT },
313
{ ImageID::invalid(), VIRTKEY_MUTE_TOGGLE },
314
{ ImageID::invalid(), VIRTKEY_OPENCHAT },
315
{ ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CW },
316
{ ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CCW },
317
{ ImageID::invalid(), VIRTKEY_PAUSE },
318
{ ImageID::invalid(), VIRTKEY_RESET_EMULATION },
319
{ ImageID::invalid(), VIRTKEY_DEVMENU },
320
#ifndef MOBILE_DEVICE
321
{ ImageID::invalid(), VIRTKEY_RECORD },
322
#endif
323
{ ImageID::invalid(), VIRTKEY_AXIS_X_MIN },
324
{ ImageID::invalid(), VIRTKEY_AXIS_Y_MIN },
325
{ ImageID::invalid(), VIRTKEY_AXIS_X_MAX },
326
{ ImageID::invalid(), VIRTKEY_AXIS_Y_MAX },
327
{ ImageID::invalid(), VIRTKEY_PREVIOUS_SLOT },
328
};
329
static_assert(ARRAY_SIZE(customKeyList) <= 64, "Too many key for a uint64_t bit mask");
330
};
331
332
// Gesture key only have virtual button that can work without constant press
333
namespace GestureKey {
334
static const uint32_t keyList[] = {
335
CTRL_SQUARE,
336
CTRL_TRIANGLE,
337
CTRL_CIRCLE,
338
CTRL_CROSS,
339
CTRL_UP,
340
CTRL_DOWN,
341
CTRL_LEFT,
342
CTRL_RIGHT,
343
CTRL_START,
344
CTRL_SELECT,
345
CTRL_LTRIGGER,
346
CTRL_RTRIGGER,
347
VIRTKEY_AXIS_Y_MAX,
348
VIRTKEY_AXIS_Y_MIN,
349
VIRTKEY_AXIS_X_MIN,
350
VIRTKEY_AXIS_X_MAX,
351
VIRTKEY_SPEED_TOGGLE,
352
VIRTKEY_REWIND,
353
VIRTKEY_SAVE_STATE,
354
VIRTKEY_LOAD_STATE,
355
VIRTKEY_PREVIOUS_SLOT,
356
VIRTKEY_NEXT_SLOT,
357
VIRTKEY_TEXTURE_DUMP,
358
VIRTKEY_TEXTURE_REPLACE,
359
VIRTKEY_SCREENSHOT,
360
VIRTKEY_MUTE_TOGGLE,
361
VIRTKEY_OPENCHAT,
362
VIRTKEY_PAUSE,
363
VIRTKEY_DEVMENU,
364
#ifndef MOBILE_DEVICE
365
VIRTKEY_RECORD,
366
#endif
367
VIRTKEY_AXIS_X_MIN,
368
VIRTKEY_AXIS_Y_MIN,
369
VIRTKEY_AXIS_X_MAX,
370
VIRTKEY_AXIS_Y_MAX,
371
};
372
}
373
374
void GamepadTouch(bool reset = false);
375
void GamepadUpdateOpacity(float force = -1.0f);
376
float GamepadGetOpacity();
377
378