fixed loader and music playback

This commit is contained in:
2025-12-16 14:18:15 +01:00
parent 81586aa768
commit 29c1d6b745
2 changed files with 49 additions and 21 deletions

View File

@ -5,7 +5,7 @@
Fullscreen=1 Fullscreen=1
[Audio] [Audio]
Music=0 Music=1
Sound=1 Sound=1
[Gameplay] [Gameplay]
@ -14,7 +14,7 @@ SmoothScroll=1
UpRotateClockwise=0 UpRotateClockwise=0
[Player] [Player]
Name=PLAYER Name=GREGOR
[Debug] [Debug]
Enabled=1 Enabled=1

View File

@ -699,6 +699,13 @@ int main(int, char **)
SDL_Texture* statisticsPanelTex = nullptr; SDL_Texture* statisticsPanelTex = nullptr;
SDL_Texture* nextPanelTex = nullptr; SDL_Texture* nextPanelTex = nullptr;
// Music loading tracking
int totalTracks = 0;
int currentTrackLoading = 0;
bool musicLoaded = false;
bool musicStarted = false;
bool musicLoadingStarted = false;
// Loader control: execute incrementally on main thread to avoid SDL threading issues // Loader control: execute incrementally on main thread to avoid SDL threading issues
std::atomic_bool g_loadingStarted{false}; std::atomic_bool g_loadingStarted{false};
std::atomic_bool g_loadingComplete{false}; std::atomic_bool g_loadingComplete{false};
@ -710,7 +717,8 @@ int main(int, char **)
// Initialize counters on first step // Initialize counters on first step
if (step == 0) { if (step == 0) {
g_totalLoadingTasks.store(25); // Total: 2 fonts + 2 logos + 1 main + 1 blocks + 3 panels + 16 audio constexpr int baseTasks = 25; // 2 fonts + 2 logos + 1 main + 1 blocks + 3 panels + 16 SFX
g_totalLoadingTasks.store(baseTasks);
g_loadedTasks.store(0); g_loadedTasks.store(0);
{ {
std::lock_guard<std::mutex> lk(g_assetLoadErrorsMutex); std::lock_guard<std::mutex> lk(g_assetLoadErrorsMutex);
@ -720,6 +728,26 @@ int main(int, char **)
std::lock_guard<std::mutex> lk(g_currentLoadingMutex); std::lock_guard<std::mutex> lk(g_currentLoadingMutex);
g_currentLoadingFile.clear(); g_currentLoadingFile.clear();
} }
// Initialize background music loading
Audio::instance().init();
for (int i = 1; i <= 100; ++i) {
char base[128];
std::snprintf(base, sizeof(base), "assets/music/music%03d", i);
std::string path = AssetPath::resolveWithExtensions(base, { ".mp3" });
if (path.empty()) break;
Audio::instance().addTrackAsync(path);
totalTracks++;
}
// Expand task budget to account for music tracks so the loading bar waits for them
g_totalLoadingTasks.store(baseTasks + totalTracks);
if (totalTracks > 0) {
Audio::instance().startBackgroundLoading();
musicLoadingStarted = true;
} else {
// No music files found, mark as loaded so game can continue
musicLoaded = true;
}
} }
// Execute one load operation per step // Execute one load operation per step
@ -851,10 +879,6 @@ int main(int, char **)
SDL_Rect logicalVP{0, 0, LOGICAL_W, LOGICAL_H}; SDL_Rect logicalVP{0, 0, LOGICAL_W, LOGICAL_H};
float logicalScale = 1.f; float logicalScale = 1.f;
Uint64 lastMs = SDL_GetPerformanceCounter(); Uint64 lastMs = SDL_GetPerformanceCounter();
bool musicStarted = false;
bool musicLoaded = false;
int currentTrackLoading = 0;
int totalTracks = 0; // Will be set dynamically based on actual files
enum class MenuFadePhase { None, FadeOut, FadeIn }; enum class MenuFadePhase { None, FadeOut, FadeIn };
MenuFadePhase menuFadePhase = MenuFadePhase::None; MenuFadePhase menuFadePhase = MenuFadePhase::None;
@ -1399,6 +1423,18 @@ int main(int, char **)
rightHeld = right; rightHeld = right;
if (down && !game.isPaused()) if (down && !game.isPaused())
game.softDropBoost(frameMs); game.softDropBoost(frameMs);
// Track music loading on every frame so it finishes even after the loading screen ends
if (musicLoadingStarted && !musicLoaded) {
currentTrackLoading = Audio::instance().getLoadedTrackCount();
if (Audio::instance().isLoadingComplete() || (totalTracks > 0 && currentTrackLoading >= totalTracks)) {
Audio::instance().shuffle();
if (musicEnabled) {
Audio::instance().start();
}
musicLoaded = true;
}
}
if (state == AppState::Playing) if (state == AppState::Playing)
{ {
if (!game.isPaused()) { if (!game.isPaused()) {
@ -1438,22 +1474,14 @@ int main(int, char **)
} }
} }
// Update progress based on background loading
if (currentTrackLoading > 0 && !musicLoaded) {
currentTrackLoading = Audio::instance().getLoadedTrackCount();
// If loading is complete OR we've loaded all expected tracks (handles potential thread cleanup hang)
if (Audio::instance().isLoadingComplete() || (totalTracks > 0 && currentTrackLoading >= totalTracks)) {
Audio::instance().shuffle(); // Shuffle once all tracks are loaded
musicLoaded = true;
}
}
// Prefer task-based progress if we have tasks registered // Prefer task-based progress if we have tasks registered
int totalTasks = g_totalLoadingTasks.load(std::memory_order_acquire); const int totalTasks = g_totalLoadingTasks.load(std::memory_order_acquire);
int doneTasks = g_loadedTasks.load(std::memory_order_acquire); const int musicDone = std::min(totalTracks, currentTrackLoading);
int doneTasks = g_loadedTasks.load(std::memory_order_acquire) + musicDone;
if (doneTasks > totalTasks) doneTasks = totalTasks;
if (totalTasks > 0) { if (totalTasks > 0) {
loadingProgress = std::min(1.0, double(doneTasks) / double(totalTasks)); loadingProgress = std::min(1.0, double(doneTasks) / double(totalTasks));
if (loadingProgress >= 1.0) { if (loadingProgress >= 1.0 && musicLoaded) {
state = AppState::Menu; state = AppState::Menu;
stateMgr.setState(state); stateMgr.setState(state);
} }
@ -1481,7 +1509,7 @@ int main(int, char **)
double timeProgress = std::min(0.1, (now - loadStart) / 500.0); double timeProgress = std::min(0.1, (now - loadStart) / 500.0);
loadingProgress = std::min(1.0, assetProgress + musicProgress + timeProgress); loadingProgress = std::min(1.0, assetProgress + musicProgress + timeProgress);
if (loadingProgress > 0.99) loadingProgress = 1.0; if (loadingProgress > 0.99) loadingProgress = 1.0;
if (musicLoaded && timeProgress >= 0.1) loadingProgress = 1.0; if (!musicLoaded && timeProgress >= 0.1) loadingProgress = 1.0;
if (loadingProgress >= 1.0 && musicLoaded) { if (loadingProgress >= 1.0 && musicLoaded) {
state = AppState::Menu; state = AppState::Menu;
stateMgr.setState(state); stateMgr.setState(state);