From b7b012f90af84fe53d24b5f78313ff90a8e0bb5c Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Fri, 10 Feb 2023 03:59:16 +0800 Subject: [PATCH] Fix menu controls --- src/game/context.hpp | 11 +- src/game/controls.cpp | 313 +++++++++++++++++++++++- src/game/controls.hpp | 10 + src/game/menu.cpp | 235 ------------------ src/game/menu.hpp | 4 - src/game/state/boot.cpp | 61 +---- src/game/state/controls-menu.cpp | 17 +- src/game/state/extras-menu.cpp | 12 +- src/game/state/gamepad-config-menu.cpp | 15 +- src/game/state/graphics-menu.cpp | 16 +- src/game/state/keyboard-config-menu.cpp | 17 +- src/game/state/language-menu.cpp | 11 +- src/game/state/main-menu.cpp | 14 +- src/game/state/options-menu.cpp | 24 +- src/game/state/pause-menu.cpp | 13 +- src/game/state/sound-menu.cpp | 9 +- src/input/control-map.cpp | 21 +- src/input/control.cpp | 5 + src/input/control.hpp | 5 + 19 files changed, 433 insertions(+), 380 deletions(-) diff --git a/src/game/context.hpp b/src/game/context.hpp index c2fb85c..03bac24 100644 --- a/src/game/context.hpp +++ b/src/game/context.hpp @@ -40,6 +40,7 @@ #include "input/control-map.hpp" #include "input/control.hpp" #include "input/mapper.hpp" +#include "math/moving-average.hpp" #include "render/anti-aliasing-method.hpp" #include "render/material-property.hpp" #include "render/material.hpp" @@ -50,12 +51,10 @@ #include "utility/dict.hpp" #include "utility/fundamental-types.hpp" #include "utility/state-machine.hpp" -#include "math/moving-average.hpp" #include #include #include #include -#include #include #include #include @@ -175,7 +174,7 @@ struct context input::control_map window_controls; input::control fullscreen_control; input::control screenshot_control; - std::forward_list> control_subscriptions; + std::vector> window_control_subscriptions; input::control_map menu_controls; input::control menu_up_control; input::control menu_down_control; @@ -184,7 +183,8 @@ struct context input::control menu_select_control; input::control menu_back_control; input::control menu_modifier_control; - std::forward_list> menu_control_subscriptions; + std::vector> menu_control_subscriptions; + std::vector> menu_mouse_subscriptions; // Debugging math::moving_average average_frame_time; @@ -194,15 +194,12 @@ struct context hsm::state_machine state_machine; std::function resume_callback; - - // Queue for scheduling "next frame" function calls std::queue> function_queue; // Parallel processes std::unordered_map> processes; - bool mouse_look; /// Game loop diff --git a/src/game/controls.cpp b/src/game/controls.cpp index 1618f41..893544f 100644 --- a/src/game/controls.cpp +++ b/src/game/controls.cpp @@ -18,15 +18,320 @@ */ #include "game/controls.hpp" +#include "game/graphics.hpp" +#include "game/menu.hpp" #include "resources/resource-manager.hpp" #include "resources/json.hpp" -#include "game/component/transform.hpp" -#include "game/component/constraint/constraint.hpp" -#include "game/component/constraint-stack.hpp" -#include namespace game { +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.screenshot_control, input::key_mapping(nullptr, input::scancode::f12, false)); + + // Setup fullscreen control + ctx.window_control_subscriptions.emplace_back + ( + ctx.fullscreen_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + ctx.window->set_fullscreen(!ctx.window->is_fullscreen()); + } + ) + ); + + // Setup screenshot control + ctx.window_control_subscriptions.emplace_back + ( + ctx.screenshot_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + game::graphics::save_screenshot(ctx); + } + ) + ); +} + +void setup_menu_controls(game::context& ctx) +{ + // Map menu controls + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::up, true)); + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::w, true)); + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::i, true)); + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::left_stick_y, true)); + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::right_stick_y, true)); + ctx.menu_controls.add_mapping(ctx.menu_up_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::dpad_up)); + + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::down, true)); + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::s, true)); + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::k, true)); + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::left_stick_y, false)); + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::right_stick_y, false)); + ctx.menu_controls.add_mapping(ctx.menu_down_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::dpad_down)); + + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::left, true)); + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::a, true)); + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::j, true)); + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::left_stick_x, true)); + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::right_stick_x, true)); + ctx.menu_controls.add_mapping(ctx.menu_left_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::dpad_left)); + + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::right, true)); + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::d, true)); + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::l, true)); + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::left_stick_x, false)); + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::gamepad_axis_mapping(nullptr, input::gamepad_axis::right_stick_x, false)); + ctx.menu_controls.add_mapping(ctx.menu_right_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::dpad_right)); + + ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::enter, false)); + ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::space, false)); + ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::e, false)); + ctx.menu_controls.add_mapping(ctx.menu_select_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::a)); + + ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::escape, false)); + ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::backspace, false)); + ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::q, false)); + ctx.menu_controls.add_mapping(ctx.menu_back_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::b)); + ctx.menu_controls.add_mapping(ctx.menu_back_control, input::gamepad_button_mapping(nullptr, input::gamepad_button::back)); + + ctx.menu_controls.add_mapping(ctx.menu_modifier_control, input::key_mapping(nullptr, input::scancode::left_shift, false)); + ctx.menu_controls.add_mapping(ctx.menu_modifier_control, input::key_mapping(nullptr, input::scancode::right_shift, false)); + + // Setup menu controls + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_up_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + --(*ctx.menu_item_index); + if (*ctx.menu_item_index < 0) + *ctx.menu_item_index = static_cast(ctx.menu_item_texts.size()) - 1; + + game::menu::update_text_color(ctx); + } + ) + ); + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_down_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + ++(*ctx.menu_item_index); + if (*ctx.menu_item_index >= ctx.menu_item_texts.size()) + *ctx.menu_item_index = 0; + + game::menu::update_text_color(ctx); + } + ) + ); + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_left_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + auto callback = ctx.menu_left_callbacks[*ctx.menu_item_index]; + if (callback != nullptr) + callback(); + } + ) + ); + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_right_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + auto callback = ctx.menu_right_callbacks[*ctx.menu_item_index]; + if (callback != nullptr) + callback(); + } + ) + ); + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_select_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + const auto& callback = ctx.menu_select_callbacks[*ctx.menu_item_index]; + if (callback != nullptr) + callback(); + } + ) + ); + ctx.menu_control_subscriptions.emplace_back + ( + ctx.menu_back_control.get_activated_channel().subscribe + ( + [&ctx](const auto& event) + { + if (ctx.menu_back_callback != nullptr) + ctx.menu_back_callback(); + } + ) + ); + + // Set activation threshold for menu navigation controls to mitigate drifting gamepad axes + auto menu_control_threshold = [](float x) -> bool + { + return x > 0.1f; + }; + ctx.menu_up_control.set_threshold_function(menu_control_threshold); + ctx.menu_down_control.set_threshold_function(menu_control_threshold); + ctx.menu_left_control.set_threshold_function(menu_control_threshold); + ctx.menu_right_control.set_threshold_function(menu_control_threshold); +} + +void enable_window_controls(game::context& ctx) +{ + ctx.window_controls.connect(ctx.input_manager->get_event_queue()); +} + +void enable_menu_controls(game::context& ctx) +{ + ctx.menu_controls.connect(ctx.input_manager->get_event_queue()); + + // Enable menu mouse tracking + ctx.menu_mouse_subscriptions.clear(); + ctx.menu_mouse_subscriptions.emplace_back + ( + ctx.input_manager->get_event_queue().subscribe + ( + [&ctx](const auto& event) + { + 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]; + + const auto& name_bounds = static_cast&>(name->get_world_bounds()); + float min_x = name_bounds.min_point.x(); + float min_y = name_bounds.min_point.y(); + float max_x = name_bounds.max_point.x(); + float max_y = name_bounds.max_point.y(); + if (value) + { + const auto& value_bounds = static_cast&>(value->get_world_bounds()); + min_x = std::min(min_x, value_bounds.min_point.x()); + min_y = std::min(min_y, value_bounds.min_point.y()); + max_x = std::max(max_x, value_bounds.max_point.x()); + max_y = std::max(max_y, value_bounds.max_point.y()); + } + + min_x -= padding; + min_y -= padding; + max_x += padding; + max_y += padding; + + const auto& viewport = ctx.window->get_viewport_size(); + const float x = static_cast(event.position.x() - viewport[0] / 2); + const float y = static_cast((viewport[1] - event.position.y() + 1) - viewport[1] / 2); + + if (x >= min_x && x <= max_x) + { + if (y >= min_y && y <= max_y) + { + *ctx.menu_item_index = i; + game::menu::update_text_color(ctx); + break; + } + } + } + } + ) + ); + ctx.menu_mouse_subscriptions.emplace_back + ( + ctx.input_manager->get_event_queue().subscribe + ( + [&ctx](const auto& event) + { + 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]; + + const auto& name_bounds = static_cast&>(name->get_world_bounds()); + float min_x = name_bounds.min_point.x(); + float min_y = name_bounds.min_point.y(); + float max_x = name_bounds.max_point.x(); + float max_y = name_bounds.max_point.y(); + if (value) + { + const auto& value_bounds = static_cast&>(value->get_world_bounds()); + min_x = std::min(min_x, value_bounds.min_point.x()); + min_y = std::min(min_y, value_bounds.min_point.y()); + max_x = std::max(max_x, value_bounds.max_point.x()); + max_y = std::max(max_y, value_bounds.max_point.y()); + } + + min_x -= padding; + min_y -= padding; + max_x += padding; + max_y += padding; + + const auto& viewport = ctx.window->get_viewport_size(); + const float x = static_cast(event.position.x() - viewport[0] / 2); + const float y = static_cast((viewport[1] - event.position.y() + 1) - viewport[1] / 2); + + if (x >= min_x && x <= max_x) + { + if (y >= min_y && y <= max_y) + { + *ctx.menu_item_index = i; + game::menu::update_text_color(ctx); + + if (event.button == input::mouse_button::left) + { + const auto& callback = ctx.menu_select_callbacks[i]; + if (callback) + callback(); + } + else if (event.button == input::mouse_button::right) + { + const auto& callback = ctx.menu_left_callbacks[i]; + if (callback) + callback(); + } + + return; + } + } + } + } + ) + ); +} + +void disable_window_controls(game::context& ctx) +{ + ctx.window_controls.disconnect(); +} + +void disable_menu_controls(game::context& ctx) +{ + // Reset menu control states + ctx.menu_up_control.reset(); + ctx.menu_down_control.reset(); + ctx.menu_left_control.reset(); + ctx.menu_right_control.reset(); + ctx.menu_select_control.reset(); + ctx.menu_back_control.reset(); + ctx.menu_modifier_control.reset(); + + ctx.menu_controls.disconnect(); + ctx.menu_mouse_subscriptions.clear(); +} + std::filesystem::path gamepad_calibration_path(const game::context& ctx, const input::gamepad& gamepad) { return std::filesystem::path("gamepad-" + gamepad.get_uuid().string() + ".json"); diff --git a/src/game/controls.hpp b/src/game/controls.hpp index 15b70ca..b6a7a1a 100644 --- a/src/game/controls.hpp +++ b/src/game/controls.hpp @@ -27,6 +27,16 @@ namespace game { +void setup_window_controls(game::context& ctx); +void setup_menu_controls(game::context& ctx); + +void enable_window_controls(game::context& ctx); +void enable_menu_controls(game::context& ctx); + +void disable_window_controls(game::context& ctx); +void disable_menu_controls(game::context& ctx); + + /** * Applies a control profile to the game context. * diff --git a/src/game/menu.cpp b/src/game/menu.cpp index a8c436f..a81bc33 100644 --- a/src/game/menu.cpp +++ b/src/game/menu.cpp @@ -293,240 +293,5 @@ void fade_out_bg(game::context& ctx) ctx.menu_bg_fade_out_animation->play(); } -void setup_controls(game::context& ctx) -{ - // Map menu controls - ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::up, true)); - ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::w, true)); - ctx.menu_controls.add_mapping(ctx.menu_up_control, input::key_mapping(nullptr, input::scancode::i, true)); - ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::down, true)); - ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::s, true)); - ctx.menu_controls.add_mapping(ctx.menu_down_control, input::key_mapping(nullptr, input::scancode::k, true)); - ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::left, true)); - ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::a, true)); - ctx.menu_controls.add_mapping(ctx.menu_left_control, input::key_mapping(nullptr, input::scancode::j, true)); - ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::right, true)); - ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::d, true)); - ctx.menu_controls.add_mapping(ctx.menu_right_control, input::key_mapping(nullptr, input::scancode::l, true)); - ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::enter, false)); - ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::space, false)); - ctx.menu_controls.add_mapping(ctx.menu_select_control, input::key_mapping(nullptr, input::scancode::e, false)); - ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::escape, false)); - ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::backspace, false)); - ctx.menu_controls.add_mapping(ctx.menu_back_control, input::key_mapping(nullptr, input::scancode::q, false)); - ctx.menu_controls.add_mapping(ctx.menu_modifier_control, input::key_mapping(nullptr, input::scancode::left_shift, false)); - ctx.menu_controls.add_mapping(ctx.menu_modifier_control, input::key_mapping(nullptr, input::scancode::right_shift, false)); - - // Setup menu control callbacks - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_up_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - --(*ctx.menu_item_index); - if (*ctx.menu_item_index < 0) - *ctx.menu_item_index = static_cast(ctx.menu_item_texts.size()) - 1; - - update_text_color(ctx); - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_down_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - ++(*ctx.menu_item_index); - if (*ctx.menu_item_index >= ctx.menu_item_texts.size()) - *ctx.menu_item_index = 0; - - update_text_color(ctx); - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_left_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - auto callback = ctx.menu_left_callbacks[*ctx.menu_item_index]; - if (callback != nullptr) - callback(); - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_right_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - auto callback = ctx.menu_right_callbacks[*ctx.menu_item_index]; - if (callback != nullptr) - callback(); - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_select_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - auto callback = ctx.menu_select_callbacks[*ctx.menu_item_index]; - if (callback != nullptr) - callback(); - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.menu_back_control.get_activated_channel().subscribe - ( - [&ctx](const auto& event) - { - if (ctx.menu_back_callback != nullptr) - ctx.menu_back_callback(); - } - ) - ); - - // Setup mouse event callbacks - ctx.menu_control_subscriptions.emplace_front - ( - ctx.input_manager->get_event_queue().subscribe - ( - [&ctx](const auto& event) - { - 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]; - - const auto& name_bounds = static_cast&>(name->get_world_bounds()); - float min_x = name_bounds.min_point.x(); - float min_y = name_bounds.min_point.y(); - float max_x = name_bounds.max_point.x(); - float max_y = name_bounds.max_point.y(); - if (value) - { - const auto& value_bounds = static_cast&>(value->get_world_bounds()); - min_x = std::min(min_x, value_bounds.min_point.x()); - min_y = std::min(min_y, value_bounds.min_point.y()); - max_x = std::max(max_x, value_bounds.max_point.x()); - max_y = std::max(max_y, value_bounds.max_point.y()); - } - - min_x -= padding; - min_y -= padding; - max_x += padding; - max_y += padding; - - const auto& viewport = ctx.window->get_viewport_size(); - const float x = static_cast(event.position.x() - viewport[0] / 2); - const float y = static_cast((viewport[1] - event.position.y() + 1) - viewport[1] / 2); - - if (x >= min_x && x <= max_x) - { - if (y >= min_y && y <= max_y) - { - *ctx.menu_item_index = i; - update_text_color(ctx); - break; - } - } - } - } - ) - ); - ctx.menu_control_subscriptions.emplace_front - ( - ctx.input_manager->get_event_queue().subscribe - ( - [&ctx](const auto& event) - { - 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]; - - const auto& name_bounds = static_cast&>(name->get_world_bounds()); - float min_x = name_bounds.min_point.x(); - float min_y = name_bounds.min_point.y(); - float max_x = name_bounds.max_point.x(); - float max_y = name_bounds.max_point.y(); - if (value) - { - const auto& value_bounds = static_cast&>(value->get_world_bounds()); - min_x = std::min(min_x, value_bounds.min_point.x()); - min_y = std::min(min_y, value_bounds.min_point.y()); - max_x = std::max(max_x, value_bounds.max_point.x()); - max_y = std::max(max_y, value_bounds.max_point.y()); - } - - min_x -= padding; - min_y -= padding; - max_x += padding; - max_y += padding; - - const auto& viewport = ctx.window->get_viewport_size(); - const float x = static_cast(event.position.x() - viewport[0] / 2); - const float y = static_cast((viewport[1] - event.position.y() + 1) - viewport[1] / 2); - - if (x >= min_x && x <= max_x) - { - if (y >= min_y && y <= max_y) - { - *ctx.menu_item_index = i; - update_text_color(ctx); - - //if (event.button == input::mouse_button::left) - { - auto callback = ctx.menu_select_callbacks[i]; - if (callback) - callback(); - } - // else if (event.button == input::mouse_button::right) - // { - // auto callback = ctx.menu_left_callbacks[i]; - // if (callback) - // callback(); - // } - - return; - } - } - } - } - ) - ); -} - -void clear_controls(game::context& ctx) -{ - // Unsubscribe menu control event callbacks - ctx.menu_control_subscriptions.clear(); - - // Clear menu control mappings - ctx.menu_controls.remove_mappings(); -} - -void enable_controls(game::context& ctx) -{ - // Enable menu controls - ctx.menu_controls.connect(ctx.input_manager->get_event_queue()); -} - -void disable_controls(game::context& ctx) -{ - // Disable menu controls - ctx.menu_controls.disconnect(); -} - } // namespace menu } // namespace game diff --git a/src/game/menu.hpp b/src/game/menu.hpp index 714ad73..3c83e68 100644 --- a/src/game/menu.hpp +++ b/src/game/menu.hpp @@ -26,10 +26,6 @@ namespace game { namespace menu { void init_menu_item_index(game::context& ctx, const std::string& menu_name); -void setup_controls(game::context& ctx); -void clear_controls(game::context& ctx); -void enable_controls(game::context& ctx); -void disable_controls(game::context& ctx); void setup_animations(game::context& ctx); void clear_callbacks(game::context& ctx); diff --git a/src/game/state/boot.cpp b/src/game/state/boot.cpp index 5e224a1..f7a2618 100644 --- a/src/game/state/boot.cpp +++ b/src/game/state/boot.cpp @@ -1064,6 +1064,12 @@ void boot::setup_controls() // ctx.resource_manager->unload("gamecontrollerdb.txt"); // } + + setup_window_controls(ctx); + setup_menu_controls(ctx); + + enable_window_controls(ctx); + // Load controls debug::log::trace("Loading controls..."); try @@ -1105,57 +1111,7 @@ void boot::setup_controls() // apply_gamepad_calibration(*gamepad, *calibration); // } // } - - // Setup fullscreen control - ctx.control_subscriptions.emplace_front - ( - ctx.fullscreen_control.get_activated_channel().subscribe - ( - [&ctx = this->ctx](const auto& event) - { - bool fullscreen = !ctx.window->is_fullscreen(); - - // Toggle fullscreen - ctx.window->set_fullscreen(fullscreen); - - // Update fullscreen setting - (*ctx.settings)["fullscreen"_fnv1a32] = fullscreen; - - if (!fullscreen) - { - // Restore window size and position - //ctx.app->resize_window(resolution.x(), resolution.y()); - } - } - ) - ); - - // Setup screenshot control - ctx.control_subscriptions.emplace_front - ( - ctx.screenshot_control.get_activated_channel().subscribe - ( - [&ctx = this->ctx](const auto& event) - { - game::graphics::save_screenshot(ctx); - } - ) - ); - - // Map and enable window controls - ctx.window_controls.add_mapping(ctx.fullscreen_control, input::key_mapping(nullptr, input::scancode::f11, false)); - ctx.window_controls.add_mapping(ctx.screenshot_control, input::key_mapping(nullptr, input::scancode::f12, false)); - ctx.window_controls.connect(ctx.input_manager->get_event_queue()); - - // Set activation threshold for menu navigation controls to mitigate drifting gamepad axes - auto menu_control_threshold = [](float x) -> bool - { - return x > 0.1f; - }; - ctx.menu_up_control.set_threshold_function(menu_control_threshold); - ctx.menu_down_control.set_threshold_function(menu_control_threshold); - ctx.menu_left_control.set_threshold_function(menu_control_threshold); - ctx.menu_right_control.set_threshold_function(menu_control_threshold); + debug::log::trace("Loaded controls"); } @@ -1164,8 +1120,7 @@ void boot::setup_controls() debug::log::error("Failed to load controls"); } - // Setup menu controls - game::menu::setup_controls(ctx); + } void boot::setup_ui() diff --git a/src/game/state/controls-menu.cpp b/src/game/state/controls-menu.cpp index 91c852a..04e3737 100644 --- a/src/game/state/controls-menu.cpp +++ b/src/game/state/controls-menu.cpp @@ -21,6 +21,7 @@ #include "game/state/keyboard-config-menu.hpp" #include "game/state/gamepad-config-menu.hpp" #include "game/state/options-menu.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "game/menu.hpp" @@ -65,8 +66,8 @@ controls_menu::controls_menu(game::context& ctx): // Construct menu item callbacks auto select_keyboard_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -87,8 +88,8 @@ controls_menu::controls_menu(game::context& ctx): }; auto select_gamepad_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -109,8 +110,8 @@ controls_menu::controls_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -149,7 +150,7 @@ controls_menu::controls_menu(game::context& ctx): ctx.menu_back_callback = select_back_callback; // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -162,7 +163,7 @@ controls_menu::~controls_menu() debug::log::trace("Exiting options menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/extras-menu.cpp b/src/game/state/extras-menu.cpp index 70aae98..18d8727 100644 --- a/src/game/state/extras-menu.cpp +++ b/src/game/state/extras-menu.cpp @@ -20,6 +20,7 @@ #include "game/state/extras-menu.hpp" #include "game/state/main-menu.hpp" #include "game/state/credits.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "game/fonts.hpp" @@ -62,8 +63,8 @@ extras_menu::extras_menu(game::context& ctx): // Construct menu item callbacks auto select_credits_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -84,8 +85,8 @@ extras_menu::extras_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -124,7 +125,7 @@ extras_menu::extras_menu(game::context& ctx): game::menu::fade_in(ctx, nullptr); // Queue enable menu controls - ctx.function_queue.push(std::bind(game::menu::enable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); debug::log::trace("Entered extras menu state"); } @@ -134,6 +135,7 @@ extras_menu::~extras_menu() debug::log::trace("Exiting extras menu state..."); // Destruct menu + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/gamepad-config-menu.cpp b/src/game/state/gamepad-config-menu.cpp index ee5ad3c..ffad869 100644 --- a/src/game/state/gamepad-config-menu.cpp +++ b/src/game/state/gamepad-config-menu.cpp @@ -19,6 +19,7 @@ #include "game/state/gamepad-config-menu.hpp" #include "game/state/controls-menu.hpp" +#include "game/controls.hpp" #include "game/context.hpp" #include "scene/text.hpp" #include "debug/log.hpp" @@ -72,8 +73,8 @@ gamepad_config_menu::gamepad_config_menu(game::context& ctx): // Construct menu item callbacks auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -106,7 +107,7 @@ gamepad_config_menu::gamepad_config_menu(game::context& ctx): ctx.menu_back_callback = select_back_callback; // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -119,7 +120,7 @@ gamepad_config_menu::~gamepad_config_menu() debug::log::trace("Exiting gamepad config menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); @@ -302,14 +303,14 @@ void gamepad_config_menu::add_control_item(const std::string& control_name) auto select_callback = [this, &ctx = this->ctx, value_text]() { + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); + // Clear binding string from value text value_text->set_content(get_string(ctx, "ellipsis"_fnv1a32)); game::menu::align_text(ctx); game::menu::update_text_tweens(ctx); - // Disable controls - game::menu::clear_controls(ctx); - /* // Remove gamepad event mappings from control ctx.input_event_router->remove_mappings(control, input::mapping_type::gamepad_axis); diff --git a/src/game/state/graphics-menu.cpp b/src/game/state/graphics-menu.cpp index 90be37e..3d645be 100644 --- a/src/game/state/graphics-menu.cpp +++ b/src/game/state/graphics-menu.cpp @@ -19,6 +19,7 @@ #include "game/state/graphics-menu.hpp" #include "game/state/options-menu.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "game/fonts.hpp" @@ -91,7 +92,6 @@ graphics_menu::graphics_menu(game::context& ctx): ctx.window->set_fullscreen(fullscreen); - this->update_value_text_content(); game::menu::align_text(ctx); game::menu::update_text_tweens(ctx); @@ -296,8 +296,8 @@ graphics_menu::graphics_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -347,8 +347,8 @@ graphics_menu::graphics_menu(game::context& ctx): // Set menu back callback ctx.menu_back_callback = select_back_callback; - // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + // Enable menu controls next frame + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -361,7 +361,7 @@ graphics_menu::~graphics_menu() debug::log::trace("Exiting graphics menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); @@ -402,8 +402,8 @@ void graphics_menu::update_value_text_content() std::get<1>(ctx.menu_item_texts[1])->set_content(std::to_string(static_cast(std::round(render_scale * 100.0f))) + "%"); std::get<1>(ctx.menu_item_texts[2])->set_content((v_sync) ? string_on : string_off); std::get<1>(ctx.menu_item_texts[3])->set_content(string_aa_methods[aa_method_index]); - std::get<1>(ctx.menu_item_texts[5])->set_content(std::to_string(static_cast(std::round(font_scale * 100.0f))) + "%"); - std::get<1>(ctx.menu_item_texts[6])->set_content((dyslexia_font) ? string_on : string_off); + std::get<1>(ctx.menu_item_texts[4])->set_content(std::to_string(static_cast(std::round(font_scale * 100.0f))) + "%"); + std::get<1>(ctx.menu_item_texts[5])->set_content((dyslexia_font) ? string_on : string_off); } } // namespace state diff --git a/src/game/state/keyboard-config-menu.cpp b/src/game/state/keyboard-config-menu.cpp index 0e2fb9f..56ef44f 100644 --- a/src/game/state/keyboard-config-menu.cpp +++ b/src/game/state/keyboard-config-menu.cpp @@ -19,6 +19,7 @@ #include "game/state/keyboard-config-menu.hpp" #include "game/state/controls-menu.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "resources/resource-manager.hpp" @@ -71,8 +72,8 @@ keyboard_config_menu::keyboard_config_menu(game::context& ctx): // Construct menu item callbacks auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -104,8 +105,8 @@ keyboard_config_menu::keyboard_config_menu(game::context& ctx): // Set menu back callback ctx.menu_back_callback = select_back_callback; - // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + // Enable menu controls next frame + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -118,7 +119,7 @@ keyboard_config_menu::~keyboard_config_menu() debug::log::trace("Exiting keyboard config menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); @@ -244,14 +245,14 @@ void keyboard_config_menu::add_control_item(const std::string& control_name) auto select_callback = [this, &ctx = this->ctx, value_text]() { + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); + // Clear binding string from value text value_text->set_content(get_string(ctx, "ellipsis"_fnv1a32)); game::menu::align_text(ctx); game::menu::update_text_tweens(ctx); - // Disable controls - game::menu::clear_controls(ctx); - /* // Remove keyboard and mouse event mappings from control ctx.input_event_router->remove_mappings(control, input::mapping_type::key); diff --git a/src/game/state/language-menu.cpp b/src/game/state/language-menu.cpp index e55c8ba..0effe4a 100644 --- a/src/game/state/language-menu.cpp +++ b/src/game/state/language-menu.cpp @@ -19,6 +19,7 @@ #include "game/state/language-menu.hpp" #include "game/state/options-menu.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "game/fonts.hpp" @@ -124,8 +125,8 @@ language_menu::language_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -160,8 +161,8 @@ language_menu::language_menu(game::context& ctx): // Set menu back callback ctx.menu_back_callback = select_back_callback; - // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + // Enable menu controls next frame + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -174,7 +175,7 @@ language_menu::~language_menu() debug::log::trace("Exiting language menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/main-menu.cpp b/src/game/state/main-menu.cpp index 91a9db7..defd3e2 100644 --- a/src/game/state/main-menu.cpp +++ b/src/game/state/main-menu.cpp @@ -34,6 +34,7 @@ #include "game/state/options-menu.hpp" #include "game/strings.hpp" #include "game/world.hpp" +#include "game/controls.hpp" #include "math/projection.hpp" #include "physics/light/exposure.hpp" #include "render/model.hpp" @@ -117,7 +118,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in): auto select_start_callback = [this, &ctx]() { // Disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Create change state function auto change_state_nuptial_flight = [&ctx]() @@ -146,7 +147,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in): auto select_options_callback = [this, &ctx]() { // Disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Fade out title this->fade_out_title(); @@ -172,7 +173,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in): auto select_extras_callback = [this, &ctx]() { // Disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Fade out title this->fade_out_title(); @@ -198,7 +199,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in): auto select_quit_callback = [this, &ctx]() { // Disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Fade out title this->fade_out_title(); @@ -279,8 +280,8 @@ main_menu::main_menu(game::context& ctx, bool fade_in): //if (!ctx.menu_bg_billboard->is_active()) // game::menu::fade_in_bg(ctx); - // Queue enable menu controls - ctx.function_queue.push(std::bind(game::menu::enable_controls, std::ref(ctx))); + // Enable menu controls + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); debug::log::trace("Entered main menu state"); } @@ -290,6 +291,7 @@ main_menu::~main_menu() debug::log::trace("Exiting main menu state..."); // Destruct menu + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/options-menu.cpp b/src/game/state/options-menu.cpp index 501ae0b..0293087 100644 --- a/src/game/state/options-menu.cpp +++ b/src/game/state/options-menu.cpp @@ -25,6 +25,7 @@ #include "game/state/language-menu.hpp" #include "game/state/pause-menu.hpp" #include "game/menu.hpp" +#include "game/controls.hpp" #include "animation/ease.hpp" #include "animation/animation.hpp" #include "animation/animator.hpp" @@ -77,8 +78,8 @@ options_menu::options_menu(game::context& ctx): // Construct menu item callbacks auto select_controls_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Return to main menu game::menu::fade_out @@ -100,8 +101,8 @@ options_menu::options_menu(game::context& ctx): }; auto select_graphics_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Return to main menu game::menu::fade_out @@ -123,8 +124,8 @@ options_menu::options_menu(game::context& ctx): }; auto select_sound_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Return to main menu game::menu::fade_out @@ -146,8 +147,8 @@ options_menu::options_menu(game::context& ctx): }; auto select_language_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Return to main menu game::menu::fade_out @@ -169,8 +170,8 @@ options_menu::options_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Queue disable menu controls - ctx.function_queue.push(std::bind(game::menu::disable_controls, std::ref(ctx))); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Save config //game::save::config(ctx); @@ -216,7 +217,7 @@ options_menu::options_menu(game::context& ctx): game::menu::fade_in(ctx, nullptr); // Queue enable menu controls - ctx.function_queue.push(std::bind(game::menu::enable_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); debug::log::trace("Entered options menu state"); } @@ -226,6 +227,7 @@ options_menu::~options_menu() debug::log::trace("Exiting options menu state..."); // Destruct menu + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/pause-menu.cpp b/src/game/state/pause-menu.cpp index 7e628d5..94e97c9 100644 --- a/src/game/state/pause-menu.cpp +++ b/src/game/state/pause-menu.cpp @@ -22,6 +22,7 @@ #include "game/state/options-menu.hpp" #include "game/state/nuptial-flight.hpp" #include "game/menu.hpp" +#include "game/controls.hpp" #include "animation/ease.hpp" #include "animation/animation.hpp" #include "animation/animator.hpp" @@ -77,7 +78,7 @@ pause_menu::pause_menu(game::context& ctx): //ctx.controls["pause"]->set_activated_callback(nullptr); // Disable menu controls - game::menu::clear_controls(ctx); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); auto resume_paused_state = [&ctx]() { @@ -101,7 +102,7 @@ pause_menu::pause_menu(game::context& ctx): //ctx.controls["pause"]->set_activated_callback(nullptr); // Disable menu controls - game::menu::clear_controls(ctx); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Fade out pause menu then open options menu game::menu::fade_out @@ -127,7 +128,7 @@ pause_menu::pause_menu(game::context& ctx): //ctx.controls["pause"]->set_activated_callback(nullptr); // Disable menu controls - game::menu::clear_controls(ctx); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Clear resume callback ctx.resume_callback = nullptr; @@ -160,7 +161,7 @@ pause_menu::pause_menu(game::context& ctx): //ctx.controls["pause"]->set_activated_callback(nullptr); // Disable menu controls - game::menu::clear_controls(ctx); + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); // Clear paused state //ctx.paused_state.reset(); @@ -197,7 +198,7 @@ pause_menu::pause_menu(game::context& ctx): //ctx.controls["pause"]->set_activated_callback(select_resume_callback); // Enable menu controls - game::menu::setup_controls(ctx); + game::enable_menu_controls(ctx); } ); @@ -217,7 +218,7 @@ pause_menu::~pause_menu() debug::log::trace("Exiting pause menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/game/state/sound-menu.cpp b/src/game/state/sound-menu.cpp index 27fdf85..fa6b555 100644 --- a/src/game/state/sound-menu.cpp +++ b/src/game/state/sound-menu.cpp @@ -19,6 +19,7 @@ #include "game/state/sound-menu.hpp" #include "game/state/options-menu.hpp" +#include "game/controls.hpp" #include "scene/text.hpp" #include "debug/log.hpp" #include "game/menu.hpp" @@ -166,8 +167,8 @@ sound_menu::sound_menu(game::context& ctx): }; auto select_back_callback = [&ctx]() { - // Disable controls - game::menu::clear_controls(ctx); + // Disable menu controls + ctx.function_queue.push(std::bind(game::disable_menu_controls, std::ref(ctx))); game::menu::fade_out ( @@ -218,7 +219,7 @@ sound_menu::sound_menu(game::context& ctx): ctx.menu_back_callback = select_back_callback; // Queue menu control setup - ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx))); + ctx.function_queue.push(std::bind(game::enable_menu_controls, std::ref(ctx))); // Fade in menu game::menu::fade_in(ctx, nullptr); @@ -231,7 +232,7 @@ sound_menu::~sound_menu() debug::log::trace("Exiting sound menu state..."); // Destruct menu - game::menu::clear_controls(ctx); + game::disable_menu_controls(ctx); game::menu::clear_callbacks(ctx); game::menu::delete_animations(ctx); game::menu::remove_text_from_ui(ctx); diff --git a/src/input/control-map.cpp b/src/input/control-map.cpp index 879dfd7..bae1e30 100644 --- a/src/input/control-map.cpp +++ b/src/input/control-map.cpp @@ -27,15 +27,18 @@ namespace input { void control_map::connect(::event::queue& queue) { - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_axis_moved, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_button_pressed, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_button_released, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_key_pressed, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_key_released, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_button_pressed, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_button_released, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_moved, this))); - subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_scrolled, this))); + if (subscriptions.empty()) + { + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_axis_moved, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_button_pressed, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_gamepad_button_released, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_key_pressed, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_key_released, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_button_pressed, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_button_released, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_moved, this))); + subscriptions.emplace_back(queue.subscribe(std::bind_front(&control_map::handle_mouse_scrolled, this))); + } } void control_map::disconnect() diff --git a/src/input/control.cpp b/src/input/control.cpp index cf48b9d..ff0f164 100644 --- a/src/input/control.cpp +++ b/src/input/control.cpp @@ -67,4 +67,9 @@ void control::evaluate(float value) } } +void control::reset() +{ + active = false; +} + } // namespace input diff --git a/src/input/control.hpp b/src/input/control.hpp index fe50138..4751455 100644 --- a/src/input/control.hpp +++ b/src/input/control.hpp @@ -56,6 +56,11 @@ public: */ void evaluate(float value); + /** + * Resets the activation state of the control without publishing any events. + */ + void reset(); + /// Returns the threshold function. [[nodiscard]] inline const threshold_function_type& get_threshold_function() const noexcept {