2012-03-24 23:39:19 +01:00
|
|
|
#pragma once
|
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
// InputState is the simple way of getting input. All the input we have is collected
|
|
|
|
// to a canonical Xbox360-style pad fully automatically.
|
|
|
|
//
|
|
|
|
// Recommended for use in game UIs and games that don't have advanced needs.
|
|
|
|
//
|
|
|
|
// For more detailed and configurable input, implement NativeTouch, NativeKey and NativeAxis and do your
|
|
|
|
// own mapping. Might later move the mapping system from PPSSPP to native.
|
|
|
|
|
2014-02-05 20:01:33 +01:00
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
|
2012-03-24 23:39:19 +01:00
|
|
|
#include "math/lin/vec3.h"
|
2012-04-27 00:48:30 +02:00
|
|
|
#include "base/mutex.h"
|
2012-08-12 20:50:12 +02:00
|
|
|
#include "base/basictypes.h"
|
2013-08-22 06:45:45 -04:00
|
|
|
#include "input/keycodes.h"
|
2012-03-24 23:39:19 +01:00
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
// Default device IDs
|
|
|
|
|
|
|
|
enum {
|
2015-08-29 21:52:53 +02:00
|
|
|
DEVICE_ID_ANY = -1, // Represents any device ID
|
2013-07-06 19:07:48 +02:00
|
|
|
DEVICE_ID_DEFAULT = 0, // Old Android
|
|
|
|
DEVICE_ID_KEYBOARD = 1, // PC keyboard, android keyboards
|
2013-07-08 12:34:39 +02:00
|
|
|
DEVICE_ID_MOUSE = 2, // PC mouse only (not touchscreen!)
|
2013-07-06 19:07:48 +02:00
|
|
|
DEVICE_ID_PAD_0 = 10, // Generic joypads
|
2014-06-01 11:35:57 +02:00
|
|
|
DEVICE_ID_PAD_1 = 11, // these should stay as contiguous numbers
|
|
|
|
DEVICE_ID_PAD_2 = 12,
|
|
|
|
DEVICE_ID_PAD_3 = 13,
|
|
|
|
DEVICE_ID_PAD_4 = 14,
|
|
|
|
DEVICE_ID_PAD_5 = 15,
|
|
|
|
DEVICE_ID_PAD_6 = 16,
|
|
|
|
DEVICE_ID_PAD_7 = 17,
|
|
|
|
DEVICE_ID_PAD_8 = 18,
|
|
|
|
DEVICE_ID_PAD_9 = 19,
|
2013-07-06 19:07:48 +02:00
|
|
|
DEVICE_ID_X360_0 = 20, // XInput joypads
|
|
|
|
DEVICE_ID_ACCELEROMETER = 30,
|
|
|
|
};
|
|
|
|
|
2014-06-01 11:35:57 +02:00
|
|
|
//number of contiguous generic joypad IDs
|
|
|
|
const int MAX_NUM_PADS = 10;
|
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
const char *GetDeviceName(int deviceId);
|
|
|
|
|
2012-03-24 23:39:19 +01:00
|
|
|
enum {
|
2012-10-30 13:20:55 +01:00
|
|
|
PAD_BUTTON_A = 1,
|
|
|
|
PAD_BUTTON_B = 2,
|
|
|
|
PAD_BUTTON_X = 4,
|
|
|
|
PAD_BUTTON_Y = 8,
|
|
|
|
PAD_BUTTON_LBUMPER = 16,
|
|
|
|
PAD_BUTTON_RBUMPER = 32,
|
|
|
|
PAD_BUTTON_START = 64,
|
|
|
|
PAD_BUTTON_SELECT = 128,
|
|
|
|
PAD_BUTTON_UP = 256,
|
|
|
|
PAD_BUTTON_DOWN = 512,
|
|
|
|
PAD_BUTTON_LEFT = 1024,
|
|
|
|
PAD_BUTTON_RIGHT = 2048,
|
2012-10-28 11:37:10 +01:00
|
|
|
|
|
|
|
PAD_BUTTON_MENU = 4096,
|
|
|
|
PAD_BUTTON_BACK = 8192,
|
2013-01-11 13:41:21 +10:00
|
|
|
|
2016-10-11 17:34:19 +02:00
|
|
|
// For Qt
|
2013-01-11 13:41:21 +10:00
|
|
|
PAD_BUTTON_JOY_UP = 1<<14,
|
|
|
|
PAD_BUTTON_JOY_DOWN = 1<<15,
|
|
|
|
PAD_BUTTON_JOY_LEFT = 1<<16,
|
|
|
|
PAD_BUTTON_JOY_RIGHT = 1<<17,
|
2013-03-31 11:22:49 +02:00
|
|
|
|
|
|
|
PAD_BUTTON_LEFT_THUMB = 1 << 18, // Click left thumb stick on X360
|
|
|
|
PAD_BUTTON_RIGHT_THUMB = 1 << 19, // Click right thumb stick on X360
|
2013-05-31 23:04:42 +02:00
|
|
|
|
|
|
|
PAD_BUTTON_LEFT_TRIGGER = 1 << 21, // Click left thumb stick on X360
|
|
|
|
PAD_BUTTON_RIGHT_TRIGGER = 1 << 22, // Click left thumb stick on X360
|
|
|
|
|
2013-05-13 20:04:09 -05:00
|
|
|
PAD_BUTTON_UNTHROTTLE = 1 << 20, // Click Tab to unthrottle
|
2012-03-24 23:39:19 +01:00
|
|
|
};
|
|
|
|
|
2013-08-27 19:43:40 +02:00
|
|
|
#define MAX_POINTERS 10
|
2013-06-24 21:47:29 -07:00
|
|
|
|
|
|
|
#ifndef MAX_KEYQUEUESIZE
|
|
|
|
#define MAX_KEYQUEUESIZE 20
|
|
|
|
#endif
|
2013-07-06 19:07:48 +02:00
|
|
|
|
2015-08-28 16:51:07 +02:00
|
|
|
// Represents a single bindable key
|
|
|
|
class KeyDef {
|
|
|
|
public:
|
|
|
|
KeyDef() : deviceId(0), keyCode(0) {}
|
|
|
|
KeyDef(int devId, int k) : deviceId(devId), keyCode(k) {}
|
|
|
|
int deviceId;
|
|
|
|
int keyCode;
|
|
|
|
|
2015-09-17 22:07:22 +02:00
|
|
|
// If you want to use std::find and match ANY, you need to perform an explicit search for that.
|
2015-08-28 16:51:07 +02:00
|
|
|
bool operator < (const KeyDef &other) const {
|
|
|
|
if (deviceId < other.deviceId) return true;
|
|
|
|
if (deviceId > other.deviceId) return false;
|
|
|
|
if (keyCode < other.keyCode) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool operator == (const KeyDef &other) const {
|
2015-08-29 21:52:53 +02:00
|
|
|
if (deviceId != other.deviceId && deviceId != DEVICE_ID_ANY && other.deviceId != DEVICE_ID_ANY) return false;
|
2015-08-28 16:51:07 +02:00
|
|
|
if (keyCode != other.keyCode) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Represents a single bindable axis direction
|
|
|
|
struct AxisPos {
|
|
|
|
int axis;
|
|
|
|
float position;
|
|
|
|
|
|
|
|
bool operator < (const AxisPos &other) const {
|
|
|
|
if (axis < other.axis) return true;
|
|
|
|
if (axis > other.axis) return false;
|
|
|
|
return position < other.position;
|
|
|
|
}
|
|
|
|
bool operator == (const AxisPos &other) const {
|
|
|
|
return axis == other.axis && position == other.position;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-10-31 20:42:43 +01:00
|
|
|
// Collection of all possible inputs, and automatically computed
|
2012-03-24 23:39:19 +01:00
|
|
|
// deltas where applicable.
|
|
|
|
struct InputState {
|
2012-10-30 13:20:55 +01:00
|
|
|
// Lock this whenever you access the data in this struct.
|
|
|
|
mutable recursive_mutex lock;
|
|
|
|
InputState()
|
|
|
|
: pad_buttons(0),
|
|
|
|
pad_last_buttons(0),
|
|
|
|
pad_buttons_down(0),
|
|
|
|
pad_buttons_up(0),
|
|
|
|
mouse_valid(false),
|
|
|
|
accelerometer_valid(false) {
|
|
|
|
memset(pointer_down, 0, sizeof(pointer_down));
|
|
|
|
}
|
2012-04-27 00:48:30 +02:00
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
// Gamepad style input. For ease of use.
|
2012-10-30 13:20:55 +01:00
|
|
|
int pad_buttons; // bitfield
|
|
|
|
int pad_last_buttons;
|
|
|
|
int pad_buttons_down; // buttons just pressed this frame
|
|
|
|
int pad_buttons_up; // buttons just pressed last frame
|
|
|
|
float pad_lstick_x;
|
|
|
|
float pad_lstick_y;
|
|
|
|
float pad_rstick_x;
|
|
|
|
float pad_rstick_y;
|
|
|
|
float pad_ltrigger;
|
|
|
|
float pad_rtrigger;
|
2012-03-24 23:39:19 +01:00
|
|
|
|
2012-10-30 13:20:55 +01:00
|
|
|
// Mouse/touch style input
|
|
|
|
// There are up to 8 mice / fingers.
|
|
|
|
volatile bool mouse_valid;
|
2012-04-27 00:48:30 +02:00
|
|
|
|
2012-10-30 13:20:55 +01:00
|
|
|
int pointer_x[MAX_POINTERS];
|
|
|
|
int pointer_y[MAX_POINTERS];
|
|
|
|
bool pointer_down[MAX_POINTERS];
|
2012-03-31 11:16:13 +02:00
|
|
|
|
2012-10-30 13:20:55 +01:00
|
|
|
// Accelerometer
|
|
|
|
bool accelerometer_valid;
|
|
|
|
Vec3 acc;
|
2012-07-26 17:24:47 +02:00
|
|
|
|
|
|
|
private:
|
2012-10-30 13:20:55 +01:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(InputState);
|
2012-03-24 23:39:19 +01:00
|
|
|
};
|
|
|
|
|
2013-07-15 20:29:50 +02:00
|
|
|
void UpdateInputState(InputState *input, bool merge = false);
|
2013-07-15 17:37:16 +02:00
|
|
|
void EndInputState(InputState *input);
|
2013-05-03 00:21:39 +02:00
|
|
|
|
|
|
|
enum {
|
2014-02-05 20:01:33 +01:00
|
|
|
TOUCH_MOVE = 1 << 0,
|
|
|
|
TOUCH_DOWN = 1 << 1,
|
|
|
|
TOUCH_UP = 1 << 2,
|
|
|
|
TOUCH_CANCEL = 1 << 3, // Sent by scrollviews to their children when they detect a scroll
|
2014-07-20 22:20:09 +02:00
|
|
|
TOUCH_WHEEL = 1 << 4, // Scrollwheel event. Usually only affects Y but can potentially affect X.
|
|
|
|
TOUCH_MOUSE = 1 << 5, // Identifies that this touch event came from a mouse
|
2015-05-21 10:45:49 +02:00
|
|
|
TOUCH_RELEASE_ALL = 1 << 6, // Useful for app focus switches when events may be lost.
|
2014-02-05 20:01:33 +01:00
|
|
|
|
|
|
|
// These are the Android getToolType() codes, shifted by 10.
|
|
|
|
TOUCH_TOOL_MASK = 7 << 10,
|
|
|
|
TOUCH_TOOL_UNKNOWN = 0 << 10,
|
|
|
|
TOUCH_TOOL_FINGER = 1 << 10,
|
|
|
|
TOUCH_TOOL_STYLUS = 2 << 10,
|
|
|
|
TOUCH_TOOL_MOUSE = 3 << 10,
|
|
|
|
TOUCH_TOOL_ERASER = 4 << 10,
|
2013-05-03 00:21:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Used for asynchronous touch input.
|
|
|
|
// DOWN is always on its own.
|
|
|
|
// MOVE and UP can be combined.
|
|
|
|
struct TouchInput {
|
|
|
|
float x;
|
|
|
|
float y;
|
|
|
|
int id; // can be relied upon to be 0...MAX_POINTERS
|
|
|
|
int flags;
|
|
|
|
double timestamp;
|
|
|
|
};
|
|
|
|
|
2013-07-07 17:46:37 +10:00
|
|
|
#undef KEY_DOWN
|
2013-07-08 12:34:39 +02:00
|
|
|
#undef KEY_UP
|
2013-07-07 17:46:37 +10:00
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
enum {
|
2014-02-05 20:01:33 +01:00
|
|
|
KEY_DOWN = 1 << 0,
|
|
|
|
KEY_UP = 1 << 1,
|
|
|
|
KEY_HASWHEELDELTA = 1 << 2,
|
2014-06-15 13:04:10 +02:00
|
|
|
KEY_IS_REPEAT = 1 << 3,
|
2014-06-29 23:31:09 +02:00
|
|
|
KEY_CHAR = 1 << 4, // Unicode character input. Cannot detect keyups of these so KEY_DOWN and KEY_UP are zero when this is set.
|
2013-07-06 19:07:48 +02:00
|
|
|
};
|
2013-06-24 21:47:29 -07:00
|
|
|
|
2013-07-06 19:07:48 +02:00
|
|
|
struct KeyInput {
|
2013-07-09 16:33:05 +02:00
|
|
|
KeyInput() {}
|
|
|
|
KeyInput(int devId, int code, int fl) : deviceId(devId), keyCode(code), flags(fl) {}
|
2013-07-06 19:07:48 +02:00
|
|
|
int deviceId;
|
|
|
|
int keyCode; // Android keycodes are the canonical keycodes, everyone else map to them.
|
|
|
|
int flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AxisInput {
|
|
|
|
int deviceId;
|
|
|
|
int axisId; // Android axis Ids are the canonical ones.
|
|
|
|
float value;
|
|
|
|
int flags;
|
|
|
|
};
|
2013-07-15 17:37:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
class ButtonTracker {
|
|
|
|
public:
|
|
|
|
ButtonTracker() { Reset(); }
|
|
|
|
void Reset() {
|
|
|
|
pad_buttons_ = 0;
|
|
|
|
pad_buttons_async_set = 0;
|
|
|
|
pad_buttons_async_clear = 0;
|
|
|
|
}
|
|
|
|
void Process(const KeyInput &input);
|
2013-07-15 20:29:50 +02:00
|
|
|
uint32_t Update();
|
2013-07-15 17:37:16 +02:00
|
|
|
uint32_t GetPadButtons() const { return pad_buttons_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
uint32_t pad_buttons_;
|
|
|
|
uint32_t pad_buttons_async_set;
|
|
|
|
uint32_t pad_buttons_async_clear;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Platforms should call g_buttonTracker.Process().
|
2013-08-22 06:45:45 -04:00
|
|
|
extern ButtonTracker g_buttonTracker;
|
|
|
|
|
|
|
|
// Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest..
|
2015-08-28 20:51:33 +02:00
|
|
|
extern std::vector<KeyDef> dpadKeys;
|
2015-08-28 17:05:11 +02:00
|
|
|
extern std::vector<KeyDef> confirmKeys;
|
|
|
|
extern std::vector<KeyDef> cancelKeys;
|
|
|
|
extern std::vector<KeyDef> tabLeftKeys;
|
|
|
|
extern std::vector<KeyDef> tabRightKeys;
|
2015-08-28 20:51:33 +02:00
|
|
|
void SetDPadKeys(const std::vector<KeyDef> &leftKey, const std::vector<KeyDef> &rightKey,
|
|
|
|
const std::vector<KeyDef> &upKey, const std::vector<KeyDef> &downKey);
|
2015-08-28 17:05:11 +02:00
|
|
|
void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel);
|
|
|
|
void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<KeyDef> &tabRight);
|