Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 856 was 790, checked in by nicolasc, 17 years ago

merged FICN back into trunk
awaiting release.

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