Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Mar 21, 2008, 6:14:31 PM (17 years ago)
Author:
rgrieder
Message:
  • merged all changes in the input branch into this one
  • moved Tickable to core (would have created circular library dependencies)
  • exported OrxListener to a separate file, soon to be deleted
changed
, &&, XOR back to or, and, xor because I found the necessary include file for VC++
  • created abortRequest() in Orxonox.cc to call for a smooth end of the game (an alternative would be to make tick() return a boolean, like it is with frameStarted())
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/network/src/orxonox/Orxonox.cc

    r905 r917  
    4444#include <OgreOverlay.h>
    4545#include <OgreOverlayManager.h>
     46#include <OgreTimer.h>
     47#include <OgreWindowEventUtilities.h>
    4648
    4749//****** OIS *******
     
    5658#include "util/Sleep.h"
    5759
    58 // loader and audio
    59 //#include "loader/LevelLoader.h"
     60// audio
    6061#include "audio/AudioManager.h"
    6162
     
    6970
    7071// objects
    71 #include "objects/Tickable.h"
    7272#include "tools/Timer.h"
    73 #include "objects/NPC.h"
     73#include "tools/OrxListener.h"
    7474#include "core/ArgReader.h"
     75#include "core/Debug.h"
    7576#include "core/Factory.h"
    76 #include "core/Debug.h"
    7777#include "core/Loader.h"
     78#include "core/Tickable.h"
    7879#include "hud/HUD.h"
    7980#include "objects/weapon/BulletManager.h"
     
    8485namespace orxonox
    8586{
    86    // put this in a seperate Class or solve the problem in another fashion
    87   class OrxListener : public Ogre::FrameListener
    88   {
    89     public:
    90       OrxListener(OIS::Keyboard *keyboard, audio::AudioManager*  auMan, gameMode mode)
    91       {
    92         mKeyboard = keyboard;
    93         mode_=mode;
    94         auMan_ = auMan;
    95       }
    96 
    97       bool frameStarted(const Ogre::FrameEvent& evt)
    98       {
    99         auMan_->update();
    100         updateAI();
    101 
    102 //         if(mode_ == SERVER)
    103 //           server_g->tick(evt.timeSinceLastFrame);
    104 //         else if(mode_ == CLIENT)
    105 //           client_g->tick(evt.timeSinceLastFrame);
    106 
    107         usleep(10);
    108 
    109         if(mode_!=CLIENT){
    110         mKeyboard->capture();
    111         return !mKeyboard->isKeyDown(OIS::KC_ESCAPE);
    112         }else
    113           return true;
    114       }
    115 
    116       void updateAI()
    117       {
    118         for(Iterator<NPC> it = ObjectList<NPC>::start(); it; ++it)
    119         {
    120           it->update();
    121         }
    122       }
    123 
    124     private:
    125       gameMode mode_;
    126       OIS::Keyboard *mKeyboard;
    127       audio::AudioManager*  auMan_;
    128   };
    129 
    130   // init static singleton reference of Orxonox
     87  /// init static singleton reference of Orxonox
    13188  Orxonox* Orxonox::singletonRef_ = NULL;
    13289
     
    13895    this->ogre_ = new GraphicsEngine();
    13996    this->dataPath_ = "";
    140 //    this->loader_ = 0;
    14197    this->auMan_ = 0;
    14298    this->singletonRef_ = 0;
     
    146102    this->frameListener_ = 0;
    147103    this->root_ = 0;
     104    // turn frame smoothing on by setting a value different from 0
     105    this->frameSmoothingTime_ = 0.0f;
     106    this->bAbort_ = false;
    148107  }
    149108
     
    159118   * initialization of Orxonox object
    160119   * @param argc argument counter
    161    * @param argv list of arguments
     120   * @param argv list of argumenst
    162121   * @param path path to config (in home dir or something)
    163122   */
     
    281240    //TODO: destroy and destruct everything and print nice error msg
    282241    delete this;
     242  }
     243
     244  /**
     245    Asks the mainloop nicely to abort.
     246  */
     247  void Orxonox::abortRequest()
     248  {
     249    bAbort_ = true;
    283250  }
    284251
     
    365332  }
    366333
    367   /**
    368    *
    369    * @param
    370    */
    371334  void Orxonox::createScene(void)
    372335  {
     
    383346
    384347    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);
     348    //HUD* orxonoxHud;
     349    orxonoxHUD_ = new HUD();
     350    orxonoxHUD_->setEnergyValue(20);
     351    orxonoxHUD_->setEnergyDistr(20,20,60);
    389352    hudOverlay->show();
    390353
     
    398361
    399362
    400   /**
    401    *
    402    */
    403363  void Orxonox::setupScene()
    404364  {
     
    451411  void Orxonox::createFrameListener()
    452412  {
    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_);
     413    frameListener_ = new OrxListener(keyboard_, auMan_, mode_);
    462414  }
    463415
     
    477429      ms.height = height;
    478430    }
    479     ogre_->getRoot()->startRendering();
     431    mainLoop();
     432  }
     433
     434  /**
     435    Main loop of the orxonox game.
     436    This is a new solution, using the ogre engine instead of beeing used by it.
     437    An alternative solution would be to simply use the timer of the Root object,
     438    but that implies using Ogre in any case. There would be no way to test
     439    our code without the help of the root object.
     440    There's even a chance that we can dispose of the root object entirely
     441    in server mode.
     442    About the loop: The design is almost exactly like the one in ogre, so that
     443    if any part of ogre registers a framelisteners, it will still behave
     444    correctly. Furthermore I have taken over the time smoothing feature from
     445    ogre. If turned on (see orxonox constructor), it will calculate the dt_n by
     446    means of the recent most dt_n-1, dt_n-2, etc.
     447  */
     448  void Orxonox::mainLoop()
     449  {
     450    // use the ogre timer class to measure time.
     451    Ogre::Timer *timer = new Ogre::Timer();
     452    timer->reset();
     453
     454    // Contains the times of recently fired events
     455    std::deque<unsigned long> eventTimes[3];
     456    // Clear event times
     457    for (int i = 0; i < 3; ++i)
     458      eventTimes[i].clear();
     459
     460          while (!bAbort_)
     461          {
     462                  // Pump messages in all registered RenderWindows
     463      Ogre::WindowEventUtilities::messagePump();
     464
     465      // get current time
     466      unsigned long now = timer->getMilliseconds();
     467
     468      // create an event to pass to the frameStarted method in ogre
     469      Ogre::FrameEvent evt;
     470      evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
     471      evt.timeSinceLastFrame = calculateEventTime(now, eventTimes[1]);
     472
     473      // show the current time in the HUD
     474      orxonoxHUD_->setTime((int)now, 0);
     475
     476      // don't forget to call _fireFrameStarted in ogre to make sure
     477      // everything goes smoothly
     478      if (!ogre_->getRoot()->_fireFrameStarted(evt))
     479        break;
     480
     481      // Iterate through all Tickables and call their tick(dt) function
     482      for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; )
     483        (it++)->tick((float)evt.timeSinceLastFrame);
     484
     485      if (mode_ != SERVER)
     486      {
     487        // only render in non-server mode
     488        ogre_->getRoot()->_updateAllRenderTargets();
     489      }
     490
     491      // get current time
     492      now = timer->getMilliseconds();
     493
     494      // create an event to pass to the frameEnded method in ogre
     495      evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
     496      evt.timeSinceLastFrame = calculateEventTime(now, eventTimes[2]);
     497
     498      // again, just to be sure ogre works fine
     499      if (!ogre_->getRoot()->_fireFrameEnded(evt))
     500        break;
     501          }
     502  }
     503
     504  /**
     505    Method for calculating the average time between recently fired events.
     506    Code directly taken from OgreRoot.cc
     507    @param now The current time in ms.
     508    @param type The type of event to be considered.
     509  */
     510  float Orxonox::calculateEventTime(unsigned long now, std::deque<unsigned long> &times)
     511  {
     512    // Calculate the average time passed between events of the given type
     513    // during the last mFrameSmoothingTime seconds.
     514
     515    times.push_back(now);
     516
     517    if(times.size() == 1)
     518      return 0;
     519
     520    // Times up to mFrameSmoothingTime seconds old should be kept
     521    unsigned long discardThreshold =
     522      static_cast<unsigned long>(frameSmoothingTime_ * 1000.0f);
     523
     524    // Find the oldest time to keep
     525    std::deque<unsigned long>::iterator it = times.begin(),
     526      end = times.end()-2; // We need at least two times
     527    while(it != end)
     528    {
     529      if (now - *it > discardThreshold)
     530        ++it;
     531      else
     532        break;
     533    }
     534
     535    // Remove old times
     536    times.erase(times.begin(), it);
     537
     538    return (float)(times.back() - times.front()) / ((times.size()-1) * 1000);
    480539  }
    481540}
Note: See TracChangeset for help on using the changeset viewer.