Mercurial > fife-parpg
changeset 181:56ac89189bc4
fixed time handling in fife:
- the time scaling method was unreliable when changing the time factors (jumping in the moment of the change)
- replaced much calls to SDL_GetTicks with TimerManager::instance()->getTime()
- some other time related cleanup
author | spq@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sat, 31 Jan 2009 04:15:43 +0000 |
parents | 66bd7f8c541e |
children | bcc93e17f978 |
files | engine/core/model/metamodel/timeprovider.cpp engine/core/model/metamodel/timeprovider.h engine/core/model/metamodel/timeprovider.i engine/core/model/structures/instance.cpp engine/core/model/structures/instance.h engine/core/model/structures/instance.i engine/core/model/structures/layer.cpp engine/core/util/time/timemanager.cpp engine/core/view/camera.cpp engine/core/view/renderers/genericrenderer.cpp |
diffstat | 10 files changed, 84 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/engine/core/model/metamodel/timeprovider.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/metamodel/timeprovider.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -35,7 +35,8 @@ namespace FIFE { TimeProvider::TimeProvider(TimeProvider* master): m_master(master), - m_multiplier(1.0) { + m_multiplier(1.0) { + m_time_static = m_time_scaled = master ? master->getGameTime() : TimeManager::instance()->getTime(); } TimeProvider::~TimeProvider() {} @@ -44,6 +45,8 @@ if (multiplier < 0.0) { throw NotSupported("Negative time multiplier are not supported"); } + m_time_static = getPreciseGameTime(); + m_time_scaled = m_master ? m_master->getPreciseGameTime() : static_cast<float>(TimeManager::instance()->getTime()); m_multiplier = multiplier; } @@ -59,14 +62,14 @@ } } - unsigned int TimeProvider::getGameTicks() const { - if (m_master) { - return m_master->getGameTicks(); - } else { - return TimeManager::instance()->getTime(); - } + unsigned int TimeProvider::getGameTime() const { + return static_cast<unsigned int>(getPreciseGameTime()); } - + + double TimeProvider::getPreciseGameTime() const { + return m_time_static + m_multiplier * ((m_master ? m_master->getPreciseGameTime() : static_cast<float>(TimeManager::instance()->getTime())) - m_time_scaled); + } + unsigned int scaleTime(float multiplier, unsigned int ticks) { return static_cast<unsigned int>(static_cast<float>(ticks) * multiplier); }
--- a/engine/core/model/metamodel/timeprovider.h Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/metamodel/timeprovider.h Sat Jan 31 04:15:43 2009 +0000 @@ -60,13 +60,18 @@ */ float getTotalMultiplier() const; - /** Returns current game ticks. Fetched from furthest master to reduce system calls. + /** Returns current game ticks, already scaled. */ - unsigned int getGameTicks() const; + unsigned int getGameTime() const; private: TimeProvider* m_master; float m_multiplier; + double m_time_static, m_time_scaled; + + /** Returns current game ticks, already scaled, more precise. + */ + double getPreciseGameTime() const; }; /** Utility function to calculate time scaling. Mostly done to avoid littering other code
--- a/engine/core/model/metamodel/timeprovider.i Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/metamodel/timeprovider.i Sat Jan 31 04:15:43 2009 +0000 @@ -33,6 +33,6 @@ void setMultiplier(float multiplier); float getMultiplier() const; float getTotalMultiplier() const; - unsigned int getGameTicks() const; + unsigned int getGameTime() const; }; }
--- a/engine/core/model/structures/instance.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/structures/instance.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -32,6 +32,7 @@ #include "util/log/logger.h" #include "util/base/exception.h" #include "util/math/fife_math.h" +#include "util/time/timemanager.h" #include "model/metamodel/grids/cellgrid.h" #include "model/metamodel/abstractpather.h" #include "model/metamodel/action.h" @@ -52,8 +53,8 @@ m_target(NULL), m_speed(0), m_repeating(false), - m_action_start_time(SDL_GetTicks()), - m_prev_call_time(m_action_start_time), + m_action_start_time(0), + m_prev_call_time(0), m_pather_session_id(-1), m_pather(pather), m_leader(NULL) {} @@ -78,8 +79,6 @@ unsigned int m_action_start_time; // ticks since last call unsigned int m_prev_call_time; - // current time for action processing (set by Instance::update), optimized to avoid multiple calls to GetTicks - unsigned int m_cur_time; // session id for pather int m_pather_session_id; // pather @@ -93,8 +92,8 @@ SayInfo(const std::string& txt, unsigned int duration): m_txt(txt), m_duration(duration), - m_start_time(SDL_GetTicks()) { - } + m_start_time(0) {} + std::string m_txt; unsigned int m_duration; unsigned int m_start_time; @@ -251,6 +250,7 @@ m_activity->m_actioninfo = NULL; throw NotFound(std::string("action ") + action_name + " not found"); } + m_activity->m_actioninfo->m_prev_call_time = m_activity->m_actioninfo->m_action_start_time = getRuntime(); } void Instance::move(const std::string& action_name, const Location& target, const double speed) { @@ -286,6 +286,7 @@ if (text != "") { m_activity->m_sayinfo = new SayInfo(text, duration); + m_activity->m_sayinfo->m_start_time = getRuntime(); } } @@ -308,7 +309,7 @@ FL_DBG(_log, "Moving..."); ActionInfo* info = m_activity->m_actioninfo; // timeslice for this movement - unsigned int timedelta = scaleTime(getTotalTimeMultiplier(), info->m_cur_time - info->m_prev_call_time); + unsigned int timedelta = m_activity->m_timeprovider->getGameTime() - info->m_prev_call_time; FL_DBG(_log, LMsg("timedelta ") << timedelta << " prevcalltime " << info->m_prev_call_time); // how far we can travel double distance_to_travel = (static_cast<double>(timedelta) / 1000.0) * info->m_speed; @@ -331,7 +332,7 @@ return false; } - InstanceChangeInfo Instance::update(unsigned int curticks) { + InstanceChangeInfo Instance::update() { if (!m_activity) { return ICHANGE_NO_CHANGES; } @@ -339,14 +340,9 @@ if (!m_activity->m_timeprovider) { bindTimeProvider(); } - - if (curticks == 0) { - curticks = SDL_GetTicks(); - } ActionInfo* info = m_activity->m_actioninfo; if (info) { - info->m_cur_time = curticks; - FL_DBG(_log, LMsg("updating instance, ticks = ") << curticks); + FL_DBG(_log, "updating instance"); if (info->m_target) { FL_DBG(_log, "action contains target for movement"); @@ -361,20 +357,20 @@ } } else { FL_DBG(_log, "action does not contain target for movement"); - if (scaleTime(getTotalTimeMultiplier(), curticks - info->m_action_start_time) >= info->m_action->getDuration()) { + if (m_activity->m_timeprovider->getGameTime() - info->m_action_start_time >= info->m_action->getDuration()) { if (info->m_repeating) { - info->m_action_start_time = curticks; + info->m_action_start_time = m_activity->m_timeprovider->getGameTime(); } else { finalizeAction(); } } } - m_activity->m_actioninfo->m_prev_call_time = curticks; + m_activity->m_actioninfo->m_prev_call_time = m_activity->m_timeprovider->getGameTime(); } if (m_activity->m_sayinfo) { if (m_activity->m_sayinfo->m_duration > 0) { - if (scaleTime(getTotalTimeMultiplier(), curticks - m_activity->m_sayinfo->m_start_time) > m_activity->m_sayinfo->m_duration) { + if (m_activity->m_timeprovider->getGameTime() >= m_activity->m_sayinfo->m_start_time + m_activity->m_sayinfo->m_duration) { say(""); } } @@ -432,13 +428,15 @@ return *m_facinglocation; } - int Instance::getActionRuntime() const { + unsigned int Instance::getActionRuntime() { if (m_activity && m_activity->m_actioninfo) { - return SDL_GetTicks() - m_activity->m_actioninfo->m_action_start_time; + if(!m_activity->m_timeprovider) + bindTimeProvider(); + return m_activity->m_timeprovider->getGameTime() - m_activity->m_actioninfo->m_action_start_time; } - return -1; + return getRuntime(); } - + void Instance::bindTimeProvider() { float multiplier = 1.0; if (m_activity->m_timeprovider) { @@ -458,12 +456,12 @@ } m_activity->m_timeprovider->setMultiplier(multiplier); } - + void Instance::refresh() { initializeChanges(); bindTimeProvider(); } - + void Instance::setTimeMultiplier(float multip) { initializeChanges(); if (!m_activity->m_timeprovider) { @@ -471,19 +469,39 @@ } m_activity->m_timeprovider->setMultiplier(multip); } - + float Instance::getTimeMultiplier() { if (m_activity && m_activity->m_timeprovider) { return m_activity->m_timeprovider->getMultiplier(); } return 1.0; } - + float Instance::getTotalTimeMultiplier() { if (m_activity && m_activity->m_timeprovider) { return m_activity->m_timeprovider->getTotalMultiplier(); } + if (m_location.getLayer()) { + Map* map = m_location.getLayer()->getMap(); + if (map && map->getTimeProvider()) { + return map->getTimeProvider()->getTotalMultiplier(); + } + } return 1.0; } + + unsigned int Instance::getRuntime() { + if (m_activity) { + if(!m_activity->m_timeprovider) + bindTimeProvider(); + return m_activity->m_timeprovider->getGameTime(); + } + if (m_location.getLayer()) { + Map* map = m_location.getLayer()->getMap(); + if (map && map->getTimeProvider()) { + return map->getTimeProvider()->getGameTime(); + } + } + return TimeManager::instance()->getTime(); + } } -
--- a/engine/core/model/structures/instance.h Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/structures/instance.h Sat Jan 31 04:15:43 2009 +0000 @@ -185,7 +185,7 @@ * In case there is no current action, returns -1 * @return action runtime */ - int getActionRuntime() const; + unsigned int getActionRuntime(); /** Performs given named action to the instance. While performing the action * moves instance to given target with given speed @@ -221,12 +221,11 @@ const std::string* getSayText() const; /** Updates the instance related to the current action - * @param curticks current tick count of the system * @note call this only once in engine update cycle, so that tracking between * current position and previous position keeps in sync. * @returns marked changes */ - InstanceChangeInfo update(unsigned int curticks=0); + InstanceChangeInfo update(); /** Sets visualization to be used. Transfers ownership. */ @@ -248,6 +247,11 @@ */ float getTotalTimeMultiplier(); + /** Gets the scaled runtime in milliseconds + * @return runtime + */ + unsigned int getRuntime(); + /** Refreshes instance e.g. in case location is updated directly (not via setLocation) * In this case e.g. instance's master time provider is changed, so it needs to be updated */
--- a/engine/core/model/structures/instance.i Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/structures/instance.i Sat Jan 31 04:15:43 2009 +0000 @@ -84,13 +84,14 @@ void setFacingLocation(const Location& loc); Location getFacingLocation(); Location& getFacingLocationRef(); - int getActionRuntime() const; + unsigned int getActionRuntime(); void move(const std::string& action_name, const Location& target, const double speed); void act(const std::string& action_name, const Location& direction, bool repeating=false); void follow(const std::string& action_name, Instance* leader, const double speed); void say(const std::string& text, unsigned int duration=0); void setTimeMultiplier(float multip); float getTimeMultiplier(); + unsigned int getRuntime(); void refresh(); InstanceChangeInfo getChangeInfo();
--- a/engine/core/model/structures/layer.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/model/structures/layer.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -203,10 +203,9 @@ bool Layer::update() { m_changedinstances.clear(); - unsigned int curticks = SDL_GetTicks(); std::vector<Instance*>::iterator it = m_instances.begin(); for(; it != m_instances.end(); ++it) { - if ((*it)->update(curticks) != ICHANGE_NO_CHANGES) { + if ((*it)->update() != ICHANGE_NO_CHANGES) { m_changedinstances.push_back(*it); m_changed = true; }
--- a/engine/core/util/time/timemanager.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/util/time/timemanager.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -54,10 +54,12 @@ if (m_current_time == 0) { m_current_time = SDL_GetTicks(); avg_multiplier = 0; + m_time_delta = 0; + } else { + m_time_delta = m_current_time; + m_current_time = SDL_GetTicks(); + m_time_delta = m_current_time - m_time_delta; } - m_time_delta = m_current_time; - m_current_time = SDL_GetTicks(); - m_time_delta = m_current_time - m_time_delta; m_average_frame_time = m_average_frame_time * avg_multiplier + double(m_time_delta) * (1.0 - avg_multiplier);
--- a/engine/core/view/camera.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/view/camera.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -484,8 +484,6 @@ // return; //} - const unsigned long curtime = TimeManager::instance()->getTime(); - // update each layer m_renderbackend->pushClipArea(getViewPort()); @@ -534,9 +532,8 @@ if (action) { FL_DBG(_log, "Instance has action"); int animation_id = action->getVisual<ActionVisual>()->getAnimationIndexByAngle(angle); - Animation& animation = m_apool->getAnimation(animation_id); - int animtime = scaleTime(instance->getTotalTimeMultiplier(), instance->getActionRuntime()) % animation.getDuration(); + unsigned int animtime = instance->getActionRuntime() % animation.getDuration(); image = animation.getFrameByTimestamp(animtime); } else { FL_DBG(_log, "No action"); @@ -550,7 +547,7 @@ if (action) { int animation_id = action->getVisual<ActionVisual>()->getAnimationIndexByAngle(angle); Animation& animation = m_apool->getAnimation(animation_id); - int animtime = scaleTime(instance->getTotalTimeMultiplier(), curtime) % animation.getDuration(); + unsigned int animtime = instance->getRuntime() % animation.getDuration(); image = animation.getFrameByTimestamp(animtime); } }
--- a/engine/core/view/renderers/genericrenderer.cpp Fri Jan 30 00:58:43 2009 +0000 +++ b/engine/core/view/renderers/genericrenderer.cpp Sat Jan 31 04:15:43 2009 +0000 @@ -35,6 +35,7 @@ #include "video/image.h" #include "util/math/fife_math.h" #include "util/log/logger.h" +#include "util/time/timemanager.h" #include "model/metamodel/grids/cellgrid.h" #include "model/metamodel/timeprovider.h" #include "model/structures/instance.h" @@ -246,13 +247,13 @@ GenericRendererElementInfo(), m_anchor(anchor), m_animation(animation), - m_start_time(SDL_GetTicks()), + m_start_time(TimeManager::instance()->getTime()), m_time_scale(1.0) { } void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { Point p = m_anchor.getCalculatedPoint(cam, layer, instances); Animation& animation = animpool->getAnimation(m_animation); - int animtime = scaleTime(m_time_scale, SDL_GetTicks() - m_start_time) % animation.getDuration(); + int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration(); Image* img = animation.getFrameByTimestamp(animtime); Rect r; r.x = p.x-img->getWidth()/2;