fixed menu

This commit is contained in:
2025-12-17 18:55:55 +01:00
parent cecf5cf68e
commit a671825502
5 changed files with 124 additions and 88 deletions

View File

@ -25,6 +25,7 @@
#include "../utils/ImagePathResolver.h"
#include "../graphics/renderers/UIRenderer.h"
#include "../graphics/renderers/GameRenderer.h"
#include "../ui/MenuLayout.h"
#include <SDL3_image/SDL_image.h>
// Frosted tint helper: draw a safe, inexpensive frosted overlay for the panel area.
@ -135,19 +136,54 @@ void MenuState::onEnter() {
void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) {
const float LOGICAL_W = 1200.f;
const float LOGICAL_H = 1000.f;
float contentOffsetX = 0.0f;
float contentOffsetY = 0.0f;
UIRenderer::computeContentOffsets((float)logicalVP.w, (float)logicalVP.h, LOGICAL_W, LOGICAL_H, logicalScale, contentOffsetX, contentOffsetY);
float contentW = LOGICAL_W * logicalScale;
bool isSmall = (contentW < 700.0f);
float btnW = 200.0f;
float btnH = 70.0f;
float btnX = LOGICAL_W * 0.5f + contentOffsetX;
// move buttons a bit lower for better visibility
// small global vertical offset for the whole menu (tweak to move UI down)
float menuYOffset = LOGICAL_H * 0.03f;
float btnY = LOGICAL_H * 0.865f + contentOffsetY + (LOGICAL_H * 0.02f) + menuYOffset + 4.5f;
// Use the same layout code as mouse hit-testing so each button is the same size.
ui::MenuLayoutParams params{
static_cast<int>(LOGICAL_W),
static_cast<int>(LOGICAL_H),
logicalVP.w,
logicalVP.h,
logicalScale
};
auto rects = ui::computeMenuButtonRects(params);
// Draw a compact translucent panel behind the button row for readability.
// Keep it tight so the main_screen art stays visible.
{
float left = rects[0].x;
float right = rects[0].x + rects[0].w;
float top = rects[0].y;
float bottom = rects[0].y + rects[0].h;
for (int i = 1; i < MENU_BTN_COUNT; ++i) {
left = std::min(left, rects[i].x);
right = std::max(right, rects[i].x + rects[i].w);
top = std::min(top, rects[i].y);
bottom = std::max(bottom, rects[i].y + rects[i].h);
}
const float padX = 16.0f;
const float padY = 12.0f;
SDL_FRect panel{ left - padX, top - padY, (right - left) + padX * 2.0f, (bottom - top) + padY * 2.0f };
SDL_BlendMode prevBlend = SDL_BLENDMODE_NONE;
SDL_GetRenderDrawBlendMode(renderer, &prevBlend);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
// Soft shadow (dark, low alpha)
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 80);
SDL_FRect shadow{ panel.x + 3.0f, panel.y + 5.0f, panel.w, panel.h };
SDL_RenderFillRect(renderer, &shadow);
// Bright translucent fill (use existing cyan family used elsewhere in UI)
SDL_SetRenderDrawColor(renderer, 180, 235, 255, 46);
SDL_RenderFillRect(renderer, &panel);
// Border
SDL_SetRenderDrawColor(renderer, 120, 220, 255, 120);
SDL_RenderRect(renderer, &panel);
SDL_SetRenderDrawBlendMode(renderer, prevBlend);
}
// Compose same button definition used in render()
char levelBtnText[32];
@ -165,60 +201,17 @@ void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale,
std::array<SDL_Texture*,5> icons = { playIcon, levelIcon, optionsIcon, helpIcon, exitIcon };
float spacing = isSmall ? btnW * 1.2f : btnW * 1.15f;
// Draw semi-transparent background panel behind the full button group (draw first so text sits on top)
// `groupCenterY` is declared here so it can be used when drawing the buttons below.
float groupCenterY = 0.0f;
{
float groupCenterX = btnX;
float halfSpan = 1.5f * spacing; // covers from leftmost to rightmost button centers
float panelLeft = groupCenterX - halfSpan - btnW * 0.5f - 14.0f;
float panelRight = groupCenterX + halfSpan + btnW * 0.5f + 14.0f;
// Nudge the panel slightly lower for better visual spacing
float panelTop = btnY - btnH * 0.5f - 12.0f + 18.0f;
float panelH = btnH + 24.0f;
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
// Backdrop blur pass before tint (use captured scene texture if available)
renderBackdropBlur(renderer, logicalVP, logicalScale, panelTop, panelH, ctx.sceneTex, ctx.sceneW, ctx.sceneH);
// Brighter, more transparent background to increase contrast but keep scene visible
// More transparent background so underlying scene shows through
SDL_SetRenderDrawColor(renderer, 28, 36, 46, 110);
// Fill full-width background so edges are covered in fullscreen
float viewportLogicalW = (float)logicalVP.w / logicalScale;
SDL_FRect fullPanel{ 0.0f, panelTop, viewportLogicalW, panelH };
SDL_RenderFillRect(renderer, &fullPanel);
// Also draw the central strip to keep visual center emphasis
SDL_FRect panelRect{ panelLeft, panelTop, panelRight - panelLeft, panelH };
SDL_RenderFillRect(renderer, &panelRect);
// brighter full-width border (slightly more transparent)
SDL_SetRenderDrawColor(renderer, 120, 140, 160, 120);
// Expand border to cover full window width (use actual viewport)
SDL_FRect borderFull{ 0.0f, panelTop, viewportLogicalW, panelH };
SDL_RenderRect(renderer, &borderFull);
// Compute a vertical center for the group so labels/icons can be centered
groupCenterY = panelTop + panelH * 0.5f;
}
// Draw all five buttons on top
// Draw all five buttons on top of the main_screen art (text/icon only).
for (int i = 0; i < 5; ++i) {
float cxCenter = 0.0f;
// Use the group's center Y so text/icons sit visually centered in the panel
float cyCenter = groupCenterY;
if (ctx.menuButtonsExplicit) {
cxCenter = ctx.menuButtonCX[i] + contentOffsetX;
cyCenter = ctx.menuButtonCY[i] + contentOffsetY;
} else {
float offset = (static_cast<float>(i) - 2.0f) * spacing;
// small per-button offsets to better match original art placement
float extra = 0.0f;
if (i == 0) extra = 15.0f;
if (i == 2) extra = -18.0f;
if (i == 4) extra = -24.0f;
cxCenter = btnX + offset + extra;
}
const SDL_FRect& r = rects[i];
float cxCenter = r.x + r.w * 0.5f;
float cyCenter = r.y + r.h * 0.5f;
float btnW = r.w;
float btnH = r.h;
const bool isHovered = (ctx.hoveredButton && *ctx.hoveredButton == i);
const bool isSelected = (selectedButton == i);
// Apply group alpha and transient flash to button colors
double aMul = std::clamp(buttonGroupAlpha + buttonFlash * buttonFlashAmount, 0.0, 1.0);
SDL_Color bgCol = buttons[i].bg;
@ -226,12 +219,9 @@ void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale,
bgCol.a = static_cast<Uint8>(std::round(aMul * static_cast<double>(bgCol.a)));
bdCol.a = static_cast<Uint8>(std::round(aMul * static_cast<double>(bdCol.a)));
UIRenderer::drawButton(renderer, ctx.pixelFont, cxCenter, cyCenter, btnW, btnH,
buttons[i].label, false, selectedButton == i,
buttons[i].label, isHovered, isSelected,
bgCol, bdCol, true, icons[i]);
// no per-button neon outline here; draw group background below instead
}
// (panel for the top-button draw path is drawn before the buttons so text is on top)
}
void MenuState::onExit() {