Skip to content

Input ​

Keyboard, mouse, and game controller input handling.

Header: #include <asw/modules/input.h>
Namespace: asw::input

Keyboard ​

Key Enum ​

The asw::input::Key enum maps to SDL scancodes. Common keys include:

KeyDescription
Key::A - Key::ZLetter keys
Key::Num0 - Key::Num9Number keys
Key::F1 - Key::F24Function keys
Key::ReturnEnter key
Key::EscapeEscape key
Key::SpaceSpacebar
Key::Up, Key::Down, Key::Left, Key::RightArrow keys
Key::LShift, Key::RShiftShift keys
Key::LCtrl, Key::RCtrlControl keys
Key::LAlt, Key::RAltAlt keys
Key::TabTab key
Key::BackspaceBackspace key

Keyboard Functions ​

get_key ​

cpp
bool get_key(asw::input::Key key);

Check if a key is currently held down.

get_key_down ​

cpp
bool get_key_down(asw::input::Key key);

Check if a key was pressed since the last update (single-frame). A held key does not repeat.

get_key_repeat ​

cpp
bool get_key_repeat(asw::input::Key key);

Check if a key was pressed or auto-repeated since the last update. A held key repeats at the rate that the operating system sets. Use it for text editing and menu movement, and get_key_down() for game actions.

get_key_up ​

cpp
bool get_key_up(asw::input::Key key);

Check if a key was released since the last update (single-frame).

KeyState ​

cpp
const KeyState& get_keyboard();

Get the current keyboard state. Fields:

FieldTypeDescription
pressedstd::array<bool, NUM_KEYS>Keys pressed this frame
releasedstd::array<bool, NUM_KEYS>Keys released this frame
downstd::array<bool, NUM_KEYS>Keys currently held
repeatedstd::array<bool, NUM_KEYS>Keys pressed or auto-repeated this frame
any_pressedboolWhether any key is pressed
last_pressedintLast pressed key index

Text Input ​

cpp
const std::string& get_text_input();

Get the text input received during the current frame. Useful for text fields and chat input.

Mouse ​

MouseButton Enum ​

ValueDescription
MouseButton::LeftLeft mouse button
MouseButton::MiddleMiddle mouse button
MouseButton::RightRight mouse button
MouseButton::X1Extra button 1
MouseButton::X2Extra button 2

Mouse Functions ​

get_mouse_button ​

cpp
bool get_mouse_button(asw::input::MouseButton button);

Check if a mouse button is currently held down.

get_mouse_button_down ​

cpp
bool get_mouse_button_down(asw::input::MouseButton button);

Check if a mouse button was pressed since the last update.

get_mouse_button_up ​

cpp
bool get_mouse_button_up(asw::input::MouseButton button);

Check if a mouse button was released since the last update.

MouseState ​

cpp
const MouseState& get_mouse();

Get the current mouse state. Fields:

FieldTypeDescription
positionVec2<float>Current mouse position
changeVec2<float>Total movement since the last frame
zfloatScroll wheel value
any_pressedboolWhether any button is pressed
last_pressedintButton pressed this frame, or -1 if none

Cursor ​

set_cursor ​

cpp
void set_cursor(asw::input::CursorId cursor);

Change the system cursor. Available cursors include CursorId::Default, CursorId::Text, CursorId::Wait, CursorId::Crosshair, CursorId::Pointer, and various resize cursors.

set_cursor_visible ​

cpp
void set_cursor_visible(bool visible);

Show or hide the mouse cursor. Use this if your game draws its own cursor.

Game Controller ​

Each controller keeps its index while other controllers are disconnected. A controller that is connected again gets its old index back. ASW finds it by its serial number, or by its model if it has no serial number. A new controller takes the first empty index.

ANY_CONTROLLER ​

cpp
constexpr uint32_t ANY_CONTROLLER = UINT32_MAX;

Pass ANY_CONTROLLER as the controller index to read all connected controllers. A button is active if it is active on any controller. Axes and sticks return the value that is farthest from the center.

Use it for single-player games, so the player can use any controller.

ControllerButton Enum ​

ValueDescription
ControllerButton::ASouth face button
ControllerButton::BEast face button
ControllerButton::XWest face button
ControllerButton::YNorth face button
ControllerButton::BackBack/Select button
ControllerButton::StartStart button
ControllerButton::GuideGuide/Home button
ControllerButton::LeftStickLeft stick press
ControllerButton::RightStickRight stick press
ControllerButton::LeftShoulderLeft bumper
ControllerButton::RightShoulderRight bumper
ControllerButton::DPadUp/Down/Left/RightD-pad directions
ControllerButton::Misc1Extra button (for example, Share or Capture)
ControllerButton::LeftPaddle1/2, RightPaddle1/2Back paddles
ControllerButton::TouchPadTouchpad press

ControllerAxis Enum ​

ValueDescription
ControllerAxis::LeftXLeft stick X axis
ControllerAxis::LeftYLeft stick Y axis
ControllerAxis::RightXRight stick X axis
ControllerAxis::RightYRight stick Y axis
ControllerAxis::LeftTriggerLeft trigger
ControllerAxis::RightTriggerRight trigger

ControllerStick Enum ​

ValueDescription
ControllerStick::LeftLeft analog stick
ControllerStick::RightRight analog stick

Controller Functions ​

In all of these functions, index is the controller index or ANY_CONTROLLER.

get_controller_button ​

cpp
bool get_controller_button(uint32_t index, asw::input::ControllerButton button);

Check if a controller button is currently held down.

get_controller_button_down ​

cpp
bool get_controller_button_down(uint32_t index, asw::input::ControllerButton button);

Check if a controller button was pressed since the last update.

get_controller_button_up ​

cpp
bool get_controller_button_up(uint32_t index, asw::input::ControllerButton button);

Check if a controller button was released since the last update.

get_controller_axis ​

cpp
float get_controller_axis(uint32_t index, asw::input::ControllerAxis axis);

Get the value of a controller axis, with the dead zone applied. Sticks go from -1.0f to 1.0f, and triggers go from 0.0f to 1.0f.

Stick axes use a radial dead zone, so a stick that is pushed straight along one axis reads zero on the other axis. Values past the dead zone are rescaled to start from zero.

get_controller_stick ​

cpp
Vec2<float> get_controller_stick(uint32_t index, asw::input::ControllerStick stick);

Get the position of a controller stick, with the dead zone applied. The length of the result is 1 or less. Use this for movement in all directions, because it keeps diagonal speed the same as straight speed.

set_controller_dead_zone ​

cpp
void set_controller_dead_zone(uint32_t index, float dead_zone);

Set the dead zone of a controller, from 0.0f to 1.0f (default: 0.25f). Values are clamped to the range 0.0f to 0.99f. Pass ANY_CONTROLLER to set it for all connected controllers, and for controllers that connect later.

get_controller_count ​

cpp
int get_controller_count();

Get the number of controller indexes: the highest connected index plus one. Returns 0 when no controller is connected. An index below this count can be empty, so check it with is_controller_connected().

is_controller_connected ​

cpp
bool is_controller_connected(uint32_t index);

Returns true if a controller is connected at the index.

get_controller_name ​

cpp
std::string get_controller_name(uint32_t index);

Get the name of a controller.

Rumble ​

rumble_controller ​

cpp
bool rumble_controller(uint32_t index, float low_frequency, float high_frequency,
                       uint32_t duration_ms);

Rumble the main motors of a controller. low_frequency is the left motor and high_frequency is the right motor, each from 0.0f to 1.0f. Each call replaces the last rumble on that controller. Call with both values at 0 to stop early. Pass ANY_CONTROLLER to rumble all connected controllers. Returns true if at least one controller started to rumble.

rumble_controller_triggers ​

cpp
bool rumble_controller_triggers(uint32_t index, float left, float right, uint32_t duration_ms);

Rumble the trigger motors of a controller, from 0.0f to 1.0f. Only some controllers have trigger motors, for example Xbox One and Xbox Series controllers. Works the same as rumble_controller().

controller_has_rumble / controller_has_trigger_rumble ​

cpp
bool controller_has_rumble(uint32_t index);
bool controller_has_trigger_rumble(uint32_t index);

Returns true if the controller supports rumble or trigger rumble. With ANY_CONTROLLER, returns true if any connected controller does.

cpp
if (player_hit) {
  asw::input::rumble_controller(asw::input::ANY_CONTROLLER, 0.8f, 0.4f, 200);
}

Constants ​

ConstantValueDescription
NUM_KEYSSDL_SCANCODE_COUNTNumber of keys
NUM_MOUSE_BUTTONS6Number of mouse buttons
NUM_CURSORSSDL_SYSTEM_CURSOR_COUNTNumber of system cursors
NUM_CONTROLLER_BUTTONSSDL_GAMEPAD_BUTTON_COUNTNumber of controller buttons
NUM_CONTROLLER_AXESSDL_GAMEPAD_AXIS_COUNTNumber of controller axes
ANY_CONTROLLERUINT32_MAXController index that reads all connected controllers. See ANY_CONTROLLER

Last Used Device ​

InputDevice Enum ​

ValueDescription
InputDevice::KeyboardMouseKeyboard and mouse
InputDevice::ControllerA game controller

get_last_device ​

cpp
InputDevice get_last_device();

Get the device that the player used most recently. Use it to show keyboard or controller prompts. Key presses, mouse clicks and mouse motion count as KeyboardMouse. Button presses, and axes past the dead zone, count as Controller. The default is KeyboardMouse.

Simulated Input ​

These functions queue the same events that a real device sends. The game gets them through the normal input path on the next asw::core::update(). Use them to script demos or automated test runs.

simulate_key_down ​

cpp
void simulate_key_down(asw::input::Key key);

Simulate a key press.

simulate_key_up ​

cpp
void simulate_key_up(asw::input::Key key);

Simulate a key release.

simulate_mouse_move ​

cpp
void simulate_mouse_move(const asw::Vec2<float>& position);

Simulate a mouse move. position is in logical (render) coordinates, the same space that get_mouse() reports.

simulate_mouse_button_down ​

cpp
void simulate_mouse_button_down(asw::input::MouseButton button);

Simulate a mouse button press.

simulate_mouse_button_up ​

cpp
void simulate_mouse_button_up(asw::input::MouseButton button);

Simulate a mouse button release.

Actions ​

To bind named actions to keys, mouse buttons and controller input, see Actions.

Reset ​

reset ​

cpp
void reset();

Reset the per-frame input states. asw::core::update() calls this for you.

Example ​

cpp
// Keyboard
if (asw::input::get_key_down(asw::input::Key::Space)) {
  // jump
}

if (asw::input::get_key(asw::input::Key::A)) {
  // move left while held
}

// Mouse
if (asw::input::get_mouse_button_down(asw::input::MouseButton::Left)) {
  auto pos = asw::input::get_mouse().position;
  // handle click at pos
}

// Controller
auto move = asw::input::get_controller_stick(asw::input::ANY_CONTROLLER,
                                            asw::input::ControllerStick::Left);
if (asw::input::get_controller_button_down(asw::input::ANY_CONTROLLER,
                                           asw::input::ControllerButton::A)) {
  // jump
}

// Text input
if (!asw::input::get_text_input().empty()) {
  // handle typed text
}

// Scripted input, read on the next asw::core::update()
asw::input::simulate_key_down(asw::input::Key::Space);

// Show the right button prompts
bool use_pad = asw::input::get_last_device() == asw::input::InputDevice::Controller;

Released under the MIT License.