Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/Orxonox.cc @ 737

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