Fixing UI bugs, updating web UI

This commit is contained in:
Vladislav Khorev committed 2026-06-12 20:18:43 +03:00
1 parent dee9615483
commit 7031a21922
28 files changed
+216 -48

No files matched your search

+2
View File
@@ -185,6 +185,8 @@ set(EMSCRIPTEN_LINK_FLAGS
"-sALLOW_MEMORY_GROWTH=1" "-sALLOW_MEMORY_GROWTH=1"
"-sFULL_ES3=1" "-sFULL_ES3=1"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loading.png@resources/loading.png" "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loading.png@resources/loading.png"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loadingProgressBar.png@resources/loadingProgressBar.png"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loadingProgressBarFrame.png@resources/loadingProgressBarFrame.png"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders" "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_interior.lua@resources/start_uni_interior.lua" "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_interior.lua@resources/start_uni_interior.lua"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_exterior.lua@resources/start_uni_exterior.lua" "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_exterior.lua@resources/start_uni_exterior.lua"
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -26,6 +26,7 @@ function on_container_clicked()
game_api.start_dialogue("dialog_contaier003") game_api.start_dialogue("dialog_contaier003")
elseif player_container_aware == 1 then elseif player_container_aware == 1 then
game_api.start_dialogue("dialog_contaier002") game_api.start_dialogue("dialog_contaier002")
game_api.setIntValue("player_has_coursework", 1)
else else
game_api.start_dialogue("dialog_contaier001") game_api.start_dialogue("dialog_contaier001")
end end
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7 -6
View File
@@ -4,7 +4,7 @@
"name": "hud_root", "name": "hud_root",
"width": "match_parent", "width": "match_parent",
"height": "match_parent", "height": "match_parent",
"vertical_align": "center", "vertical_align": "top",
"horizontal_align": "center", "horizontal_align": "center",
"children": [ "children": [
{ {
@@ -12,19 +12,20 @@
"name": "background", "name": "background",
"width": 1266, "width": 1266,
"height": 585, "height": 585,
"y": 68,
"horizontal_gravity": "center", "horizontal_gravity": "center",
"vertical_gravity": "center", "vertical_gravity": "top",
"texture": "resources/w/ui/img/journal/QuestJournal003.png" "texture": "resources/w/ui/img/journal/QuestJournal003.png"
}, },
{ {
"type": "Button", "type": "Button",
"name": "journalExitButton", "name": "journalExitButton",
"horizontal_gravity": "top", "horizontal_gravity": "center",
"vertical_gravity": "center", "vertical_gravity": "top",
"width": 90, "width": 90,
"height": 90, "height": 90,
"x": 1170, "x": 580,
"y": 240, "y": 70,
"textures": { "textures": {
"normal": "resources/w/ui/img/Close001_State=Default.png", "normal": "resources/w/ui/img/Close001_State=Default.png",
"hover": "resources/w/ui/img/Close001_State=Selected.png", "hover": "resources/w/ui/img/Close001_State=Selected.png",
+132 -3
View File
@@ -48,18 +48,24 @@ namespace ZL
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
Game* Game::s_instance = nullptr; Game* Game::s_instance = nullptr;
void Game::onResourcesZipLoaded(const char* /*filename*/) { void Game::onResourcesZipLoaded(unsigned /*handle*/, void* /*userData*/, const char* /*filename*/) {
std::cout << "Resources.zip loaded successfully" << std::endl; std::cout << "Resources.zip loaded successfully" << std::endl;
if (s_instance) { if (s_instance) {
s_instance->resourcesDownloadProgress = 1.0f;
s_instance->mainThreadHandler.EnqueueMainThreadTask([&]() { s_instance->mainThreadHandler.EnqueueMainThreadTask([&]() {
s_instance->setupPart2(); s_instance->setupPart2();
}); });
} }
} }
void Game::onResourcesZipError(const char* /*filename*/) { void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int /*httpStatus*/) {
std::cout << "Failed to download resources.zip" << std::endl; std::cout << "Failed to download resources.zip" << std::endl;
} }
void Game::onResourcesZipProgress(unsigned /*handle*/, void* /*userData*/, int percentComplete) {
if (s_instance)
s_instance->resourcesDownloadProgress = percentComplete / 100.0f;
}
#endif #endif
Game::Game() Game::Game()
@@ -98,6 +104,12 @@ namespace ZL
#endif #endif
loadingTexture = renderer.textureManager.LoadFromPng("resources/loading.png", ""); loadingTexture = renderer.textureManager.LoadFromPng("resources/loading.png", "");
#ifdef EMSCRIPTEN
loadingProgressBarFrameTexture = renderer.textureManager.LoadFromPng(
"resources/loadingProgressBarFrame.png", "", true);
loadingProgressBarTexture = renderer.textureManager.LoadFromPng(
"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;
@@ -119,7 +131,8 @@ namespace ZL
// The loading screen stays visible until the download finishes. // The loading screen stays visible until the download finishes.
s_instance = this; s_instance = this;
std::cout << "Load resurces step 1" << std::endl; std::cout << "Load resurces step 1" << std::endl;
emscripten_async_wget("resources.zip", "resources.zip", onResourcesZipLoaded, onResourcesZipError); emscripten_async_wget2("resources.zip", "resources.zip", "GET", nullptr, nullptr,
onResourcesZipLoaded, onResourcesZipError, onResourcesZipProgress);
#else #else
mainThreadHandler.EnqueueMainThreadTask([this]() { mainThreadHandler.EnqueueMainThreadTask([this]() {
std::cout << "Load resurces step 2" << std::endl; std::cout << "Load resurces step 2" << std::endl;
@@ -451,6 +464,9 @@ namespace ZL
renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/item_received001.png", CONST_ZIP_FILE, true); renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/item_received001.png", CONST_ZIP_FILE, true);
renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/item_removed001.png", CONST_ZIP_FILE, true); renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/item_removed001.png", CONST_ZIP_FILE, true);
mobileRotateTexture = renderer.textureManager.LoadFromPng(
"resources/rotateYourDevice.png", CONST_ZIP_FILE, true);
// Wire inventory callbacks: tutorial tracking + toast notifications. // Wire inventory callbacks: tutorial tracking + toast notifications.
@@ -608,6 +624,9 @@ namespace ZL
if (!loadingCompleted) { if (!loadingCompleted) {
drawLoading(); drawLoading();
} }
else if (Environment::width < Environment::height) {
drawMobilePortraitOverlay();
}
else else
{ {
if (currentLocation) if (currentLocation)
@@ -643,6 +662,37 @@ namespace ZL
CheckGlError(__FILE__, __LINE__); CheckGlError(__FILE__, __LINE__);
} }
void Game::drawMobilePortraitOverlay()
{
if (!mobileRotateTexture) return;
const float W = Environment::projectionWidth;
const float H = Environment::projectionHeight;
if (W != mobileRotateMeshLastW || H != mobileRotateMeshLastH) {
mobileRotateMeshLastW = W;
mobileRotateMeshLastH = H;
const float minDim = min(W, H);
mobileRotateMesh.data = CreateRect2D({ 0.f, 0.f }, { minDim * 0.5f, minDim * 0.5f }, 3.f);
mobileRotateMesh.RefreshVBO();
}
renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
renderer.RenderUniform1f("uAlpha", 1.0f);
renderer.PushProjectionMatrix(-W * 0.5f, W * 0.5f, -H * 0.5f, H * 0.5f, -10, 10);
renderer.PushMatrix();
renderer.LoadIdentity();
glBindTexture(GL_TEXTURE_2D, mobileRotateTexture->getTexID());
renderer.DrawVertexRenderStruct(mobileRotateMesh);
renderer.PopMatrix();
renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader();
CheckGlError(__FILE__, __LINE__);
}
void Game::drawLoading() void Game::drawLoading()
{ {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
@@ -669,6 +719,81 @@ namespace ZL
renderer.PopMatrix(); renderer.PopMatrix();
renderer.PopProjectionMatrix(); renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader(); renderer.shaderManager.PopShader();
#ifdef EMSCRIPTEN
if (loadingProgressBarFrameTexture && loadingProgressBarTexture) {
const float W = Environment::projectionWidth;
const float H = Environment::projectionHeight;
static constexpr float kBarW = 400.0f;
static constexpr float kBarH = 40.0f;
const float barCenterY = -(H * 0.4f - 60.0f);
const float barLeft = -kBarW * 0.5f;
const float barBottom = barCenterY - kBarH * 0.5f;
const float barTop = barCenterY + kBarH * 0.5f;
// Rebuild frame mesh when projection dimensions change
if (W != loadingBarLastW || H != loadingBarLastH) {
loadingBarLastW = W;
loadingBarLastH = H;
VertexDataStruct frameData;
frameData.PositionData = {
{barLeft, barBottom, 4.f}, {barLeft, barTop, 4.f}, {barLeft+kBarW, barTop, 4.f},
{barLeft+kBarW, barTop, 4.f}, {barLeft+kBarW, barBottom, 4.f}, {barLeft, barBottom, 4.f}
};
frameData.TexCoordData = {
{0.f,0.f},{0.f,1.f},{1.f,1.f},
{1.f,1.f},{1.f,0.f},{0.f,0.f}
};
loadingProgressBarFrameMesh.data = std::move(frameData);
loadingProgressBarFrameMesh.RefreshVBO();
loadingBarLastRenderedProgress = -1.0f; // force fill rebuild too
}
// Rebuild fill mesh when progress changes
const float p = std::min(resourcesDownloadProgress, 1.0f);
if (p != loadingBarLastRenderedProgress) {
loadingBarLastRenderedProgress = p;
if (p > 0.001f) {
const float fillRight = barLeft + kBarW * p;
VertexDataStruct fillData;
fillData.PositionData = {
{barLeft, barBottom, 4.f}, {barLeft, barTop, 4.f}, {fillRight, barTop, 4.f},
{fillRight, barTop, 4.f}, {fillRight, barBottom, 4.f}, {barLeft, barBottom, 4.f}
};
fillData.TexCoordData = {
{0.f,0.f},{0.f,1.f},{p,1.f},
{p,1.f},{p,0.f},{0.f,0.f}
};
loadingProgressBarFillMesh.data = std::move(fillData);
loadingProgressBarFillMesh.RefreshVBO();
}
}
renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
renderer.RenderUniform1f("uAlpha", 1.0f);
renderer.PushProjectionMatrix(-W*0.5f, W*0.5f, -H*0.5f, H*0.5f, -10, 10);
renderer.PushMatrix();
renderer.LoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, loadingProgressBarFrameTexture->getTexID());
renderer.DrawVertexRenderStruct(loadingProgressBarFrameMesh);
if (p > 0.001f) {
glBindTexture(GL_TEXTURE_2D, loadingProgressBarTexture->getTexID());
renderer.DrawVertexRenderStruct(loadingProgressBarFillMesh);
}
renderer.PopMatrix();
renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader();
}
#endif
CheckGlError(__FILE__, __LINE__); CheckGlError(__FILE__, __LINE__);
} }
@@ -729,6 +854,7 @@ namespace ZL
void Game::update() { void Game::update() {
SDL_Event event; SDL_Event event;
const bool mobileIsPortrait = loadingCompleted && (Environment::width < Environment::height);
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) { if (event.type == SDL_QUIT) {
Environment::exitGameLoop = true; Environment::exitGameLoop = true;
@@ -746,6 +872,9 @@ namespace ZL
//space.clearTextRendererCache(); //space.clearTextRendererCache();
} }
// Suppress all input while portrait overlay is shown
if (mobileIsPortrait) continue;
#ifdef __ANDROID__ #ifdef __ANDROID__
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) { if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
Environment::exitGameLoop = true; Environment::exitGameLoop = true;
+20 -2
View File
@@ -115,8 +115,18 @@ namespace ZL {
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
static Game* s_instance; static Game* s_instance;
static void onResourcesZipLoaded(const char* filename); static void onResourcesZipLoaded(unsigned handle, void* userData, const char* filename);
static void onResourcesZipError(const char* filename); static void onResourcesZipError(unsigned handle, void* userData, int httpStatus);
static void onResourcesZipProgress(unsigned handle, void* userData, int percentComplete);
float resourcesDownloadProgress = 0.0f;
std::shared_ptr<Texture> loadingProgressBarTexture;
std::shared_ptr<Texture> loadingProgressBarFrameTexture;
VertexRenderStruct loadingProgressBarFrameMesh;
VertexRenderStruct loadingProgressBarFillMesh;
float loadingBarLastRenderedProgress = -1.0f;
float loadingBarLastW = -1.0f;
float loadingBarLastH = -1.0f;
#endif #endif
// Screen-flash transition state (shared by darklands and night transitions) // Screen-flash transition state (shared by darklands and night transitions)
@@ -131,6 +141,14 @@ namespace ZL {
void updateDarklandsFlash(int64_t deltaMs); void updateDarklandsFlash(int64_t deltaMs);
void drawDarklandsFlash(); void drawDarklandsFlash();
// Portrait-mode overlay (mobile / portrait browsers)
std::shared_ptr<Texture> mobileRotateTexture;
VertexRenderStruct mobileRotateMesh;
float mobileRotateMeshLastW = -1.0f;
float mobileRotateMeshLastH = -1.0f;
void drawMobilePortraitOverlay();
int64_t newTickCount; int64_t newTickCount;
int64_t lastTickCount; int64_t lastTickCount;
+8
View File
@@ -218,6 +218,7 @@ namespace ZL {
uiManager.pushMenuFromSavedRoot(aboutScreenRoot); uiManager.pushMenuFromSavedRoot(aboutScreenRoot);
uiManager.setTextButtonCallback("aboutBackButton", [this](const std::string&) { uiManager.setTextButtonCallback("aboutBackButton", [this](const std::string&) {
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
}); });
} }
@@ -308,6 +309,7 @@ namespace ZL {
void MenuManager::closeInventory() { void MenuManager::closeInventory() {
state = GameState::Gameplay; state = GameState::Gameplay;
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
} }
void MenuManager::openQuestJournal() { void MenuManager::openQuestJournal() {
@@ -344,6 +346,7 @@ namespace ZL {
selectedQuestIndex = -1; selectedQuestIndex = -1;
visibleQuestIds.clear(); visibleQuestIds.clear();
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
} }
void MenuManager::toggleQuestJournal() { void MenuManager::toggleQuestJournal() {
@@ -480,6 +483,7 @@ namespace ZL {
}); });
uiManager.setButtonCallback("buttonBack", [this](const std::string&) { uiManager.setButtonCallback("buttonBack", [this](const std::string&) {
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
}); });
} }
@@ -491,6 +495,7 @@ namespace ZL {
}); });
uiManager.setButtonCallback("buttonBack", [this](const std::string&) { uiManager.setButtonCallback("buttonBack", [this](const std::string&) {
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
}); });
uiManager.setButtonCallback("videoSkip", [this](const std::string&) { uiManager.setButtonCallback("videoSkip", [this](const std::string&) {
closePhoneEntirely(); closePhoneEntirely();
@@ -533,6 +538,7 @@ namespace ZL {
}); });
uiManager.setButtonCallback("buttonBack", [this](const std::string&) { uiManager.setButtonCallback("buttonBack", [this](const std::string&) {
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
}); });
uiManager.setButtonCallback("mapGo", [this](const std::string&) { uiManager.setButtonCallback("mapGo", [this](const std::string&) {
tutorialNeedOpenTaxiScreen = false; tutorialNeedOpenTaxiScreen = false;
@@ -572,6 +578,7 @@ namespace ZL {
activeChatIndex_ = -1; activeChatIndex_ = -1;
phoneChatVisibleBubbles_.clear(); phoneChatVisibleBubbles_.clear();
uiManager.popMenu(); uiManager.popMenu();
uiManager.updateAllLayouts();
if (tutorialPhoneChatScreenOpened) if (tutorialPhoneChatScreenOpened)
{ {
uiManager.setNodeVisible("hint_m002", false); uiManager.setNodeVisible("hint_m002", false);
@@ -590,6 +597,7 @@ namespace ZL {
phoneChatVisibleBubbles_.clear(); phoneChatVisibleBubbles_.clear();
const int depth = uiManager.menuStackSize(); const int depth = uiManager.menuStackSize();
for (int i = 0; i < depth; ++i) uiManager.popMenu(); for (int i = 0; i < depth; ++i) uiManager.popMenu();
uiManager.updateAllLayouts();
if (tutorialNeedOpenTaxiScreen) if (tutorialNeedOpenTaxiScreen)
{ {