minor fixes

This commit is contained in:
2025-12-23 20:24:50 +01:00
parent a7a3ae9055
commit d28feb3276
3 changed files with 87 additions and 45 deletions

View File

@ -21,7 +21,11 @@ std::string Settings::getSettingsPath() {
bool Settings::load() { bool Settings::load() {
std::ifstream file(getSettingsPath()); std::ifstream file(getSettingsPath());
if (!file.is_open()) { if (!file.is_open()) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Settings file not found, using defaults"); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Settings file not found, using defaults. Creating settings file with defaults.");
// Persist defaults so next run has an explicit settings.ini
try {
save();
} catch (...) {}
return false; return false;
} }

View File

@ -48,7 +48,8 @@ private:
Settings& operator=(const Settings&) = delete; Settings& operator=(const Settings&) = delete;
// Settings values // Settings values
bool m_fullscreen = false; // Default to fullscreen on first run when no settings.ini exists
bool m_fullscreen = true;
bool m_musicEnabled = true; bool m_musicEnabled = true;
bool m_soundEnabled = true; bool m_soundEnabled = true;
bool m_debugEnabled = false; bool m_debugEnabled = false;

View File

@ -1241,11 +1241,15 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
} }
static const std::vector<ScoreEntry> EMPTY_SCORES; static const std::vector<ScoreEntry> EMPTY_SCORES;
const auto& hs = ctx.scores ? ctx.scores->all() : EMPTY_SCORES; const auto& hs = ctx.scores ? ctx.scores->all() : EMPTY_SCORES;
// Choose which game_type to show based on current menu selection // Choose which game_type to show based on current menu selection or mouse hover.
// Prefer `hoveredButton` (mouse-over) when available so the TOP PLAYER panel
// updates responsively while the user moves the pointer over the bottom menu.
int activeBtn = (ctx.hoveredButton ? *ctx.hoveredButton : -1);
if (activeBtn < 0) activeBtn = selectedButton;
std::string wantedType = "classic"; std::string wantedType = "classic";
if (selectedButton == 0) wantedType = "classic"; // Play / Endless if (activeBtn == 0) wantedType = "classic"; // Play / Endless
else if (selectedButton == 1) wantedType = "cooperate"; // Coop else if (activeBtn == 1) wantedType = "cooperate"; // Coop
else if (selectedButton == 2) wantedType = "challenge"; // Challenge else if (activeBtn == 2) wantedType = "challenge"; // Challenge
// Filter highscores to the desired game type // Filter highscores to the desired game type
std::vector<ScoreEntry> filtered; std::vector<ScoreEntry> filtered;
filtered.reserve(hs.size()); filtered.reserve(hs.size());
@ -1581,16 +1585,19 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
float alphaFactor = static_cast<float>(coopSetupTransition); float alphaFactor = static_cast<float>(coopSetupTransition);
if (alphaFactor < 0.0f) alphaFactor = 0.0f; if (alphaFactor < 0.0f) alphaFactor = 0.0f;
if (alphaFactor > 1.0f) alphaFactor = 1.0f; if (alphaFactor > 1.0f) alphaFactor = 1.0f;
// Compute coop info image placement (draw as background for both ChoosePartner and Network steps)
float imgX = 0.0f, imgY = 0.0f, targetW = 0.0f, targetH = 0.0f;
bool hasCoopImg = false;
if (coopInfoTexture && coopInfoTexW > 0 && coopInfoTexH > 0) { if (coopInfoTexture && coopInfoTexW > 0 && coopInfoTexH > 0) {
float totalW = totalChoiceW; float totalW = totalChoiceW;
// Increase allowed image width by ~15% (was 0.75 of totalW) // Keep coop info image slightly smaller than the button row.
const float scaleFactor = 0.75f * 1.25f; // ~0.8625 // Use a modest scale so it doesn't dominate the UI.
float maxImgW = totalW * scaleFactor; float maxImgW = totalW * 0.65f;
float targetW = std::min(maxImgW, static_cast<float>(coopInfoTexW)); targetW = std::min(maxImgW, static_cast<float>(coopInfoTexW));
float scale = targetW / static_cast<float>(coopInfoTexW); float scale = targetW / static_cast<float>(coopInfoTexW);
float targetH = static_cast<float>(coopInfoTexH) * scale; targetH = static_cast<float>(coopInfoTexH) * scale;
float imgX = bx + (totalW - targetW) * 0.5f; imgX = bx + (totalW - targetW) * 0.5f;
float imgY = by - targetH - 8.0f; // keep the small gap above buttons imgY = by - targetH - 8.0f; // keep the small gap above buttons
float minY = panelBaseY + 6.0f; float minY = panelBaseY + 6.0f;
if (imgY < minY) imgY = minY; if (imgY < minY) imgY = minY;
SDL_FRect dst{ imgX, imgY, targetW, targetH }; SDL_FRect dst{ imgX, imgY, targetW, targetH };
@ -1598,8 +1605,10 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
// Make the coop info image slightly transparent scaled by transition // Make the coop info image slightly transparent scaled by transition
SDL_SetTextureAlphaMod(coopInfoTexture, static_cast<Uint8>(std::round(200.0f * alphaFactor))); SDL_SetTextureAlphaMod(coopInfoTexture, static_cast<Uint8>(std::round(200.0f * alphaFactor)));
SDL_RenderTexture(renderer, coopInfoTexture, nullptr, &dst); SDL_RenderTexture(renderer, coopInfoTexture, nullptr, &dst);
hasCoopImg = true;
// Draw cooperative instructions inside the panel area (overlayed on the panel background) // Only draw the instructional overlay text when choosing partner.
if (coopSetupStep == CoopSetupStep::ChoosePartner) {
FontAtlas* f = ctx.font ? ctx.font : ctx.pixelFont; FontAtlas* f = ctx.font ? ctx.font : ctx.pixelFont;
if (f) { if (f) {
const float pad = 38.0f; const float pad = 38.0f;
@ -1654,6 +1663,7 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
f->draw(renderer, goalX, textY, goalText, 0.86f, goalTextCol); f->draw(renderer, goalX, textY, goalText, 0.86f, goalTextCol);
} }
} }
}
// Delay + eased fade specifically for the two coop buttons so they appear after the image/text. // Delay + eased fade specifically for the two coop buttons so they appear after the image/text.
const float btnDelay = 0.25f; // fraction of transition to wait before buttons start fading const float btnDelay = 0.25f; // fraction of transition to wait before buttons start fading
@ -1694,7 +1704,7 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
coopSetupBtnRects[2].x + btnW2 * 0.5f, coopSetupBtnRects[2].x + btnW2 * 0.5f,
coopSetupBtnRects[2].y + btnH2 * 0.5f, coopSetupBtnRects[2].y + btnH2 * 0.5f,
btnW2, btnH2, btnW2, btnH2,
"2 PLAYER (NETWORK)", "2 PLAYER (NET)",
false, false,
coopSetupSelected == 2, coopSetupSelected == 2,
bgA, bgA,
@ -1710,7 +1720,9 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
const float roleGap = 48.0f; const float roleGap = 48.0f;
const float roleTotalW = roleBtnW * 2.0f + roleGap; const float roleTotalW = roleBtnW * 2.0f + roleGap;
const float roleX = panelBaseX + (panelW - roleTotalW) * 0.5f + shiftX; const float roleX = panelBaseX + (panelW - roleTotalW) * 0.5f + shiftX;
const float roleY = by + btnH2 + 18.0f; // Move the host/join buttons down from the previous higher position.
// Shift down by one button height plus half a button (effectively lower them):
const float roleY = by + (btnH2 * 0.5f) - 18.0f;
SDL_FRect hostRect{ roleX, roleY, roleBtnW, btnH2 }; SDL_FRect hostRect{ roleX, roleY, roleBtnW, btnH2 };
SDL_FRect joinRect{ roleX + roleBtnW + roleGap, roleY, roleBtnW, btnH2 }; SDL_FRect joinRect{ roleX + roleBtnW + roleGap, roleY, roleBtnW, btnH2 };
@ -1744,23 +1756,48 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
FontAtlas* f = ctx.font ? ctx.font : ctx.pixelFont; FontAtlas* f = ctx.font ? ctx.font : ctx.pixelFont;
if (f) { if (f) {
SDL_Color infoCol{200, 220, 230, static_cast<Uint8>(std::round(220.0f * buttonFade))}; SDL_Color infoCol{200, 220, 230, static_cast<Uint8>(std::round(220.0f * buttonFade))};
char endpoint[256]; // Draw connection info on separate lines and shift right by ~200px
std::snprintf(endpoint, sizeof(endpoint), "PORT %u HOST IP %s JOIN IP %s", char portLine[64];
(unsigned)coopNetworkPort, std::snprintf(portLine, sizeof(portLine), "PORT %u", (unsigned)coopNetworkPort);
coopNetworkBindAddress.c_str(), char hostLine[128];
coopNetworkJoinAddress.c_str()); std::snprintf(hostLine, sizeof(hostLine), "HOST IP %s", coopNetworkBindAddress.c_str());
f->draw(renderer, panelBaseX + 60.0f, roleY + btnH2 + 12.0f, endpoint, 0.90f, infoCol); char joinLine[128];
std::snprintf(joinLine, sizeof(joinLine), "JOIN IP %s", coopNetworkJoinAddress.c_str());
const float textShiftX = 200.0f;
const float textX = panelBaseX + 60.0f + textShiftX;
const float endpointY = (hasCoopImg ? (imgY + targetH * 0.62f) : (roleY + btnH2 + 12.0f));
const float lineSpacing = 28.0f;
// Show only the minimal info needed for the selected role.
f->draw(renderer, textX, endpointY, portLine, 0.90f, infoCol);
if (coopNetworkRoleSelected == 0) {
// Host: show bind address only
f->draw(renderer, textX, endpointY + lineSpacing, hostLine, 0.90f, infoCol);
} else {
// Client: show join target only
f->draw(renderer, textX, endpointY + lineSpacing, joinLine, 0.90f, infoCol);
}
float hintY = endpointY + lineSpacing * 2.0f + 6.0f;
// Bottom helper prompt: show a compact instruction under the image window
float bottomY = hasCoopImg ? (imgY + targetH + 18.0f) : (hintY + 36.0f);
SDL_Color bottomCol{180,200,210,200};
if (coopNetworkRoleSelected == 0) {
f->draw(renderer, textX, bottomY, "HOST: press ENTER to edit bind IP, then press ENTER to confirm", 0.82f, bottomCol);
} else {
f->draw(renderer, textX, bottomY, "JOIN: press ENTER to type server IP, then press ENTER to connect", 0.82f, bottomCol);
}
if (coopSetupStep == CoopSetupStep::NetworkWaiting && !coopNetworkStatusText.empty()) { if (coopSetupStep == CoopSetupStep::NetworkWaiting && !coopNetworkStatusText.empty()) {
SDL_Color statusCol{255, 215, 80, static_cast<Uint8>(std::round(240.0f * buttonFade))}; SDL_Color statusCol{255, 215, 80, static_cast<Uint8>(std::round(240.0f * buttonFade))};
f->draw(renderer, panelBaseX + 60.0f, roleY + btnH2 + 44.0f, coopNetworkStatusText, 1.00f, statusCol); f->draw(renderer, textX, hintY, coopNetworkStatusText, 1.00f, statusCol);
} else if (coopSetupStep == CoopSetupStep::NetworkEnterAddress) { } else if (coopSetupStep == CoopSetupStep::NetworkEnterAddress) {
SDL_Color hintCol{160, 190, 210, static_cast<Uint8>(std::round(200.0f * buttonFade))}; SDL_Color hintCol{160, 190, 210, static_cast<Uint8>(std::round(200.0f * buttonFade))};
const char* label = (coopNetworkRoleSelected == 0) ? "TYPE HOST IP (BIND) THEN ENTER" : "TYPE JOIN IP THEN ENTER"; const char* label = (coopNetworkRoleSelected == 0) ? "TYPE HOST IP (BIND) THEN ENTER" : "TYPE JOIN IP THEN ENTER";
f->draw(renderer, panelBaseX + 60.0f, roleY + btnH2 + 44.0f, label, 0.82f, hintCol); f->draw(renderer, textX, hintY, label, 0.82f, hintCol);
} else { } else {
SDL_Color hintCol{160, 190, 210, static_cast<Uint8>(std::round(200.0f * buttonFade))}; SDL_Color hintCol{160, 190, 210, static_cast<Uint8>(std::round(200.0f * buttonFade))};
f->draw(renderer, panelBaseX + 60.0f, roleY + btnH2 + 44.0f, "PRESS ENTER TO EDIT/CONFIRM ESC TO GO BACK", 0.82f, hintCol); f->draw(renderer, textX, hintY, "PRESS ENTER TO EDIT/CONFIRM ESC TO GO BACK", 0.82f, hintCol);
} }
} }
} }