Retro exit modal styling and shortcuts

This commit is contained in:
2025-11-22 19:56:07 +01:00
parent aed1cb62e7
commit c0bee9296a
7 changed files with 389 additions and 239 deletions

View File

@ -268,8 +268,9 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
// Draw bottom action buttons with responsive sizing (reduced to match main mouse hit-test)
// Use the contentW calculated at the top with content offsets
bool isSmall = (contentW < 700.0f);
float btnW = isSmall ? (LOGICAL_W * 0.4f) : 300.0f;
float btnH = isSmall ? 60.0f : 70.0f;
float btnW = isSmall ? (LOGICAL_W * 0.32f) : (LOGICAL_W * 0.18f);
btnW = std::clamp(btnW, 180.0f, 260.0f); // keep buttons from consuming entire row
float btnH = isSmall ? 56.0f : 64.0f;
float btnX = LOGICAL_W * 0.5f + contentOffsetX;
// Move buttons down by 40px to match original layout (user requested 30-50px)
const float btnYOffset = 40.0f;
@ -294,9 +295,13 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
SDL_FRect br{ x-6, y-6, w+12, h+12 }; SDL_RenderFillRect(r, &br);
SDL_SetRenderDrawColor(r, 255,255,255,255); SDL_FRect br2{ x-4, y-4, w+8, h+8 }; SDL_RenderFillRect(r, &br2);
SDL_SetRenderDrawColor(r, bg.r, bg.g, bg.b, bg.a); SDL_FRect br3{ x, y, w, h }; SDL_RenderFillRect(r, &br3);
float textScale = 1.5f; float approxCharW = 12.0f * textScale; float textW = label.length() * approxCharW; float tx = x + (w - textW) / 2.0f; float ty = y + (h - 20.0f * textScale) / 2.0f;
font.draw(r, tx+2, ty+2, label, textScale, SDL_Color{0,0,0,200});
font.draw(r, tx, ty, label, textScale, SDL_Color{255,255,255,255});
float textScale = 1.5f;
int textW = 0, textH = 0;
font.measure(label, textScale, textW, textH);
float tx = x + (w - static_cast<float>(textW)) * 0.5f;
float ty = y + (h - static_cast<float>(textH)) * 0.5f;
font.draw(r, tx + 2.0f, ty + 2.0f, label, textScale, SDL_Color{0, 0, 0, 200});
font.draw(r, tx, ty, label, textScale, SDL_Color{255, 255, 255, 255});
};
struct MenuButtonDef {
@ -312,7 +317,7 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
MenuButtonDef{ SDL_Color{200,70,70,255}, SDL_Color{150,40,40,255}, "EXIT" }
};
float spacing = isSmall ? btnW * 1.15f : btnW * 1.05f;
float spacing = isSmall ? btnW * 1.2f : btnW * 1.15f;
for (size_t i = 0; i < buttons.size(); ++i) {
float offset = (static_cast<float>(i) - 1.5f) * spacing;
float cx = btnX + offset;
@ -327,43 +332,89 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
SDL_FRect overlay{contentOffsetX, contentOffsetY, LOGICAL_W, LOGICAL_H};
SDL_RenderFillRect(renderer, &overlay);
float popupW = 420.0f;
float popupH = 230.0f;
float popupX = (LOGICAL_W - popupW) * 0.5f + contentOffsetX;
float popupY = (LOGICAL_H - popupH) * 0.5f + contentOffsetY;
const float panelW = 640.0f;
const float panelH = 320.0f;
SDL_FRect panel{
(LOGICAL_W - panelW) * 0.5f + contentOffsetX,
(LOGICAL_H - panelH) * 0.5f + contentOffsetY,
panelW,
panelH
};
SDL_SetRenderDrawColor(renderer, 20, 30, 50, 240);
SDL_FRect popup{popupX, popupY, popupW, popupH};
SDL_RenderFillRect(renderer, &popup);
SDL_SetRenderDrawColor(renderer, 90, 140, 220, 255);
SDL_RenderRect(renderer, &popup);
FontAtlas* titleFont = ctx.font ? ctx.font : ctx.pixelFont;
if (titleFont) {
titleFont->draw(renderer, popupX + 40.0f, popupY + 30.0f, "EXIT GAME?", 1.8f, SDL_Color{255, 230, 140, 255});
titleFont->draw(renderer, popupX + 40.0f, popupY + 80.0f, "Are you sure you want to quit?", 1.1f, SDL_Color{200, 210, 230, 255});
SDL_FRect shadow{panel.x + 6.0f, panel.y + 10.0f, panel.w, panel.h};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 140);
SDL_RenderFillRect(renderer, &shadow);
for (int i = 0; i < 5; ++i) {
SDL_FRect glow{panel.x - float(i * 2), panel.y - float(i * 2), panel.w + float(i * 4), panel.h + float(i * 4)};
SDL_SetRenderDrawColor(renderer, 0, 180, 255, Uint8(44 - i * 7));
SDL_RenderRect(renderer, &glow);
}
auto drawChoice = [&](const char* label, float cx, int idx) {
float btnW2 = 140.0f;
float btnH2 = 50.0f;
float x = cx - btnW2 / 2.0f;
float y = popupY + popupH - btnH2 - 30.0f;
SDL_SetRenderDrawColor(renderer, 18, 30, 52, 255);
SDL_RenderFillRect(renderer, &panel);
SDL_SetRenderDrawColor(renderer, 70, 120, 210, 255);
SDL_RenderRect(renderer, &panel);
SDL_FRect inner{panel.x + 24.0f, panel.y + 98.0f, panel.w - 48.0f, panel.h - 146.0f};
SDL_SetRenderDrawColor(renderer, 16, 24, 40, 235);
SDL_RenderFillRect(renderer, &inner);
SDL_SetRenderDrawColor(renderer, 40, 80, 140, 235);
SDL_RenderRect(renderer, &inner);
FontAtlas* retroFont = ctx.pixelFont ? ctx.pixelFont : ctx.font;
if (retroFont) {
const float titleScale = 1.9f;
const char* title = "EXIT GAME?";
int titleW = 0, titleH = 0;
retroFont->measure(title, titleScale, titleW, titleH);
float titleX = panel.x + (panel.w - static_cast<float>(titleW)) * 0.5f;
retroFont->draw(renderer, titleX, panel.y + 30.0f, title, titleScale, SDL_Color{255, 230, 140, 255});
const float bodyScale = 1.05f;
const char* line = "Are you sure you want to quit?";
int bodyW = 0, bodyH = 0;
retroFont->measure(line, bodyScale, bodyW, bodyH);
float bodyX = panel.x + (panel.w - static_cast<float>(bodyW)) * 0.5f;
retroFont->draw(renderer, bodyX, inner.y + 18.0f, line, bodyScale, SDL_Color{210, 220, 240, 255});
}
const float horizontalPad = 28.0f;
const float buttonGap = 32.0f;
const float buttonH = 66.0f;
float buttonW = (inner.w - horizontalPad * 2.0f - buttonGap) * 0.5f;
float buttonY = inner.y + inner.h - buttonH - 24.0f;
auto drawChoice = [&](int idx, float x, const char* label) {
bool selected = (selection == idx);
SDL_Color bg = selected ? SDL_Color{220, 180, 60, 255} : SDL_Color{80, 110, 160, 255};
SDL_Color border = selected ? SDL_Color{255, 220, 120, 255} : SDL_Color{40, 60, 100, 255};
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_SetRenderDrawColor(renderer, 0, 0, 0, 120);
SDL_FRect shadowRect{x + 4.0f, buttonY + 6.0f, buttonW, buttonH};
SDL_RenderFillRect(renderer, &shadowRect);
SDL_FRect bodyRect{x, buttonY, buttonW, buttonH};
SDL_SetRenderDrawColor(renderer, body.r, body.g, body.b, body.a);
SDL_RenderFillRect(renderer, &bodyRect);
SDL_SetRenderDrawColor(renderer, border.r, border.g, border.b, border.a);
SDL_FRect br{ x-4, y-4, btnW2+8, btnH2+8 };
SDL_RenderFillRect(renderer, &br);
SDL_SetRenderDrawColor(renderer, bg.r, bg.g, bg.b, bg.a);
SDL_FRect body{ x, y, btnW2, btnH2 };
SDL_RenderFillRect(renderer, &body);
if (titleFont) {
titleFont->draw(renderer, x + 20.0f, y + 10.0f, label, 1.2f, SDL_Color{15, 20, 35, 255});
SDL_RenderRect(renderer, &bodyRect);
if (retroFont) {
const float labelScale = 1.4f;
int textW = 0, textH = 0;
retroFont->measure(label, labelScale, textW, textH);
float textX = bodyRect.x + (bodyRect.w - static_cast<float>(textW)) * 0.5f;
float textY = bodyRect.y + (bodyRect.h - static_cast<float>(textH)) * 0.5f;
SDL_Color textColor = selected ? SDL_Color{255, 255, 255, 255} : SDL_Color{230, 235, 250, 255};
retroFont->draw(renderer, textX, textY, label, labelScale, textColor);
}
};
drawChoice("YES", popupX + popupW * 0.3f, 0);
drawChoice("NO", popupX + popupW * 0.7f, 1);
float yesX = inner.x + horizontalPad;
float noX = yesX + buttonW + buttonGap;
drawChoice(0, yesX, "YES");
drawChoice(1, noX, "NO");
}
// Popups (settings only - level popup is now a separate state)