From 596c0c2ddd6dd7fb3421c0b4d0b24309dd2f7869 Mon Sep 17 00:00:00 2001 From: phosit Date: Thu, 17 Apr 2025 12:17:19 +0200 Subject: [PATCH] Split screenshot from main input handler This enables the screenshot hotkeys in atlas. --- source/main.cpp | 10 --------- source/ps/Input.h | 21 +++++++++--------- source/renderer/Renderer.cpp | 41 +++++++++++++++++++++++++++++++----- source/renderer/Renderer.h | 2 -- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index ff5ecc57f5..4fd9474fb2 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -221,16 +221,6 @@ static Input::Reaction MainInputHandler(const SDL_Event& ev) QuitEngine(EXIT_SUCCESS); return Input::Reaction::HANDLED; } - else if (hotkey == "screenshot") - { - g_Renderer.MakeScreenShotOnNextFrame(CRenderer::ScreenShotType::DEFAULT); - return Input::Reaction::HANDLED; - } - else if (hotkey == "bigscreenshot") - { - g_Renderer.MakeScreenShotOnNextFrame(CRenderer::ScreenShotType::BIG); - return Input::Reaction::HANDLED; - } else if (hotkey == "togglefullscreen") { g_VideoMode.ToggleFullscreen(); diff --git a/source/ps/Input.h b/source/ps/Input.h index c26805a870..7f8a5e8cd3 100644 --- a/source/ps/Input.h +++ b/source/ps/Input.h @@ -50,28 +50,29 @@ namespace Slot { constexpr std::integral_constant PRIMARY; constexpr std::integral_constant WINDOW; +constexpr std::integral_constant SCREENSHOT; // These two must be called first `globalsInput` deals with some important global state, such as which // scancodes are being pressed, mouse buttons pressed, etc. while hotkeyStateChange updates the map of // active hotkeys. -constexpr std::integral_constant HOTKEY_STATE_CHANGE; -constexpr std::integral_constant GLOBAL; +constexpr std::integral_constant HOTKEY_STATE_CHANGE; +constexpr std::integral_constant GLOBAL; // Should be called after scancode map update (i.e. after the global input, but before UI). This never // blocks the event, but it does some processing necessary for hotkeys, which are triggered later down the // input chain. (by calling this before the UI, we can use `EventWouldTriggerHotkey` in the UI). -constexpr std::integral_constant HOTKEY_INPUT_PREPARATION; +constexpr std::integral_constant HOTKEY_INPUT_PREPARATION; -constexpr std::integral_constant TOUCH_INPUT; +constexpr std::integral_constant TOUCH_INPUT; // The console handler needs to be called before the hotkey handler so that text can be typed in without // setting off hotkeys. -constexpr std::integral_constant CONSOLE; +constexpr std::integral_constant CONSOLE; // Likewise for gui. -constexpr std::integral_constant GUI; -constexpr std::integral_constant HOTKEY_INPUT; -constexpr std::integral_constant PROFILE_VIEWER; -constexpr std::integral_constant GAME_VIEW; +constexpr std::integral_constant GUI; +constexpr std::integral_constant HOTKEY_INPUT; +constexpr std::integral_constant PROFILE_VIEWER; +constexpr std::integral_constant GAME_VIEW; } /** @@ -138,7 +139,7 @@ public: PollEventsResult PollEvents(); private: - std::array m_Handlers{{}}; + std::array m_Handlers{{}}; const std::unique_ptr> m_PriorityEvents; }; diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index a7545c9dae..cafd37e0ce 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -54,6 +54,7 @@ #include "ps/GameSetup/Config.h" #include "ps/Globals.h" #include "ps/memory/LinearAllocator.h" +#include "ps/Hotkey.h" #include "ps/Profile.h" #include "ps/ProfileViewer.h" #include "ps/Profiler2.h" @@ -76,6 +77,7 @@ #include "tools/atlas/GameInterface/GameLoop.h" #include "tools/atlas/GameInterface/View.h" +#include #include #include #include @@ -371,6 +373,35 @@ public: std::vector, std::unique_ptr, VertexAttributesHash> vertexInputLayouts; + ScreenShotType m_ScreenShotType{ScreenShotType::NONE}; + + struct InputHandler + { + ScreenShotType& screenshotType; + + Input::Reaction operator()(const SDL_Event& ev) + { + if (ev.type != SDL_HOTKEYPRESS) + return Input::Reaction::PASS; + + std::string_view hotkey{static_cast(ev.user.data1)}; + if (hotkey == "screenshot") + { + screenshotType = ScreenShotType::DEFAULT; + return Input::Reaction::HANDLED; + } + if (hotkey == "bigscreenshot") + { + screenshotType = ScreenShotType::BIG; + return Input::Reaction::HANDLED; + } + return Input::Reaction::PASS; + } + }; + + Input::Handler m_InputHandler{g_VideoMode.m_InputManager, Input::Slot::SCREENSHOT, + {m_ScreenShotType}}; + Internals(Renderer::Backend::IDevice* device) : device(device), deviceCommandContext(device->CreateCommandContext()), @@ -508,11 +539,11 @@ void CRenderer::RenderFrame(const bool needsPresent) if (!ShouldRender()) return; - if (m_ScreenShotType == ScreenShotType::BIG) + if (m->m_ScreenShotType == ScreenShotType::BIG) { RenderBigScreenShot(needsPresent); } - else if (m_ScreenShotType == ScreenShotType::DEFAULT) + else if (m->m_ScreenShotType == ScreenShotType::DEFAULT) { RenderScreenShot(needsPresent); } @@ -727,7 +758,7 @@ void CRenderer::RenderFrame2D(const bool renderGUI, const bool renderLogger) void CRenderer::RenderScreenShot(const bool needsPresent) { - m_ScreenShotType = ScreenShotType::NONE; + m->m_ScreenShotType = ScreenShotType::NONE; // get next available numbered filename // note: %04d -> always 4 digits, so sorting by filename works correctly. @@ -779,7 +810,7 @@ void CRenderer::RenderScreenShot(const bool needsPresent) void CRenderer::RenderBigScreenShot(const bool needsPresent) { - m_ScreenShotType = ScreenShotType::NONE; + m->m_ScreenShotType = ScreenShotType::NONE; // If the game hasn't started yet then use WriteScreenshot to generate the image. if (!g_Game) @@ -985,7 +1016,7 @@ void CRenderer::PreloadResourcesBeforeNextFrame() void CRenderer::MakeScreenShotOnNextFrame(ScreenShotType screenShotType) { - m_ScreenShotType = screenShotType; + m->m_ScreenShotType = screenShotType; } Renderer::Backend::IDeviceCommandContext* CRenderer::GetDeviceCommandContext() diff --git a/source/renderer/Renderer.h b/source/renderer/Renderer.h index e4a70b6ba4..5d2079340e 100644 --- a/source/renderer/Renderer.h +++ b/source/renderer/Renderer.h @@ -188,8 +188,6 @@ protected: Stats m_Stats; bool m_ShouldPreloadResourcesBeforeNextFrame = false; - - ScreenShotType m_ScreenShotType = ScreenShotType::NONE; }; #define g_Renderer CRenderer::GetSingleton()