latest state
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
#include "../core/GlobalState.h"
|
||||
#include "../core/state/StateManager.h"
|
||||
#include "../audio/Audio.h"
|
||||
#include "../audio/SoundEffect.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
@ -20,6 +21,8 @@
|
||||
// Menu helper wrappers are declared in a shared header implemented in main.cpp
|
||||
#include "../audio/MenuWrappers.h"
|
||||
#include "../utils/ImagePathResolver.h"
|
||||
#include "../graphics/renderers/UIRenderer.h"
|
||||
#include "../graphics/renderers/GameRenderer.h"
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
|
||||
MenuState::MenuState(StateContext& ctx) : State(ctx) {}
|
||||
@ -38,6 +41,12 @@ void MenuState::onExit() {
|
||||
if (ctx.showExitConfirmPopup) {
|
||||
*ctx.showExitConfirmPopup = false;
|
||||
}
|
||||
|
||||
// Clean up icon textures
|
||||
if (playIcon) { SDL_DestroyTexture(playIcon); playIcon = nullptr; }
|
||||
if (levelIcon) { SDL_DestroyTexture(levelIcon); levelIcon = nullptr; }
|
||||
if (optionsIcon) { SDL_DestroyTexture(optionsIcon); optionsIcon = nullptr; }
|
||||
if (exitIcon) { SDL_DestroyTexture(exitIcon); exitIcon = nullptr; }
|
||||
}
|
||||
|
||||
void MenuState::handleEvent(const SDL_Event& e) {
|
||||
@ -177,10 +186,9 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
// Compute content offsets (same approach as main.cpp for proper centering)
|
||||
float winW = (float)logicalVP.w;
|
||||
float winH = (float)logicalVP.h;
|
||||
float contentW = LOGICAL_W * logicalScale;
|
||||
float contentH = LOGICAL_H * logicalScale;
|
||||
float contentOffsetX = (winW - contentW) * 0.5f / logicalScale;
|
||||
float contentOffsetY = (winH - contentH) * 0.5f / logicalScale;
|
||||
float contentOffsetX = 0.0f;
|
||||
float contentOffsetY = 0.0f;
|
||||
UIRenderer::computeContentOffsets(winW, winH, LOGICAL_W, LOGICAL_H, logicalScale, contentOffsetX, contentOffsetY);
|
||||
|
||||
// Background is drawn by main (stretched to the full window) to avoid double-draw.
|
||||
{
|
||||
@ -250,106 +258,19 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the sci-fi overlay that sits above the scoreboard but below the buttons
|
||||
SDL_Texture* overlayTex = ctx.mainScreenTex;
|
||||
int overlayW = ctx.mainScreenW;
|
||||
int overlayH = ctx.mainScreenH;
|
||||
|
||||
static SDL_Texture* fallbackOverlay = nullptr;
|
||||
static int fallbackW = 0;
|
||||
static int fallbackH = 0;
|
||||
|
||||
if (!overlayTex) {
|
||||
if (!fallbackOverlay) {
|
||||
const std::string resolvedOverlay = AssetPath::resolveImagePath("assets/images/main_screen.bmp");
|
||||
fallbackOverlay = IMG_LoadTexture(renderer, resolvedOverlay.c_str());
|
||||
if (fallbackOverlay) {
|
||||
SDL_SetTextureBlendMode(fallbackOverlay, SDL_BLENDMODE_BLEND);
|
||||
float tmpW = 0.0f;
|
||||
float tmpH = 0.0f;
|
||||
SDL_GetTextureSize(fallbackOverlay, &tmpW, &tmpH);
|
||||
fallbackW = static_cast<int>(tmpW);
|
||||
fallbackH = static_cast<int>(tmpH);
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render loaded fallback overlay texture %p path=%s size=%dx%d\n",
|
||||
(void*)fallbackOverlay, resolvedOverlay.c_str(), fallbackW, fallbackH);
|
||||
fclose(f);
|
||||
}
|
||||
} else {
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render failed to load fallback overlay: %s\n", SDL_GetError());
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
overlayTex = fallbackOverlay;
|
||||
overlayW = fallbackW;
|
||||
overlayH = fallbackH;
|
||||
}
|
||||
|
||||
if (overlayTex) {
|
||||
{
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render overlay tex=%llu dims=%dx%d\n",
|
||||
(unsigned long long)(uintptr_t)overlayTex,
|
||||
overlayW,
|
||||
overlayH);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
float texW = overlayW > 0 ? static_cast<float>(overlayW) : 0.0f;
|
||||
float texH = overlayH > 0 ? static_cast<float>(overlayH) : 0.0f;
|
||||
if (texW <= 0.0f || texH <= 0.0f) {
|
||||
if (!SDL_GetTextureSize(overlayTex, &texW, &texH)) {
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render failed to query overlay size: %s\n", SDL_GetError());
|
||||
fclose(f);
|
||||
}
|
||||
texW = 0.0f;
|
||||
texH = 0.0f;
|
||||
}
|
||||
}
|
||||
if (texW > 0.0f && texH > 0.0f) {
|
||||
const float drawH = LOGICAL_H;
|
||||
const float scale = drawH / texH;
|
||||
const float drawW = texW * scale;
|
||||
SDL_FRect dst{
|
||||
(LOGICAL_W - drawW) * 0.5f + contentOffsetX,
|
||||
contentOffsetY,
|
||||
drawW,
|
||||
drawH
|
||||
};
|
||||
int renderResult = SDL_RenderTexture(renderer, overlayTex, nullptr, &dst);
|
||||
if (renderResult < 0) {
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render failed to draw overlay: %s\n", SDL_GetError());
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FILE* f = fopen("tetris_trace.log", "a");
|
||||
if (f) {
|
||||
fprintf(f, "MenuState::render no overlay texture available\n");
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
// The main_screen overlay is drawn by main.cpp as the background
|
||||
// We don't need to draw it again here as a logo
|
||||
|
||||
// Draw bottom action buttons with responsive sizing (reduced to match main mouse hit-test)
|
||||
// Use the contentW calculated at the top with content offsets
|
||||
float contentW = LOGICAL_W * logicalScale;
|
||||
bool isSmall = (contentW < 700.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;
|
||||
// Adjust button dimensions to match the background button graphics
|
||||
float btnW = 200.0f; // Fixed width to match background buttons
|
||||
float btnH = 70.0f; // Fixed height to match background buttons
|
||||
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;
|
||||
float btnY = LOGICAL_H * 0.86f + contentOffsetY + btnYOffset; // align with main's button vertical position
|
||||
// Adjust vertical position to align with background buttons
|
||||
float btnY = LOGICAL_H * 0.865f + contentOffsetY;
|
||||
|
||||
if (ctx.pixelFont) {
|
||||
{
|
||||
@ -359,26 +280,6 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
int startLevel = ctx.startLevelSelection ? *ctx.startLevelSelection : 0;
|
||||
std::snprintf(levelBtnText, sizeof(levelBtnText), "LEVEL %d", startLevel);
|
||||
|
||||
auto drawMenuButtonLocal = [&](SDL_Renderer* r, FontAtlas& font, float cx, float cy, float w, float h, const std::string& label, SDL_Color bg, SDL_Color border, bool selected){
|
||||
float x = cx - w/2; float y = cy - h/2;
|
||||
if (selected) {
|
||||
SDL_SetRenderDrawColor(r, 255, 220, 0, 110);
|
||||
SDL_FRect glow{ x-10, y-10, w+20, h+20 };
|
||||
SDL_RenderFillRect(r, &glow);
|
||||
}
|
||||
SDL_SetRenderDrawColor(r, border.r, border.g, border.b, border.a);
|
||||
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;
|
||||
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 {
|
||||
SDL_Color bg;
|
||||
SDL_Color border;
|
||||
@ -391,137 +292,104 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
MenuButtonDef{ SDL_Color{130,80,210,255}, SDL_Color{90,40,170,255}, "OPTIONS" },
|
||||
MenuButtonDef{ SDL_Color{200,70,70,255}, SDL_Color{150,40,40,255}, "EXIT" }
|
||||
};
|
||||
|
||||
// Icon array (nullptr if icon not loaded)
|
||||
std::array<SDL_Texture*, 4> icons = {
|
||||
playIcon,
|
||||
levelIcon,
|
||||
optionsIcon,
|
||||
exitIcon
|
||||
};
|
||||
|
||||
// Fixed spacing to match background button positions
|
||||
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;
|
||||
drawMenuButtonLocal(renderer, *ctx.pixelFont, cx, btnY, btnW, btnH, buttons[i].label, buttons[i].bg, buttons[i].border, selectedButton == static_cast<int>(i));
|
||||
|
||||
// Draw each button individually so each can have its own coordinates
|
||||
// Button 0 - PLAY
|
||||
{
|
||||
const int i = 0;
|
||||
float cxCenter = 0.0f;
|
||||
float cyCenter = btnY;
|
||||
if (ctx.menuButtonsExplicit) {
|
||||
cxCenter = ctx.menuButtonCX[i] + contentOffsetX;
|
||||
cyCenter = ctx.menuButtonCY[i] + contentOffsetY;
|
||||
} else {
|
||||
float offset = (static_cast<float>(i) - 1.5f) * spacing;
|
||||
cxCenter = btnX + offset;
|
||||
}
|
||||
UIRenderer::drawButton(renderer, ctx.pixelFont, cxCenter, cyCenter, btnW, btnH,
|
||||
buttons[i].label, false, selectedButton == i,
|
||||
buttons[i].bg, buttons[i].border, true, icons[i]);
|
||||
}
|
||||
|
||||
// Button 1 - LEVEL
|
||||
{
|
||||
const int i = 1;
|
||||
float cxCenter = 0.0f;
|
||||
float cyCenter = btnY;
|
||||
if (ctx.menuButtonsExplicit) {
|
||||
cxCenter = ctx.menuButtonCX[i] + contentOffsetX;
|
||||
cyCenter = ctx.menuButtonCY[i] + contentOffsetY;
|
||||
} else {
|
||||
float offset = (static_cast<float>(i) - 1.5f) * spacing;
|
||||
cxCenter = btnX + offset;
|
||||
}
|
||||
UIRenderer::drawButton(renderer, ctx.pixelFont, cxCenter, cyCenter, btnW, btnH,
|
||||
buttons[i].label, false, selectedButton == i,
|
||||
buttons[i].bg, buttons[i].border, true, icons[i]);
|
||||
}
|
||||
|
||||
// Button 2 - OPTIONS
|
||||
{
|
||||
const int i = 2;
|
||||
float cxCenter = 0.0f;
|
||||
float cyCenter = btnY;
|
||||
if (ctx.menuButtonsExplicit) {
|
||||
cxCenter = ctx.menuButtonCX[i] + contentOffsetX;
|
||||
cyCenter = ctx.menuButtonCY[i] + contentOffsetY;
|
||||
} else {
|
||||
float offset = (static_cast<float>(i) - 1.5f) * spacing;
|
||||
cxCenter = btnX + offset;
|
||||
}
|
||||
UIRenderer::drawButton(renderer, ctx.pixelFont, cxCenter, cyCenter, btnW, btnH,
|
||||
buttons[i].label, false, selectedButton == i,
|
||||
buttons[i].bg, buttons[i].border, true, icons[i]);
|
||||
}
|
||||
|
||||
// Button 3 - EXIT
|
||||
{
|
||||
const int i = 3;
|
||||
float cxCenter = 0.0f;
|
||||
float cyCenter = btnY;
|
||||
if (ctx.menuButtonsExplicit) {
|
||||
cxCenter = ctx.menuButtonCX[i] + contentOffsetX;
|
||||
cyCenter = ctx.menuButtonCY[i] + contentOffsetY;
|
||||
} else {
|
||||
float offset = (static_cast<float>(i) - 1.5f) * spacing;
|
||||
cxCenter = btnX + offset;
|
||||
}
|
||||
UIRenderer::drawButton(renderer, ctx.pixelFont, cxCenter, cyCenter, btnW, btnH,
|
||||
buttons[i].label, false, selectedButton == i,
|
||||
buttons[i].bg, buttons[i].border, true, icons[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.showExitConfirmPopup && *ctx.showExitConfirmPopup) {
|
||||
int selection = ctx.exitPopupSelectedButton ? *ctx.exitPopupSelectedButton : 1;
|
||||
|
||||
// Switch to window coordinates for full-screen overlay
|
||||
SDL_SetRenderViewport(renderer, nullptr);
|
||||
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 150);
|
||||
|
||||
// Get actual window size
|
||||
int actualWinW = 0, actualWinH = 0;
|
||||
SDL_GetRenderOutputSize(renderer, &actualWinW, &actualWinH);
|
||||
SDL_FRect overlay{0, 0, (float)actualWinW, (float)actualWinH};
|
||||
SDL_RenderFillRect(renderer, &overlay);
|
||||
|
||||
// Restore viewport and scale for popup content
|
||||
SDL_SetRenderViewport(renderer, &logicalVP);
|
||||
SDL_SetRenderScale(renderer, logicalScale, logicalScale);
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
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 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_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);
|
||||
}
|
||||
};
|
||||
|
||||
float yesX = inner.x + horizontalPad;
|
||||
float noX = yesX + buttonW + buttonGap;
|
||||
drawChoice(0, yesX, "YES");
|
||||
drawChoice(1, noX, "NO");
|
||||
GameRenderer::renderExitPopup(
|
||||
renderer,
|
||||
ctx.pixelFont,
|
||||
winW,
|
||||
winH,
|
||||
logicalScale,
|
||||
ctx.exitPopupSelectedButton ? *ctx.exitPopupSelectedButton : 1
|
||||
);
|
||||
}
|
||||
|
||||
// Popups (settings only - level popup is now a separate state)
|
||||
if (ctx.showSettingsPopup && *ctx.showSettingsPopup) {
|
||||
// draw settings popup inline
|
||||
bool musicOn = ctx.musicEnabled ? *ctx.musicEnabled : true;
|
||||
float popupW = 350, popupH = 260;
|
||||
float popupX = (LOGICAL_W - popupW) / 2;
|
||||
float popupY = (LOGICAL_H - popupH) / 2;
|
||||
SDL_SetRenderDrawColor(renderer, 0,0,0,128); SDL_FRect overlay{0,0,(float)LOGICAL_W,(float)LOGICAL_H}; SDL_RenderFillRect(renderer, &overlay);
|
||||
SDL_SetRenderDrawColor(renderer, 100,120,160,255); SDL_FRect bord{popupX-4,popupY-4,popupW+8,popupH+8}; SDL_RenderFillRect(renderer, &bord);
|
||||
SDL_SetRenderDrawColor(renderer, 40,50,70,255); SDL_FRect body{popupX,popupY,popupW,popupH}; SDL_RenderFillRect(renderer, &body);
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 20, "SETTINGS", 2.0f, SDL_Color{255,220,0,255});
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 70, "MUSIC:", 1.5f, SDL_Color{255,255,255,255});
|
||||
ctx.font->draw(renderer, popupX + 120, popupY + 70, musicOn ? "ON" : "OFF", 1.5f, musicOn ? SDL_Color{0,255,0,255} : SDL_Color{255,0,0,255});
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 100, "SOUND FX:", 1.5f, SDL_Color{255,255,255,255});
|
||||
ctx.font->draw(renderer, popupX + 140, popupY + 100, "ON", 1.5f, SDL_Color{0,255,0,255});
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 150, "M = TOGGLE MUSIC", 1.0f, SDL_Color{200,200,220,255});
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 170, "S = TOGGLE SOUND FX", 1.0f, SDL_Color{200,200,220,255});
|
||||
ctx.font->draw(renderer, popupX + 20, popupY + 190, "ESC = CLOSE", 1.0f, SDL_Color{200,200,220,255});
|
||||
bool soundOn = SoundEffectManager::instance().isEnabled();
|
||||
UIRenderer::drawSettingsPopup(renderer, ctx.font, LOGICAL_W, LOGICAL_H, musicOn, soundOn);
|
||||
}
|
||||
// Trace exit
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user