Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/orxonox/Game.cc @ 2840

Last change on this file since 2840 was 2817, checked in by rgrieder, 16 years ago

Removed GameState template and renamed GameStateBase to GameState.
Moved statistics stuff (fps and tick time) to Game and removed the remaining hacks in GSGraphics and GSRoot.

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30@file
31@brief
32    Implementation of the Game class.
33*/
34
35#include "OrxonoxStableHeaders.h"
36#include "Game.h"
37
38#include <exception>
39#include <cassert>
40
41#include "util/Debug.h"
42#include "util/Exception.h"
43#include "core/CommandLine.h"
44#include "core/ConsoleCommand.h"
45#include "core/Core.h"
46#include "core/Identifier.h"
47#include "core/CoreIncludes.h"
48#include "core/ConfigValueIncludes.h"
49
50#include "gamestates/GSRoot.h"
51#include "gamestates/GSGraphics.h"
52#include "gamestates/GSStandalone.h"
53#include "gamestates/GSServer.h"
54#include "gamestates/GSClient.h"
55#include "gamestates/GSDedicated.h"
56#include "gamestates/GSGUI.h"
57#include "gamestates/GSIOConsole.h"
58
59/*
60@brief
61    Main method. Game starts here (except for static initialisations).
62*/
63int main(int argc, char** argv)
64{
65    {
66        orxonox::Game orxonox(argc, argv);
67        orxonox.run();
68        // objects gets destroyed here!
69    }
70
71    // Clean up class hierarchy stuff (identifiers, xmlport, configvalue, consolecommand)
72    // Needs to be done after Game destructor because of ~OrxonoxClass
73    orxonox::Identifier::destroyAllIdentifiers();
74
75    return 0;
76}
77
78namespace orxonox
79{
80    void stop_game()
81    {
82        Game::getInstance().stop();
83    }
84
85    SetCommandLineArgument(state, "gui").shortcut("s");
86    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
87
88    Game* Game::singletonRef_s = 0;
89
90    /**
91    @brief
92        Non-initialising constructor.
93    */
94    Game::Game(int argc, char** argv)
95    {
96        assert(singletonRef_s == 0);
97        singletonRef_s = this;
98
99        this->abort_ = false;
100
101        // reset statistics
102        this->statisticsStartTime_ = 0;
103        this->statisticsTickTimes_.clear();
104        this->periodTickTime_ = 0;
105        this->periodTime_ = 0;
106        this->avgFPS_ = 0.0f;
107        this->avgTickTime_ = 0.0f;
108
109        this->core_ = new orxonox::Core();
110        this->gameClock_ = this->core_->initialise(argc, argv);
111
112        RegisterRootObject(Game);
113        this->setConfigValues();
114    }
115
116    /**
117    @brief
118    */
119    Game::~Game()
120    {
121        // Destroy pretty much everyhting left
122        delete this->core_;
123
124        assert(singletonRef_s);
125        singletonRef_s = 0;
126    }
127
128    void Game::setConfigValues()
129    {
130        SetConfigValue(statisticsRefreshCycle_, 250000)
131            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
132        SetConfigValue(statisticsAvgLength_, 1000000)
133            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
134    }
135
136    /**
137    @brief
138        Main loop of the orxonox game.
139    @note
140        We use the Ogre::Timer to measure time since it uses the most precise
141        method an any platform (however the windows timer lacks time when under
142        heavy kernel load!).
143    */
144    void Game::run()
145    {
146        // create the gamestates
147        GSRoot root;
148        GSGraphics graphics;
149        GSStandalone standalone;
150        GSServer server;
151        GSClient client;
152        GSDedicated dedicated;
153        GSGUI gui;
154        GSIOConsole ioConsole;
155
156        // make the hierarchy
157        root.addChild(&graphics);
158        graphics.addChild(&standalone);
159        graphics.addChild(&server);
160        graphics.addChild(&client);
161        graphics.addChild(&gui);
162        root.addChild(&ioConsole);
163        root.addChild(&dedicated);
164
165        root.activate();
166
167        // get initial state from command line
168        root.gotoState(CommandLine::getValue("state"));
169
170        this->gameClock_->capture(); // first delta time should be about 0 seconds
171        while (!this->abort_)
172        {
173            this->gameClock_->capture();
174            uint64_t currentTime = this->gameClock_->getMicroseconds();
175
176            // STATISTICS
177            statisticsTickInfo tickInfo = {currentTime, 0};
178            statisticsTickTimes_.push_back(tickInfo);
179            this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
180
181            // UPDATE
182            root.tick(*this->gameClock_);
183
184            // STATISTICS
185            if (this->periodTime_ > statisticsRefreshCycle_)
186            {
187                std::list<statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
188                assert(it != this->statisticsTickTimes_.end());
189                int64_t lastTime = currentTime - this->statisticsAvgLength_;
190                if ((int64_t)it->tickTime < lastTime)
191                {
192                    do
193                    {
194                        assert(this->periodTickTime_ > it->tickLength);
195                        this->periodTickTime_ -= it->tickLength;
196                        ++it;
197                        assert(it != this->statisticsTickTimes_.end());
198                    } while ((int64_t)it->tickTime < lastTime);
199                    this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
200                }
201
202                uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
203                this->avgFPS_ = (float)framesPerPeriod / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0;
204                this->avgTickTime_ = (float)this->periodTickTime_ / framesPerPeriod / 1000.0;
205
206                this->periodTime_ -= this->statisticsRefreshCycle_;
207            }
208
209            if (root.stateRequest_ != "")
210                root.gotoState(root.stateRequest_);
211        }
212
213        root.gotoState("root");
214        root.deactivate();
215    }
216
217    void Game::stop()
218    {
219        this->abort_ = true;
220    }
221
222    void Game::addTickTime(uint32_t length)
223    {
224        assert(!this->statisticsTickTimes_.empty());
225        this->statisticsTickTimes_.back().tickLength += length;
226        this->periodTickTime_+=length;
227    }
228}
Note: See TracBrowser for help on using the repository browser.