yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
input_backend.cc
Go to the documentation of this file.
2
4#include "imgui/imgui.h"
5#include "util/log.h"
6
7#ifdef YAZE_USE_SDL3
9#endif
10
11namespace yaze {
12namespace emu {
13namespace input {
14
16 if (config.key_a == 0) config.key_a = platform::kKeyX;
17 if (config.key_b == 0) config.key_b = platform::kKeyZ;
18 if (config.key_x == 0) config.key_x = platform::kKeyS;
19 if (config.key_y == 0) config.key_y = platform::kKeyA;
20 if (config.key_l == 0) config.key_l = platform::kKeyD;
21 if (config.key_r == 0) config.key_r = platform::kKeyC;
22 if (config.key_start == 0) config.key_start = platform::kKeyReturn;
23 if (config.key_select == 0) config.key_select = platform::kKeyRShift;
24 if (config.key_up == 0) config.key_up = platform::kKeyUp;
25 if (config.key_down == 0) config.key_down = platform::kKeyDown;
26 if (config.key_left == 0) config.key_left = platform::kKeyLeft;
27 if (config.key_right == 0) config.key_right = platform::kKeyRight;
28}
29
34 public:
35 SDL2InputBackend() = default;
36 ~SDL2InputBackend() override { Shutdown(); }
37
38 bool Initialize(const InputConfig& config) override {
39 if (initialized_) {
40 LOG_WARN("InputBackend", "Already initialized");
41 return true;
42 }
43
44 config_ = config;
45
47
48 initialized_ = true;
49 LOG_INFO("InputBackend", "SDL2 Input Backend initialized");
50 return true;
51 }
52
53 void Shutdown() override {
54 if (initialized_) {
55 initialized_ = false;
56 LOG_INFO("InputBackend", "SDL2 Input Backend shut down");
57 }
58 }
59
60 ControllerState Poll(int player) override {
61 if (!initialized_)
62 return ControllerState{};
63
64 ControllerState state;
65
67 // Pump events to update keyboard state - critical for edge detection
68 // when multiple emulated frames run per host frame
69 SDL_PumpEvents();
70
71 // Continuous polling mode (for games)
72 // Continuous polling mode (for games)
73 platform::KeyboardState keyboard_state = SDL_GetKeyboardState(nullptr);
74
75 // Do NOT block emulator input when ImGui wants text; games rely on edge detection
76 // and we don't want UI focus to interfere with controller state.
77
78 // Map keyboard to SNES buttons
83 state.SetButton(
86 state.SetButton(
95 state.SetButton(
106
107 // Debug: Log when any button is pressed
108 static int button_log_count = 0;
109 if (state.buttons != 0 && button_log_count++ < 100) {
110 LOG_INFO("InputBackend", "SDL2 Poll: buttons=0x%04X (keyboard detected)",
111 state.buttons);
112 }
113 } else {
114 // Event-based mode (use cached event state)
115 state = event_state_;
116 }
117
118 // TODO: Add gamepad support
119 // if (config_.enable_gamepad) { ... }
120
121 return state;
122 }
123
124 void ProcessEvent(void* event) override {
125 if (!initialized_ || !event)
126 return;
127
128 SDL_Event* sdl_event = static_cast<SDL_Event*>(event);
129
130 // Cache keyboard events for event-based mode
131 if (sdl_event->type == platform::kEventKeyDown) {
133 } else if (sdl_event->type == platform::kEventKeyUp) {
135 }
136
137 // TODO: Handle gamepad events
138 }
139
140 InputConfig GetConfig() const override { return config_; }
141
142 void SetConfig(const InputConfig& config) override { config_ = config; }
143
144 std::string GetBackendName() const override { return "SDL2"; }
145
146 bool IsInitialized() const override { return initialized_; }
147
148 private:
149 void UpdateEventState(int keycode, bool pressed) {
150 // Map keycode to button and update event state
151 if (keycode == config_.key_a)
153 else if (keycode == config_.key_b)
155 else if (keycode == config_.key_x)
157 else if (keycode == config_.key_y)
159 else if (keycode == config_.key_l)
161 else if (keycode == config_.key_r)
163 else if (keycode == config_.key_start)
165 else if (keycode == config_.key_select)
167 else if (keycode == config_.key_up)
169 else if (keycode == config_.key_down)
171 else if (keycode == config_.key_left)
173 else if (keycode == config_.key_right)
175 }
176
178 bool initialized_ = false;
179 ControllerState event_state_; // Cached state for event-based mode
180};
181
186 public:
187 bool Initialize(const InputConfig& config) override {
188 config_ = config;
190 return true;
191 }
192 void Shutdown() override {}
193 ControllerState Poll(int player) override { return replay_state_; }
194 void ProcessEvent(void* event) override {}
195 InputConfig GetConfig() const override { return config_; }
196 void SetConfig(const InputConfig& config) override { config_ = config; }
197 std::string GetBackendName() const override { return "NULL"; }
198 bool IsInitialized() const override { return true; }
199
200 // For replay/testing - set controller state directly
201 void SetReplayState(const ControllerState& state) { replay_state_ = state; }
202
203 private:
206};
207
208// Factory implementation
209std::unique_ptr<IInputBackend> InputBackendFactory::Create(BackendType type) {
210 switch (type) {
212#ifdef YAZE_USE_SDL3
213 LOG_WARN("InputBackend",
214 "SDL2 backend requested but SDL3 build enabled, using SDL3");
215 return std::make_unique<SDL3InputBackend>();
216#else
217 return std::make_unique<SDL2InputBackend>();
218#endif
219
221#ifdef YAZE_USE_SDL3
222 return std::make_unique<SDL3InputBackend>();
223#else
224 LOG_WARN("InputBackend",
225 "SDL3 backend requested but not available, using SDL2");
226 return std::make_unique<SDL2InputBackend>();
227#endif
228
230 return std::make_unique<NullInputBackend>();
231
232 default:
233#ifdef YAZE_USE_SDL3
234 LOG_ERROR("InputBackend", "Unknown backend type, using SDL3");
235 return std::make_unique<SDL3InputBackend>();
236#else
237 LOG_ERROR("InputBackend", "Unknown backend type, using SDL2");
238 return std::make_unique<SDL2InputBackend>();
239#endif
240 }
241}
242
243} // namespace input
244} // namespace emu
245} // namespace yaze
Abstract input backend interface.
static std::unique_ptr< IInputBackend > Create(BackendType type)
Null input backend for testing/replay.
bool IsInitialized() const override
Check if backend is initialized.
InputConfig GetConfig() const override
Get current configuration.
bool Initialize(const InputConfig &config) override
Initialize the input backend.
ControllerState Poll(int player) override
Poll current input state (call every frame)
void SetReplayState(const ControllerState &state)
void SetConfig(const InputConfig &config) override
Update configuration (hot-reload)
void ProcessEvent(void *event) override
Process platform-specific events (optional)
void Shutdown() override
Shutdown the input backend.
std::string GetBackendName() const override
Get backend name for debugging.
SDL2 input backend implementation.
InputConfig GetConfig() const override
Get current configuration.
void ProcessEvent(void *event) override
Process platform-specific events (optional)
void UpdateEventState(int keycode, bool pressed)
void SetConfig(const InputConfig &config) override
Update configuration (hot-reload)
void Shutdown() override
Shutdown the input backend.
bool IsInitialized() const override
Check if backend is initialized.
std::string GetBackendName() const override
Get backend name for debugging.
bool Initialize(const InputConfig &config) override
Initialize the input backend.
ControllerState Poll(int player) override
Poll current input state (call every frame)
#define LOG_ERROR(category, format,...)
Definition log.h:109
#define LOG_WARN(category, format,...)
Definition log.h:107
#define LOG_INFO(category, format,...)
Definition log.h:105
void ApplyDefaultKeyBindings(InputConfig &config)
Apply default keyboard bindings if unset.
constexpr auto kEventKeyDown
Definition sdl_compat.h:53
SDL_Scancode GetScancodeFromKey(SDL_Keycode key)
Get scancode from keycode.
Definition sdl_compat.h:128
constexpr auto kKeyX
Definition sdl_compat.h:95
constexpr auto kKeyC
Definition sdl_compat.h:92
constexpr auto kKeyRShift
Definition sdl_compat.h:99
constexpr auto kKeyRight
Definition sdl_compat.h:103
constexpr auto kKeyA
Definition sdl_compat.h:90
constexpr auto kEventKeyUp
Definition sdl_compat.h:54
constexpr auto kKeyLeft
Definition sdl_compat.h:102
constexpr auto kKeyZ
Definition sdl_compat.h:97
constexpr auto kKeyUp
Definition sdl_compat.h:100
SDL_Keycode GetKeyFromEvent(const SDL_Event &event)
Get keyboard state from SDL event.
Definition sdl_compat.h:115
constexpr auto kKeyDown
Definition sdl_compat.h:101
constexpr auto kKeyD
Definition sdl_compat.h:93
constexpr auto kKeyReturn
Definition sdl_compat.h:98
constexpr auto kKeyS
Definition sdl_compat.h:94
const Uint8 * KeyboardState
Definition sdl_compat.h:32
SDL2/SDL3 compatibility layer.
Controller state (16-bit SNES controller format)
void SetButton(SnesButton button, bool pressed)
Input configuration (platform-agnostic key codes)