Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/Orxonox.cc @ 868

Last change on this file since 868 was 868, checked in by scheusso, 16 years ago

some changes

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