upodate game start and blur on pause

This commit is contained in:
2025-11-23 09:40:00 +01:00
parent 9a035df452
commit 5bf87f2c21
8 changed files with 350 additions and 177 deletions

View File

@ -4,6 +4,8 @@
#include "../gameplay/effects/LineEffect.h"
#include "../persistence/Scores.h"
#include "../audio/Audio.h"
#include "../graphics/renderers/GameRenderer.h"
#include "../core/Config.h"
#include <SDL3/SDL.h>
PlayingState::PlayingState(StateContext& ctx) : State(ctx) {}
@ -18,6 +20,10 @@ void PlayingState::onEnter() {
}
void PlayingState::onExit() {
if (m_renderTarget) {
SDL_DestroyTexture(m_renderTarget);
m_renderTarget = nullptr;
}
}
void PlayingState::handleEvent(const SDL_Event& e) {
@ -145,5 +151,132 @@ void PlayingState::update(double frameMs) {
void PlayingState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) {
if (!ctx.game) return;
// Rendering kept in main for now to avoid changing many layout calculations in one change.
// Get current window size
int winW = 0, winH = 0;
SDL_GetRenderOutputSize(renderer, &winW, &winH);
// Create or resize render target if needed
if (!m_renderTarget || m_targetW != winW || m_targetH != winH) {
if (m_renderTarget) SDL_DestroyTexture(m_renderTarget);
m_renderTarget = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, winW, winH);
SDL_SetTextureBlendMode(m_renderTarget, SDL_BLENDMODE_BLEND);
m_targetW = winW;
m_targetH = winH;
}
bool paused = ctx.game->isPaused();
bool exitPopup = ctx.showExitConfirmPopup && *ctx.showExitConfirmPopup;
bool countdown = (ctx.gameplayCountdownActive && *ctx.gameplayCountdownActive) ||
(ctx.menuPlayCountdownArmed && *ctx.menuPlayCountdownArmed);
// Only blur if paused AND NOT in countdown (and not exit popup, though exit popup implies paused)
// Actually, exit popup should probably still blur/dim.
// But countdown should definitely NOT show the "PAUSED" overlay.
bool shouldBlur = paused && !countdown;
if (shouldBlur && m_renderTarget) {
// Render game to texture
SDL_SetRenderTarget(renderer, m_renderTarget);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
// Apply the same view/scale as main.cpp uses
SDL_SetRenderViewport(renderer, &logicalVP);
SDL_SetRenderScale(renderer, logicalScale, logicalScale);
// Render game content (no overlays)
GameRenderer::renderPlayingState(
renderer,
ctx.game,
ctx.pixelFont,
ctx.lineEffect,
ctx.blocksTex,
1200.0f, // LOGICAL_W
1000.0f, // LOGICAL_H
logicalScale,
(float)winW,
(float)winH
);
// Reset to screen
SDL_SetRenderTarget(renderer, nullptr);
// Draw blurred texture
SDL_Rect oldVP;
SDL_GetRenderViewport(renderer, &oldVP);
float oldSX, oldSY;
SDL_GetRenderScale(renderer, &oldSX, &oldSY);
SDL_SetRenderViewport(renderer, nullptr);
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
SDL_FRect dst{0, 0, (float)winW, (float)winH};
// Blur pass (accumulate multiple offset copies)
int offset = Config::Visuals::PAUSE_BLUR_OFFSET;
int iterations = Config::Visuals::PAUSE_BLUR_ITERATIONS;
// Base layer
SDL_SetTextureAlphaMod(m_renderTarget, Config::Visuals::PAUSE_BLUR_ALPHA);
SDL_RenderTexture(renderer, m_renderTarget, nullptr, &dst);
// Accumulate offset layers
for (int i = 1; i <= iterations; ++i) {
float currentOffset = (float)(offset * i);
SDL_FRect d1 = dst; d1.x -= currentOffset; d1.y -= currentOffset;
SDL_RenderTexture(renderer, m_renderTarget, nullptr, &d1);
SDL_FRect d2 = dst; d2.x += currentOffset; d2.y -= currentOffset;
SDL_RenderTexture(renderer, m_renderTarget, nullptr, &d2);
SDL_FRect d3 = dst; d3.x -= currentOffset; d3.y += currentOffset;
SDL_RenderTexture(renderer, m_renderTarget, nullptr, &d3);
SDL_FRect d4 = dst; d4.x += currentOffset; d4.y += currentOffset;
SDL_RenderTexture(renderer, m_renderTarget, nullptr, &d4);
}
SDL_SetTextureAlphaMod(m_renderTarget, 255);
// Restore state
SDL_SetRenderViewport(renderer, &oldVP);
SDL_SetRenderScale(renderer, oldSX, oldSY);
// Draw overlays
if (exitPopup) {
GameRenderer::renderExitPopup(
renderer,
ctx.pixelFont,
(float)winW,
(float)winH,
logicalScale,
(ctx.exitPopupSelectedButton ? *ctx.exitPopupSelectedButton : 1)
);
} else {
GameRenderer::renderPauseOverlay(
renderer,
ctx.pixelFont,
(float)winW,
(float)winH,
logicalScale
);
}
} else {
// Render normally directly to screen
GameRenderer::renderPlayingState(
renderer,
ctx.game,
ctx.pixelFont,
ctx.lineEffect,
ctx.blocksTex,
1200.0f,
1000.0f,
logicalScale,
(float)winW,
(float)winH
);
}
}