group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
InputSampleSystem.hpp
Go to the documentation of this file.
1
3
4#pragma once
5
12
13#include <SDL3/SDL.h>
14
15#include <algorithm>
16#include <cmath>
17#include <glm/geometric.hpp>
18#include <glm/trigonometric.hpp>
19#include <glm/vec2.hpp>
20
24namespace systems
25{
26
28inline bool prevKillSelfKey = false;
30inline bool prevGrenadeKey = false;
32inline float grenadeHeldSeconds = 0.0f;
34inline bool grenadeRadialActive = false;
36inline glm::vec2 grenadeRadialAim{0.0f, -1.0f};
38inline bool pendingGrenadeThrow = false;
40inline constexpr float k_grenadeRadialHoldSeconds = 0.24f;
42inline constexpr float k_grenadeRadialDeadzone = 18.0f;
44inline constexpr float k_grenadeRadialMaxDistance = 130.0f;
46inline bool prevAbilitySelectLeft = false;
48inline bool prevAbilitySelectRight = false;
50inline bool prevGamepadAbilitySelectLeft = false;
53
56{
57 SDL_GamepadAxis x;
58 SDL_GamepadAxis y;
59};
60
62inline JoystickAxis getLookJoystickAxes(bool swapSticks)
63{
64 return {
65 .x = swapSticks ? SDL_GAMEPAD_AXIS_LEFTX : SDL_GAMEPAD_AXIS_RIGHTX,
66 .y = swapSticks ? SDL_GAMEPAD_AXIS_LEFTY : SDL_GAMEPAD_AXIS_RIGHTY,
67 };
68}
69
71inline JoystickAxis getMoveJoystickAxes(bool swapSticks)
72{
73 return {
74 .x = swapSticks ? SDL_GAMEPAD_AXIS_RIGHTX : SDL_GAMEPAD_AXIS_LEFTX,
75 .y = swapSticks ? SDL_GAMEPAD_AXIS_RIGHTY : SDL_GAMEPAD_AXIS_LEFTY,
76 };
77}
78
80inline bool gamepadConnected(SDL_Gamepad* gamepad)
81{
82 return gamepad != nullptr && SDL_GamepadConnected(gamepad);
83}
84
87inline std::uint8_t grenadeRadialIndexFromAim()
88{
91 }
92
93 constexpr glm::vec2 directions[3] = {
94 {0.0f, -1.0f},
95 {0.8660254f, 0.5f},
96 {-0.8660254f, 0.5f},
97 };
98
99 const glm::vec2 aim = glm::normalize(grenadeRadialAim);
100 std::uint8_t bestIndex = 0;
101 float bestDot = glm::dot(aim, directions[0]);
102 for (std::uint8_t i = 1; i < 3; ++i) {
103 const float d = glm::dot(aim, directions[i]);
104 if (d > bestDot) {
105 bestDot = d;
106 bestIndex = i;
107 }
108 }
109 return bestIndex;
110}
111
114{
115 const bool shouldThrow = pendingGrenadeThrow;
116 pendingGrenadeThrow = false;
117 return shouldThrow;
118}
119
133inline void runMouseLook(Registry& registry, float mouseSensitivity, bool gravityFlipped = false)
134{
135 float mdx = 0.0f;
136 float mdy = 0.0f;
137 SDL_GetRelativeMouseState(&mdx, &mdy);
138
140 grenadeRadialAim += glm::vec2{mdx, mdy};
141 const float len = glm::length(grenadeRadialAim);
142 if (len > k_grenadeRadialMaxDistance) {
144 }
145 return;
146 }
147
148 // When gravity is flipped the camera is rolled 180°, which swaps
149 // both screen-left/right and screen-up/down relative to world space.
150 // Negating both deltas keeps controls feeling natural.
151 if (gravityFlipped) {
152 mdx = -mdx;
153 mdy = -mdy;
154 }
155
156 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
157 // Negate: SDL mdx is positive when moving right, but positive yaw
158 // rotates toward +X which maps to screen-left via glm::lookAt's
159 // cross(forward, up) convention. Negating gives the standard
160 // "mouse right = look right" behaviour.
161 snap.yaw -= mdx * mouseSensitivity;
162
163 // Wrap yaw to [-π, π] to avoid float precision drift over time.
164 snap.yaw = std::remainder(snap.yaw, glm::radians(360.0f));
165
166 // Clamp pitch to avoid gimbal-lock at the poles.
167 snap.pitch = std::clamp(snap.pitch + mdy * mouseSensitivity, -glm::radians(89.0f), glm::radians(89.0f));
168 });
169}
170
181inline void runMovementKeys(Registry& registry, const InputBindings& bindings, bool gravityFlipped = false)
182{
183 const bool* const kKeys = SDL_GetKeyboardState(nullptr);
184 const SDL_MouseButtonFlags mouse = SDL_GetMouseState(nullptr, nullptr);
185
186 // Edge-detect K key: only fire killSelf on the rising edge (key-down),
187 // not while held. Prevents respawn → immediate re-death loop.
188 const bool killKeyNow = bindings.pressed(Action::KillSelf, kKeys, mouse);
189 const bool killEdge = killKeyNow && !prevKillSelfKey;
190 prevKillSelfKey = killKeyNow;
191
192 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
193 // Movement keys
194 const bool forward = bindings.pressed(Action::Forward, kKeys, mouse);
195 const bool back = bindings.pressed(Action::Back, kKeys, mouse);
196 const bool left = bindings.pressed(Action::Left, kKeys, mouse);
197 const bool right = bindings.pressed(Action::Right, kKeys, mouse);
198
199 snap.forward = forward;
200 snap.back = back;
201 // When gravity is flipped the camera is rolled 180°, which negates
202 // the screen-space right vector. Swapping A/D compensates so
203 // pressing A still moves the player screen-left.
204 snap.left = gravityFlipped ? right : left;
205 snap.right = gravityFlipped ? left : right;
206 snap.jump = bindings.pressed(Action::Jump, kKeys, mouse);
207 snap.crouch = bindings.pressed(Action::Crouch, kKeys, mouse);
208 snap.ability1 = bindings.pressed(Action::Ability1, kKeys, mouse);
209 snap.ability2 = bindings.pressed(Action::Ability2, kKeys, mouse);
210 snap.killSelf = killEdge;
211 snap.skipRespawn = false; // Clear stale flag from previous death.
212 });
213}
214
222inline void runDeadInput(Registry& registry, const InputBindings& bindings)
223{
224 const bool* const kKeys = SDL_GetKeyboardState(nullptr);
225 const SDL_MouseButtonFlags mouse = SDL_GetMouseState(nullptr, nullptr);
226
227 registry.view<InputSnapshot, LocalPlayer, RespawnTimer>().each(
228 [&](InputSnapshot& snap, const RespawnTimer& /*unused*/) {
229 snap.skipRespawn = bindings.pressed(Action::Jump, kKeys, mouse);
230 });
231}
232
242inline void runWeaponKeys(Registry& registry, const InputBindings& bindings, float dt = 0.0f)
243{
244 const bool* const kKeys = SDL_GetKeyboardState(nullptr);
245 const SDL_MouseButtonFlags mouse = SDL_GetMouseState(nullptr, nullptr);
246 const bool abilityMenuHeld = bindings.pressed(Action::AbilityMenu, kKeys, mouse);
247 const bool shootDown = bindings.pressed(Action::Shoot, kKeys, mouse);
248 const bool scopeDown = bindings.pressed(Action::Scope, kKeys, mouse);
249 const bool selectLeftNow = abilityMenuHeld && shootDown;
250 const bool selectRightNow = abilityMenuHeld && scopeDown;
251 const bool selectLeftEdge = selectLeftNow && !prevAbilitySelectLeft;
252 const bool selectRightEdge = selectRightNow && !prevAbilitySelectRight;
253 prevAbilitySelectLeft = selectLeftNow;
254 prevAbilitySelectRight = selectRightNow;
255
256 const bool grenadeKeyNow = bindings.pressed(Action::CycleGrenade, kKeys, mouse);
257 if (grenadeKeyNow) {
258 if (!prevGrenadeKey) {
259 grenadeHeldSeconds = 0.0f;
260 grenadeRadialActive = false;
261 grenadeRadialAim = glm::vec2{0.0f, -1.0f};
262 } else {
263 grenadeHeldSeconds += dt;
264 }
265
267 grenadeRadialActive = true;
268 }
269 } else if (prevGrenadeKey) {
270 if (!grenadeRadialActive) {
271 pendingGrenadeThrow = true;
272 }
273 grenadeHeldSeconds = 0.0f;
274 grenadeRadialActive = false;
275 }
276 prevGrenadeKey = grenadeKeyNow;
277 const std::uint8_t grenadeSelectIndex =
279
280 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
281 snap.shooting = shootDown && !abilityMenuHeld;
282 snap.scoped = scopeDown && !abilityMenuHeld;
283 snap.switchToPrimary = bindings.pressed(Action::SwitchToPrimary, kKeys, mouse);
284 snap.switchToSecondary = bindings.pressed(Action::SwitchToSecondary, kKeys, mouse);
285 snap.throwGrenade = false;
287 snap.grenadeSelectIndex = grenadeSelectIndex;
288 snap.reload = bindings.pressed(Action::Reload, kKeys, mouse);
289 snap.pickup = bindings.pressed(Action::Pickup, kKeys, mouse);
290 snap.abilitySelectHeld = abilityMenuHeld;
291 snap.abilitySelectLeft = selectLeftEdge;
292 snap.abilitySelectRight = selectRightEdge;
293 });
294}
295
299inline void runInputSample(Registry& registry, const InputBindings& bindings, float mouseSensitivity = 0.001f)
300{
301 runMouseLook(registry, mouseSensitivity);
302 runMovementKeys(registry, bindings);
303 runWeaponKeys(registry, bindings);
304}
305
306// ─── Gamepad samplers ────────────────────────────────────────────────────────
307//
308// Mirror the keyboard/mouse pipeline so a controller can drive every action a
309// PC player has access to. SDL3's gamepad API gives us a standardised
310// abstract layout (Xbox 360 / One, DualShock, Switch Pro, etc. all map onto
311// the same buttons/axes) so a single mapping serves "all controllers behave
312// the same way". Tested on Xbox 360.
313//
314// Gamepad samplers OR their state into the InputSnapshot fields that the
315// keyboard samplers already populated, so a player can use kbm and pad
316// simultaneously without one stomping the other. The look sampler ADDs to
317// yaw/pitch the same way mouse delta does, so the two compose cleanly.
318
319namespace gamepad
320{
321
327inline constexpr float k_stickDeadzone = 0.15f;
328
333inline constexpr float k_triggerThreshold = 0.5f;
334
339inline float normaliseAxis(Sint16 raw, float deadzone = k_stickDeadzone)
340{
341 // SDL_Gamepad axes are int16; normalise to [-1, 1]. -32768 is one larger
342 // in magnitude than 32767 — divide by 32767 and clamp to keep the range
343 // symmetric (otherwise full-down on a stick reads as -1.0000305...).
344 const float v = std::clamp(static_cast<float>(raw) / 32767.0f, -1.0f, 1.0f);
345 if (std::fabs(v) < deadzone)
346 return 0.0f;
347 // Rescale [deadzone, 1] → [0, 1] so the user gets the full output range.
348 const float sign = v < 0.0f ? -1.0f : 1.0f;
349 return sign * (std::fabs(v) - deadzone) / (1.0f - deadzone);
350}
351
352} // namespace gamepad
353
371inline void runGamepadLook(Registry& registry,
372 SDL_Gamepad* gamepad,
373 float pitchSensitivity,
374 float yawSensitivity,
375 float deadzone,
376 float dt,
377 bool gravityFlipped = false,
378 bool swapSticks = false)
379{
381 return;
382
383 JoystickAxis lookAxis = getLookJoystickAxes(swapSticks);
384
385 float rx = gamepad::normaliseAxis(SDL_GetGamepadAxis(gamepad, lookAxis.x), deadzone);
386 float ry = gamepad::normaliseAxis(SDL_GetGamepadAxis(gamepad, lookAxis.y), deadzone);
387
388 if (rx == 0.0f && ry == 0.0f)
389 return;
390
391 if (gravityFlipped) {
392 rx = -rx;
393 ry = -ry;
394 }
395
396 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
397 // Sign convention matches runMouseLook: stick-right (positive rx)
398 // should look right, which means yaw decreases (see runMouseLook
399 // comment for why the negation is correct).
400 snap.yaw -= rx * yawSensitivity * dt;
401 snap.yaw = std::remainder(snap.yaw, glm::radians(360.0f));
402
403 // SDL gamepad Y axis is +down/-up (screen-coord convention) — same as
404 // mouse mdy — so adding directly matches mouse-down = pitch+ behaviour.
405 snap.pitch = std::clamp(snap.pitch + ry * pitchSensitivity * dt, -glm::radians(89.0f), glm::radians(89.0f));
406 });
407}
408
426inline void runGamepadMovement(Registry& registry,
427 SDL_Gamepad* gamepad,
428 const InputBindings& bindings,
429 float deadzone,
430 bool gravityFlipped = false,
431 bool swapSticks = false)
432{
434 return;
435
436 JoystickAxis moveAxis = getMoveJoystickAxes(swapSticks);
437
438 const float lx = gamepad::normaliseAxis(SDL_GetGamepadAxis(gamepad, moveAxis.x), deadzone);
439 const float ly = gamepad::normaliseAxis(SDL_GetGamepadAxis(gamepad, moveAxis.y), deadzone);
440
441 // Movement booleans are derived from a stronger threshold than the deadzone
442 // so a player resting their thumb on the stick doesn't drift-walk. 0.3 is
443 // ~tip pressure on a 360 stick.
444 constexpr float moveThresh = 0.3f;
445 const bool padForward = ly < -moveThresh; // stick-up = -Y in SDL
446 const bool padBack = ly > moveThresh;
447 // Swap left/right when gravity is flipped (same reasoning as keyboard).
448 const bool padLeft = gravityFlipped ? (lx > moveThresh) : (lx < -moveThresh);
449 const bool padRight = gravityFlipped ? (lx < -moveThresh) : (lx > moveThresh);
450
451 const bool padJump = bindings.controllerPressed(Action::Jump, gamepad);
452 const bool padCrouch = bindings.controllerPressed(Action::Crouch, gamepad);
453 const bool padAbility1 = bindings.controllerPressed(Action::Ability1, gamepad);
454 const bool padAbility2 = bindings.controllerPressed(Action::Ability2, gamepad);
455
456 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
457 snap.forward |= padForward;
458 snap.back |= padBack;
459 snap.left |= padLeft;
460 snap.right |= padRight;
461 snap.jump |= padJump;
462 snap.crouch |= padCrouch;
463 snap.ability1 |= padAbility1;
464 snap.ability2 |= padAbility2;
465 });
466}
467
478inline void runGamepadWeapon(Registry& registry, SDL_Gamepad* gamepad, const InputBindings& bindings)
479{
481 return;
482
483 const bool abilityMenuHeld = bindings.controllerPressed(Action::AbilityMenu, gamepad);
484 const bool padShoot = bindings.controllerPressed(Action::Shoot, gamepad);
485 const bool padScope = bindings.controllerPressed(Action::Scope, gamepad);
486 const bool padReload = bindings.controllerPressed(Action::Reload, gamepad);
487 const bool padPickup = bindings.controllerPressed(Action::Pickup, gamepad);
488 const bool padPrimary = bindings.controllerPressed(Action::SwitchToPrimary, gamepad);
489 const bool padSecondary = bindings.controllerPressed(Action::SwitchToSecondary, gamepad);
490 const bool padCycleGrenade = bindings.controllerPressed(Action::CycleGrenade, gamepad);
491 const bool selectLeftNow = abilityMenuHeld && padShoot;
492 const bool selectRightNow = abilityMenuHeld && padScope;
493 const bool selectLeftEdge = selectLeftNow && !prevGamepadAbilitySelectLeft;
494 const bool selectRightEdge = selectRightNow && !prevGamepadAbilitySelectRight;
495 prevGamepadAbilitySelectLeft = selectLeftNow;
496 prevGamepadAbilitySelectRight = selectRightNow;
497
498 registry.view<InputSnapshot, LocalPlayer, Controllable>().each([&](InputSnapshot& snap) {
499 snap.shooting |= padShoot && !abilityMenuHeld;
500 snap.scoped |= padScope && !abilityMenuHeld;
501 snap.reload |= padReload;
502 snap.pickup |= padPickup;
503 snap.switchToPrimary |= padPrimary;
504 snap.switchToSecondary |= padSecondary;
505 snap.grenadeMenuHeld |= padCycleGrenade;
506 snap.abilitySelectHeld |= abilityMenuHeld;
507 snap.abilitySelectLeft |= selectLeftEdge;
508 snap.abilitySelectRight |= selectRightEdge;
509 });
510}
511
516inline void runGamepadDeadInput(Registry& registry, SDL_Gamepad* gamepad, const InputBindings& bindings)
517{
519 return;
520 const bool skipRespawn = bindings.controllerPressed(Action::Jump, gamepad);
521 registry.view<InputSnapshot, LocalPlayer, RespawnTimer>().each(
522 [&](InputSnapshot& snap, const RespawnTimer& /*unused*/) { snap.skipRespawn = skipRespawn; });
523}
524
525} // namespace systems
Client side Tag component — entity is eligible to receive player input.
@ Back
Move backward.
Definition InputBindings.hpp:18
@ Jump
Jump and skip respawn while dead.
Definition InputBindings.hpp:21
@ SwitchToSecondary
Switch to the secondary weapon slot.
Definition InputBindings.hpp:31
@ AbilityMenu
Open the ability selection radial menu.
Definition InputBindings.hpp:23
@ Crouch
Crouch and slide.
Definition InputBindings.hpp:22
@ Reload
Reload the equipped weapon.
Definition InputBindings.hpp:28
@ Scope
Aim/scope the equipped weapon.
Definition InputBindings.hpp:27
@ Forward
Move forward.
Definition InputBindings.hpp:17
@ Ability1
Activate the first ability slot.
Definition InputBindings.hpp:24
@ Ability2
Activate the second ability slot.
Definition InputBindings.hpp:25
@ Right
Strafe right.
Definition InputBindings.hpp:20
@ Left
Strafe left.
Definition InputBindings.hpp:19
@ Pickup
Pick up an interactable weapon or item.
Definition InputBindings.hpp:29
@ CycleGrenade
Quick-throw or open the grenade radial menu.
Definition InputBindings.hpp:34
@ KillSelf
Request self-elimination.
Definition InputBindings.hpp:35
@ SwitchToPrimary
Switch to the primary weapon slot.
Definition InputBindings.hpp:30
@ Shoot
Fire the equipped weapon.
Definition InputBindings.hpp:26
Per-tick player input snapshot for networking and prediction.
constexpr std::uint8_t kInvalidGrenadeSelectIndex
Definition InputSnapshot.hpp:8
Marker component identifying the locally controlled player entity.
Shared ECS registry type alias for the game engine.
entt::registry Registry
Shared ECS registry type alias.
Definition Registry.hpp:11
Component for tracking player respawn times.
Stores action-to-input bindings and helper conversions for UI and persistence.
Definition InputBindings.hpp:127
bool pressed(Action a, const bool *keyStates, SDL_MouseButtonFlags mouseState) const
Test whether an action is currently pressed using SDL keyboard and mouse state.
Definition InputBindings.cpp:261
bool controllerPressed(Action a, SDL_Gamepad *gamepad) const
Test whether an action is currently pressed on a controller.
Definition InputBindings.cpp:272
Definition InputSampleSystem.hpp:320
constexpr float k_stickDeadzone
Stick deadzone as a fraction of full deflection.
Definition InputSampleSystem.hpp:327
float normaliseAxis(Sint16 raw, float deadzone=k_stickDeadzone)
Convert SDL's int16 axis value to a deadzoned float in [-1, 1].
Definition InputSampleSystem.hpp:339
constexpr float k_triggerThreshold
Trigger threshold for treating an analog trigger as "pressed".
Definition InputSampleSystem.hpp:333
Client-only input sampling system — split into two halves so mouse look can run every iterate() (smoo...
Definition DebugUI.hpp:15
void runGamepadLook(Registry &registry, SDL_Gamepad *gamepad, float pitchSensitivity, float yawSensitivity, float deadzone, float dt, bool gravityFlipped=false, bool swapSticks=false)
Sample the right stick into yaw / pitch.
Definition InputSampleSystem.hpp:371
float grenadeHeldSeconds
Seconds the grenade key has been continuously held.
Definition InputSampleSystem.hpp:32
bool prevGrenadeKey
Tracks previous-frame G key state for grenade quick-throw / radial behavior.
Definition InputSampleSystem.hpp:30
void runGamepadDeadInput(Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings)
Sample controller skip-respawn input while the local player is dead.
Definition InputSampleSystem.hpp:516
constexpr float k_grenadeRadialHoldSeconds
Hold duration before the grenade quick-throw becomes radial selection.
Definition InputSampleSystem.hpp:40
void runGamepadMovement(Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings, float deadzone, bool gravityFlipped=false, bool swapSticks=false)
Sample gamepad buttons / left stick into the movement flags.
Definition InputSampleSystem.hpp:426
bool consumePendingGrenadeThrow()
Consume and clear the queued grenade quick-throw request.
Definition InputSampleSystem.hpp:113
JoystickAxis getMoveJoystickAxes(bool swapSticks)
Return the SDL axes used for movement, honoring the stick-swap setting.
Definition InputSampleSystem.hpp:71
bool prevGamepadAbilitySelectRight
Tracks previous-frame gamepad right ability-select chord for edge detection.
Definition InputSampleSystem.hpp:52
void runMouseLook(Registry &registry, float mouseSensitivity, bool gravityFlipped=false)
Sample mouse delta and accumulate into yaw / pitch.
Definition InputSampleSystem.hpp:133
void runMovementKeys(Registry &registry, const InputBindings &bindings, bool gravityFlipped=false)
Sample keyboard state into the movement flags.
Definition InputSampleSystem.hpp:181
bool grenadeRadialActive
True while the grenade radial selector is open.
Definition InputSampleSystem.hpp:34
std::uint8_t grenadeRadialIndexFromAim()
Convert the current grenade radial aim vector into a grenade slot index.
Definition InputSampleSystem.hpp:87
void runInputSample(Registry &registry, const InputBindings &bindings, float mouseSensitivity=0.001f)
Legacy combined sampler — calls both runMouseLook and runMovementKeys.
Definition InputSampleSystem.hpp:299
bool prevGamepadAbilitySelectLeft
Tracks previous-frame gamepad left ability-select chord for edge detection.
Definition InputSampleSystem.hpp:50
JoystickAxis getLookJoystickAxes(bool swapSticks)
Return the SDL axes used for camera look, honoring the stick-swap setting.
Definition InputSampleSystem.hpp:62
void runWeaponKeys(Registry &registry, const InputBindings &bindings, float dt=0.0f)
Sample keyboard state into the weapon flags.
Definition InputSampleSystem.hpp:242
void runGamepadWeapon(Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings)
Sample gamepad buttons / right trigger into the weapon flags.
Definition InputSampleSystem.hpp:478
constexpr float k_grenadeRadialDeadzone
Minimum radial aim distance required to choose a grenade slot.
Definition InputSampleSystem.hpp:42
bool gamepadConnected(SDL_Gamepad *gamepad)
True when a gamepad handle is non-null and still connected.
Definition InputSampleSystem.hpp:80
bool pendingGrenadeThrow
Latched quick-throw request consumed by HUD/gameplay code.
Definition InputSampleSystem.hpp:38
bool prevAbilitySelectRight
Tracks previous-frame Alt+RMB state for ability choice edge detection.
Definition InputSampleSystem.hpp:48
glm::vec2 grenadeRadialAim
Current mouse-relative aim vector inside the grenade radial selector.
Definition InputSampleSystem.hpp:36
bool prevAbilitySelectLeft
Tracks previous-frame Alt+LMB state for ability choice edge detection.
Definition InputSampleSystem.hpp:46
constexpr float k_grenadeRadialMaxDistance
Maximum stored cursor distance from the grenade radial center.
Definition InputSampleSystem.hpp:44
bool prevKillSelfKey
Tracks previous-frame key state for edge detection.
Definition InputSampleSystem.hpp:28
void runDeadInput(Registry &registry, const InputBindings &bindings)
Sample skip-respawn input while the local player is dead.
Definition InputSampleSystem.hpp:222
Client side Tag component — entity is eligible to receive player input.
Definition Controllable.hpp:9
One tick of player input, stamped with the tick it was sampled on.
Definition InputSnapshot.hpp:19
bool switchToSecondary
Switch to gun in secondary slot.
Definition InputSnapshot.hpp:36
bool pickup
Pick Up button (f).
Definition InputSnapshot.hpp:34
bool killSelf
Debug: kill self (rising-edge only).
Definition InputSnapshot.hpp:38
bool switchToPrimary
Switch to gun in primary slot.
Definition InputSnapshot.hpp:35
bool jump
Space key.
Definition InputSnapshot.hpp:27
bool ability2
Activate ability 2.
Definition InputSnapshot.hpp:44
bool throwGrenade
Quick G press: throw the selected grenade.
Definition InputSnapshot.hpp:40
bool abilitySelectRight
Choose the right pending ability option (edge-triggered).
Definition InputSnapshot.hpp:47
bool ability1
Activate ability 1.
Definition InputSnapshot.hpp:43
bool abilitySelectLeft
Choose the left pending ability option (edge-triggered).
Definition InputSnapshot.hpp:46
bool skipRespawn
Skip respawn timer (space while dead).
Definition InputSnapshot.hpp:39
bool right
D key.
Definition InputSnapshot.hpp:26
bool forward
W key.
Definition InputSnapshot.hpp:23
bool left
A key.
Definition InputSnapshot.hpp:25
bool reload
Reload button.
Definition InputSnapshot.hpp:33
float yaw
Horizontal look angle in radians (accumulated from mouse X deltas).
Definition InputSnapshot.hpp:50
bool scoped
Right click.
Definition InputSnapshot.hpp:32
bool crouch
Left Ctrl key.
Definition InputSnapshot.hpp:28
bool shooting
Primary fire button.
Definition InputSnapshot.hpp:31
float pitch
Vertical look angle in radians, clamped to [-89°, +89°] by InputSampleSystem.
Definition InputSnapshot.hpp:51
bool grenadeMenuHeld
True while the held-G radial menu is open.
Definition InputSnapshot.hpp:41
std::uint8_t grenadeSelectIndex
Hovered radial grenade index, or invalid.
Definition InputSnapshot.hpp:42
bool back
S key.
Definition InputSnapshot.hpp:24
bool abilitySelectHeld
True while holding the ability-selection modifier.
Definition InputSnapshot.hpp:45
Marker component that tags exactly one entity per client as the locally controlled player.
Definition LocalPlayer.hpp:12
ECS component: countdown until a dead player respawns.
Definition RespawnTimer.hpp:10
Gamepad axis mapping configuration for look and move axes, used to support stick swapping in user set...
Definition InputSampleSystem.hpp:56
SDL_GamepadAxis x
Definition InputSampleSystem.hpp:57
SDL_GamepadAxis y
Definition InputSampleSystem.hpp:58