Working on loading screen
This commit is contained in:
parent
1c2c80f0ea
commit
44f5136f1d
117
src/Game.cpp
117
src/Game.cpp
@ -44,15 +44,11 @@ namespace ZL
|
|||||||
std::cout << "Resources.zip loaded successfully--0" << std::endl;
|
std::cout << "Resources.zip loaded successfully--0" << std::endl;
|
||||||
if (s_instance) {
|
if (s_instance) {
|
||||||
s_instance->resourcesDownloadProgress = 1.0f;
|
s_instance->resourcesDownloadProgress = 1.0f;
|
||||||
/*s_instance->mainThreadHandler.EnqueueMainThreadTask([&]() {
|
// Builds the loadSteps queue (cheap, no GL work); the actual loading
|
||||||
|
// happens one step per frame in Game::update() so the browser tab
|
||||||
|
// keeps repainting/responding instead of freezing for the whole load.
|
||||||
s_instance->setupPart2();
|
s_instance->setupPart2();
|
||||||
});*/
|
|
||||||
std::cout << "s_instance setup part 2" << std::endl;
|
|
||||||
s_instance->setupPart2();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
std::cout << "s_instance end setup" << std::endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int /*httpStatus*/) {
|
void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int /*httpStatus*/) {
|
||||||
@ -107,12 +103,11 @@ namespace ZL
|
|||||||
#endif
|
#endif
|
||||||
loadingTexture = renderer.textureManager.LoadFromPng("resources/loading.png", "");
|
loadingTexture = renderer.textureManager.LoadFromPng("resources/loading.png", "");
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
loadingProgressBarFrameTexture = renderer.textureManager.LoadFromPng(
|
loadingProgressBarFrameTexture = renderer.textureManager.LoadFromPng(
|
||||||
"resources/loadingProgressBarFrame.png", "", true);
|
"resources/loadingProgressBarFrame.png", "", true);
|
||||||
loadingProgressBarTexture = renderer.textureManager.LoadFromPng(
|
loadingProgressBarTexture = renderer.textureManager.LoadFromPng(
|
||||||
"resources/loadingProgressBar.png", "", true);
|
"resources/loadingProgressBar.png", "", true);
|
||||||
#endif
|
|
||||||
float minDimension;
|
float minDimension;
|
||||||
float width = Environment::projectionWidth;
|
float width = Environment::projectionWidth;
|
||||||
float height = Environment::projectionHeight;
|
float height = Environment::projectionHeight;
|
||||||
@ -137,76 +132,54 @@ namespace ZL
|
|||||||
emscripten_async_wget2("resources.zip", "resources.zip", "GET", nullptr, nullptr,
|
emscripten_async_wget2("resources.zip", "resources.zip", "GET", nullptr, nullptr,
|
||||||
onResourcesZipLoaded, onResourcesZipError, onResourcesZipProgress);
|
onResourcesZipLoaded, onResourcesZipError, onResourcesZipProgress);
|
||||||
#else
|
#else
|
||||||
mainThreadHandler.EnqueueMainThreadTask([this]() {
|
// Builds the loadSteps queue (cheap, no GL work); the actual loading
|
||||||
std::cout << "Load resurces step 2" << std::endl;
|
// happens one step per frame in Game::update() so the window keeps
|
||||||
this->setupPart2();
|
// pumping events / repainting instead of freezing for the whole load.
|
||||||
std::cout << "Load resurces step 3" << std::endl;
|
setupPart2();
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::setupPart2()
|
void Game::setupPart2()
|
||||||
{
|
{
|
||||||
std::cout << "Load resurces step 12x1" << std::endl;
|
// Builds an ordered queue of small closures instead of doing the work here.
|
||||||
|
// Game::update() drains one closure per frame, so the event loop / browser
|
||||||
|
// paint gets a turn between steps instead of the window freezing for the
|
||||||
|
// whole duration of loading. Building the queue itself is cheap (no GL calls).
|
||||||
|
|
||||||
// Must happen before createLocations() below: some location scripts
|
// Must happen before the location step below: some location scripts
|
||||||
// (e.g. resources/start_dorm.lua) start a dialogue as soon as they're
|
// (e.g. resources/start_dorm.lua) start a dialogue as soon as they're
|
||||||
// loaded, so the language needs to be known before that first load.
|
// loaded, so the language needs to be known before that first load.
|
||||||
|
loadSteps.push([this]() {
|
||||||
ZL::loadLanguageSetting();
|
ZL::loadLanguageSetting();
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x2" << std::endl;
|
|
||||||
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x3" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x4" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "resources/shaders/planet_stone.vertex", "resources/shaders/planet_stone_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetStone", "resources/shaders/planet_stone.vertex", "resources/shaders/planet_stone_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x5" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "resources/shaders/planet_land.vertex", "resources/shaders/planet_land_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetLand", "resources/shaders/planet_land.vertex", "resources/shaders/planet_land_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x6" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("spark", "resources/shaders/spark.vertex", "resources/shaders/spark_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("spark", "resources/shaders/spark.vertex", "resources/shaders/spark_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x7" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("skinning", "resources/shaders/skinning.vertex", "resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("skinning", "resources/shaders/skinning.vertex", "resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x8" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("fog", "resources/shaders/fog.vertex", "resources/shaders/fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("fog", "resources/shaders/fog.vertex", "resources/shaders/fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x9" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("fog_skinning", "resources/shaders/fog_skinning.vertex", "resources/shaders/fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("fog_skinning", "resources/shaders/fog_skinning.vertex", "resources/shaders/fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x10" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("darklands_fog", "resources/shaders/darklands_fog.vertex", "resources/shaders/darklands_fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("darklands_fog", "resources/shaders/darklands_fog.vertex", "resources/shaders/darklands_fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x11" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("darklands_fog_skinning", "resources/shaders/darklands_fog_skinning.vertex", "resources/shaders/darklands_fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("darklands_fog_skinning", "resources/shaders/darklands_fog_skinning.vertex", "resources/shaders/darklands_fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x12" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("darklands_flash", "resources/shaders/default.vertex", "resources/shaders/darklands_flash_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("darklands_flash", "resources/shaders/default.vertex", "resources/shaders/darklands_flash_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x13" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("cutsceneFade", "resources/shaders/default.vertex", "resources/shaders/cutscene_fade_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("cutsceneFade", "resources/shaders/default.vertex", "resources/shaders/cutscene_fade_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x14" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("cutsceneBlack", "resources/shaders/default.vertex", "resources/shaders/cutscene_black_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("cutsceneBlack", "resources/shaders/default.vertex", "resources/shaders/cutscene_black_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x15" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("shadow_depth", "resources/shaders/shadow_depth.vertex", "resources/shaders/shadow_depth_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("shadow_depth", "resources/shaders/shadow_depth.vertex", "resources/shaders/shadow_depth_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x16" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("shadow_depth_skinning", "resources/shaders/shadow_depth_skinning.vertex", "resources/shaders/shadow_depth_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("shadow_depth_skinning", "resources/shaders/shadow_depth_skinning.vertex", "resources/shaders/shadow_depth_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x17" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("default_shadow", "resources/shaders/default_shadow.vertex", "resources/shaders/default_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default_shadow", "resources/shaders/default_shadow.vertex", "resources/shaders/default_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x18" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("skinning_shadow", "resources/shaders/skinning_shadow.vertex", "resources/shaders/default_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("skinning_shadow", "resources/shaders/skinning_shadow.vertex", "resources/shaders/default_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x19" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("fog_shadow", "resources/shaders/fog_shadow.vertex", "resources/shaders/fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("fog_shadow", "resources/shaders/fog_shadow.vertex", "resources/shaders/fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x20" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("fog_skinning_shadow", "resources/shaders/fog_skinning_shadow.vertex", "resources/shaders/fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("fog_skinning_shadow", "resources/shaders/fog_skinning_shadow.vertex", "resources/shaders/fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x21" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog", "resources/shaders/night_fog.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog", "resources/shaders/night_fog.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x22" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x23" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x24" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
std::cout << "Load resurces step 12x25" << std::endl;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
||||||
@ -232,9 +205,10 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_aiperi.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_aiperi.png", CONST_ZIP_FILE);
|
||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_ghost.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_ghost.png", CONST_ZIP_FILE);
|
||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_hero_neutral.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_hero_neutral.png", CONST_ZIP_FILE);
|
||||||
@ -243,15 +217,21 @@ namespace ZL
|
|||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_student_boy.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_student_boy.png", CONST_ZIP_FILE);
|
||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_student_girl.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_student_girl.png", CONST_ZIP_FILE);
|
||||||
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_teacher.png", CONST_ZIP_FILE);
|
renderer.textureManager.LoadFromPng("resources/dialogue/portrait_teacher.png", CONST_ZIP_FILE);
|
||||||
|
});
|
||||||
|
|
||||||
std::cout << "Load resurces step 4" << std::endl;
|
loadSteps.push([this]() {
|
||||||
|
|
||||||
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
|
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
|
||||||
|
|
||||||
Character::nameTranslations.loadFromFile("resources/config/translate_names.json");
|
Character::nameTranslations.loadFromFile("resources/config/translate_names.json");
|
||||||
|
});
|
||||||
|
|
||||||
|
// createLocations() is also used by the full-reset path (see performFullReset()),
|
||||||
|
// so it stays a single synchronous function rather than being split into
|
||||||
|
// per-location queue steps; it's queued here as one coarse step.
|
||||||
|
loadSteps.push([this]() {
|
||||||
createLocations();
|
createLocations();
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
// Wire inventory callbacks: tutorial tracking + toast notifications.
|
// Wire inventory callbacks: tutorial tracking + toast notifications.
|
||||||
gameState.inventory.onItemAdded = [this](const std::string& itemId) {
|
gameState.inventory.onItemAdded = [this](const std::string& itemId) {
|
||||||
menuManager.onItemPickedUp(itemId);
|
menuManager.onItemPickedUp(itemId);
|
||||||
@ -286,15 +266,14 @@ namespace ZL
|
|||||||
menuManager.skipCutsceneFunc = [this]() {
|
menuManager.skipCutsceneFunc = [this]() {
|
||||||
if (currentLocation()) currentLocation()->dialogueSystem.skipCutscene();
|
if (currentLocation()) currentLocation()->dialogueSystem.skipCutscene();
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
std::cout << "Load resurces step 13" << std::endl;
|
loadSteps.push([this]() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
menuManager.setup(gameState.inventory, CONST_ZIP_FILE);
|
menuManager.setup(gameState.inventory, CONST_ZIP_FILE);
|
||||||
std::cout << "UI loaded successfully" << std::endl;
|
std::cout << "UI loaded successfully" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
|
|
||||||
std::cerr << "Failed to load UI: " << e.what() << std::endl;
|
std::cerr << "Failed to load UI: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +290,21 @@ namespace ZL
|
|||||||
menuManager.onLoadGame = [this](int slot) { loadGame(slot); };
|
menuManager.onLoadGame = [this](int slot) { loadGame(slot); };
|
||||||
menuManager.getSlotInfoFunc = [this](int slot) { return readSlotInfo(slot); };
|
menuManager.getSlotInfoFunc = [this](int slot) { return readSlotInfo(slot); };
|
||||||
|
|
||||||
|
// Lets MenuManager run a heavy operation (e.g. reloadLocalizedGameContent())
|
||||||
|
// as a chunked sequence instead of one blocking call: the closures are
|
||||||
|
// drained one per frame by update(), with the loading screen shown for
|
||||||
|
// the duration, exactly like the initial resource load.
|
||||||
|
menuManager.runAsLoadingSequence = [this](std::vector<std::function<void()>> steps) {
|
||||||
|
for (auto& step : steps) loadSteps.push(std::move(step));
|
||||||
|
loadSteps.push([this]() { loadingCompleted = true; });
|
||||||
|
loadStepsTotal = loadSteps.size();
|
||||||
|
loadStepsDone = 0;
|
||||||
|
showLoadingProgressBar = false;
|
||||||
|
loadingCompleted = false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
if (audioPlayer->init()) {
|
if (audioPlayer->init()) {
|
||||||
audioPlayer->setMusicVolume(100);
|
audioPlayer->setMusicVolume(100);
|
||||||
audioPlayer->setSoundVolume(80);
|
audioPlayer->setSoundVolume(80);
|
||||||
@ -319,14 +313,19 @@ namespace ZL
|
|||||||
else {
|
else {
|
||||||
std::cout << "Audio initialization failed" << std::endl;
|
std::cout << "Audio initialization failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
menuManager.loadSettings();
|
menuManager.loadSettings();
|
||||||
|
|
||||||
audioPlayer->crossFadeMusicAsync("audio/main menu final.ogg");
|
audioPlayer->crossFadeMusicAsync("audio/main menu final.ogg");
|
||||||
|
});
|
||||||
|
|
||||||
|
loadSteps.push([this]() {
|
||||||
loadingCompleted = true;
|
loadingCompleted = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
loadStepsTotal = loadSteps.size();
|
||||||
|
loadStepsDone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::rearmDormOneShotCallbacks() {
|
void Game::rearmDormOneShotCallbacks() {
|
||||||
@ -860,8 +859,7 @@ namespace ZL
|
|||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
if (showLoadingProgressBar && loadingProgressBarFrameTexture && loadingProgressBarTexture) {
|
||||||
if (loadingProgressBarFrameTexture && loadingProgressBarTexture) {
|
|
||||||
const float W = Environment::projectionWidth;
|
const float W = Environment::projectionWidth;
|
||||||
const float H = Environment::projectionHeight;
|
const float H = Environment::projectionHeight;
|
||||||
static constexpr float kBarW = 400.0f;
|
static constexpr float kBarW = 400.0f;
|
||||||
@ -891,7 +889,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rebuild fill mesh when progress changes
|
// Rebuild fill mesh when progress changes
|
||||||
const float p = std::min(resourcesDownloadProgress, 1.0f);
|
const float p = (std::min)(currentLoadingProgress(), 1.0f);
|
||||||
if (p != loadingBarLastRenderedProgress) {
|
if (p != loadingBarLastRenderedProgress) {
|
||||||
loadingBarLastRenderedProgress = p;
|
loadingBarLastRenderedProgress = p;
|
||||||
if (p > 0.001f) {
|
if (p > 0.001f) {
|
||||||
@ -932,7 +930,6 @@ namespace ZL
|
|||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
CheckGlError(__FILE__, __LINE__);
|
CheckGlError(__FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
@ -1282,6 +1279,14 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Drain one loading step per frame so the window/tab keeps pumping events
|
||||||
|
// and repainting between steps instead of freezing for the whole load.
|
||||||
|
if (!loadingCompleted && !loadSteps.empty()) {
|
||||||
|
loadSteps.front()();
|
||||||
|
loadSteps.pop();
|
||||||
|
loadStepsDone++;
|
||||||
|
}
|
||||||
|
|
||||||
render();
|
render();
|
||||||
|
|
||||||
mainThreadHandler.processMainThreadTasks();
|
mainThreadHandler.processMainThreadTasks();
|
||||||
|
|||||||
25
src/Game.h
25
src/Game.h
@ -10,6 +10,7 @@
|
|||||||
#include "items/Item.h"
|
#include "items/Item.h"
|
||||||
#include "items/InteractiveObject.h"
|
#include "items/InteractiveObject.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -49,6 +50,22 @@ namespace ZL {
|
|||||||
VertexRenderStruct loadingMesh;
|
VertexRenderStruct loadingMesh;
|
||||||
bool loadingCompleted = false;
|
bool loadingCompleted = false;
|
||||||
|
|
||||||
|
// setupPart2() populates this queue with one closure per loading step instead of
|
||||||
|
// running the work itself; Game::update() drains one step per frame so the window
|
||||||
|
// keeps pumping events / repainting (and, on Emscripten, the browser keeps the tab
|
||||||
|
// responsive) instead of freezing for the whole duration of loading.
|
||||||
|
std::queue<std::function<void()>> loadSteps;
|
||||||
|
size_t loadStepsTotal = 0;
|
||||||
|
size_t loadStepsDone = 0;
|
||||||
|
float currentLoadingProgress() const {
|
||||||
|
return loadStepsTotal ? (float)loadStepsDone / (float)loadStepsTotal : resourcesDownloadProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The progress bar only reflects the initial resource load (its steps are
|
||||||
|
// pre-counted upfront). Later loadSteps runs, like MenuManager's localized
|
||||||
|
// content reload, don't have a meaningful denominator, so the bar is hidden.
|
||||||
|
bool showLoadingProgressBar = true;
|
||||||
|
|
||||||
GameState gameState;
|
GameState gameState;
|
||||||
|
|
||||||
EditorMode editorMode = EditorMode::None;
|
EditorMode editorMode = EditorMode::None;
|
||||||
@ -138,8 +155,13 @@ namespace ZL {
|
|||||||
static void onResourcesZipLoaded(unsigned handle, void* userData, const char* filename);
|
static void onResourcesZipLoaded(unsigned handle, void* userData, const char* filename);
|
||||||
static void onResourcesZipError(unsigned handle, void* userData, int httpStatus);
|
static void onResourcesZipError(unsigned handle, void* userData, int httpStatus);
|
||||||
static void onResourcesZipProgress(unsigned handle, void* userData, int percentComplete);
|
static void onResourcesZipProgress(unsigned handle, void* userData, int percentComplete);
|
||||||
|
#endif
|
||||||
|
// Only meaningful during the Emscripten zip-download phase, before loadSteps
|
||||||
|
// exists (see currentLoadingProgress() above); harmless/unused on other platforms.
|
||||||
float resourcesDownloadProgress = 0.0f;
|
float resourcesDownloadProgress = 0.0f;
|
||||||
|
|
||||||
|
// Progress bar assets/meshes, loaded and drawn on every platform so setupPart2's
|
||||||
|
// step-by-step progress is visible during desktop/Android loading too.
|
||||||
std::shared_ptr<Texture> loadingProgressBarTexture;
|
std::shared_ptr<Texture> loadingProgressBarTexture;
|
||||||
std::shared_ptr<Texture> loadingProgressBarFrameTexture;
|
std::shared_ptr<Texture> loadingProgressBarFrameTexture;
|
||||||
VertexRenderStruct loadingProgressBarFrameMesh;
|
VertexRenderStruct loadingProgressBarFrameMesh;
|
||||||
@ -147,7 +169,6 @@ namespace ZL {
|
|||||||
float loadingBarLastRenderedProgress = -1.0f;
|
float loadingBarLastRenderedProgress = -1.0f;
|
||||||
float loadingBarLastW = -1.0f;
|
float loadingBarLastW = -1.0f;
|
||||||
float loadingBarLastH = -1.0f;
|
float loadingBarLastH = -1.0f;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Screen-flash transition state (shared by darklands and night transitions)
|
// Screen-flash transition state (shared by darklands and night transitions)
|
||||||
float darklandsFlashAlpha = 0.0f;
|
float darklandsFlashAlpha = 0.0f;
|
||||||
|
|||||||
@ -88,9 +88,11 @@ namespace ZL
|
|||||||
|
|
||||||
// Load static game objects
|
// Load static game objects
|
||||||
gameObjects = GameObjectLoader::loadAndCreateGameObjects(params.gameObjectsJsonPath, renderer, CONST_ZIP_FILE);
|
gameObjects = GameObjectLoader::loadAndCreateGameObjects(params.gameObjectsJsonPath, renderer, CONST_ZIP_FILE);
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
// Load interactive objects
|
// Load interactive objects
|
||||||
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects(params.interactiveObjectsJsonPath, renderer, CONST_ZIP_FILE);
|
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects(params.interactiveObjectsJsonPath, renderer, CONST_ZIP_FILE);
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
//auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
//auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
||||||
//auto playerTexture = renderer.textureManager.LoadFromPng("resources/w/gg/UniV_Grid_2K_Base_color.png", CONST_ZIP_FILE);
|
//auto playerTexture = renderer.textureManager.LoadFromPng("resources/w/gg/UniV_Grid_2K_Base_color.png", CONST_ZIP_FILE);
|
||||||
@ -140,6 +142,7 @@ namespace ZL
|
|||||||
player->setupHitSparks(sparkTexture);
|
player->setupHitSparks(sparkTexture);
|
||||||
player->audioPlayer = audioPlayer;
|
player->audioPlayer = audioPlayer;
|
||||||
std::cout << "Load resurces step 9" << std::endl;
|
std::cout << "Load resurces step 9" << std::endl;
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
// Load NPCs from JSON. Aggressive (canAttack) NPCs need a player target
|
// Load NPCs from JSON. Aggressive (canAttack) NPCs need a player target
|
||||||
// and hit sparks; peaceful NPCs don't take damage from the player so
|
// and hit sparks; peaceful NPCs don't take damage from the player so
|
||||||
@ -155,6 +158,8 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
loadTeleportZones(params.teleportsJsonPath, CONST_ZIP_FILE);
|
loadTeleportZones(params.teleportsJsonPath, CONST_ZIP_FILE);
|
||||||
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
|
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
|
||||||
loadPointLights(params.lightsJsonPath, CONST_ZIP_FILE);
|
loadPointLights(params.lightsJsonPath, CONST_ZIP_FILE);
|
||||||
@ -167,6 +172,7 @@ namespace ZL
|
|||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
setupNavigation(params.navigationJsonPaths);
|
setupNavigation(params.navigationJsonPaths);
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
||||||
dialogueSystem.loadDatabase(params.dialoguesJsonPath);
|
dialogueSystem.loadDatabase(params.dialoguesJsonPath);
|
||||||
@ -175,6 +181,8 @@ namespace ZL
|
|||||||
dialogueSystem.loadCutsceneTranslations("resources/dialogue/translate_cutscenes.json");
|
dialogueSystem.loadCutsceneTranslations("resources/dialogue/translate_cutscenes.json");
|
||||||
dialogueSystem.setQuestJournal(journal);
|
dialogueSystem.setQuestJournal(journal);
|
||||||
|
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
npcNameText = std::make_unique<TextRenderer>();
|
npcNameText = std::make_unique<TextRenderer>();
|
||||||
if (!npcNameText->init(renderer, "resources/fonts/DroidSans.ttf", 24, CONST_ZIP_FILE)) {
|
if (!npcNameText->init(renderer, "resources/fonts/DroidSans.ttf", 24, CONST_ZIP_FILE)) {
|
||||||
std::cerr << "Failed to init NPC name TextRenderer" << std::endl;
|
std::cerr << "Failed to init NPC name TextRenderer" << std::endl;
|
||||||
@ -405,6 +413,9 @@ namespace ZL
|
|||||||
navigationMaps.resize(paths.size());
|
navigationMaps.resize(paths.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < paths.size(); ++i) {
|
for (size_t i = 0; i < paths.size(); ++i) {
|
||||||
|
// Service the OS message queue between builds so the window doesn't
|
||||||
|
// get flagged as "not responding" while loading many navigation grids.
|
||||||
|
SDL_PumpEvents();
|
||||||
navigationMaps[i].build(paths[i], CONST_ZIP_FILE);
|
navigationMaps[i].build(paths[i], CONST_ZIP_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -119,6 +120,9 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UiNode> MenuManager::loadLocalizedUi(const std::string& basePath, const std::string& zipFile) {
|
std::shared_ptr<UiNode> MenuManager::loadLocalizedUi(const std::string& basePath, const std::string& zipFile) {
|
||||||
|
// Service the OS message queue between UI screens so the window doesn't
|
||||||
|
// get flagged as "not responding" while loading the ~50 UI layout files.
|
||||||
|
SDL_PumpEvents();
|
||||||
static const std::string marker = "resources/w/ui/";
|
static const std::string marker = "resources/w/ui/";
|
||||||
if (basePath.rfind(marker, 0) == 0) {
|
if (basePath.rfind(marker, 0) == 0) {
|
||||||
const std::string localizedPath = "resources/w/ui_" + languageToCode(g_currentLanguage) + "/" + basePath.substr(marker.size());
|
const std::string localizedPath = "resources/w/ui_" + languageToCode(g_currentLanguage) + "/" + basePath.substr(marker.size());
|
||||||
@ -507,9 +511,6 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::reloadLocalizedGameContent() {
|
void MenuManager::reloadLocalizedGameContent() {
|
||||||
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
|
|
||||||
gameState_.questJournal.reloadDefinitionsPreservingState("resources/config/quests.json", CONST_ZIP_FILE);
|
|
||||||
|
|
||||||
// Screens below the Language screen on the menu stack hold onto their old
|
// Screens below the Language screen on the menu stack hold onto their old
|
||||||
// (pre-reload) UiNode instances, so simply reopening Language on top of
|
// (pre-reload) UiNode instances, so simply reopening Language on top of
|
||||||
// them would leave Main Menu / Settings / the pause menu showing stale
|
// them would leave Main Menu / Settings / the pause menu showing stale
|
||||||
@ -525,6 +526,19 @@ namespace ZL {
|
|||||||
for (int i = 0; i < depth; ++i) uiManager.popMenu();
|
for (int i = 0; i < depth; ++i) uiManager.popMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unloading/reloading ~50 UI screens and their textures is heavy enough to
|
||||||
|
// freeze the window for a noticeable moment, so run it the same way the
|
||||||
|
// initial resource load runs: a queue of closures drained one per frame
|
||||||
|
// with the loading screen shown, instead of one big blocking call here.
|
||||||
|
std::vector<std::function<void()>> steps;
|
||||||
|
|
||||||
|
steps.push_back([this]() {
|
||||||
|
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
|
||||||
|
gameState_.questJournal.reloadDefinitionsPreservingState("resources/config/quests.json", CONST_ZIP_FILE);
|
||||||
|
});
|
||||||
|
|
||||||
|
steps.push_back([this]() {
|
||||||
|
renderer.textureManager.UnloadByPrefix("resources/w/ui");
|
||||||
loadUiRoots(CONST_ZIP_FILE);
|
loadUiRoots(CONST_ZIP_FILE);
|
||||||
|
|
||||||
toastTextureQuestNew = loadLocalizedTexture("resources/w/ui/img/toast/quest_new001.png", CONST_ZIP_FILE);
|
toastTextureQuestNew = loadLocalizedTexture("resources/w/ui/img/toast/quest_new001.png", CONST_ZIP_FILE);
|
||||||
@ -532,9 +546,17 @@ namespace ZL {
|
|||||||
toastTextureQuestFailed = loadLocalizedTexture("resources/w/ui/img/toast/quest_failed001.png", CONST_ZIP_FILE);
|
toastTextureQuestFailed = loadLocalizedTexture("resources/w/ui/img/toast/quest_failed001.png", CONST_ZIP_FILE);
|
||||||
toastTextureItemAdded = loadLocalizedTexture("resources/w/ui/img/toast/item_received001.png", CONST_ZIP_FILE);
|
toastTextureItemAdded = loadLocalizedTexture("resources/w/ui/img/toast/item_received001.png", CONST_ZIP_FILE);
|
||||||
toastTextureItemRemoved = loadLocalizedTexture("resources/w/ui/img/toast/item_removed001.png", CONST_ZIP_FILE);
|
toastTextureItemRemoved = loadLocalizedTexture("resources/w/ui/img/toast/item_removed001.png", CONST_ZIP_FILE);
|
||||||
|
});
|
||||||
|
|
||||||
|
steps.push_back([this]() {
|
||||||
showMainMenu();
|
showMainMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (runAsLoadingSequence) {
|
||||||
|
runAsLoadingSequence(std::move(steps));
|
||||||
|
} else {
|
||||||
|
for (auto& step : steps) step();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::showLoadGameScreen()
|
void MenuManager::showLoadGameScreen()
|
||||||
|
|||||||
@ -79,6 +79,13 @@ namespace ZL {
|
|||||||
std::function<void(int)> onLoadGame;
|
std::function<void(int)> onLoadGame;
|
||||||
std::function<SaveSlotInfo(int)> getSlotInfoFunc;
|
std::function<SaveSlotInfo(int)> getSlotInfoFunc;
|
||||||
|
|
||||||
|
// Set by Game: runs the given closures one per frame with the loading
|
||||||
|
// screen shown (same mechanism as the initial resource load), so a heavy
|
||||||
|
// operation like reloadLocalizedGameContent() doesn't block the window
|
||||||
|
// for its whole duration. Game re-enables normal rendering once all the
|
||||||
|
// closures have run.
|
||||||
|
std::function<void(std::vector<std::function<void()>>)> runAsLoadingSequence;
|
||||||
|
|
||||||
// Called when a chat message bubble should be shown (text + direction)
|
// Called when a chat message bubble should be shown (text + direction)
|
||||||
void onChatBubbleReady(const std::string& text, bool incoming);
|
void onChatBubbleReady(const std::string& text, bool incoming);
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "utils/Utils.h"
|
#include "utils/Utils.h"
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
#include "../Character.h"
|
#include "../Character.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -195,6 +196,9 @@ namespace ZL {
|
|||||||
std::unordered_map<std::string, LoadedGameObject> gameObjects;
|
std::unordered_map<std::string, LoadedGameObject> gameObjects;
|
||||||
|
|
||||||
for (const auto& data : loadFromJson(jsonPath, zipPath)) {
|
for (const auto& data : loadFromJson(jsonPath, zipPath)) {
|
||||||
|
// Service the OS message queue between loads so the window doesn't
|
||||||
|
// get flagged as "not responding" during long location loads.
|
||||||
|
SDL_PumpEvents();
|
||||||
std::cout << "Loading game object: " << data.name << std::endl;
|
std::cout << "Loading game object: " << data.name << std::endl;
|
||||||
try {
|
try {
|
||||||
LoadedGameObject obj = buildLoadedObject(data, renderer, zipPath);
|
LoadedGameObject obj = buildLoadedObject(data, renderer, zipPath);
|
||||||
@ -225,6 +229,7 @@ namespace ZL {
|
|||||||
return interactiveObjects;
|
return interactiveObjects;
|
||||||
|
|
||||||
for (const auto& data : loadInteractiveFromJson(jsonPath, zipPath)) {
|
for (const auto& data : loadInteractiveFromJson(jsonPath, zipPath)) {
|
||||||
|
SDL_PumpEvents();
|
||||||
std::cout << "Loading interactive object: " << data.base.name << std::endl;
|
std::cout << "Loading interactive object: " << data.base.name << std::endl;
|
||||||
try {
|
try {
|
||||||
InteractiveObject intObj = InteractiveObject::createFromState(
|
InteractiveObject intObj = InteractiveObject::createFromState(
|
||||||
@ -359,6 +364,7 @@ namespace ZL {
|
|||||||
std::vector<std::unique_ptr<Character>> npcs;
|
std::vector<std::unique_ptr<Character>> npcs;
|
||||||
|
|
||||||
for (const auto& npcData : loadNpcsFromJson(jsonPath, zipPath)) {
|
for (const auto& npcData : loadNpcsFromJson(jsonPath, zipPath)) {
|
||||||
|
SDL_PumpEvents();
|
||||||
std::cout << "Loading NPC: " << npcData.name << std::endl;
|
std::cout << "Loading NPC: " << npcData.name << std::endl;
|
||||||
try {
|
try {
|
||||||
auto npc = Character::createFromState(npcData.toCharacterState(), renderer, zipPath.c_str());
|
auto npc = Character::createFromState(npcData.toCharacterState(), renderer, zipPath.c_str());
|
||||||
|
|||||||
@ -528,8 +528,20 @@ namespace ZL
|
|||||||
|
|
||||||
void TextureManager::Unload(const std::string& fileName, const std::string& zipFile)
|
void TextureManager::Unload(const std::string& fileName, const std::string& zipFile)
|
||||||
{
|
{
|
||||||
//For now, we should keep all textures in memory, to make game load faster after restart
|
textureMap.erase(MakeKey(fileName, zipFile));
|
||||||
//textureMap.erase(MakeKey(fileName, zipFile));
|
}
|
||||||
|
|
||||||
|
void TextureManager::UnloadByPrefix(const std::string& prefix)
|
||||||
|
{
|
||||||
|
for (auto& it = textureMap.begin(); it != textureMap.end(); ) {
|
||||||
|
if (it->first.substr(0, prefix.size()) == prefix) {
|
||||||
|
std::cout << "Unloading texture with prefix: " << it->first << std::endl;
|
||||||
|
it = textureMap.erase(it);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureManager::UnloadAll()
|
void TextureManager::UnloadAll()
|
||||||
|
|||||||
@ -76,6 +76,7 @@ namespace ZL
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Unload(const std::string& fileName, const std::string& zipFile = "");
|
void Unload(const std::string& fileName, const std::string& zipFile = "");
|
||||||
|
void UnloadByPrefix(const std::string& prefix);
|
||||||
void UnloadAll();
|
void UnloadAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user