From adc5ceb6e5d804eb4061399980ea70b39d52cf26 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Mon, 13 Feb 2023 15:48:20 +0800 Subject: [PATCH] Improve keyboard config menu. Add support for modifier keys in key mappings --- CMakeLists.txt | 1 - src/app/sdl/sdl-input-manager.cpp | 25 ++- src/game/context.hpp | 8 + src/game/controls.cpp | 48 +++-- src/game/menu.cpp | 26 ++- src/game/state/boot.cpp | 9 +- src/game/state/collection-menu.cpp | 181 ++++++++++++++++ src/game/state/collection-menu.hpp | 65 ++++++ src/game/state/controls-menu.cpp | 2 +- src/game/state/keyboard-config-menu.cpp | 271 ++++++++++-------------- src/game/state/keyboard-config-menu.hpp | 13 +- src/game/state/language-menu.cpp | 2 +- src/game/state/main-menu.cpp | 15 +- src/input/control-map.cpp | 155 +++++++++----- src/input/control-map.hpp | 59 +++++- src/input/gamepad.cpp | 4 +- src/input/mapping.cpp | 5 +- src/input/mapping.hpp | 6 +- src/input/scancode.hpp | 266 +++++++++++------------ 19 files changed, 755 insertions(+), 406 deletions(-) create mode 100644 src/game/state/collection-menu.cpp create mode 100644 src/game/state/collection-menu.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c9deac5..baf682a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.25) - option(APPLICATION_NAME "Application name" "Antkeeper") option(APPLICATION_VERSION "Application version string" "0.0.0") option(APPLICATION_AUTHOR "Application author" "C. J. Howard") diff --git a/src/app/sdl/sdl-input-manager.cpp b/src/app/sdl/sdl-input-manager.cpp index 12eaf47..ba5a271 100644 --- a/src/app/sdl/sdl-input-manager.cpp +++ b/src/app/sdl/sdl-input-manager.cpp @@ -127,7 +127,7 @@ void sdl_input_manager::update() const input::scancode scancode = static_cast(event.key.keysym.scancode); // Rebuild modifier keys bit mask - if (event.key.keysym.mod != sdl_key_mod) + if (sdl_key_mod != event.key.keysym.mod) { sdl_key_mod = event.key.keysym.mod; @@ -140,6 +140,10 @@ void sdl_input_manager::update() modifier_keys |= input::modifier_key::left_ctrl; if (sdl_key_mod & KMOD_RCTRL) modifier_keys |= input::modifier_key::right_ctrl; + if (sdl_key_mod & KMOD_LALT) + modifier_keys |= input::modifier_key::left_alt; + if (sdl_key_mod & KMOD_RALT) + modifier_keys |= input::modifier_key::right_alt; if (sdl_key_mod & KMOD_LGUI) modifier_keys |= input::modifier_key::left_gui; if (sdl_key_mod & KMOD_RGUI) @@ -237,14 +241,19 @@ void sdl_input_manager::update() if (SDL_IsGameController(event.cdevice.which)) { SDL_GameController* sdl_controller = SDL_GameControllerOpen(event.cdevice.which); - const char* controller_name = SDL_GameControllerNameForIndex(event.cdevice.which); - if (sdl_controller) { + // Get gamepad name + const char* controller_name = SDL_GameControllerNameForIndex(event.cdevice.which); + if (!controller_name) + { + controller_name = ""; + } + if (auto it = gamepad_map.find(event.cdevice.which); it != gamepad_map.end()) { // Gamepad reconnected - debug::log::info("Reconnected gamepad \"{}\"", controller_name); + debug::log::info("Reconnected gamepad {}", event.cdevice.which); it->second->connect(); } else @@ -257,7 +266,7 @@ void sdl_input_manager::update() ::uuid gamepad_uuid; std::memcpy(gamepad_uuid.data.data(), sdl_guid.data, gamepad_uuid.data.size()); - debug::log::info("Connected gamepad \"{}\" (UUID: {})", controller_name, gamepad_uuid.string()); + debug::log::info("Connected gamepad {}; name: \"{}\"; UUID: {}", event.cdevice.which, controller_name, gamepad_uuid.string()); // Create new gamepad input::gamepad* gamepad = new input::gamepad(); @@ -275,7 +284,7 @@ void sdl_input_manager::update() } else { - debug::log::error("Failed to connected gamepad \"{}\": {}", controller_name, SDL_GetError()); + debug::log::error("Failed to connect gamepad {}: {}", event.cdevice.which, SDL_GetError()); SDL_ClearError(); } } @@ -289,15 +298,13 @@ void sdl_input_manager::update() if (sdl_controller) { - const char* controller_name = SDL_GameControllerNameForIndex(event.cdevice.which); - SDL_GameControllerClose(sdl_controller); if (auto it = gamepad_map.find(event.cdevice.which); it != gamepad_map.end()) { it->second->disconnect(); } - debug::log::info("Disconnected gamepad \"{}\"", controller_name); + debug::log::info("Disconnected gamepad {}", event.cdevice.which); } break; diff --git a/src/game/context.hpp b/src/game/context.hpp index d4cea21..512a97f 100644 --- a/src/game/context.hpp +++ b/src/game/context.hpp @@ -192,6 +192,14 @@ struct context input::control menu_modifier_control; std::vector> menu_control_subscriptions; std::vector> menu_mouse_subscriptions; + input::control_map movement_controls; + input::control move_forward_control; + input::control move_back_control; + input::control move_left_control; + input::control move_right_control; + input::control move_up_control; + input::control move_down_control; + input::control pause_control; // Debugging math::moving_average average_frame_time; diff --git a/src/game/controls.cpp b/src/game/controls.cpp index 0bde120..84d3fbb 100644 --- a/src/game/controls.cpp +++ b/src/game/controls.cpp @@ -22,6 +22,7 @@ #include "game/menu.hpp" #include "resources/resource-manager.hpp" #include "resources/json.hpp" +#include "input/modifier-key.hpp" namespace game { @@ -29,7 +30,9 @@ void setup_window_controls(game::context& ctx) { // Map window controls ctx.window_controls.add_mapping(ctx.fullscreen_control, input::key_mapping(nullptr, input::scancode::f11, false)); + ctx.window_controls.add_mapping(ctx.fullscreen_control, input::key_mapping(nullptr, input::scancode::enter, false, input::modifier_key::alt)); ctx.window_controls.add_mapping(ctx.screenshot_control, input::key_mapping(nullptr, input::scancode::f12, false)); + ctx.window_controls.add_mapping(ctx.screenshot_control, input::key_mapping(nullptr, input::scancode::print_screen, false)); // Setup fullscreen control ctx.window_control_subscriptions.emplace_back @@ -203,10 +206,10 @@ void enable_menu_controls(game::context& ctx) ctx.menu_controls.connect(ctx.input_manager->get_event_queue()); // Function to select menu item at mouse position - auto select_menu_item = [&ctx](const math::vector& mouse_position) + auto select_menu_item = [&ctx](const math::vector& mouse_position) -> bool { const float padding = config::menu_mouseover_padding * ctx.menu_font.get_font_metrics().size; - + for (std::size_t i = 0; i < ctx.menu_item_texts.size(); ++i) { auto [name, value] = ctx.menu_item_texts[i]; @@ -240,10 +243,12 @@ void enable_menu_controls(game::context& ctx) { *ctx.menu_item_index = static_cast(i); game::menu::update_text_color(ctx); - break; + return true; } } } + + return false; }; // Enable menu mouse tracking @@ -266,29 +271,30 @@ void enable_menu_controls(game::context& ctx) [&ctx, select_menu_item](const auto& event) { // Select menu item at mouse position (if any) - select_menu_item(math::vector(event.position)); - - // Determine appropriate menu item callback - auto callback = ctx.menu_select_callbacks[*ctx.menu_item_index]; - if (event.button == input::mouse_button::left) + if (select_menu_item(math::vector(event.position))) { - if (ctx.menu_left_callbacks[*ctx.menu_item_index]) + // Determine appropriate menu item callback + auto callback = ctx.menu_select_callbacks[*ctx.menu_item_index]; + if (event.button == input::mouse_button::left) { - callback = ctx.menu_left_callbacks[*ctx.menu_item_index]; + if (ctx.menu_left_callbacks[*ctx.menu_item_index]) + { + callback = ctx.menu_left_callbacks[*ctx.menu_item_index]; + } } - } - else if (event.button == input::mouse_button::right) - { - if (ctx.menu_right_callbacks[*ctx.menu_item_index]) + else if (event.button == input::mouse_button::right) { - callback = ctx.menu_right_callbacks[*ctx.menu_item_index]; + if (ctx.menu_right_callbacks[*ctx.menu_item_index]) + { + callback = ctx.menu_right_callbacks[*ctx.menu_item_index]; + } + } + + // Invoke menu item callback + if (callback) + { + callback(); } - } - - // Invoke menu item callback - if (callback) - { - callback(); } } ) diff --git a/src/game/menu.cpp b/src/game/menu.cpp index 00e99b0..3cca780 100644 --- a/src/game/menu.cpp +++ b/src/game/menu.cpp @@ -85,29 +85,37 @@ void update_text_tweens(game::context& ctx) void align_text(game::context& ctx, bool center, bool has_back, float anchor_y) { + + const vec2 viewport_size = vec2(ctx.window->get_viewport_size()); const vec2 viewport_center = viewport_size * 0.5f; + const float viewport_padding = viewport_size.y() * (1.0f / 9.0f); + // Calculate menu width + float m_width = ctx.menu_font.get_glyph_metrics(U'M').width; + float column_spacing = m_width * 2.0f; + const float min_two_column_row_width = m_width * 18.0f; float menu_width = 0.0f; - float menu_spacing = ctx.menu_font.get_glyph_metrics(U'M').width; for (auto [name, value]: ctx.menu_item_texts) { float row_width = 0.0f; - // Add name width to width + // Add name width to row width const auto& name_bounds = static_cast&>(name->get_local_bounds()); row_width += name_bounds.max_point.x() - name_bounds.min_point.x(); if (value) { - // Add value width to width - //const auto& value_bounds = static_cast&>(value->get_local_bounds()); - //row_width += value_bounds.max_point.x() - value_bounds.min_point.x(); + // Add value width to row width + const auto& value_bounds = static_cast&>(value->get_local_bounds()); + row_width += value_bounds.max_point.x() - value_bounds.min_point.x(); - // Add spacing to row width - row_width += menu_spacing * 8.0f; + // Add column spacing to row width + row_width += column_spacing; + + row_width = std::max(min_two_column_row_width, row_width); } menu_width = std::max(menu_width, row_width); @@ -130,7 +138,9 @@ void align_text(game::context& ctx, bool center, bool has_back, float anchor_y) float x = menu_x; float y = menu_y - ctx.menu_font.get_font_metrics().linespace * i; if (has_back && i == ctx.menu_item_texts.size() - 1) - y -= ctx.menu_font.get_font_metrics().linespace; + { + y = viewport_padding;// + ctx.menu_font.get_font_metrics().linespace; + } if (center || i == ctx.menu_item_texts.size() - 1) { diff --git a/src/game/state/boot.cpp b/src/game/state/boot.cpp index 1f4632a..042e58a 100644 --- a/src/game/state/boot.cpp +++ b/src/game/state/boot.cpp @@ -35,6 +35,7 @@ #include "game/strings.hpp" #include "game/state/boot.hpp" #include "game/state/splash.hpp" +#include "game/state/main-menu.hpp" #include "game/system/astronomy.hpp" #include "game/system/atmosphere.hpp" #include "game/system/behavior.hpp" @@ -133,8 +134,8 @@ boot::boot(game::context& ctx, int argc, const char* const* argv): debug::log::trace("Boot up complete"); - // Push splash state - ctx.state_machine.emplace(new game::state::splash(ctx)); + // Push next state + ctx.state_machine.emplace(new game::state::main_menu(ctx, true)); // Enter main loop debug::log::trace("Entered main loop"); @@ -847,8 +848,8 @@ void boot::setup_scenes() float clip_right = viewport_size[0]; float clip_top = 0.0f; float clip_bottom = viewport_size[1]; - float clip_near = 0.0f; - float clip_far = 1000.0f; + float clip_near = -100.0f; + float clip_far = 100.0f; ctx.ui_camera->set_orthographic(clip_left, clip_right, clip_top, clip_bottom, clip_near, clip_far); ctx.ui_camera->look_at({0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f}); ctx.ui_camera->update_tweens(); diff --git a/src/game/state/collection-menu.cpp b/src/game/state/collection-menu.cpp new file mode 100644 index 0000000..3b7cf43 --- /dev/null +++ b/src/game/state/collection-menu.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "game/state/collection-menu.hpp" +#include "game/state/main-menu.hpp" +#include "game/controls.hpp" +#include "scene/text.hpp" +#include "debug/log.hpp" +#include "game/menu.hpp" +#include "game/strings.hpp" +#include "utility/hash/fnv1a.hpp" +#include "resources/resource-manager.hpp" +#include "animation/screen-transition.hpp" +#include "animation/ease.hpp" +#include "render/passes/clear-pass.hpp" + +using namespace hash::literals; + +namespace game { +namespace state { + +collection_menu::collection_menu(game::context& ctx): + game::state::base(ctx) +{ + debug::log::trace("Entering collection menu state..."); + + // Enable color buffer clearing in UI pass + ctx.ui_clear_pass->set_cleared_buffers(true, true, false); + + // Construct box material + box_material.set_blend_mode(render::blend_mode::translucent); + box_material.set_shader_program(ctx.resource_manager->load("ui-element-untextured.glsl")); + box_material.add_property("tint")->set_value(float4{0.5f, 0.5f, 0.5f, 1}); + box_material.update_tweens(); + + // Construct box billboard + box_billboard.set_material(&box_material); + + // Construct selection material + selection_material.set_blend_mode(render::blend_mode::translucent); + selection_material.set_shader_program(ctx.resource_manager->load("ui-element-untextured.glsl")); + selection_material.add_property("tint")->set_value(float4{1, 1, 1, 1}); + selection_material.update_tweens(); + + // Construct selection billboard + selection_billboard.set_material(&selection_material); + + // Add box and selection billboard to UI scene + ctx.ui_scene->add_object(&box_billboard); + ctx.ui_scene->add_object(&selection_billboard); + + row_count = 64; + column_count = 6; + selected_row = 0; + selected_column = 0; + resize_box(); + + mouse_moved_subscription = ctx.input_manager->get_event_queue().subscribe + ( + [&](const auto& event) + { + + } + ); + + mouse_button_pressed_subscription = ctx.input_manager->get_event_queue().subscribe + ( + [&](const auto& event) + { + const auto& viewport_size = ctx.window->get_viewport_size(); + const float2 mouse_position = + { + static_cast(event.position.x()), + static_cast(viewport_size.y() - event.position.y() + 1) + }; + + if (box_bounds.contains(mouse_position)) + { + int column = static_cast((mouse_position.x() - box_bounds.min.x()) / selection_size); + int row = static_cast((box_bounds.max.y() - mouse_position.y()) / selection_size); + + if (column != selected_column || row != selected_row) + { + selected_column = column; + selected_row = row; + + selection_billboard.set_translation + ( + { + (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column, + (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row , + 0.0f + } + ); + selection_billboard.update_tweens(); + + debug::log::debug("selected colony: ({}, {})", selected_column, selected_row); + } + } + } + ); + + window_resized_subscription = ctx.window->get_resized_channel().subscribe + ( + [&](const auto& event) + { + this->resize_box(); + } + ); + + // Queue enable menu controls + //ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); + + // Fade in from black + ctx.fade_transition->transition(config::title_fade_in_duration, true, ease::out_cubic); + + debug::log::trace("Entered collection menu state"); +} + +collection_menu::~collection_menu() +{ + debug::log::trace("Exiting collection menu state..."); + + // Destruct menu + //game::disable_menu_controls(ctx); + + debug::log::trace("Exited collection menu state"); +} + +void collection_menu::resize_box() +{ + const float padding = 64.0f; + const auto viewport_size = float2(ctx.window->get_viewport_size()); + + box_bounds.min.x() = viewport_size.x() * 0.5f + padding; + box_bounds.max.x() = viewport_size.x() - padding; + + selection_size = (box_bounds.max.x() - box_bounds.min.x()) / static_cast(column_count); + + box_bounds.max.y() = viewport_size.y() - padding; + box_bounds.min.y() = std::max(padding, box_bounds.max.y() - selection_size * row_count); + + const float2 box_size = box_bounds.size(); + const float2 box_center = box_bounds.center(); + + // Resize box + box_billboard.set_scale({box_size.x() * 0.5f, box_size.y() * 0.5f, 1.0f}); + box_billboard.set_translation({box_center.x(), box_center.y(), -1.0f}); + box_billboard.update_tweens(); + + // Resize selection + selection_billboard.set_scale({selection_size * 0.5f, selection_size * 0.5f, 1.0f}); + selection_billboard.set_translation + ( + { + (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column, + (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row, + 0.0f + } + ); + selection_billboard.update_tweens(); +} + +} // namespace state +} // namespace game diff --git a/src/game/state/collection-menu.hpp b/src/game/state/collection-menu.hpp new file mode 100644 index 0000000..ed7985d --- /dev/null +++ b/src/game/state/collection-menu.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GAME_STATE_COLLECTION_MENU_HPP +#define ANTKEEPER_GAME_STATE_COLLECTION_MENU_HPP + +#include "game/state/base.hpp" +#include "event/subscription.hpp" +#include "render/material.hpp" +#include "scene/billboard.hpp" +#include "animation/animation.hpp" +#include "geom/primitive/rectangle.hpp" +#include + +namespace game { +namespace state { + +class collection_menu: public game::state::base +{ +public: + collection_menu(game::context& ctx); + virtual ~collection_menu(); + +private: + void resize_box(); + + render::material selection_material; + scene::billboard selection_billboard; + animation selection_snap_animation; + + render::material box_material; + scene::billboard box_billboard; + + std::shared_ptr mouse_moved_subscription; + std::shared_ptr mouse_button_pressed_subscription; + std::shared_ptr window_resized_subscription; + + geom::primitive::rectangle box_bounds; + int row_count; + int column_count; + int selected_row; + int selected_column; + float selection_size; +}; + +} // namespace state +} // namespace game + +#endif // ANTKEEPER_GAME_STATE_COLLECTION_MENU_HPP diff --git a/src/game/state/controls-menu.cpp b/src/game/state/controls-menu.cpp index 04e3737..66f663e 100644 --- a/src/game/state/controls-menu.cpp +++ b/src/game/state/controls-menu.cpp @@ -58,7 +58,7 @@ controls_menu::controls_menu(game::context& ctx): game::menu::update_text_color(ctx); game::menu::update_text_font(ctx); - game::menu::align_text(ctx); + game::menu::align_text(ctx, true); game::menu::update_text_tweens(ctx); game::menu::add_text_to_ui(ctx); game::menu::setup_animations(ctx); diff --git a/src/game/state/keyboard-config-menu.cpp b/src/game/state/keyboard-config-menu.cpp index 56ef44f..be1d3f0 100644 --- a/src/game/state/keyboard-config-menu.cpp +++ b/src/game/state/keyboard-config-menu.cpp @@ -27,6 +27,8 @@ #include "game/controls.hpp" #include "game/strings.hpp" #include "utility/hash/fnv1a.hpp" +#include +#include using namespace hash::literals; @@ -38,17 +40,14 @@ keyboard_config_menu::keyboard_config_menu(game::context& ctx): { debug::log::trace("Entering keyboard config menu state..."); - // Add camera control menu items - add_control_item("move_forward"); - add_control_item("move_back"); - add_control_item("move_left"); - add_control_item("move_right"); - add_control_item("move_up"); - add_control_item("move_down"); - - // Add application control menu items - add_control_item("toggle_fullscreen"); - add_control_item("screenshot"); + // Add control menu items + add_control_item(ctx.movement_controls, ctx.move_forward_control, "control_move_forward"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.move_back_control, "control_move_back"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.move_left_control, "control_move_left"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.move_right_control, "control_move_right"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.move_up_control, "control_move_up"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.move_down_control, "control_move_down"_fnv1a32); + add_control_item(ctx.movement_controls, ctx.pause_control, "control_pause"_fnv1a32); // Construct menu item texts scene::text* back_text = new scene::text(); @@ -131,105 +130,82 @@ keyboard_config_menu::~keyboard_config_menu() debug::log::trace("Exited keyboard config menu state..."); } -std::string keyboard_config_menu::get_binding_string(input::control* control) +std::string keyboard_config_menu::get_mapping_string(const input::control_map& control_map, const input::control& control) { - std::string binding_string; - /* - auto mappings = ctx.input_event_router->get_mappings(control); - for (input::mapping* mapping: *mappings) + std::string mapping_string; + + if (auto key_mappings = control_map.get_key_mappings(control); !key_mappings.empty()) { - std::string mapping_string; + const auto& key_mapping = key_mappings.front(); - switch (mapping->get_type()) + // Get name of scancode string from scancode + std::string scancode_string_name = std::format("scancode_{:02x}", std::to_underlying(key_mapping.scancode)); + + // Set mapping string to scancode string + mapping_string = get_string(ctx, hash::fnv1a32(scancode_string_name.data(), scancode_string_name.length())); + } + else if (auto mouse_button_mappings = control_map.get_mouse_button_mappings(control); !mouse_button_mappings.empty()) + { + const auto& mouse_button_mapping = mouse_button_mappings.front(); + switch (mouse_button_mapping.button) { - - case input::mapping_type::key: - { - const input::key_mapping* key_mapping = static_cast(mapping); - const char* scancode_name = input::keyboard::get_scancode_name(key_mapping->scancode); - mapping_string = scancode_name; + case input::mouse_button::left: + mapping_string = get_string(ctx, "mouse_button_left"_fnv1a32); break; - } - case input::mapping_type::mouse_wheel: - { - const input::mouse_wheel_mapping* wheel_mapping = static_cast(mapping); - - switch (wheel_mapping->axis) - { - case input::mouse_wheel_axis::negative_x: - mapping_string = (*ctx.strings)["mouse_wheel_left"]; - break; - - case input::mouse_wheel_axis::positive_x: - mapping_string = (*ctx.strings)["mouse_wheel_right"]; - break; - - case input::mouse_wheel_axis::negative_y: - mapping_string = (*ctx.strings)["mouse_wheel_down"]; - break; - - case input::mouse_wheel_axis::positive_y: - mapping_string = (*ctx.strings)["mouse_wheel_up"]; - break; - - default: - break; - } + case input::mouse_button::middle: + mapping_string = get_string(ctx, "mouse_button_middle"_fnv1a32); break; - } - case input::mapping_type::mouse_button: - { - const input::mouse_button_mapping* button_mapping = static_cast(mapping); - - if (button_mapping->button == 1) - { - mapping_string = (*ctx.strings)["mouse_button_left"]; - } - else if (button_mapping->button == 2) - { - mapping_string = (*ctx.strings)["mouse_button_middle"]; - } - else if (button_mapping->button == 3) - { - mapping_string = (*ctx.strings)["mouse_button_right"]; - } - else - { - const std::string& format = (*ctx.strings)["mouse_button_n"]; - char buffer[64]; - std::snprintf(buffer, 64, format.c_str(), button_mapping->button); - mapping_string = buffer; - } + case input::mouse_button::right: + mapping_string = get_string(ctx, "mouse_button_right"_fnv1a32); break; - } default: + { + std::string format_string = get_string(ctx, "mouse_button_n_format"_fnv1a32); + mapping_string = std::vformat(format_string, std::make_format_args(std::to_underlying(mouse_button_mapping.button))); break; + } } + } + else if (auto mouse_scroll_mappings = control_map.get_mouse_scroll_mappings(control); !mouse_scroll_mappings.empty()) + { + const auto& mouse_scroll_mapping = mouse_scroll_mappings.front(); - if (!mapping_string.empty()) + if (mouse_scroll_mapping.axis == input::mouse_scroll_axis::x) + { + if (!mouse_scroll_mapping.direction) + { + mapping_string = get_string(ctx, "mouse_scroll_left"_fnv1a32); + } + else + { + mapping_string = get_string(ctx, "mouse_scroll_right"_fnv1a32); + } + } + else { - if (binding_string.empty()) + if (!mouse_scroll_mapping.direction) { - binding_string = mapping_string; + mapping_string = get_string(ctx, "mouse_scroll_up"_fnv1a32); } else { - binding_string += " " + mapping_string; + mapping_string = get_string(ctx, "mouse_scroll_down"_fnv1a32); } } } - */ - return binding_string; + else + { + mapping_string = get_string(ctx, "control_unmapped"_fnv1a32); + } + + return mapping_string; } -void keyboard_config_menu::add_control_item(const std::string& control_name) +void keyboard_config_menu::add_control_item(input::control_map& control_map, input::control& control, std::uint32_t control_name_hash) { - // Get pointer to control - //input::control* control = ctx.controls[control_name]; - // Construct texts scene::text* name_text = new scene::text(); scene::text* value_text = new scene::text(); @@ -237,88 +213,71 @@ void keyboard_config_menu::add_control_item(const std::string& control_name) // Add texts to list of menu item texts ctx.menu_item_texts.push_back({name_text, value_text}); - // Set content of name text - name_text->set_content(control_name); + // Set control name and mapping texts + name_text->set_content(get_string(ctx, control_name_hash)); + value_text->set_content(get_mapping_string(control_map, control)); - // Set content of value text - //value_text->set_content(get_binding_string( control)); - - auto select_callback = [this, &ctx = this->ctx, value_text]() + // Callback invoked when an input has been mapped to the control + auto input_mapped_callback = [this, &ctx = this->ctx, control_map = &control_map, control = &control, value_text](const auto& event) { - // Disable menu controls - ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); + // Remove key mappings, mouse button mappings, and mouse scroll mappings mapped to the control + control_map->remove_mappings(*control, input::mapping_type::key); + control_map->remove_mappings(*control, input::mapping_type::mouse_button); + control_map->remove_mappings(*control, input::mapping_type::mouse_scroll); - // Clear binding string from value text - value_text->set_content(get_string(ctx, "ellipsis"_fnv1a32)); + //if (event.mapping.scancode != input::scancode::escape && event.mapping.scancode != input::scancode::backspace) + { + // Map generated input mapping to the control + control_map->add_mapping(*control, event.mapping); + } + + // Update control mapping text + value_text->set_content(this->get_mapping_string(*control_map, *control)); game::menu::align_text(ctx); game::menu::update_text_tweens(ctx); - /* - // Remove keyboard and mouse event mappings from control - ctx.input_event_router->remove_mappings(control, input::mapping_type::key); - ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_motion); - ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_wheel); - ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_button); + // Queue disabling of input mapper re-enabling of menu controls + ctx.function_queue.push + ( + [&ctx]() + { + ctx.input_mapper.disconnect(); + game::enable_menu_controls(ctx); + } + ); + }; + + // Callback invoked when the control menu item has been selected + auto select_callback = [this, &ctx = this->ctx, control_map = &control_map, control = &control, value_text, input_mapped_callback]() + { + // Set control mapping text to "..." + value_text->set_content(get_string(ctx, "control_mapping"_fnv1a32)); + game::menu::align_text(ctx); + game::menu::update_text_tweens(ctx); + + // Setup input mapped callbacks + key_mapped_subscription = ctx.input_mapper.get_key_mapped_channel().subscribe + ( + input_mapped_callback + ); + mouse_button_mapped_subscription = ctx.input_mapper.get_mouse_button_mapped_channel().subscribe + ( + input_mapped_callback + ); + mouse_scroll_mapped_subscription = ctx.input_mapper.get_mouse_scroll_mapped_channel().subscribe + ( + input_mapped_callback + ); - // Setup input binding listener - ctx.input_listener->set_callback + // Queue disabling of menu controls and enabling of input mapper + ctx.function_queue.push ( - [this, &ctx, control, value_text](const event_base& event) + [&]() { - auto id = event.get_event_type_id(); - if (id == key_pressed_event::event_type_id) - { - // Map key pressed event to control - const key_pressed_event& key_event = static_cast(event); - - if (key_event.scancode != input::scancode::escape && key_event.scancode != input::scancode::backspace) - ctx.input_event_router->add_mapping(input::key_mapping(control, key_event.keyboard, key_event.scancode)); - } - else if (id == mouse_wheel_scrolled_event::event_type_id) - { - // Map mouse wheel scrolled event to control - const mouse_wheel_scrolled_event& wheel_event = static_cast(event); - input::mouse_wheel_axis axis; - - if (wheel_event.x < 0) - axis = input::mouse_wheel_axis::negative_x; - else if (wheel_event.x > 0) - axis = input::mouse_wheel_axis::positive_x; - else if (wheel_event.y < 0) - axis = input::mouse_wheel_axis::negative_y; - else if (wheel_event.y > 0) - axis = input::mouse_wheel_axis::positive_y; - else - return; - - ctx.input_event_router->add_mapping(input::mouse_wheel_mapping(control, wheel_event.mouse, axis)); - } - else if (id == mouse_button_pressed_event::event_type_id) - { - // Map mouse button pressed event to control - const mouse_button_pressed_event& button_event = static_cast(event); - ctx.input_event_router->add_mapping(input::mouse_button_mapping(control, button_event.mouse, button_event.button)); - } - else - { - return; - } - - // Update menu text - value_text->set_content(this->get_binding_string(control)); - game::menu::align_text(ctx); - game::menu::update_text_tweens(ctx); - - // Disable input listener - ctx.input_listener->set_enabled(false); - ctx.input_listener->set_callback(nullptr); - - // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + game::disable_menu_controls(ctx); + ctx.input_mapper.connect(ctx.input_manager->get_event_queue()); } ); - ctx.input_listener->set_enabled(true); - */ }; // Register menu item callbacks diff --git a/src/game/state/keyboard-config-menu.hpp b/src/game/state/keyboard-config-menu.hpp index 3c1f602..96ba89e 100644 --- a/src/game/state/keyboard-config-menu.hpp +++ b/src/game/state/keyboard-config-menu.hpp @@ -22,7 +22,10 @@ #include "game/state/base.hpp" #include "input/control.hpp" -#include +#include "input/control-map.hpp" +#include "event/subscription.hpp" +#include +#include namespace game { namespace state { @@ -34,8 +37,12 @@ public: virtual ~keyboard_config_menu(); private: - std::string get_binding_string(input::control* control); - void add_control_item(const std::string& control_name); + std::string get_mapping_string(const input::control_map& control_map, const input::control& control); + void add_control_item(input::control_map& control_map, input::control& control, std::uint32_t control_name_hash); + + std::shared_ptr key_mapped_subscription; + std::shared_ptr mouse_button_mapped_subscription; + std::shared_ptr mouse_scroll_mapped_subscription; }; } // namespace state diff --git a/src/game/state/language-menu.cpp b/src/game/state/language-menu.cpp index 0effe4a..12a5d54 100644 --- a/src/game/state/language-menu.cpp +++ b/src/game/state/language-menu.cpp @@ -181,7 +181,7 @@ language_menu::~language_menu() game::menu::remove_text_from_ui(ctx); game::menu::delete_text(ctx); - debug::log::trace("Exited language menu state..."); + debug::log::trace("Exited language menu state"); } void language_menu::update_text_content() diff --git a/src/game/state/main-menu.cpp b/src/game/state/main-menu.cpp index 7c613d4..2ead391 100644 --- a/src/game/state/main-menu.cpp +++ b/src/game/state/main-menu.cpp @@ -27,14 +27,16 @@ #include "game/component/model.hpp" #include "game/component/steering.hpp" #include "game/component/transform.hpp" +#include "game/controls.hpp" #include "game/ecoregion.hpp" #include "game/menu.hpp" +#include "game/state/collection-menu.hpp" #include "game/state/extras-menu.hpp" #include "game/state/nuptial-flight.hpp" #include "game/state/options-menu.hpp" #include "game/strings.hpp" #include "game/world.hpp" -#include "game/controls.hpp" +#include "math/glsl.hpp" #include "math/projection.hpp" #include "physics/light/exposure.hpp" #include "render/model.hpp" @@ -43,7 +45,6 @@ #include "render/passes/sky-pass.hpp" #include "resources/resource-manager.hpp" #include "utility/hash/fnv1a.hpp" -#include "math/glsl.hpp" #include using namespace hash::literals; @@ -126,7 +127,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in): ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Create change state function - auto change_state_nuptial_flight = [&ctx]() + auto change_state = [&ctx]() { // Queue change to nuptial state ctx.function_queue.push @@ -134,7 +135,8 @@ main_menu::main_menu(game::context& ctx, bool fade_in): [&ctx]() { ctx.state_machine.pop(); - ctx.state_machine.emplace(new game::state::nuptial_flight(ctx)); + //ctx.state_machine.emplace(new game::state::nuptial_flight(ctx)); + ctx.state_machine.emplace(new game::state::collection_menu(ctx)); } ); }; @@ -146,8 +148,9 @@ main_menu::main_menu(game::context& ctx, bool fade_in): game::menu::fade_out(ctx, nullptr); // Start fade out to white - ctx.fade_transition_color->set_value({1, 1, 1}); - ctx.fade_transition->transition(config::new_colony_fade_out_duration, false, ease::out_cubic, false, change_state_nuptial_flight); + //ctx.fade_transition_color->set_value({1, 1, 1}); + ctx.fade_transition_color->set_value({0, 0, 0}); + ctx.fade_transition->transition(config::new_colony_fade_out_duration, false, ease::out_cubic, false, change_state); }; auto select_options_callback = [this, &ctx]() { diff --git a/src/input/control-map.cpp b/src/input/control-map.cpp index bae1e30..63a9036 100644 --- a/src/input/control-map.cpp +++ b/src/input/control-map.cpp @@ -46,71 +46,37 @@ void control_map::disconnect() subscriptions.clear(); } -void control_map::add_mapping(control& control, const mapping& mapping) +void control_map::add_mapping(control& control, gamepad_axis_mapping mapping) { - switch (mapping.get_mapping_type()) - { - case mapping_type::gamepad_axis: - add_mapping(control, static_cast(mapping)); - break; - - case mapping_type::gamepad_button: - add_mapping(control, static_cast(mapping)); - break; - - case mapping_type::key: - add_mapping(control, static_cast(mapping)); - break; - - case mapping_type::mouse_button: - add_mapping(control, static_cast(mapping)); - break; - - case mapping_type::mouse_motion: - add_mapping(control, static_cast(mapping)); - break; - - case mapping_type::mouse_scroll: - add_mapping(control, static_cast(mapping)); - break; - - default: - //std::unreachable(); - break; - } -} - -void control_map::add_mapping(control& control, gamepad_axis_mapping&& mapping) -{ - gamepad_axis_mappings.emplace_back(&control, mapping); + gamepad_axis_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::add_mapping(control& control, gamepad_button_mapping&& mapping) +void control_map::add_mapping(control& control, gamepad_button_mapping mapping) { - gamepad_button_mappings.emplace_back(&control, mapping); + gamepad_button_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::add_mapping(control& control, key_mapping&& mapping) +void control_map::add_mapping(control& control, key_mapping mapping) { - key_mappings.emplace_back(&control, mapping); + key_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::add_mapping(control& control, mouse_button_mapping&& mapping) +void control_map::add_mapping(control& control, mouse_button_mapping mapping) { - mouse_button_mappings.emplace_back(&control, mapping); + mouse_button_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::add_mapping(control& control, mouse_motion_mapping&& mapping) +void control_map::add_mapping(control& control, mouse_motion_mapping mapping) { - mouse_motion_mappings.emplace_back(&control, mapping); + mouse_motion_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::add_mapping(control& control, mouse_scroll_mapping&& mapping) +void control_map::add_mapping(control& control, mouse_scroll_mapping mapping) { - mouse_scroll_mappings.emplace_back(&control, mapping); + mouse_scroll_mappings.emplace_back(&control, std::move(mapping)); } -void control_map::remove_mappings(control& control, mapping_type type) +void control_map::remove_mappings(const control& control, mapping_type type) { auto predicate = [&](const auto& tuple) -> bool { @@ -149,7 +115,7 @@ void control_map::remove_mappings(control& control, mapping_type type) } } -void control_map::remove_mappings(control& control) +void control_map::remove_mappings(const control& control) { auto predicate = [&](const auto& tuple) -> bool { @@ -222,7 +188,8 @@ void control_map::handle_key_pressed(const key_pressed_event& event) for (const auto& [control, mapping]: key_mappings) { if (mapping.scancode == event.scancode && - (!mapping.keyboard || mapping.keyboard == event.keyboard)) + (!mapping.keyboard || mapping.keyboard == event.keyboard) && + (!mapping.modifiers || (mapping.modifiers & event.modifiers))) { if (!event.repeat) { @@ -307,4 +274,94 @@ void control_map::handle_mouse_button_released(const mouse_button_released_event } } +std::vector control_map::get_gamepad_axis_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: gamepad_axis_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + +std::vector control_map::get_gamepad_button_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: gamepad_button_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + +std::vector control_map::get_key_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: key_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + +std::vector control_map::get_mouse_button_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: mouse_button_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + +std::vector control_map::get_mouse_motion_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: mouse_motion_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + +std::vector control_map::get_mouse_scroll_mappings(const control& control) const +{ + std::vector mappings; + + for (const auto& [mapped_control, mapping]: mouse_scroll_mappings) + { + if (mapped_control == &control) + { + mappings.emplace_back(mapping); + } + } + + return mappings; +} + } // namespace input diff --git a/src/input/control-map.hpp b/src/input/control-map.hpp index ab18e30..7722e25 100644 --- a/src/input/control-map.hpp +++ b/src/input/control-map.hpp @@ -59,13 +59,12 @@ public: * @param mapping Input mapping to add. */ /// @{ - void add_mapping(control& control, const mapping& mapping); - void add_mapping(control& control, gamepad_axis_mapping&& mapping); - void add_mapping(control& control, gamepad_button_mapping&& mapping); - void add_mapping(control& control, key_mapping&& mapping); - void add_mapping(control& control, mouse_button_mapping&& mapping); - void add_mapping(control& control, mouse_motion_mapping&& mapping); - void add_mapping(control& control, mouse_scroll_mapping&& mapping); + void add_mapping(control& control, gamepad_axis_mapping mapping); + void add_mapping(control& control, gamepad_button_mapping mapping); + void add_mapping(control& control, key_mapping mapping); + void add_mapping(control& control, mouse_button_mapping mapping); + void add_mapping(control& control, mouse_motion_mapping mapping); + void add_mapping(control& control, mouse_scroll_mapping mapping); /// @} /** @@ -74,20 +73,62 @@ public: * @param control Control from which input will be unmapped. * @param type Type of input mapping to remove. */ - void remove_mappings(control& control, mapping_type type); + void remove_mappings(const control& control, mapping_type type); /** * Unmaps all input from a control. * * @param control Control from which input will be unmapped. */ - void remove_mappings(control& control); + void remove_mappings(const control& control); /** * Unmaps all input from all controls in the control map. */ void remove_mappings(); + /** + * Returns all of the gamepad axis mappings associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_gamepad_axis_mappings(const control& control) const; + + /** + * Returns all of the gamepad button mappings associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_gamepad_button_mappings(const control& control) const; + + /** + * Returns all of the key mappings associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_key_mappings(const control& control) const; + + /** + * Returns all of the mouse button mappings associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_mouse_button_mappings(const control& control) const; + + /** + * Returns all of the mouse motion mappings associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_mouse_motion_mappings(const control& control) const; + + /** + * Returns all of the mouse scroll associated with a control. + * + * @param control Control with which associated mappings will be returned. + */ + std::vector get_mouse_scroll_mappings(const control& control) const; + private: void handle_gamepad_axis_moved(const gamepad_axis_moved_event& event); void handle_gamepad_button_pressed(const gamepad_button_pressed_event& event); diff --git a/src/input/gamepad.cpp b/src/input/gamepad.cpp index 00c3f26..714a81d 100644 --- a/src/input/gamepad.cpp +++ b/src/input/gamepad.cpp @@ -34,8 +34,8 @@ gamepad::gamepad(): for (int i = 0; i < 6; ++i) { axis_positions[i] = 0.0f; - axis_activation_min[i] = 0.0f; - axis_activation_max[i] = 1.0f; + axis_activation_min[i] = 0.15f; + axis_activation_max[i] = 0.98f; axis_response_curves[i] = gamepad_response_curve::linear; } } diff --git a/src/input/mapping.cpp b/src/input/mapping.cpp index 3bf5da6..019dff6 100644 --- a/src/input/mapping.cpp +++ b/src/input/mapping.cpp @@ -32,10 +32,11 @@ gamepad_button_mapping::gamepad_button_mapping(input::gamepad* gamepad, gamepad_ button(button) {} -key_mapping::key_mapping(input::keyboard* keyboard, input::scancode scancode, bool repeat): +key_mapping::key_mapping(input::keyboard* keyboard, input::scancode scancode, bool repeat, std::uint16_t modifiers): keyboard(keyboard), scancode(scancode), - repeat(repeat) + repeat(repeat), + modifiers(modifiers) {} mouse_button_mapping::mouse_button_mapping(input::mouse* mouse, mouse_button button): diff --git a/src/input/mapping.hpp b/src/input/mapping.hpp index e104401..0fb7fe0 100644 --- a/src/input/mapping.hpp +++ b/src/input/mapping.hpp @@ -136,9 +136,10 @@ public: * @param keyboard Pointer to the keyboard to map, or `nullptr` if input from any keyboard will be mapped. * @param scancode Scancode of the key to map. * @param repeat `false` if the mapping should ignore key repeats, `true` otherwise. + * @param modifiers Modifier keys bitmask. */ /// @{ - key_mapping(input::keyboard* keyboard, input::scancode scancode, bool repeat = false); + key_mapping(input::keyboard* keyboard, input::scancode scancode, bool repeat = false, std::uint16_t modifiers = 0); key_mapping() = default; /// @} @@ -159,6 +160,9 @@ public: /// `false` if the mapping ignores key repeats, `true` otherwise. bool repeat; + + /// Modifier keys bitbask. + std::uint16_t modifiers; }; /** diff --git a/src/input/scancode.hpp b/src/input/scancode.hpp index dfb4d7b..1df71e9 100644 --- a/src/input/scancode.hpp +++ b/src/input/scancode.hpp @@ -41,12 +41,12 @@ enum class scancode: std::uint16_t d = 0x07, e = 0x08, f = 0x09, - g = 0x0A, - h = 0x0B, - i = 0x0C, - j = 0x0D, - k = 0x0E, - l = 0x0F, + g = 0x0a, + h = 0x0b, + i = 0x0c, + j = 0x0d, + k = 0x0e, + l = 0x0f, m = 0x10, n = 0x11, o = 0x12, @@ -57,12 +57,12 @@ enum class scancode: std::uint16_t t = 0x17, u = 0x18, v = 0x19, - w = 0x1A, - x = 0x1B, - y = 0x1C, - z = 0x1D, - digit_1 = 0x1E, - digit_2 = 0x1F, + w = 0x1a, + x = 0x1b, + y = 0x1c, + z = 0x1d, + digit_1 = 0x1e, + digit_2 = 0x1f, digit_3 = 0x20, digit_4 = 0x21, digit_5 = 0x22, @@ -73,12 +73,12 @@ enum class scancode: std::uint16_t digit_0 = 0x27, enter = 0x28, escape = 0x29, - backspace = 0x2A, - tab = 0x2B, - space = 0x2C, - minus = 0x2D, - equal = 0x2E, - left_brace = 0x2F, + backspace = 0x2a, + tab = 0x2b, + space = 0x2c, + minus = 0x2d, + equal = 0x2e, + left_brace = 0x2f, right_brace = 0x30, backslash = 0x31, non_us_hash = 0x32, @@ -89,12 +89,12 @@ enum class scancode: std::uint16_t dot = 0x37, slash = 0x38, caps_lock = 0x39, - f1 = 0x3A, - f2 = 0x3B, - f3 = 0x3C, - f4 = 0x3D, - f5 = 0x3E, - f6 = 0x3F, + f1 = 0x3a, + f2 = 0x3b, + f3 = 0x3c, + f4 = 0x3d, + f5 = 0x3e, + f6 = 0x3f, f7 = 0x40, f8 = 0x41, f9 = 0x42, @@ -105,12 +105,12 @@ enum class scancode: std::uint16_t scroll_lock = 0x47, pause = 0x48, insert = 0x49, - home = 0x4A, - page_up = 0x4B, - del = 0x4C, - end = 0x4D, - page_down = 0x4E, - right = 0x4F, + home = 0x4a, + page_up = 0x4b, + del = 0x4c, + end = 0x4d, + page_down = 0x4e, + right = 0x4f, left = 0x50, down = 0x51, up = 0x52, @@ -121,12 +121,12 @@ enum class scancode: std::uint16_t kp_plus = 0x57, kp_enter = 0x58, kp_1 = 0x59, - kp_2 = 0x5A, - kp_3 = 0x5B, - kp_4 = 0x5C, - kp_5 = 0x5D, - kp_6 = 0x5E, - kp_7 = 0x5F, + kp_2 = 0x5a, + kp_3 = 0x5b, + kp_4 = 0x5c, + kp_5 = 0x5d, + kp_6 = 0x5e, + kp_7 = 0x5f, kp_8 = 0x60, kp_9 = 0x61, kp_0 = 0x62, @@ -137,12 +137,12 @@ enum class scancode: std::uint16_t kp_equal = 0x67, f13 = 0x68, f14 = 0x69, - f15 = 0x6A, - f16 = 0x6B, - f17 = 0x6C, - f18 = 0x6D, - f19 = 0x6E, - f20 = 0x6F, + f15 = 0x6a, + f16 = 0x6b, + f17 = 0x6c, + f18 = 0x6d, + f19 = 0x6e, + f20 = 0x6f, f21 = 0x70, f22 = 0x71, f23 = 0x72, @@ -153,12 +153,12 @@ enum class scancode: std::uint16_t select = 0x77, stop = 0x78, again = 0x79, - undo = 0x7A, - cut = 0x7B, - copy = 0x7C, - paste = 0x7D, - find = 0x7E, - mute = 0x7F, + undo = 0x7a, + cut = 0x7b, + copy = 0x7c, + paste = 0x7d, + find = 0x7e, + mute = 0x7f, volume_up = 0x80, volume_down = 0x81, locking_caps_lock = 0x82, @@ -169,12 +169,12 @@ enum class scancode: std::uint16_t international_1 = 0x87, international_2 = 0x88, international_3 = 0x89, - international_4 = 0x8A, - international_5 = 0x8B, - international_6 = 0x8C, - international_7 = 0x8D, - international_8 = 0x8E, - international_9 = 0x8F, + international_4 = 0x8a, + international_5 = 0x8b, + international_6 = 0x8c, + international_7 = 0x8d, + international_8 = 0x8e, + international_9 = 0x8f, lang_1 = 0x90, lang_2 = 0x91, lang_3 = 0x92, @@ -185,85 +185,85 @@ enum class scancode: std::uint16_t lang_8 = 0x97, lang_9 = 0x98, alt_erase = 0x99, - sys_req = 0x9A, - cancel = 0x9B, - clear = 0x9C, - prior = 0x9D, - return_2 = 0x9E, - separator = 0x9F, - _out = 0xA0, - oper = 0xA1, - clear_again = 0xA2, - cr_sel = 0xA3, - ex_sel = 0xA4, - // reserved = 0xA5, - // reserved = 0xA6, - // reserved = 0xA7, - // reserved = 0xA8, - // reserved = 0xA9, - // reserved = 0xAA, - // reserved = 0xAB, - // reserved = 0xAC, - // reserved = 0xAD, - // reserved = 0xAE, - // reserved = 0xAF, - kp_00 = 0xB0, - kp_000 = 0xB1, - thousands_separator = 0xB2, - decimal_separator = 0xB3, - currency_unit = 0xB4, - currency_sub_unit = 0xB5, - kp_left_paren = 0xB6, - kp_right_paren = 0xB7, - kp_left_brace = 0xB8, - kp_right_brace = 0xB9, - kp_tab = 0xBA, - kp_backspace = 0xBB, - kp_a = 0xBC, - kp_b = 0xBD, - kp_c = 0xBE, - kp_d = 0xBF, - kp_e = 0xC0, - kp_f = 0xC1, - kp_xor = 0xC2, - kp_power = 0xC3, - kp_percent = 0xC4, - kp_less = 0xC5, - kp_greater = 0xC6, - kp_ampersand = 0xC7, - kp_double_ampersand = 0xC8, - kp_vertical_bar = 0xC9, - kp_double_vertical_bar = 0xCA, - kp_colon = 0xCB, - kp_hash = 0xCC, - kp_space = 0xCD, - kp_at = 0xCE, - kp_exclam = 0xCF, - kp_mem_store = 0xD0, - kp_mem_recall = 0xD1, - kp_mem_clear = 0xD2, - kp_mem_add = 0xD3, - kp_mem_subtract = 0xD4, - kp_mem_multiply = 0xD5, - kp_mem_divide = 0xD6, - kp_plus_minus = 0xD7, - kp_clear = 0xD8, - kp_clear_entry = 0xD9, - kp_binary = 0xDA, - kp_octal = 0xDB, - kp_decimal = 0xDC, - kp_hexadecimal = 0xDD, - // reserved = 0xDE, - // reserved = 0xDF, - left_ctrl = 0xE0, - left_shift = 0xE1, - left_alt = 0xE2, - left_gui = 0xE3, - right_ctrl = 0xE4, - right_shift = 0xE5, - right_alt = 0xE6, - right_gui = 0xE7 - // reserved = 0xE8-0xFFFF + sys_req = 0x9a, + cancel = 0x9b, + clear = 0x9c, + prior = 0x9d, + return_2 = 0x9e, + separator = 0x9f, + _out = 0xa0, + oper = 0xa1, + clear_again = 0xa2, + cr_sel = 0xa3, + ex_sel = 0xa4, + // reserved = 0xa5, + // reserved = 0xa6, + // reserved = 0xa7, + // reserved = 0xa8, + // reserved = 0xa9, + // reserved = 0xaa, + // reserved = 0xab, + // reserved = 0xac, + // reserved = 0xad, + // reserved = 0xae, + // reserved = 0xaf, + kp_00 = 0xb0, + kp_000 = 0xb1, + thousands_separator = 0xb2, + decimal_separator = 0xb3, + currency_unit = 0xb4, + currency_sub_unit = 0xb5, + kp_left_paren = 0xb6, + kp_right_paren = 0xb7, + kp_left_brace = 0xb8, + kp_right_brace = 0xb9, + kp_tab = 0xba, + kp_backspace = 0xbb, + kp_a = 0xbc, + kp_b = 0xbd, + kp_c = 0xbe, + kp_d = 0xbf, + kp_e = 0xc0, + kp_f = 0xc1, + kp_xor = 0xc2, + kp_power = 0xc3, + kp_percent = 0xc4, + kp_less = 0xc5, + kp_greater = 0xc6, + kp_ampersand = 0xc7, + kp_double_ampersand = 0xc8, + kp_vertical_bar = 0xc9, + kp_double_vertical_bar = 0xca, + kp_colon = 0xcb, + kp_hash = 0xcc, + kp_space = 0xcd, + kp_at = 0xce, + kp_exclam = 0xcf, + kp_mem_store = 0xd0, + kp_mem_recall = 0xd1, + kp_mem_clear = 0xd2, + kp_mem_add = 0xd3, + kp_mem_subtract = 0xd4, + kp_mem_multiply = 0xd5, + kp_mem_divide = 0xd6, + kp_plus_minus = 0xd7, + kp_clear = 0xd8, + kp_clear_entry = 0xd9, + kp_binary = 0xda, + kp_octal = 0xdb, + kp_decimal = 0xdc, + kp_hexadecimal = 0xdd, + // reserved = 0xde, + // reserved = 0xdf, + left_ctrl = 0xe0, + left_shift = 0xe1, + left_alt = 0xe2, + left_gui = 0xe3, + right_ctrl = 0xe4, + right_shift = 0xe5, + right_alt = 0xe6, + right_gui = 0xe7 + // reserved = 0xe8-0xffff }; } // namespace input