// MenuState.h #pragma once #include "State.h" class MenuState : public State { public: MenuState(StateContext& ctx); void onEnter() override; void onExit() override; void handleEvent(const SDL_Event& e) override; void update(double frameMs) override; void render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) override; // When false, the main PLAY button is not drawn by `render()` and can be // rendered separately with `renderMainButtonTop` (useful for layer ordering). bool drawMainButtonNormally = true; // Draw only the main PLAY button on top of other layers (expects logical coords). void renderMainButtonTop(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP); // Show or hide the inline HELP panel (menu-style) void showHelpPanel(bool show); // Show or hide the inline ABOUT panel (menu-style) void showAboutPanel(bool show); // Show or hide the inline COOPERATE setup panel (2P vs AI). void showCoopSetupPanel(bool show); private: int selectedButton = 0; // 0=PLAY,1=COOPERATE,2=CHALLENGE,3=LEVEL,4=OPTIONS,5=HELP,6=ABOUT,7=EXIT // Button icons (optional - will use text if nullptr) SDL_Texture* playIcon = nullptr; SDL_Texture* levelIcon = nullptr; SDL_Texture* optionsIcon = nullptr; SDL_Texture* exitIcon = nullptr; SDL_Texture* helpIcon = nullptr; // Options panel animation state bool optionsVisible = false; bool optionsAnimating = false; double optionsTransition = 0.0; // 0..1 double optionsTransitionDurationMs = 400.0; int optionsDirection = 1; // 1 show, -1 hide // Which row in the inline options panel is currently selected (0..4) int optionsSelectedRow = 0; // Inline level selector HUD state bool levelPanelVisible = false; bool levelPanelAnimating = false; double levelTransition = 0.0; // 0..1 double levelTransitionDurationMs = 400.0; int levelDirection = 1; // 1 show, -1 hide int levelHovered = -1; // hovered cell int levelSelected = 0; // current selected level // Cache logical viewport/scale for input conversion when needed float lastLogicalScale = 1.0f; SDL_Rect lastLogicalVP{0,0,0,0}; // Animated highlight position (world/logical coordinates) double levelHighlightX = 0.0; double levelHighlightY = 0.0; bool levelHighlightInitialized = false; // Highlight tuning parameters double levelHighlightSpeed = 0.018; // smoothing constant - higher = snappier double levelHighlightGlowAlpha = 0.70; // 0..1 base glow alpha int levelHighlightThickness = 3; // inner outline thickness (px) SDL_Color levelHighlightColor = SDL_Color{80, 200, 255, 200}; // Button pulsing/fade parameters (used for PLAY emphasis) double buttonGroupAlpha = 1.0; // base alpha for the whole group (kept stable) double buttonPulseAlpha = 1.0; // pulsing alpha (0..1), applied to PLAY only double buttonPulseTime = 0.0; // accumulator in ms bool buttonPulseEnabled = true; // enable/disable pulsing double buttonPulseSpeed = 1.0; // multiplier for pulse frequency double buttonPulseMinAlpha = 0.60; // minimum alpha during pulse double buttonPulseMaxAlpha = 1.00; // maximum alpha during pulse // Pulse easing mode: 0=sin,1=triangle,2=exponential int buttonPulseEasing = 1; // Short bright flash when navigating buttons double buttonFlash = 0.0; // transient flash amount (0..1) double buttonFlashAmount = 0.45; // how much flash adds to group alpha double buttonFlashDecay = 0.0025; // linear decay per ms // Exit confirmation HUD state (inline HUD like Options/Level) bool exitPanelVisible = false; bool exitPanelAnimating = false; double exitTransition = 0.0; // 0..1 double exitTransitionDurationMs = 360.0; int exitDirection = 1; // 1 show, -1 hide int exitSelectedButton = 0; // 0 = YES (quit), 1 = NO (cancel) double exitScroll = 0.0; // vertical scroll offset for content // Help submenu (inline HUD like Options/Exit) bool helpPanelVisible = false; bool helpPanelAnimating = false; double helpTransition = 0.0; // 0..1 double helpTransitionDurationMs = 360.0; int helpDirection = 1; // 1 show, -1 hide double helpScroll = 0.0; // vertical scroll offset for content // About submenu (inline HUD like Help) bool aboutPanelVisible = false; bool aboutPanelAnimating = false; double aboutTransition = 0.0; // 0..1 double aboutTransitionDurationMs = 360.0; int aboutDirection = 1; // 1 show, -1 hide // Coop setup panel (inline HUD like Exit/Help) bool coopSetupVisible = false; bool coopSetupAnimating = false; double coopSetupTransition = 0.0; // 0..1 double coopSetupTransitionDurationMs = 320.0; int coopSetupDirection = 1; // 1 show, -1 hide int coopSetupSelected = 0; // 0 = 2 players, 1 = AI SDL_FRect coopSetupBtnRects[2]{}; bool coopSetupRectsValid = false; // Optional cooperative info image shown when coop setup panel is active SDL_Texture* coopInfoTexture = nullptr; int coopInfoTexW = 0; int coopInfoTexH = 0; };