Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/run_manager.cc @ 588

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

corrected strange behaviour

File size: 14.1 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 *      Reto Grieder
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28
29#include "OgreVector3.h"
30#include "OgreStringConverter.h"
31#include "OgreRoot.h"
32#include "OgreSceneManager.h"
33#include "OgreSceneNode.h"
34#include "OgreCamera.h"
35#include "OgreViewport.h"
36#include "OgreRenderWindow.h"
37#include "OgreTextureManager.h"
38#include "OgreMaterialManager.h"
39#include "OgreLogManager.h"
40#include "OgreWindowEventUtilities.h"
41
42//Use this define to signify OIS will be used as a DLL
43//(so that dll import/export macros are in effect)
44#define OIS_DYNAMIC_LIB
45#include <OIS/OIS.h>
46
47#include "ogre_control.h"
48#include "orxonox_scene.h"
49#include "orxonox_ship.h"
50#include "inertial_node.h"
51
52#include "weapon/bullet.h"
53#include "weapon/bullet_manager.h"
54#include "weapon/base_weapon.h"
55
56//#include "hud/hud_overlay.h"
57//#include "hud/test_overlay.h"
58#include "hud/HUD.h"
59
60#include "run_manager.h"
61
62
63namespace orxonox {
64  using namespace Ogre;
65  using namespace weapon;
66  using namespace hud;
67
68  /**
69  * RunManager is the basic control object during the game.
70  *
71  * The RunManger class is designed to actually "run" the main part of the
72  * game. The Idea is, that you could derive from the RunManager in order
73  * to distinguish between a first person shooter or a space craft shooter.
74  * RunManager loads and initialises everything in the scene (like the ship,
75  * the enemies in the scene, any scripts, the physics, window events,
76  * environment, HUD, etc.).
77  * It also captures any input from keyboard, mous, joystick (optional) or
78  * Ogre (window events).
79  */
80
81
82  RunManager* RunManager::singletonPtr_s = NULL;
83
84
85  /**
86  * Contructor only needs the Root object.
87  */
88  RunManager::RunManager()
89        : ogre_(NULL), window_(NULL), screenShotCounter_(0),
90        timeUntilNextToggle_(0), mouseSensitivity_(0.003), inputManager_(0),
91        mouse_(0), keyboard_(0), joystick_(0), statsOn_(true)
92  {
93  }
94
95  /**
96  * @param ogre_ The OgreControl object holding the render window and the Root
97  */
98  void RunManager::initialise(OgreControl *ogre)
99    {
100    ogre_ = ogre;
101    window_ = ogre->getRenderWindow();
102
103    // SETTING UP THE SCENE
104
105    // create one new SceneManger
106    sceneMgr_ = ogre_->getRoot()->createSceneManager(ST_GENERIC, "Orxonox Scene");
107
108    // background scene (world objects, skybox, lights, etc.)
109    backgroundScene_ = new OrxonoxScene(sceneMgr_);
110
111
112    // BULLET LIST FOR THE TEST APPLICATION
113
114    // create a bullet manager
115    bulletManager_ = new BulletManager(sceneMgr_);
116
117
118    // PLAYER SPACESHIP
119
120    // Create a space ship object and its SceneNode.
121    // It should also be considered, that the ship should provide another Node
122    // for a camera to be attached (otherwise the spaceship in front of the
123    // ship would be very static, never moving at all).
124
125    // Construct a new spaceship and give it the node
126    playerShip_ = new OrxonoxShip(sceneMgr_->getRootSceneNode()
127      ->createChildSceneNode("ShipNode", Vector3(20, 20, 20)));
128
129
130    // RESOURCE LOADING (using ResourceGroups if implemented)
131
132    // load all resources and create the entities by calling the initialise()
133    // methods for each object (no constructor initialisations!).
134    backgroundScene_->initialise();
135    playerShip_->initialise();
136
137
138    // CAMERA AND VIEWPORT
139
140    // create camera and viewport
141    createCamera();
142    createViewports();
143
144    // create HUD
145    //hud_ = new hud::TestOverlay(window_);
146    //hud_->show();
147    /*hud_ = new hud::HUD();
148    hud_->show();*/
149
150
151    // Set default mipmap level (NB some APIs ignore this)
152    TextureManager::getSingleton().setDefaultNumMipmaps(5);
153
154
155    // HUMAN INTERFACE
156
157    using namespace OIS;
158
159    LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
160    ParamList pl;
161    size_t windowHnd = 0;
162    std::ostringstream windowHndStr;
163
164    window_->getCustomAttribute("WINDOW", &windowHnd);
165    windowHndStr << windowHnd;
166    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
167
168    inputManager_ = InputManager::createInputSystem( pl );
169
170    // Create all devices (We only catch joystick exceptions here,
171    // as, most people have Key/Mouse)
172    keyboard_ = static_cast<Keyboard*>(inputManager_
173      ->createInputObject( OISKeyboard, false ));
174    mouse_ = static_cast<Mouse*>(inputManager_
175      ->createInputObject( OISMouse, false ));
176    try {
177      joystick_ = static_cast<JoyStick*>(inputManager_
178        ->createInputObject( OISJoyStick, false ));
179    }
180    catch(...) {
181      joystick_ = 0;
182    }
183
184    //Set initial mouse clipping size
185    windowResized(window_);
186
187    //showDebugOverlay(true);
188
189    // REGISTER THIS OBJECT AS A WINDOW EVENT LISTENER IN OGRE
190    // It will then receive events liek windowClosed, windowResized, etc.
191    WindowEventUtilities::addWindowEventListener(window_, this);
192  }
193
194  /**
195  * Standard destructor.
196  * Removes this object as a window event listener and deletes all created
197  * variables.
198  */
199  RunManager::~RunManager()
200  {
201    //Remove ourself as a Window listener
202    WindowEventUtilities::removeWindowEventListener(window_, this);
203    windowClosed(window_);
204
205    if (backgroundScene_)
206      delete backgroundScene_;
207    if (playerShip_)
208      delete playerShip_;
209    if (bulletManager_)
210      delete bulletManager_;
211    /*if (hud_)
212      delete hud_;*/
213  }
214
215
216  /**
217  * Method to compute anything between 2 frames.
218  *
219  * Everything that needs to be computed during the games happens right here.
220  * The only exception are the listeners (which should only set variables,
221  * not actually do something).
222  *
223  * @param time Absolute play time
224  * @param deltaTime Time passed since last frame
225  * @return Return false to end rendering
226  */
227  bool RunManager::tick(unsigned long time, float deltaTime)
228  {
229    // synchronize with internal class timer
230    totalTime_ = time;
231
232    // Call tick() for every object
233    // This could be done by registering (needs a factory..)
234    backgroundScene_->tick(time, deltaTime);
235    playerShip_->tick(time, deltaTime);
236
237
238    // Update the HUD
239    Ogre::String tempStr = " | Speed = "
240      + StringConverter::toString(playerShip_->getSpeed())
241      + " | Left Ammo = "
242      + StringConverter::toString(playerShip_
243      ->getMainWeapon()->getAmmoState())
244      + " | Ammo stock = "
245      + StringConverter::toString(playerShip_->getAmmoStock());
246    //hud_->setDebugText(tempStr);
247
248    //hud_->tick(time, deltaTime);
249
250    // update the bullet positions
251    bulletManager_->tick(time, deltaTime);
252
253
254    // HUMAN INTERFACE
255
256    using namespace OIS;
257
258    if(window_->isClosed())     return false;
259
260    //Need to capture/update each device
261    keyboard_->capture();
262    mouse_->capture();
263    if( joystick_ ) joystick_->capture();
264
265    bool buffJ = (joystick_) ? joystick_->buffered() : true;
266
267    //Check if one of the devices is not buffered
268    if( !mouse_->buffered() || !keyboard_->buffered() || !buffJ )
269    {
270      // one of the input modes is immediate, so setup what
271      // is needed for immediate movement
272      if (timeUntilNextToggle_ >= 0)
273        timeUntilNextToggle_ -= deltaTime;
274    }
275
276    // handle HID devices
277    if( processUnbufferedKeyInput() == false )
278        return false;
279    if( processUnbufferedMouseInput() == false )
280        return false;
281
282    // keep rendering
283    return true;
284  }
285
286
287  SceneManager& RunManager::getSceneManager()
288  {
289    return *sceneMgr_;
290  }
291
292  SceneManager* RunManager::getSceneManagerPtr()
293  {
294    return sceneMgr_;
295  }
296
297  BulletManager* RunManager::getBulletManagerPtr()
298  {
299    return bulletManager_;
300  }
301
302  int RunManager::getAmmunitionID(const Ogre::String &ammoName)
303  {
304    Ogre::String ammoTypes[] = { "Energy Cell", "Barrel", "Lead Shot" };
305    int ammoTypesLength = 3;
306
307    for (int i = 0; i < ammoTypesLength; i++)
308    {
309      if (ammoTypes[i] == ammoName)
310        return i;
311    }
312    return -1;
313  }
314
315  int RunManager::getNumberOfAmmos()
316  {
317    return 3;
318  }
319
320
321  /**
322  * Adjust mouse clipping area.
323  * This method is called by Ogre without regards of tick()!
324  * Avoid doing too much in this call.
325  * @param rw render window
326  */
327  void RunManager::windowResized(RenderWindow* rw)
328  {
329    unsigned int width, height, depth;
330    int left, top;
331    rw->getMetrics(width, height, depth, left, top);
332
333    const OIS::MouseState &ms = mouse_->getMouseState();
334    ms.width = width;
335    ms.height = height;
336  }
337
338
339  /**
340  * Unattach OIS before window shutdown (very important under Linux).
341  * Again, avoid computing a lot in this function.
342  * @param rw Render Window
343  */
344  void RunManager::windowClosed(RenderWindow* rw)
345  {
346    //Only close for window that created OIS (the main window in these demos)
347    if( rw == window_ )
348    {
349      if( inputManager_ )
350      {
351        inputManager_->destroyInputObject( mouse_ );
352        inputManager_->destroyInputObject( keyboard_ );
353        inputManager_->destroyInputObject( joystick_ );
354
355        OIS::InputManager::destroyInputSystem(inputManager_);
356        inputManager_ = 0;
357      }
358    }
359  }
360
361  /**
362  * Processes the Keyboard input.
363  * TODO: Use listeners to improve performance.
364  * A lookup table should be implemented to bind any key to a specific action.
365  * @return Return true to keep rendering
366  */
367  bool RunManager::processUnbufferedKeyInput()
368  {
369    using namespace OIS;
370
371    if(keyboard_->isKeyDown(KC_A) || keyboard_->isKeyDown(KC_LEFT))
372      playerShip_->setSideThrust(1);
373    else if(keyboard_->isKeyDown(KC_D) || keyboard_->isKeyDown(KC_RIGHT))
374      playerShip_->setSideThrust(-1);
375    else
376      playerShip_->setSideThrust(0);
377
378    if(keyboard_->isKeyDown(KC_UP) || keyboard_->isKeyDown(KC_W) )
379      playerShip_->setMainThrust(1);
380    else if(keyboard_->isKeyDown(KC_DOWN) || keyboard_->isKeyDown(KC_S) )
381      playerShip_->setMainThrust(-1);
382    else
383      playerShip_->setMainThrust(0);
384
385    if (keyboard_->isKeyDown(KC_C))
386      playerShip_->setYThrust(1);
387    else if (keyboard_->isKeyDown(KC_SPACE))
388      playerShip_->setYThrust(-1);
389    else
390      playerShip_->setYThrust(0);
391
392    if (keyboard_->isKeyDown(KC_G))
393      playerShip_->getMainWeapon()->addAction(BaseWeapon::RELOAD);
394
395    if( keyboard_->isKeyDown(KC_ESCAPE) || keyboard_->isKeyDown(KC_Q) )
396      return false;
397
398    if( keyboard_->isKeyDown(KC_F) && timeUntilNextToggle_ <= 0 )
399    {
400      statsOn_ = !statsOn_;
401      timeUntilNextToggle_ = 1;
402    }
403
404    if(keyboard_->isKeyDown(KC_SYSRQ) && timeUntilNextToggle_ <= 0)
405    {
406      std::ostringstream ss;
407      ss << "screenshot_" << ++screenShotCounter_ << ".png";
408      window_->writeContentsToFile(ss.str());
409      timeUntilNextToggle_ = 0.5;
410    }
411
412    // Return true to continue rendering
413    return true;
414  }
415
416
417  /**
418  * Processes the Mouse input.
419  * TODO: Use listeners to improve performance.
420  * A lookup table should be implemented to bind ANY button or movement
421  * to a specific action.
422  * @return Return true to keep rendering
423  */
424  bool RunManager::processUnbufferedMouseInput()
425  {
426    using namespace OIS;
427
428    const MouseState &ms = mouse_->getMouseState();
429
430    if (ms.buttonDown(MB_Left))
431      playerShip_->getMainWeapon()->primaryFireRequest();
432
433    if (ms.buttonDown(MB_Right))
434      playerShip_->getMainWeapon()->secondaryFireRequest();
435
436    playerShip_->turnUpAndDown(Radian(ms.Y.rel * mouseSensitivity_));
437    playerShip_->turnLeftAndRight(Radian(ms.X.rel * mouseSensitivity_));
438
439    // keep rendering
440    return true;
441  }
442
443  /**
444  * Show an overlay desired.
445  * @param show Whether or not to show the debug overlay
446  */
447  void RunManager::showDebugOverlay(bool show)
448  {
449    /*if (hud_)
450    {
451      if (show)
452        hud_->show();
453      else
454        hud_->hide();
455    }*/
456  }
457
458
459  /**
460  * Simple camera creator.
461  * playerShip_Node->attachObject(camera_) should not be here! This is what
462  * the camera manager is for. Right now, this method should do just fine,
463  * setting the cam behind the ship.
464  */
465  void RunManager::createCamera()
466  {
467    camera_ = sceneMgr_->createCamera("PlayerCam");
468    playerShip_->getRootNode()->getSceneNode()->attachObject(camera_);
469    camera_->setNearClipDistance(5);
470    camera_->setPosition(Vector3(0,10,500));
471    camera_->lookAt(Vector3(0,0,0));
472  }
473
474  /**
475  * Simple viewport creator.
476  * For now the viewport uses the entire render window and is based on the one
477  * camera created so far.
478  */
479  void RunManager::createViewports()
480  {
481    // Create one viewport, entire window
482    Viewport* vp = window_->addViewport(camera_);
483    vp->setBackgroundColour(ColourValue(0,0,0));
484
485    // Alter the camera aspect ratio to match the viewport
486    camera_->setAspectRatio(
487      Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
488  }
489
490
491  RunManager* RunManager::createSingleton()
492  {
493    if (singletonPtr_s)
494      return NULL;
495    singletonPtr_s = new RunManager();
496    return singletonPtr_s;
497  }
498
499  void RunManager::destroySingleton()
500  {
501    if (singletonPtr_s)
502      delete singletonPtr_s;
503  }
504
505
506  RunManager& RunManager::getSingleton()
507  {
508    return *singletonPtr_s;
509  }
510
511  RunManager* RunManager::getSingletonPtr()
512  {
513    return singletonPtr_s;
514  }
515
516}
Note: See TracBrowser for help on using the repository browser.