fixed assertion
This commit is contained in:
43
src/main.cpp
43
src/main.cpp
@ -16,6 +16,7 @@
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
#include "audio/Audio.h"
|
||||
#include "audio/SoundEffect.h"
|
||||
@ -696,7 +697,6 @@ int main(int, char **)
|
||||
exeDir.string().c_str(), ec.message().c_str());
|
||||
}
|
||||
#endif
|
||||
SDL_free(const_cast<char*>(basePathRaw));
|
||||
} else {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetBasePath() failed; asset lookups rely on current directory: %s",
|
||||
@ -711,15 +711,13 @@ int main(int, char **)
|
||||
pixelFont.init("assets/fonts/PressStart2P-Regular.ttf", 16);
|
||||
|
||||
ScoreManager scores;
|
||||
std::atomic<bool> scoresLoadComplete{false};
|
||||
// Load scores asynchronously but keep the worker alive until shutdown to avoid lifetime issues
|
||||
std::jthread scoreLoader([&scores]() {
|
||||
std::jthread scoreLoader([&scores, &scoresLoadComplete]() {
|
||||
scores.load();
|
||||
scoresLoadComplete.store(true, std::memory_order_release);
|
||||
});
|
||||
const auto ensureScoresLoaded = [&]() {
|
||||
if (scoreLoader.joinable()) {
|
||||
scoreLoader.join();
|
||||
}
|
||||
};
|
||||
std::jthread menuTrackLoader;
|
||||
Starfield starfield;
|
||||
starfield.init(200, LOGICAL_W, LOGICAL_H);
|
||||
Starfield3D starfield3D;
|
||||
@ -904,7 +902,7 @@ int main(int, char **)
|
||||
// Allow states to access the state manager for transitions
|
||||
ctx.stateManager = &stateMgr;
|
||||
ctx.game = &game;
|
||||
ctx.scores = &scores;
|
||||
ctx.scores = nullptr; // populated once async load finishes
|
||||
ctx.starfield = &starfield;
|
||||
ctx.starfield3D = &starfield3D;
|
||||
ctx.font = &font;
|
||||
@ -938,6 +936,15 @@ int main(int, char **)
|
||||
running = false;
|
||||
};
|
||||
|
||||
auto ensureScoresLoaded = [&]() {
|
||||
if (scoreLoader.joinable()) {
|
||||
scoreLoader.join();
|
||||
}
|
||||
if (!ctx.scores) {
|
||||
ctx.scores = &scores;
|
||||
}
|
||||
};
|
||||
|
||||
auto beginStateFade = [&](AppState targetState, bool armGameplayCountdown) {
|
||||
if (!ctx.stateManager) {
|
||||
return;
|
||||
@ -1023,6 +1030,10 @@ int main(int, char **)
|
||||
// Playing, LevelSelect and GameOver currently use inline logic in main; we'll migrate later
|
||||
while (running)
|
||||
{
|
||||
if (!ctx.scores && scoresLoadComplete.load(std::memory_order_acquire)) {
|
||||
ensureScoresLoaded();
|
||||
}
|
||||
|
||||
int winW = 0, winH = 0;
|
||||
SDL_GetWindowSize(window, &winW, &winH);
|
||||
|
||||
@ -1460,14 +1471,17 @@ int main(int, char **)
|
||||
// Load menu track once on first menu entry (in background to avoid blocking)
|
||||
static bool menuTrackLoaded = false;
|
||||
if (!menuTrackLoaded) {
|
||||
std::thread([]() {
|
||||
if (menuTrackLoader.joinable()) {
|
||||
menuTrackLoader.join();
|
||||
}
|
||||
menuTrackLoader = std::jthread([]() {
|
||||
std::string menuTrack = AssetPath::resolveWithExtensions("assets/music/Every Block You Take", { ".mp3" });
|
||||
if (!menuTrack.empty()) {
|
||||
Audio::instance().setMenuTrack(menuTrack);
|
||||
} else {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Menu track not found (Every Block You Take)");
|
||||
}
|
||||
}).detach();
|
||||
});
|
||||
menuTrackLoaded = true;
|
||||
}
|
||||
|
||||
@ -1959,6 +1973,15 @@ int main(int, char **)
|
||||
// Save settings on exit
|
||||
Settings::instance().save();
|
||||
|
||||
if (scoreLoader.joinable()) {
|
||||
scoreLoader.join();
|
||||
if (!ctx.scores) {
|
||||
ctx.scores = &scores;
|
||||
}
|
||||
}
|
||||
if (menuTrackLoader.joinable()) {
|
||||
menuTrackLoader.join();
|
||||
}
|
||||
lineEffect.shutdown();
|
||||
Audio::instance().shutdown();
|
||||
SoundEffectManager::instance().shutdown();
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
// Use dynamic logical dimensions from GlobalState instead of hardcoded values
|
||||
// This allows the UI to adapt when the window is resized or goes fullscreen
|
||||
@ -239,7 +240,8 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
|
||||
// High scores table with wave offset
|
||||
float scoresStartY = topPlayersY + 70; // more spacing under title
|
||||
const auto &hs = ctx.scores ? ctx.scores->all() : *(new std::vector<ScoreEntry>());
|
||||
static const std::vector<ScoreEntry> EMPTY_SCORES;
|
||||
const auto& hs = ctx.scores ? ctx.scores->all() : EMPTY_SCORES;
|
||||
size_t maxDisplay = std::min(hs.size(), size_t(12));
|
||||
|
||||
// Draw table header
|
||||
|
||||
Reference in New Issue
Block a user