yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
input_manager.cc
Go to the documentation of this file.
2
3#include "app/emu/snes.h"
4#include "util/log.h"
5
6namespace yaze {
7namespace emu {
8namespace input {
9
16
19 if (!backend_) {
20 LOG_ERROR("InputManager", "Failed to create input backend");
21 return false;
22 }
23
25
26 if (!backend_->Initialize(config_)) {
27 LOG_ERROR("InputManager", "Failed to initialize input backend");
28 return false;
29 }
30
31 config_ = backend_->GetConfig();
32
33 LOG_INFO("InputManager", "Initialized with backend: %s",
34 backend_->GetBackendName().c_str());
35 return true;
36}
37
38void InputManager::Initialize(std::unique_ptr<IInputBackend> backend) {
39 backend_ = std::move(backend);
40
41 if (backend_) {
42 if (!backend_->IsInitialized()) {
44 backend_->Initialize(config_);
45 }
46 config_ = backend_->GetConfig();
47 LOG_INFO("InputManager", "Initialized with custom backend: %s",
48 backend_->GetBackendName().c_str());
49 }
50}
51
53 if (backend_) {
54 backend_->Shutdown();
55 backend_.reset();
56 }
57}
58
59void InputManager::Poll(Snes* snes, int player) {
60 if (!snes || !backend_)
61 return;
62
63 ControllerState physical_state = backend_->Poll(player);
64
65 // Combine physical input with agent-controlled input (OR operation)
66 // Use atomic load for thread-safe access from gRPC thread
67 ControllerState final_state;
68 final_state.buttons =
69 physical_state.buttons | agent_buttons_.load(std::memory_order_acquire);
70
71 // Apply button state directly to SNES
72 // Just send the raw button state on every Poll() call
73 // The button state will be latched by HandleInput() at VBlank
74 for (int i = 0; i < 12; i++) {
75 bool button_held = (final_state.buttons & (1 << i)) != 0;
76 snes->SetButtonState(player, i, button_held);
77 }
78
79 // Debug: Log complete button state when any button is pressed
80 static int poll_log_count = 0;
81 if (final_state.buttons != 0 && poll_log_count++ < 50) {
82 LOG_INFO("InputManager", "Poll: buttons=0x%04X (passed to SetButtonState)",
83 final_state.buttons);
84 }
85}
86
87void InputManager::ProcessEvent(void* event) {
88 if (backend_) {
89 backend_->ProcessEvent(event);
90 }
91}
92
94 if (backend_) {
95 return backend_->GetConfig();
96 }
97 return config_;
98}
99
101 config_ = config;
103 LOG_WARN("InputManager",
104 "continuous_polling disabled in config; forcing it ON to keep edge "
105 "detection working for menus (event-based path is not wired)");
107 }
108 // Always ignore ImGui text input capture for game controls to avoid blocking
110 LOG_WARN("InputManager",
111 "ignore_imgui_text_input was false; forcing true so game input is not blocked");
113 }
115 if (backend_) {
116 backend_->SetConfig(config_);
117 config_ = backend_->GetConfig();
118 }
119}
120
122 // Atomic fetch-and-or for thread-safe button press from gRPC thread
123 uint16_t mask = 1 << static_cast<uint8_t>(button);
124 agent_buttons_.fetch_or(mask, std::memory_order_release);
125}
126
128 // Atomic fetch-and-and for thread-safe button release from gRPC thread
129 uint16_t mask = ~(1 << static_cast<uint8_t>(button));
130 agent_buttons_.fetch_and(mask, std::memory_order_release);
131}
132
133} // namespace input
134} // namespace emu
135} // namespace yaze
void SetButtonState(int player, int button, bool pressed)
Definition snes.cc:864
static std::unique_ptr< IInputBackend > Create(BackendType type)
void Poll(Snes *snes, int player=1)
void PressButton(SnesButton button)
std::unique_ptr< IInputBackend > backend_
void SetConfig(const InputConfig &config)
void ReleaseButton(SnesButton button)
InputConfig GetConfig() const
std::atomic< uint16_t > agent_buttons_
bool Initialize(InputBackendFactory::BackendType type=InputBackendFactory::BackendType::SDL2)
#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.
SnesButton
SNES controller button mapping (platform-agnostic)
Controller state (16-bit SNES controller format)
Input configuration (platform-agnostic key codes)