From 3906262fd42a4c122d17731760194750c59b2b7f Mon Sep 17 00:00:00 2001 From: ZedB0T <89345505+Zedb0T@users.noreply.github.com> Date: Sat, 26 Apr 2025 17:17:27 -0400 Subject: [PATCH] Toggle Cpp openGL with F12 / Alt + Enter / Anything else (#3901) This is a successor to #3230 --------- Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com> --- game/graphics/pipelines/opengl.cpp | 11 +++++++ game/settings/settings.cpp | 6 ++-- game/settings/settings.h | 19 ++++++++++- game/system/hid/devices/game_controller.cpp | 8 ++++- game/system/hid/devices/keyboard.cpp | 8 ++++- game/system/hid/devices/mouse.cpp | 8 ++++- game/system/hid/display_manager.cpp | 35 +++++++++++++++++++++ game/system/hid/display_manager.h | 4 ++- game/system/hid/input_bindings.h | 20 ++++++++++-- iso_data/jak2/.gitignore | 2 +- 10 files changed, 110 insertions(+), 11 deletions(-) diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index 2411066b25..76f2cace19 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -349,6 +349,17 @@ GLDisplay::GLDisplay(SDL_Window* window, SDL_GLContext gl_context, bool is_main) m_input_manager->register_command( CommandBinding::Source::KEYBOARD, CommandBinding(SDLK_F2, [&]() { m_take_screenshot_next_frame = true; })); + + const auto& bind = Gfx::g_debug_settings.toggle_fullscreen_key; + + m_input_manager->register_command( + CommandBinding::Source::KEYBOARD, + CommandBinding(bind.key, bind.modifiers, [&](const SDL_Event& event) { + if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0 && + bind.modifiers.has_necessary_modifiers(SDL_GetModState())) { + m_display_manager->toggle_display_mode(); + } + })); } GLDisplay::~GLDisplay() { diff --git a/game/settings/settings.cpp b/game/settings/settings.cpp index 9ab64cf735..cbf8f378be 100644 --- a/game/settings/settings.cpp +++ b/game/settings/settings.cpp @@ -18,6 +18,7 @@ void to_json(json& j, const DebugSettings& obj) { json_serialize(text_check_range); json_serialize(text_max_range); json_serialize(hide_imgui_key); + j["toggle_fullscreen_key"] = obj.toggle_fullscreen_key; } void from_json(const json& j, DebugSettings& obj) { @@ -31,10 +32,11 @@ void from_json(const json& j, DebugSettings& obj) { json_deserialize_if_exists(text_check_range); json_deserialize_if_exists(text_max_range); json_deserialize_if_exists(hide_imgui_key); + if (j.contains("toggle_fullscreen_key")) { + j.at("toggle_fullscreen_key").get_to(obj.toggle_fullscreen_key); + } } -DebugSettings::DebugSettings() {} - void DebugSettings::load_settings() { try { std::string file_path = diff --git a/game/settings/settings.h b/game/settings/settings.h index 78e766fd73..157e764ced 100644 --- a/game/settings/settings.h +++ b/game/settings/settings.h @@ -3,13 +3,25 @@ #include "common/util/FileUtil.h" #include "common/util/json_util.h" +#include "SDL3/SDL.h" #include "game/system/hid/input_bindings.h" #include "game/system/hid/sdl_util.h" #include "game/tools/filter_menu/filter_menu.h" namespace game_settings { + +struct KeyWithModifiers { + u32 key; + InputModifiers modifiers; + + KeyWithModifiers() = default; + KeyWithModifiers(u32 k, const InputModifiers& m) : key(k), modifiers(m) {} +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(KeyWithModifiers, key, modifiers) + struct DebugSettings { - DebugSettings(); + DebugSettings() = default; std::string current_version = "1.2"; std::string version = current_version; @@ -24,11 +36,16 @@ struct DebugSettings { std::vector text_filters = {}; bool text_check_range = false; float text_max_range = 0; + u32 hide_imgui_key = SDLK_LALT; + KeyWithModifiers toggle_fullscreen_key = + KeyWithModifiers(SDLK_RETURN, InputModifiers(SDL_KMOD_ALT)); + void load_settings(); void save_settings(); }; + void to_json(json& j, const DebugSettings& obj); void from_json(const json& j, DebugSettings& obj); diff --git a/game/system/hid/devices/game_controller.cpp b/game/system/hid/devices/game_controller.cpp index 54f98c4cb6..2bad7bee69 100644 --- a/game/system/hid/devices/game_controller.cpp +++ b/game/system/hid/devices/game_controller.cpp @@ -222,7 +222,13 @@ void GameController::process_event(const SDL_Event& event, if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN && commands.controller_binds.find(event.gbutton.button) != commands.controller_binds.end()) { for (const auto& command : commands.controller_binds.at(event.gbutton.button)) { - command.command(); + if (command.event_command) { + command.event_command(event); + } else if (command.command) { + command.command(); + } else { + lg::warn("CommandBinding has no valid callback for controller bind"); + } } } } else if (SDL_EVENT_JOYSTICK_AXIS_MOTION && m_has_pressure_sensitive_buttons) { diff --git a/game/system/hid/devices/keyboard.cpp b/game/system/hid/devices/keyboard.cpp index cc55f3083f..f788b69ac6 100644 --- a/game/system/hid/devices/keyboard.cpp +++ b/game/system/hid/devices/keyboard.cpp @@ -169,7 +169,13 @@ void KeyboardDevice::process_event(const SDL_Event& event, commands.keyboard_binds.find(key_event.key) != commands.keyboard_binds.end()) { for (const auto& command : commands.keyboard_binds.at(key_event.key)) { if (command.modifiers.has_necessary_modifiers(key_event.mod)) { - command.command(); + if (command.event_command) { + command.event_command(event); + } else if (command.command) { + command.command(); + } else { + lg::warn("CommandBinding has no valid callback for keyboard bind"); + } } } } diff --git a/game/system/hid/devices/mouse.cpp b/game/system/hid/devices/mouse.cpp index 48f0d98d15..edb260be38 100644 --- a/game/system/hid/devices/mouse.cpp +++ b/game/system/hid/devices/mouse.cpp @@ -213,7 +213,13 @@ void MouseDevice::process_event(const SDL_Event& event, commands.mouse_binds.find(button_event.button) != commands.mouse_binds.end()) { for (const auto& command : commands.mouse_binds.at(button_event.button)) { if (command.modifiers.has_necessary_modifiers(SDL_GetModState())) { - command.command(); + if (command.event_command) { + command.event_command(event); + } else if (command.command) { + command.command(); + } else { + lg::warn("CommandBinding has no valid callback for mouse bind"); + } } } } diff --git a/game/system/hid/display_manager.cpp b/game/system/hid/display_manager.cpp index 5a3d034285..3c2116c996 100644 --- a/game/system/hid/display_manager.cpp +++ b/game/system/hid/display_manager.cpp @@ -300,6 +300,41 @@ void DisplayManager::set_display_mode(game_settings::DisplaySettings::DisplayMod } } +void DisplayManager::toggle_display_mode() { + const auto current_mode = m_display_settings.display_mode; + // Store the current prefered fullscreen mode + if (current_mode != game_settings::DisplaySettings::DisplayMode::Windowed) { + m_previous_fullscreen_display_mode = current_mode; + } + lg::info("Current display mode: "); + switch (current_mode) { + case game_settings::DisplaySettings::DisplayMode::Fullscreen: + case game_settings::DisplaySettings::DisplayMode::Borderless: + lg::info("Fullscreen/Borderless\n"); + lg::info("Switching to Windowed mode...\n"); + enqueue_set_window_display_mode(game_settings::DisplaySettings::DisplayMode::Windowed); + break; + + case game_settings::DisplaySettings::DisplayMode::Windowed: + lg::info("Windowed\n"); + if (m_previous_fullscreen_display_mode == + game_settings::DisplaySettings::DisplayMode::Fullscreen) { + lg::info("Switching to Fullscreen mode...\n"); + } else if (m_previous_fullscreen_display_mode == + game_settings::DisplaySettings::DisplayMode::Borderless) { + lg::info("Switching to Borderless mode...\n"); + } else { + lg::info("Switching to unknown preferred mode...\n"); + } + enqueue_set_window_display_mode(m_previous_fullscreen_display_mode); + break; + + default: + lg::info("Unknown display mode!\n"); + break; + } +} + void DisplayManager::enqueue_set_display_id(int display_id) { const std::lock_guard lock(event_queue_mtx); ee_event_queue.push({EEDisplayEventType::SET_DISPLAY_ID, display_id, {}}); diff --git a/game/system/hid/display_manager.h b/game/system/hid/display_manager.h index a706bf71d7..3c3be0a1b8 100644 --- a/game/system/hid/display_manager.h +++ b/game/system/hid/display_manager.h @@ -47,7 +47,8 @@ struct Resolution { class DisplayManager { private: enum class EEDisplayEventType { SET_WINDOW_SIZE, SET_DISPLAY_MODE, SET_DISPLAY_ID }; - + game_settings::DisplaySettings::DisplayMode m_previous_fullscreen_display_mode = + game_settings::DisplaySettings::DisplayMode::Fullscreen; struct EEDisplayEvent { EEDisplayEventType type; std::variant param1; @@ -88,6 +89,7 @@ class DisplayManager { // Mutators void enqueue_set_window_size(int width, int height); void enqueue_set_window_display_mode(game_settings::DisplaySettings::DisplayMode mode); + void toggle_display_mode(); void enqueue_set_display_id(int display_id); void set_game_size(int width, int height) { diff --git a/game/system/hid/input_bindings.h b/game/system/hid/input_bindings.h index 789f493fa0..b047580451 100644 --- a/game/system/hid/input_bindings.h +++ b/game/system/hid/input_bindings.h @@ -11,6 +11,8 @@ #include "common/log/log.h" #include "common/util/json_util.h" +#include "SDL3/SDL.h" + #define GET_PRESSURE_BUTTON_DATA(button_name) \ {button_data.at(ButtonIndex::button_name), \ pressure_data.at(PressureIndex::button_name##_PRESSURE)}; @@ -391,11 +393,23 @@ extern const InputBindingGroups DEFAULT_MOUSE_BINDS; struct CommandBinding { enum Source { CONTROLLER, KEYBOARD, MOUSE }; - CommandBinding(const u32 _host_key, std::function _command) - : host_key(_host_key), command(_command) {}; u32 host_key; - std::function command; InputModifiers modifiers; + + // Three types of callbacks: one with SDL_Event, one without, and one with input modifiers + std::function command = nullptr; + std::function event_command = nullptr; + + CommandBinding(u32 _host_key, std::function _command) + : host_key(_host_key), command(std::move(_command)) {} + + CommandBinding(u32 _host_key, std::function _command) + : host_key(_host_key), event_command(std::move(_command)) {} + + CommandBinding(u32 _host_key, + const InputModifiers& _modifiers, + std::function _command) + : host_key(_host_key), modifiers(_modifiers), event_command(std::move(_command)) {} }; struct CommandBindingGroups { diff --git a/iso_data/jak2/.gitignore b/iso_data/jak2/.gitignore index d6b7ef32c8..c96a04f008 100644 --- a/iso_data/jak2/.gitignore +++ b/iso_data/jak2/.gitignore @@ -1,2 +1,2 @@ * -!.gitignore +!.gitignore \ No newline at end of file