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
|