Add exit-confirm modal (fullscreen dim, centered P2 text) and keyboard shortcuts

Add an in-game exit confirmation modal for Playing state: ESC opens modal and pauses the game; YES resets and returns to Menu; NO hides modal and resumes.
Draw a full-window translucent dim background (reset viewport) so overlay covers any window size / fullscreen.
Use PressStart2P (pixel P2) font for all modal text and center title/body/button labels using measured text widths.
Add FontAtlas::measure(...) to accurately measure text sizes (used for proper centering).
Ensure popup rendering and mouse hit-testing use the same logical/content-local coordinate math so visuals and clicks align.
Add keyboard shortcuts for modal (Enter = confirm, Esc = cancel) and suppress other gameplay input while modal is active.
Add helper scripts for debug build+run: build-debug-and-run.ps1 and build-debug-and-run.bat.
Minor fixes to related rendering & state wiring; verified Debug build completes and modal behavior in runtime.
This commit is contained in:
2025-08-16 19:40:23 +02:00
parent 2afaea7fd3
commit 6d4f3c54ed
5 changed files with 167 additions and 3 deletions

View File

@ -1,4 +1,5 @@
#include "PlayingState.h"
#include "core/StateManager.h"
#include "gameplay/Game.h"
#include "gameplay/LineEffect.h"
#include "persistence/Scores.h"
@ -14,14 +15,45 @@ void PlayingState::onExit() {
}
void PlayingState::handleEvent(const SDL_Event& e) {
// We keep short-circuited input here; main still handles mouse UI
// We keep short-circuited input here; main still owns mouse UI
if (e.type == SDL_EVENT_KEY_DOWN && !e.key.repeat) {
if (!ctx.game) return;
// Pause toggle (P)
if (e.key.scancode == SDL_SCANCODE_P) {
bool paused = ctx.game->isPaused();
ctx.game->setPaused(!paused);
return;
}
// If exit-confirm popup is visible, handle shortcuts here
if (ctx.showExitConfirmPopup && *ctx.showExitConfirmPopup) {
// Confirm with Enter (main or keypad)
if (e.key.scancode == SDL_SCANCODE_RETURN || e.key.scancode == SDL_SCANCODE_KP_ENTER) {
*ctx.showExitConfirmPopup = false;
// Reset game and return to menu
ctx.game->reset(false);
if (ctx.stateManager) ctx.stateManager->setState(AppState::Menu);
return;
}
// Cancel with Esc
if (e.key.scancode == SDL_SCANCODE_ESCAPE) {
*ctx.showExitConfirmPopup = false;
ctx.game->setPaused(false);
return;
}
// While modal is open, suppress other gameplay keys
return;
}
// ESC key - open confirmation popup
if (e.key.scancode == SDL_SCANCODE_ESCAPE) {
if (ctx.showExitConfirmPopup) {
if (ctx.game) ctx.game->setPaused(true);
*ctx.showExitConfirmPopup = true;
}
return;
}
// Other gameplay keys already registered by main's Playing handler for now
}
}