upodate game start and blur on pause
This commit is contained in:
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user