From f6d2f78121845a1571881d0b19eb42cd78823456 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sat, 3 Jan 2026 12:46:33 -0600 Subject: [PATCH 01/21] Setup Phase Evasion state machine --- include/engine/system-config.h | 4 +-- .../games/phase-evasion/phase-evasion-core.h | 1 + .../games/phase-evasion/phase-evasion-state.h | 9 +++++- include/games/recall/recall-state.h | 4 +-- .../phase-evasion/phase-evasion-core.cpp | 16 +++++++++- src/games/recall/recall-core.cpp | 30 +++++++++---------- 6 files changed, 43 insertions(+), 21 deletions(-) diff --git a/include/engine/system-config.h b/include/engine/system-config.h index 80f83ea..e84c291 100644 --- a/include/engine/system-config.h +++ b/include/engine/system-config.h @@ -8,9 +8,9 @@ namespace Engine { // REQUIRED: modify this address to match the mac address of your PS3 controller static constexpr char macAddress[] = "00:1b:fb:8e:87:ac"; - static constexpr uint16_t numLeds = 327; + static constexpr uint16_t numLeds = 300; static constexpr uint32_t serialBaud = 921600; - static constexpr uint16_t recallBoundaries[4] = {0, 113, 168, 281}; + static constexpr uint16_t recallBoundaries[4] = {0, 112, 150, 262}; static constexpr uint8_t ledDimmerGpio = 34; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 4982ec8..32bea75 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -15,6 +15,7 @@ namespace Games private: Core::ContextManager *contextManager; + PhaseEvasionGameState &state = contextManager->stateManager.getPhaseEvasionGameState(); PhaseEvasionPlayer player; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-state.h b/include/games/phase-evasion/phase-evasion-state.h index 7fc2446..b962a9a 100644 --- a/include/games/phase-evasion/phase-evasion-state.h +++ b/include/games/phase-evasion/phase-evasion-state.h @@ -4,12 +4,19 @@ namespace Games { + enum class PhaseEvasionStates + { + Startup, + ActiveGame + }; + class PhaseEvasionGameState { public: PhaseEvasionGameState() : highScore{0}, spectersDodged{0} {} - void reset() { highScore = spectersDodged = 0; } uint16_t highScore; uint16_t spectersDodged; + PhaseEvasionStates current = PhaseEvasionStates::Startup; + void reset() { highScore = spectersDodged = 0; } }; } \ No newline at end of file diff --git a/include/games/recall/recall-state.h b/include/games/recall/recall-state.h index 3602a56..c87fa1a 100644 --- a/include/games/recall/recall-state.h +++ b/include/games/recall/recall-state.h @@ -4,7 +4,7 @@ namespace Games { - enum class GameState + enum class RecallStates { Startup, ComputerPlaybackOnDisplay, @@ -20,7 +20,7 @@ namespace Games RecallGameState() : highScore{0}, round{0} {} uint16_t highScore; uint16_t round; - GameState current = GameState::Startup; + RecallStates current = RecallStates::Startup; void reset() { highScore = round = 0; } }; diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index fe86d11..ae404e7 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -4,10 +4,24 @@ namespace Games { PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, player{PhaseEvasionPlayer{contextManager}} { - contextManager->stateManager.getPhaseEvasionGameState().reset(); + state = contextManager->stateManager.getPhaseEvasionGameState(); + state.reset(); + state.current = PhaseEvasionStates::Startup; + wait(500); } void PhaseEvasionCore::nextEvent() { + switch (state.current) + { + case PhaseEvasionStates::Startup: + if (isReady()) + { + state.current = PhaseEvasionStates::ActiveGame; + } + break; + case PhaseEvasionStates::ActiveGame: + break; + } } } \ No newline at end of file diff --git a/src/games/recall/recall-core.cpp b/src/games/recall/recall-core.cpp index 82a9fff..e362175 100644 --- a/src/games/recall/recall-core.cpp +++ b/src/games/recall/recall-core.cpp @@ -11,7 +11,7 @@ namespace Games setupGameColors(); state = contextManager->stateManager.getRecallGameState(); state.reset(); - state.current = GameState::Startup; + state.current = RecallStates::Startup; wait(gameplaySpeedIlluminated); } @@ -36,26 +36,26 @@ namespace Games handleUserSpeedChange(); switch (state.current) { - case GameState::Startup: + case RecallStates::Startup: if (isReady()) { - state.current = GameState::ComputerPlaybackOnDisplay; + state.current = RecallStates::ComputerPlaybackOnDisplay; wait(gameplaySpeedIlluminated); } break; - case GameState::ComputerPlaybackOnDisplay: + case RecallStates::ComputerPlaybackOnDisplay: displayComputerPlayback(); break; - case GameState::ComputerPlaybackPaused: + case RecallStates::ComputerPlaybackPaused: pauseComputerPlayback(); break; - case GameState::PlayerResponseEvaluation: + case RecallStates::PlayerResponseEvaluation: evaluateUserRecall(); break; - case GameState::PlayerResponseVerified: + case RecallStates::PlayerResponseVerified: prepareComputerPlayback(); break; - case GameState::GameOver: + case RecallStates::GameOver: gameOver(); break; } @@ -81,7 +81,7 @@ namespace Games { if (isReady()) { - state.current = GameState::ComputerPlaybackPaused; + state.current = RecallStates::ComputerPlaybackPaused; wait(gameplaySpeedPaused); return; } @@ -108,7 +108,7 @@ namespace Games { if (sequenceIndex >= state.round) { - state.current = GameState::PlayerResponseEvaluation; + state.current = RecallStates::PlayerResponseEvaluation; sequenceIndex = 0; contextManager->controller.reset(); successFadeawayAnimation = 1; @@ -119,7 +119,7 @@ namespace Games if (isReady()) { ++sequenceIndex; - state.current = GameState::ComputerPlaybackOnDisplay; + state.current = RecallStates::ComputerPlaybackOnDisplay; wait(gameplaySpeedIlluminated); } } @@ -128,7 +128,7 @@ namespace Games { if (sequenceIndex > state.round && isReady()) { - state.current = GameState::PlayerResponseVerified; + state.current = RecallStates::PlayerResponseVerified; ++state.round; contextManager->stateManager.displayShouldUpdate = true; contextManager->controller.reset(); @@ -156,7 +156,7 @@ namespace Games } logf("User provided the incorrect answer. Entering game over sequence."); - state.current = GameState::GameOver; + state.current = RecallStates::GameOver; } } } @@ -220,7 +220,7 @@ namespace Games auto &color = colorPalette[static_cast(button)]; logf(" Color=%u (%u - %u - %u)", button, color.r, color.g, color.b); } - state.current = GameState::ComputerPlaybackOnDisplay; + state.current = RecallStates::ComputerPlaybackOnDisplay; sequenceIndex = 0; wait(gameplaySpeedIlluminated); return; @@ -239,7 +239,7 @@ namespace Games { if (contextManager->controller.wasPressed(Player::ControllerButton::Start)) { - state.current = GameState::Startup; + state.current = RecallStates::Startup; sequenceIndex = 0; state.reset(); contextManager->stateManager.getRecallGameState().reset(); From 0ee720ad744e86256fe48327eb83d6060e5bb401 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sat, 10 Jan 2026 14:19:57 -0600 Subject: [PATCH 02/21] Render user color --- .../games/phase-evasion/phase-evasion-core.h | 5 ++++ .../phase-evasion/phase-evasion-player.h | 14 ++++++++- include/lights/color.h | 10 +++---- .../phase-evasion/phase-evasion-core.cpp | 12 ++++++++ .../phase-evasion/phase-evasion-player.cpp | 29 +++++++++++++++++++ 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/games/phase-evasion/phase-evasion-player.cpp diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 32bea75..7d93209 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -4,6 +4,7 @@ #include "engine/timer.h" #include "core/context-manager.h" #include "games/phase-evasion/phase-evasion-player.h" +#include "games/phase-evasion/phase-evasion-flare.h" namespace Games { @@ -17,5 +18,9 @@ namespace Games Core::ContextManager *contextManager; PhaseEvasionGameState &state = contextManager->stateManager.getPhaseEvasionGameState(); PhaseEvasionPlayer player; + PhaseEvasionFlare flare; + void renderUserColor(); + + static constexpr uint16_t playerWidth = 7; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-player.h b/include/games/phase-evasion/phase-evasion-player.h index 71cae00..9bb0317 100644 --- a/include/games/phase-evasion/phase-evasion-player.h +++ b/include/games/phase-evasion/phase-evasion-player.h @@ -9,9 +9,21 @@ namespace Games { public: PhaseEvasionPlayer(Core::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; + void checkColorChangeRequest(); + Lights::Color getColor() { return currentColor; } private: Core::ContextManager *contextManager; - static constexpr uint16_t width = 7; + Lights::Color currentColor; + static constexpr ::Player::ControllerButton availableGameplayButtons[] = { + ::Player::ControllerButton::Cross, + ::Player::ControllerButton::Square, + ::Player::ControllerButton::Triangle, + ::Player::ControllerButton::Circle}; + Lights::Color colorPalette[4] = { + {Lights::ColorCode::GameBlue}, // ✕ blue + {Lights::ColorCode::GameRed}, // ◯ red + {Lights::ColorCode::GameGreen}, // △ green + {Lights::ColorCode::GameYellow}}; // □ yellow }; } \ No newline at end of file diff --git a/include/lights/color.h b/include/lights/color.h index c1585b2..76e1148 100644 --- a/include/lights/color.h +++ b/include/lights/color.h @@ -15,7 +15,7 @@ namespace Lights Color(uint8_t red, uint8_t green, uint8_t blue) : CRGB(red, green, blue) {} Color(ColorCode color) : CRGB{static_cast(color)} {} - Lights::Color operator*(double scale) const + Color operator*(double scale) const { Color result; result.r = static_cast(std::clamp(r * scale, 0.0, 255.0)); @@ -24,7 +24,7 @@ namespace Lights return result; } - Lights::Color operator*(uint8_t scale) const + Color operator*(uint8_t scale) const { Color result; result.r = (r * scale) / 255; @@ -33,7 +33,7 @@ namespace Lights return result; } - Lights::Color operator/(double scale) const + Color operator/(double scale) const { Color result; result.r = static_cast(std::clamp(r / scale, 0.0, 255.0)); @@ -42,7 +42,7 @@ namespace Lights return result; } - Lights::Color operator/(uint8_t scale) const + Color operator/(uint8_t scale) const { Color result; result.r = (r / scale) / 255; @@ -51,7 +51,7 @@ namespace Lights return result; } - Lights::Color &operator*=(double scale) + Color &operator*=(double scale) { r = static_cast(std::clamp(r * scale, 0.0, 255.0)); g = static_cast(std::clamp(g * scale, 0.0, 255.0)); diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index ae404e7..001535c 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -1,4 +1,5 @@ #include "games/phase-evasion/phase-evasion-core.h" +#include "logger.h" namespace Games { @@ -18,10 +19,21 @@ namespace Games if (isReady()) { state.current = PhaseEvasionStates::ActiveGame; + log("Starting new game."); } break; case PhaseEvasionStates::ActiveGame: + player.checkColorChangeRequest(); + renderUserColor(); break; } } + + void PhaseEvasionCore::renderUserColor() + { + for (uint16_t i = 1; i < 8; ++i) + { + contextManager->leds.buffer[i] = player.getColor(); + } + } } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-player.cpp b/src/games/phase-evasion/phase-evasion-player.cpp new file mode 100644 index 0000000..2381083 --- /dev/null +++ b/src/games/phase-evasion/phase-evasion-player.cpp @@ -0,0 +1,29 @@ +#include "games/phase-evasion/phase-evasion-player.h" +#include "logger.h" + +namespace Games +{ + void PhaseEvasionPlayer::checkColorChangeRequest() + { + for (auto button : availableGameplayButtons) + { + if (contextManager->controller.isDown(button)) + { +#ifdef DEBUG + if (currentColor != colorPalette[static_cast(button)]) + { + auto c = colorPalette[static_cast(button)]; + logf("User pressed color=%u (%u - %u - %u)", button, c.r, c.g, c.b); + } +#endif + currentColor = colorPalette[static_cast(button)]; + return; + } + } + if (currentColor != Lights::Color::SlateGray) + { + log("User returned color to neutral."); + currentColor = Lights::Color::SlateGray; + } + } +} \ No newline at end of file From 0e0bd3d0030d9770b3c5fc9d9328b7864254839e Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sun, 11 Jan 2026 20:59:23 -0600 Subject: [PATCH 03/21] Setup flare and position updating --- include/engine/system-config.h | 4 ++-- .../games/phase-evasion/phase-evasion-core.h | 5 +++-- .../games/phase-evasion/phase-evasion-flare.h | 17 +++++++++----- .../phase-evasion/phase-evasion-player.h | 1 + .../games/phase-evasion/phase-evasion-state.h | 3 ++- .../phase-evasion/phase-evasion-core.cpp | 22 +++++++++++++++++-- .../phase-evasion/phase-evasion-flare.cpp | 13 +++++++++++ .../phase-evasion/phase-evasion-player.cpp | 4 ++-- 8 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 src/games/phase-evasion/phase-evasion-flare.cpp diff --git a/include/engine/system-config.h b/include/engine/system-config.h index e84c291..80f83ea 100644 --- a/include/engine/system-config.h +++ b/include/engine/system-config.h @@ -8,9 +8,9 @@ namespace Engine { // REQUIRED: modify this address to match the mac address of your PS3 controller static constexpr char macAddress[] = "00:1b:fb:8e:87:ac"; - static constexpr uint16_t numLeds = 300; + static constexpr uint16_t numLeds = 327; static constexpr uint32_t serialBaud = 921600; - static constexpr uint16_t recallBoundaries[4] = {0, 112, 150, 262}; + static constexpr uint16_t recallBoundaries[4] = {0, 113, 168, 281}; static constexpr uint8_t ledDimmerGpio = 34; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 7d93209..d77c21e 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -13,6 +13,7 @@ namespace Games public: PhaseEvasionCore(Core::ContextManager *ctx); void nextEvent() override; + static constexpr uint16_t clearance = 15; private: Core::ContextManager *contextManager; @@ -20,7 +21,7 @@ namespace Games PhaseEvasionPlayer player; PhaseEvasionFlare flare; void renderUserColor(); - - static constexpr uint16_t playerWidth = 7; + void renderFlare(); + void checkCollision(); }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index d0c787b..5099b33 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -1,18 +1,25 @@ #pragma once +#include "engine/timer.h" +#include "core/context-manager.h" #include "lights/color-code.h" namespace Games { - class PhaseEvasionFlare + class PhaseEvasionFlare : public Engine::Timer { public: - PhaseEvasionFlare() - { - color = Lights::ColorCode::MenuLightBlue; - }; + PhaseEvasionFlare(Core::ContextManager *ctx) : contextManager{ctx}, + color{Lights::ColorCode::MenuLightBlue}, + position{ctx->config.numLeds + width} {} + + static constexpr uint16_t width = 10; + void updatePosition(); + uint16_t getPosition() { return position; } private: + Core::ContextManager *contextManager; Lights::ColorCode color; + uint16_t position; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-player.h b/include/games/phase-evasion/phase-evasion-player.h index 9bb0317..f099884 100644 --- a/include/games/phase-evasion/phase-evasion-player.h +++ b/include/games/phase-evasion/phase-evasion-player.h @@ -11,6 +11,7 @@ namespace Games PhaseEvasionPlayer(Core::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; void checkColorChangeRequest(); Lights::Color getColor() { return currentColor; } + static constexpr uint16_t width = 10; private: Core::ContextManager *contextManager; diff --git a/include/games/phase-evasion/phase-evasion-state.h b/include/games/phase-evasion/phase-evasion-state.h index b962a9a..cfdb320 100644 --- a/include/games/phase-evasion/phase-evasion-state.h +++ b/include/games/phase-evasion/phase-evasion-state.h @@ -7,7 +7,8 @@ namespace Games enum class PhaseEvasionStates { Startup, - ActiveGame + ActiveGame, + GameOver }; class PhaseEvasionGameState diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 001535c..703ef60 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -3,7 +3,9 @@ namespace Games { - PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, player{PhaseEvasionPlayer{contextManager}} + PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, + player{ctx}, + flare{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); @@ -24,6 +26,9 @@ namespace Games break; case PhaseEvasionStates::ActiveGame: player.checkColorChangeRequest(); + flare.updatePosition(); + checkCollision(); + renderFlare(); renderUserColor(); break; } @@ -31,9 +36,22 @@ namespace Games void PhaseEvasionCore::renderUserColor() { - for (uint16_t i = 1; i < 8; ++i) + for (uint16_t i = clearance; i < clearance + player.width; ++i) { contextManager->leds.buffer[i] = player.getColor(); } } + + void PhaseEvasionCore::renderFlare() + { + for (uint16_t i = flare.getPosition() - flare.width; i < flare.getPosition(); ++i) + { + contextManager->leds.buffer[i] = Lights::ColorCode::GameRed; + } + } + + void PhaseEvasionCore::checkCollision() + { + // if () + } } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/phase-evasion-flare.cpp new file mode 100644 index 0000000..2caf4a1 --- /dev/null +++ b/src/games/phase-evasion/phase-evasion-flare.cpp @@ -0,0 +1,13 @@ +#include "games/phase-evasion/phase-evasion-flare.h" + +namespace Games +{ + void PhaseEvasionFlare::updatePosition() + { + if (isReady()) + { + --position; + wait(20); // TODO: variable speed + } + } +} \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-player.cpp b/src/games/phase-evasion/phase-evasion-player.cpp index 2381083..edd52d2 100644 --- a/src/games/phase-evasion/phase-evasion-player.cpp +++ b/src/games/phase-evasion/phase-evasion-player.cpp @@ -20,10 +20,10 @@ namespace Games return; } } - if (currentColor != Lights::Color::SlateGray) + if (currentColor != Lights::Color::DimGray) { log("User returned color to neutral."); - currentColor = Lights::Color::SlateGray; + currentColor = Lights::Color::DimGray; } } } \ No newline at end of file From ebd8a11278af8973f68a0bbc15ae6ba78c97bc0f Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Fri, 16 Jan 2026 20:28:58 -0600 Subject: [PATCH 04/21] Set flare render boundary --- .../games/phase-evasion/phase-evasion-core.h | 3 ++- .../games/phase-evasion/phase-evasion-flare.h | 1 + src/games/phase-evasion/phase-evasion-core.cpp | 18 +++++++++++++----- .../phase-evasion/phase-evasion-flare.cpp | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index d77c21e..5e46230 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -13,13 +13,14 @@ namespace Games public: PhaseEvasionCore(Core::ContextManager *ctx); void nextEvent() override; - static constexpr uint16_t clearance = 15; + static constexpr uint16_t playerClearance = 15; private: Core::ContextManager *contextManager; PhaseEvasionGameState &state = contextManager->stateManager.getPhaseEvasionGameState(); PhaseEvasionPlayer player; PhaseEvasionFlare flare; + void getUpdates(); void renderUserColor(); void renderFlare(); void checkCollision(); diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index 5099b33..f2f37d3 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -16,6 +16,7 @@ namespace Games static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() { return position; } + Lights::ColorCode getColor() { return color; } private: Core::ContextManager *contextManager; diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 703ef60..0074bd9 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -25,8 +25,7 @@ namespace Games } break; case PhaseEvasionStates::ActiveGame: - player.checkColorChangeRequest(); - flare.updatePosition(); + getUpdates(); checkCollision(); renderFlare(); renderUserColor(); @@ -34,9 +33,15 @@ namespace Games } } + void PhaseEvasionCore::getUpdates() + { + player.checkColorChangeRequest(); + flare.updatePosition(); + } + void PhaseEvasionCore::renderUserColor() { - for (uint16_t i = clearance; i < clearance + player.width; ++i) + for (uint16_t i = playerClearance; i < playerClearance + player.width; ++i) { contextManager->leds.buffer[i] = player.getColor(); } @@ -44,9 +49,12 @@ namespace Games void PhaseEvasionCore::renderFlare() { - for (uint16_t i = flare.getPosition() - flare.width; i < flare.getPosition(); ++i) + uint16_t start = std::max(flare.getPosition() - flare.width, 0); + uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + + for (uint16_t i = start; i < end; ++i) { - contextManager->leds.buffer[i] = Lights::ColorCode::GameRed; + contextManager->leds.buffer[i] = flare.getColor(); } } diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/phase-evasion-flare.cpp index 2caf4a1..270f03c 100644 --- a/src/games/phase-evasion/phase-evasion-flare.cpp +++ b/src/games/phase-evasion/phase-evasion-flare.cpp @@ -7,7 +7,7 @@ namespace Games if (isReady()) { --position; - wait(20); // TODO: variable speed + wait(15); // TODO: variable speed } } } \ No newline at end of file From 892c9a7d2f0e64a84a1b31cef4e065b72232f122 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sat, 17 Jan 2026 11:44:21 -0600 Subject: [PATCH 05/21] Trigger game ending on collision --- .../games/phase-evasion/phase-evasion-flare.h | 4 ++-- src/games/phase-evasion/phase-evasion-core.cpp | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index f2f37d3..ead1e30 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -16,11 +16,11 @@ namespace Games static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() { return position; } - Lights::ColorCode getColor() { return color; } + Lights::Color getColor() { return color; } private: Core::ContextManager *contextManager; - Lights::ColorCode color; + Lights::Color color; uint16_t position; }; } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 0074bd9..64d9133 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -26,10 +26,16 @@ namespace Games break; case PhaseEvasionStates::ActiveGame: getUpdates(); - checkCollision(); renderFlare(); + checkCollision(); renderUserColor(); break; + case PhaseEvasionStates::GameOver: + for (uint16_t i = 0; i < contextManager->config.numLeds; ++i) + { + contextManager->leds.buffer[i] = Lights::ColorCode::GameRed; + } + break; } } @@ -60,6 +66,12 @@ namespace Games void PhaseEvasionCore::checkCollision() { - // if () + uint16_t start = std::max(flare.getPosition() - flare.width, 0); + uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + + if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flare.getColor()) + { + state.current = PhaseEvasionStates::GameOver; + } } } \ No newline at end of file From 6e7e1d7b6c4b7e44e570e73e55ac968090b192f4 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Mon, 19 Jan 2026 20:48:02 -0600 Subject: [PATCH 06/21] Create FlareManager data structure to orchestrate multiple flares --- .../games/phase-evasion/phase-evasion-core.h | 4 +++- .../phase-evasion-flare-manager.h | 17 ++++++++++++++++ .../phase-evasion/phase-evasion-core.cpp | 20 +++++++++---------- 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 include/games/phase-evasion/phase-evasion-flare-manager.h diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 5e46230..3948bdf 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -5,6 +5,7 @@ #include "core/context-manager.h" #include "games/phase-evasion/phase-evasion-player.h" #include "games/phase-evasion/phase-evasion-flare.h" +#include "games/phase-evasion/phase-evasion-flare-manager.h" namespace Games { @@ -19,7 +20,8 @@ namespace Games Core::ContextManager *contextManager; PhaseEvasionGameState &state = contextManager->stateManager.getPhaseEvasionGameState(); PhaseEvasionPlayer player; - PhaseEvasionFlare flare; + PhaseEvasionFlareManager flareMgr; + void getUpdates(); void renderUserColor(); void renderFlare(); diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/phase-evasion-flare-manager.h new file mode 100644 index 0000000..f650130 --- /dev/null +++ b/include/games/phase-evasion/phase-evasion-flare-manager.h @@ -0,0 +1,17 @@ +#pragma once + +#include "engine/timer.h" +#include "games/phase-evasion/phase-evasion-flare.h" + +namespace Games +{ + class PhaseEvasionFlareManager : public Engine::Timer + { + public: + PhaseEvasionFlare &operator[](uint16_t index) { return flares[index]; } + const PhaseEvasionFlare &operator[](uint16_t index) const { return flares[index]; } + fl::vector flares; + + private: + }; +} \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 64d9133..269eefe 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -4,9 +4,9 @@ namespace Games { PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx}, - flare{ctx} + player{ctx} { + flareMgr.flares.push_back(ctx); state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); state.current = PhaseEvasionStates::Startup; @@ -26,8 +26,8 @@ namespace Games break; case PhaseEvasionStates::ActiveGame: getUpdates(); - renderFlare(); checkCollision(); + renderFlare(); renderUserColor(); break; case PhaseEvasionStates::GameOver: @@ -42,7 +42,7 @@ namespace Games void PhaseEvasionCore::getUpdates() { player.checkColorChangeRequest(); - flare.updatePosition(); + flareMgr[0].updatePosition(); } void PhaseEvasionCore::renderUserColor() @@ -55,21 +55,21 @@ namespace Games void PhaseEvasionCore::renderFlare() { - uint16_t start = std::max(flare.getPosition() - flare.width, 0); - uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + uint16_t start = std::max(flareMgr[0].getPosition() - flareMgr[0].width, 0); + uint16_t end = std::min(flareMgr[0].getPosition(), contextManager->config.numLeds); for (uint16_t i = start; i < end; ++i) { - contextManager->leds.buffer[i] = flare.getColor(); + contextManager->leds.buffer[i] = flareMgr[0].getColor(); } } void PhaseEvasionCore::checkCollision() { - uint16_t start = std::max(flare.getPosition() - flare.width, 0); - uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + uint16_t start = std::max(flareMgr[0].getPosition() - flareMgr[0].width, 0); + uint16_t end = std::min(flareMgr[0].getPosition(), contextManager->config.numLeds); - if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flare.getColor()) + if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flareMgr[0].getColor()) { state.current = PhaseEvasionStates::GameOver; } From 3912b5b0824f1ddfc20c8321f3d7aa15541eff39 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Mon, 19 Jan 2026 22:14:46 -0600 Subject: [PATCH 07/21] Add precision in flare speed --- include/games/phase-evasion/phase-evasion-core.h | 2 +- include/games/phase-evasion/phase-evasion-flare.h | 13 +++++++------ src/games/phase-evasion/phase-evasion-flare.cpp | 4 ++-- src/player/player.cpp | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 3948bdf..93f6163 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -14,7 +14,7 @@ namespace Games public: PhaseEvasionCore(Core::ContextManager *ctx); void nextEvent() override; - static constexpr uint16_t playerClearance = 15; + static constexpr uint16_t playerClearance = 20; private: Core::ContextManager *contextManager; diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index ead1e30..c417e7a 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -11,16 +11,17 @@ namespace Games public: PhaseEvasionFlare(Core::ContextManager *ctx) : contextManager{ctx}, color{Lights::ColorCode::MenuLightBlue}, - position{ctx->config.numLeds + width} {} - + positionFloat{ctx->config.numLeds + width}, + speed{0.75f} {} static constexpr uint16_t width = 10; void updatePosition(); - uint16_t getPosition() { return position; } + uint16_t getPosition() const { return static_cast(positionFloat); } Lights::Color getColor() { return color; } private: - Core::ContextManager *contextManager; - Lights::Color color; - uint16_t position; + const Core::ContextManager *contextManager; + const Lights::Color color; + float positionFloat; + float speed; }; } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/phase-evasion-flare.cpp index 270f03c..1191067 100644 --- a/src/games/phase-evasion/phase-evasion-flare.cpp +++ b/src/games/phase-evasion/phase-evasion-flare.cpp @@ -6,8 +6,8 @@ namespace Games { if (isReady()) { - --position; - wait(15); // TODO: variable speed + positionFloat -= speed; + wait(1); // TODO: variable speed } } } \ No newline at end of file diff --git a/src/player/player.cpp b/src/player/player.cpp index 1b8b6ee..eab4260 100644 --- a/src/player/player.cpp +++ b/src/player/player.cpp @@ -16,6 +16,6 @@ namespace Player if (positionPrecise < 0.0f) positionPrecise += ledCountF; - position = static_cast(std::floor(positionPrecise)) % static_cast(contextManager->leds.size()); + position = static_cast(std::floor(positionPrecise)) % contextManager->leds.size(); } } \ No newline at end of file From 4e7acae9672f0226b3e015a92df428aacc482ff6 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Tue, 20 Jan 2026 18:34:55 -0600 Subject: [PATCH 08/21] Setup loop over FlareManager --- .../phase-evasion-flare-manager.h | 9 ++++- .../games/phase-evasion/phase-evasion-flare.h | 10 +++--- .../phase-evasion/phase-evasion-core.cpp | 35 ++++++++++++------- .../phase-evasion-flare-manager.cpp | 10 ++++++ .../phase-evasion/phase-evasion-flare.cpp | 6 +--- 5 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 src/games/phase-evasion/phase-evasion-flare-manager.cpp diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/phase-evasion-flare-manager.h index f650130..3deb8f0 100644 --- a/include/games/phase-evasion/phase-evasion-flare-manager.h +++ b/include/games/phase-evasion/phase-evasion-flare-manager.h @@ -8,10 +8,17 @@ namespace Games class PhaseEvasionFlareManager : public Engine::Timer { public: + PhaseEvasionFlareManager(Core::ContextManager *ctx); + PhaseEvasionFlare &operator[](uint16_t index) { return flares[index]; } const PhaseEvasionFlare &operator[](uint16_t index) const { return flares[index]; } - fl::vector flares; + fl::vector::iterator begin() { return flares.begin(); } + fl::vector::iterator end() { return flares.end(); } + fl::vector::const_iterator begin() const { return flares.begin(); } + fl::vector::const_iterator end() const { return flares.end(); } private: + Core::ContextManager *contextManager; + fl::vector flares; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index c417e7a..9197064 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -9,14 +9,14 @@ namespace Games class PhaseEvasionFlare : public Engine::Timer { public: - PhaseEvasionFlare(Core::ContextManager *ctx) : contextManager{ctx}, - color{Lights::ColorCode::MenuLightBlue}, - positionFloat{ctx->config.numLeds + width}, - speed{0.75f} {} + PhaseEvasionFlare(const Core::ContextManager *ctx) : contextManager{ctx}, + color{Lights::ColorCode::MenuLightBlue}, + positionFloat{ctx->config.numLeds + width}, + speed{0.75f} {} static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() const { return static_cast(positionFloat); } - Lights::Color getColor() { return color; } + const Lights::Color getColor() const { return color; } private: const Core::ContextManager *contextManager; diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 269eefe..8d36764 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -4,9 +4,9 @@ namespace Games { PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx} + player{ctx}, + flareMgr{ctx} { - flareMgr.flares.push_back(ctx); state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); state.current = PhaseEvasionStates::Startup; @@ -42,7 +42,10 @@ namespace Games void PhaseEvasionCore::getUpdates() { player.checkColorChangeRequest(); - flareMgr[0].updatePosition(); + for (auto &flare : flareMgr) + { + flare.updatePosition(); + } } void PhaseEvasionCore::renderUserColor() @@ -55,23 +58,29 @@ namespace Games void PhaseEvasionCore::renderFlare() { - uint16_t start = std::max(flareMgr[0].getPosition() - flareMgr[0].width, 0); - uint16_t end = std::min(flareMgr[0].getPosition(), contextManager->config.numLeds); - - for (uint16_t i = start; i < end; ++i) + for (const auto &flare : flareMgr) { - contextManager->leds.buffer[i] = flareMgr[0].getColor(); + uint16_t start = std::max(flare.getPosition() - flare.width, 0); + uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + + for (uint16_t i = start; i < end; ++i) + { + contextManager->leds.buffer[i] = flare.getColor(); + } } } void PhaseEvasionCore::checkCollision() { - uint16_t start = std::max(flareMgr[0].getPosition() - flareMgr[0].width, 0); - uint16_t end = std::min(flareMgr[0].getPosition(), contextManager->config.numLeds); - - if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flareMgr[0].getColor()) + for (const auto &flare : flareMgr) { - state.current = PhaseEvasionStates::GameOver; + uint16_t start = std::max(flare.getPosition() - flare.width, 0); + uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); + + if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flare.getColor()) + { + state.current = PhaseEvasionStates::GameOver; + } } } } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-flare-manager.cpp b/src/games/phase-evasion/phase-evasion-flare-manager.cpp new file mode 100644 index 0000000..53ec380 --- /dev/null +++ b/src/games/phase-evasion/phase-evasion-flare-manager.cpp @@ -0,0 +1,10 @@ +#include "games/phase-evasion/phase-evasion-flare-manager.h" + +namespace Games +{ + PhaseEvasionFlareManager::PhaseEvasionFlareManager(Core::ContextManager *ctx) : contextManager{ctx} + { + flares.reserve(10); + flares.push_back(ctx); + } +} \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/phase-evasion-flare.cpp index 1191067..6ddecf1 100644 --- a/src/games/phase-evasion/phase-evasion-flare.cpp +++ b/src/games/phase-evasion/phase-evasion-flare.cpp @@ -4,10 +4,6 @@ namespace Games { void PhaseEvasionFlare::updatePosition() { - if (isReady()) - { - positionFloat -= speed; - wait(1); // TODO: variable speed - } + positionFloat -= speed; } } \ No newline at end of file From dee9ddf541691f551df4a4f2019e4a1347df63a5 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Tue, 20 Jan 2026 23:22:07 -0600 Subject: [PATCH 09/21] Reduce data required for Flare construction --- .../phase-evasion/phase-evasion-flare-manager.h | 6 ++++++ .../games/phase-evasion/phase-evasion-flare.h | 14 +++++++------- src/games/phase-evasion/phase-evasion-core.cpp | 5 +---- .../phase-evasion-flare-manager.cpp | 17 +++++++++++++++-- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/phase-evasion-flare-manager.h index 3deb8f0..95b3172 100644 --- a/include/games/phase-evasion/phase-evasion-flare-manager.h +++ b/include/games/phase-evasion/phase-evasion-flare-manager.h @@ -1,6 +1,7 @@ #pragma once #include "engine/timer.h" +#include "core/context-manager.h" #include "games/phase-evasion/phase-evasion-flare.h" namespace Games @@ -12,11 +13,16 @@ namespace Games PhaseEvasionFlare &operator[](uint16_t index) { return flares[index]; } const PhaseEvasionFlare &operator[](uint16_t index) const { return flares[index]; } + fl::vector::iterator begin() { return flares.begin(); } fl::vector::iterator end() { return flares.end(); } fl::vector::const_iterator begin() const { return flares.begin(); } fl::vector::const_iterator end() const { return flares.end(); } + fl::size size() { return flares.size(); } + + void updatePositions(); + private: Core::ContextManager *contextManager; fl::vector flares; diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index 9197064..8d10883 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -1,7 +1,8 @@ #pragma once #include "engine/timer.h" -#include "core/context-manager.h" +#include "engine/system-config.h" +#include "lights/color.h" #include "lights/color-code.h" namespace Games @@ -9,19 +10,18 @@ namespace Games class PhaseEvasionFlare : public Engine::Timer { public: - PhaseEvasionFlare(const Core::ContextManager *ctx) : contextManager{ctx}, - color{Lights::ColorCode::MenuLightBlue}, - positionFloat{ctx->config.numLeds + width}, - speed{0.75f} {} + PhaseEvasionFlare() = delete; + PhaseEvasionFlare(const float s) : color{Lights::ColorCode::MenuLightBlue}, + positionFloat{Engine::SystemConfig::numLeds + width}, + speed{s} {} static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() const { return static_cast(positionFloat); } const Lights::Color getColor() const { return color; } private: - const Core::ContextManager *contextManager; const Lights::Color color; + const float speed; float positionFloat; - float speed; }; } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 8d36764..79a2dfd 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -42,10 +42,7 @@ namespace Games void PhaseEvasionCore::getUpdates() { player.checkColorChangeRequest(); - for (auto &flare : flareMgr) - { - flare.updatePosition(); - } + flareMgr.updatePositions(); } void PhaseEvasionCore::renderUserColor() diff --git a/src/games/phase-evasion/phase-evasion-flare-manager.cpp b/src/games/phase-evasion/phase-evasion-flare-manager.cpp index 53ec380..f49742a 100644 --- a/src/games/phase-evasion/phase-evasion-flare-manager.cpp +++ b/src/games/phase-evasion/phase-evasion-flare-manager.cpp @@ -4,7 +4,20 @@ namespace Games { PhaseEvasionFlareManager::PhaseEvasionFlareManager(Core::ContextManager *ctx) : contextManager{ctx} { - flares.reserve(10); - flares.push_back(ctx); + flares.emplace_back(0.75f); + } + + void PhaseEvasionFlareManager::updatePositions() + { + fl::vector survivors; + for (auto itr = flares.begin(); itr != flares.end(); ++itr) + { + itr->updatePosition(); + if (itr->getPosition() > 0) + { + survivors.push_back(fl::move(*itr)); + } + } + flares.swap(survivors); } } \ No newline at end of file From e635b8f3f9de8bcfb7ec039d85c4cc1546c0b0a7 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Wed, 21 Jan 2026 00:13:49 -0600 Subject: [PATCH 10/21] Random color flare dispatch --- .../games/phase-evasion/phase-evasion-core.h | 1 + .../phase-evasion-flare-manager.h | 6 ++-- .../games/phase-evasion/phase-evasion-flare.h | 12 ++++++- .../phase-evasion/phase-evasion-core.cpp | 14 ++++++-- .../phase-evasion-flare-manager.cpp | 34 +++++++++++++++++-- 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index 93f6163..eab8d35 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -26,5 +26,6 @@ namespace Games void renderUserColor(); void renderFlare(); void checkCollision(); + void checkGrowth(); }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/phase-evasion-flare-manager.h index 95b3172..3a4a225 100644 --- a/include/games/phase-evasion/phase-evasion-flare-manager.h +++ b/include/games/phase-evasion/phase-evasion-flare-manager.h @@ -1,7 +1,5 @@ #pragma once -#include "engine/timer.h" -#include "core/context-manager.h" #include "games/phase-evasion/phase-evasion-flare.h" namespace Games @@ -9,7 +7,7 @@ namespace Games class PhaseEvasionFlareManager : public Engine::Timer { public: - PhaseEvasionFlareManager(Core::ContextManager *ctx); + PhaseEvasionFlareManager(); PhaseEvasionFlare &operator[](uint16_t index) { return flares[index]; } const PhaseEvasionFlare &operator[](uint16_t index) const { return flares[index]; } @@ -22,9 +20,9 @@ namespace Games fl::size size() { return flares.size(); } void updatePositions(); + void dispatch(); private: - Core::ContextManager *contextManager; fl::vector flares; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index 8d10883..a8e58fb 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -1,5 +1,9 @@ #pragma once +#include "esp_system.h" + +#include "common.h" + #include "engine/timer.h" #include "engine/system-config.h" #include "lights/color.h" @@ -11,7 +15,7 @@ namespace Games { public: PhaseEvasionFlare() = delete; - PhaseEvasionFlare(const float s) : color{Lights::ColorCode::MenuLightBlue}, + PhaseEvasionFlare(const float s) : color{colorPalette[static_cast(esp_random()) % arraySize(colorPalette)]}, positionFloat{Engine::SystemConfig::numLeds + width}, speed{s} {} static constexpr uint16_t width = 10; @@ -20,6 +24,12 @@ namespace Games const Lights::Color getColor() const { return color; } private: + Lights::Color colorPalette[4] = { + {Lights::ColorCode::GameBlue}, // ✕ blue + {Lights::ColorCode::GameRed}, // ◯ red + {Lights::ColorCode::GameGreen}, // △ green + {Lights::ColorCode::GameYellow}}; // □ yellow + const Lights::Color color; const float speed; float positionFloat; diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 79a2dfd..4f6f6c8 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -4,8 +4,7 @@ namespace Games { PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx}, - flareMgr{ctx} + player{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); @@ -21,11 +20,13 @@ namespace Games if (isReady()) { state.current = PhaseEvasionStates::ActiveGame; + wait(1500); log("Starting new game."); } break; case PhaseEvasionStates::ActiveGame: getUpdates(); + checkGrowth(); checkCollision(); renderFlare(); renderUserColor(); @@ -80,4 +81,13 @@ namespace Games } } } + + void PhaseEvasionCore::checkGrowth() + { + if (isReady()) + { + flareMgr.dispatch(); + wait(1500); + } + } } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-flare-manager.cpp b/src/games/phase-evasion/phase-evasion-flare-manager.cpp index f49742a..38f666c 100644 --- a/src/games/phase-evasion/phase-evasion-flare-manager.cpp +++ b/src/games/phase-evasion/phase-evasion-flare-manager.cpp @@ -1,23 +1,51 @@ #include "games/phase-evasion/phase-evasion-flare-manager.h" +#include "logger.h" namespace Games { - PhaseEvasionFlareManager::PhaseEvasionFlareManager(Core::ContextManager *ctx) : contextManager{ctx} + PhaseEvasionFlareManager::PhaseEvasionFlareManager() + { + flares.emplace_back(0.75f); + } + + void PhaseEvasionFlareManager::dispatch() { flares.emplace_back(0.75f); } void PhaseEvasionFlareManager::updatePositions() { + bool started = false; fl::vector survivors; + for (auto itr = flares.begin(); itr != flares.end(); ++itr) { itr->updatePosition(); + if (itr->getPosition() > 0) { - survivors.push_back(fl::move(*itr)); + if (started) + { + survivors.push_back(fl::move(*itr)); + } } + else + { + if (!started) + { + started = true; + survivors.reserve(flares.size()); + for (auto prev = flares.begin(); prev != itr; ++prev) + { + survivors.push_back(fl::move(*prev)); + } + } + } + } + + if (started) + { + flares.swap(survivors); } - flares.swap(survivors); } } \ No newline at end of file From 387d8b5891db139246717ea9f818bcc4745e2210 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Wed, 21 Jan 2026 00:35:40 -0600 Subject: [PATCH 11/21] Make colorPallette shared/reusable --- include/games/phase-evasion/phase-evasion-flare.h | 8 +------- include/games/phase-evasion/phase-evasion-player.h | 5 ----- include/games/recall/recall-core.h | 5 ----- include/lights/color.h | 6 ++++++ src/games/phase-evasion/phase-evasion-core.cpp | 4 ++-- src/games/phase-evasion/phase-evasion-player.cpp | 6 +++--- src/games/recall/recall-core.cpp | 12 ++++++------ 7 files changed, 18 insertions(+), 28 deletions(-) diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index a8e58fb..c67b64a 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -15,7 +15,7 @@ namespace Games { public: PhaseEvasionFlare() = delete; - PhaseEvasionFlare(const float s) : color{colorPalette[static_cast(esp_random()) % arraySize(colorPalette)]}, + PhaseEvasionFlare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, positionFloat{Engine::SystemConfig::numLeds + width}, speed{s} {} static constexpr uint16_t width = 10; @@ -24,12 +24,6 @@ namespace Games const Lights::Color getColor() const { return color; } private: - Lights::Color colorPalette[4] = { - {Lights::ColorCode::GameBlue}, // ✕ blue - {Lights::ColorCode::GameRed}, // ◯ red - {Lights::ColorCode::GameGreen}, // △ green - {Lights::ColorCode::GameYellow}}; // □ yellow - const Lights::Color color; const float speed; float positionFloat; diff --git a/include/games/phase-evasion/phase-evasion-player.h b/include/games/phase-evasion/phase-evasion-player.h index f099884..963202c 100644 --- a/include/games/phase-evasion/phase-evasion-player.h +++ b/include/games/phase-evasion/phase-evasion-player.h @@ -21,10 +21,5 @@ namespace Games ::Player::ControllerButton::Square, ::Player::ControllerButton::Triangle, ::Player::ControllerButton::Circle}; - Lights::Color colorPalette[4] = { - {Lights::ColorCode::GameBlue}, // ✕ blue - {Lights::ColorCode::GameRed}, // ◯ red - {Lights::ColorCode::GameGreen}, // △ green - {Lights::ColorCode::GameYellow}}; // □ yellow }; } \ No newline at end of file diff --git a/include/games/recall/recall-core.h b/include/games/recall/recall-core.h index dcfb984..99341dc 100644 --- a/include/games/recall/recall-core.h +++ b/include/games/recall/recall-core.h @@ -27,11 +27,6 @@ namespace Games Player::ControllerButton::Triangle, Player::ControllerButton::Circle}; uint16_t sequenceIndex = 0; - Lights::Color colorPalette[4] = { - {Lights::ColorCode::GameBlue}, // ✕ blue - {Lights::ColorCode::GameRed}, // ◯ red - {Lights::ColorCode::GameGreen}, // △ green - {Lights::ColorCode::GameYellow}}; // □ yellow Player::ControllerButton gameplayColors[maxRound]; float gameOverLedPhaseShift = 0.0f; float successFadeawayAnimation = 1.0f; diff --git a/include/lights/color.h b/include/lights/color.h index 76e1148..8a6a52a 100644 --- a/include/lights/color.h +++ b/include/lights/color.h @@ -59,4 +59,10 @@ namespace Lights return *this; } }; + + inline const Color colorPalette[4] = { + Color(ColorCode::GameBlue), + Color(ColorCode::GameRed), + Color(ColorCode::GameGreen), + Color(ColorCode::GameYellow)}; } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 4f6f6c8..30d7cb4 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -20,7 +20,7 @@ namespace Games if (isReady()) { state.current = PhaseEvasionStates::ActiveGame; - wait(1500); + wait(1000); log("Starting new game."); } break; @@ -87,7 +87,7 @@ namespace Games if (isReady()) { flareMgr.dispatch(); - wait(1500); + wait(1000); } } } \ No newline at end of file diff --git a/src/games/phase-evasion/phase-evasion-player.cpp b/src/games/phase-evasion/phase-evasion-player.cpp index edd52d2..f1328c3 100644 --- a/src/games/phase-evasion/phase-evasion-player.cpp +++ b/src/games/phase-evasion/phase-evasion-player.cpp @@ -10,13 +10,13 @@ namespace Games if (contextManager->controller.isDown(button)) { #ifdef DEBUG - if (currentColor != colorPalette[static_cast(button)]) + if (currentColor != Lights::colorPalette[static_cast(button)]) { - auto c = colorPalette[static_cast(button)]; + auto c = Lights::colorPalette[static_cast(button)]; logf("User pressed color=%u (%u - %u - %u)", button, c.r, c.g, c.b); } #endif - currentColor = colorPalette[static_cast(button)]; + currentColor = Lights::colorPalette[static_cast(button)]; return; } } diff --git a/src/games/recall/recall-core.cpp b/src/games/recall/recall-core.cpp index e362175..eb9cace 100644 --- a/src/games/recall/recall-core.cpp +++ b/src/games/recall/recall-core.cpp @@ -26,7 +26,7 @@ namespace Games gameplayColors[i] = static_cast(colorIndex); } auto button = gameplayColors[0]; - auto &color = colorPalette[static_cast(button)]; + auto &color = Lights::colorPalette[static_cast(button)]; log("First round's RGB color:"); logf(" Color=%u (%u - %u - %u)", button, color.r, color.g, color.b); } @@ -99,7 +99,7 @@ namespace Games { double x = static_cast(i); double scope = std::exp(-0.5 * std::pow((x - mu) / delta, 2.0)); - auto color = colorPalette[static_cast(gameplayColors[sequenceIndex])]; + auto color = Lights::colorPalette[static_cast(gameplayColors[sequenceIndex])]; contextManager->leds.buffer[i] = color * scope; } } @@ -149,7 +149,7 @@ namespace Games if (button == expectedButton) { ++sequenceIndex; - auto &color = colorPalette[static_cast(button)]; + auto &color = Lights::colorPalette[static_cast(button)]; logf("User correctly responded with color=%u (%u - %u - %u)", button, color.r, color.g, color.b); wait(gameplaySpeedPaused); return; @@ -185,7 +185,7 @@ namespace Games { auto boundaries = directionBoundaries(static_cast(pressedButtonIndex)); for (uint16_t i = boundaries.first; i <= boundaries.second; ++i) - contextManager->leds.buffer[i] = colorPalette[pressedButtonIndex]; + contextManager->leds.buffer[i] = Lights::colorPalette[pressedButtonIndex]; } } } @@ -217,7 +217,7 @@ namespace Games for (int i = 0; i <= sequenceIndex; ++i) { auto button = gameplayColors[i]; - auto &color = colorPalette[static_cast(button)]; + auto &color = Lights::colorPalette[static_cast(button)]; logf(" Color=%u (%u - %u - %u)", button, color.r, color.g, color.b); } state.current = RecallStates::ComputerPlaybackOnDisplay; @@ -229,7 +229,7 @@ namespace Games auto boundaries = directionBoundaries(gameplayColors[sequenceIndex - 1]); for (uint16_t i = boundaries.first; i <= boundaries.second; ++i) { - auto &color = colorPalette[static_cast(gameplayColors[sequenceIndex - 1])]; + auto &color = Lights::colorPalette[static_cast(gameplayColors[sequenceIndex - 1])]; contextManager->leds.buffer[i] = color * successFadeawayAnimation; } successFadeawayAnimation = std::clamp(successFadeawayAnimation - 0.08, 0.0, 1.0); From 9d9b5aa4031f7eb22bef61ced4c6d51f9aed3584 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Thu, 22 Jan 2026 21:22:10 -0600 Subject: [PATCH 12/21] Phase Evasion namespace --- include/engine/state-manager.h | 4 +-- .../games/phase-evasion/phase-evasion-core.h | 14 ++++----- .../phase-evasion-flare-manager.h | 20 ++++++------- .../games/phase-evasion/phase-evasion-flare.h | 12 ++++---- .../phase-evasion/phase-evasion-player.h | 8 ++--- .../games/phase-evasion/phase-evasion-state.h | 10 +++---- src/core/context-manager.cpp | 2 +- .../phase-evasion/phase-evasion-core.cpp | 30 +++++++++---------- .../phase-evasion-flare-manager.cpp | 10 +++---- .../phase-evasion/phase-evasion-flare.cpp | 4 +-- .../phase-evasion/phase-evasion-player.cpp | 4 +-- 11 files changed, 59 insertions(+), 59 deletions(-) diff --git a/include/engine/state-manager.h b/include/engine/state-manager.h index bdd7e5d..38d1e1a 100644 --- a/include/engine/state-manager.h +++ b/include/engine/state-manager.h @@ -77,7 +77,7 @@ namespace Engine const char *printSceneName(uint8_t index); Games::RecallGameState &getRecallGameState() { return recallGameState; } - Games::PhaseEvasionGameState &getPhaseEvasionGameState() { return phaseEvasionGameState; } + Games::PhaseEvasion::GameState &getPhaseEvasionGameState() { return phaseEvasionGameState; } Games::DemoGameState &getDemoGameState() { return demoGameState; } Scenes::CanvasSceneState &getCanvasSceneState() { return canvasSceneState; } @@ -90,7 +90,7 @@ namespace Engine SceneSelection userSceneChoice = SceneSelection::Canvas; Games::RecallGameState recallGameState; - Games::PhaseEvasionGameState phaseEvasionGameState; + Games::PhaseEvasion::GameState phaseEvasionGameState; Games::DemoGameState demoGameState; Scenes::CanvasSceneState canvasSceneState; diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/phase-evasion-core.h index eab8d35..ef1728e 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/phase-evasion-core.h @@ -7,20 +7,20 @@ #include "games/phase-evasion/phase-evasion-flare.h" #include "games/phase-evasion/phase-evasion-flare-manager.h" -namespace Games +namespace Games::PhaseEvasion { - class PhaseEvasionCore : public Engine::Layer, private Engine::Timer + class Core : public Engine::Layer, private Engine::Timer { public: - PhaseEvasionCore(Core::ContextManager *ctx); + Core(::Core::ContextManager *ctx); void nextEvent() override; static constexpr uint16_t playerClearance = 20; private: - Core::ContextManager *contextManager; - PhaseEvasionGameState &state = contextManager->stateManager.getPhaseEvasionGameState(); - PhaseEvasionPlayer player; - PhaseEvasionFlareManager flareMgr; + ::Core::ContextManager *contextManager; + GameState &state = contextManager->stateManager.getPhaseEvasionGameState(); + Player player; + FlareManager flareMgr; void getUpdates(); void renderUserColor(); diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/phase-evasion-flare-manager.h index 3a4a225..6ab66ea 100644 --- a/include/games/phase-evasion/phase-evasion-flare-manager.h +++ b/include/games/phase-evasion/phase-evasion-flare-manager.h @@ -2,20 +2,20 @@ #include "games/phase-evasion/phase-evasion-flare.h" -namespace Games +namespace Games::PhaseEvasion { - class PhaseEvasionFlareManager : public Engine::Timer + class FlareManager : public Engine::Timer { public: - PhaseEvasionFlareManager(); + FlareManager(); - PhaseEvasionFlare &operator[](uint16_t index) { return flares[index]; } - const PhaseEvasionFlare &operator[](uint16_t index) const { return flares[index]; } + Flare &operator[](uint16_t index) { return flares[index]; } + const Flare &operator[](uint16_t index) const { return flares[index]; } - fl::vector::iterator begin() { return flares.begin(); } - fl::vector::iterator end() { return flares.end(); } - fl::vector::const_iterator begin() const { return flares.begin(); } - fl::vector::const_iterator end() const { return flares.end(); } + fl::vector::iterator begin() { return flares.begin(); } + fl::vector::iterator end() { return flares.end(); } + fl::vector::const_iterator begin() const { return flares.begin(); } + fl::vector::const_iterator end() const { return flares.end(); } fl::size size() { return flares.size(); } @@ -23,6 +23,6 @@ namespace Games void dispatch(); private: - fl::vector flares; + fl::vector flares; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/phase-evasion-flare.h index c67b64a..a43642a 100644 --- a/include/games/phase-evasion/phase-evasion-flare.h +++ b/include/games/phase-evasion/phase-evasion-flare.h @@ -9,15 +9,15 @@ #include "lights/color.h" #include "lights/color-code.h" -namespace Games +namespace Games::PhaseEvasion { - class PhaseEvasionFlare : public Engine::Timer + class Flare : public Engine::Timer { public: - PhaseEvasionFlare() = delete; - PhaseEvasionFlare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, - positionFloat{Engine::SystemConfig::numLeds + width}, - speed{s} {} + Flare() = delete; + Flare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, + positionFloat{Engine::SystemConfig::numLeds + width}, + speed{s} {} static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() const { return static_cast(positionFloat); } diff --git a/include/games/phase-evasion/phase-evasion-player.h b/include/games/phase-evasion/phase-evasion-player.h index 963202c..2d60715 100644 --- a/include/games/phase-evasion/phase-evasion-player.h +++ b/include/games/phase-evasion/phase-evasion-player.h @@ -3,18 +3,18 @@ #include "core/context-manager.h" #include "player/player.h" -namespace Games +namespace Games::PhaseEvasion { - class PhaseEvasionPlayer : public Player::Player + class Player : public ::Player::Player { public: - PhaseEvasionPlayer(Core::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; + Player(::Core::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; void checkColorChangeRequest(); Lights::Color getColor() { return currentColor; } static constexpr uint16_t width = 10; private: - Core::ContextManager *contextManager; + ::Core::ContextManager *contextManager; Lights::Color currentColor; static constexpr ::Player::ControllerButton availableGameplayButtons[] = { ::Player::ControllerButton::Cross, diff --git a/include/games/phase-evasion/phase-evasion-state.h b/include/games/phase-evasion/phase-evasion-state.h index cfdb320..4c9778c 100644 --- a/include/games/phase-evasion/phase-evasion-state.h +++ b/include/games/phase-evasion/phase-evasion-state.h @@ -2,22 +2,22 @@ #include -namespace Games +namespace Games::PhaseEvasion { - enum class PhaseEvasionStates + enum class Actions { Startup, ActiveGame, GameOver }; - class PhaseEvasionGameState + class GameState { public: - PhaseEvasionGameState() : highScore{0}, spectersDodged{0} {} + GameState() : highScore{0}, spectersDodged{0} {} uint16_t highScore; uint16_t spectersDodged; - PhaseEvasionStates current = PhaseEvasionStates::Startup; + Actions current = Actions::Startup; void reset() { highScore = spectersDodged = 0; } }; } \ No newline at end of file diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index bd88e73..41addb3 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -154,7 +154,7 @@ namespace Core logf("Transitioning to Recall (Game)"); break; case Engine::SystemState::GamePhaseEvasion: - application = new Games::PhaseEvasionCore{this}; + application = new Games::PhaseEvasion::Core{this}; logf("Transitioning to Phase Evasion (Game)"); break; case Engine::SystemState::GameDemo: diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/phase-evasion-core.cpp index 30d7cb4..b1a3a8e 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/phase-evasion-core.cpp @@ -1,37 +1,37 @@ #include "games/phase-evasion/phase-evasion-core.h" #include "logger.h" -namespace Games +namespace Games::PhaseEvasion { - PhaseEvasionCore::PhaseEvasionCore(Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx} + Core::Core(::Core::ContextManager *ctx) : contextManager{ctx}, + player{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); - state.current = PhaseEvasionStates::Startup; + state.current = Actions::Startup; wait(500); } - void PhaseEvasionCore::nextEvent() + void Core::nextEvent() { switch (state.current) { - case PhaseEvasionStates::Startup: + case Actions::Startup: if (isReady()) { - state.current = PhaseEvasionStates::ActiveGame; + state.current = Actions::ActiveGame; wait(1000); log("Starting new game."); } break; - case PhaseEvasionStates::ActiveGame: + case Actions::ActiveGame: getUpdates(); checkGrowth(); checkCollision(); renderFlare(); renderUserColor(); break; - case PhaseEvasionStates::GameOver: + case Actions::GameOver: for (uint16_t i = 0; i < contextManager->config.numLeds; ++i) { contextManager->leds.buffer[i] = Lights::ColorCode::GameRed; @@ -40,13 +40,13 @@ namespace Games } } - void PhaseEvasionCore::getUpdates() + void Core::getUpdates() { player.checkColorChangeRequest(); flareMgr.updatePositions(); } - void PhaseEvasionCore::renderUserColor() + void Core::renderUserColor() { for (uint16_t i = playerClearance; i < playerClearance + player.width; ++i) { @@ -54,7 +54,7 @@ namespace Games } } - void PhaseEvasionCore::renderFlare() + void Core::renderFlare() { for (const auto &flare : flareMgr) { @@ -68,7 +68,7 @@ namespace Games } } - void PhaseEvasionCore::checkCollision() + void Core::checkCollision() { for (const auto &flare : flareMgr) { @@ -77,12 +77,12 @@ namespace Games if (start <= playerClearance + player.width && end >= playerClearance && player.getColor() != flare.getColor()) { - state.current = PhaseEvasionStates::GameOver; + state.current = Actions::GameOver; } } } - void PhaseEvasionCore::checkGrowth() + void Core::checkGrowth() { if (isReady()) { diff --git a/src/games/phase-evasion/phase-evasion-flare-manager.cpp b/src/games/phase-evasion/phase-evasion-flare-manager.cpp index 38f666c..87fd341 100644 --- a/src/games/phase-evasion/phase-evasion-flare-manager.cpp +++ b/src/games/phase-evasion/phase-evasion-flare-manager.cpp @@ -1,22 +1,22 @@ #include "games/phase-evasion/phase-evasion-flare-manager.h" #include "logger.h" -namespace Games +namespace Games::PhaseEvasion { - PhaseEvasionFlareManager::PhaseEvasionFlareManager() + FlareManager::FlareManager() { flares.emplace_back(0.75f); } - void PhaseEvasionFlareManager::dispatch() + void FlareManager::dispatch() { flares.emplace_back(0.75f); } - void PhaseEvasionFlareManager::updatePositions() + void FlareManager::updatePositions() { bool started = false; - fl::vector survivors; + fl::vector survivors; for (auto itr = flares.begin(); itr != flares.end(); ++itr) { diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/phase-evasion-flare.cpp index 6ddecf1..4d7d547 100644 --- a/src/games/phase-evasion/phase-evasion-flare.cpp +++ b/src/games/phase-evasion/phase-evasion-flare.cpp @@ -1,8 +1,8 @@ #include "games/phase-evasion/phase-evasion-flare.h" -namespace Games +namespace Games::PhaseEvasion { - void PhaseEvasionFlare::updatePosition() + void Flare::updatePosition() { positionFloat -= speed; } diff --git a/src/games/phase-evasion/phase-evasion-player.cpp b/src/games/phase-evasion/phase-evasion-player.cpp index f1328c3..4ad48dd 100644 --- a/src/games/phase-evasion/phase-evasion-player.cpp +++ b/src/games/phase-evasion/phase-evasion-player.cpp @@ -1,9 +1,9 @@ #include "games/phase-evasion/phase-evasion-player.h" #include "logger.h" -namespace Games +namespace Games::PhaseEvasion { - void PhaseEvasionPlayer::checkColorChangeRequest() + void Player::checkColorChangeRequest() { for (auto button : availableGameplayButtons) { From 63c98e8a55dc048f826e0a71fca51f9a168e2520 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Thu, 22 Jan 2026 21:31:57 -0600 Subject: [PATCH 13/21] Phase Evasion file system refresh --- include/engine/state-manager.h | 2 +- .../{phase-evasion-core.h => controller.h} | 10 +++++----- ...evasion-flare-manager.h => flare-manager.h} | 2 +- .../{phase-evasion-flare.h => flare.h} | 0 .../{phase-evasion-player.h => player.h} | 0 .../{phase-evasion-state.h => state.h} | 0 src/core/context-manager.cpp | 4 ++-- .../{phase-evasion-core.cpp => controller.cpp} | 18 +++++++++--------- ...ion-flare-manager.cpp => flare-manager.cpp} | 2 +- .../{phase-evasion-flare.cpp => flare.cpp} | 2 +- .../{phase-evasion-player.cpp => player.cpp} | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) rename include/games/phase-evasion/{phase-evasion-core.h => controller.h} (67%) rename include/games/phase-evasion/{phase-evasion-flare-manager.h => flare-manager.h} (92%) rename include/games/phase-evasion/{phase-evasion-flare.h => flare.h} (100%) rename include/games/phase-evasion/{phase-evasion-player.h => player.h} (100%) rename include/games/phase-evasion/{phase-evasion-state.h => state.h} (100%) rename src/games/phase-evasion/{phase-evasion-core.cpp => controller.cpp} (82%) rename src/games/phase-evasion/{phase-evasion-flare-manager.cpp => flare-manager.cpp} (93%) rename src/games/phase-evasion/{phase-evasion-flare.cpp => flare.cpp} (65%) rename src/games/phase-evasion/{phase-evasion-player.cpp => player.cpp} (93%) diff --git a/include/engine/state-manager.h b/include/engine/state-manager.h index 38d1e1a..100beda 100644 --- a/include/engine/state-manager.h +++ b/include/engine/state-manager.h @@ -1,7 +1,7 @@ #pragma once #include "games/recall/recall-state.h" -#include "games/phase-evasion/phase-evasion-state.h" +#include "games/phase-evasion/state.h" #include "games/demo/demo-state.h" #include "scenes/canvas/canvas-state.h" diff --git a/include/games/phase-evasion/phase-evasion-core.h b/include/games/phase-evasion/controller.h similarity index 67% rename from include/games/phase-evasion/phase-evasion-core.h rename to include/games/phase-evasion/controller.h index ef1728e..086ae6c 100644 --- a/include/games/phase-evasion/phase-evasion-core.h +++ b/include/games/phase-evasion/controller.h @@ -3,16 +3,16 @@ #include "engine/layer.h" #include "engine/timer.h" #include "core/context-manager.h" -#include "games/phase-evasion/phase-evasion-player.h" -#include "games/phase-evasion/phase-evasion-flare.h" -#include "games/phase-evasion/phase-evasion-flare-manager.h" +#include "games/phase-evasion/player.h" +#include "games/phase-evasion/flare.h" +#include "games/phase-evasion/flare-manager.h" namespace Games::PhaseEvasion { - class Core : public Engine::Layer, private Engine::Timer + class Controller : public Engine::Layer, private Engine::Timer { public: - Core(::Core::ContextManager *ctx); + Controller(::Core::ContextManager *ctx); void nextEvent() override; static constexpr uint16_t playerClearance = 20; diff --git a/include/games/phase-evasion/phase-evasion-flare-manager.h b/include/games/phase-evasion/flare-manager.h similarity index 92% rename from include/games/phase-evasion/phase-evasion-flare-manager.h rename to include/games/phase-evasion/flare-manager.h index 6ab66ea..1020c42 100644 --- a/include/games/phase-evasion/phase-evasion-flare-manager.h +++ b/include/games/phase-evasion/flare-manager.h @@ -1,6 +1,6 @@ #pragma once -#include "games/phase-evasion/phase-evasion-flare.h" +#include "games/phase-evasion/flare.h" namespace Games::PhaseEvasion { diff --git a/include/games/phase-evasion/phase-evasion-flare.h b/include/games/phase-evasion/flare.h similarity index 100% rename from include/games/phase-evasion/phase-evasion-flare.h rename to include/games/phase-evasion/flare.h diff --git a/include/games/phase-evasion/phase-evasion-player.h b/include/games/phase-evasion/player.h similarity index 100% rename from include/games/phase-evasion/phase-evasion-player.h rename to include/games/phase-evasion/player.h diff --git a/include/games/phase-evasion/phase-evasion-state.h b/include/games/phase-evasion/state.h similarity index 100% rename from include/games/phase-evasion/phase-evasion-state.h rename to include/games/phase-evasion/state.h diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index 41addb3..9ff7be5 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -1,7 +1,7 @@ #include "core/context-manager.h" #include "games/demo/demo-core.h" #include "games/recall/recall-core.h" -#include "games/phase-evasion/phase-evasion-core.h" +#include "games/phase-evasion/controller.h" #include "scenes/canvas/canvas.h" #include "logger.h" @@ -154,7 +154,7 @@ namespace Core logf("Transitioning to Recall (Game)"); break; case Engine::SystemState::GamePhaseEvasion: - application = new Games::PhaseEvasion::Core{this}; + application = new Games::PhaseEvasion::Controller{this}; logf("Transitioning to Phase Evasion (Game)"); break; case Engine::SystemState::GameDemo: diff --git a/src/games/phase-evasion/phase-evasion-core.cpp b/src/games/phase-evasion/controller.cpp similarity index 82% rename from src/games/phase-evasion/phase-evasion-core.cpp rename to src/games/phase-evasion/controller.cpp index b1a3a8e..3d7f82c 100644 --- a/src/games/phase-evasion/phase-evasion-core.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -1,10 +1,10 @@ -#include "games/phase-evasion/phase-evasion-core.h" +#include "games/phase-evasion/controller.h" #include "logger.h" namespace Games::PhaseEvasion { - Core::Core(::Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx} + Controller::Controller(::Core::ContextManager *ctx) : contextManager{ctx}, + player{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); @@ -12,7 +12,7 @@ namespace Games::PhaseEvasion wait(500); } - void Core::nextEvent() + void Controller::nextEvent() { switch (state.current) { @@ -40,13 +40,13 @@ namespace Games::PhaseEvasion } } - void Core::getUpdates() + void Controller::getUpdates() { player.checkColorChangeRequest(); flareMgr.updatePositions(); } - void Core::renderUserColor() + void Controller::renderUserColor() { for (uint16_t i = playerClearance; i < playerClearance + player.width; ++i) { @@ -54,7 +54,7 @@ namespace Games::PhaseEvasion } } - void Core::renderFlare() + void Controller::renderFlare() { for (const auto &flare : flareMgr) { @@ -68,7 +68,7 @@ namespace Games::PhaseEvasion } } - void Core::checkCollision() + void Controller::checkCollision() { for (const auto &flare : flareMgr) { @@ -82,7 +82,7 @@ namespace Games::PhaseEvasion } } - void Core::checkGrowth() + void Controller::checkGrowth() { if (isReady()) { diff --git a/src/games/phase-evasion/phase-evasion-flare-manager.cpp b/src/games/phase-evasion/flare-manager.cpp similarity index 93% rename from src/games/phase-evasion/phase-evasion-flare-manager.cpp rename to src/games/phase-evasion/flare-manager.cpp index 87fd341..d8545a2 100644 --- a/src/games/phase-evasion/phase-evasion-flare-manager.cpp +++ b/src/games/phase-evasion/flare-manager.cpp @@ -1,4 +1,4 @@ -#include "games/phase-evasion/phase-evasion-flare-manager.h" +#include "games/phase-evasion/flare-manager.h" #include "logger.h" namespace Games::PhaseEvasion diff --git a/src/games/phase-evasion/phase-evasion-flare.cpp b/src/games/phase-evasion/flare.cpp similarity index 65% rename from src/games/phase-evasion/phase-evasion-flare.cpp rename to src/games/phase-evasion/flare.cpp index 4d7d547..4183954 100644 --- a/src/games/phase-evasion/phase-evasion-flare.cpp +++ b/src/games/phase-evasion/flare.cpp @@ -1,4 +1,4 @@ -#include "games/phase-evasion/phase-evasion-flare.h" +#include "games/phase-evasion/flare.h" namespace Games::PhaseEvasion { diff --git a/src/games/phase-evasion/phase-evasion-player.cpp b/src/games/phase-evasion/player.cpp similarity index 93% rename from src/games/phase-evasion/phase-evasion-player.cpp rename to src/games/phase-evasion/player.cpp index 4ad48dd..6ee4599 100644 --- a/src/games/phase-evasion/phase-evasion-player.cpp +++ b/src/games/phase-evasion/player.cpp @@ -1,4 +1,4 @@ -#include "games/phase-evasion/phase-evasion-player.h" +#include "games/phase-evasion/player.h" #include "logger.h" namespace Games::PhaseEvasion From 9863e8e54463e160e2719b5ceeebfb9ca07679f7 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Thu, 22 Jan 2026 21:40:08 -0600 Subject: [PATCH 14/21] Move Config to Core module --- include/{engine/system-config.h => core/configuration.h} | 4 ++-- include/core/context-manager.h | 6 +++--- include/display/display.h | 6 +++--- include/engine/engine.h | 2 +- include/games/demo/demo-core.h | 4 ++-- include/games/demo/demo-player.h | 4 ++-- include/games/phase-evasion/controller.h | 4 ++-- include/games/phase-evasion/flare.h | 4 ++-- include/games/phase-evasion/player.h | 4 ++-- include/games/recall/recall-core.h | 4 ++-- include/lights/led-luminance.h | 6 +++--- include/lights/led-strip.h | 8 ++++---- include/player/player.h | 4 ++-- include/scenes/canvas/canvas.h | 4 ++-- src/core/context-manager.cpp | 2 +- src/display/display.cpp | 2 +- src/engine/engine.cpp | 2 +- src/games/phase-evasion/controller.cpp | 4 ++-- src/games/recall/recall-core.cpp | 2 +- src/lights/led-strip.cpp | 6 +++--- src/scenes/canvas/canvas.cpp | 2 +- 21 files changed, 42 insertions(+), 42 deletions(-) rename include/{engine/system-config.h => core/configuration.h} (90%) diff --git a/include/engine/system-config.h b/include/core/configuration.h similarity index 90% rename from include/engine/system-config.h rename to include/core/configuration.h index 80f83ea..779a71f 100644 --- a/include/engine/system-config.h +++ b/include/core/configuration.h @@ -2,9 +2,9 @@ #include -namespace Engine +namespace SystemCore { - struct SystemConfig + struct Configuration { // REQUIRED: modify this address to match the mac address of your PS3 controller static constexpr char macAddress[] = "00:1b:fb:8e:87:ac"; diff --git a/include/core/context-manager.h b/include/core/context-manager.h index a17b12f..acf2aec 100644 --- a/include/core/context-manager.h +++ b/include/core/context-manager.h @@ -2,12 +2,12 @@ #include "engine/layer.h" #include "engine/state-manager.h" -#include "engine/system-config.h" +#include "core/configuration.h" #include "player/controller.h" #include "lights/led-strip.h" #include "display/display.h" -namespace Core +namespace SystemCore { class ContextManager { @@ -19,7 +19,7 @@ namespace Core Engine::Layer *application = nullptr; Engine::StateManager stateManager; - Engine::SystemConfig config; + SystemCore::Configuration config; Player::Controller controller; Lights::LedStrip leds; Display::OledDisplay display; diff --git a/include/display/display.h b/include/display/display.h index 5f961bc..05d77f7 100644 --- a/include/display/display.h +++ b/include/display/display.h @@ -12,7 +12,7 @@ #include "display/display-images.h" // forward declaration because of ContextManager/OledDisplay circular dependency -namespace Core +namespace SystemCore { class ContextManager; } @@ -23,7 +23,7 @@ namespace Display class OledDisplay { public: - OledDisplay(Core::ContextManager *contextManager); + OledDisplay(SystemCore::ContextManager *contextManager); void updateDisplay(); private: @@ -32,7 +32,7 @@ namespace Display static constexpr int DISPLAY_ADDRESS = 0x3c; Adafruit_SSD1306 display; - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; ImageInitLogo initLogo; char selectedOption(uint8_t index, uint8_t selectedOptionIndex) { return index == selectedOptionIndex ? '>' : ' '; }; diff --git a/include/engine/engine.h b/include/engine/engine.h index f4a97c5..634bf66 100644 --- a/include/engine/engine.h +++ b/include/engine/engine.h @@ -16,7 +16,7 @@ namespace Engine void standbyControllerConnection(); private: - Core::ContextManager contextManager; + SystemCore::ContextManager contextManager; uint32_t lastRender = 0; void initializeEngine(); void renderLedStrip(); diff --git a/include/games/demo/demo-core.h b/include/games/demo/demo-core.h index b2b8414..1e23cb8 100644 --- a/include/games/demo/demo-core.h +++ b/include/games/demo/demo-core.h @@ -9,7 +9,7 @@ namespace Games class DemoCore : public Engine::Layer { public: - DemoCore(Core::ContextManager *ctx) : Engine::Layer{}, contextManager{ctx}, player1{DemoPlayer{ctx}}, player2{DemoPlayer{ctx}} + DemoCore(SystemCore::ContextManager *ctx) : Engine::Layer{}, contextManager{ctx}, player1{DemoPlayer{ctx}}, player2{DemoPlayer{ctx}} { contextManager->stateManager.getDemoGameState().reset(); } @@ -21,7 +21,7 @@ namespace Games void incrementHighScore(); private: - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; DemoPlayer player1; DemoPlayer player2; static constexpr float speed = 4.0f; diff --git a/include/games/demo/demo-player.h b/include/games/demo/demo-player.h index fa8da66..989cc94 100644 --- a/include/games/demo/demo-player.h +++ b/include/games/demo/demo-player.h @@ -8,12 +8,12 @@ namespace Games class DemoPlayer : public Player::Player { public: - DemoPlayer(Core::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; + DemoPlayer(SystemCore::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; void updatePlayer1LedBuffer(); void updatePlayer2LedBuffer(); private: - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; static constexpr uint16_t width = 7; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/controller.h b/include/games/phase-evasion/controller.h index 086ae6c..67eb815 100644 --- a/include/games/phase-evasion/controller.h +++ b/include/games/phase-evasion/controller.h @@ -12,12 +12,12 @@ namespace Games::PhaseEvasion class Controller : public Engine::Layer, private Engine::Timer { public: - Controller(::Core::ContextManager *ctx); + Controller(::SystemCore::ContextManager *ctx); void nextEvent() override; static constexpr uint16_t playerClearance = 20; private: - ::Core::ContextManager *contextManager; + ::SystemCore::ContextManager *contextManager; GameState &state = contextManager->stateManager.getPhaseEvasionGameState(); Player player; FlareManager flareMgr; diff --git a/include/games/phase-evasion/flare.h b/include/games/phase-evasion/flare.h index a43642a..90b9fa4 100644 --- a/include/games/phase-evasion/flare.h +++ b/include/games/phase-evasion/flare.h @@ -5,7 +5,7 @@ #include "common.h" #include "engine/timer.h" -#include "engine/system-config.h" +#include "core/configuration.h" #include "lights/color.h" #include "lights/color-code.h" @@ -16,7 +16,7 @@ namespace Games::PhaseEvasion public: Flare() = delete; Flare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, - positionFloat{Engine::SystemConfig::numLeds + width}, + positionFloat{SystemCore::Configuration::numLeds + width}, speed{s} {} static constexpr uint16_t width = 10; void updatePosition(); diff --git a/include/games/phase-evasion/player.h b/include/games/phase-evasion/player.h index 2d60715..9adaab7 100644 --- a/include/games/phase-evasion/player.h +++ b/include/games/phase-evasion/player.h @@ -8,13 +8,13 @@ namespace Games::PhaseEvasion class Player : public ::Player::Player { public: - Player(::Core::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; + Player(::SystemCore::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; void checkColorChangeRequest(); Lights::Color getColor() { return currentColor; } static constexpr uint16_t width = 10; private: - ::Core::ContextManager *contextManager; + ::SystemCore::ContextManager *contextManager; Lights::Color currentColor; static constexpr ::Player::ControllerButton availableGameplayButtons[] = { ::Player::ControllerButton::Cross, diff --git a/include/games/recall/recall-core.h b/include/games/recall/recall-core.h index 99341dc..73f833e 100644 --- a/include/games/recall/recall-core.h +++ b/include/games/recall/recall-core.h @@ -11,11 +11,11 @@ namespace Games class RecallCore : public Engine::Layer, private Engine::Timer { public: - RecallCore(Core::ContextManager *ctx); + RecallCore(SystemCore::ContextManager *ctx); void nextEvent() override; private: - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; RecallGameState &state = contextManager->stateManager.getRecallGameState(); uint16_t gameplaySpeedIlluminated = 500; diff --git a/include/lights/led-luminance.h b/include/lights/led-luminance.h index fabdfdd..d10a4b1 100644 --- a/include/lights/led-luminance.h +++ b/include/lights/led-luminance.h @@ -1,13 +1,13 @@ #pragma once -#include "engine/system-config.h" +#include "core/configuration.h" namespace Lights { class LedLuminance { public: - LedLuminance(Engine::SystemConfig &configuration) : config{configuration} {} + LedLuminance(SystemCore::Configuration &configuration) : config{configuration} {} static constexpr float MAX_LED_BRIGHTNESS = 255.0f; static constexpr int MAX_ADC_READING = 4095; @@ -17,7 +17,7 @@ namespace Lights static uint8_t applyGamma(uint8_t value); private: - const Engine::SystemConfig &config; + const SystemCore::Configuration &config; int currentLuminance = MAX_ADC_READING; }; } \ No newline at end of file diff --git a/include/lights/led-strip.h b/include/lights/led-strip.h index c5a650c..c7dadcd 100644 --- a/include/lights/led-strip.h +++ b/include/lights/led-strip.h @@ -1,6 +1,6 @@ #pragma once -#include "engine/system-config.h" +#include "core/configuration.h" #include "lights/color.h" #include "lights/led-buffer.h" #include "lights/led-luminance.h" @@ -11,15 +11,15 @@ namespace Lights { public: LedBuffer buffer; - LedStrip(Engine::SystemConfig &configuration); + LedStrip(SystemCore::Configuration &configuration); Color *getRawColors(); - static constexpr uint16_t size() { return Engine::SystemConfig::numLeds; } + static constexpr uint16_t size() { return SystemCore::Configuration::numLeds; } void reset(); void adjustLuminance(); private: - const Engine::SystemConfig &config; + const SystemCore::Configuration &config; LedLuminance luminance; }; } \ No newline at end of file diff --git a/include/player/player.h b/include/player/player.h index decd206..6ded16e 100644 --- a/include/player/player.h +++ b/include/player/player.h @@ -7,12 +7,12 @@ namespace Player class Player { public: - Player(Core::ContextManager *ctx) : contextManager{ctx} {}; + Player(SystemCore::ContextManager *ctx) : contextManager{ctx} {}; void move(const int distance, const float speed); uint16_t getPosition() { return position; } protected: - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; uint16_t position = 0; float positionPrecise = 0.0f; }; diff --git a/include/scenes/canvas/canvas.h b/include/scenes/canvas/canvas.h index d9e0a70..193e9a1 100644 --- a/include/scenes/canvas/canvas.h +++ b/include/scenes/canvas/canvas.h @@ -9,11 +9,11 @@ namespace Scenes class Canvas : public Engine::Layer, private Engine::Timer { public: - Canvas(Core::ContextManager *ctx); + Canvas(SystemCore::ContextManager *ctx); void nextEvent() override; private: - Core::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; CanvasSceneState &state = contextManager->stateManager.getCanvasSceneState(); Lights::ColorHsl colorHsl; bool hasChange = false; diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index 9ff7be5..14b6370 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -5,7 +5,7 @@ #include "scenes/canvas/canvas.h" #include "logger.h" -namespace Core +namespace SystemCore { ContextManager::ContextManager() : leds{config}, display{this} {} diff --git a/src/display/display.cpp b/src/display/display.cpp index c4a2a69..59a53b3 100644 --- a/src/display/display.cpp +++ b/src/display/display.cpp @@ -5,7 +5,7 @@ namespace Display { - OledDisplay::OledDisplay(Core::ContextManager *ctx) : contextManager{ctx} + OledDisplay::OledDisplay(SystemCore::ContextManager *ctx) : contextManager{ctx} { Wire.begin(); display.begin(SSD1306_SWITCHCAPVCC, DISPLAY_ADDRESS); diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 6f248af..a2c2f33 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -206,7 +206,7 @@ namespace Engine void GameEngine::displayTask(void *param) { - auto *ctx = static_cast(param); + auto *ctx = static_cast(param); while (true) { if (ctx->stateManager.displayShouldUpdate) diff --git a/src/games/phase-evasion/controller.cpp b/src/games/phase-evasion/controller.cpp index 3d7f82c..5133863 100644 --- a/src/games/phase-evasion/controller.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -3,8 +3,8 @@ namespace Games::PhaseEvasion { - Controller::Controller(::Core::ContextManager *ctx) : contextManager{ctx}, - player{ctx} + Controller::Controller(::SystemCore::ContextManager *ctx) : contextManager{ctx}, + player{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); diff --git a/src/games/recall/recall-core.cpp b/src/games/recall/recall-core.cpp index eb9cace..ab50efc 100644 --- a/src/games/recall/recall-core.cpp +++ b/src/games/recall/recall-core.cpp @@ -6,7 +6,7 @@ namespace Games { - RecallCore::RecallCore(Core::ContextManager *ctx) : contextManager{ctx} + RecallCore::RecallCore(SystemCore::ContextManager *ctx) : contextManager{ctx} { setupGameColors(); state = contextManager->stateManager.getRecallGameState(); diff --git a/src/lights/led-strip.cpp b/src/lights/led-strip.cpp index 7b7fbd2..f07fd62 100644 --- a/src/lights/led-strip.cpp +++ b/src/lights/led-strip.cpp @@ -2,9 +2,9 @@ namespace Lights { - LedStrip::LedStrip(Engine::SystemConfig &configuration) : config{configuration}, - buffer{configuration.numLeds}, - luminance{configuration} + LedStrip::LedStrip(SystemCore::Configuration &configuration) : config{configuration}, + buffer{configuration.numLeds}, + luminance{configuration} { #ifdef RELEASE FastLED.addLeds(static_cast(buffer), size()); diff --git a/src/scenes/canvas/canvas.cpp b/src/scenes/canvas/canvas.cpp index 33a2f09..f42e946 100644 --- a/src/scenes/canvas/canvas.cpp +++ b/src/scenes/canvas/canvas.cpp @@ -6,7 +6,7 @@ namespace Scenes { - Canvas::Canvas(Core::ContextManager *ctx) : contextManager{ctx} + Canvas::Canvas(SystemCore::ContextManager *ctx) : contextManager{ctx} { reset(); } From d99ea30982b50e697dbad51df5877421fb48845f Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Fri, 23 Jan 2026 20:14:36 -0600 Subject: [PATCH 15/21] Demo namespace --- include/display/display-images.h | 2 +- include/display/display.h | 2 +- include/engine/state-manager.h | 6 +++--- include/games/demo/{demo-core.h => controller.h} | 12 ++++++------ include/games/demo/{demo-player.h => player.h} | 6 +++--- include/games/demo/{demo-state.h => state.h} | 6 +++--- src/core/context-manager.cpp | 4 ++-- src/games/demo/{demo-core.cpp => core.cpp} | 12 ++++++------ src/games/demo/{demo-player.cpp => player.cpp} | 8 ++++---- 9 files changed, 29 insertions(+), 29 deletions(-) rename include/games/demo/{demo-core.h => controller.h} (67%) rename include/games/demo/{demo-player.h => player.h} (63%) rename include/games/demo/{demo-state.h => state.h} (62%) rename src/games/demo/{demo-core.cpp => core.cpp} (75%) rename src/games/demo/{demo-player.cpp => player.cpp} (89%) diff --git a/include/display/display-images.h b/include/display/display-images.h index f4fba66..8cd26ed 100644 --- a/include/display/display-images.h +++ b/include/display/display-images.h @@ -11,7 +11,7 @@ namespace Display { struct ImageInitLogo { - inline static const unsigned char rawValues[] PROGMEM = { + static constexpr unsigned char rawValues[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, diff --git a/include/display/display.h b/include/display/display.h index 05d77f7..e54e38f 100644 --- a/include/display/display.h +++ b/include/display/display.h @@ -11,9 +11,9 @@ #include "display/display-images.h" -// forward declaration because of ContextManager/OledDisplay circular dependency namespace SystemCore { + // forward declaration because of ContextManager/OledDisplay circular dependency class ContextManager; } diff --git a/include/engine/state-manager.h b/include/engine/state-manager.h index 100beda..fe55af9 100644 --- a/include/engine/state-manager.h +++ b/include/engine/state-manager.h @@ -2,7 +2,7 @@ #include "games/recall/recall-state.h" #include "games/phase-evasion/state.h" -#include "games/demo/demo-state.h" +#include "games/demo/state.h" #include "scenes/canvas/canvas-state.h" namespace Engine @@ -78,7 +78,7 @@ namespace Engine Games::RecallGameState &getRecallGameState() { return recallGameState; } Games::PhaseEvasion::GameState &getPhaseEvasionGameState() { return phaseEvasionGameState; } - Games::DemoGameState &getDemoGameState() { return demoGameState; } + Games::Demo::GameState &getDemoGameState() { return demoGameState; } Scenes::CanvasSceneState &getCanvasSceneState() { return canvasSceneState; } @@ -91,7 +91,7 @@ namespace Engine Games::RecallGameState recallGameState; Games::PhaseEvasion::GameState phaseEvasionGameState; - Games::DemoGameState demoGameState; + Games::Demo::GameState demoGameState; Scenes::CanvasSceneState canvasSceneState; }; diff --git a/include/games/demo/demo-core.h b/include/games/demo/controller.h similarity index 67% rename from include/games/demo/demo-core.h rename to include/games/demo/controller.h index 1e23cb8..c750e7e 100644 --- a/include/games/demo/demo-core.h +++ b/include/games/demo/controller.h @@ -2,14 +2,14 @@ #include "core/context-manager.h" #include "engine/layer.h" -#include "games/demo/demo-player.h" +#include "games/demo/player.h" -namespace Games +namespace Games::Demo { - class DemoCore : public Engine::Layer + class Controller : public Engine::Layer { public: - DemoCore(SystemCore::ContextManager *ctx) : Engine::Layer{}, contextManager{ctx}, player1{DemoPlayer{ctx}}, player2{DemoPlayer{ctx}} + Controller(SystemCore::ContextManager *ctx) : Engine::Layer{}, contextManager{ctx}, player1{Player{ctx}}, player2{Player{ctx}} { contextManager->stateManager.getDemoGameState().reset(); } @@ -22,8 +22,8 @@ namespace Games private: SystemCore::ContextManager *contextManager; - DemoPlayer player1; - DemoPlayer player2; + Player player1; + Player player2; static constexpr float speed = 4.0f; }; } \ No newline at end of file diff --git a/include/games/demo/demo-player.h b/include/games/demo/player.h similarity index 63% rename from include/games/demo/demo-player.h rename to include/games/demo/player.h index 989cc94..a4f4252 100644 --- a/include/games/demo/demo-player.h +++ b/include/games/demo/player.h @@ -3,12 +3,12 @@ #include "core/context-manager.h" #include "player/player.h" -namespace Games +namespace Games::Demo { - class DemoPlayer : public Player::Player + class Player : public ::Player::Player { public: - DemoPlayer(SystemCore::ContextManager *ctx) : contextManager{ctx}, Player::Player{ctx} {}; + Player(SystemCore::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; void updatePlayer1LedBuffer(); void updatePlayer2LedBuffer(); diff --git a/include/games/demo/demo-state.h b/include/games/demo/state.h similarity index 62% rename from include/games/demo/demo-state.h rename to include/games/demo/state.h index 5c95907..4c87d8d 100644 --- a/include/games/demo/demo-state.h +++ b/include/games/demo/state.h @@ -2,12 +2,12 @@ #include -namespace Games +namespace Games::Demo { - class DemoGameState + class GameState { public: - DemoGameState() : highScore{0}, currentScore{0} {} + GameState() : highScore{0}, currentScore{0} {} void reset() { highScore = currentScore = 0; } uint16_t highScore; uint16_t currentScore; diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index 14b6370..c012974 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -1,5 +1,5 @@ #include "core/context-manager.h" -#include "games/demo/demo-core.h" +#include "games/demo/controller.h" #include "games/recall/recall-core.h" #include "games/phase-evasion/controller.h" #include "scenes/canvas/canvas.h" @@ -158,7 +158,7 @@ namespace SystemCore logf("Transitioning to Phase Evasion (Game)"); break; case Engine::SystemState::GameDemo: - application = new Games::DemoCore{this}; + application = new Games::Demo::Controller{this}; logf("Transitioning to Demo (Game)"); break; case Engine::SystemState::SceneCanvas: diff --git a/src/games/demo/demo-core.cpp b/src/games/demo/core.cpp similarity index 75% rename from src/games/demo/demo-core.cpp rename to src/games/demo/core.cpp index 93c6853..b5ffe14 100644 --- a/src/games/demo/demo-core.cpp +++ b/src/games/demo/core.cpp @@ -1,12 +1,12 @@ -#include "games/demo/demo-core.h" +#include "games/demo/controller.h" #include "player/controller.h" #include "logger.h" -namespace Games +namespace Games::Demo { - void DemoCore::nextEvent() + void Controller::nextEvent() { - if (contextManager->controller.wasPressed(Player::ControllerButton::Cross)) + if (contextManager->controller.wasPressed(::Player::ControllerButton::Cross)) { incrementCurrentScore(); contextManager->stateManager.displayShouldUpdate = true; @@ -20,13 +20,13 @@ namespace Games player2.updatePlayer2LedBuffer(); } - void DemoCore::incrementCurrentScore() + void Controller::incrementCurrentScore() { ++contextManager->stateManager.getDemoGameState().currentScore; contextManager->stateManager.displayShouldUpdate = true; } - void DemoCore::incrementHighScore() + void Controller::incrementHighScore() { ++contextManager->stateManager.getDemoGameState().highScore; contextManager->stateManager.displayShouldUpdate = true; diff --git a/src/games/demo/demo-player.cpp b/src/games/demo/player.cpp similarity index 89% rename from src/games/demo/demo-player.cpp rename to src/games/demo/player.cpp index 8bcf014..645df10 100644 --- a/src/games/demo/demo-player.cpp +++ b/src/games/demo/player.cpp @@ -1,11 +1,11 @@ #include #include -#include "games/demo/demo-player.h" +#include "games/demo/player.h" -namespace Games +namespace Games::Demo { - void DemoPlayer::updatePlayer1LedBuffer() + void Player::updatePlayer1LedBuffer() { float center = (width + 1) / 2.0f; for (uint16_t i = 1; i <= width; ++i) @@ -21,7 +21,7 @@ namespace Games } } - void DemoPlayer::updatePlayer2LedBuffer() + void Player::updatePlayer2LedBuffer() { float center = (width + 1) / 2.0f; From 19cc8c63aa9d372c861c7f31ba986dc988604938 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Fri, 23 Jan 2026 20:20:11 -0600 Subject: [PATCH 16/21] Recall namespace --- include/engine/state-manager.h | 6 +- include/games/phase-evasion/controller.h | 4 +- include/games/phase-evasion/player.h | 4 +- .../recall/{recall-core.h => controller.h} | 8 +-- .../games/recall/{recall-state.h => state.h} | 10 ++-- src/core/context-manager.cpp | 4 +- src/games/phase-evasion/controller.cpp | 4 +- .../{recall-core.cpp => controller.cpp} | 58 +++++++++---------- 8 files changed, 49 insertions(+), 49 deletions(-) rename include/games/recall/{recall-core.h => controller.h} (85%) rename include/games/recall/{recall-state.h => state.h} (64%) rename src/games/recall/{recall-core.cpp => controller.cpp} (84%) diff --git a/include/engine/state-manager.h b/include/engine/state-manager.h index fe55af9..b7e4eb8 100644 --- a/include/engine/state-manager.h +++ b/include/engine/state-manager.h @@ -1,6 +1,6 @@ #pragma once -#include "games/recall/recall-state.h" +#include "games/recall/state.h" #include "games/phase-evasion/state.h" #include "games/demo/state.h" #include "scenes/canvas/canvas-state.h" @@ -76,7 +76,7 @@ namespace Engine const char *printGameName(uint8_t index); const char *printSceneName(uint8_t index); - Games::RecallGameState &getRecallGameState() { return recallGameState; } + Games::Recall::GameState &getRecallGameState() { return recallGameState; } Games::PhaseEvasion::GameState &getPhaseEvasionGameState() { return phaseEvasionGameState; } Games::Demo::GameState &getDemoGameState() { return demoGameState; } @@ -89,7 +89,7 @@ namespace Engine GameSelection userGameChoice = GameSelection::Demo; SceneSelection userSceneChoice = SceneSelection::Canvas; - Games::RecallGameState recallGameState; + Games::Recall::GameState recallGameState; Games::PhaseEvasion::GameState phaseEvasionGameState; Games::Demo::GameState demoGameState; diff --git a/include/games/phase-evasion/controller.h b/include/games/phase-evasion/controller.h index 67eb815..e487781 100644 --- a/include/games/phase-evasion/controller.h +++ b/include/games/phase-evasion/controller.h @@ -12,12 +12,12 @@ namespace Games::PhaseEvasion class Controller : public Engine::Layer, private Engine::Timer { public: - Controller(::SystemCore::ContextManager *ctx); + Controller(SystemCore::ContextManager *ctx); void nextEvent() override; static constexpr uint16_t playerClearance = 20; private: - ::SystemCore::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; GameState &state = contextManager->stateManager.getPhaseEvasionGameState(); Player player; FlareManager flareMgr; diff --git a/include/games/phase-evasion/player.h b/include/games/phase-evasion/player.h index 9adaab7..830fe91 100644 --- a/include/games/phase-evasion/player.h +++ b/include/games/phase-evasion/player.h @@ -8,13 +8,13 @@ namespace Games::PhaseEvasion class Player : public ::Player::Player { public: - Player(::SystemCore::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; + Player(SystemCore::ContextManager *ctx) : contextManager{ctx}, ::Player::Player{ctx} {}; void checkColorChangeRequest(); Lights::Color getColor() { return currentColor; } static constexpr uint16_t width = 10; private: - ::SystemCore::ContextManager *contextManager; + SystemCore::ContextManager *contextManager; Lights::Color currentColor; static constexpr ::Player::ControllerButton availableGameplayButtons[] = { ::Player::ControllerButton::Cross, diff --git a/include/games/recall/recall-core.h b/include/games/recall/controller.h similarity index 85% rename from include/games/recall/recall-core.h rename to include/games/recall/controller.h index 73f833e..81c4777 100644 --- a/include/games/recall/recall-core.h +++ b/include/games/recall/controller.h @@ -6,17 +6,17 @@ #include "lights/color.h" #include "lights/color-code.h" -namespace Games +namespace Games::Recall { - class RecallCore : public Engine::Layer, private Engine::Timer + class Controller : public Engine::Layer, private Engine::Timer { public: - RecallCore(SystemCore::ContextManager *ctx); + Controller(SystemCore::ContextManager *ctx); void nextEvent() override; private: SystemCore::ContextManager *contextManager; - RecallGameState &state = contextManager->stateManager.getRecallGameState(); + GameState &state = contextManager->stateManager.getRecallGameState(); uint16_t gameplaySpeedIlluminated = 500; uint16_t gameplaySpeedPaused = gameplaySpeedIlluminated / 6; diff --git a/include/games/recall/recall-state.h b/include/games/recall/state.h similarity index 64% rename from include/games/recall/recall-state.h rename to include/games/recall/state.h index c87fa1a..8155674 100644 --- a/include/games/recall/recall-state.h +++ b/include/games/recall/state.h @@ -2,9 +2,9 @@ #include -namespace Games +namespace Games::Recall { - enum class RecallStates + enum class Actions { Startup, ComputerPlaybackOnDisplay, @@ -14,13 +14,13 @@ namespace Games GameOver }; - class RecallGameState + class GameState { public: - RecallGameState() : highScore{0}, round{0} {} + GameState() : highScore{0}, round{0} {} uint16_t highScore; uint16_t round; - RecallStates current = RecallStates::Startup; + Actions current = Actions::Startup; void reset() { highScore = round = 0; } }; diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index c012974..bb5dcb2 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -1,6 +1,6 @@ #include "core/context-manager.h" #include "games/demo/controller.h" -#include "games/recall/recall-core.h" +#include "games/recall/controller.h" #include "games/phase-evasion/controller.h" #include "scenes/canvas/canvas.h" #include "logger.h" @@ -150,7 +150,7 @@ namespace SystemCore switch (stateManager.current()) { case Engine::SystemState::GameRecall: - application = new Games::RecallCore{this}; + application = new Games::Recall::Controller{this}; logf("Transitioning to Recall (Game)"); break; case Engine::SystemState::GamePhaseEvasion: diff --git a/src/games/phase-evasion/controller.cpp b/src/games/phase-evasion/controller.cpp index 5133863..3075c2e 100644 --- a/src/games/phase-evasion/controller.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -3,8 +3,8 @@ namespace Games::PhaseEvasion { - Controller::Controller(::SystemCore::ContextManager *ctx) : contextManager{ctx}, - player{ctx} + Controller::Controller(SystemCore::ContextManager *ctx) : contextManager{ctx}, + player{ctx} { state = contextManager->stateManager.getPhaseEvasionGameState(); state.reset(); diff --git a/src/games/recall/recall-core.cpp b/src/games/recall/controller.cpp similarity index 84% rename from src/games/recall/recall-core.cpp rename to src/games/recall/controller.cpp index ab50efc..55b16ed 100644 --- a/src/games/recall/recall-core.cpp +++ b/src/games/recall/controller.cpp @@ -1,21 +1,21 @@ #include "esp_system.h" -#include "games/recall/recall-core.h" +#include "games/recall/controller.h" #include "common.h" #include "logger.h" -namespace Games +namespace Games::Recall { - RecallCore::RecallCore(SystemCore::ContextManager *ctx) : contextManager{ctx} + Controller::Controller(SystemCore::ContextManager *ctx) : contextManager{ctx} { setupGameColors(); state = contextManager->stateManager.getRecallGameState(); state.reset(); - state.current = RecallStates::Startup; + state.current = Actions::Startup; wait(gameplaySpeedIlluminated); } - void RecallCore::setupGameColors() + void Controller::setupGameColors() { for (uint16_t i = 0; i < maxRound; ++i) { @@ -31,37 +31,37 @@ namespace Games logf(" Color=%u (%u - %u - %u)", button, color.r, color.g, color.b); } - void RecallCore::nextEvent() + void Controller::nextEvent() { handleUserSpeedChange(); switch (state.current) { - case RecallStates::Startup: + case Actions::Startup: if (isReady()) { - state.current = RecallStates::ComputerPlaybackOnDisplay; + state.current = Actions::ComputerPlaybackOnDisplay; wait(gameplaySpeedIlluminated); } break; - case RecallStates::ComputerPlaybackOnDisplay: + case Actions::ComputerPlaybackOnDisplay: displayComputerPlayback(); break; - case RecallStates::ComputerPlaybackPaused: + case Actions::ComputerPlaybackPaused: pauseComputerPlayback(); break; - case RecallStates::PlayerResponseEvaluation: + case Actions::PlayerResponseEvaluation: evaluateUserRecall(); break; - case RecallStates::PlayerResponseVerified: + case Actions::PlayerResponseVerified: prepareComputerPlayback(); break; - case RecallStates::GameOver: + case Actions::GameOver: gameOver(); break; } } - void RecallCore::handleUserSpeedChange() + void Controller::handleUserSpeedChange() { if (contextManager->controller.wasPressed(Player::ControllerButton::Up) || contextManager->controller.leftAnalog().y < -64) { @@ -77,11 +77,11 @@ namespace Games } } - void RecallCore::displayComputerPlayback() + void Controller::displayComputerPlayback() { if (isReady()) { - state.current = RecallStates::ComputerPlaybackPaused; + state.current = Actions::ComputerPlaybackPaused; wait(gameplaySpeedPaused); return; } @@ -104,11 +104,11 @@ namespace Games } } - void RecallCore::pauseComputerPlayback() + void Controller::pauseComputerPlayback() { if (sequenceIndex >= state.round) { - state.current = RecallStates::PlayerResponseEvaluation; + state.current = Actions::PlayerResponseEvaluation; sequenceIndex = 0; contextManager->controller.reset(); successFadeawayAnimation = 1; @@ -119,16 +119,16 @@ namespace Games if (isReady()) { ++sequenceIndex; - state.current = RecallStates::ComputerPlaybackOnDisplay; + state.current = Actions::ComputerPlaybackOnDisplay; wait(gameplaySpeedIlluminated); } } - void RecallCore::evaluateUserRecall() + void Controller::evaluateUserRecall() { if (sequenceIndex > state.round && isReady()) { - state.current = RecallStates::PlayerResponseVerified; + state.current = Actions::PlayerResponseVerified; ++state.round; contextManager->stateManager.displayShouldUpdate = true; contextManager->controller.reset(); @@ -140,7 +140,7 @@ namespace Games evaluateUserButton(gameplayColors[sequenceIndex]); } - void RecallCore::evaluateUserButton(Player::ControllerButton expectedButton) + void Controller::evaluateUserButton(Player::ControllerButton expectedButton) { for (auto button : availableGameplayButtons) { @@ -156,12 +156,12 @@ namespace Games } logf("User provided the incorrect answer. Entering game over sequence."); - state.current = RecallStates::GameOver; + state.current = Actions::GameOver; } } } - void RecallCore::illuminateOnSelection() + void Controller::illuminateOnSelection() { static uint32_t lastLightTime = 0; static int pressedButtonIndex = -1; @@ -190,7 +190,7 @@ namespace Games } } - std::pair RecallCore::directionBoundaries(Player::ControllerButton button) + std::pair Controller::directionBoundaries(Player::ControllerButton button) { const auto &boundary = contextManager->config.recallBoundaries; @@ -209,7 +209,7 @@ namespace Games } } - void RecallCore::prepareComputerPlayback() + void Controller::prepareComputerPlayback() { if (isReady()) { @@ -220,7 +220,7 @@ namespace Games auto &color = Lights::colorPalette[static_cast(button)]; logf(" Color=%u (%u - %u - %u)", button, color.r, color.g, color.b); } - state.current = RecallStates::ComputerPlaybackOnDisplay; + state.current = Actions::ComputerPlaybackOnDisplay; sequenceIndex = 0; wait(gameplaySpeedIlluminated); return; @@ -235,11 +235,11 @@ namespace Games successFadeawayAnimation = std::clamp(successFadeawayAnimation - 0.08, 0.0, 1.0); } - void RecallCore::gameOver() + void Controller::gameOver() { if (contextManager->controller.wasPressed(Player::ControllerButton::Start)) { - state.current = RecallStates::Startup; + state.current = Actions::Startup; sequenceIndex = 0; state.reset(); contextManager->stateManager.getRecallGameState().reset(); From 7a035c309568507a766fc4b74b5e0f3ad0c44413 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Fri, 23 Jan 2026 20:39:50 -0600 Subject: [PATCH 17/21] Canvas namespace --- include/common.h | 2 +- include/engine/state-manager.h | 6 ++-- include/scenes/canvas/canvas.h | 29 ------------------- include/scenes/canvas/controller.h | 29 +++++++++++++++++++ .../scenes/canvas/{canvas-state.h => state.h} | 6 ++-- src/core/context-manager.cpp | 4 +-- .../canvas/{canvas.cpp => controller.cpp} | 20 ++++++------- 7 files changed, 48 insertions(+), 48 deletions(-) delete mode 100644 include/scenes/canvas/canvas.h create mode 100644 include/scenes/canvas/controller.h rename include/scenes/canvas/{canvas-state.h => state.h} (57%) rename src/scenes/canvas/{canvas.cpp => controller.cpp} (88%) diff --git a/include/common.h b/include/common.h index c05325e..7949b86 100644 --- a/include/common.h +++ b/include/common.h @@ -1,6 +1,6 @@ #pragma once -#include +#include template constexpr uint16_t arraySize(const T (&)[N]) { return N; } diff --git a/include/engine/state-manager.h b/include/engine/state-manager.h index b7e4eb8..fa116d6 100644 --- a/include/engine/state-manager.h +++ b/include/engine/state-manager.h @@ -3,7 +3,7 @@ #include "games/recall/state.h" #include "games/phase-evasion/state.h" #include "games/demo/state.h" -#include "scenes/canvas/canvas-state.h" +#include "scenes/canvas/state.h" namespace Engine { @@ -80,7 +80,7 @@ namespace Engine Games::PhaseEvasion::GameState &getPhaseEvasionGameState() { return phaseEvasionGameState; } Games::Demo::GameState &getDemoGameState() { return demoGameState; } - Scenes::CanvasSceneState &getCanvasSceneState() { return canvasSceneState; } + Scenes::Canvas::SceneState &getCanvasSceneState() { return canvasSceneState; } private: SystemState systemState = SystemState::MenuHome; @@ -93,6 +93,6 @@ namespace Engine Games::PhaseEvasion::GameState phaseEvasionGameState; Games::Demo::GameState demoGameState; - Scenes::CanvasSceneState canvasSceneState; + Scenes::Canvas::SceneState canvasSceneState; }; } \ No newline at end of file diff --git a/include/scenes/canvas/canvas.h b/include/scenes/canvas/canvas.h deleted file mode 100644 index 193e9a1..0000000 --- a/include/scenes/canvas/canvas.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "core/context-manager.h" -#include "engine/timer.h" -#include "lights/color-hsl.h" - -namespace Scenes -{ - class Canvas : public Engine::Layer, private Engine::Timer - { - public: - Canvas(SystemCore::ContextManager *ctx); - void nextEvent() override; - - private: - SystemCore::ContextManager *contextManager; - CanvasSceneState &state = contextManager->stateManager.getCanvasSceneState(); - Lights::ColorHsl colorHsl; - bool hasChange = false; - bool controllerWasActive = false; - - inline void checkAnalogColorChange(); - inline void checkBalanceColorRequest(); - inline void checkNewColorRequest(); - inline void checkStableControllerForDisplay(); - inline void checkChangeOccured(); - inline void reset(); - }; -} \ No newline at end of file diff --git a/include/scenes/canvas/controller.h b/include/scenes/canvas/controller.h new file mode 100644 index 0000000..d62998f --- /dev/null +++ b/include/scenes/canvas/controller.h @@ -0,0 +1,29 @@ +#pragma once + +#include "core/context-manager.h" +#include "engine/timer.h" +#include "lights/color-hsl.h" + +namespace Scenes::Canvas +{ + class Controller : public Engine::Layer, private Engine::Timer + { + public: + Controller(SystemCore::ContextManager *ctx); + void nextEvent() override; + + private: + SystemCore::ContextManager *contextManager; + SceneState &state = contextManager->stateManager.getCanvasSceneState(); + Lights::ColorHsl colorHsl; + bool hasChange = false; + bool controllerWasActive = false; + + void checkAnalogColorChange(); + void checkBalanceColorRequest(); + void checkNewColorRequest(); + void checkStableControllerForDisplay(); + void checkChangeOccured(); + void reset(); + }; +} \ No newline at end of file diff --git a/include/scenes/canvas/canvas-state.h b/include/scenes/canvas/state.h similarity index 57% rename from include/scenes/canvas/canvas-state.h rename to include/scenes/canvas/state.h index 096c192..9d9fd8a 100644 --- a/include/scenes/canvas/canvas-state.h +++ b/include/scenes/canvas/state.h @@ -4,12 +4,12 @@ #include "lights/color.h" -namespace Scenes +namespace Scenes::Canvas { - class CanvasSceneState + class SceneState { public: - CanvasSceneState() : currentColor{} {} + SceneState() : currentColor{} {} Lights::Color currentColor; }; } \ No newline at end of file diff --git a/src/core/context-manager.cpp b/src/core/context-manager.cpp index bb5dcb2..422fdc5 100644 --- a/src/core/context-manager.cpp +++ b/src/core/context-manager.cpp @@ -2,7 +2,7 @@ #include "games/demo/controller.h" #include "games/recall/controller.h" #include "games/phase-evasion/controller.h" -#include "scenes/canvas/canvas.h" +#include "scenes/canvas/controller.h" #include "logger.h" namespace SystemCore @@ -162,7 +162,7 @@ namespace SystemCore logf("Transitioning to Demo (Game)"); break; case Engine::SystemState::SceneCanvas: - application = new Scenes::Canvas{this}; + application = new Scenes::Canvas::Controller{this}; logf("Transitioning to Canvas (Scene)"); break; } diff --git a/src/scenes/canvas/canvas.cpp b/src/scenes/canvas/controller.cpp similarity index 88% rename from src/scenes/canvas/canvas.cpp rename to src/scenes/canvas/controller.cpp index f42e946..cdce2a7 100644 --- a/src/scenes/canvas/canvas.cpp +++ b/src/scenes/canvas/controller.cpp @@ -1,17 +1,17 @@ -#include "scenes/canvas/canvas.h" +#include "scenes/canvas/controller.h" #include "esp_system.h" #include "logger.h" #include -namespace Scenes +namespace Scenes::Canvas { - Canvas::Canvas(SystemCore::ContextManager *ctx) : contextManager{ctx} + Controller::Controller(SystemCore::ContextManager *ctx) : contextManager{ctx} { reset(); } - void Canvas::nextEvent() + void Controller::nextEvent() { checkAnalogColorChange(); checkBalanceColorRequest(); @@ -25,7 +25,7 @@ namespace Scenes } } - void Canvas::checkAnalogColorChange() + void Controller::checkAnalogColorChange() { if (contextManager->controller.leftAnalog().x > 64) { @@ -59,7 +59,7 @@ namespace Scenes } } - void Canvas::checkNewColorRequest() + void Controller::checkNewColorRequest() { if (contextManager->controller.wasPressed(Player::ControllerButton::Triangle)) { @@ -68,7 +68,7 @@ namespace Scenes } } - void Canvas::checkBalanceColorRequest() + void Controller::checkBalanceColorRequest() { if (contextManager->controller.wasPressed(Player::ControllerButton::L1)) { @@ -91,7 +91,7 @@ namespace Scenes } } - void Canvas::checkChangeOccured() + void Controller::checkChangeOccured() { if (hasChange) { @@ -102,7 +102,7 @@ namespace Scenes } } - void Canvas::checkStableControllerForDisplay() + void Controller::checkStableControllerForDisplay() { bool isMoving = abs(contextManager->controller.leftAnalog().x) > 64 || @@ -122,7 +122,7 @@ namespace Scenes } } - void Canvas::reset() + void Controller::reset() { colorHsl.hue = static_cast(esp_random() % std::numeric_limits::max()); colorHsl.saturation = static_cast((esp_random() % 64u) + 191u); From e0ee76d943516a236107d82e71b3496184d9913e Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sat, 24 Jan 2026 16:40:26 -0600 Subject: [PATCH 18/21] Vector to Array DS change --- include/games/phase-evasion/flare-manager.h | 18 +++---- include/games/phase-evasion/flare.h | 11 ++++- src/games/phase-evasion/controller.cpp | 8 +++- src/games/phase-evasion/flare-manager.cpp | 52 +++++++++------------ src/games/phase-evasion/flare.cpp | 20 +++++++- 5 files changed, 68 insertions(+), 41 deletions(-) diff --git a/include/games/phase-evasion/flare-manager.h b/include/games/phase-evasion/flare-manager.h index 1020c42..5c49b32 100644 --- a/include/games/phase-evasion/flare-manager.h +++ b/include/games/phase-evasion/flare-manager.h @@ -8,21 +8,23 @@ namespace Games::PhaseEvasion { public: FlareManager(); + FlareManager(const FlareManager &) = delete; + FlareManager &operator=(const FlareManager &) = delete; - Flare &operator[](uint16_t index) { return flares[index]; } - const Flare &operator[](uint16_t index) const { return flares[index]; } + Flare &operator[](uint16_t index) { return flarePool[index]; } + const Flare &operator[](uint16_t index) const { return flarePool[index]; } - fl::vector::iterator begin() { return flares.begin(); } - fl::vector::iterator end() { return flares.end(); } - fl::vector::const_iterator begin() const { return flares.begin(); } - fl::vector::const_iterator end() const { return flares.end(); } + auto begin() { return flarePool.begin(); } + auto end() { return flarePool.end(); } + const auto begin() const { return flarePool.begin(); } + const auto end() const { return flarePool.end(); } - fl::size size() { return flares.size(); } + const size_t size() const; void updatePositions(); void dispatch(); private: - fl::vector flares; + std::array flarePool; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/flare.h b/include/games/phase-evasion/flare.h index 90b9fa4..73127f1 100644 --- a/include/games/phase-evasion/flare.h +++ b/include/games/phase-evasion/flare.h @@ -14,16 +14,25 @@ namespace Games::PhaseEvasion class Flare : public Engine::Timer { public: - Flare() = delete; + Flare() : active{false}, + color{Lights::ColorCode::GameRed}, + speed{0.75}, + positionFloat{SystemCore::Configuration::numLeds + width} {}; + Flare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, positionFloat{SystemCore::Configuration::numLeds + width}, speed{s} {} static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() const { return static_cast(positionFloat); } + const Lights::Color getColor() const { return color; } + const bool isActive() const { return active; } + void activate(); + void deactivate(); private: + bool active = false; const Lights::Color color; const float speed; float positionFloat; diff --git a/src/games/phase-evasion/controller.cpp b/src/games/phase-evasion/controller.cpp index 3075c2e..c710f0f 100644 --- a/src/games/phase-evasion/controller.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -27,7 +27,7 @@ namespace Games::PhaseEvasion case Actions::ActiveGame: getUpdates(); checkGrowth(); - checkCollision(); + // checkCollision(); renderFlare(); renderUserColor(); break; @@ -58,6 +58,9 @@ namespace Games::PhaseEvasion { for (const auto &flare : flareMgr) { + if (!flare.isActive()) + continue; + uint16_t start = std::max(flare.getPosition() - flare.width, 0); uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); @@ -72,6 +75,9 @@ namespace Games::PhaseEvasion { for (const auto &flare : flareMgr) { + if (!flare.isActive()) + continue; + uint16_t start = std::max(flare.getPosition() - flare.width, 0); uint16_t end = std::min(flare.getPosition(), contextManager->config.numLeds); diff --git a/src/games/phase-evasion/flare-manager.cpp b/src/games/phase-evasion/flare-manager.cpp index d8545a2..7ff797f 100644 --- a/src/games/phase-evasion/flare-manager.cpp +++ b/src/games/phase-evasion/flare-manager.cpp @@ -5,47 +5,39 @@ namespace Games::PhaseEvasion { FlareManager::FlareManager() { - flares.emplace_back(0.75f); + dispatch(); } void FlareManager::dispatch() { - flares.emplace_back(0.75f); + auto flare = flarePool.begin(); + while (flare != flarePool.end()) + { + if (!flare->isActive()) + { + flare->activate(); + logf("Flare #%lu dispatched", (unsigned long)size()); + return; + } + ++flare; + } + logf("Flare dispatch: no free flares"); } void FlareManager::updatePositions() { - bool started = false; - fl::vector survivors; - - for (auto itr = flares.begin(); itr != flares.end(); ++itr) + for (auto flare = flarePool.begin(); flare != flarePool.end(); ++flare) { - itr->updatePosition(); + if (!flare->isActive()) + continue; - if (itr->getPosition() > 0) - { - if (started) - { - survivors.push_back(fl::move(*itr)); - } - } - else - { - if (!started) - { - started = true; - survivors.reserve(flares.size()); - for (auto prev = flares.begin(); prev != itr; ++prev) - { - survivors.push_back(fl::move(*prev)); - } - } - } + flare->updatePosition(); } + } - if (started) - { - flares.swap(survivors); - } + const size_t FlareManager::size() const + { + return std::count_if(flarePool.begin(), flarePool.end(), [](const Flare &flare) + { return flare.isActive(); }); } } \ No newline at end of file diff --git a/src/games/phase-evasion/flare.cpp b/src/games/phase-evasion/flare.cpp index 4183954..979a4b5 100644 --- a/src/games/phase-evasion/flare.cpp +++ b/src/games/phase-evasion/flare.cpp @@ -4,6 +4,24 @@ namespace Games::PhaseEvasion { void Flare::updatePosition() { - positionFloat -= speed; + if (positionFloat <= 0) + { + active = false; + } + else + { + positionFloat -= speed; + } + } + + void Flare::activate() + { + active = true; + positionFloat = static_cast(SystemCore::Configuration::numLeds + width); + } + + void Flare::deactivate() + { + active = false; } } \ No newline at end of file From 1c1d113ffad2cd1a6cc85d4146eb49ae39c10fcc Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Sun, 25 Jan 2026 22:27:42 -0600 Subject: [PATCH 19/21] Validate manager tracks positions --- include/games/phase-evasion/controller.h | 2 +- include/games/phase-evasion/flare-manager.h | 4 ++-- include/games/phase-evasion/flare.h | 7 ++----- src/games/phase-evasion/controller.cpp | 11 ++++++----- src/games/phase-evasion/flare-manager.cpp | 12 +++--------- src/games/phase-evasion/flare.cpp | 2 +- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/include/games/phase-evasion/controller.h b/include/games/phase-evasion/controller.h index e487781..083a9e6 100644 --- a/include/games/phase-evasion/controller.h +++ b/include/games/phase-evasion/controller.h @@ -20,7 +20,7 @@ namespace Games::PhaseEvasion SystemCore::ContextManager *contextManager; GameState &state = contextManager->stateManager.getPhaseEvasionGameState(); Player player; - FlareManager flareMgr; + FlareManager flareManager; void getUpdates(); void renderUserColor(); diff --git a/include/games/phase-evasion/flare-manager.h b/include/games/phase-evasion/flare-manager.h index 5c49b32..9bad831 100644 --- a/include/games/phase-evasion/flare-manager.h +++ b/include/games/phase-evasion/flare-manager.h @@ -7,7 +7,7 @@ namespace Games::PhaseEvasion class FlareManager : public Engine::Timer { public: - FlareManager(); + FlareManager() = default; FlareManager(const FlareManager &) = delete; FlareManager &operator=(const FlareManager &) = delete; @@ -25,6 +25,6 @@ namespace Games::PhaseEvasion void dispatch(); private: - std::array flarePool; + std::array flarePool; }; } \ No newline at end of file diff --git a/include/games/phase-evasion/flare.h b/include/games/phase-evasion/flare.h index 73127f1..ee2e6cf 100644 --- a/include/games/phase-evasion/flare.h +++ b/include/games/phase-evasion/flare.h @@ -19,20 +19,17 @@ namespace Games::PhaseEvasion speed{0.75}, positionFloat{SystemCore::Configuration::numLeds + width} {}; - Flare(const float s) : color{Lights::colorPalette[static_cast(esp_random()) % arraySize(Lights::colorPalette)]}, - positionFloat{SystemCore::Configuration::numLeds + width}, - speed{s} {} static constexpr uint16_t width = 10; void updatePosition(); uint16_t getPosition() const { return static_cast(positionFloat); } const Lights::Color getColor() const { return color; } - const bool isActive() const { return active; } + bool isActive() const { return active; } void activate(); void deactivate(); private: - bool active = false; + bool active; const Lights::Color color; const float speed; float positionFloat; diff --git a/src/games/phase-evasion/controller.cpp b/src/games/phase-evasion/controller.cpp index c710f0f..f90d361 100644 --- a/src/games/phase-evasion/controller.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -20,8 +20,9 @@ namespace Games::PhaseEvasion if (isReady()) { state.current = Actions::ActiveGame; - wait(1000); + flareManager.dispatch(); log("Starting new game."); + wait(1000); } break; case Actions::ActiveGame: @@ -43,7 +44,7 @@ namespace Games::PhaseEvasion void Controller::getUpdates() { player.checkColorChangeRequest(); - flareMgr.updatePositions(); + flareManager.updatePositions(); } void Controller::renderUserColor() @@ -56,7 +57,7 @@ namespace Games::PhaseEvasion void Controller::renderFlare() { - for (const auto &flare : flareMgr) + for (const auto &flare : flareManager) { if (!flare.isActive()) continue; @@ -73,7 +74,7 @@ namespace Games::PhaseEvasion void Controller::checkCollision() { - for (const auto &flare : flareMgr) + for (const auto &flare : flareManager) { if (!flare.isActive()) continue; @@ -92,7 +93,7 @@ namespace Games::PhaseEvasion { if (isReady()) { - flareMgr.dispatch(); + flareManager.dispatch(); wait(1000); } } diff --git a/src/games/phase-evasion/flare-manager.cpp b/src/games/phase-evasion/flare-manager.cpp index 7ff797f..f8b9945 100644 --- a/src/games/phase-evasion/flare-manager.cpp +++ b/src/games/phase-evasion/flare-manager.cpp @@ -3,11 +3,6 @@ namespace Games::PhaseEvasion { - FlareManager::FlareManager() - { - dispatch(); - } - void FlareManager::dispatch() { auto flare = flarePool.begin(); @@ -16,7 +11,6 @@ namespace Games::PhaseEvasion if (!flare->isActive()) { flare->activate(); - logf("Flare #%lu dispatched", (unsigned long)size()); return; } ++flare; @@ -26,12 +20,12 @@ namespace Games::PhaseEvasion void FlareManager::updatePositions() { - for (auto flare = flarePool.begin(); flare != flarePool.end(); ++flare) + for (auto &flare : flarePool) { - if (!flare->isActive()) + if (!flare.isActive()) continue; - flare->updatePosition(); + flare.updatePosition(); } } diff --git a/src/games/phase-evasion/flare.cpp b/src/games/phase-evasion/flare.cpp index 979a4b5..8da1ae2 100644 --- a/src/games/phase-evasion/flare.cpp +++ b/src/games/phase-evasion/flare.cpp @@ -4,7 +4,7 @@ namespace Games::PhaseEvasion { void Flare::updatePosition() { - if (positionFloat <= 0) + if (positionFloat <= 0.0f) { active = false; } From 9fe0f373108371c86e9f53c050519f17024dc247 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Mon, 26 Jan 2026 23:30:04 -0600 Subject: [PATCH 20/21] Manager controls Flare config --- include/games/phase-evasion/flare.h | 11 +++++------ src/games/phase-evasion/flare-manager.cpp | 4 +++- src/games/phase-evasion/flare.cpp | 5 ++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/games/phase-evasion/flare.h b/include/games/phase-evasion/flare.h index ee2e6cf..a5ddcfe 100644 --- a/include/games/phase-evasion/flare.h +++ b/include/games/phase-evasion/flare.h @@ -7,7 +7,6 @@ #include "engine/timer.h" #include "core/configuration.h" #include "lights/color.h" -#include "lights/color-code.h" namespace Games::PhaseEvasion { @@ -15,8 +14,8 @@ namespace Games::PhaseEvasion { public: Flare() : active{false}, - color{Lights::ColorCode::GameRed}, - speed{0.75}, + color{Lights::Color::WhiteSmoke}, + speed{0.0f}, positionFloat{SystemCore::Configuration::numLeds + width} {}; static constexpr uint16_t width = 10; @@ -25,13 +24,13 @@ namespace Games::PhaseEvasion const Lights::Color getColor() const { return color; } bool isActive() const { return active; } - void activate(); + void activate(Lights::Color color, float speed); void deactivate(); private: bool active; - const Lights::Color color; - const float speed; + Lights::Color color; + float speed; float positionFloat; }; } \ No newline at end of file diff --git a/src/games/phase-evasion/flare-manager.cpp b/src/games/phase-evasion/flare-manager.cpp index f8b9945..b30a3a4 100644 --- a/src/games/phase-evasion/flare-manager.cpp +++ b/src/games/phase-evasion/flare-manager.cpp @@ -1,4 +1,5 @@ #include "games/phase-evasion/flare-manager.h" +#include "common.h" #include "logger.h" namespace Games::PhaseEvasion @@ -10,7 +11,8 @@ namespace Games::PhaseEvasion { if (!flare->isActive()) { - flare->activate(); + uint16_t colorIndex = static_cast(esp_random()) % arraySize(Lights::colorPalette); + flare->activate(Lights::colorPalette[colorIndex], 0.75); return; } ++flare; diff --git a/src/games/phase-evasion/flare.cpp b/src/games/phase-evasion/flare.cpp index 8da1ae2..8dae6a2 100644 --- a/src/games/phase-evasion/flare.cpp +++ b/src/games/phase-evasion/flare.cpp @@ -7,6 +7,7 @@ namespace Games::PhaseEvasion if (positionFloat <= 0.0f) { active = false; + color = Lights::Color::WhiteSmoke; } else { @@ -14,9 +15,11 @@ namespace Games::PhaseEvasion } } - void Flare::activate() + void Flare::activate(Lights::Color _color, float _speed) { active = true; + color = _color; + speed = _speed; positionFloat = static_cast(SystemCore::Configuration::numLeds + width); } From b6fe373a37220f9c1be0d3bfb57366f16c88a423 Mon Sep 17 00:00:00 2001 From: Eric McDaniel Date: Thu, 29 Jan 2026 19:19:48 -0600 Subject: [PATCH 21/21] MLP, playable --- include/games/phase-evasion/flare-manager.h | 2 +- src/engine/engine.cpp | 1 + src/games/phase-evasion/controller.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/games/phase-evasion/flare-manager.h b/include/games/phase-evasion/flare-manager.h index 9bad831..e2db21f 100644 --- a/include/games/phase-evasion/flare-manager.h +++ b/include/games/phase-evasion/flare-manager.h @@ -25,6 +25,6 @@ namespace Games::PhaseEvasion void dispatch(); private: - std::array flarePool; + std::array flarePool; }; } \ No newline at end of file diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index a2c2f33..7044a89 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -110,6 +110,7 @@ namespace Engine lastRender = micros(); log("Startup process completed. Transitioning to Main Menu"); } + randomSeed(esp_random()); } void GameEngine::standbyControllerConnection() diff --git a/src/games/phase-evasion/controller.cpp b/src/games/phase-evasion/controller.cpp index f90d361..66ddbfe 100644 --- a/src/games/phase-evasion/controller.cpp +++ b/src/games/phase-evasion/controller.cpp @@ -28,7 +28,7 @@ namespace Games::PhaseEvasion case Actions::ActiveGame: getUpdates(); checkGrowth(); - // checkCollision(); + checkCollision(); renderFlare(); renderUserColor(); break;