1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-03 17:19:46 +02:00

Move some non-game code into GameBase class

This moves window setup and configuration loading into a base
class so that RWGame can focus on game related matters
This commit is contained in:
Daniel Evans 2016-10-16 18:21:50 +01:00
parent 657a726a9b
commit 2f118631dc
6 changed files with 117 additions and 103 deletions

View File

@ -8,6 +8,8 @@ set(RWGAME_SOURCES
main.cpp
GameBase.hpp
GameBase.cpp
RWGame.cpp
GameConfig.cpp

69
rwgame/GameBase.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "GameBase.hpp"
#include "GitSHA1.h"
#include "SDL.h"
// Use first 8 chars of git hash as the build string
const std::string kBuildStr(kGitSHA1Hash, 8);
const std::string kWindowTitle = "RWGame";
constexpr int kWindowWidth = 800;
constexpr int kWindowHeight = 600;
GameBase::GameBase(Logger &inlog, int argc, char *argv[]) : log(inlog) {
log.info("Game", "Build: " + kBuildStr);
if (!config.isValid()) {
throw std::runtime_error("Invalid configuration file at: " +
config.getConfigFile());
}
size_t w = kWindowWidth, h = kWindowHeight;
bool fullscreen = false;
bool help = false;
// Define and parse command line options
namespace po = boost::program_options;
po::options_description desc("Available options");
desc.add_options()("help", "Show this help message")(
"width,w", po::value<size_t>(), "Game resolution width in pixel")(
"height,h", po::value<size_t>(), "Game resolution height in pixel")(
"fullscreen,f", "Enable fullscreen mode")("newgame,n",
"Directly start a new game")(
"test,t", "Starts a new game in a test location")(
"load,l", po::value<std::string>(), "Load save file")(
"benchmark,b", po::value<std::string>(), "Run benchmark from file");
po::variables_map &vm = options;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
} catch (po::error &ex) {
help = true;
std::cout << "Error parsing arguments: " << ex.what() << std::endl;
}
if (help || vm.count("help")) {
std::cout << desc;
throw std::invalid_argument("");
}
if (vm.count("width")) {
w = vm["width"].as<size_t>();
}
if (vm.count("height")) {
h = vm["height"].as<size_t>();
}
if (vm.count("fullscreen")) {
fullscreen = true;
}
if (SDL_Init(SDL_INIT_VIDEO) < 0)
throw std::runtime_error("Failed to initialize SDL2!");
window.create(kWindowTitle + " [" + kBuildStr + "]", w, h, fullscreen);
}
GameBase::~GameBase() {
SDL_Quit();
log.info("Game", "Done cleaning up");
}

33
rwgame/GameBase.hpp Normal file
View File

@ -0,0 +1,33 @@
#ifndef RWGAME_GAMEBASE_HPP
#define RWGAME_GAMEBASE_HPP
#include "GameConfig.hpp"
#include "GameWindow.hpp"
#include <core/Logger.hpp>
#include <boost/program_options.hpp>
/**
* @brief Handles basic window and setup
*/
class GameBase {
public:
GameBase(Logger& inlog, int argc, char* argv[]);
~GameBase();
GameWindow& getWindow() {
return window;
}
const GameConfig& getConfig() const {
return config;
}
protected:
Logger& log;
GameConfig config{"openrw.ini"};
GameWindow window;
boost::program_options::variables_map options;
};
#endif

View File

@ -7,7 +7,6 @@
#include "states/MenuState.hpp"
#include <core/Profiler.hpp>
#include <core/Logger.hpp>
#include <engine/GameState.hpp>
#include <engine/GameWorld.hpp>
@ -25,15 +24,8 @@
#include <objects/VehicleObject.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/program_options.hpp>
#include <functional>
#include "GitSHA1.h"
// Use first 8 chars of git hash as the build string
const std::string kBuildStr(kGitSHA1Hash, 8);
const std::string kWindowTitle = "RWGame";
std::map<GameRenderer::SpecialModel, std::string> kSpecialModels = {
{GameRenderer::ZoneCylinderA, "zonecyla.dff"},
{GameRenderer::ZoneCylinderB, "zonecylb.dff"},
@ -43,77 +35,19 @@ std::map<GameRenderer::SpecialModel, std::string> kSpecialModels = {
DebugDraw* debug = nullptr;
RWGame::RWGame(Logger& log, int argc, char* argv[]) : log(log) {
if (!config.isValid()) {
throw std::runtime_error("Invalid configuration file at: " +
config.getConfigFile());
}
size_t w = GAME_WINDOW_WIDTH, h = GAME_WINDOW_HEIGHT;
bool fullscreen = false;
bool newgame = false;
bool test = false;
bool help = false;
std::string startSave;
std::string benchFile;
// Define and parse command line options
namespace po = boost::program_options;
po::options_description desc("Available options");
desc.add_options()("help", "Show this help message")(
"width,w", po::value<size_t>(), "Game resolution width in pixel")(
"height,h", po::value<size_t>(), "Game resolution height in pixel")(
"fullscreen,f", "Enable fullscreen mode")("newgame,n",
"Directly start a new game")(
"test,t", "Starts a new game in a test location")(
"load,l", po::value<std::string>(), "Load save file")(
"benchmark,b", po::value<std::string>(), "Run benchmark from file");
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
} catch (po::error& ex) {
help = true;
std::cout << "Error parsing arguments: " << ex.what() << std::endl;
}
if (help || vm.count("help")) {
std::cout << desc;
throw std::invalid_argument("");
}
if (vm.count("width")) {
w = vm["width"].as<size_t>();
}
if (vm.count("height")) {
h = vm["height"].as<size_t>();
}
if (vm.count("fullscreen")) {
fullscreen = true;
}
if (vm.count("newgame")) {
newgame = true;
}
if (vm.count("test")) {
test = true;
}
if (vm.count("load")) {
startSave = vm["load"].as<std::string>();
}
if (vm.count("benchmark")) {
benchFile = vm["benchmark"].as<std::string>();
}
if (SDL_Init(SDL_INIT_VIDEO) < 0)
throw std::runtime_error("Failed to initialize SDL2!");
window = new GameWindow();
window->create(kWindowTitle + " [" + kBuildStr + "]", w, h, fullscreen);
RWGame::RWGame(Logger& log, int argc, char* argv[])
: GameBase(log, argc, argv) {
bool newgame = options.count("newgame");
bool test = options.count("test");
std::string startSave(
options.count("load") ? options["load"].as<std::string>() : "");
std::string benchFile(options.count("benchmark")
? options["benchmark"].as<std::string>()
: "");
work = new WorkContext();
log.info("Game", "Game directory: " + config.getGameDataPath());
log.info("Game", "Build: " + kBuildStr);
if (!GameData::isValidGameDirectory(config.getGameDataPath())) {
throw std::runtime_error("Invalid game directory path: " +
@ -192,15 +126,8 @@ RWGame::~RWGame() {
log.info("Game", "Cleaning up state");
delete state;
log.info("Game", "Cleaning up window");
delete window;
log.info("Game", "Cleaning up work queue");
delete work;
SDL_Quit();
log.info("Game", "Done cleaning up");
}
void RWGame::newGame() {
@ -561,7 +488,7 @@ int RWGame::run() {
renderProfile();
window->swap();
getWindow().swap();
}
return 0;
@ -649,7 +576,7 @@ void RWGame::render(float alpha, float time) {
getRenderer()->getRenderer()->swap();
glm::ivec2 windowSize = window->getSize();
glm::ivec2 windowSize = getWindow().getSize();
renderer->setViewport(windowSize.x, windowSize.y);
ViewCamera viewCam;

View File

@ -8,24 +8,17 @@
#include <script/ScriptMachine.hpp>
#include "game.hpp"
#include "GameConfig.hpp"
#include "GameWindow.hpp"
#include "SDL.h"
#include "GameBase.hpp"
class PlayerController;
class Logger;
class RWGame {
Logger& log;
GameConfig config{"openrw.ini"};
class RWGame : public GameBase {
GameState* state = nullptr;
GameData* data = nullptr;
GameWorld* world = nullptr;
// must be allocated after Logger setup.
GameRenderer* renderer = nullptr;
ScriptMachine* script = nullptr;
GameWindow* window = nullptr;
// Background worker
WorkContext* work = nullptr;
std::chrono::steady_clock clock;
@ -77,18 +70,10 @@ public:
return renderer;
}
GameWindow& getWindow() {
return *window;
}
ScriptMachine* getScript() const {
return script;
}
const GameConfig& getConfig() const {
return config;
}
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal,
GameObject** object = nullptr) {
auto vc = nextCam;

View File

@ -15,7 +15,5 @@ bool hitWorldRay(const glm::vec3& start, const glm::vec3& direction,
GameObject** object = nullptr);
#define GAME_TIMESTEP (1.f / 30.f)
#define GAME_WINDOW_WIDTH 800
#define GAME_WINDOW_HEIGHT 600
#endif // GAME_HPP