From a382f6818971520286aebac1c9f05817ab64cd4c Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Thu, 28 Mar 2019 00:30:11 +0800 Subject: [PATCH] Make game use parameter dict for settings instead of a string table --- src/game.cpp | 391 +++++++++++++-------------------------------------- src/game.hpp | 26 ++-- 2 files changed, 110 insertions(+), 307 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 7f371d7..50d3378 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -68,169 +68,6 @@ #include "debug/logger.hpp" #include "debug/ansi-escape-codes.hpp" -template <> -bool Game::readSetting(const std::string& name, std::string* value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - *value = (*settingsTable)[it->second][1]; - - return true; -} - -template <> -bool Game::readSetting(const std::string& name, bool* value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - const std::string& string = (*settingsTable)[it->second][1]; - if (string == "true" || string == "on" || string == "1") - { - *value = true; - return true; - } - else if (string == "false" || string == "off" || string == "0") - { - *value = false; - return true; - } - - return false; -} - -template <> -bool Game::readSetting(const std::string& name, int* value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - std::stringstream stream; - stream << (*settingsTable)[it->second][1]; - stream >> (*value); - - return (!stream.fail()); -} - -template <> -bool Game::readSetting(const std::string& name, float* value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - std::stringstream stream; - stream << (*settingsTable)[it->second][1]; - stream >> (*value); - - return (!stream.fail()); -} - -template <> -bool Game::readSetting(const std::string& name, Vector2* value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - std::stringstream stream; - stream << (*settingsTable)[it->second][1]; - stream >> value->x; - - stream.str(std::string()); - stream.clear(); - - stream << (*settingsTable)[it->second][2]; - stream >> value->y; - - return (!stream.fail()); -} - -template <> -bool Game::writeSetting(const std::string& name, const std::string& value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - (*settingsTable)[it->second][1] = value; - - return true; -} - -template <> -bool Game::writeSetting(const std::string& name, const bool& value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - (*settingsTable)[it->second][1] = (value) ? "on" : "off"; - - return true; -} - -template <> -bool Game::writeSetting(const std::string& name, const int& value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - (*settingsTable)[it->second][1] = std::to_string(value); - - return true; -} - -template <> -bool Game::writeSetting(const std::string& name, const float& value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - (*settingsTable)[it->second][1] = std::to_string(value); - - return true; -} - -template <> -bool Game::writeSetting(const std::string& name, const Vector2& value) const -{ - auto it = settingsTableIndex.find(name); - if (it == settingsTableIndex.end()) - { - return false; - } - - (*settingsTable)[it->second][1] = std::to_string(value.x); - (*settingsTable)[it->second][2] = std::to_string(value.y); - - return true; -} - Game::Game(int argc, char* argv[]): currentState(nullptr), window(nullptr) @@ -535,23 +372,20 @@ void Game::toggleFullscreen() { if (!toggleFullscreenDisabled) { - fullscreen = !fullscreen; - window->setFullscreen(fullscreen); + fullscreen = !(*fullscreen); + window->setFullscreen(*fullscreen); - if (!fullscreen) + if (!(*fullscreen)) { const Display* display = deviceManager->getDisplays()->front(); int displayWidth = std::get<0>(display->getDimensions()); int displayHeight = std::get<1>(display->getDimensions()); - w = static_cast(windowResolution.x); - h = static_cast(windowResolution.y); + w = (*windowResolution)[0]; + h = (*windowResolution)[1]; - //int x = std::get<0>(display->getPosition()) + displayWidth / 2 - w / 2; - //int y = std::get<1>(display->getPosition()) + displayHeight / 2 - h / 2; - window->setDimensions(w, h); - window->setPosition(windowPosition.x, windowPosition.y); + window->setPosition((*windowPosition)[0], (*windowPosition)[1]); } restringUI(); @@ -573,8 +407,8 @@ void Game::toggleFullscreen() void Game::toggleVSync() { - vsync = !vsync; - window->setVSync(vsync); + vsync = !(*vsync); + window->setVSync(*vsync); restringUI(); // Save settings @@ -830,17 +664,15 @@ void Game::handleEvent(const WindowResizedEvent& event) w = event.width; h = event.height; - if (fullscreen) + if (*fullscreen) { logger->log("Resized fullscreen window to " + std::to_string(w) + "x" + std::to_string(h)); - fullscreenResolution.x = event.width; - fullscreenResolution.y = event.height; + fullscreenResolution = {event.width, event.height}; } else { logger->log("Resized window to " + std::to_string(w) + "x" + std::to_string(h)); - windowResolution.x = event.width; - windowResolution.y = event.height; + windowResolution = {event.width, event.height}; } // Save resolution settings @@ -866,7 +698,7 @@ void Game::handleEvent(const GamepadConnectedEvent& event) inputRouter->reset(); // Reload control profile - loadControlProfile(controlProfileName); + loadControlProfile(*controlProfileName); } void Game::handleEvent(const GamepadDisconnectedEvent& event) @@ -1010,7 +842,7 @@ void Game::setupLocalization() StringTableRow* languageCodes = &(*stringTable)[1]; for (std::size_t i = 2; i < languageCodes->size(); ++i) { - if (language == (*languageCodes)[i]) + if (*language == (*languageCodes)[i]) { currentLanguageIndex = i - 2; break; @@ -1025,35 +857,35 @@ void Game::setupWindow() int displayWidth = std::get<0>(display->getDimensions()); int displayHeight = std::get<1>(display->getDimensions()); - // Determine window position - int x = std::get<0>(display->getPosition()) + displayWidth / 2 - w / 2; - int y = std::get<1>(display->getPosition()) + displayHeight / 2 - h / 2; - - if (fullscreen) + int x; + int y; + if (*fullscreen) { - w = static_cast(fullscreenResolution.x); - h = static_cast(fullscreenResolution.y); + w = (*fullscreenResolution)[0]; + h = (*fullscreenResolution)[1]; + x = std::get<0>(display->getPosition()); + y = std::get<1>(display->getPosition()); } else { - w = static_cast(windowResolution.x); - h = static_cast(windowResolution.y); - x = static_cast(windowPosition.x); - y = static_cast(windowPosition.y); + w = (*windowResolution)[0]; + h = (*windowResolution)[1]; + x = (*windowPosition)[0]; + y = (*windowPosition)[1]; } // Read title string std::string title = getString("title"); // Create window - window = windowManager->createWindow(title.c_str(), x, y, w, h, fullscreen, WindowFlag::RESIZABLE); + window = windowManager->createWindow(title.c_str(), x, y, w, h, *fullscreen, WindowFlag::RESIZABLE); if (!window) { throw std::runtime_error("Game::Game(): Failed to create window."); } // Set v-sync mode - window->setVSync(vsync); + window->setVSync(*vsync); debugFont = nullptr; menuFont = nullptr; @@ -1209,10 +1041,10 @@ void Game::setupUI() // Get DPI and convert font size to pixels const Display* display = deviceManager->getDisplays()->front(); dpi = display->getDPI(); - fontSizePX = fontSizePT * (1.0f / 96.0f) * dpi; + fontSizePX = (*fontSize) * (1.0f / 96.0f) * dpi; logger->log("Detected display DPI as " + std::to_string(dpi) + "."); - logger->log("Font size = " + std::to_string(fontSizePT) + " PT = " + std::to_string(fontSizePX) + " PX."); + logger->log("Font size = " + std::to_string(*fontSize) + " PT = " + std::to_string(fontSizePX) + " PX."); // Load fonts loadFonts(); @@ -2062,14 +1894,14 @@ void Game::setupControls() controlNameMap["toggle-edit-mode"] = &toggleEditModeControl; // Load control profile - if (pathExists(controlsPath + controlProfileName + ".csv")) + if (pathExists(controlsPath + (*controlProfileName) + ".csv")) { - loadControlProfile(controlProfileName); + loadControlProfile(*controlProfileName); } else { loadControlProfile("default-keyboard-controls"); - saveControlProfile(controlProfileName); + saveControlProfile(*controlProfileName); } // Setup input mapper @@ -2096,130 +1928,109 @@ void Game::setupGameplay() cameraRig = orbitCam; } -void Game::resetSettings() -{ - // Set default language - language = "en-us"; - - // Set default resolutions - const Display* display = deviceManager->getDisplays()->front(); - int displayWidth = std::get<0>(display->getDimensions()); - int displayHeight = std::get<1>(display->getDimensions()); - float windowResolutionRatio = 5.0f / 6.0f; - windowResolution = Vector2(displayWidth, displayHeight) * 5.0f / 6.0f; - windowResolution.x = static_cast(windowResolution.x); - windowResolution.y = static_cast(windowResolution.y); - fullscreenResolution = Vector2(displayWidth, displayHeight); - - // Set default fullscreen mode - fullscreen = false; - - // Set default vsync mode - vsync = true; - - // Set default font size - fontSizePT = 14.0f; - - // Set control profile name - controlProfileName = "controls"; -} - void Game::loadSettings() { - // Reset settings to default values - resetSettings(); firstRun = false; + // Load settings try { - settings = resourceManager->load("params.csv"); + settings = resourceManager->load("settings.csv"); } catch (const std::exception& e) { + logger->warning("No user settings found. First run assumed."); + firstRun = true; + try + { + settings = resourceManager->load("default-settings.csv"); + } + catch (const std::exception& e) + { + logger->error("Failed to load default settings."); + settings = new ParameterDict(); + } } - std::optional fs = settings->get("fullscreen"); - if (!fs) - { - logger->log("Fullscreen unset"); - } - else + // Read settings + language = settings->get("language"); + windowPosition = settings->get("window-position"); + windowResolution = settings->get("window-resolution"); + fullscreenResolution = settings->get("window-resolution"); + fullscreen = settings->get("fullscreen"); + vsync = settings->get("vsync"); + fontSize = settings->get("font-size"); + controlProfileName = settings->get("control-profile"); + + // Use default values for unset parameters { - if (*fs) + if (language == std::nullopt) { - logger->log("Fullscreen on"); + language = "en-us"; } - else + + // Get display dimensions + const Display* display = deviceManager->getDisplays()->front(); + int displayWidth = std::get<0>(display->getDimensions()); + int displayHeight = std::get<1>(display->getDimensions()); + + if (windowResolution == std::nullopt) { + const float windowResolutionRatio = 5.0f / 6.0f; + int windowWidth = static_cast(static_cast(displayWidth) * windowResolutionRatio); + int windowHeight = static_cast(static_cast(displayHeight) * windowResolutionRatio); - logger->log("Fullscreen off"); + windowResolution = {windowWidth, windowHeight}; } - } - std::array ints = {5, 7, -89}; - settings->set("cool", ints); + if (windowPosition == std::nullopt) + { + int windowX = std::get<0>(display->getPosition()) + displayWidth / 2 - (*windowResolution)[0] / 2; + int windowY = std::get<1>(display->getPosition()) + displayHeight / 2 - (*windowResolution)[1] / 2; - std::optional> arrayOption = settings->get("cool"); - if (arrayOption != std::nullopt) - { - for (std::size_t i = 0; i < 3; ++i) + windowPosition = {windowX, windowY}; + } + + if (fullscreen == std::nullopt) { - logger->log(std::to_string(i) + ": " + std::to_string((*arrayOption)[i])); + fullscreen = true; } - } - // Load settings table - try - { - settingsTable = resourceManager->load("settings.csv"); - } - catch (const std::exception& e) - { - logger->warning("No user settings found. First run assumed."); - firstRun = true; + if (vsync == std::nullopt) + { + vsync = true; + } - try + if (fontSize == std::nullopt) { - settingsTable = resourceManager->load("default-settings.csv"); + fontSize = 14.0f; } - catch (const std::exception& e) + + if (controlProfileName == std::nullopt) { - logger->error("Failed to load default settings."); + controlProfileName = "controls"; } } - - // Build settings table index - settingsTableIndex = createIndex(*settingsTable); - - // Read settings from table - readSetting("language", &language); - readSetting("window-position", &windowPosition); - readSetting("window-resolution", &windowResolution); - readSetting("fullscreen-resolution", &fullscreenResolution); - readSetting("fullscreen", &fullscreen); - readSetting("vsync", &vsync); - readSetting("font-size", &fontSizePT); - readSetting("control-profile", &controlProfileName); } void Game::saveSettings() { - // Update settings table - writeSetting("language", language); - writeSetting("window-position", windowPosition); - writeSetting("window-resolution", windowResolution); - writeSetting("fullscreen-resolution", fullscreenResolution); - writeSetting("fullscreen", fullscreen); - writeSetting("vsync", vsync); - writeSetting("font-size", fontSizePT); - writeSetting("control-profile", controlProfileName); - - // Form full path to control profile file + // Update settings + settings->set("language", *language); + settings->set("window-position", *windowPosition); + settings->set("window-resolution", *windowResolution); + settings->set("fullscreen-resolution", *fullscreenResolution); + settings->set("fullscreen", *fullscreen); + settings->set("vsync", *vsync); + settings->set("font-size", *fontSize); + settings->set("control-profile", *controlProfileName); + + // Form full path to settings file std::string settingsPath = configPath + "settings.csv"; - // Save control profile - resourceManager->save(settingsTable, settingsPath); + // Save settings + resourceManager->save(settings, settingsPath); } void Game::loadStrings() @@ -2830,7 +2641,7 @@ void Game::resetControls() { inputRouter->reset(); loadControlProfile("default-keyboard-controls"); - saveControlProfile(controlProfileName); + saveControlProfile(*controlProfileName); restringUI(); } @@ -3382,7 +3193,7 @@ void Game::inputMapped(const InputMapping& mapping) eventDispatcher.schedule(event, time + 0.1f); // Save control profile - saveControlProfile(controlProfileName); + saveControlProfile(*controlProfileName); } void Game::languageSelected() diff --git a/src/game.hpp b/src/game.hpp index e95806b..ce6267f 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -174,7 +174,6 @@ private: void setupControls(); void setupGameplay(); - void resetSettings(); void loadSettings(); void saveSettings(); void loadStrings(); @@ -241,12 +240,6 @@ public: void boxSelect(float x, float y, float w, float h); - template - bool readSetting(const std::string& name, T* value) const; - - template - bool writeSetting(const std::string& name, const T& value) const; - public: // Game states StateMachine::State languageSelectState; @@ -266,8 +259,6 @@ public: // Settings ParameterDict* settings; bool firstRun; - StringTable* settingsTable; - StringTableIndex settingsTableIndex; // Localization StringTable* stringTable; @@ -554,14 +545,15 @@ public: bool paused; // Settings - std::string language; - Vector2 windowPosition; - Vector2 windowResolution; - Vector2 fullscreenResolution; - bool fullscreen; - bool vsync; - float fontSizePT; - std::string controlProfileName; + std::optional language; + std::optional windowPosition; + std::optional windowResolution; + std::optional fullscreenResolution; + std::optional fullscreen; + std::optional vsync; + std::optional fontSize; + std::optional controlProfileName; + bool toggleFullscreenDisabled; // Debugging