Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/orxonox.cc @ 542

Last change on this file since 542 was 542, checked in by bknecht, 16 years ago

added an argument reader

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