File: menu_input.h

package info (click to toggle)
retroarch 1.22.2%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 80,716 kB
  • sloc: ansic: 1,275,794; cpp: 115,470; objc: 9,973; asm: 6,624; python: 4,071; makefile: 2,867; sh: 2,828; xml: 1,408; perl: 393; java: 298; javascript: 196
file content (274 lines) | stat: -rw-r--r-- 8,400 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*  RetroArch - A frontend for libretro.
 *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
 *  Copyright (C) 2011-2017 - Daniel De Matteis
 *  Copyright (C) 2016-2019 - Brad Parker
 *
 *  RetroArch is free software: you can redistribute it and/or modify it under the terms
 *  of the GNU General Public License as published by the Free Software Found-
 *  ation, either version 3 of the License, or (at your option) any later version.
 *
 *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE.  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with RetroArch.
 *  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _MENU_INPUT_H
#define _MENU_INPUT_H

#include <stdint.h>
#include <compat/strl.h>

#include <retro_common_api.h>
#include <libretro.h>

#include "menu_defines.h"
#include "../input/input_types.h"
#include "../input/input_driver.h"
#include "../gfx/gfx_display.h"
#include "../performance_counters.h"

RETRO_BEGIN_DECLS

/* Mouse wheel tilt actions repeat at a very high
 * frequency - we ignore any input that occurs
 * with a period less than MENU_INPUT_HORIZ_WHEEL_DELAY */
#define MENU_INPUT_HORIZ_WHEEL_DELAY 250000          /* 250 ms */

/* Press directions are triggered as a pulse train.
 * Pulse period starts at MENU_INPUT_PRESS_DIRECTION_DELAY_MAX,
 * and decreases to MENU_INPUT_PRESS_DIRECTION_DELAY_MIN as
 * the start/current delta offset increases from
 * MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_MIN to
 * MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_MAX */
#define MENU_INPUT_PRESS_DIRECTION_DELAY_MIN 100000  /* 100 ms */
#define MENU_INPUT_PRESS_DIRECTION_DELAY_MAX 500000  /* 500 ms */

#define MENU_INPUT_HIDE_CURSOR_DELAY 4000000         /* 4 seconds */

#define MENU_INPUT_PRESS_TIME_SHORT 200000           /* 200 ms */
#define MENU_INPUT_PRESS_TIME_LONG 1000000           /* 1 second */
/* (Anything less than 'short' is considered a tap) */

/* Swipe gestures must be completed within a duration
 * of MENU_INPUT_SWIPE_TIMEOUT ms (helps to minimise
 * unwanted input if user 'zones out' and meanders on
 * a touchscreen) */
#define MENU_INPUT_SWIPE_TIMEOUT 500000              /* 500 ms */

/* Standard behaviour (on Android, at least) is to stop
 * scrolling when the user touches the screen. To prevent
 * jerky stop/start scrolling, we wait MENU_INPUT_Y_ACCEL_RESET_DELAY
 * ms before resetting y acceleration after a stationary
 * pointer down event is detected */
#define MENU_INPUT_Y_ACCEL_RESET_DELAY 50000         /* 50 ms */

#define MENU_INPUT_Y_ACCEL_DECAY_FACTOR 0.96f

/* Pointer is considered stationary if dx/dy remain
 * below (display DPI) * MENU_INPUT_DPI_THRESHOLD_DRAG */
#define MENU_INPUT_DPI_THRESHOLD_DRAG 0.1f

/* Press direction detection:
 * While holding the pointer down, a press in a
 * specific direction (up, down, left, right) will
 * be detected if:
 * - Current delta (i.e. from start to current) in
 *   press direction is greater than
 *   (display DPI) * MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_MIN
 * - Current delta in perpendicular axis is less than
 *   (display DPI) * MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_TANGENT
 * Press direction repeat rate is proportional to the current
 * delta in press direction.
 * Note: 'Tangent' is technically not the correct word here,
 * but the alternatives look silly, and the actual meaning
 * is transparent... */
#define MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_MIN 0.5f
#define MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_MAX 1.4f
#define MENU_INPUT_DPI_THRESHOLD_PRESS_DIRECTION_TANGENT 0.35f

/* Swipe detection:
 * A gesture will register as a swipe if:
 * - Final start/current delta in swipe direction is
 *   greater than (display DPI) * MENU_INPUT_DPI_THRESHOLD_SWIPE
 * - Maximum start/current delta in all other directions is
 *   less than (display DPI) * MENU_INPUT_DPI_THRESHOLD_SWIPE_TANGENT
 * - Pointer was held for less than MENU_INPUT_SWIPE_TIMEOUT ms */
#define MENU_INPUT_DPI_THRESHOLD_SWIPE 0.55f
#define MENU_INPUT_DPI_THRESHOLD_SWIPE_TANGENT 0.45f

#define MENU_MAX_BUTTONS           219
#define MENU_MAX_AXES              32
#define MENU_MAX_HATS              4
#define MENU_MAX_MBUTTONS          32 /* Enough to cover largest libretro constant*/

enum menu_pointer_type
{
   MENU_POINTER_DISABLED = 0,
   MENU_POINTER_MOUSE,
   MENU_POINTER_TOUCHSCREEN
};

enum menu_input_mouse_hw_id
{
   MENU_MOUSE_X_AXIS = 0,
   MENU_MOUSE_Y_AXIS,
   MENU_MOUSE_LEFT_BUTTON,
   MENU_MOUSE_RIGHT_BUTTON,
   MENU_MOUSE_WHEEL_UP,
   MENU_MOUSE_WHEEL_DOWN,
   MENU_MOUSE_HORIZ_WHEEL_UP,
   MENU_MOUSE_HORIZ_WHEEL_DOWN
};

enum menu_input_pointer_press_direction
{
   MENU_INPUT_PRESS_DIRECTION_NONE = 0,
   MENU_INPUT_PRESS_DIRECTION_UP,
   MENU_INPUT_PRESS_DIRECTION_DOWN,
   MENU_INPUT_PRESS_DIRECTION_LEFT,
   MENU_INPUT_PRESS_DIRECTION_RIGHT
};

enum menu_input_pointer_gesture
{
   MENU_INPUT_GESTURE_NONE = 0,
   MENU_INPUT_GESTURE_TAP,
   MENU_INPUT_GESTURE_SHORT_PRESS,
   MENU_INPUT_GESTURE_LONG_PRESS,
   MENU_INPUT_GESTURE_SWIPE_UP,
   MENU_INPUT_GESTURE_SWIPE_DOWN,
   MENU_INPUT_GESTURE_SWIPE_LEFT,
   MENU_INPUT_GESTURE_SWIPE_RIGHT
};

struct menu_bind_state_port
{
   int16_t axes[MENU_MAX_AXES];
   uint16_t hats[MENU_MAX_HATS];
   bool mouse_buttons[MENU_MAX_MBUTTONS];
   bool buttons[MENU_MAX_BUTTONS];
   bool keys[RETROK_LAST];
};

struct menu_bind_axis_state
{
   /* Default axis state. */
   int16_t rested_axes[MENU_MAX_AXES];
   /* Locked axis state. If we configured an axis,
    * avoid having the same axis state trigger something again right away. */
   int16_t locked_axes[MENU_MAX_AXES];
};

struct menu_bind_state
{
   rarch_timer_t timer_timeout;
   rarch_timer_t timer_hold;

   struct retro_keybind *output;
   struct retro_keybind buffer;

   struct menu_bind_state_port state[MAX_USERS];
   struct menu_bind_axis_state axis_state[MAX_USERS];

   unsigned begin;
   unsigned last;
   unsigned order;
   unsigned user;
   unsigned port;

   bool skip;
};

enum menu_inp_ptr_hwst_flags
{
   MENU_INP_PTR_FLG_ACTIVE       = (1 << 0),
   MENU_INP_PTR_FLG_PRESS_SELECT = (1 << 1),
   MENU_INP_PTR_FLG_PRESS_CANCEL = (1 << 2),
   MENU_INP_PTR_FLG_PRESS_UP     = (1 << 3),
   MENU_INP_PTR_FLG_PRESS_DOWN   = (1 << 4),
   MENU_INP_PTR_FLG_PRESS_LEFT   = (1 << 5),
   MENU_INP_PTR_FLG_PRESS_RIGHT  = (1 << 6),
   MENU_INP_PTR_FLG_PRESSED      = (1 << 7),
   MENU_INP_PTR_FLG_DRAGGED      = (1 << 8),
   MENU_INP_PTR_FLG_RESET        = (1 << 9)
};

/* Defines set of (abstracted) inputs/states
 * common to mouse + touchscreen hardware */
typedef struct menu_input_pointer_hw_state
{
   int16_t x;
   int16_t y;
   uint16_t flags;
} menu_input_pointer_hw_state_t;

typedef struct menu_input_pointer
{
   retro_time_t press_duration;  /* int64_t alignment */
   /**
    * NOTE: menu drivers typically set y_accel to zero
    * manually when populating entries.
    **/
   float y_accel;
   enum menu_pointer_type type;
   enum menu_input_pointer_press_direction press_direction;
   int16_t x;
   int16_t y;
   int16_t dx;
   int16_t dy;
   uint16_t flags;
} menu_input_pointer_t;

typedef struct menu_input
{
   menu_input_pointer_t pointer; /* retro_time_t alignment */
   unsigned ptr;
   bool select_inhibit;
   bool cancel_inhibit;
} menu_input_t;

typedef struct key_desc
{
   /* libretro key id */
   unsigned key;

   /* description */
   char desc[32];
} key_desc_t;

typedef struct menu_input_ctx_line
{
   const char *label;
   const char *label_setting;
   unsigned type;
   unsigned idx;
   input_keyboard_line_complete_t cb;
} menu_input_ctx_line_t;

/**
 * Copy parameters from the global menu_input_state to a menu_input_pointer_t
 * in order to provide access to all pointer device parameters.
 *
 * @param copy_target  menu_input_pointer_t struct where values will be copied
 **/
void menu_input_get_pointer_state(menu_input_pointer_t *copy_target);

bool menu_input_dialog_start(menu_input_ctx_line_t *line);

const char *menu_input_dialog_get_buffer(void);

bool menu_input_dialog_start_search(void);

bool menu_input_dialog_get_display_kb(void);

void menu_input_dialog_end(void);

/* TODO/FIXME - public global variables */
extern struct key_desc key_descriptors[RARCH_MAX_KEYS];

RETRO_END_DECLS

#endif