Multi-controller support

This commit is contained in:
Gordon Weeks 2026-01-31 01:01:20 -08:00
parent 54319aa49c
commit 93fb826893

View File

@ -1,6 +1,8 @@
/**
* DDR / Guitar Hero style rhythm game: 12 lanes, pre-coded notes, controller support.
* DDR / Guitar Hero style rhythm game: 12 lanes, pre-coded notes.
* Supports multiple controllers: any connected gamepad can hit notes (shared chart/score).
* Controller: D-pad (lanes 0-3), face X/Y/A/B (4-7), LB/LT/RB/RT (8-11). 8bitdo compatible.
* Keyboard (Q/W/E/R/A/S/D/F/Z/X/C/V) remains supported.
*/
#pragma once
@ -13,6 +15,7 @@
namespace
{
constexpr int LANE_COUNT = 12;
constexpr int MAX_GAMEPADS = 4;
constexpr float HIT_WINDOW_PX = 80.0f;
constexpr float RECEPTOR_HEIGHT = 100.0f;
constexpr float SCROLL_PX_PER_SEC = 350.0f;
@ -123,7 +126,6 @@ public:
float lane_width = 0.0f;
float screen_width = 0.0f;
float screen_height = 0.0f;
int gamepad_id = 0;
Sound note_sounds[LANE_COUNT] = {0};
bool note_sounds_loaded[LANE_COUNT] = {false};
static constexpr float PRESS_FLASH_DURATION = 0.12f;
@ -211,6 +213,38 @@ public:
return (lane + 0.5f) * lane_width;
}
bool is_lane_pressed(int lane) const
{
if (IsKeyPressed(KEY_KEYS[lane]))
{
return true;
}
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (IsGamepadAvailable(i) && IsGamepadButtonPressed(i, GAMEPAD_BUTTONS[lane]))
{
return true;
}
}
return false;
}
bool is_menu_pressed() const
{
if (IsKeyPressed(KEY_ENTER))
{
return true;
}
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (IsGamepadAvailable(i) && IsGamepadButtonPressed(i, GAMEPAD_BUTTON_MIDDLE_RIGHT))
{
return true;
}
}
return false;
}
bool is_note_hittable(const Glyph& n) const
{
float y = n.y_position(song_time, hit_line_y);
@ -234,7 +268,7 @@ public:
{
if (game_ended)
{
if (IsKeyPressed(KEY_ENTER) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_MIDDLE_RIGHT))
if (is_menu_pressed())
{
game->go_to_scene("title");
}
@ -315,8 +349,7 @@ public:
{
miss_flash_timer[lane] = 0.0f;
}
bool pressed = IsKeyPressed(KEY_KEYS[lane]) ||
IsGamepadButtonPressed(gamepad_id, GAMEPAD_BUTTONS[lane]);
bool pressed = is_lane_pressed(lane);
if (pressed)
{
press_flash_timer[lane] = PRESS_FLASH_DURATION;
@ -355,7 +388,7 @@ public:
}
}
if (IsKeyPressed(KEY_ENTER) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_MIDDLE_RIGHT))
if (is_menu_pressed())
{
game->go_to_scene("title");
}