1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 11:22:45 +01:00
openrw/rwgame/GameBase.cpp
Anonymous Maarten 8b38fda984 rwgame: merge argument + configuration file parsing + add tests
- definition of arguments an configuration parameters is centralized
  in rwgame/RWConfig.inc
- argument parsing is tested
- the try/catch in main is less weird now (imho)
2018-12-28 00:58:10 +01:00

87 lines
2.9 KiB
C++

#include "GameBase.hpp"
#include <rw/debug.hpp>
#include "GitSHA1.h"
#include <SDL.h>
#include <iostream>
// Use first 8 chars of git hash as the build string
const std::string kBuildStr(kGitSHA1Hash, 8);
const std::string kWindowTitle = "RWGame";
GameBase::GameBase(Logger &inlog, const std::optional<RWArgConfigLayer> &args) :
log(inlog),
config(buildConfig(args)) {
log.info("Game", "Build: " + kBuildStr);
bool fullscreen = config.fullscreen();
size_t w = config.width(), h = config.height();
if (SDL_Init(SDL_INIT_VIDEO) < 0)
throw std::runtime_error("Failed to initialize SDL2!");
window.create(kWindowTitle + " [" + kBuildStr + "]", w, h, fullscreen);
SET_RW_ABORT_CB([this]() {window.showCursor();},
[this]() {window.hideCursor();});
}
RWConfig GameBase::buildConfig(const std::optional<RWArgConfigLayer> &args) {
RWConfig config;
if (args.has_value()) {
config.setLayer(RWConfig::LAYER_ARGUMENT, *args);
}
auto defaultLayer = buildDefaultConfigLayer();
config.setLayer(RWConfig::LAYER_DEFAULT, defaultLayer);
rwfs::path configPath;
if (args.has_value() && args->configPath.has_value()) {
configPath = *args->configPath;
} else {
configPath = RWConfigParser::getDefaultConfigPath() / "openrw.ini";
}
if ((!args) || (args && !args->noconfig)) {
RWConfigParser configParser{};
auto [configLayer, parseResult] = configParser.loadFile(configPath);
if (!parseResult.isValid()) {
log.error("Config", "Could not read configuation file at " + configPath.string());
throw std::runtime_error(parseResult.what());
}
config.unknown = parseResult.getUnknownData();
config.setLayer(RWConfig::LAYER_CONFIGFILE, configLayer);
}
auto missingKeys = config.missingKeys();
if (!missingKeys.empty()) {
std::ostringstream oss;
oss << "Configuration is incomplete. The following configuration parameters are missing:";
for (const auto &missingKey : missingKeys) {
oss << "\n- " << missingKey << '\n';
}
defaultLayer.gamedataPath = "/path/to/gta3/data";
RWConfigParser configParser{};
auto [default_ini_string, parseResult] = configParser.layerToString(defaultLayer);
log.error("Config", "Configuration is incomplete. INI file at \"" + configPath.string() + "\"");
if (parseResult.isValid()) {
log.error("Config", "Adapt the following default INI to your configuration.");
log.error("Config", default_ini_string);
} else {
log.error("Config", "Default INI creation failed.");
oss << "\n On top, an internal error occured while creating the default INI string.";
}
throw std::runtime_error(oss.str());
}
return config;
}
GameBase::~GameBase() {
SDL_Quit();
log.info("Game", "Done cleaning up");
}