OXYGENHUB
◆ main openmsx / src / events / BooleanInput.hh
3.8 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef BOOLEAN_INPUT_HH
2
#define BOOLEAN_INPUT_HH
3
4
// A 'BooleanInput' represents an input which has a well defined start and stop.
5
//
6
// Some examples:
7
// * Press a key on the keyboard, later release that key.
8
// * Same for joystick and mouse buttons.
9
// * The 4 directions on a joystick hat (d-pad): active when e.g. pressing the
10
//   'up' direction, it remains active when the 'up-left' or 'up-right'
11
//   combination is pressed, but becomes deactive for any other combination
12
//   (including 'center').
13
// * Joystick axis: becomes active when moving the axis in e.g. the positive
14
//   direction (the negative direction is a different BooleanInput) past the
15
//   dead-zone in the center. Becomes deactive when moving the axis back to the
16
//   center or in the opposite direction.
17
//
18
// Counter-examples:
19
// * Mouse-wheel.
20
// * Mouse motion.
21
22
#include "Event.hh"
23
#include "JoystickId.hh"
24
25
#include "function_ref.hh"
26
#include "unreachable.hh"
27
28
#include <SDL.h>
29
30
#include <cstdint>
31
#include <optional>
32
#include <string>
33
#include <string_view>
34
#include <variant>
35
36
namespace openmsx {
37
38
class BooleanKeyboard
39
{
40
public:
41
	explicit BooleanKeyboard(SDL_Keycode code)
42
		: keyCode(code) {}
43
44
	[[nodiscard]] auto getKeyCode() const { return keyCode; }
45
46
private:
47
	SDL_Keycode keyCode;
48
};
49
50
class BooleanMouseButton
51
{
52
public:
53
	explicit BooleanMouseButton(uint8_t button_)
54
		: button(button_) {}
55
56
	[[nodiscard]] auto getButton() const { return button; }
57
58
private:
59
	uint8_t button;
60
};
61
62
class BooleanJoystickButton
63
{
64
public:
65
	explicit BooleanJoystickButton(JoystickId joystick_, uint8_t button_)
66
		: joystick(joystick_), button(button_) {}
67
68
	[[nodiscard]] auto getJoystick() const { return joystick; }
69
	[[nodiscard]] auto getButton() const { return button; }
70
71
private:
72
	JoystickId joystick;
73
	uint8_t button;
74
};
75
76
class BooleanJoystickHat
77
{
78
public:
79
	enum class Direction : uint8_t {
80
		UP    = SDL_HAT_UP,
81
		RIGHT = SDL_HAT_RIGHT,
82
		DOWN  = SDL_HAT_DOWN,
83
		LEFT  = SDL_HAT_LEFT,
84
	};
85
86
	explicit BooleanJoystickHat(JoystickId joystick_, uint8_t hat_, Direction value_)
87
		: joystick(joystick_), hat(hat_), value(value_) {}
88
89
	[[nodiscard]] auto getJoystick() const { return joystick; }
90
	[[nodiscard]] auto getHat() const { return hat; }
91
	[[nodiscard]] auto getValue() const { return value; }
92
93
private:
94
	JoystickId joystick;
95
	uint8_t hat;
96
	Direction value;
97
};
98
[[nodiscard]] constexpr std::string_view toString(BooleanJoystickHat::Direction dir)
99
{
100
	using namespace std::literals;
101
	using enum BooleanJoystickHat::Direction;
102
	switch (dir) {
103
		case UP:    return "up"sv;
104
		case RIGHT: return "right"sv;
105
		case DOWN:  return "down"sv;
106
		case LEFT:  return "left"sv;
107
	}
108
	UNREACHABLE;
109
}
110
111
class BooleanJoystickAxis
112
{
113
public:
114
	enum class Direction : uint8_t { POS, NEG };
115
116
	explicit BooleanJoystickAxis(JoystickId joystick_, uint8_t axis_, Direction direction_)
117
		: joystick(joystick_), axis(axis_), direction(direction_) {}
118
119
	[[nodiscard]] auto getJoystick() const { return joystick; }
120
	[[nodiscard]] auto getAxis() const { return axis; }
121
	[[nodiscard]] auto getDirection() const { return direction; }
122
123
private:
124
	JoystickId joystick;
125
	uint8_t axis;
126
	Direction direction;
127
};
128
129
130
using BooleanInput = std::variant<
131
	BooleanKeyboard,
132
	BooleanMouseButton,
133
	BooleanJoystickButton,
134
	BooleanJoystickHat,
135
	BooleanJoystickAxis>;
136
137
138
[[nodiscard]] std::string toString(const BooleanInput& input);
139
[[nodiscard]] std::optional<BooleanInput> parseBooleanInput(std::string_view text);
140
[[nodiscard]] std::optional<BooleanInput> captureBooleanInput(const Event& event, function_ref<int(JoystickId)> getJoyDeadThreshold);
141
142
[[nodiscard]] bool operator==(const BooleanInput& x, const BooleanInput& y);
143
144
[[nodiscard]] std::optional<bool> match(const BooleanInput& binding, const Event& event,
145
                                        function_ref<int(JoystickId)> getJoyDeadThreshold);
146
147
} // namespace openmsx
148
149
#endif