Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/Orxonox.cc @ 998

Last change on this file since 998 was 871, checked in by landauf, 17 years ago

merged core branch to trunk

File size: 12.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28/**
29 @file  Orxonox.cc
30 @brief Orxonox Main Class
31 */
32
33// Precompiled Headers
34#include "OrxonoxStableHeaders.h"
35
36//****** OGRE ******
37#include <OgreException.h>
38#include <OgreRoot.h>
39#include <OgreFrameListener.h>
40#include <OgreRenderWindow.h>
41#include <OgreTextureManager.h>
42#include <OgreResourceGroupManager.h>
43#include <OgreConfigFile.h>
44#include <OgreOverlay.h>
45#include <OgreOverlayManager.h>
46
47//****** OIS *******
48#include <OIS/OIS.h>
49
50//****** STD *******
51#include <iostream>
52#include <exception>
53
54//***** ORXONOX ****
55//misc
56#include "util/Sleep.h"
57
58// loader and audio
59//#include "loader/LevelLoader.h"
60#include "audio/AudioManager.h"
61
62// network
63#include "network/Server.h"
64#include "network/Client.h"
65#include "network/NetworkFrameListener.h"
66
67// objects
68#include "objects/Tickable.h"
69#include "tools/Timer.h"
70#include "objects/NPC.h"
71#include "core/ArgReader.h"
72#include "core/Factory.h"
73#include "core/Debug.h"
74#include "core/Loader.h"
75#include "hud/HUD.h"
76#include "objects/weapon/BulletManager.h"
77#include "GraphicsEngine.h"
78
79#include "Orxonox.h"
80
81namespace orxonox
82{
83   // put this in a seperate Class or solve the problem in another fashion
84  class OrxListener : public Ogre::FrameListener
85  {
86    public:
87      OrxListener(OIS::Keyboard *keyboard, audio::AudioManager*  auMan, gameMode mode)
88      {
89        mKeyboard = keyboard;
90        mode_=mode;
91        auMan_ = auMan;
92      }
93
94      bool frameStarted(const Ogre::FrameEvent& evt)
95      {
96        auMan_->update();
97        updateAI();
98
99        if(mode_ == PRESENTATION)
100          server_g->tick(evt.timeSinceLastFrame);
101        else if(mode_ == CLIENT)
102          client_g->tick(evt.timeSinceLastFrame);
103
104        usleep(10);
105
106        mKeyboard->capture();
107        return !mKeyboard->isKeyDown(OIS::KC_ESCAPE);
108      }
109
110      void updateAI()
111      {
112        for(Iterator<NPC> it = ObjectList<NPC>::start(); it; ++it)
113        {
114          it->update();
115        }
116      }
117
118    private:
119      gameMode mode_;
120      OIS::Keyboard *mKeyboard;
121      audio::AudioManager*  auMan_;
122  };
123
124  // init static singleton reference of Orxonox
125  Orxonox* Orxonox::singletonRef_ = NULL;
126
127  /**
128   * create a new instance of Orxonox
129   */
130  Orxonox::Orxonox()
131  {
132    this->ogre_ = new GraphicsEngine();
133    this->dataPath_ = "";
134//    this->loader_ = 0;
135    this->auMan_ = 0;
136    this->singletonRef_ = 0;
137    this->keyboard_ = 0;
138    this->mouse_ = 0;
139    this->inputManager_ = 0;
140    this->frameListener_ = 0;
141    this->root_ = 0;
142  }
143
144  /**
145   * destruct Orxonox
146   */
147  Orxonox::~Orxonox()
148  {
149    // nothing to delete as for now
150  }
151
152  /**
153   * initialization of Orxonox object
154   * @param argc argument counter
155   * @param argv list of arguments
156   * @param path path to config (in home dir or something)
157   */
158  void Orxonox::init(int argc, char **argv, std::string path)
159  {
160    //TODO: find config file (assuming executable directory)
161    //TODO: read config file
162    //TODO: give config file to Ogre
163    std::string mode;
164//     if(argc>=2)
165//       mode = std::string(argv[1]);
166//     else
167//       mode = "";
168    ArgReader ar = ArgReader(argc, argv);
169    ar.checkArgument("mode", mode, false);
170    ar.checkArgument("data", this->dataPath_, false);
171    ar.checkArgument("ip", serverIp_, false);
172    //mode = "presentation";
173    if(ar.errorHandling()) die();
174    if(mode == std::string("server"))
175    {
176      serverInit(path);
177      mode_ = SERVER;
178    }
179    else if(mode == std::string("client"))
180    {
181      clientInit(path);
182      mode_ = CLIENT;
183    }
184    else if(mode == std::string("presentation"))
185    {
186      serverInit(path);
187      mode_ = PRESENTATION;
188    }
189    else{
190      standaloneInit(path);
191      mode_ = STANDALONE;
192    }
193  }
194
195  /**
196   * start modules
197   */
198  void Orxonox::start()
199  {
200    //TODO: start modules
201    ogre_->startRender();
202    //TODO: run engine
203    Factory::createClassHierarchy();
204    createScene();
205    setupScene();
206    setupInputSystem();
207    if(mode_!=CLIENT){ // remove this in future ---- presentation hack
208    }
209    else
210      std::cout << "client here" << std::endl;
211    createFrameListener();
212    switch(mode_){
213    case PRESENTATION:
214      //ogre_->getRoot()->addFrameListener(new network::ServerFrameListener());
215      //std::cout << "could not add framelistener" << std::endl;
216      server_g->open();
217      break;
218    case CLIENT:
219      client_g->establishConnection();
220      break;
221    case SERVER:
222    case STANDALONE:
223    default:
224      break;
225    }
226    startRenderLoop();
227  }
228
229  /**
230   * @return singleton object
231   */
232  Orxonox* Orxonox::getSingleton()
233  {
234    if (!singletonRef_)
235      singletonRef_ = new Orxonox();
236    return singletonRef_;
237  }
238
239  /**
240   * error kills orxonox
241   */
242  void Orxonox::die(/* some error code */)
243  {
244    //TODO: destroy and destruct everything and print nice error msg
245    delete this;
246  }
247
248  void Orxonox::standaloneInit(std::string path)
249  {
250    ogre_->setConfigPath(path);
251    ogre_->setup();
252    root_ = ogre_->getRoot();
253    if(!ogre_->load()) die(/* unable to load */);
254
255    //defineResources();
256    //setupRenderSystem();
257    //createRenderWindow();
258    //initializeResourceGroups();
259    /*createScene();
260    setupScene();
261    setupInputSystem();
262    createFrameListener();
263    Factory::createClassHierarchy();
264    startRenderLoop();*/
265  }
266
267  void Orxonox::playableServer(std::string path)
268  {
269    ogre_->setConfigPath(path);
270    ogre_->setup();
271    root_ = ogre_->getRoot();
272    defineResources();
273    setupRenderSystem();
274    createRenderWindow();
275    initializeResourceGroups();
276    setupInputSystem();
277    Factory::createClassHierarchy();
278    createScene();
279    setupScene();
280    createFrameListener();
281    try{
282      server_g = new network::Server(); //!< add port and bindadress
283      server_g->open(); //!< open server and create listener thread
284      if(ogre_ && ogre_->getRoot())
285        ogre_->getRoot()->addFrameListener(new network::ServerFrameListener()); // adds a framelistener for the server
286      COUT(3) << "Info: network framelistener added" << std::endl;
287    }
288    catch(...)
289    {
290      COUT(1) << "Error: There was a problem initialising the server :(" << std::endl;
291    }
292    startRenderLoop();
293  }
294
295  void Orxonox::standalone(){
296
297
298
299  }
300
301  void Orxonox::serverInit(std::string path)
302  {
303    COUT(2) << "initialising server" << std::endl;
304    ogre_->setConfigPath(path);
305    ogre_->setup();
306    server_g = new network::Server(); // FIXME add some settings if wanted
307    if(!ogre_->load()) die(/* unable to load */);
308    // FIXME add network framelistener
309  }
310
311  void Orxonox::clientInit(std::string path)
312  {
313    COUT(2) << "initialising client" << std::endl;
314    ogre_->setConfigPath(path);
315    ogre_->setup();
316    if(serverIp_.compare("")==0)
317      client_g = new network::Client();
318    else
319      client_g = new network::Client(serverIp_, 55556);
320    if(!ogre_->load()) die(/* unable to load */);
321    ogre_->getRoot()->addFrameListener(new network::ClientFrameListener());
322  }
323
324  void Orxonox::defineResources()
325  {
326    std::string secName, typeName, archName;
327    Ogre::ConfigFile cf;
328#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
329    cf.load(macBundlePath() + "/Contents/Resources/resources.cfg");
330#else
331    cf.load(dataPath_ + "resources.cfg");
332#endif
333
334    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
335    while (seci.hasMoreElements())
336    {
337      secName = seci.peekNextKey();
338      Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
339      Ogre::ConfigFile::SettingsMultiMap::iterator i;
340      for (i = settings->begin(); i != settings->end(); ++i)
341      {
342        typeName = i->first;
343        archName = i->second;
344#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
345        Ogre::ResourceGroupManager::getSingleton().addResourceLocation( std::string(macBundlePath() + "/" + archName), typeName, secName);
346#else
347        Ogre::ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName);
348#endif
349      }
350    }
351  }
352
353  void Orxonox::setupRenderSystem()
354  {
355    if (!root_->restoreConfig() && !root_->showConfigDialog())
356      throw Ogre::Exception(52, "User canceled the config dialog!", "OrxApplication::setupRenderSystem()");
357  }
358
359  void Orxonox::createRenderWindow()
360  {
361    root_->initialise(true, "OrxonoxV2");
362  }
363
364  void Orxonox::initializeResourceGroups()
365  {
366    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
367    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
368  }
369
370  /**
371   *
372   * @param
373   */
374  void Orxonox::createScene(void)
375  {
376        // Init audio
377    auMan_ = new audio::AudioManager();
378
379    bulletMgr_ = new BulletManager();
380
381    // load this file from config
382//    loader_ = new loader::LevelLoader("sample.oxw");
383//    loader_->loadLevel();
384    Level* startlevel = new Level("levels/sample.oxw");
385    Loader::open(startlevel);
386
387    Ogre::Overlay* hudOverlay = Ogre::OverlayManager::getSingleton().getByName("Orxonox/HUD1.2");
388    HUD* orxonoxHud;
389    orxonoxHud = new HUD();
390    orxonoxHud->setEnergyValue(20);
391    orxonoxHud->setEnergyDistr(20,20,60);
392    hudOverlay->show();
393
394        /*
395    auMan_->ambientAdd("a1");
396    auMan_->ambientAdd("a2");
397    auMan_->ambientAdd("a3");
398                                //auMan->ambientAdd("ambient1");
399    auMan_->ambientStart();*/
400  }
401
402
403  /**
404   *
405   */
406  void Orxonox::setupScene()
407  {
408//    SceneManager *mgr = ogre_->getSceneManager();
409
410
411//    SceneNode* node = (SceneNode*)mgr->getRootSceneNode()->getChild("OgreHeadNode");
412//     SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("OgreHeadNode", Vector3(0,0,0));
413
414
415/*
416    particle::ParticleInterface *e = new particle::ParticleInterface(mgr,"engine","Orxonox/strahl");
417    e->particleSystem_->setParameter("local_space","true");
418    e->setPositionOfEmitter(0, Vector3(0,-10,0));
419    e->setDirection(Vector3(0,0,-1));
420    e->addToSceneNode(node);
421*/
422  }
423
424
425  void Orxonox::setupInputSystem()
426  {
427    size_t windowHnd = 0;
428    std::ostringstream windowHndStr;
429    OIS::ParamList pl;
430
431    // fixes auto repeat problem
432    #if defined OIS_LINUX_PLATFORM
433      pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
434    #endif
435
436      Ogre::RenderWindow *win = ogre_->getRoot()->getAutoCreatedWindow();
437    win->getCustomAttribute("WINDOW", &windowHnd);
438    windowHndStr << windowHnd;
439    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
440    inputManager_ = OIS::InputManager::createInputSystem(pl);
441
442    try
443    {
444      keyboard_ = static_cast<OIS::Keyboard*>(inputManager_->createInputObject(OIS::OISKeyboard, false));
445      mouse_ = static_cast<OIS::Mouse*>(inputManager_->createInputObject(OIS::OISMouse, true));
446    }
447    catch (const OIS::Exception &e)
448    {
449      throw new Ogre::Exception(42, e.eText, "OrxApplication::setupInputSystem");
450    }
451  }
452
453  // FIXME we actually want to do this differently...
454  void Orxonox::createFrameListener()
455  {
456    TickFrameListener* TickFL = new TickFrameListener();
457    ogre_->getRoot()->addFrameListener(TickFL);
458
459    TimerFrameListener* TimerFL = new TimerFrameListener();
460    ogre_->getRoot()->addFrameListener(TimerFL);
461
462    //if(mode_!=CLIENT) // FIXME just a hack ------- remove this in future
463      frameListener_ = new OrxListener(keyboard_, auMan_, mode_);
464    ogre_->getRoot()->addFrameListener(frameListener_);
465  }
466
467  void Orxonox::startRenderLoop()
468  {
469    // FIXME
470    // this is a hack!!!
471    // the call to reset the mouse clipping size should probably be somewhere
472    // else, however this works for the moment.
473    unsigned int width, height, depth;
474    int left, top;
475    ogre_->getRoot()->getAutoCreatedWindow()->getMetrics(width, height, depth, left, top);
476
477    if(mode_!=CLIENT){
478      const OIS::MouseState &ms = mouse_->getMouseState();
479      ms.width = width;
480      ms.height = height;
481    }
482    ogre_->getRoot()->startRendering();
483  }
484}
Note: See TracBrowser for help on using the repository browser.