Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/UI/GamepadEmu.h
3185 views
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
bool CanGlide() const;
58
59
protected:
60
uint32_t pointerDownMask_ = 0;
61
float scale_;
62
63
private:
64
ImageID bgImg_;
65
ImageID bgDownImg_;
66
ImageID img_;
67
float bgAngle_ = 0.0f;
68
float angle_ = 0.0f;
69
bool flipImageH_ = false;
70
};
71
72
class BoolButton : public MultiTouchButton {
73
public:
74
BoolButton(bool *value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
75
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), value_(value) {
76
}
77
bool Touch(const TouchInput &input) override;
78
bool IsDown() override { return *value_; }
79
80
UI::Event OnChange;
81
82
private:
83
bool *value_;
84
};
85
86
class PSPButton : public MultiTouchButton {
87
public:
88
PSPButton(int pspButtonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
89
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) {
90
}
91
bool Touch(const TouchInput &input) override;
92
bool IsDown() override;
93
94
private:
95
int pspButtonBit_;
96
};
97
98
class PSPDpad : public GamepadView {
99
public:
100
PSPDpad(ImageID arrowIndex, const char *key, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams);
101
102
bool Touch(const TouchInput &input) override;
103
void Draw(UIContext &dc) override;
104
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
105
106
private:
107
void ProcessTouch(float x, float y, bool down);
108
ImageID arrowIndex_;
109
ImageID arrowDownIndex_;
110
ImageID overlayIndex_;
111
112
float scale_;
113
float spacing_;
114
115
int dragPointerId_;
116
int down_;
117
};
118
119
class PSPStick : public GamepadView {
120
public:
121
PSPStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams);
122
123
bool Touch(const TouchInput &input) override;
124
void Draw(UIContext &dc) override;
125
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
126
127
protected:
128
int dragPointerId_;
129
ImageID bgImg_;
130
ImageID stickImageIndex_;
131
ImageID stickDownImg_;
132
133
int stick_;
134
float stick_size_;
135
float scale_;
136
137
float centerX_;
138
float centerY_;
139
140
private:
141
void ProcessTouch(float x, float y, bool down);
142
};
143
144
class PSPCustomStick : public PSPStick {
145
public:
146
PSPCustomStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams);
147
148
bool Touch(const TouchInput &input) override;
149
void Draw(UIContext &dc) override;
150
151
private:
152
void ProcessTouch(float x, float y, bool down);
153
154
float posX_ = 0.0f;
155
float posY_ = 0.0f;
156
};
157
158
//initializes the layout from Config. if a default layout does not exist,
159
//it sets up default values
160
void InitPadLayout(float xres, float yres, float globalScale = 1.15f);
161
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause, bool showPauseButton, ControlMapper* controllMapper);
162
163
const int D_pad_Radius = 50;
164
const int baseActionButtonSpacing = 60;
165
166
class CustomButton : public MultiTouchButton {
167
public:
168
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)
169
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), repeat_(repeat), controlMapper_(controllMapper), on_(false), invertedContextDimension_(invertedContextDimension) {
170
}
171
bool Touch(const TouchInput &input) override;
172
void Update() override;
173
bool IsDown() override;
174
175
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
176
private:
177
uint64_t pspButtonBit_;
178
bool toggle_;
179
bool repeat_;
180
int pressedFrames_ = 0;
181
ControlMapper* controlMapper_;
182
bool on_;
183
bool invertedContextDimension_; // Swap width and height
184
};
185
186
class GestureGamepad : public UI::View {
187
public:
188
GestureGamepad(ControlMapper* controllMapper) : controlMapper_(controllMapper) {};
189
190
bool Touch(const TouchInput &input) override;
191
void Update() override;
192
void Draw(UIContext &dc) override;
193
194
protected:
195
196
float lastX_ = 0.0f;
197
float lastY_ = 0.0f;
198
float deltaX_ = 0.0f;
199
float deltaY_ = 0.0f;
200
float downX_;
201
float downY_;
202
float lastTapRelease_ = 0.0f;
203
float lastTouchDown_ = 0.0f;
204
int dragPointerId_ = -1;
205
bool swipeLeftReleased_ = true;
206
bool swipeRightReleased_ = true;
207
bool swipeUpReleased_ = true;
208
bool swipeDownReleased_ = true;
209
bool haveDoubleTapped_ = false;
210
ControlMapper* controlMapper_;
211
};
212
213
// Just edit this to add new image, shape or button function
214
namespace CustomKeyData {
215
// Image list
216
struct keyImage {
217
ImageID i; // ImageID
218
float r; // Rotation angle in degree
219
};
220
static const keyImage customKeyImages[] = {
221
{ ImageID("I_1"), 0.0f },
222
{ ImageID("I_2"), 0.0f },
223
{ ImageID("I_3"), 0.0f },
224
{ ImageID("I_4"), 0.0f },
225
{ ImageID("I_5"), 0.0f },
226
{ ImageID("I_6"), 0.0f },
227
{ ImageID("I_A"), 0.0f },
228
{ ImageID("I_B"), 0.0f },
229
{ ImageID("I_C"), 0.0f },
230
{ ImageID("I_D"), 0.0f },
231
{ ImageID("I_E"), 0.0f },
232
{ ImageID("I_F"), 0.0f },
233
{ ImageID("I_CIRCLE"), 0.0f },
234
{ ImageID("I_CROSS"), 0.0f },
235
{ ImageID("I_SQUARE"), 0.0f },
236
{ ImageID("I_TRIANGLE"), 0.0f },
237
{ ImageID("I_L"), 0.0f },
238
{ ImageID("I_R"), 0.0f },
239
{ ImageID("I_START"), 0.0f },
240
{ ImageID("I_SELECT"), 0.0f },
241
{ ImageID("I_CROSS"), 45.0f },
242
{ ImageID("I_SQUARE"), 45.0f },
243
{ ImageID("I_TRIANGLE"), 180.0f },
244
{ ImageID("I_ARROW"), 90.0f},
245
{ ImageID("I_ARROW"), 270.0f},
246
{ ImageID("I_ARROW"), 0.0f},
247
{ ImageID("I_ARROW"), 180.0f},
248
{ ImageID("I_GEAR"), 0.0f},
249
{ ImageID("I_ROTATE_LEFT"), 0.0f},
250
{ ImageID("I_ROTATE_RIGHT"), 0.0f},
251
{ ImageID("I_ARROW_LEFT"), 0.0f},
252
{ ImageID("I_ARROW_RIGHT"), 0.0f},
253
{ ImageID("I_ARROW_UP"), 0.0f},
254
{ ImageID("I_ARROW_DOWN"), 0.0f},
255
{ ImageID("I_THREE_DOTS"), 0.0f},
256
{ ImageID("I_EMPTY"), 0.0f},
257
};
258
259
// Shape list
260
struct keyShape {
261
ImageID i; // ImageID
262
ImageID l; // ImageID line version
263
float r; // Rotation angle in dregree
264
bool f; // Flip Horizontally
265
bool d; // Invert height and width for context dimension (for example for 90 degree rot)
266
};
267
static const keyShape customKeyShapes[] = {
268
{ ImageID("I_ROUND"), ImageID("I_ROUND_LINE"), 0.0f, false, false },
269
{ ImageID("I_RECT"), ImageID("I_RECT_LINE"), 0.0f, false, false },
270
{ ImageID("I_RECT"), ImageID("I_RECT_LINE"), 90.0f, false, true },
271
{ ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, false, false },
272
{ ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, true, false },
273
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 270.0f, false, true },
274
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 90.0f, false, true },
275
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 180.0f, false, false },
276
{ ImageID("I_DIR"), ImageID("I_DIR_LINE"), 0.0f, false, false },
277
{ ImageID("I_SQUARE_SHAPE"), ImageID("I_SQUARE_SHAPE_LINE"), 0.0f, false, false },
278
{ ImageID("I_EMPTY"), ImageID("I_EMPTY"), 0.0f, false, false },
279
};
280
281
// Button list
282
struct keyList {
283
ImageID i; // UI ImageID
284
uint32_t c; // Key code
285
};
286
static const keyList customKeyList[] = {
287
{ ImageID("I_SQUARE"), CTRL_SQUARE },
288
{ ImageID("I_TRIANGLE"), CTRL_TRIANGLE },
289
{ ImageID("I_CIRCLE"), CTRL_CIRCLE },
290
{ ImageID("I_CROSS"), CTRL_CROSS },
291
{ ImageID::invalid(), CTRL_UP },
292
{ ImageID::invalid(), CTRL_DOWN },
293
{ ImageID::invalid(), CTRL_LEFT },
294
{ ImageID::invalid(), CTRL_RIGHT },
295
{ ImageID("I_START"), CTRL_START },
296
{ ImageID("I_SELECT"), CTRL_SELECT },
297
{ ImageID("I_L"), CTRL_LTRIGGER },
298
{ ImageID("I_R"), CTRL_RTRIGGER },
299
{ ImageID::invalid(), VIRTKEY_RAPID_FIRE },
300
{ ImageID::invalid(), VIRTKEY_FASTFORWARD },
301
{ ImageID::invalid(), VIRTKEY_SPEED_TOGGLE },
302
{ ImageID::invalid(), VIRTKEY_REWIND },
303
{ ImageID::invalid(), VIRTKEY_SAVE_STATE },
304
{ ImageID::invalid(), VIRTKEY_LOAD_STATE },
305
{ ImageID::invalid(), VIRTKEY_NEXT_SLOT },
306
#if !defined(MOBILE_DEVICE)
307
{ ImageID::invalid(), VIRTKEY_TOGGLE_FULLSCREEN },
308
#endif
309
{ ImageID::invalid(), VIRTKEY_SPEED_CUSTOM1 },
310
{ ImageID::invalid(), VIRTKEY_SPEED_CUSTOM2 },
311
{ ImageID::invalid(), VIRTKEY_TEXTURE_DUMP },
312
{ ImageID::invalid(), VIRTKEY_TEXTURE_REPLACE },
313
{ ImageID::invalid(), VIRTKEY_SCREENSHOT },
314
{ ImageID::invalid(), VIRTKEY_MUTE_TOGGLE },
315
{ ImageID::invalid(), VIRTKEY_OPENCHAT },
316
{ ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CW },
317
{ ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CCW },
318
{ ImageID::invalid(), VIRTKEY_PAUSE },
319
{ ImageID::invalid(), VIRTKEY_RESET_EMULATION },
320
{ ImageID::invalid(), VIRTKEY_DEVMENU },
321
#ifndef MOBILE_DEVICE
322
{ ImageID::invalid(), VIRTKEY_RECORD },
323
#endif
324
{ ImageID::invalid(), VIRTKEY_AXIS_X_MIN },
325
{ ImageID::invalid(), VIRTKEY_AXIS_Y_MIN },
326
{ ImageID::invalid(), VIRTKEY_AXIS_X_MAX },
327
{ ImageID::invalid(), VIRTKEY_AXIS_Y_MAX },
328
{ ImageID::invalid(), VIRTKEY_PREVIOUS_SLOT },
329
{ ImageID::invalid(), VIRTKEY_TOGGLE_TOUCH_CONTROLS },
330
{ ImageID::invalid(), VIRTKEY_TOGGLE_DEBUGGER },
331
};
332
static_assert(ARRAY_SIZE(customKeyList) <= 64, "Too many key for a uint64_t bit mask");
333
};
334
335
// Gesture key only have virtual button that can work without constant press
336
namespace GestureKey {
337
static const uint32_t keyList[] = {
338
CTRL_SQUARE,
339
CTRL_TRIANGLE,
340
CTRL_CIRCLE,
341
CTRL_CROSS,
342
CTRL_UP,
343
CTRL_DOWN,
344
CTRL_LEFT,
345
CTRL_RIGHT,
346
CTRL_START,
347
CTRL_SELECT,
348
CTRL_LTRIGGER,
349
CTRL_RTRIGGER,
350
VIRTKEY_AXIS_Y_MAX,
351
VIRTKEY_AXIS_Y_MIN,
352
VIRTKEY_AXIS_X_MIN,
353
VIRTKEY_AXIS_X_MAX,
354
VIRTKEY_SPEED_TOGGLE,
355
VIRTKEY_REWIND,
356
VIRTKEY_SAVE_STATE,
357
VIRTKEY_LOAD_STATE,
358
VIRTKEY_PREVIOUS_SLOT,
359
VIRTKEY_NEXT_SLOT,
360
VIRTKEY_TEXTURE_DUMP,
361
VIRTKEY_TEXTURE_REPLACE,
362
VIRTKEY_SCREENSHOT,
363
VIRTKEY_MUTE_TOGGLE,
364
VIRTKEY_OPENCHAT,
365
VIRTKEY_PAUSE,
366
VIRTKEY_DEVMENU,
367
#ifndef MOBILE_DEVICE
368
VIRTKEY_RECORD,
369
#endif
370
VIRTKEY_AXIS_X_MIN,
371
VIRTKEY_AXIS_Y_MIN,
372
VIRTKEY_AXIS_X_MAX,
373
VIRTKEY_AXIS_Y_MAX,
374
VIRTKEY_TOGGLE_DEBUGGER,
375
};
376
}
377
378
void GamepadTouch(bool reset = false);
379
void GamepadUpdateOpacity(float force = -1.0f);
380
float GamepadGetOpacity();
381
382