raylib-cpp
C++ object-oriented wrapper library for raylib.
Loading...
Searching...
No Matches
BufferedRaylib.cpp
1#include "BufferedRaylib.hpp"
2
3#include "raymath.h"
4
5#include <set>
6#include <string>
7#include <string_view>
8#include <map>
9#include <array>
10#include <concepts>
11
12namespace raylib {
13
14 bool Button::operator<(const Button& o) const {
15 if (type != o.type) return type < o.type;
16 if (type == Type::Gamepad && gamepad.id == o.gamepad.id)
17 return gamepad.button < o.gamepad.button;
18 return keyboard < o.keyboard; // They should all be castable to a keyboard key, thus comparing only it should be fine!
19 }
20
21 bool Button::IsPressed(const Button& button) {
22 switch(button.type) {
23 break; case Button::Type::Keyboard:
24 return IsKeyDown(button.keyboard);
25 break; case Button::Type::Mouse:
26 return IsMouseButtonDown(button.mouse);
27 break; case Button::Type::Gamepad: {
28 return IsGamepadButtonDown(button.gamepad.id, button.gamepad.button);
29 }
30 break; default: assert(button.type != Button::Type::Invalid);
31 }
32 return false;
33 }
34
35 uint8_t Button::IsSetPressed(const std::set<Button>& buttons) {
36 uint8_t state = 0;
37 for(auto& button: buttons)
38 state += IsPressed(button);
39 return state;
40 }
41
42 Action& Action::operator=(Action&& o) {
43 type = o.type;
44 data = std::move(o.data);
45 callback = std::move(o.callback);
46 if(o.type == Type::Button) data.button.buttons = std::exchange(o.data.button.buttons, nullptr);
47 else if(o.type == Type::MultiButton) data.multi.quadButtons = std::exchange(o.data.multi.quadButtons, nullptr);
48 return *this;
49 }
50
51 void Action::PumpButton(std::string_view name) {
52 assert(data.button.buttons);
53 uint8_t state = Button::IsSetPressed(*data.button.buttons);
54 if (state != data.button.last_state) {
55 if(data.button.combo) {
56 if(bool comboState = state == data.button.buttons->size(), lastComboState = data.button.last_state == data.button.buttons->size(); comboState != lastComboState)
57 callback(name, {(float)comboState}, {(float)lastComboState});
58 } else callback(name, {(float)state}, {(float)data.button.last_state});
59 data.button.last_state = state;
60 }
61 }
62
63 void Action::PumpAxis(std::string_view name) {
64 float state = data.axis.last_state;
65 switch(data.axis.type) {
66 break; case Data::Axis::Type::Gamepad: {
67 float movement = GetGamepadAxisMovement(data.axis.gamepad.id, data.axis.gamepad.axis);
68 if(movement != 0) state += movement;
69 }
70 break; case Data::Axis::Type::MouseWheel: {
71 float movement = GetMouseWheelMove();
72 if(movement != 0) state += movement;
73 }
74 break; default: assert(data.axis.type != Data::Axis::Type::Invalid);
75 }
76 if (state != data.axis.last_state) {
77 callback(name, {state}, {state - data.axis.last_state});
78 data.axis.last_state = state;
79 }
80 }
81
82 void Action::PumpVector(std::string_view name) {
83 Vector2 state = data.vector.last_state;
84 switch(data.vector.type) {
85 break; case Data::Vector::Type::MouseWheel:
86 state = GetMouseWheelMoveV();
87 break; case Data::Vector::Type::MousePosition:
88 state = GetMousePosition();
89 // break; case Type::MouseDelta:
90 // state = GetMouseDelta();
91 break; case Data::Vector::Type::GamepadAxes: {
92 state.x += GetGamepadAxisMovement(data.vector.gamepad.horizontal.id, data.vector.gamepad.horizontal.axis);
93 state.y += GetGamepadAxisMovement(data.vector.gamepad.vertical.id, data.vector.gamepad.vertical.axis);
94 }
95 break; default: assert(data.vector.type != Data::Vector::Type::Invalid);
96 }
97 if (!Vector2Equals(state, data.vector.last_state)) {
98 callback(name, state, Vector2Subtract(state, data.vector.last_state));
99 data.vector.last_state = state;
100 }
101 }
102
103 Action Action::gamepad_axes(GamepadAxis horizontal /*= GAMEPAD_AXIS_LEFT_X*/, GamepadAxis vertical /*= GAMEPAD_AXIS_LEFT_Y*/, int gamepadHorizontal /*= 0*/, int gamepadVertical /*= -1*/) {
104 if(gamepadVertical < 0) gamepadVertical = gamepadHorizontal;
105
106 Action out = {Action::Type::Vector, {.vector = { Data::Vector::Type::GamepadAxes}}};
107 out.data.vector.gamepad = {{gamepadHorizontal, horizontal}, {gamepadVertical, vertical}};
108 return out;
109 }
110
111 void Action::PumpMultiButton(std::string_view name) {
112 Vector2 state = data.multi.last_state;
113 {
114 auto type = data.multi.type;
115 std::array<uint8_t, 4> buttonState;
116 for(uint8_t i = 0; i < (type == Data::MultiButton::Type::QuadButtons ? 4 : 2); i++) {
117 buttonState[i] = Button::IsSetPressed(data.multi.quadButtons->directions[i]);
118 if(data.multi.quadButtons->normalize && buttonState[i] > 0)
119 buttonState[i] = 1;
120 }
121 if(type == Data::MultiButton::Type::QuadButtons)
122 state.x = buttonState[MultiButtonData<4>::Direction::Left] - buttonState[MultiButtonData<4>::Direction::Right];
123 state.y = buttonState[MultiButtonData<4>::Direction::Up] - buttonState[MultiButtonData<4>::Direction::Down];
124
125 if(type == Data::MultiButton::Type::ButtonPair)
126 state.x = state.y;
127 }
128 if (!Vector2Equals(state, data.multi.last_state)) {
129 callback(name, state, Vector2Subtract(state, data.multi.last_state));
130 data.multi.last_state = state;
131 }
132 }
133
134 void Action::PollEvents(std::string_view name) {
135 switch(type){
136 break; case Action::Type::Button:
137 PumpButton(name);
138 break; case Action::Type::Axis:
139 PumpAxis(name);
140 break; case Action::Type::Vector:
141 PumpVector(name);
142 break; case Action::Type::MultiButton:
143 PumpMultiButton(name);
144 break; default: assert(type != Action::Type::Invalid);
145 }
146 }
147
148 void BufferedInput::PollEvents(bool whileUnfocused /*= false*/) {
149 if(!whileUnfocused && !IsWindowFocused()) return;
150 for(auto& [name, action]: actions)
151 action.PollEvents(name);
152 }
153}
Vector2 type.
Definition: Vector2.hpp:20
All raylib-cpp classes and functions appear in the raylib namespace.
Definition: AudioDevice.hpp:8
Represents various input action types, such as buttons, axes (controller trigger, mouse wheel),...
void PollEvents(std::string_view name)
Function which updates the state of the action and invokes the callback if a change occured.
static Action gamepad_axes(GamepadAxis horizontal=GAMEPAD_AXIS_LEFT_X, GamepadAxis vertical=GAMEPAD_AXIS_LEFT_Y, int gamepadHorizontal=0, int gamepadVertical=-1)
Action that merges two seperate gamepad axis into a single vector.
Represents various input button types, including keyboard keys, mouse buttons, and gamepad buttons.
static bool IsPressed(const Button &button)
Checks if the specified button is currently pressed.
bool operator<(const Button &o) const
Overloaded less-than operator for comparing buttons.
static uint8_t IsSetPressed(const std::set< Button > &buttons)
Checks if a set of buttons is pressed.