Eager-write defaults if the file is missing, then apply the cfg values to the live graphics engine. Normalize-but-don't-persist so a temporarily disconnected monitor keeps its remembered name.
| 305 | // values to the live graphics engine. Normalize-but-don't-persist |
| 306 | // so a temporarily disconnected monitor keeps its remembered name. |
| 307 | void LoadAndApplyDisplayConfig() |
| 308 | { |
| 309 | if (!GEngine) |
| 310 | return; |
| 311 | |
| 312 | const std::string path = DisplayConfigPath(); |
| 313 | DisplayConfig cfg; |
| 314 | if (!cfg.Load(path)) |
| 315 | { |
| 316 | cfg.LoadDefaults(); |
| 317 | cfg.Save(path); |
| 318 | LOG_INFO(Graphics, "LoadDisplayConfig: created defaults at '{}'", path); |
| 319 | } |
| 320 | |
| 321 | LiveDisplayEnv env(GEngine); |
| 322 | if (cfg.Normalize(env)) |
| 323 | LOG_INFO(Graphics, "LoadDisplayConfig: normalized invalid fields (not persisted)"); |
| 324 | |
| 325 | DisplayStartupOverrides overrides = GetCliDisplayOverrides(AppConfig::Instance()); |
| 326 | if (ApplyDisplayStartupOverrides(cfg, overrides)) |
| 327 | LOG_INFO(Graphics, "LoadDisplayConfig: applied explicit CLI display overrides"); |
| 328 | |
| 329 | // Apply order matters: monitor first (window may move), |
| 330 | // window mode next, resolution + refresh rate last. |
| 331 | if (cfg.monitor != GEngine->GetCurrentMonitor()) |
| 332 | GEngine->SwitchMonitor(cfg.monitor); |
| 333 | |
| 334 | // Honour the --window CLI override — when the user/test runner |
| 335 | // explicitly asked for Windowed, applying the cfg's Borderless or |
| 336 | // Fullscreen via SetWindowMode would route through |
| 337 | // SDL_SetWindowFullscreen(true), which fires WINDOW_ENTER_FULLSCREEN |
| 338 | // and flips the engine's _windowed back to false. Tests that boot |
| 339 | // with --window then assert IsWindowed() would race-fail. |
| 340 | const auto effectiveWindowMode = |
| 341 | ENGINE_CONFIG.useWindow ? DisplayConfig::Windowed : static_cast<DisplayConfig::WindowMode>(cfg.windowMode); |
| 342 | GEngine->SetWindowMode(static_cast<WindowMode>(effectiveWindowMode)); |
| 343 | if (cfg.resolutionWidth > 0 && cfg.resolutionHeight > 0) |
| 344 | GEngine->SwitchRes(cfg.resolutionWidth, cfg.resolutionHeight, /*bpp*/ 32); |
| 345 | if (cfg.refreshRate > 0 && effectiveWindowMode == DisplayConfig::Fullscreen) |
| 346 | GEngine->SwitchRefreshRate(cfg.refreshRate); |
| 347 | ApplyAspectPolicy(cfg); |
| 348 | |
| 349 | LOG_DEBUG(Graphics, "LoadDisplayConfig: monitor={} mode={} res={}x{} refresh={}", cfg.monitor, (int)cfg.windowMode, |
| 350 | cfg.resolutionWidth, cfg.resolutionHeight, cfg.refreshRate); |
| 351 | } |
| 352 | |
| 353 | // GraphicsConfig::Environment impl — only consults system RAM today. |
| 354 | struct LiveGraphicsEnv : GraphicsConfig::Environment |
no test coverage detected