From 8a004f263689de041037b4832c99b3bcf1cdbc9e Mon Sep 17 00:00:00 2001 From: al Date: Sat, 16 Aug 2008 18:06:10 -0400 Subject: [PATCH] Kind of implemented engine_core loop. Implemented subsystem registration. Implemented basic window subsystem. --- src/engine.cpp | 67 +++++++++++++++++++++++++++++++------ src/engine.hpp | 17 +++++++--- src/main.cpp | 20 ++++++++--- src/{engine.hpp => state.cpp} | 28 ++++------------ src/{engine.hpp => state.hpp} | 37 +++++++++----------- src/window.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++ src/{engine.hpp => window.hpp} | 27 ++++++--------- 7 files changed, 196 insertions(+), 76 deletions(-) copy src/{engine.hpp => state.cpp} (65%) copy src/{engine.hpp => state.hpp} (66%) create mode 100644 src/window.cpp copy src/{engine.hpp => window.hpp} (67%) diff --git a/src/engine.cpp b/src/engine.cpp index f6438da..172ed0c 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -14,15 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see -// -------------------------------------------------------------------- -// One of the neat (or not so neat) things about programming in a -// language as sloppy as C++ is that there is not only one way of doing -// things. I'm choosing to modularize the engine, and represent each -// module with C++ classes. I don't know what other people will think -// about this choice, but it should enable us to keep things separate -// that aught to be separate, and it should allow us to crash in a -// rather clean way when we need to. -// ---- +// engine_core: operates subsystems when registered. Controls timing #include #include @@ -32,7 +24,7 @@ #include "engine.hpp" -void engine_subsystem::tick() +void engine_subsystem::tick(state &s) { // To be overloaded by derived subsystems } @@ -68,3 +60,58 @@ engine_core::~engine_core() _instance = NULL; std::cout << "engine_core shut down." << std::endl; } + +static bool subsystem_order_sort(std::pair a, + std::pair b) +{ + return (a.first < b.first); +} + +void engine_core::register_subsystem(engine_subsystem *sys, int order) +{ + _subsystems.push_back(std::pair(order, sys)); + _subsystems.sort(subsystem_order_sort); +} + +void engine_core::release_subsystem(engine_subsystem *sys) +{ + std::list >::iterator it; + + for(it = _subsystems.begin(); it != _subsystems.end(); ++it) + { + if(sys == (*it).second) + { + _subsystems.erase(it); + break; + } + } +} + + +void engine_core::run() +{ + // TODO: when we have a conf system, we can un-hardcode these values + _state.running = true; + _state.tickrate = 15; + _state.speed = 100; + + while(_state.running) + { + //std::cout << _subsystems.size() << std::endl; + // we'll never get a signal to stop if there are no active subsystems + if(_subsystems.empty()) + { + std::cerr << "Run engine with no subsystems??" << std::endl; + break; + } + + _state.time = SDL_GetTicks(); + + // Run each subsystem's 'tick' function + std::list >::iterator it; + for(it = _subsystems.begin(); it != _subsystems.end(); ++it) + (*it).second->tick(_state); + + SDL_Delay(1000 / _state.tickrate); + } +} diff --git a/src/engine.hpp b/src/engine.hpp index a71a055..46e6082 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -14,29 +14,38 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#ifndef ENGINE_HPP +#define ENGINE_HPP + #include +#include "state.hpp" + class engine_subsystem { private: public: - void tick(); + virtual void tick(state &s); }; class engine_core { private: - std::list _subsystems; + std::list > _subsystems; + + state _state; static engine_core *_instance; public: engine_core(int argc, char *argv[]); ~engine_core(); - void register_subsystem(engine_subsystem *); - void release_subsystem(engine_subsystem *); + void register_subsystem(engine_subsystem *sys, int order); + void release_subsystem(engine_subsystem *sys); void run(); }; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 7e239b3..f594cbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,12 +15,14 @@ // along with this program. If not, see . #include +#include "SDL.h" #ifdef HAVE_CONFIG_H #include "config.hpp" #endif #include "engine.hpp" +#include "window.hpp" int main(int argc, char *argv[]) { @@ -28,12 +30,22 @@ int main(int argc, char *argv[]) // Initialize the engine core engine_core ec(argc, argv); + + { + // Initialize subsystems + window_subsystem wss; - // Initialize subsystems and register them with the engine + // Register subsystems with engine + ec.register_subsystem(&wss, 1); - // Start the game... + // Start the game... + ec.run(); - // Bring down the subsystems and engine + // Release subsystems + ec.release_subsystem(&wss); - return 0; + } // (subsystem instances have gone out of scope) + + + return 0; // (engine_core has gone out of scope) } diff --git a/src/engine.hpp b/src/state.cpp similarity index 65% copy from src/engine.hpp copy to src/state.cpp index a71a055..daff16b 100644 --- a/src/engine.hpp +++ b/src/state.cpp @@ -14,29 +14,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include "state.hpp" -class engine_subsystem -{ -private: - -public: - void tick(); -}; +// QUESTION: should this be where the default settings go? I don't think so. -class engine_core +state::state() { -private: - std::list _subsystems; - - static engine_core *_instance; -public: - engine_core(int argc, char *argv[]); - ~engine_core(); +} - void register_subsystem(engine_subsystem *); - void release_subsystem(engine_subsystem *); - - void run(); -}; +state::~state() +{ +} diff --git a/src/engine.hpp b/src/state.hpp similarity index 66% copy from src/engine.hpp copy to src/state.hpp index a71a055..ab1e51f 100644 --- a/src/engine.hpp +++ b/src/state.hpp @@ -14,29 +14,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#ifndef STATE_HPP +#define STATE_HPP - -class engine_subsystem +class state { -private: - public: - void tick(); + state(); + ~state(); + + // serialize/read/write file functions + + // -------- STATE INFO UNDER HERE -------- + + // engine_core status + bool running; + unsigned int time; + unsigned int tickrate; + unsigned int speed; // this may belong to the physics engine }; -class engine_core -{ -private: - std::list _subsystems; - - static engine_core *_instance; -public: - engine_core(int argc, char *argv[]); - ~engine_core(); - - void register_subsystem(engine_subsystem *); - void release_subsystem(engine_subsystem *); - - void run(); -}; +#endif diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..01af267 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,76 @@ +// Plastic Engine +// Copyright (C) 2008 Albert Brown +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Window subsystem: establish a buffer to draw in, handle input + +#include +#include +#include +#include "SDL.h" + +#include "state.hpp" +#include "window.hpp" + + + +window_subsystem::window_subsystem() +{ + // TODO: we're going to have to implement commandline arguments and + // some sort of config interface before we can un-hardcode these values + _screen = SDL_SetVideoMode(640, 480, 32, SDL_DOUBLEBUF | SDL_OPENGL); + + if(!_screen) + { + // Something went wrong + std::string msg = std::string("SDL failed to set video mode: ") + + SDL_GetError(); + throw std::runtime_error(msg.c_str()); + } + + std::cout << "window_subsystem initialized." << std::endl; +} + +window_subsystem::~window_subsystem() +{ + // The way SDL is designed, we can't really close the window. + // TODO: maybe it would be possible if we init the SDL video subsystem + // here (in this class). This might allow us to close and restart + // it aswell, although this should not be neccesary (maybe on windows). + + std::cout << "window_subsystem shut down." << std::endl; +} + +void window_subsystem::tick(state &s) +{ + SDL_Event event; + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_KEYDOWN: + if(event.key.keysym.sym == SDLK_ESCAPE) + { + std::cout << "Escape" << std::endl; + s.running = false; + } + break; + case SDL_QUIT: + std::cout << "Close button" << std::endl; + s.running = false; + break; + } + } +} diff --git a/src/engine.hpp b/src/window.hpp similarity index 67% copy from src/engine.hpp copy to src/window.hpp index a71a055..f4f6df8 100644 --- a/src/engine.hpp +++ b/src/window.hpp @@ -14,29 +14,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#ifndef WINDOW_HPP +#define WINDOW_HPP +#include "SDL.h" -class engine_subsystem -{ -private: +#include "engine.hpp" -public: - void tick(); -}; -class engine_core +class window_subsystem : public engine_subsystem { private: - std::list _subsystems; + SDL_Surface *_screen; - static engine_core *_instance; public: - engine_core(int argc, char *argv[]); - ~engine_core(); - - void register_subsystem(engine_subsystem *); - void release_subsystem(engine_subsystem *); + window_subsystem(); + ~window_subsystem(); - void run(); + void tick(state &s); }; + +#endif -- 2.11.4.GIT