Răsfoiți Sursa

Fixed issue where time would not progress properly in animations when the game framerate was significantly high (greater than several hundred FPS).

Changed the method signatures of Game::getAbsoluteTime, Game::getGameTime, Game::update and Game::render to use floating point instead of integers in order to compute fractions of milliseconds of elapsed time (to support the above fix).
Steve Grenier 13 ani în urmă
părinte
comite
ee61e40cc8

+ 15 - 15
gameplay/src/AnimationClip.cpp

@@ -84,7 +84,7 @@ unsigned long AnimationClip::getEndTime() const
     return _endTime;
 }
 
-unsigned long AnimationClip::getElaspedTime() const
+float AnimationClip::getElaspedTime() const
 {
     return _elapsedTime;
 }
@@ -120,7 +120,7 @@ void AnimationClip::setActiveDuration(unsigned long duration)
     else
     {
         _activeDuration = _duration;
-        _repeatCount = (float) _activeDuration / (float) _duration;
+        _repeatCount = (float)_activeDuration / (float)_duration;
     }
 }
 
@@ -242,7 +242,7 @@ void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
     // Set and intiliaze this clip to fade out
     setClipStateBit(CLIP_IS_FADING_OUT_STARTED_BIT);
     setClipStateBit(CLIP_IS_FADING_OUT_BIT);
-    _crossFadeOutElapsed = 0L;
+    _crossFadeOutElapsed = 0.0f;
     _crossFadeOutDuration = duration;
     
     // If this clip is currently not playing, we should start playing it.
@@ -282,7 +282,7 @@ void AnimationClip::addListener(AnimationClip::Listener* listener, unsigned long
                 // otherwise, it will just be set the next time the clip gets played.
                 if (isClipStateBitSet(CLIP_IS_PLAYING_BIT))
                 {
-                    unsigned long currentTime = _elapsedTime % _duration;
+                    float currentTime = fmodf(_elapsedTime, (float)_duration);
                     GP_ASSERT(**_listenerItr || *_listenerItr == _listeners->end());
                     if ((_speed >= 0.0f && currentTime < eventTime && (*_listenerItr == _listeners->end() || eventTime < (**_listenerItr)->_eventTime)) || 
                         (_speed <= 0 && currentTime > eventTime && (*_listenerItr == _listeners->begin() || eventTime > (**_listenerItr)->_eventTime)))
@@ -313,7 +313,7 @@ void AnimationClip::addEndListener(AnimationClip::Listener* listener)
     _endListeners->push_back(listener);
 }
 
-bool AnimationClip::update(unsigned long elapsedTime)
+bool AnimationClip::update(float elapsedTime)
 {
     if (isClipStateBitSet(CLIP_IS_PAUSED_BIT))
     {
@@ -338,9 +338,9 @@ bool AnimationClip::update(unsigned long elapsedTime)
             _elapsedTime = _activeDuration + _elapsedTime;
     }
 
-    unsigned long currentTime = 0L;
+    float currentTime = 0.0f;
     // Check to see if clip is complete.
-    if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0.0f && _elapsedTime >= (long) _activeDuration) || (_speed <= 0.0f && _elapsedTime <= 0L)))
+    if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0.0f && _elapsedTime >= _activeDuration) || (_speed <= 0.0f && _elapsedTime <= 0.0f)))
     {
         resetClipStateBit(CLIP_IS_STARTED_BIT);
         
@@ -349,27 +349,27 @@ bool AnimationClip::update(unsigned long elapsedTime)
             // If _duration == 0, we have a "pose". Just set currentTime to 0.
             if (_duration == 0)
             {
-                currentTime = 0L;
+                currentTime = 0.0f;
             }
             else
             {
-                currentTime = _activeDuration % _duration; // Get's the fractional part of the final repeat.
-                if (currentTime == 0L)
+                currentTime = (float)(_activeDuration % _duration); // Get's the fractional part of the final repeat.
+                if (currentTime == 0.0f)
                     currentTime = _duration;
             }
         }
         else
         {
-            currentTime = 0L; // If we are negative speed, the end value should be 0.
+            currentTime = 0.0f; // If we are negative speed, the end value should be 0.
         }
     }
     else
     {
         // If _duration == 0, we have a "pose". Just set currentTime to 0.
         if (_duration == 0)
-            currentTime = 0L;
+            currentTime = 0.0f;
         else // Gets portion/fraction of the repeat.
-            currentTime = _elapsedTime % _duration;
+            currentTime = fmodf(_elapsedTime, _duration);
     }
 
     // Notify any listeners of Animation events.
@@ -406,7 +406,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
     // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
     GP_ASSERT(_animation);
     GP_ASSERT(_animation->_duration > 0);
-    float percentComplete = (float)(_startTime + currentTime) / (float) _animation->_duration;
+    float percentComplete = ((float)_startTime + currentTime) / (float)_animation->_duration;
     
     if (isClipStateBitSet(CLIP_IS_FADING_OUT_BIT))
     {
@@ -428,7 +428,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
         if (_crossFadeOutElapsed < _crossFadeOutDuration)
         {
             // Calculate this clip's blend weight.
-            float tempBlendWeight = (float) (_crossFadeOutDuration - _crossFadeOutElapsed) / (float) _crossFadeOutDuration;
+            float tempBlendWeight = ((float)_crossFadeOutDuration - _crossFadeOutElapsed) / (float)_crossFadeOutDuration;
             
             // If this clip is fading in, adjust the crossfade clip's weight to be a percentage of your current blend weight
             if (isClipStateBitSet(CLIP_IS_FADING_IN_BIT))

+ 8 - 7
gameplay/src/AnimationClip.h

@@ -103,7 +103,7 @@ public:
      *
      * @return The elapsed time of the AnimationClip (in milliseconds).
      */
-    unsigned long getElaspedTime() const;
+    float getElaspedTime() const;
 
     /**
      * Sets the AnimationClip's repeat count. Overrides repeat duration.
@@ -126,7 +126,7 @@ public:
      *
      * Use REPEAT_INDEFINITE to play the AnimationClip indefinitely.
      *
-     * @param duration The active duration that is set on the AnimationClip.
+     * @param duration The active duration that is set on the AnimationClip, in milliseconds.
      */
     void setActiveDuration(unsigned long duration);
 
@@ -140,7 +140,7 @@ public:
     /**
      * Gets the AnimationClip's duration.
      *
-     * @return the AnimationClip's duration.
+     * @return the AnimationClip's duration, in milliseconds.
      */
     unsigned long getDuration() const;
 
@@ -283,7 +283,7 @@ private:
     /**
      * Updates the animation with the elapsed time.
      */
-    bool update(unsigned long elapsedTime);
+    bool update(float elapsedTime);
 
     /**
      * Handles when the AnimationClip begins.
@@ -319,10 +319,10 @@ private:
     float _repeatCount;                                 // The clip's repeat count.
     unsigned long _activeDuration;                      // The active duration of the clip.
     float _speed;                                       // The speed that the clip is playing. Default is 1.0. Negative goes in reverse.
-    unsigned long _timeStarted;                         // The game time when this clip was actually started.
-    long _elapsedTime;                                  // Time elapsed while the clip is running.
+    double _timeStarted;                                // The game time when this clip was actually started.
+    float _elapsedTime;                                 // Time elapsed while the clip is running.
     AnimationClip* _crossFadeToClip;                    // The clip to cross fade to.
-    unsigned long _crossFadeOutElapsed;                 // The amount of time that has elapsed for the crossfade.
+    float _crossFadeOutElapsed;                         // The amount of time that has elapsed for the crossfade.
     unsigned long _crossFadeOutDuration;                // The duration of the cross fade.
     float _blendWeight;                                 // The clip's blendweight.
     std::vector<AnimationValue*> _values;               // AnimationValue holder.
@@ -333,4 +333,5 @@ private:
 };
 
 }
+
 #endif

+ 1 - 1
gameplay/src/AnimationController.cpp

@@ -93,7 +93,7 @@ void AnimationController::unschedule(AnimationClip* clip)
         _state = IDLE;
 }
 
-void AnimationController::update(long elapsedTime)
+void AnimationController::update(float elapsedTime)
 {
     if (_state != RUNNING)
         return;

+ 1 - 1
gameplay/src/AnimationController.h

@@ -94,7 +94,7 @@ private:
     /**
      * Callback for when the controller receives a frame update event.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
     
     State _state;                                 // The current state of the AnimationController.
     std::list<AnimationClip*> _runningClips;      // A list of running AnimationClips.

+ 1 - 1
gameplay/src/AudioController.cpp

@@ -91,7 +91,7 @@ void AudioController::resume()
     }
 }
 
-void AudioController::update(long elapsedTime)
+void AudioController::update(float elapsedTime)
 {
     AudioListener* listener = AudioListener::getInstance();
     if (listener)

+ 1 - 1
gameplay/src/AudioController.h

@@ -52,7 +52,7 @@ private:
     /**
      * Controller update.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
 
     ALCdevice* _alcDevice;

+ 2 - 0
gameplay/src/Base.h

@@ -39,6 +39,8 @@ using std::size_t;
 using std::min;
 using std::max;
 using std::modf;
+using std::fmodf;
+using std::fmodl;
 
 // Common
 #ifndef NULL

+ 8 - 8
gameplay/src/Container.cpp

@@ -632,9 +632,9 @@ Layout::Type Container::getLayoutType(const char* layoutString)
 void Container::updateScroll()
 {
     // Update Time.
-    static long lastFrameTime = Game::getGameTime();
-    long frameTime = Game::getGameTime();
-    long elapsedTime = (frameTime - lastFrameTime);
+    double lastFrameTime = Game::getGameTime();
+    double frameTime = Game::getGameTime();
+    float elapsedTime = (float)(frameTime - lastFrameTime);
     lastFrameTime = frameTime;
 
     const Theme::Border& containerBorder = getBorder(_state);
@@ -802,7 +802,7 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
 
     case Touch::TOUCH_RELEASE:
         _scrolling = false;
-        long timeSinceLastMove = Game::getAbsoluteTime() - _scrollingLastTime;
+        float timeSinceLastMove = (float)(Game::getAbsoluteTime() - _scrollingLastTime);
         if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
         {
             _scrollingVelocity.set(0, 0);
@@ -812,10 +812,10 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         int dx = _scrollingLastX - _scrollingFirstX;
         int dy = _scrollingLastY - _scrollingFirstY;
 
-        long timeTakenX = Game::getAbsoluteTime() - _scrollingStartTimeX;
-        float elapsedSecsX = (float)timeTakenX * 0.001f;
-        long timeTakenY = Game::getAbsoluteTime() - _scrollingStartTimeY;
-        float elapsedSecsY = (float)timeTakenY * 0.001f;
+        float timeTakenX = (float)(Game::getAbsoluteTime() - _scrollingStartTimeX);
+        float elapsedSecsX = timeTakenX * 0.001f;
+        float timeTakenY = (float)(Game::getAbsoluteTime() - _scrollingStartTimeY);
+        float elapsedSecsY = timeTakenY * 0.001f;
 
         float vx = dx;
         float vy = dy;

+ 3 - 3
gameplay/src/Container.h

@@ -391,15 +391,15 @@ protected:
     /** 
      * Time we started scrolling in the x
      */ 
-    long _scrollingStartTimeX;
+    double _scrollingStartTimeX;
     /** 
      * Time we started scrolling in the y
      */ 
-    long _scrollingStartTimeY;
+    double _scrollingStartTimeY;
     /** 
      * The last time we were scrolling
      */
-    long _scrollingLastTime;
+    double _scrollingLastTime;
     /** 
      * Speed to continue scrolling at after touch release.
      */ 

+ 16 - 14
gameplay/src/Game.cpp

@@ -13,8 +13,8 @@ namespace gameplay
 {
 
 static Game* __gameInstance = NULL;
-long Game::_pausedTimeLast = 0L;
-long Game::_pausedTimeTotal = 0L;
+double Game::_pausedTimeLast = 0.0;
+double Game::_pausedTimeTotal = 0.0;
 
 Game::Game() 
     : _initialized(false), _state(UNINITIALIZED), 
@@ -48,12 +48,12 @@ Game* Game::getInstance()
     return __gameInstance;
 }
 
-long Game::getAbsoluteTime()
+double Game::getAbsoluteTime()
 {
     return Platform::getAbsoluteTime();
 }
 
-long Game::getGameTime()
+double Game::getGameTime()
 {
     return Platform::getAbsoluteTime() - _pausedTimeTotal;
 }
@@ -193,9 +193,9 @@ void Game::frame()
         GP_ASSERT(_physicsController);
 
         // Update Time.
-        static long lastFrameTime = Game::getGameTime();
-        long frameTime = Game::getGameTime();
-        long elapsedTime = (frameTime - lastFrameTime);
+        static double lastFrameTime = Game::getGameTime();
+        double frameTime = getGameTime();
+        float elapsedTime = (frameTime - lastFrameTime);
         lastFrameTime = frameTime;
 
         // Update the scheduled and running animations.
@@ -206,11 +206,13 @@ void Game::frame()
     
         // Update the physics.
         _physicsController->update(elapsedTime);
+
         // Application Update.
         update(elapsedTime);
 
         // Audio Rendering.
         _audioController->update(elapsedTime);
+
         // Graphics Rendering.
         render(elapsedTime);
 
@@ -220,7 +222,7 @@ void Game::frame()
         {
             _frameRate = _frameCount;
             _frameCount = 0;
-            _frameLastFPS = Game::getGameTime();
+            _frameLastFPS = getGameTime();
         }
     }
     else
@@ -303,7 +305,7 @@ void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactI
 {
 }
 
-void Game::schedule(long timeOffset, TimeListener* timeListener, void* cookie)
+void Game::schedule(float timeOffset, TimeListener* timeListener, void* cookie)
 {
     GP_ASSERT(_timeEvents);
     TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
@@ -322,9 +324,9 @@ void Game::updateOnce()
     GP_ASSERT(_physicsController);
 
     // Update Time.
-    static long lastFrameTime = Game::getGameTime();
-    long frameTime = Game::getGameTime();
-    long elapsedTime = (frameTime - lastFrameTime);
+    static double lastFrameTime = getGameTime();
+    double frameTime = getGameTime();
+    float elapsedTime = (frameTime - lastFrameTime);
     lastFrameTime = frameTime;
 
     // Update the internal controllers.
@@ -358,7 +360,7 @@ void Game::loadConfig()
     }
 }
 
-void Game::fireTimeEvents(long frameTime)
+void Game::fireTimeEvents(double frameTime)
 {
     while (_timeEvents->size() > 0)
     {
@@ -373,7 +375,7 @@ void Game::fireTimeEvents(long frameTime)
     }
 }
 
-Game::TimeEvent::TimeEvent(long time, TimeListener* timeListener, void* cookie)
+Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
             : time(time), listener(timeListener), cookie(cookie)
 {
 }

+ 11 - 11
gameplay/src/Game.h

@@ -79,7 +79,7 @@ public:
      * 
      * @return The total absolute running time (in milliseconds).
      */
-    static long getAbsoluteTime();
+    static double getAbsoluteTime();
 
     /**
      * Gets the total game time (in milliseconds). This is the total accumulated game time (unpaused).
@@ -89,7 +89,7 @@ public:
      * 
      * @return The total game time (in milliseconds).
      */
-    static long getGameTime();
+    static double getGameTime();
 
     /**
      * Gets the game state.
@@ -297,7 +297,7 @@ public:
      * @param timeListener The TimeListener that will receive the event.
      * @param cookie The cookie data that the time event will contain.
      */
-    void schedule(long timeOffset, TimeListener* timeListener, void* cookie = 0);
+    void schedule(float timeOffset, TimeListener* timeListener, void* cookie = 0);
 
 protected:
 
@@ -324,7 +324,7 @@ protected:
      *
      * @param elapsedTime The elapsed game time.
      */
-    virtual void update(long elapsedTime) = 0;
+    virtual void update(float elapsedTime) = 0;
 
     /**
      * Render callback for handling rendering routines.
@@ -334,7 +334,7 @@ protected:
      *
      * @param elapsedTime The elapsed game time.
      */
-    virtual void render(long elapsedTime) = 0;
+    virtual void render(float elapsedTime) = 0;
 
     /**
      * Renders a single frame once and then swaps it to the display.
@@ -363,7 +363,7 @@ private:
     {
     public:
 
-        TimeEvent(long time, TimeListener* timeListener, void* cookie);
+        TimeEvent(double time, TimeListener* timeListener, void* cookie);
         // The comparator is used to determine the order of time events in the priority queue.
         bool operator<(const TimeEvent& v) const;
         
@@ -371,7 +371,7 @@ private:
          * The game time.
          * @see Game::getGameTime()
          */
-        long time;
+        double time;
         TimeListener* listener;
         void* cookie;
     };
@@ -398,7 +398,7 @@ private:
      * 
      * @param frameTime The current game frame time. Used to determine which time events need to be fired.
      */
-    void fireTimeEvents(long frameTime);
+    void fireTimeEvents(double frameTime);
 
     /**
      * Loads the game configuration.
@@ -407,9 +407,9 @@ private:
 
     bool _initialized;                          // If game has initialized yet.
     State _state;                               // The game state.
-    static long _pausedTimeLast;                // The last time paused.
-    static long _pausedTimeTotal;               // The total time paused.
-    long _frameLastFPS;                         // The last time the frame count was updated.
+    static double _pausedTimeLast;              // The last time paused.
+    static double _pausedTimeTotal;             // The total time paused.
+    double _frameLastFPS;                       // The last time the frame count was updated.
     unsigned int _frameCount;                   // The current frame count.
     unsigned int _frameRate;                    // The current frame rate.
     unsigned int _width;                        // The game's display width.

+ 1 - 1
gameplay/src/Node.cpp

@@ -21,7 +21,7 @@ namespace gameplay
 {
 
 Node::Node(const char* id)
-    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(NULL),
+    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(0),
     _nodeFlags(NODE_FLAG_VISIBLE), _camera(NULL), _light(NULL), _model(NULL), _form(NULL), _audioSource(NULL), _particleEmitter(NULL),
     _collisionObject(NULL), _dirtyBits(NODE_DIRTY_ALL), _notifyHierarchyChanged(true), _userData(NULL)
 {

+ 6 - 8
gameplay/src/ParticleEmitter.cpp

@@ -28,7 +28,7 @@ ParticleEmitter::ParticleEmitter(SpriteBatch* batch, unsigned int particleCountM
     _spriteBatch(batch), _spriteTextureBlending(BLEND_TRANSPARENT),  _spriteTextureWidth(0), _spriteTextureHeight(0), _spriteTextureWidthRatio(0), _spriteTextureHeightRatio(0), _spriteTextureCoords(NULL),
     _spriteAnimated(false),  _spriteLooped(false), _spriteFrameCount(1), _spriteFrameRandomOffset(0),_spriteFrameDuration(0L), _spriteFrameDurationSecs(0.0f), _spritePercentPerFrame(0.0f),
     _node(NULL), _orbitPosition(false), _orbitVelocity(false), _orbitAcceleration(false),
-    _timePerEmission(PARTICLE_EMISSION_RATE_TIME_INTERVAL), _timeLast(0L), _timeRunning(0L)
+    _timePerEmission(PARTICLE_EMISSION_RATE_TIME_INTERVAL), _timeRunning(0)
 {
     GP_ASSERT(particleCountMax);
     _particles = new Particle[particleCountMax];
@@ -228,7 +228,6 @@ void ParticleEmitter::setEmissionRate(unsigned int rate)
 void ParticleEmitter::start()
 {
     _started = true;
-    _timeLast = Game::getGameTime();
 }
 
 void ParticleEmitter::stop()
@@ -786,8 +785,7 @@ ParticleEmitter::TextureBlending ParticleEmitter::getTextureBlendingFromString(c
     }
 }
 
-
-void ParticleEmitter::update(long elapsedTime)
+void ParticleEmitter::update(float elapsedTime)
 {
     if (!isActive())
     {
@@ -795,7 +793,7 @@ void ParticleEmitter::update(long elapsedTime)
     }
 
     // Calculate the time passed since last update.
-    float elapsedSecs = (float)elapsedTime * 0.001f;
+    float elapsedSecs = elapsedTime * 0.001f;
 
     if (_started && _emissionRate)
     {
@@ -804,13 +802,13 @@ void ParticleEmitter::update(long elapsedTime)
 
         // How many particles should we emit this frame?
         GP_ASSERT(_timePerEmission);
-        unsigned int emitCount = _timeRunning / _timePerEmission;
-            
+        unsigned int emitCount = (unsigned int)(_timeRunning / _timePerEmission);
+
         if (emitCount)
         {
             if ((int)_timePerEmission > 0)
             {
-                _timeRunning %= (int)_timePerEmission;
+                _timeRunning = fmodl(_timeRunning, _timePerEmission);
             }
 
             emit(emitCount);

+ 2 - 3
gameplay/src/ParticleEmitter.h

@@ -608,7 +608,7 @@ public:
      *
      * @param elapsedTime The amount of time that has passed since the last call to update(), in milliseconds.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
     /**
      * Draws the particles currently being emitted.
@@ -733,8 +733,7 @@ private:
     bool _orbitVelocity;
     bool _orbitAcceleration;
     float _timePerEmission;
-    long _timeLast;
-    long _timeRunning;
+    double _timeRunning;
 };
 
 }

+ 2 - 2
gameplay/src/PhysicsController.cpp

@@ -381,7 +381,7 @@ void PhysicsController::resume()
     // Unused
 }
 
-void PhysicsController::update(long elapsedTime)
+void PhysicsController::update(float elapsedTime)
 {
     GP_ASSERT(_world);
 
@@ -390,7 +390,7 @@ void PhysicsController::update(long elapsedTime)
     //
     // Note that stepSimulation takes elapsed time in seconds
     // so we divide by 1000 to convert from milliseconds.
-    _world->stepSimulation((float)elapsedTime * 0.001, 10);
+    _world->stepSimulation(elapsedTime * 0.001f, 10);
 
     // If we have status listeners, then check if our status has changed.
     if (_listeners)

+ 1 - 1
gameplay/src/PhysicsController.h

@@ -321,7 +321,7 @@ private:
     /**
      * Controller update.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
     // Adds the given collision listener for the two given collision objects.
     void addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);

+ 2 - 2
gameplay/src/Platform.h

@@ -66,14 +66,14 @@ public:
      *
      * @return The absolute platform time. (in milliseconds)
      */
-    static long getAbsoluteTime();
+    static double getAbsoluteTime();
 
     /**
      * Sets the absolute platform time since the start of the message pump.
      *
      * @param time The time to set (in milliseconds).
      */
-    static void setAbsoluteTime(long time);
+    static void setAbsoluteTime(double time);
 
     /**
      * Gets whether vertical sync is enabled for the game display.

+ 7 - 7
gameplay/src/PlatformAndroid.cpp

@@ -25,8 +25,8 @@ static EGLConfig __eglConfig = 0;
 static int __width;
 static int __height;
 static struct timespec __timespec;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static ASensorManager* __sensorManager;
 static ASensorEventQueue* __sensorEventQueue;
@@ -47,10 +47,10 @@ PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 namespace gameplay
 {
 
-static long timespec2millis(struct timespec *a)
+static double timespec2millis(struct timespec *a)
 {
     GP_ASSERT(a);
-    return a->tv_sec*1000 + a->tv_nsec/1000000;
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
 }
 
 extern void printError(const char* format, ...)
@@ -858,16 +858,16 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
     
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     clock_gettime(CLOCK_REALTIME, &__timespec);
-    long now = timespec2millis(&__timespec);
+    double now = timespec2millis(&__timespec);
     __timeAbsolute = now - __timeStart;
 
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 8 - 8
gameplay/src/PlatformMacOSX.mm

@@ -21,8 +21,8 @@ static int __height = 720;
 static float ACCELEROMETER_FACTOR_X = 90.0f / __width;
 static float ACCELEROMETER_FACTOR_Y = 90.0f / __height;
 
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __pitch;
 static float __roll;
@@ -37,17 +37,17 @@ static char* __title = NULL;
 static bool __fullscreen = false;
 
 
-long getMachTimeInMilliseconds()
+double getMachTimeInMilliseconds()
 {
-    static const int64_t kOneMillion = 1000 * 1000;
+    static const double kOneMillion = 1000 * 1000;
     static mach_timebase_info_data_t s_timebase_info;
     
     if (s_timebase_info.denom == 0) 
         (void) mach_timebase_info(&s_timebase_info);
     
     // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
-    GP_ASSERT(kOneMillion * s_timebase_info.denom);
-    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+    GP_ASSERT(s_timebase_info.denom);
+    return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
 }
 
 
@@ -717,13 +717,13 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
 
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     __timeAbsolute = getMachTimeInMilliseconds();
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 7 - 7
gameplay/src/PlatformQNX.cpp

@@ -22,8 +22,8 @@
 using namespace std;
 
 struct timespec __timespec;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static screen_context_t __screenContext;
 static screen_window_t __screenWindow;
@@ -751,10 +751,10 @@ error:
 /**
  * Convert the timespec into milliseconds.
  */
-long timespec2millis(struct timespec *a)
+double timespec2millis(struct timespec *a)
 {
     GP_ASSERT(a);
-    return a->tv_sec*1000 + a->tv_nsec/1000000;
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
 }
 
 /**
@@ -1044,16 +1044,16 @@ unsigned int Platform::getDisplayHeight()
     return __screenWindowSize[1];
 }
 
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     clock_gettime(CLOCK_REALTIME, &__timespec);
-    long now = timespec2millis(&__timespec);
+    double now = timespec2millis(&__timespec);
     __timeAbsolute = now - __timeStart;
 
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 6 - 6
gameplay/src/PlatformWin32.cpp

@@ -14,9 +14,9 @@ using gameplay::printError;
 static int __width = 1280;
 static int __height = 720;
 
-static long __timeTicksPerMillis;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeTicksPerMillis;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __roll;
 static float __pitch;
@@ -628,7 +628,7 @@ int Platform::enterMessagePump()
     // Get the initial time.
     LARGE_INTEGER tps;
     QueryPerformanceFrequency(&tps);
-    __timeTicksPerMillis = (long)(tps.QuadPart / 1000L);
+    __timeTicksPerMillis = (double)(tps.QuadPart / 1000L);
     LARGE_INTEGER queryTime;
     QueryPerformanceCounter(&queryTime);
     GP_ASSERT(__timeTicksPerMillis);
@@ -687,7 +687,7 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
     
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     LARGE_INTEGER queryTime;
     QueryPerformanceCounter(&queryTime);
@@ -697,7 +697,7 @@ long Platform::getAbsoluteTime()
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 9 - 9
gameplay/src/PlatformiOS.mm

@@ -37,14 +37,14 @@ extern const int WINDOW_SCALE = [[UIScreen mainScreen] scale];
 static AppDelegate *__appDelegate = NULL;
 static View* __view = NULL;
 
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __pitch;
 static float __roll;
 
 
-long getMachTimeInMilliseconds();
+double getMachTimeInMilliseconds();
 
 int getKey(unichar keyCode);
 
@@ -580,17 +580,17 @@ int getKey(unichar keyCode);
 @end
 
 
-long getMachTimeInMilliseconds()
+dobule getMachTimeInMilliseconds()
 {
-    static const int64_t kOneMillion = 1000 * 1000;
+    static const double kOneMillion = 1000 * 1000;
     static mach_timebase_info_data_t s_timebase_info;
     
     if (s_timebase_info.denom == 0) 
         (void) mach_timebase_info(&s_timebase_info);
     
     // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
-    GP_ASSERT(kOneMillion * s_timebase_info.denom);
-    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+    GP_ASSERT(s_timebase_info.denom);
+    return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
 }
 
 int getKey(unichar keyCode) 
@@ -868,13 +868,13 @@ unsigned int Platform::getDisplayHeight()
     return size.height;
 }
 
-long Platform::getAbsoluteTime()
+dobule Platform::getAbsoluteTime()
 {
     __timeAbsolute = getMachTimeInMilliseconds();
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 6 - 6
gameplay/src/ScreenDisplayer.h

@@ -27,7 +27,7 @@ public:
      * @param cookie See {@link Game#renderOnce}.
      * @param time The minimum amount of time to display the screen (in milliseconds).
      */
-    template <typename T> void run(T* instance, void (T::*method) (void*), void* cookie, long time);
+    template <typename T> void run(T* instance, void (T::*method) (void*), void* cookie, unsigned long time);
 
     /**
      * Destructor.
@@ -37,14 +37,14 @@ public:
 private:
 
     long _time;
-    long _startTime;
+    double _startTime;
 };
 
-inline ScreenDisplayer::ScreenDisplayer() : _time(0L), _startTime(0L)
+inline ScreenDisplayer::ScreenDisplayer() : _time(0L), _startTime(0)
 {
 }
 
-template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (void*), void* cookie, long time)
+template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (void*), void* cookie, unsigned long time)
 {
     _time = time;
     Game::getInstance()->renderOnce(instance, method, cookie);
@@ -53,9 +53,9 @@ template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (
 
 inline ScreenDisplayer::~ScreenDisplayer()
 {
-    long elapsedTime = Game::getInstance()->getGameTime() - _startTime;
+    long elapsedTime = (long)(Game::getInstance()->getGameTime() - _startTime);
     if (elapsedTime < _time)
-        Platform::sleep(_time - (Game::getInstance()->getGameTime() - _startTime));
+        Platform::sleep(_time - elapsedTime);
 }
 
 /**