Added hold block and minor fixes
This commit is contained in:
@ -77,7 +77,11 @@ bool AssetLoader::performStep() {
|
||||
m_errors.push_back(std::string("CreateTexture failed: ") + fullPath);
|
||||
} else {
|
||||
std::lock_guard<std::mutex> lk(m_texturesMutex);
|
||||
m_textures[path] = tex;
|
||||
auto& slot = m_textures[path];
|
||||
if (slot && slot != tex) {
|
||||
SDL_DestroyTexture(slot);
|
||||
}
|
||||
slot = tex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +99,19 @@ bool AssetLoader::performStep() {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoader::adoptTexture(const std::string& path, SDL_Texture* texture) {
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lk(m_texturesMutex);
|
||||
auto& slot = m_textures[path];
|
||||
if (slot && slot != texture) {
|
||||
SDL_DestroyTexture(slot);
|
||||
}
|
||||
slot = texture;
|
||||
}
|
||||
|
||||
float AssetLoader::getProgress() const {
|
||||
int total = m_totalTasks.load(std::memory_order_relaxed);
|
||||
if (total <= 0) return 1.0f;
|
||||
|
||||
@ -39,6 +39,10 @@ public:
|
||||
// Get a loaded texture (or nullptr if not loaded).
|
||||
SDL_Texture* getTexture(const std::string& path) const;
|
||||
|
||||
// Adopt an externally-created texture so AssetLoader owns its lifetime.
|
||||
// If a texture is already registered for this path, it will be replaced.
|
||||
void adoptTexture(const std::string& path, SDL_Texture* texture);
|
||||
|
||||
// Return currently-loading path (empty when idle).
|
||||
std::string getCurrentLoading() const;
|
||||
|
||||
|
||||
@ -139,6 +139,7 @@ struct TetrisApp::Impl {
|
||||
SDL_Texture* scorePanelTex = nullptr;
|
||||
SDL_Texture* statisticsPanelTex = nullptr;
|
||||
SDL_Texture* nextPanelTex = nullptr;
|
||||
SDL_Texture* holdPanelTex = nullptr;
|
||||
|
||||
BackgroundManager levelBackgrounds;
|
||||
int startLevelSelection = 0;
|
||||
@ -973,7 +974,8 @@ void TetrisApp::Impl::runLoop()
|
||||
"assets/images/blocks90px_001.bmp",
|
||||
"assets/images/panel_score.png",
|
||||
"assets/images/statistics_panel.png",
|
||||
"assets/images/next_panel.png"
|
||||
"assets/images/next_panel.png",
|
||||
"assets/images/hold_panel.png"
|
||||
};
|
||||
for (auto &p : queuedPaths) {
|
||||
loadingManager->queueTexture(p);
|
||||
@ -1007,10 +1009,11 @@ void TetrisApp::Impl::runLoop()
|
||||
logoTex = assetLoader.getTexture("assets/images/spacetris.png");
|
||||
logoSmallTex = assetLoader.getTexture("assets/images/spacetris.png");
|
||||
mainScreenTex = assetLoader.getTexture("assets/images/main_screen.png");
|
||||
blocksTex = assetLoader.getTexture("assets/images/blocks90px_001.bmp");
|
||||
blocksTex = assetLoader.getTexture("assets/images/blocks90px_001.png");
|
||||
scorePanelTex = assetLoader.getTexture("assets/images/panel_score.png");
|
||||
statisticsPanelTex = assetLoader.getTexture("assets/images/statistics_panel.png");
|
||||
nextPanelTex = assetLoader.getTexture("assets/images/next_panel.png");
|
||||
holdPanelTex = assetLoader.getTexture("assets/images/hold_panel.png");
|
||||
|
||||
auto ensureTextureSize = [&](SDL_Texture* tex, int& outW, int& outH) {
|
||||
if (!tex) return;
|
||||
@ -1027,17 +1030,22 @@ void TetrisApp::Impl::runLoop()
|
||||
|
||||
auto legacyLoad = [&](const std::string& p, SDL_Texture*& outTex, int* outW = nullptr, int* outH = nullptr) {
|
||||
if (!outTex) {
|
||||
outTex = textureLoader->loadFromImage(renderer, p, outW, outH);
|
||||
SDL_Texture* loaded = textureLoader->loadFromImage(renderer, p, outW, outH);
|
||||
if (loaded) {
|
||||
outTex = loaded;
|
||||
assetLoader.adoptTexture(p, loaded);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
legacyLoad("assets/images/spacetris.png", logoTex);
|
||||
legacyLoad("assets/images/spacetris.png", logoSmallTex, &logoSmallW, &logoSmallH);
|
||||
legacyLoad("assets/images/main_screen.png", mainScreenTex, &mainScreenW, &mainScreenH);
|
||||
legacyLoad("assets/images/blocks90px_001.bmp", blocksTex);
|
||||
legacyLoad("assets/images/blocks90px_001.png", blocksTex);
|
||||
legacyLoad("assets/images/panel_score.png", scorePanelTex);
|
||||
legacyLoad("assets/images/statistics_panel.png", statisticsPanelTex);
|
||||
legacyLoad("assets/images/next_panel.png", nextPanelTex);
|
||||
legacyLoad("assets/images/hold_panel.png", holdPanelTex);
|
||||
|
||||
if (!blocksTex) {
|
||||
blocksTex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 630, 90);
|
||||
@ -1051,6 +1059,9 @@ void TetrisApp::Impl::runLoop()
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
}
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
|
||||
// Ensure the generated fallback texture is cleaned up with other assets.
|
||||
assetLoader.adoptTexture("assets/images/blocks90px_001.png", blocksTex);
|
||||
}
|
||||
|
||||
if (musicLoaded) {
|
||||
@ -1192,6 +1203,7 @@ void TetrisApp::Impl::runLoop()
|
||||
ctx.scorePanelTex = scorePanelTex;
|
||||
ctx.statisticsPanelTex = statisticsPanelTex;
|
||||
ctx.nextPanelTex = nextPanelTex;
|
||||
ctx.holdPanelTex = holdPanelTex;
|
||||
ctx.mainScreenTex = mainScreenTex;
|
||||
ctx.mainScreenW = mainScreenW;
|
||||
ctx.mainScreenH = mainScreenH;
|
||||
@ -1417,7 +1429,14 @@ void TetrisApp::Impl::runLoop()
|
||||
break;
|
||||
case AppState::Menu:
|
||||
if (!mainScreenTex) {
|
||||
mainScreenTex = textureLoader->loadFromImage(renderer, "assets/images/main_screen.png", &mainScreenW, &mainScreenH);
|
||||
mainScreenTex = assetLoader.getTexture("assets/images/main_screen.png");
|
||||
}
|
||||
if (!mainScreenTex) {
|
||||
SDL_Texture* loaded = textureLoader->loadFromImage(renderer, "assets/images/main_screen.png", &mainScreenW, &mainScreenH);
|
||||
if (loaded) {
|
||||
assetLoader.adoptTexture("assets/images/main_screen.png", loaded);
|
||||
mainScreenTex = loaded;
|
||||
}
|
||||
}
|
||||
if (menuState) {
|
||||
menuState->drawMainButtonNormally = false;
|
||||
@ -1490,6 +1509,7 @@ void TetrisApp::Impl::runLoop()
|
||||
ctx.statisticsPanelTex,
|
||||
scorePanelTex,
|
||||
nextPanelTex,
|
||||
holdPanelTex,
|
||||
(float)LOGICAL_W,
|
||||
(float)LOGICAL_H,
|
||||
logicalScale,
|
||||
@ -1669,27 +1689,18 @@ void TetrisApp::Impl::shutdown()
|
||||
{
|
||||
Settings::instance().save();
|
||||
|
||||
if (logoTex) {
|
||||
SDL_DestroyTexture(logoTex);
|
||||
logoTex = nullptr;
|
||||
}
|
||||
if (mainScreenTex) {
|
||||
SDL_DestroyTexture(mainScreenTex);
|
||||
mainScreenTex = nullptr;
|
||||
}
|
||||
// BackgroundManager owns its own textures.
|
||||
levelBackgrounds.reset();
|
||||
if (blocksTex) {
|
||||
SDL_DestroyTexture(blocksTex);
|
||||
blocksTex = nullptr;
|
||||
}
|
||||
if (scorePanelTex) {
|
||||
SDL_DestroyTexture(scorePanelTex);
|
||||
scorePanelTex = nullptr;
|
||||
}
|
||||
if (logoSmallTex) {
|
||||
SDL_DestroyTexture(logoSmallTex);
|
||||
logoSmallTex = nullptr;
|
||||
}
|
||||
|
||||
// All textures are owned by AssetLoader (including legacy fallbacks adopted above).
|
||||
logoTex = nullptr;
|
||||
logoSmallTex = nullptr;
|
||||
backgroundTex = nullptr;
|
||||
mainScreenTex = nullptr;
|
||||
blocksTex = nullptr;
|
||||
scorePanelTex = nullptr;
|
||||
statisticsPanelTex = nullptr;
|
||||
nextPanelTex = nullptr;
|
||||
|
||||
if (scoreLoader.joinable()) {
|
||||
scoreLoader.join();
|
||||
@ -1704,6 +1715,11 @@ void TetrisApp::Impl::shutdown()
|
||||
lineEffect.shutdown();
|
||||
Audio::instance().shutdown();
|
||||
SoundEffectManager::instance().shutdown();
|
||||
|
||||
// Destroy textures before tearing down the renderer/window.
|
||||
assetLoader.shutdown();
|
||||
|
||||
pixelFont.shutdown();
|
||||
font.shutdown();
|
||||
|
||||
TTF_Quit();
|
||||
|
||||
Reference in New Issue
Block a user