Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 568 was 513, checked in by nicolasc, 17 years ago

added copyright notice
network still need to be done

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