Antkeeper  0.0.1
gamepad.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_INPUT_GAMEPAD_HPP
21 #define ANTKEEPER_INPUT_GAMEPAD_HPP
22 
23 #include <engine/input/device.hpp>
28 #include <cstdint>
29 
30 namespace input {
31 
33 enum class gamepad_response_curve: std::uint8_t
34 {
36  linear,
37 
39  square,
40 
42  cube
43 };
44 
48 class gamepad: public device
49 {
50 public:
54  gamepad();
55 
63  void set_activation_threshold(gamepad_axis axis, float min, float max);
64 
72 
78  void set_left_deadzone_cross(bool cross);
79 
86 
92  void set_left_deadzone_roundness(float roundness);
93 
99  void set_right_deadzone_roundness(float roundness);
100 
106  void press(gamepad_button button);
107 
113  void release(gamepad_button button);
114 
121  void move(gamepad_axis axis, float position);
122 
124  [[nodiscard]] inline ::event::channel<gamepad_button_pressed_event>& get_button_pressed_channel() noexcept
125  {
126  return button_pressed_publisher.channel();
127  }
128 
130  [[nodiscard]] inline ::event::channel<gamepad_button_released_event>& get_button_released_channel() noexcept
131  {
132  return button_released_publisher.channel();
133  }
134 
136  [[nodiscard]] inline ::event::channel<gamepad_axis_moved_event>& get_axis_moved_channel() noexcept
137  {
138  return axis_moved_publisher.channel();
139  }
140 
142  [[nodiscard]] inline constexpr device_type get_device_type() const noexcept override
143  {
144  return device_type::gamepad;
145  }
146 
147 private:
148  void handle_axial_motion(gamepad_axis axis);
149  void handle_biaxial_motion(gamepad_axis axis_x, gamepad_axis axis_y);
150  float curve_response(gamepad_axis axis, float response) const;
151 
152  float axis_positions[6];
153  float axis_activation_min[6];
154  float axis_activation_max[6];
155  gamepad_response_curve axis_response_curves[6];
156  bool left_deadzone_cross{true};
157  bool right_deadzone_cross{true};
158  float left_deadzone_roundness{0.0f};
159  float right_deadzone_roundness{0.0f};
160 
161  ::event::publisher<gamepad_button_pressed_event> button_pressed_publisher;
162  ::event::publisher<gamepad_button_released_event> button_released_publisher;
164 };
165 
166 } // namespace input
167 
168 #endif // ANTKEEPER_INPUT_GAMEPAD_HPP
Publishes messages to subscribers.
Definition: publisher.hpp:36
Abstract base class for virtual devices that generate input events.
Definition: device.hpp:36
A virtual gamepad which generates gamepad-related input events.
Definition: gamepad.hpp:49
void set_left_deadzone_cross(bool cross)
Sets the type of deadzone shape for the axes on the left stick.
Definition: gamepad.cpp:50
void move(gamepad_axis axis, float position)
Simulates a gamepad axis movement.
Definition: gamepad.cpp:80
::event::channel< gamepad_button_pressed_event > & get_button_pressed_channel() noexcept
Returns the channel through which gamepad button pressed events are published.
Definition: gamepad.hpp:124
gamepad()
Constructs a gamepad input device.
Definition: gamepad.cpp:28
void set_activation_threshold(gamepad_axis axis, float min, float max)
Sets the activation threshold for a gamepad axis.
Definition: gamepad.cpp:39
void press(gamepad_button button)
Simulates a gamepad button press.
Definition: gamepad.cpp:70
void set_right_deadzone_roundness(float roundness)
Sets the roundness of the deadzone for the axes on the right stick.
Definition: gamepad.cpp:65
::event::channel< gamepad_button_released_event > & get_button_released_channel() noexcept
Returns the channel through which gamepad button released events are published.
Definition: gamepad.hpp:130
void set_right_deadzone_cross(bool cross)
Sets the type of deadzone shape for the axes on the right stick.
Definition: gamepad.cpp:55
constexpr device_type get_device_type() const noexcept override
Returns device_type::gamepad.
Definition: gamepad.hpp:142
::event::channel< gamepad_axis_moved_event > & get_axis_moved_channel() noexcept
Returns the channel through which gamepad axis moved events are published.
Definition: gamepad.hpp:136
void set_left_deadzone_roundness(float roundness)
Sets the roundness of the deadzone for the axes on the left stick.
Definition: gamepad.cpp:60
void set_response_curve(gamepad_axis axis, gamepad_response_curve curve)
Sets the activation response curve of an axis.
Definition: gamepad.cpp:45
void release(gamepad_button button)
Simulates a gamepad button release.
Definition: gamepad.cpp:75
Input devices, events, and mapping.
gamepad_response_curve
Gamepad axis activation response curves.
Definition: gamepad.hpp:34
@ cube
Cubed response curve.
@ square
Squared response curve.
@ linear
Linear response curve.
gamepad_button
Gamepad buttons.
device_type
Input device types.
Definition: device-type.hpp:29
@ gamepad
Gamepad input device.
gamepad_axis
Gamepad axes.
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
Definition: vector.hpp:1095