From ec5793be7f1c7a3f557b9ac84b80a7fba17477b7 Mon Sep 17 00:00:00 2001 From: James Turk Date: Sun, 14 Aug 2005 07:40:12 +0000 Subject: [PATCH] fixed Application unpausing/ altered timeDelta code --- CHANGELOG.txt | 7 +++- include/Application.hpp | 29 +++++++------ src/Application.cpp | 77 +++++++++++++++++++++++++++++------ test/State_test.cpp | 90 ++++++++++++++++++++++++++++++----------- 4 files changed, 152 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index cc44aab..43e3918 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,5 @@ Changelog for Photon -$Id: CHANGELOG.txt,v 1.7 2005/08/12 06:26:00 cozman Exp $ +$Id: CHANGELOG.txt,v 1.8 2005/08/14 07:40:12 cozman Exp $ ! : Major Changes (potentially breaking existing code) + : New Features @@ -8,13 +8,18 @@ $Id: CHANGELOG.txt,v 1.7 2005/08/12 06:26:00 cozman Exp $ 0.0.2 ! Removed InputListener, opting to move features into State class. + ! Changed Application::getElapsedTime to Application::getTimeDelta + Code::Blocks and Dev-C++ support + Addition of a State stack allowing for applications to fall back to the previous state when done with a particular state. + Notification of mouse wheel events added. + + Addition of a State test/example program. + + Addition of Application::setTimeDeltaMode ability to set how time delta + is calculated. (actual/average currently supported). * Fixed X11 fullscreen mode * Removed ALUT dependencies by adding custom WAV loading code * Mouse move events now give relative position. + * Properly handle regain of focus, unpause Application's timer. 0.0.1 - Released 2005-08-08 + State-based design that allows easy creation of applications by simply diff --git a/include/Application.hpp b/include/Application.hpp index 47b1efe..0530b05 100644 --- a/include/Application.hpp +++ b/include/Application.hpp @@ -5,13 +5,14 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.hpp,v 1.18 2005/08/12 06:26:00 cozman Exp $ +// $Id: Application.hpp,v 1.19 2005/08/14 07:40:13 cozman Exp $ #ifndef PHOTON_APPLICATION_HPP #define PHOTON_APPLICATION_HPP #include #include +#include #include #include @@ -24,7 +25,12 @@ #include "audio/AudioCore.hpp" #include "util/Singleton.hpp" -#include +enum TimeDeltaMode +{ + TDM_ACTUAL, + TDM_AVERAGE, + TDM_FIXED +}; namespace photon { @@ -256,19 +262,9 @@ public: // been running. scalar getTime(); - // Function: getElapsedTime - // Finds the amount of time passed between frames, useful for time-based - // movement. - // - // Returns: - // Time between current frame and last frame. (1/()) - double getElapsedTime(); - - // Function: getFramerate - // Gets number of frames per second the application is currently processing - // - // Returns: - // Current frames per second. + void setTimeDeltaMode(TimeDeltaMode mode, int numFrames=0); + void setTimeDeltaMode(TimeDeltaMode mode, scalar fixedStep); + double getTimeDelta(); double getFramerate(); // Group: State Management @@ -353,6 +349,7 @@ private: scalar pausedTime_; scalar secPerFrame_; scalar lastUpdate_; + std::valarray frameTimes_; }; // VideoTask, does the updating work of OpenGL @@ -402,6 +399,8 @@ private: uint displayHeight_; uint viewportWidth_; uint viewportHeight_; + + TimeDeltaMode timeDeltaMode_; // tasks shared_ptr updateTask_; diff --git a/src/Application.cpp b/src/Application.cpp index e108a33..a34b7d4 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.cpp,v 1.23 2005/08/12 06:26:00 cozman Exp $ +// $Id: Application.cpp,v 1.24 2005/08/14 07:40:13 cozman Exp $ #include "Application.hpp" @@ -22,6 +22,8 @@ #include "audio/AudioCore.hpp" #include "util/filesys/filesys.hpp" +#include + namespace photon { @@ -35,6 +37,7 @@ Application::Application(const std::string& arg0) : photonVer_(0,0,1), // this is the current version displayWidth_(0), displayHeight_(0), viewportWidth_(0), viewportHeight_(0), + timeDeltaMode_(TDM_ACTUAL), updateTask_(new UpdateTask()), stateUpdate_(new StateUpdate()), stateRender_(new StateRender()) @@ -269,14 +272,56 @@ scalar Application::getTime() return glfwGetTime() - updateTask_->pausedTime_; } -double Application::getElapsedTime() +void Application::setTimeDeltaMode(TimeDeltaMode mode, int numFrames) { - return updateTask_->secPerFrame_; + // if the mode is fixed should have speficied a scalar fixedStep + if(mode == TDM_FIXED) + { + throw PreconditionException("setTimeDeltaMode called without fixedStep" + "but with TDM_FIXED mode."); + } + // if the mode is average should have at least two frames to average + if(mode == TDM_AVERAGE && numFrames <= 1) + { + throw PreconditionException("setTimeDeltaMode called with TDM_AVERAGE" + "but numFrames <= 1"); + } + + timeDeltaMode_ = mode; + updateTask_->frameTimes_.resize(numFrames); +} + +void Application::setTimeDeltaMode(TimeDeltaMode mode, scalar fixedStep) +{ + // if the mode is not fixed, should have specified a non-scalar numFrames + if(mode != TDM_FIXED) + { + throw PreconditionException("setTimeDeltaMode called with fixedStep but" + "mode not TDM_FIXED."); + } + + timeDeltaMode_ = mode; + //fixedStep_ = fixedStep; +} + +double Application::getTimeDelta() +{ + switch(timeDeltaMode_) + { + case TDM_ACTUAL: + return updateTask_->secPerFrame_; + case TDM_AVERAGE: + return updateTask_->frameTimes_.sum()/updateTask_->frameTimes_.size(); + case TDM_FIXED: + return 0.01;//fixedStep_; + default: + return 0; + } } double Application::getFramerate() { - return 1/updateTask_->secPerFrame_; + return 1/getTimeDelta(); } // States ////////////////////////////////////////////////////////////////////// @@ -458,23 +503,31 @@ Application::UpdateTask::UpdateTask() : mouseX_(0), mouseY_(0), active_(false), timerPaused_(false), unpauseOnActive_(false), lastPause_(0), pausedTime_(0), - secPerFrame_(0), lastUpdate_(0) + secPerFrame_(0), lastUpdate_(0), frameTimes_(0) { } void Application::UpdateTask::update() { - scalar curTime = glfwGetTime() - pausedTime_; + static uint frameIndex(0); + + scalar curTime( glfwGetTime() - pausedTime_ ); + + // keep track of time between frames + if(++frameIndex >= frameTimes_.size()) + { + frameIndex = 0; + } + secPerFrame_ = frameTimes_[frameIndex] = curTime-lastUpdate_; + + lastUpdate_ = curTime; + + glfwSwapBuffers(); // update the display here instead of Application (since it belongs to glfw) - glfwSwapBuffers(); glfwGetMousePos(&mouseX_, &mouseY_); - // keep track of time between frames - secPerFrame_ = curTime-lastUpdate_; - lastUpdate_ = curTime; - // quit on window closing or Alt-F4/Alt-X if(!glfwGetWindowParam(GLFW_OPENED) || ( (glfwGetKey(GLFW_KEY_LALT) || glfwGetKey(GLFW_KEY_RALT)) && @@ -495,7 +548,7 @@ void Application::UpdateTask::update() } else if(active_ && unpauseOnActive_) { - timerPaused_ = true; + timerPaused_ = false; pausedTime_ += curTime - lastPause_; unpauseOnActive_ = false; } diff --git a/test/State_test.cpp b/test/State_test.cpp index 2e3fcf5..18af780 100644 --- a/test/State_test.cpp +++ b/test/State_test.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: State_test.cpp,v 1.2 2005/08/12 07:21:51 cozman Exp $ +// $Id: State_test.cpp,v 1.3 2005/08/14 07:40:13 cozman Exp $ #include "photon.hpp" using namespace photon; @@ -15,12 +15,37 @@ using namespace photon; class Demo2D : public State { + +struct MovingRect +{ + math::Rect pos; + math::Vector2 vel; +}; + public: Demo2D() { + util::RandGen rand; + video::Image::addResource("robo","data/robo.png"); + + roboImg.open("robo"); - robo.open("robo"); + robots.resize(5); + + for(std::vector::iterator robot( robots.begin() ); + robot != robots.end(); + ++robot) + { + robot->pos.moveTo(math::Point2( + rand.genRand(0.,800-roboImg.getWidth()), + rand.genRand(0.,600-roboImg.getHeight()))); + robot->pos.resize(roboImg.getWidth(), roboImg.getHeight()); + + // generates -400 or +400 + robot->vel.x = rand.genRandSign()*400; + robot->vel.y = rand.genRandSign()*400; + } Application::getInstance().setOrthoView(); } @@ -35,17 +60,51 @@ public: void update() { - + for(std::vector::iterator robot( robots.begin() ); + robot != robots.end(); + ++robot) + { + math::Vector2 vel(robot->vel * + Application::getInstance().getTimeDelta()); + + robot->pos.moveRel(vel.x, vel.y); + + if(robot->pos.getLeft() < 0 || robot->pos.getRight() > 800) + { + robot->vel.x *= -1; + } + if(robot->pos.getTop() < 0 || robot->pos.getBottom() > 600) + { + robot->vel.y *= -1; + } + + // check for robot-robot collisions + for(std::vector::iterator robot2( robot ); + robot2 != robots.end(); + ++robot2) + { + if(robot->pos.intersects(robot2->pos)) + { + std::swap(robot->vel, robot2->vel); + } + } + + } } void render() { - robo.draw(0,0); + for(std::vector::iterator robot( robots.begin() ); + robot != robots.end(); + ++robot) + { + roboImg.draw(robot->pos.getX(), robot->pos.getY()); + } } private: - video::Image robo; - math::Point2 location; + video::Image roboImg; + std::vector robots; }; class Demo3D : public State @@ -122,9 +181,7 @@ public: void update() { - scalar dt = Application::getInstance().getElapsedTime(); - // dt is sporadic and results in terrible choppiness - //dt = 0.01; + scalar dt = Application::getInstance().getTimeDelta(); xRot += 30*dt; yRot += 40*dt; @@ -181,6 +238,7 @@ public: } app.setOrthoView(); + app.setTimeDeltaMode(TDM_AVERAGE, 250); } void onMouseButtonPress(MouseButton button) @@ -202,11 +260,6 @@ public: } } - void update() - { - std::cout << app.getElapsedTime() << "\n"; - } - void render() { video::Color c( font.getColor() ); @@ -228,15 +281,9 @@ public: } - - void onPause() - { - //setActive(false); - } void onResume() { - //setActive(true); font.setColor(video::Color(rand.genRand(0,255), rand.genRand(0,255), rand.genRand(0,255))); app.setOrthoView(); @@ -254,9 +301,6 @@ int PhotonMain(const StrVec& args) { // create window Application::getInstance().createDisplay(800,600,32,0,0,false); - - // be sure to add FPSDisplayTask - Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); // add archives to search path util::filesys::addToSearchPath("data/fonts.zip");