Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
GamepadSettingsScene.cpp
Go to the documentation of this file.
1
9#include <SFML/Window/Joystick.hpp>
10
11namespace rtp::client {
12 namespace scenes {
13
15 // Public API
17
19 Settings& settings,
20 TranslationManager& translationManager,
21 NetworkSyncSystem& network,
22 graphics::UiFactory& uiFactory,
23 std::function<void(GameState)> changeState)
24 : _uiRegistry(UiRegistry),
25 _settings(settings),
26 _translationManager(translationManager),
27 _network(network),
28 _uiFactory(uiFactory),
29 _changeState(changeState)
30 {
31 }
32
34 {
35 log::info("Entering GamepadSettingsScene");
36 float yPos = 120.0f;
37
38 // Title
41 {420.0f, 30.0f},
42 _translationManager.get("settings.gamepad_settings"),
43 "assets/fonts/main.ttf",
44 50,
45 10,
46 {255, 200, 100}
47 );
48
49 // Enable/Disable gamepad
52 {240.0f, yPos},
53 _translationManager.get("settings.gamepad"),
54 "assets/fonts/main.ttf",
55 24
56 );
57
58 std::vector<std::string> enableOptions = {_translationManager.get("settings.disabled"), _translationManager.get("settings.enabled")};
61 {540.0f, yPos},
62 {300.0f, 40.0f},
63 enableOptions,
65 [this](int index) {
66 _settings.setGamepadEnabled(index == 1);
67 log::info("Gamepad {}", index == 1 ? "enabled" : "disabled");
68 }
69 );
70
71 yPos += 70.0f;
72
73 // Deadzone slider
76 {240.0f, yPos},
77 _translationManager.get("settings.gamepad_deadzone"),
78 "assets/fonts/main.ttf",
79 24
80 );
81
84 {540.0f, yPos + 3.0f},
85 {300.0f, 20.0f},
86 0.0f,
87 50.0f,
89 [this](float value) {
91 }
92 );
93
94 yPos += 70.0f;
95
96 // Shoot Button
99 {240.0f, yPos + 5.0f},
100 _translationManager.get("keybindings.shoot"),
101 "assets/fonts/main.ttf",
102 24
103 );
104
105 unsigned int shootButton = _settings.getGamepadShootButton();
106 auto shootEntity = _uiFactory.createButton(
108 {540.0f, yPos},
109 {300.0f, 40.0f},
110 getButtonName(shootButton),
111 [this]() {
112 _isWaitingForButton = true;
115 }
116 );
118
119 yPos += 60.0f;
120
121 // Reload Button
124 {240.0f, yPos + 5.0f},
125 _translationManager.get("keybindings.reload"),
126 "assets/fonts/main.ttf",
127 24
128 );
129
130 unsigned int reloadButton = _settings.getGamepadReloadButton();
131 auto reloadEntity = _uiFactory.createButton(
133 {540.0f, yPos},
134 {300.0f, 40.0f},
135 getButtonName(reloadButton),
136 [this]() {
137 _isWaitingForButton = true;
140 }
141 );
143
144 yPos += 60.0f;
145
146 // Pause Button
149 {240.0f, yPos + 5.0f},
150 _translationManager.get("keybindings.pause"),
151 "assets/fonts/main.ttf",
152 24
153 );
154
155 unsigned int pauseButton = _settings.getGamepadPauseButton();
156 auto pauseEntity = _uiFactory.createButton(
158 {540.0f, yPos},
159 {300.0f, 40.0f},
160 getButtonName(pauseButton),
161 [this]() {
162 _isWaitingForButton = true;
165 }
166 );
168
169 yPos += 80.0f;
170
171 // Info text
174 {350.0f, yPos},
175 "Movement: Left Stick or D-pad",
176 "assets/fonts/main.ttf",
177 18,
178 0,
179 {200, 200, 200}
180 );
181
182 yPos += 40.0f;
183
184 // Back button
187 {490.0f, yPos},
188 {300.0f, 50.0f},
189 _translationManager.get("settings.close"),
190 [this]() {
191 _settings.save();
193 }
194 );
195 }
196
198 {
199 _isWaitingForButton = false;
200 }
201
202 void GamepadSettingsScene::handleEvent(const sf::Event& event)
203 {
205 return;
206
207 // Check if any gamepad button is pressed
208 if (_settings.getGamepadEnabled() && sf::Joystick::isConnected(0)) {
209 for (unsigned int i = 0; i < sf::Joystick::getButtonCount(0); ++i) {
210 if (sf::Joystick::isButtonPressed(0, i)) {
211 // Button pressed, assign it
212 switch (_actionToRebind) {
215 break;
218 break;
221 break;
222 }
223
224 _settings.save();
225 _isWaitingForButton = false;
226
227 log::info("Gamepad button {} bound to action",
228 getButtonName(i));
229
231
232 // Wait a bit to avoid detecting the same press multiple times
233 sf::sleep(sf::milliseconds(200));
234 return;
235 }
236 }
237 }
238
239 // Allow Escape to cancel
240 if (const auto* kp = event.getIf<sf::Event::KeyPressed>()) {
241 if (kp->code == sf::Keyboard::Key::Escape) {
242 _isWaitingForButton = false;
243 log::info("Button binding cancelled");
245 return;
246 }
247 }
248 }
249
251 {
252 (void)dt;
253 }
254
256 // Private API
258
260 {
261 auto it = _actionToButton.find(action);
262 if (it == _actionToButton.end()) {
263 log::warning("No button found for action");
264 return;
265 }
266
267 const ecs::Entity e = it->second;
268
269 unsigned int button = 0;
270 switch (action) {
273 break;
276 break;
279 break;
280 }
281
282 const std::string buttonName = _isWaitingForButton ? "Press button..." : getButtonName(button);
283
284 auto buttonsRes = _uiRegistry.get<ecs::components::ui::Button>();
285 if (!buttonsRes) {
286 log::error("Failed to get Button components");
287 return;
288 }
289
290 auto& buttons = buttonsRes.value().get();
291
292 if (!buttons.has(e)) {
293 log::warning("Button component not found for entity");
294 return;
295 }
296
297 buttons[e].text = buttonName;
298 }
299
300 std::string GamepadSettingsScene::getButtonName(unsigned int button) const
301 {
302 static const std::vector<std::string> buttonNames = {
303 "A (0)", "B (1)", "X (2)", "Y (3)",
304 "LB (4)", "RB (5)", "Back (6)", "Start (7)",
305 "LS (8)", "RS (9)", "LT (10)", "RT (11)"
306 };
307
308 if (button < buttonNames.size()) {
309 return buttonNames[button];
310 }
311 return "Button " + std::to_string(button);
312 }
313
314 } // namespace scenes
315} // namespace rtp::client
System to handle network-related operations on the client side.
Manages game settings and preferences.
Definition Settings.hpp:67
void setGamepadPauseButton(unsigned int button)
Definition Settings.hpp:239
void setGamepadReloadButton(unsigned int button)
Definition Settings.hpp:209
unsigned int getGamepadReloadButton() const
Definition Settings.hpp:204
void setGamepadEnabled(bool enabled)
Definition Settings.hpp:179
bool getGamepadEnabled() const
Definition Settings.hpp:174
unsigned int getGamepadPauseButton() const
Definition Settings.hpp:234
bool save(const std::string &filename="config/settings.cfg")
Definition Settings.cpp:339
void setGamepadDeadzone(float deadzone)
Definition Settings.hpp:189
unsigned int getGamepadShootButton() const
Definition Settings.hpp:194
void setGamepadShootButton(unsigned int button)
Definition Settings.hpp:199
float getGamepadDeadzone() const
Definition Settings.hpp:184
Manages game translations for all UI elements.
std::string get(const std::string &key) const
Get translated string for a key.
Factory class for creating UI components in the ECS registry.
Definition UiFactory.hpp:72
static ecs::Entity createText(ecs::Registry &registry, const position &position, const std::string &content, const std::string &fontPath, unsigned int fontSize, const std::uint8_t zIndex=0, const color &textColor={255, 255, 255})
Definition UiFactory.cpp:43
static ecs::Entity createButton(ecs::Registry &registry, const position &position, const size &size, const std::string &label, std::function< void()> onClick=nullptr)
Create a button UI component.
Definition UiFactory.cpp:17
static ecs::Entity createDropdown(ecs::Registry &registry, const position &position, const size &size, const std::vector< std::string > &options, const int selectedIndex, std::function< void(int index)> onSelect=nullptr)
static ecs::Entity createSlider(ecs::Registry &registry, const position &position, const size &size, float minValue, float maxValue, float initialValue, std::function< void(float)> onChange=nullptr)
Definition UiFactory.cpp:75
std::unordered_map< GamepadAction, ecs::Entity > _actionToButton
void handleEvent(const sf::Event &event) override
Handle an incoming event.
GamepadSettingsScene(ecs::Registry &UiRegistry, Settings &settings, TranslationManager &translationManager, NetworkSyncSystem &network, graphics::UiFactory &uiFactory, std::function< void(GameState)> changeState)
void onEnter() override
Called when the scene is entered.
void update(float dt) override
Update the scene state.
std::string getButtonName(unsigned int button) const
void onExit() override
Called when the scene is exited.
Represents an entity in the ECS (Entity-Component-System) architecture.
Definition Entity.hpp:63
auto get(this const Self &self) -> std::expected< std::reference_wrapper< ConstLike< Self, SparseArray< T > > >, rtp::Error >
R-Type client namespace.
@ Settings
Settings menu state.
void error(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an error message.
void warning(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log a warning message.
void info(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an informational message.
Component representing a clickable button.
Definition Button.hpp:30