diff --git a/resources/dialogue/translate_dialogues.json b/resources/dialogue/translate_dialogues.json index 3b939a4..6a381bc 100644 --- a/resources/dialogue/translate_dialogues.json +++ b/resources/dialogue/translate_dialogues.json @@ -2254,6 +2254,11 @@ "key": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.", "ru": "Прошу прощения Аида Дженибековна, я правда старался, но у меня возникли обстоятельства непреодолимой силы.", "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!" } ] } \ No newline at end of file diff --git a/resources/w/ui/screen_settings.json b/resources/w/ui/screen_settings.json index 3441bc2..596eb7a 100644 --- a/resources/w/ui/screen_settings.json +++ b/resources/w/ui/screen_settings.json @@ -105,11 +105,11 @@ }, { "type": "TextButton", - "name": "fullScreenToggleButton", + "name": "graphicsButton", "width": 500, "height": 60, - "text": "Полноэкранный режим: ВЫКЛ", - "fontSize": 32, + "text": "Настройки графики", + "fontSize": 40, "textCentered": true, "color": [1.0, 1.0, 1.0, 1.0] } diff --git a/resources/w/ui/screen_settings_graphics.json b/resources/w/ui/screen_settings_graphics.json new file mode 100644 index 0000000..3c36638 --- /dev/null +++ b/resources/w/ui/screen_settings_graphics.json @@ -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 + } + ] + } +} diff --git a/resources/w/ui_en/screen_settings.json b/resources/w/ui_en/screen_settings.json index d71fed8..21614e8 100644 --- a/resources/w/ui_en/screen_settings.json +++ b/resources/w/ui_en/screen_settings.json @@ -105,11 +105,11 @@ }, { "type": "TextButton", - "name": "fullScreenToggleButton", + "name": "graphicsButton", "width": 500, "height": 60, - "text": "", - "fontSize": 32, + "text": "Graphics settings", + "fontSize": 40, "textCentered": true, "color": [1.0, 1.0, 1.0, 1.0] } diff --git a/resources/w/ui_en/screen_settings_graphics.json b/resources/w/ui_en/screen_settings_graphics.json new file mode 100644 index 0000000..704d490 --- /dev/null +++ b/resources/w/ui_en/screen_settings_graphics.json @@ -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 + } + ] + } +} diff --git a/src/Environment.cpp b/src/Environment.cpp index b9c289e..d34b0f3 100644 --- a/src/Environment.cpp +++ b/src/Environment.cpp @@ -31,6 +31,9 @@ bool Environment::isFullscreen = false; bool Environment::isFullscreen = true; #endif +bool Environment::isHighDPIEnabled = false; +int Environment::customDpiScale = 1; + bool Environment::showMouse = false; bool Environment::exitGameLoop = false; diff --git a/src/Environment.h b/src/Environment.h index 50b66bd..7084b9c 100644 --- a/src/Environment.h +++ b/src/Environment.h @@ -33,6 +33,9 @@ public: static bool isFullscreen; static void setFullscreen(bool enable); + static bool isHighDPIEnabled; + static int customDpiScale; + static bool showMouse; static bool exitGameLoop; diff --git a/src/Game.cpp b/src/Game.cpp index 3c3ace5..c06ff1c 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -292,6 +292,19 @@ namespace ZL menuManager.onLoadGame = [this](int slot) { loadGame(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()) // as a chunked sequence instead of one blocking call: the closures are // 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"); }); + + /*loadSteps.push([this]() { + if (menshadowsEnabled) + { + createShadowMapAndProparateToLocations(); + } + });*/ + loadSteps.push([this]() { 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(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() { glClear(GL_DEPTH_BUFFER_BIT); @@ -991,19 +1036,32 @@ namespace ZL if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) { - // Обновляем размеры и сбрасываем кеш текстов, т.к. меши хранятся в пикселях 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(); + const bool isPortrait = Environment::width < Environment::height; menuManager.uiManager.updateAllLayouts(); menuManager.topUiManager.updateAllLayouts(); + if (wasPortrait != isPortrait) { 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(); } diff --git a/src/Game.h b/src/Game.h index e497c82..6e5a3ec 100644 --- a/src/Game.h +++ b/src/Game.h @@ -50,6 +50,8 @@ namespace ZL { VertexRenderStruct loadingMesh; bool loadingCompleted = false; + std::shared_ptr shadowMap; + // 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 @@ -117,6 +119,8 @@ namespace ZL { void loadGame(int slot); SaveSlotInfo readSlotInfo(int slot) const; void createLocations(); + void createShadowMapAndProparateToLocations(); + void destroyShadowMapAndProparateToLocations(); // 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(). diff --git a/src/Location.cpp b/src/Location.cpp index 8b6641e..ed6c34c 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -168,13 +168,6 @@ namespace ZL loadTriggerZones(params.triggerZonesJsonPath, 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(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); SDL_PumpEvents(); diff --git a/src/Location.h b/src/Location.h index 06c06d8..b707328 100644 --- a/src/Location.h +++ b/src/Location.h @@ -79,7 +79,7 @@ namespace ZL std::vector navigationMaps; PathFinder* navigation = nullptr; - std::unique_ptr shadowMap; + std::shared_ptr shadowMap; Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity(); std::unique_ptr npcNameText; diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index c8a00de..9595235 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -12,7 +12,8 @@ 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)"; @@ -91,12 +92,12 @@ namespace ZL { if (negative) result = "-" + result; - + //Localization if (g_currentLanguage == Language::English) { return result + " som"; } - return result + " сом"; + return result + u8" сом"; } static std::array questStatusColor(Quest::QuestStatus status) { @@ -113,13 +114,14 @@ namespace ZL { gameState_(gameState), 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_exterior"][Language::Russian] = "Университет, двор"; + localizedLocationName["uni_exterior"][Language::Russian] = u8"Университет, двор"; 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"; } @@ -214,6 +216,7 @@ namespace ZL { mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile); aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.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); loadSavedGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_load.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"); }); + 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 // setSliderValue does not fire an unregistered callback. const float musicFrac = audioPlayer_.getMusicVolume() / 128.0f; @@ -400,6 +408,7 @@ namespace ZL { uiManager.setSliderValue("musicVolumeSlider", musicFrac); uiManager.setSliderValue("soundVolumeSlider", soundFrac); + // Localization if (g_currentLanguage == Language::English) { musicVolumePrefix = "Music volume: "; @@ -408,19 +417,15 @@ namespace ZL { musicToggleOff = "Music: OFF"; soundToggleOn = "Sound: ON"; soundToggleOff = "Sound: OFF"; - fullScreenToggleOn = "Full Screen: ON"; - fullScreenToggleOff = "Full Screen: OFF"; } else if (g_currentLanguage == Language::Russian) { - musicVolumePrefix = "Громкость музыки: "; - soundVolumePrefix = "Громкость звука: "; - musicToggleOn = "Музыка: ВКЛ"; - musicToggleOff = "Музыка: ВЫКЛ"; - soundToggleOn = "Звук: ВКЛ"; - soundToggleOff = "Звук: ВЫКЛ"; - fullScreenToggleOn = "Полноэкранный режим: ВКЛ"; - fullScreenToggleOff = "Полноэкранный режим: ВЫКЛ"; + musicVolumePrefix = u8"Громкость музыки: "; + soundVolumePrefix = u8"Громкость звука: "; + musicToggleOn = u8"Музыка: ВКЛ"; + musicToggleOff = u8"Музыка: ВЫКЛ"; + soundToggleOn = u8"Звук: ВКЛ"; + soundToggleOff = u8"Звук: ВЫКЛ"; } uiManager.setText("musicVolumeText", @@ -458,17 +463,9 @@ namespace ZL { ? std::array{ 0.2f, 0.9f, 0.2f, 1.0f } : std::array{ 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{ 0.2f, 0.9f, 0.2f, 1.0f } - : std::array{ 0.9f, 0.2f, 0.2f, 1.0f });*/ - }; refreshMusicToggle(); refreshSoundToggle(); - refreshFullscreenToggle(); uiManager.setTextButtonCallback("musicToggleButton", [this](const std::string&) { audioPlayer_.setMusicEnabled(!audioPlayer_.isMusicEnabled()); @@ -488,11 +485,59 @@ namespace ZL { : std::array{ 0.9f, 0.2f, 0.2f, 1.0f });*/ 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&) { Environment::setFullscreen(!Environment::isFullscreen); refreshFullscreenToggle(); 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() { @@ -2099,6 +2144,7 @@ namespace ZL { root["soundEnabled"] = audioPlayer_.isSoundEnabled(); root["fullscreen"] = Environment::isFullscreen; root["language"] = ZL::languageToCode(ZL::g_currentLanguage); + root["shadow"] = shadowsEnabled; saveJsonToFile(root, "settings.json"); } @@ -2130,6 +2176,19 @@ namespace ZL { Environment::setFullscreen(root["fullscreen"].get()); #endif } + if (root.contains("shadow")) { + if (shadowMapSettingsChangedFunc) + { + shadowMapSettingsChangedFunc(root["shadow"].get()); + } + } + else + { + if (shadowMapSettingsChangedFunc) + { + shadowMapSettingsChangedFunc(shadowsEnabled); + } + } } catch (const std::exception& e) { std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl; } diff --git a/src/MenuManager.h b/src/MenuManager.h index 78de0dc..8bcf4d4 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -78,6 +78,8 @@ namespace ZL { std::function onSaveGame; std::function onLoadGame; std::function getSlotInfoFunc; + std::function shadowMapSettingsChangedFunc; + // 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 @@ -126,6 +128,9 @@ namespace ZL { std::shared_ptr languageLoadingRu; std::shared_ptr languageLoadingEn; + bool shadowsEnabled = true; + + protected: Renderer& renderer; @@ -168,6 +173,7 @@ namespace ZL { void showAboutScreen(); void showSettingsScreen(); + void showSettingsGraphicsScreen(); void showLanguageScreen(); void showLoadGameScreen(); void showSaveGameScreen(); @@ -257,6 +263,7 @@ namespace ZL { std::shared_ptr mainMenuRoot; std::shared_ptr aboutScreenRoot; std::shared_ptr settingsScreenRoot; + std::shared_ptr settingsGraphicsScreenRoot; std::shared_ptr languageScreenRoot; std::shared_ptr loadSavedGameScreenRoot; std::shared_ptr saveGameScreenRoot; @@ -328,6 +335,8 @@ namespace ZL { std::string soundToggleOff; std::string fullScreenToggleOn; std::string fullScreenToggleOff; + std::string shadowToggleOn; + std::string shadowToggleOff; }; diff --git a/src/main.cpp b/src/main.cpp index a810093..9731426 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -235,6 +235,8 @@ int main(int argc, char *argv[]) { 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_HEIGHT = ZL::Environment::CONST_DEFAULT_HEIGHT; @@ -261,6 +263,9 @@ int main(int argc, char *argv[]) { if (settingsRoot.contains("fullscreen")) { ZL::Environment::isFullscreen = settingsRoot["fullscreen"].get(); } + if (settingsRoot.contains("isHighDPIEnabled")) { + ZL::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get(); + } } catch (const std::exception& e) { 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; } + 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( "Shadow Over Bishkek", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - ZL::Environment::width, ZL::Environment::height, + windowWidth, windowHeight, windowFlags ); @@ -285,11 +307,21 @@ int main(int argc, char *argv[]) { // On HiDPI displays the drawable (physical) size is larger than the // logical window size. Use the drawable size so the GL framebuffer // covers every physical pixel and the image stays sharp. + if (ZL::Environment::isHighDPIEnabled) { int drawW, drawH; SDL_GL_GetDrawableSize(ZL::Environment::window, &drawW, &drawH); ZL::Environment::width = drawW; 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();