Fixing localization bugs, working with graphics settings
This commit is contained in:
parent
d4365728fe
commit
9d03b52c2a
@ -2254,6 +2254,11 @@
|
|||||||
"key": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.",
|
"key": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.",
|
||||||
"ru": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.",
|
"ru": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.",
|
||||||
"en": "I apologize, Aida Dzhanybekovna, I really tried, but I encountered force majeure circumstances."
|
"en": "I apologize, Aida Dzhanybekovna, I really tried, but I encountered force majeure circumstances."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Бекзат, я сейчас занята, не мешай мне!",
|
||||||
|
"ru": "Бекзат, я сейчас занята, не мешай мне!",
|
||||||
|
"en": "Bekzat, I'm busy now, don't disturb me!"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -105,11 +105,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "fullScreenToggleButton",
|
"name": "graphicsButton",
|
||||||
"width": 500,
|
"width": 500,
|
||||||
"height": 60,
|
"height": 60,
|
||||||
"text": "Полноэкранный режим: ВЫКЛ",
|
"text": "Настройки графики",
|
||||||
"fontSize": 32,
|
"fontSize": 40,
|
||||||
"textCentered": true,
|
"textCentered": true,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
}
|
}
|
||||||
|
|||||||
72
resources/w/ui/screen_settings_graphics.json
Normal file
72
resources/w/ui/screen_settings_graphics.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "FrameLayout",
|
||||||
|
"width": "match_parent",
|
||||||
|
"height": "match_parent",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "settingsBkg",
|
||||||
|
"width": 2992,
|
||||||
|
"height": 1632,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/MenuBkg001_v001.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"horizontal_align": "left",
|
||||||
|
"width": 500,
|
||||||
|
"height": 600,
|
||||||
|
"spacing": 20,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "settingsTitleText",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Настройки графики",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "fullScreenToggleButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Полноэкранный режим: ВЫКЛ",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "shadowToggleButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Тени: ВЫКЛ",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "settingsBackButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"y": 40,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Назад",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -105,11 +105,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "fullScreenToggleButton",
|
"name": "graphicsButton",
|
||||||
"width": 500,
|
"width": 500,
|
||||||
"height": 60,
|
"height": 60,
|
||||||
"text": "",
|
"text": "Graphics settings",
|
||||||
"fontSize": 32,
|
"fontSize": 40,
|
||||||
"textCentered": true,
|
"textCentered": true,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
}
|
}
|
||||||
|
|||||||
72
resources/w/ui_en/screen_settings_graphics.json
Normal file
72
resources/w/ui_en/screen_settings_graphics.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "FrameLayout",
|
||||||
|
"width": "match_parent",
|
||||||
|
"height": "match_parent",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "settingsBkg",
|
||||||
|
"width": 2992,
|
||||||
|
"height": 1632,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/MenuBkg001_v001.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"horizontal_align": "left",
|
||||||
|
"width": 500,
|
||||||
|
"height": 600,
|
||||||
|
"spacing": 20,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "settingsTitleText",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Graphics settings",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "fullScreenToggleButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "shadowToggleButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "settingsBackButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"y": 40,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Back",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,6 +31,9 @@ bool Environment::isFullscreen = false;
|
|||||||
bool Environment::isFullscreen = true;
|
bool Environment::isFullscreen = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool Environment::isHighDPIEnabled = false;
|
||||||
|
int Environment::customDpiScale = 1;
|
||||||
|
|
||||||
bool Environment::showMouse = false;
|
bool Environment::showMouse = false;
|
||||||
|
|
||||||
bool Environment::exitGameLoop = false;
|
bool Environment::exitGameLoop = false;
|
||||||
|
|||||||
@ -33,6 +33,9 @@ public:
|
|||||||
static bool isFullscreen;
|
static bool isFullscreen;
|
||||||
static void setFullscreen(bool enable);
|
static void setFullscreen(bool enable);
|
||||||
|
|
||||||
|
static bool isHighDPIEnabled;
|
||||||
|
static int customDpiScale;
|
||||||
|
|
||||||
static bool showMouse;
|
static bool showMouse;
|
||||||
static bool exitGameLoop;
|
static bool exitGameLoop;
|
||||||
|
|
||||||
|
|||||||
66
src/Game.cpp
66
src/Game.cpp
@ -292,6 +292,19 @@ 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); };
|
||||||
|
|
||||||
|
menuManager.shadowMapSettingsChangedFunc = [this](bool newValue) {
|
||||||
|
if (newValue)
|
||||||
|
{
|
||||||
|
createShadowMapAndProparateToLocations();
|
||||||
|
menuManager.shadowsEnabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destroyShadowMapAndProparateToLocations();
|
||||||
|
menuManager.shadowsEnabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Lets MenuManager run a heavy operation (e.g. reloadLocalizedGameContent())
|
// Lets MenuManager run a heavy operation (e.g. reloadLocalizedGameContent())
|
||||||
// as a chunked sequence instead of one blocking call: the closures are
|
// as a chunked sequence instead of one blocking call: the closures are
|
||||||
// drained one per frame by update(), with the loading screen shown for
|
// drained one per frame by update(), with the loading screen shown for
|
||||||
@ -322,6 +335,14 @@ namespace ZL
|
|||||||
audioPlayer->crossFadeMusicAsync("audio/main menu final.ogg");
|
audioPlayer->crossFadeMusicAsync("audio/main menu final.ogg");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*loadSteps.push([this]() {
|
||||||
|
if (menshadowsEnabled)
|
||||||
|
{
|
||||||
|
createShadowMapAndProparateToLocations();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
loadSteps.push([this]() {
|
loadSteps.push([this]() {
|
||||||
loadingCompleted = true;
|
loadingCompleted = true;
|
||||||
});
|
});
|
||||||
@ -730,6 +751,30 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::createShadowMapAndProparateToLocations()
|
||||||
|
{
|
||||||
|
if (shadowMap) {
|
||||||
|
std::cout << "Shadow map already exists, skipping creation" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shadowMap = std::make_shared<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||||
|
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||||
|
std::cout << "Shadow map initialized" << std::endl;
|
||||||
|
|
||||||
|
for (auto& [name, loc] : gameState.locations) {
|
||||||
|
loc->shadowMap = shadowMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void Game::destroyShadowMapAndProparateToLocations()
|
||||||
|
{
|
||||||
|
shadowMap.reset();
|
||||||
|
for (auto& [name, loc] : gameState.locations) {
|
||||||
|
loc->shadowMap.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Game::drawUI()
|
void Game::drawUI()
|
||||||
{
|
{
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
@ -991,19 +1036,32 @@ namespace ZL
|
|||||||
|
|
||||||
|
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
// Обновляем размеры и сбрасываем кеш текстов, т.к. меши хранятся в пикселях
|
|
||||||
const bool wasPortrait = Environment::width < Environment::height;
|
const bool wasPortrait = Environment::width < Environment::height;
|
||||||
Environment::width = event.window.data1;
|
|
||||||
Environment::height = event.window.data2;
|
if (Environment::isHighDPIEnabled) {
|
||||||
|
// Если High DPI включен, запрашиваем реальное физическое разрешение буфера
|
||||||
|
int drawW, drawH;
|
||||||
|
SDL_GL_GetDrawableSize(Environment::window, &drawW, &drawH);
|
||||||
|
Environment::width = drawW;
|
||||||
|
Environment::height = drawH;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Если High DPI выключен, используем логические размеры из события
|
||||||
|
Environment::width = event.window.data1 / ZL::Environment::customDpiScale;
|
||||||
|
Environment::height = event.window.data2 / ZL::Environment::customDpiScale;
|
||||||
|
}
|
||||||
|
|
||||||
Environment::computeProjectionDimensions();
|
Environment::computeProjectionDimensions();
|
||||||
|
|
||||||
const bool isPortrait = Environment::width < Environment::height;
|
const bool isPortrait = Environment::width < Environment::height;
|
||||||
menuManager.uiManager.updateAllLayouts();
|
menuManager.uiManager.updateAllLayouts();
|
||||||
menuManager.topUiManager.updateAllLayouts();
|
menuManager.topUiManager.updateAllLayouts();
|
||||||
|
|
||||||
if (wasPortrait != isPortrait) {
|
if (wasPortrait != isPortrait) {
|
||||||
menuManager.onOrientationChanged();
|
menuManager.onOrientationChanged();
|
||||||
}
|
}
|
||||||
std::cout << "Window resized: " << Environment::width << "x" << Environment::height << std::endl;
|
|
||||||
|
|
||||||
|
std::cout << "Window resized (Render Size): " << Environment::width << "x" << Environment::height << std::endl;
|
||||||
//space.clearTextRendererCache();
|
//space.clearTextRendererCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,8 @@ namespace ZL {
|
|||||||
VertexRenderStruct loadingMesh;
|
VertexRenderStruct loadingMesh;
|
||||||
bool loadingCompleted = false;
|
bool loadingCompleted = false;
|
||||||
|
|
||||||
|
std::shared_ptr<ShadowMap> shadowMap;
|
||||||
|
|
||||||
// setupPart2() populates this queue with one closure per loading step instead of
|
// 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
|
// 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
|
// keeps pumping events / repainting (and, on Emscripten, the browser keeps the tab
|
||||||
@ -117,6 +119,8 @@ namespace ZL {
|
|||||||
void loadGame(int slot);
|
void loadGame(int slot);
|
||||||
SaveSlotInfo readSlotInfo(int slot) const;
|
SaveSlotInfo readSlotInfo(int slot) const;
|
||||||
void createLocations();
|
void createLocations();
|
||||||
|
void createShadowMapAndProparateToLocations();
|
||||||
|
void destroyShadowMapAndProparateToLocations();
|
||||||
|
|
||||||
// Reset entry point used by "Start New Game": loads resources/config/start_state.json
|
// Reset entry point used by "Start New Game": loads resources/config/start_state.json
|
||||||
// into the existing Location objects if present, else falls back to performFullReset().
|
// into the existing Location objects if present, else falls back to performFullReset().
|
||||||
|
|||||||
@ -168,13 +168,6 @@ namespace ZL
|
|||||||
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
|
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
|
||||||
loadPointLights(params.lightsJsonPath, CONST_ZIP_FILE);
|
loadPointLights(params.lightsJsonPath, CONST_ZIP_FILE);
|
||||||
|
|
||||||
//#ifndef EMSCRIPTEN
|
|
||||||
// Create shadow map (2048x2048, ortho size 40, near 0.1, far 100)
|
|
||||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
|
||||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
|
||||||
std::cout << "Shadow map initialized" << std::endl;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
setupNavigation(params.navigationJsonPaths);
|
setupNavigation(params.navigationJsonPaths);
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
|
|
||||||
|
|||||||
@ -79,7 +79,7 @@ namespace ZL
|
|||||||
std::vector<PathFinder> navigationMaps;
|
std::vector<PathFinder> navigationMaps;
|
||||||
PathFinder* navigation = nullptr;
|
PathFinder* navigation = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<ShadowMap> shadowMap;
|
std::shared_ptr<ShadowMap> shadowMap;
|
||||||
Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity();
|
Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity();
|
||||||
|
|
||||||
std::unique_ptr<TextRenderer> npcNameText;
|
std::unique_ptr<TextRenderer> npcNameText;
|
||||||
|
|||||||
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
static const std::string EMPTY_LANGUAGE_RU = "(пусто)";
|
// Localization
|
||||||
|
static const std::string EMPTY_LANGUAGE_RU = u8"(пусто)";
|
||||||
static const std::string EMPTY_LANGUAGE_EN = "(empty)";
|
static const std::string EMPTY_LANGUAGE_EN = "(empty)";
|
||||||
|
|
||||||
|
|
||||||
@ -91,12 +92,12 @@ namespace ZL {
|
|||||||
if (negative) result = "-" + result;
|
if (negative) result = "-" + result;
|
||||||
|
|
||||||
|
|
||||||
|
//Localization
|
||||||
if (g_currentLanguage == Language::English)
|
if (g_currentLanguage == Language::English)
|
||||||
{
|
{
|
||||||
return result + " som";
|
return result + " som";
|
||||||
}
|
}
|
||||||
return result + " сом";
|
return result + u8" сом";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::array<float, 4> questStatusColor(Quest::QuestStatus status) {
|
static std::array<float, 4> questStatusColor(Quest::QuestStatus status) {
|
||||||
@ -113,13 +114,14 @@ namespace ZL {
|
|||||||
gameState_(gameState),
|
gameState_(gameState),
|
||||||
audioPlayer_(audioPlayer)
|
audioPlayer_(audioPlayer)
|
||||||
{
|
{
|
||||||
localizedLocationName["uni_interior"][Language::Russian] = "Университет, 3 этаж";
|
//Localization
|
||||||
|
localizedLocationName["uni_interior"][Language::Russian] = u8"Университет, 3 этаж";
|
||||||
localizedLocationName["uni_interior"][Language::English] = "University, 3rd floor";
|
localizedLocationName["uni_interior"][Language::English] = "University, 3rd floor";
|
||||||
|
|
||||||
localizedLocationName["uni_exterior"][Language::Russian] = "Университет, двор";
|
localizedLocationName["uni_exterior"][Language::Russian] = u8"Университет, двор";
|
||||||
localizedLocationName["uni_exterior"][Language::English] = "University, exterior";
|
localizedLocationName["uni_exterior"][Language::English] = "University, exterior";
|
||||||
|
|
||||||
localizedLocationName["location_dorm"][Language::Russian] = "Общежитие, 1 этаж";
|
localizedLocationName["location_dorm"][Language::Russian] = u8"Общежитие, 1 этаж";
|
||||||
localizedLocationName["location_dorm"][Language::English] = "Dormitory, 1st floor";
|
localizedLocationName["location_dorm"][Language::English] = "Dormitory, 1st floor";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +216,7 @@ namespace ZL {
|
|||||||
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile);
|
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile);
|
||||||
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.json", zipFile);
|
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.json", zipFile);
|
||||||
settingsScreenRoot = loadLocalizedUi("resources/w/ui/screen_settings.json", zipFile);
|
settingsScreenRoot = loadLocalizedUi("resources/w/ui/screen_settings.json", zipFile);
|
||||||
|
settingsGraphicsScreenRoot = loadLocalizedUi("resources/w/ui/screen_settings_graphics.json", zipFile);
|
||||||
languageScreenRoot = loadLocalizedUi("resources/w/ui/screen_language.json", zipFile);
|
languageScreenRoot = loadLocalizedUi("resources/w/ui/screen_language.json", zipFile);
|
||||||
loadSavedGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_load.json", zipFile);
|
loadSavedGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_load.json", zipFile);
|
||||||
saveGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_save.json", zipFile);
|
saveGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_save.json", zipFile);
|
||||||
@ -393,6 +396,11 @@ namespace ZL {
|
|||||||
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
uiManager.setTextButtonCallback("graphicsButton", [this](const std::string&) {
|
||||||
|
showSettingsGraphicsScreen();
|
||||||
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
});
|
||||||
|
|
||||||
// Set initial slider positions before registering callbacks so
|
// Set initial slider positions before registering callbacks so
|
||||||
// setSliderValue does not fire an unregistered callback.
|
// setSliderValue does not fire an unregistered callback.
|
||||||
const float musicFrac = audioPlayer_.getMusicVolume() / 128.0f;
|
const float musicFrac = audioPlayer_.getMusicVolume() / 128.0f;
|
||||||
@ -400,6 +408,7 @@ namespace ZL {
|
|||||||
uiManager.setSliderValue("musicVolumeSlider", musicFrac);
|
uiManager.setSliderValue("musicVolumeSlider", musicFrac);
|
||||||
uiManager.setSliderValue("soundVolumeSlider", soundFrac);
|
uiManager.setSliderValue("soundVolumeSlider", soundFrac);
|
||||||
|
|
||||||
|
// Localization
|
||||||
if (g_currentLanguage == Language::English)
|
if (g_currentLanguage == Language::English)
|
||||||
{
|
{
|
||||||
musicVolumePrefix = "Music volume: ";
|
musicVolumePrefix = "Music volume: ";
|
||||||
@ -408,19 +417,15 @@ namespace ZL {
|
|||||||
musicToggleOff = "Music: OFF";
|
musicToggleOff = "Music: OFF";
|
||||||
soundToggleOn = "Sound: ON";
|
soundToggleOn = "Sound: ON";
|
||||||
soundToggleOff = "Sound: OFF";
|
soundToggleOff = "Sound: OFF";
|
||||||
fullScreenToggleOn = "Full Screen: ON";
|
|
||||||
fullScreenToggleOff = "Full Screen: OFF";
|
|
||||||
}
|
}
|
||||||
else if (g_currentLanguage == Language::Russian)
|
else if (g_currentLanguage == Language::Russian)
|
||||||
{
|
{
|
||||||
musicVolumePrefix = "Громкость музыки: ";
|
musicVolumePrefix = u8"Громкость музыки: ";
|
||||||
soundVolumePrefix = "Громкость звука: ";
|
soundVolumePrefix = u8"Громкость звука: ";
|
||||||
musicToggleOn = "Музыка: ВКЛ";
|
musicToggleOn = u8"Музыка: ВКЛ";
|
||||||
musicToggleOff = "Музыка: ВЫКЛ";
|
musicToggleOff = u8"Музыка: ВЫКЛ";
|
||||||
soundToggleOn = "Звук: ВКЛ";
|
soundToggleOn = u8"Звук: ВКЛ";
|
||||||
soundToggleOff = "Звук: ВЫКЛ";
|
soundToggleOff = u8"Звук: ВЫКЛ";
|
||||||
fullScreenToggleOn = "Полноэкранный режим: ВКЛ";
|
|
||||||
fullScreenToggleOff = "Полноэкранный режим: ВЫКЛ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uiManager.setText("musicVolumeText",
|
uiManager.setText("musicVolumeText",
|
||||||
@ -458,17 +463,9 @@ namespace ZL {
|
|||||||
? std::array<float, 4>{ 0.2f, 0.9f, 0.2f, 1.0f }
|
? std::array<float, 4>{ 0.2f, 0.9f, 0.2f, 1.0f }
|
||||||
: std::array<float, 4>{ 0.9f, 0.2f, 0.2f, 1.0f });*/
|
: std::array<float, 4>{ 0.9f, 0.2f, 0.2f, 1.0f });*/
|
||||||
};
|
};
|
||||||
auto refreshFullscreenToggle = [this]() {
|
|
||||||
const bool on = Environment::isFullscreen;
|
|
||||||
uiManager.setTextButtonText("fullScreenToggleButton", on ? fullScreenToggleOn : fullScreenToggleOff);
|
|
||||||
/*uiManager.setTextButtonColor("fullScreenToggleButton", on
|
|
||||||
? std::array<float, 4>{ 0.2f, 0.9f, 0.2f, 1.0f }
|
|
||||||
: std::array<float, 4>{ 0.9f, 0.2f, 0.2f, 1.0f });*/
|
|
||||||
};
|
|
||||||
|
|
||||||
refreshMusicToggle();
|
refreshMusicToggle();
|
||||||
refreshSoundToggle();
|
refreshSoundToggle();
|
||||||
refreshFullscreenToggle();
|
|
||||||
|
|
||||||
uiManager.setTextButtonCallback("musicToggleButton", [this](const std::string&) {
|
uiManager.setTextButtonCallback("musicToggleButton", [this](const std::string&) {
|
||||||
audioPlayer_.setMusicEnabled(!audioPlayer_.isMusicEnabled());
|
audioPlayer_.setMusicEnabled(!audioPlayer_.isMusicEnabled());
|
||||||
@ -488,11 +485,59 @@ namespace ZL {
|
|||||||
: std::array<float, 4>{ 0.9f, 0.2f, 0.2f, 1.0f });*/
|
: std::array<float, 4>{ 0.9f, 0.2f, 0.2f, 1.0f });*/
|
||||||
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManager::showSettingsGraphicsScreen() {
|
||||||
|
uiManager.pushMenuFromSavedRoot(settingsGraphicsScreenRoot);
|
||||||
|
uiManager.setTextButtonCallback("settingsBackButton", [this](const std::string&) {
|
||||||
|
//saveSettings();
|
||||||
|
uiManager.popMenu();
|
||||||
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Localization
|
||||||
|
if (g_currentLanguage == Language::English)
|
||||||
|
{
|
||||||
|
fullScreenToggleOn = "Full Screen: ON";
|
||||||
|
fullScreenToggleOff = "Full Screen: OFF";
|
||||||
|
shadowToggleOn = "Shadows: ON";
|
||||||
|
shadowToggleOff = "Shadows: OFF";
|
||||||
|
}
|
||||||
|
else if (g_currentLanguage == Language::Russian)
|
||||||
|
{
|
||||||
|
fullScreenToggleOn = u8"Полноэкранный режим: ВКЛ";
|
||||||
|
fullScreenToggleOff = u8"Полноэкранный режим: ВЫКЛ";
|
||||||
|
shadowToggleOn = u8"Тени: ВКЛ";
|
||||||
|
shadowToggleOff = u8"Тени: ВЫКЛ";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto refreshFullscreenToggle = [this]() {
|
||||||
|
const bool on = Environment::isFullscreen;
|
||||||
|
uiManager.setTextButtonText("fullScreenToggleButton", on ? fullScreenToggleOn : fullScreenToggleOff);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto refreshShadowToggle = [this]() {
|
||||||
|
const bool on = this->shadowsEnabled;
|
||||||
|
uiManager.setTextButtonText("shadowToggleButton", on ? shadowToggleOn : shadowToggleOff);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
refreshFullscreenToggle();
|
||||||
|
refreshShadowToggle();
|
||||||
|
|
||||||
uiManager.setTextButtonCallback("fullScreenToggleButton", [this, refreshFullscreenToggle](const std::string&) {
|
uiManager.setTextButtonCallback("fullScreenToggleButton", [this, refreshFullscreenToggle](const std::string&) {
|
||||||
Environment::setFullscreen(!Environment::isFullscreen);
|
Environment::setFullscreen(!Environment::isFullscreen);
|
||||||
refreshFullscreenToggle();
|
refreshFullscreenToggle();
|
||||||
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
uiManager.setTextButtonCallback("shadowToggleButton", [this, refreshShadowToggle](const std::string&) {
|
||||||
|
bool newValue = !this->shadowsEnabled;
|
||||||
|
shadowMapSettingsChangedFunc(newValue);
|
||||||
|
refreshShadowToggle();
|
||||||
|
audioPlayer_.playSoundAsync("audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::showLanguageScreen() {
|
void MenuManager::showLanguageScreen() {
|
||||||
@ -2099,6 +2144,7 @@ namespace ZL {
|
|||||||
root["soundEnabled"] = audioPlayer_.isSoundEnabled();
|
root["soundEnabled"] = audioPlayer_.isSoundEnabled();
|
||||||
root["fullscreen"] = Environment::isFullscreen;
|
root["fullscreen"] = Environment::isFullscreen;
|
||||||
root["language"] = ZL::languageToCode(ZL::g_currentLanguage);
|
root["language"] = ZL::languageToCode(ZL::g_currentLanguage);
|
||||||
|
root["shadow"] = shadowsEnabled;
|
||||||
|
|
||||||
saveJsonToFile(root, "settings.json");
|
saveJsonToFile(root, "settings.json");
|
||||||
}
|
}
|
||||||
@ -2130,6 +2176,19 @@ namespace ZL {
|
|||||||
Environment::setFullscreen(root["fullscreen"].get<bool>());
|
Environment::setFullscreen(root["fullscreen"].get<bool>());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (root.contains("shadow")) {
|
||||||
|
if (shadowMapSettingsChangedFunc)
|
||||||
|
{
|
||||||
|
shadowMapSettingsChangedFunc(root["shadow"].get<bool>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (shadowMapSettingsChangedFunc)
|
||||||
|
{
|
||||||
|
shadowMapSettingsChangedFunc(shadowsEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,6 +78,8 @@ namespace ZL {
|
|||||||
std::function<void(int)> onSaveGame;
|
std::function<void(int)> onSaveGame;
|
||||||
std::function<void(int)> onLoadGame;
|
std::function<void(int)> onLoadGame;
|
||||||
std::function<SaveSlotInfo(int)> getSlotInfoFunc;
|
std::function<SaveSlotInfo(int)> getSlotInfoFunc;
|
||||||
|
std::function<void(bool)> shadowMapSettingsChangedFunc;
|
||||||
|
|
||||||
|
|
||||||
// Set by Game: runs the given closures one per frame with the loading
|
// 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
|
// screen shown (same mechanism as the initial resource load), so a heavy
|
||||||
@ -126,6 +128,9 @@ namespace ZL {
|
|||||||
std::shared_ptr<Texture> languageLoadingRu;
|
std::shared_ptr<Texture> languageLoadingRu;
|
||||||
std::shared_ptr<Texture> languageLoadingEn;
|
std::shared_ptr<Texture> languageLoadingEn;
|
||||||
|
|
||||||
|
bool shadowsEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Renderer& renderer;
|
Renderer& renderer;
|
||||||
|
|
||||||
@ -168,6 +173,7 @@ namespace ZL {
|
|||||||
|
|
||||||
void showAboutScreen();
|
void showAboutScreen();
|
||||||
void showSettingsScreen();
|
void showSettingsScreen();
|
||||||
|
void showSettingsGraphicsScreen();
|
||||||
void showLanguageScreen();
|
void showLanguageScreen();
|
||||||
void showLoadGameScreen();
|
void showLoadGameScreen();
|
||||||
void showSaveGameScreen();
|
void showSaveGameScreen();
|
||||||
@ -257,6 +263,7 @@ namespace ZL {
|
|||||||
std::shared_ptr<UiNode> mainMenuRoot;
|
std::shared_ptr<UiNode> mainMenuRoot;
|
||||||
std::shared_ptr<UiNode> aboutScreenRoot;
|
std::shared_ptr<UiNode> aboutScreenRoot;
|
||||||
std::shared_ptr<UiNode> settingsScreenRoot;
|
std::shared_ptr<UiNode> settingsScreenRoot;
|
||||||
|
std::shared_ptr<UiNode> settingsGraphicsScreenRoot;
|
||||||
std::shared_ptr<UiNode> languageScreenRoot;
|
std::shared_ptr<UiNode> languageScreenRoot;
|
||||||
std::shared_ptr<UiNode> loadSavedGameScreenRoot;
|
std::shared_ptr<UiNode> loadSavedGameScreenRoot;
|
||||||
std::shared_ptr<UiNode> saveGameScreenRoot;
|
std::shared_ptr<UiNode> saveGameScreenRoot;
|
||||||
@ -328,6 +335,8 @@ namespace ZL {
|
|||||||
std::string soundToggleOff;
|
std::string soundToggleOff;
|
||||||
std::string fullScreenToggleOn;
|
std::string fullScreenToggleOn;
|
||||||
std::string fullScreenToggleOff;
|
std::string fullScreenToggleOff;
|
||||||
|
std::string shadowToggleOn;
|
||||||
|
std::string shadowToggleOff;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
34
src/main.cpp
34
src/main.cpp
@ -235,6 +235,8 @@ int main(int argc, char *argv[]) {
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
|
||||||
|
//SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1");
|
||||||
|
|
||||||
constexpr int CONST_WIDTH = ZL::Environment::CONST_DEFAULT_WIDTH;
|
constexpr int CONST_WIDTH = ZL::Environment::CONST_DEFAULT_WIDTH;
|
||||||
constexpr int CONST_HEIGHT = ZL::Environment::CONST_DEFAULT_HEIGHT;
|
constexpr int CONST_HEIGHT = ZL::Environment::CONST_DEFAULT_HEIGHT;
|
||||||
@ -261,6 +263,9 @@ int main(int argc, char *argv[]) {
|
|||||||
if (settingsRoot.contains("fullscreen")) {
|
if (settingsRoot.contains("fullscreen")) {
|
||||||
ZL::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
|
ZL::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
|
||||||
}
|
}
|
||||||
|
if (settingsRoot.contains("isHighDPIEnabled")) {
|
||||||
|
ZL::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get<bool>();
|
||||||
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
@ -272,10 +277,27 @@ int main(int argc, char *argv[]) {
|
|||||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_DisplayMode dm;
|
||||||
|
if (SDL_GetCurrentDisplayMode(0, &dm) == 0) {
|
||||||
|
std::cout << "Desktop resolution: " << dm.w << "x" << dm.h << " @ " << dm.refresh_rate << "Hz\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Log("SDL_GetCurrentDisplayMode failed: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
int windowWidth = ZL::Environment::width;
|
||||||
|
int windowHeight = ZL::Environment::height;
|
||||||
|
|
||||||
|
//In case if the game is launched on a small screen
|
||||||
|
if (dm.w <= 1280 && dm.h <= 720) {
|
||||||
|
windowWidth = round(dm.w / 1.5);
|
||||||
|
windowHeight = round(dm.h / 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
ZL::Environment::window = SDL_CreateWindow(
|
ZL::Environment::window = SDL_CreateWindow(
|
||||||
"Shadow Over Bishkek",
|
"Shadow Over Bishkek",
|
||||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
ZL::Environment::width, ZL::Environment::height,
|
windowWidth, windowHeight,
|
||||||
windowFlags
|
windowFlags
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -285,11 +307,21 @@ int main(int argc, char *argv[]) {
|
|||||||
// On HiDPI displays the drawable (physical) size is larger than the
|
// On HiDPI displays the drawable (physical) size is larger than the
|
||||||
// logical window size. Use the drawable size so the GL framebuffer
|
// logical window size. Use the drawable size so the GL framebuffer
|
||||||
// covers every physical pixel and the image stays sharp.
|
// covers every physical pixel and the image stays sharp.
|
||||||
|
if (ZL::Environment::isHighDPIEnabled)
|
||||||
{
|
{
|
||||||
int drawW, drawH;
|
int drawW, drawH;
|
||||||
SDL_GL_GetDrawableSize(ZL::Environment::window, &drawW, &drawH);
|
SDL_GL_GetDrawableSize(ZL::Environment::window, &drawW, &drawH);
|
||||||
ZL::Environment::width = drawW;
|
ZL::Environment::width = drawW;
|
||||||
ZL::Environment::height = drawH;
|
ZL::Environment::height = drawH;
|
||||||
|
std::cout << "HiDPI enabled, drawable size: " << drawW << "x" << drawH << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int winW, winH;
|
||||||
|
SDL_GetWindowSize(ZL::Environment::window, &winW, &winH);
|
||||||
|
ZL::Environment::width = winW;
|
||||||
|
ZL::Environment::height = winH;
|
||||||
|
std::cout << "HiDPI disabled, window size: " << winW << "x" << winH << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.setup();
|
game.setup();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user