diff --git a/src/graphics/renderers/GameRenderer.cpp b/src/graphics/renderers/GameRenderer.cpp index 7080e94..15ef2f8 100644 --- a/src/graphics/renderers/GameRenderer.cpp +++ b/src/graphics/renderers/GameRenderer.cpp @@ -795,120 +795,165 @@ void GameRenderer::renderExitPopup( float logicalScale, int selectedButton ) { - // Calculate content offsets (same as in renderPlayingState for consistency) - // We need to re-calculate them or pass them in? - // The popup uses logical coordinates centered on screen. - // Let's use the same logic as renderPauseOverlay (window coordinates) to be safe and consistent? - // The original code used logical coordinates + contentOffset. - // Let's stick to the original look but render it in window coordinates to ensure it covers everything properly. - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - // Switch to window coordinates SDL_Rect oldViewport; SDL_GetRenderViewport(renderer, &oldViewport); - float oldScaleX, oldScaleY; + float oldScaleX = 1.0f; + float oldScaleY = 1.0f; SDL_GetRenderScale(renderer, &oldScaleX, &oldScaleY); SDL_SetRenderViewport(renderer, nullptr); SDL_SetRenderScale(renderer, 1.0f, 1.0f); - // Full screen dim - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 200); - SDL_FRect fullWin{0.f, 0.f, winW, winH}; + SDL_SetRenderDrawColor(renderer, 2, 4, 12, 210); + SDL_FRect fullWin{0.0f, 0.0f, winW, winH}; SDL_RenderFillRect(renderer, &fullWin); - // Calculate panel position (centered in window) - // Original was logicalW based, let's map it to window size. - // Logical 640x320 scaled up. - float panelW = 640.0f * logicalScale; - float panelH = 320.0f * logicalScale; - float panelX = (winW - panelW) * 0.5f; - float panelY = (winH - panelH) * 0.5f; + const float scale = std::max(0.8f, logicalScale); + const float panelW = 740.0f * scale; + const float panelH = 380.0f * scale; + SDL_FRect panel{ + (winW - panelW) * 0.5f, + (winH - panelH) * 0.5f, + panelW, + panelH + }; - SDL_FRect panel{panelX, panelY, panelW, panelH}; - - SDL_FRect shadow{panel.x + 6.0f * logicalScale, panel.y + 10.0f * logicalScale, panel.w, panel.h}; + SDL_FRect shadow{ + panel.x + 14.0f * scale, + panel.y + 16.0f * scale, + panel.w + 4.0f * scale, + panel.h + 4.0f * scale + }; SDL_SetRenderDrawColor(renderer, 0, 0, 0, 140); SDL_RenderFillRect(renderer, &shadow); - for (int i = 0; i < 5; ++i) { - float off = float(i * 2) * logicalScale; - float exp = float(i * 4) * logicalScale; - SDL_FRect glow{panel.x - off, panel.y - off, panel.w + exp, panel.h + exp}; - SDL_SetRenderDrawColor(renderer, 0, 180, 255, Uint8(44 - i * 7)); - SDL_RenderRect(renderer, &glow); + const std::array panelLayers{ + SDL_Color{7, 10, 22, 255}, + SDL_Color{12, 22, 40, 255}, + SDL_Color{18, 32, 56, 255} + }; + for (size_t i = 0; i < panelLayers.size(); ++i) { + float inset = static_cast(i) * 6.0f * scale; + SDL_FRect layer{ + panel.x + inset, + panel.y + inset, + panel.w - inset * 2.0f, + panel.h - inset * 2.0f + }; + SDL_Color c = panelLayers[i]; + SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, c.a); + SDL_RenderFillRect(renderer, &layer); } - SDL_SetRenderDrawColor(renderer, 18, 30, 52, 255); - SDL_RenderFillRect(renderer, &panel); - SDL_SetRenderDrawColor(renderer, 70, 120, 210, 255); + SDL_SetRenderDrawColor(renderer, 60, 90, 150, 255); SDL_RenderRect(renderer, &panel); - SDL_FRect inner{panel.x + 24.0f * logicalScale, panel.y + 98.0f * logicalScale, panel.w - 48.0f * logicalScale, panel.h - 146.0f * logicalScale}; - SDL_SetRenderDrawColor(renderer, 16, 24, 40, 235); - SDL_RenderFillRect(renderer, &inner); - SDL_SetRenderDrawColor(renderer, 40, 80, 140, 235); - SDL_RenderRect(renderer, &inner); + SDL_FRect insetFrame{ + panel.x + 10.0f * scale, + panel.y + 10.0f * scale, + panel.w - 20.0f * scale, + panel.h - 20.0f * scale + }; + SDL_SetRenderDrawColor(renderer, 24, 45, 84, 255); + SDL_RenderRect(renderer, &insetFrame); - const std::string title = "EXIT GAME?"; + const float contentPad = 44.0f * scale; + float textX = panel.x + contentPad; + float contentWidth = panel.w - contentPad * 2.0f; + float cursorY = panel.y + contentPad * 0.6f; + + const char* title = "EXIT GAME?"; + const float titleScale = 2.0f * scale; int titleW = 0, titleH = 0; - const float titleScale = 1.8f * logicalScale; pixelFont->measure(title, titleScale, titleW, titleH); - pixelFont->draw(renderer, panel.x + (panel.w - titleW) * 0.5f, panel.y + 30.0f * logicalScale, title, titleScale, {255, 230, 140, 255}); + pixelFont->draw(renderer, textX, cursorY, title, titleScale, SDL_Color{255, 224, 130, 255}); + cursorY += titleH + 18.0f * scale; - std::array lines = { + SDL_SetRenderDrawColor(renderer, 32, 64, 110, 210); + SDL_FRect divider{textX, cursorY, contentWidth, 2.0f * scale}; + SDL_RenderFillRect(renderer, ÷r); + cursorY += 26.0f * scale; + + const std::array lines{ "Are you sure you want to quit?", "Current progress will be lost." }; - float lineY = inner.y + 22.0f * logicalScale; - const float lineScale = 1.05f * logicalScale; - for (const auto& line : lines) { + const float bodyScale = 1.05f * scale; + for (const char* line : lines) { int lineW = 0, lineH = 0; - pixelFont->measure(line, lineScale, lineW, lineH); - float textX = panel.x + (panel.w - lineW) * 0.5f; - pixelFont->draw(renderer, textX, lineY, line, lineScale, SDL_Color{210, 220, 240, 255}); - lineY += lineH + 10.0f * logicalScale; + pixelFont->measure(line, bodyScale, lineW, lineH); + pixelFont->draw(renderer, textX, cursorY, line, bodyScale, SDL_Color{210, 226, 245, 255}); + cursorY += lineH + 10.0f * scale; } - const float horizontalPad = 28.0f * logicalScale; - const float buttonGap = 32.0f * logicalScale; - const float buttonH = 66.0f * logicalScale; - float buttonW = (inner.w - horizontalPad * 2.0f - buttonGap) * 0.5f; - float buttonY = inner.y + inner.h - buttonH - 24.0f * logicalScale; + const char* tip = "Enter confirms • Esc returns"; + const float tipScale = 0.9f * scale; + int tipW = 0, tipH = 0; + pixelFont->measure(tip, tipScale, tipW, tipH); - auto drawButton = [&](int idx, float x, const char* label) { + const float buttonGap = 32.0f * scale; + const float buttonH = 78.0f * scale; + const float buttonW = (contentWidth - buttonGap) * 0.5f; + float buttonY = panel.y + panel.h - contentPad - buttonH; + + float tipX = panel.x + (panel.w - tipW) * 0.5f; + float tipY = buttonY - tipH - 14.0f * scale; + pixelFont->draw(renderer, tipX, tipY, tip, tipScale, SDL_Color{150, 170, 205, 255}); + + auto drawButton = [&](int idx, float btnX, SDL_Color baseColor, const char* label) { bool selected = (selectedButton == idx); - SDL_Color base = (idx == 0) ? SDL_Color{185, 70, 70, 255} : SDL_Color{60, 95, 150, 255}; - SDL_Color body = selected ? SDL_Color{Uint8(std::min(255, base.r + 35)), Uint8(std::min(255, base.g + 35)), Uint8(std::min(255, base.b + 35)), 255} : base; - SDL_Color border = selected ? SDL_Color{255, 220, 120, 255} : SDL_Color{80, 110, 160, 255}; + SDL_FRect btn{btnX, buttonY, buttonW, buttonH}; + SDL_Color body = baseColor; + if (selected) { + body.r = Uint8(std::min(255, body.r + 35)); + body.g = Uint8(std::min(255, body.g + 35)); + body.b = Uint8(std::min(255, body.b + 35)); + } + SDL_Color border = selected ? SDL_Color{255, 225, 150, 255} : SDL_Color{90, 120, 170, 255}; + SDL_Color topEdge = SDL_Color{Uint8(std::min(255, body.r + 20)), Uint8(std::min(255, body.g + 20)), Uint8(std::min(255, body.b + 20)), 255}; - SDL_FRect btn{x, buttonY, buttonW, buttonH}; - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 120); - SDL_FRect btnShadow{btn.x + 4.0f * logicalScale, btn.y + 6.0f * logicalScale, btn.w, btn.h}; + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 110); + SDL_FRect btnShadow{btn.x + 6.0f * scale, btn.y + 8.0f * scale, btn.w, btn.h}; SDL_RenderFillRect(renderer, &btnShadow); + SDL_SetRenderDrawColor(renderer, body.r, body.g, body.b, body.a); SDL_RenderFillRect(renderer, &btn); + + SDL_FRect topStrip{btn.x, btn.y, btn.w, 6.0f * scale}; + SDL_SetRenderDrawColor(renderer, topEdge.r, topEdge.g, topEdge.b, topEdge.a); + SDL_RenderFillRect(renderer, &topStrip); + SDL_SetRenderDrawColor(renderer, border.r, border.g, border.b, border.a); SDL_RenderRect(renderer, &btn); - int textW = 0, textH = 0; - const float labelScale = 1.4f * logicalScale; - pixelFont->measure(label, labelScale, textW, textH); - float textX = btn.x + (btn.w - textW) * 0.5f; - float textY = btn.y + (btn.h - textH) * 0.5f; - SDL_Color textColor = selected ? SDL_Color{255, 255, 255, 255} : SDL_Color{230, 235, 250, 255}; + if (selected) { + SDL_SetRenderDrawColor(renderer, 255, 230, 160, 90); + SDL_FRect glow{ + btn.x - 6.0f * scale, + btn.y - 6.0f * scale, + btn.w + 12.0f * scale, + btn.h + 12.0f * scale + }; + SDL_RenderRect(renderer, &glow); + } + + const float labelScale = 1.35f * scale; + int labelW = 0, labelH = 0; + pixelFont->measure(label, labelScale, labelW, labelH); + float textX = btn.x + (btn.w - labelW) * 0.5f; + float textY = btn.y + (btn.h - labelH) * 0.5f; + SDL_Color textColor = selected ? SDL_Color{255, 255, 255, 255} : SDL_Color{235, 238, 250, 255}; pixelFont->draw(renderer, textX, textY, label, labelScale, textColor); }; - float yesX = inner.x + horizontalPad; + float yesX = textX; float noX = yesX + buttonW + buttonGap; - drawButton(0, yesX, "YES"); - drawButton(1, noX, "NO"); + drawButton(0, yesX, SDL_Color{190, 70, 70, 255}, "YES"); + drawButton(1, noX, SDL_Color{70, 115, 190, 255}, "NO"); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - - // Restore previous render state SDL_SetRenderViewport(renderer, &oldViewport); SDL_SetRenderScale(renderer, oldScaleX, oldScaleY); }