Split screenshot from main input handler

This commit is contained in:
phosit 2025-04-17 12:17:19 +02:00
parent 0a1d1821da
commit 143b31089c
No known key found for this signature in database
GPG key ID: C9430B600671C268
4 changed files with 47 additions and 27 deletions

View file

@ -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();

View file

@ -50,28 +50,29 @@ namespace Slot
{
constexpr std::integral_constant<size_t, 0> PRIMARY;
constexpr std::integral_constant<size_t, 1> WINDOW;
constexpr std::integral_constant<size_t, 2> SCREEN_SHOT;
// 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<size_t, 2> HOTKEY_STATE_CHANGE;
constexpr std::integral_constant<size_t, 3> GLOBAL;
constexpr std::integral_constant<size_t, 3> HOTKEY_STATE_CHANGE;
constexpr std::integral_constant<size_t, 4> 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<size_t, 4> HOTKEY_INPUT_PREPARATION;
constexpr std::integral_constant<size_t, 5> HOTKEY_INPUT_PREPARATION;
constexpr std::integral_constant<size_t, 5> TOUCH_INPUT;
constexpr std::integral_constant<size_t, 6> 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<size_t, 6> CONSOLE;
constexpr std::integral_constant<size_t, 7> CONSOLE;
// Likewise for gui.
constexpr std::integral_constant<size_t, 7> GUI;
constexpr std::integral_constant<size_t, 8> HOTKEY_INPUT;
constexpr std::integral_constant<size_t, 9> PROFILE_VIEWER;
constexpr std::integral_constant<size_t, 10> GAME_VIEW;
constexpr std::integral_constant<size_t, 8> GUI;
constexpr std::integral_constant<size_t, 9> HOTKEY_INPUT;
constexpr std::integral_constant<size_t, 10> PROFILE_VIEWER;
constexpr std::integral_constant<size_t, 11> GAME_VIEW;
}
/**
@ -138,7 +139,7 @@ public:
PollEventsResult PollEvents();
private:
std::array<HandlerBase*, 11> m_Handlers{{}};
std::array<HandlerBase*, 12> m_Handlers{{}};
const std::unique_ptr<std::queue<SDL_Event>> m_PriorityEvents;
};

View file

@ -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 <SDL_events.h>
#include <cstdlib>
#include <string>
#include <unordered_map>
@ -371,6 +373,35 @@ public:
std::vector<Renderer::Backend::SVertexAttributeFormat>,
std::unique_ptr<Renderer::Backend::IVertexInputLayout>, 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<const char*>(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<InputHandler> m_InputHandler{g_VideoMode.m_InputManager, Input::Slot::SCREEN_SHOT,
{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()

View file

@ -188,8 +188,6 @@ protected:
Stats m_Stats;
bool m_ShouldPreloadResourcesBeforeNextFrame = false;
ScreenShotType m_ScreenShotType = ScreenShotType::NONE;
};
#define g_Renderer CRenderer::GetSingleton()