Browse Source

Make game use parameter dict for settings instead of a string table

master
C. J. Howard 5 years ago
parent
commit
a382f68189
Signed by: cjhoward GPG Key ID: 03E1FABA9C3EC195
2 changed files with 110 additions and 307 deletions
  1. +101
    -290
      src/game.cpp
  2. +9
    -17
      src/game.hpp

+ 101
- 290
src/game.cpp View File

@ -68,169 +68,6 @@
#include "debug/logger.hpp"
#include "debug/ansi-escape-codes.hpp"
template <>
bool Game::readSetting<std::string>(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<bool>(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<int>(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<float>(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<Vector2>(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<std::string>(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<bool>(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<int>(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<float>(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<Vector2>(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<int>(windowResolution.x);
h = static_cast<int>(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<int>(fullscreenResolution.x);
h = static_cast<int>(fullscreenResolution.y);
w = (*fullscreenResolution)[0];
h = (*fullscreenResolution)[1];
x = std::get<0>(display->getPosition());
y = std::get<1>(display->getPosition());
}
else
{
w = static_cast<int>(windowResolution.x);
h = static_cast<int>(windowResolution.y);
x = static_cast<int>(windowPosition.x);
y = static_cast<int>(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<int>(windowResolution.x);
windowResolution.y = static_cast<int>(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<ParameterDict>("params.csv");
settings = resourceManager->load<ParameterDict>("settings.csv");
}
catch (const std::exception& e)
{
logger->warning("No user settings found. First run assumed.");
firstRun = true;
try
{
settings = resourceManager->load<ParameterDict>("default-settings.csv");
}
catch (const std::exception& e)
{
logger->error("Failed to load default settings.");
settings = new ParameterDict();
}
}
std::optional<bool> fs = settings->get<bool>("fullscreen");
if (!fs)
{
logger->log("Fullscreen unset");
}
else
// Read settings
language = settings->get<std::string>("language");
windowPosition = settings->get<int, 2>("window-position");
windowResolution = settings->get<int, 2>("window-resolution");
fullscreenResolution = settings->get<int, 2>("window-resolution");
fullscreen = settings->get<bool>("fullscreen");
vsync = settings->get<bool>("vsync");
fontSize = settings->get<float>("font-size");
controlProfileName = settings->get<std::string>("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<int>(static_cast<float>(displayWidth) * windowResolutionRatio);
int windowHeight = static_cast<int>(static_cast<float>(displayHeight) * windowResolutionRatio);
logger->log("Fullscreen off");
windowResolution = {windowWidth, windowHeight};
}
}
std::array<int, 3> ints = {5, 7, -89};
settings->set<int, 3>("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<std::array<int, 3>> arrayOption = settings->get<int, 3>("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<StringTable>("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<StringTable>("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<StringTable>(settingsTable, settingsPath);
// Save settings
resourceManager->save<ParameterDict>(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()

+ 9
- 17
src/game.hpp View File

@ -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 <typename T>
bool readSetting(const std::string& name, T* value) const;
template <typename T>
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<std::string> language;
std::optional<int2> windowPosition;
std::optional<int2> windowResolution;
std::optional<int2> fullscreenResolution;
std::optional<bool> fullscreen;
std::optional<bool> vsync;
std::optional<float> fontSize;
std::optional<std::string> controlProfileName;
bool toggleFullscreenDisabled;
// Debugging

Loading…
Cancel
Save