1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +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 main.cpp
GameBase.hpp
GameBase.cpp
RWGame.cpp RWGame.cpp
GameConfig.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 "states/MenuState.hpp"
#include <core/Profiler.hpp> #include <core/Profiler.hpp>
#include <core/Logger.hpp>
#include <engine/GameState.hpp> #include <engine/GameState.hpp>
#include <engine/GameWorld.hpp> #include <engine/GameWorld.hpp>
@ -25,15 +24,8 @@
#include <objects/VehicleObject.hpp> #include <objects/VehicleObject.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/program_options.hpp>
#include <functional> #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 = { std::map<GameRenderer::SpecialModel, std::string> kSpecialModels = {
{GameRenderer::ZoneCylinderA, "zonecyla.dff"}, {GameRenderer::ZoneCylinderA, "zonecyla.dff"},
{GameRenderer::ZoneCylinderB, "zonecylb.dff"}, {GameRenderer::ZoneCylinderB, "zonecylb.dff"},
@ -43,77 +35,19 @@ std::map<GameRenderer::SpecialModel, std::string> kSpecialModels = {
DebugDraw* debug = nullptr; DebugDraw* debug = nullptr;
RWGame::RWGame(Logger& log, int argc, char* argv[]) : log(log) { RWGame::RWGame(Logger& log, int argc, char* argv[])
if (!config.isValid()) { : GameBase(log, argc, argv) {
throw std::runtime_error("Invalid configuration file at: " + bool newgame = options.count("newgame");
config.getConfigFile()); bool test = options.count("test");
} std::string startSave(
options.count("load") ? options["load"].as<std::string>() : "");
size_t w = GAME_WINDOW_WIDTH, h = GAME_WINDOW_HEIGHT; std::string benchFile(options.count("benchmark")
bool fullscreen = false; ? options["benchmark"].as<std::string>()
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);
work = new WorkContext(); work = new WorkContext();
log.info("Game", "Game directory: " + config.getGameDataPath()); log.info("Game", "Game directory: " + config.getGameDataPath());
log.info("Game", "Build: " + kBuildStr);
if (!GameData::isValidGameDirectory(config.getGameDataPath())) { if (!GameData::isValidGameDirectory(config.getGameDataPath())) {
throw std::runtime_error("Invalid game directory path: " + throw std::runtime_error("Invalid game directory path: " +
@ -192,15 +126,8 @@ RWGame::~RWGame() {
log.info("Game", "Cleaning up state"); log.info("Game", "Cleaning up state");
delete state; delete state;
log.info("Game", "Cleaning up window");
delete window;
log.info("Game", "Cleaning up work queue"); log.info("Game", "Cleaning up work queue");
delete work; delete work;
SDL_Quit();
log.info("Game", "Done cleaning up");
} }
void RWGame::newGame() { void RWGame::newGame() {
@ -561,7 +488,7 @@ int RWGame::run() {
renderProfile(); renderProfile();
window->swap(); getWindow().swap();
} }
return 0; return 0;
@ -649,7 +576,7 @@ void RWGame::render(float alpha, float time) {
getRenderer()->getRenderer()->swap(); getRenderer()->getRenderer()->swap();
glm::ivec2 windowSize = window->getSize(); glm::ivec2 windowSize = getWindow().getSize();
renderer->setViewport(windowSize.x, windowSize.y); renderer->setViewport(windowSize.x, windowSize.y);
ViewCamera viewCam; ViewCamera viewCam;

View File

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

View File

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