mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-17 13:41:07 +02:00
Merge pull request #2153 from IvanSavenko/better_time_management
Separate updates from rendering actions
This commit is contained in:
commit
ddf22a757d
@ -599,8 +599,6 @@ static void mainLoop()
|
|||||||
fsChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
|
fsChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
|
||||||
|
|
||||||
inGuiThread.reset(new bool(true));
|
inGuiThread.reset(new bool(true));
|
||||||
assert(GH.mainFPSmng);
|
|
||||||
GH.mainFPSmng->init(settings["video"]["targetfps"].Integer());
|
|
||||||
|
|
||||||
while(1) //main SDL events loop
|
while(1) //main SDL events loop
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@ set(client_SRCS
|
|||||||
gui/CIntObject.cpp
|
gui/CIntObject.cpp
|
||||||
gui/CursorHandler.cpp
|
gui/CursorHandler.cpp
|
||||||
gui/InterfaceObjectConfigurable.cpp
|
gui/InterfaceObjectConfigurable.cpp
|
||||||
|
gui/FramerateManager.cpp
|
||||||
gui/NotificationHandler.cpp
|
gui/NotificationHandler.cpp
|
||||||
gui/ShortcutHandler.cpp
|
gui/ShortcutHandler.cpp
|
||||||
|
|
||||||
@ -162,6 +163,7 @@ set(client_HEADERS
|
|||||||
gui/CIntObject.h
|
gui/CIntObject.h
|
||||||
gui/CursorHandler.h
|
gui/CursorHandler.h
|
||||||
gui/InterfaceObjectConfigurable.h
|
gui/InterfaceObjectConfigurable.h
|
||||||
|
gui/FramerateManager.h
|
||||||
gui/MouseButton.h
|
gui/MouseButton.h
|
||||||
gui/NotificationHandler.h
|
gui/NotificationHandler.h
|
||||||
gui/Shortcut.h
|
gui/Shortcut.h
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "CMT.h"
|
#include "CMT.h"
|
||||||
#include "gui/CGuiHandler.h"
|
#include "gui/CGuiHandler.h"
|
||||||
|
#include "gui/FramerateManager.h"
|
||||||
#include "renderSDL/SDL_Extensions.h"
|
#include "renderSDL/SDL_Extensions.h"
|
||||||
#include "CPlayerInterface.h"
|
#include "CPlayerInterface.h"
|
||||||
#include "../lib/filesystem/Filesystem.h"
|
#include "../lib/filesystem/Filesystem.h"
|
||||||
@ -370,7 +371,7 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
|
|||||||
auto packet_duration = frame->duration;
|
auto packet_duration = frame->duration;
|
||||||
#endif
|
#endif
|
||||||
double frameEndTime = (frame->pts + packet_duration) * av_q2d(format->streams[stream]->time_base);
|
double frameEndTime = (frame->pts + packet_duration) * av_q2d(format->streams[stream]->time_base);
|
||||||
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.0;
|
frameTime += GH.framerateManager().getElapsedMilliseconds() / 1000.0;
|
||||||
|
|
||||||
if (frameTime >= frameEndTime )
|
if (frameTime >= frameEndTime )
|
||||||
{
|
{
|
||||||
@ -450,6 +451,7 @@ bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
|
|||||||
|
|
||||||
pos.x = x;
|
pos.x = x;
|
||||||
pos.y = y;
|
pos.y = y;
|
||||||
|
frameTime = 0.0;
|
||||||
|
|
||||||
while(nextFrame())
|
while(nextFrame())
|
||||||
{
|
{
|
||||||
@ -461,10 +463,15 @@ bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
|
|||||||
SDL_RenderCopy(mainRenderer, texture, nullptr, &rect);
|
SDL_RenderCopy(mainRenderer, texture, nullptr, &rect);
|
||||||
SDL_RenderPresent(mainRenderer);
|
SDL_RenderPresent(mainRenderer);
|
||||||
|
|
||||||
// Wait 3 frames
|
#if (LIBAVUTIL_VERSION_MAJOR < 58)
|
||||||
GH.mainFPSmng->framerateDelay();
|
auto packet_duration = frame->pkt_duration;
|
||||||
GH.mainFPSmng->framerateDelay();
|
#else
|
||||||
GH.mainFPSmng->framerateDelay();
|
auto packet_duration = frame->duration;
|
||||||
|
#endif
|
||||||
|
double frameDurationSec = packet_duration * av_q2d(format->streams[stream]->time_base);
|
||||||
|
uint32_t timeToSleepMillisec = 1000 * (frameDurationSec);
|
||||||
|
|
||||||
|
boost::this_thread::sleep(boost::posix_time::millisec(timeToSleepMillisec));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -59,7 +59,7 @@ AdventureMapInterface::AdventureMapInterface():
|
|||||||
shortcuts->setState(EAdventureState::MAKING_TURN);
|
shortcuts->setState(EAdventureState::MAKING_TURN);
|
||||||
widget->getMapView()->onViewMapActivated();
|
widget->getMapView()->onViewMapActivated();
|
||||||
|
|
||||||
addUsedEvents(KEYBOARD);
|
addUsedEvents(KEYBOARD | TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdventureMapInterface::onMapViewMoved(const Rect & visibleArea, int mapLevel)
|
void AdventureMapInterface::onMapViewMoved(const Rect & visibleArea, int mapLevel)
|
||||||
@ -139,18 +139,20 @@ void AdventureMapInterface::showAll(SDL_Surface * to)
|
|||||||
|
|
||||||
void AdventureMapInterface::show(SDL_Surface * to)
|
void AdventureMapInterface::show(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
handleMapScrollingUpdate();
|
|
||||||
|
|
||||||
CIntObject::show(to);
|
CIntObject::show(to);
|
||||||
LOCPLINT->cingconsole->show(to);
|
LOCPLINT->cingconsole->show(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdventureMapInterface::handleMapScrollingUpdate()
|
void AdventureMapInterface::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
handleMapScrollingUpdate(msPassed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdventureMapInterface::handleMapScrollingUpdate(uint32_t timePassed)
|
||||||
{
|
{
|
||||||
/// Width of window border, in pixels, that triggers map scrolling
|
/// Width of window border, in pixels, that triggers map scrolling
|
||||||
static constexpr uint32_t borderScrollWidth = 15;
|
static constexpr uint32_t borderScrollWidth = 15;
|
||||||
|
|
||||||
uint32_t timePassed = GH.mainFPSmng->getElapsedMilliseconds();
|
|
||||||
uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
|
uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
|
||||||
uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
|
uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ private:
|
|||||||
const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const;
|
const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const;
|
||||||
|
|
||||||
/// check and if necessary reacts on scrolling by moving cursor to screen edge
|
/// check and if necessary reacts on scrolling by moving cursor to screen edge
|
||||||
void handleMapScrollingUpdate();
|
void handleMapScrollingUpdate(uint32_t msPassed);
|
||||||
|
|
||||||
void showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode);
|
void showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode);
|
||||||
|
|
||||||
@ -93,6 +93,7 @@ protected:
|
|||||||
void activate() override;
|
void activate() override;
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ bool DummyAnimation::init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DummyAnimation::nextFrame()
|
void DummyAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
if(counter > howMany)
|
if(counter > howMany)
|
||||||
@ -300,7 +300,7 @@ ECreatureAnimType MeleeAttackAnimation::selectGroup(bool multiAttack)
|
|||||||
return mutPosToGroup[mutPos];
|
return mutPosToGroup[mutPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeleeAttackAnimation::nextFrame()
|
void MeleeAttackAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
size_t currentFrame = stackAnimation(attackingStack)->getCurrentFrame();
|
size_t currentFrame = stackAnimation(attackingStack)->getCurrentFrame();
|
||||||
size_t totalFrames = stackAnimation(attackingStack)->framesInGroup(getGroup());
|
size_t totalFrames = stackAnimation(attackingStack)->framesInGroup(getGroup());
|
||||||
@ -308,7 +308,7 @@ void MeleeAttackAnimation::nextFrame()
|
|||||||
if ( currentFrame * 2 >= totalFrames )
|
if ( currentFrame * 2 >= totalFrames )
|
||||||
owner.executeAnimationStage(EAnimationEvents::HIT);
|
owner.executeAnimationStage(EAnimationEvents::HIT);
|
||||||
|
|
||||||
AttackAnimation::nextFrame();
|
AttackAnimation::tick(msPassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeleeAttackAnimation::MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack)
|
MeleeAttackAnimation::MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack)
|
||||||
@ -379,15 +379,15 @@ bool MovementAnimation::init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovementAnimation::nextFrame()
|
void MovementAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
progress += float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000 * progressPerSecond;
|
progress += float(msPassed) / 1000 * progressPerSecond;
|
||||||
|
|
||||||
//moving instructions
|
//moving instructions
|
||||||
myAnim->pos.x = static_cast<Sint16>(begX + distanceX * progress );
|
myAnim->pos.x = static_cast<Sint16>(begX + distanceX * progress );
|
||||||
myAnim->pos.y = static_cast<Sint16>(begY + distanceY * progress );
|
myAnim->pos.y = static_cast<Sint16>(begY + distanceY * progress );
|
||||||
|
|
||||||
BattleAnimation::nextFrame();
|
BattleAnimation::tick(msPassed);
|
||||||
|
|
||||||
if(progress >= 1.0)
|
if(progress >= 1.0)
|
||||||
{
|
{
|
||||||
@ -577,9 +577,9 @@ bool ColorTransformAnimation::init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorTransformAnimation::nextFrame()
|
void ColorTransformAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
float elapsed = GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
float elapsed = msPassed / 1000.f;
|
||||||
float fullTime = AnimationControls::getFadeInDuration();
|
float fullTime = AnimationControls::getFadeInDuration();
|
||||||
float delta = elapsed / fullTime;
|
float delta = elapsed / fullTime;
|
||||||
totalProgress += delta;
|
totalProgress += delta;
|
||||||
@ -699,7 +699,7 @@ void RangedAttackAnimation::emitProjectile()
|
|||||||
projectileEmitted = true;
|
projectileEmitted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RangedAttackAnimation::nextFrame()
|
void RangedAttackAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
// animation should be paused if there is an active projectile
|
// animation should be paused if there is an active projectile
|
||||||
if (projectileEmitted)
|
if (projectileEmitted)
|
||||||
@ -716,7 +716,7 @@ void RangedAttackAnimation::nextFrame()
|
|||||||
else
|
else
|
||||||
stackAnimation(attackingStack)->playUntil(static_cast<size_t>(-1));
|
stackAnimation(attackingStack)->playUntil(static_cast<size_t>(-1));
|
||||||
|
|
||||||
AttackAnimation::nextFrame();
|
AttackAnimation::tick(msPassed);
|
||||||
|
|
||||||
if (!projectileEmitted)
|
if (!projectileEmitted)
|
||||||
{
|
{
|
||||||
@ -790,9 +790,9 @@ CatapultAnimation::CatapultAnimation(BattleInterface & owner, const CStack * att
|
|||||||
logAnim->debug("Created shooting anim for %s", stack->getName());
|
logAnim->debug("Created shooting anim for %s", stack->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatapultAnimation::nextFrame()
|
void CatapultAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
ShootingAnimation::nextFrame();
|
ShootingAnimation::tick(msPassed);
|
||||||
|
|
||||||
if ( explosionEmitted)
|
if ( explosionEmitted)
|
||||||
return;
|
return;
|
||||||
@ -988,9 +988,9 @@ bool EffectAnimation::init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectAnimation::nextFrame()
|
void EffectAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
playEffect();
|
playEffect(msPassed);
|
||||||
|
|
||||||
if (effectFinished)
|
if (effectFinished)
|
||||||
{
|
{
|
||||||
@ -1020,7 +1020,7 @@ void EffectAnimation::onEffectFinished()
|
|||||||
effectFinished = true;
|
effectFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectAnimation::playEffect()
|
void EffectAnimation::playEffect(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
if ( effectFinished )
|
if ( effectFinished )
|
||||||
return;
|
return;
|
||||||
@ -1029,7 +1029,7 @@ void EffectAnimation::playEffect()
|
|||||||
{
|
{
|
||||||
if(elem.effectID == ID)
|
if(elem.effectID == ID)
|
||||||
{
|
{
|
||||||
elem.currentFrame += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
|
elem.currentFrame += AnimationControls::getSpellEffectSpeed() * msPassed / 1000;
|
||||||
|
|
||||||
if(elem.currentFrame >= elem.animation->size())
|
if(elem.currentFrame >= elem.animation->size())
|
||||||
{
|
{
|
||||||
@ -1113,7 +1113,7 @@ void HeroCastAnimation::emitAnimationEvent()
|
|||||||
owner.executeAnimationStage(EAnimationEvents::HIT);
|
owner.executeAnimationStage(EAnimationEvents::HIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeroCastAnimation::nextFrame()
|
void HeroCastAnimation::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
float frame = hero->getFrame();
|
float frame = hero->getFrame();
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public:
|
|||||||
|
|
||||||
bool isInitialized();
|
bool isInitialized();
|
||||||
bool tryInitialize();
|
bool tryInitialize();
|
||||||
virtual void nextFrame() {} //call every new frame
|
virtual void tick(uint32_t msPassed) {} //call every new frame
|
||||||
virtual ~BattleAnimation();
|
virtual ~BattleAnimation();
|
||||||
|
|
||||||
BattleAnimation(BattleInterface & owner);
|
BattleAnimation(BattleInterface & owner);
|
||||||
@ -120,7 +120,7 @@ class ColorTransformAnimation : public BattleStackAnimation
|
|||||||
float totalProgress;
|
float totalProgress;
|
||||||
|
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const std::string & colorFilterName, const CSpell * spell);
|
ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const std::string & colorFilterName, const CSpell * spell);
|
||||||
@ -157,7 +157,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
MovementAnimation(BattleInterface & owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance);
|
MovementAnimation(BattleInterface & owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance);
|
||||||
~MovementAnimation();
|
~MovementAnimation();
|
||||||
@ -220,7 +220,7 @@ class MeleeAttackAnimation : public AttackAnimation
|
|||||||
public:
|
public:
|
||||||
MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack);
|
MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack);
|
||||||
|
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ public:
|
|||||||
~RangedAttackAnimation();
|
~RangedAttackAnimation();
|
||||||
|
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Shooting attack
|
/// Shooting attack
|
||||||
@ -275,7 +275,7 @@ public:
|
|||||||
CatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender, int _catapultDmg = 0);
|
CatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender, int _catapultDmg = 0);
|
||||||
|
|
||||||
void createProjectile(const Point & from, const Point & dest) const override;
|
void createProjectile(const Point & from, const Point & dest) const override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastAnimation : public RangedAttackAnimation
|
class CastAnimation : public RangedAttackAnimation
|
||||||
@ -300,7 +300,7 @@ private:
|
|||||||
int howMany;
|
int howMany;
|
||||||
public:
|
public:
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
DummyAnimation(BattleInterface & owner, int howManyFrames);
|
DummyAnimation(BattleInterface & owner, int howManyFrames);
|
||||||
};
|
};
|
||||||
@ -324,7 +324,7 @@ class EffectAnimation : public BattleAnimation
|
|||||||
|
|
||||||
void onEffectFinished();
|
void onEffectFinished();
|
||||||
void clearEffect();
|
void clearEffect();
|
||||||
void playEffect();
|
void playEffect(uint32_t msPassed);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum EEffectFlags
|
enum EEffectFlags
|
||||||
@ -349,7 +349,7 @@ public:
|
|||||||
~EffectAnimation();
|
~EffectAnimation();
|
||||||
|
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeroCastAnimation : public BattleAnimation
|
class HeroCastAnimation : public BattleAnimation
|
||||||
@ -367,6 +367,6 @@ class HeroCastAnimation : public BattleAnimation
|
|||||||
public:
|
public:
|
||||||
HeroCastAnimation(BattleInterface & owner, std::shared_ptr<BattleHero> hero, BattleHex dest, const CStack * defender, const CSpell * spell);
|
HeroCastAnimation(BattleInterface & owner, std::shared_ptr<BattleHero> hero, BattleHex dest, const CStack * defender, const CSpell * spell);
|
||||||
|
|
||||||
void nextFrame() override;
|
void tick(uint32_t msPassed) override;
|
||||||
bool init() override;
|
bool init() override;
|
||||||
};
|
};
|
||||||
|
@ -68,7 +68,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
|
|||||||
backgroundWithHexes = std::make_unique<Canvas>(Point(background->width(), background->height()));
|
backgroundWithHexes = std::make_unique<Canvas>(Point(background->width(), background->height()));
|
||||||
|
|
||||||
updateAccessibleHexes();
|
updateAccessibleHexes();
|
||||||
addUsedEvents(LCLICK | RCLICK | MOVE);
|
addUsedEvents(LCLICK | RCLICK | MOVE | TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::activate()
|
void BattleFieldController::activate()
|
||||||
@ -134,7 +134,7 @@ void BattleFieldController::renderBattlefield(Canvas & canvas)
|
|||||||
|
|
||||||
renderer.execute(clippedCanvas);
|
renderer.execute(clippedCanvas);
|
||||||
|
|
||||||
owner.projectilesController->showProjectiles(clippedCanvas);
|
owner.projectilesController->render(clippedCanvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::showBackground(Canvas & canvas)
|
void BattleFieldController::showBackground(Canvas & canvas)
|
||||||
@ -611,12 +611,16 @@ void BattleFieldController::showAll(SDL_Surface * to)
|
|||||||
show(to);
|
show(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::show(SDL_Surface * to)
|
void BattleFieldController::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
updateAccessibleHexes();
|
updateAccessibleHexes();
|
||||||
owner.stacksController->update();
|
owner.stacksController->tick(msPassed);
|
||||||
owner.obstacleController->update();
|
owner.obstacleController->tick(msPassed);
|
||||||
|
owner.projectilesController->tick(msPassed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleFieldController::show(SDL_Surface * to)
|
||||||
|
{
|
||||||
Canvas canvas(to);
|
Canvas canvas(to);
|
||||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ class BattleFieldController : public CIntObject
|
|||||||
|
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
public:
|
public:
|
||||||
BattleFieldController(BattleInterface & owner);
|
BattleFieldController(BattleInterface & owner);
|
||||||
|
|
||||||
|
@ -202,6 +202,25 @@ const CGHeroInstance * BattleHero::instance()
|
|||||||
return hero;
|
return hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleHero::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
size_t groupIndex = static_cast<size_t>(phase);
|
||||||
|
|
||||||
|
float timePassed = msPassed / 1000.f;
|
||||||
|
|
||||||
|
flagCurrentFrame += currentSpeed * timePassed;
|
||||||
|
currentFrame += currentSpeed * timePassed;
|
||||||
|
|
||||||
|
if(flagCurrentFrame >= flagAnimation->size(0))
|
||||||
|
flagCurrentFrame -= flagAnimation->size(0);
|
||||||
|
|
||||||
|
if(currentFrame >= animation->size(groupIndex))
|
||||||
|
{
|
||||||
|
currentFrame -= animation->size(groupIndex);
|
||||||
|
switchToNextPhase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BattleHero::render(Canvas & canvas)
|
void BattleHero::render(Canvas & canvas)
|
||||||
{
|
{
|
||||||
size_t groupIndex = static_cast<size_t>(phase);
|
size_t groupIndex = static_cast<size_t>(phase);
|
||||||
@ -219,20 +238,6 @@ void BattleHero::render(Canvas & canvas)
|
|||||||
|
|
||||||
canvas.draw(flagFrame, flagPosition);
|
canvas.draw(flagFrame, flagPosition);
|
||||||
canvas.draw(heroFrame, heroPosition);
|
canvas.draw(heroFrame, heroPosition);
|
||||||
|
|
||||||
float timePassed = float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000.f;
|
|
||||||
|
|
||||||
flagCurrentFrame += currentSpeed * timePassed;
|
|
||||||
currentFrame += currentSpeed * timePassed;
|
|
||||||
|
|
||||||
if(flagCurrentFrame >= flagAnimation->size(0))
|
|
||||||
flagCurrentFrame -= flagAnimation->size(0);
|
|
||||||
|
|
||||||
if(currentFrame >= animation->size(groupIndex))
|
|
||||||
{
|
|
||||||
currentFrame -= animation->size(groupIndex);
|
|
||||||
switchToNextPhase();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleHero::pause()
|
void BattleHero::pause()
|
||||||
@ -354,6 +359,8 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
|
|||||||
|
|
||||||
switchToNextPhase();
|
switchToNextPhase();
|
||||||
play();
|
play();
|
||||||
|
|
||||||
|
addUsedEvents(TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||||
|
@ -114,6 +114,7 @@ public:
|
|||||||
void setPhase(EHeroAnimType newPhase); //sets phase of hero animation
|
void setPhase(EHeroAnimType newPhase); //sets phase of hero animation
|
||||||
|
|
||||||
void collectRenderableObjects(BattleRenderer & renderer);
|
void collectRenderableObjects(BattleRenderer & renderer);
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
float getFrame() const;
|
float getFrame() const;
|
||||||
void onPhaseFinished(const std::function<void()> &);
|
void onPhaseFinished(const std::function<void()> &);
|
||||||
|
@ -159,9 +159,9 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleObstacleController::update()
|
void BattleObstacleController::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
timePassed += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
timePassed += msPassed / 1000.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstacleInstance & oi)
|
std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstacleInstance & oi)
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
BattleObstacleController(BattleInterface & owner);
|
BattleObstacleController(BattleInterface & owner);
|
||||||
|
|
||||||
/// called every frame
|
/// called every frame
|
||||||
void update();
|
void tick(uint32_t msPassed);
|
||||||
|
|
||||||
/// call-in from network pack, add newly placed obstacles with any required animations
|
/// call-in from network pack, add newly placed obstacles with any required animations
|
||||||
void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi);
|
void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi);
|
||||||
|
@ -58,15 +58,18 @@ void ProjectileMissile::show(Canvas & canvas)
|
|||||||
|
|
||||||
canvas.draw(image, pos);
|
canvas.draw(image, pos);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float timePassed = GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
void ProjectileMissile::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
float timePassed = msPassed / 1000.f;
|
||||||
progress += timePassed * speed;
|
progress += timePassed * speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileAnimatedMissile::show(Canvas & canvas)
|
void ProjectileAnimatedMissile::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
ProjectileMissile::show(canvas);
|
ProjectileMissile::tick(msPassed);
|
||||||
frameProgress += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
|
frameProgress += AnimationControls::getSpellEffectSpeed() * msPassed / 1000;
|
||||||
size_t animationSize = animation->size(reverse ? 1 : 0);
|
size_t animationSize = animation->size(reverse ? 1 : 0);
|
||||||
while (frameProgress > animationSize)
|
while (frameProgress > animationSize)
|
||||||
frameProgress -= animationSize;
|
frameProgress -= animationSize;
|
||||||
@ -74,9 +77,15 @@ void ProjectileAnimatedMissile::show(Canvas & canvas)
|
|||||||
frameNum = std::floor(frameProgress);
|
frameNum = std::floor(frameProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectileCatapult::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
frameProgress += AnimationControls::getSpellEffectSpeed() * msPassed / 1000;
|
||||||
|
float timePassed = msPassed / 1000.f;
|
||||||
|
progress += timePassed * speed;
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectileCatapult::show(Canvas & canvas)
|
void ProjectileCatapult::show(Canvas & canvas)
|
||||||
{
|
{
|
||||||
frameProgress += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
|
|
||||||
int frameCounter = std::floor(frameProgress);
|
int frameCounter = std::floor(frameProgress);
|
||||||
int frameIndex = (frameCounter + 1) % animation->size(0);
|
int frameIndex = (frameCounter + 1) % animation->size(0);
|
||||||
|
|
||||||
@ -90,9 +99,6 @@ void ProjectileCatapult::show(Canvas & canvas)
|
|||||||
|
|
||||||
canvas.draw(image, pos);
|
canvas.draw(image, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
float timePassed = GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
|
||||||
progress += timePassed * speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileRay::show(Canvas & canvas)
|
void ProjectileRay::show(Canvas & canvas)
|
||||||
@ -135,8 +141,11 @@ void ProjectileRay::show(Canvas & canvas)
|
|||||||
canvas.drawLine(Point(x1 + i, y1), Point(x2 + i, y2), ray.start, ray.end);
|
canvas.drawLine(Point(x1 + i, y1), Point(x2 + i, y2), ray.start, ray.end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float timePassed = GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
void ProjectileRay::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
float timePassed = msPassed / 1000.f;
|
||||||
progress += timePassed * speed;
|
progress += timePassed * speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,13 +226,22 @@ void BattleProjectileController::emitStackProjectile(const CStack * stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleProjectileController::showProjectiles(Canvas & canvas)
|
void BattleProjectileController::render(Canvas & canvas)
|
||||||
{
|
{
|
||||||
for ( auto projectile: projectiles)
|
for ( auto projectile: projectiles)
|
||||||
{
|
{
|
||||||
if ( projectile->playing )
|
if ( projectile->playing )
|
||||||
projectile->show(canvas);
|
projectile->show(canvas);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleProjectileController::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
for ( auto projectile: projectiles)
|
||||||
|
{
|
||||||
|
if ( projectile->playing )
|
||||||
|
projectile->tick(msPassed);
|
||||||
|
}
|
||||||
|
|
||||||
vstd::erase_if(projectiles, [&](const std::shared_ptr<ProjectileBase> & projectile){
|
vstd::erase_if(projectiles, [&](const std::shared_ptr<ProjectileBase> & projectile){
|
||||||
return projectile->progress > 1.0f;
|
return projectile->progress > 1.0f;
|
||||||
|
@ -28,6 +28,7 @@ struct ProjectileBase
|
|||||||
{
|
{
|
||||||
virtual ~ProjectileBase() = default;
|
virtual ~ProjectileBase() = default;
|
||||||
virtual void show(Canvas & canvas) = 0;
|
virtual void show(Canvas & canvas) = 0;
|
||||||
|
virtual void tick(uint32_t msPassed) = 0;
|
||||||
|
|
||||||
Point from; // initial position on the screen
|
Point from; // initial position on the screen
|
||||||
Point dest; // target position on the screen
|
Point dest; // target position on the screen
|
||||||
@ -42,6 +43,7 @@ struct ProjectileBase
|
|||||||
struct ProjectileMissile : ProjectileBase
|
struct ProjectileMissile : ProjectileBase
|
||||||
{
|
{
|
||||||
void show(Canvas & canvas) override;
|
void show(Canvas & canvas) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> animation;
|
std::shared_ptr<CAnimation> animation;
|
||||||
int frameNum; // frame to display from projectile animation
|
int frameNum; // frame to display from projectile animation
|
||||||
@ -51,7 +53,7 @@ struct ProjectileMissile : ProjectileBase
|
|||||||
/// Projectile for spell - render animation moving in straight line from origin to destination
|
/// Projectile for spell - render animation moving in straight line from origin to destination
|
||||||
struct ProjectileAnimatedMissile : ProjectileMissile
|
struct ProjectileAnimatedMissile : ProjectileMissile
|
||||||
{
|
{
|
||||||
void show(Canvas & canvas) override;
|
void tick(uint32_t msPassed) override;
|
||||||
float frameProgress;
|
float frameProgress;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ struct ProjectileAnimatedMissile : ProjectileMissile
|
|||||||
struct ProjectileCatapult : ProjectileBase
|
struct ProjectileCatapult : ProjectileBase
|
||||||
{
|
{
|
||||||
void show(Canvas & canvas) override;
|
void show(Canvas & canvas) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> animation;
|
std::shared_ptr<CAnimation> animation;
|
||||||
float frameProgress;
|
float frameProgress;
|
||||||
@ -68,6 +71,7 @@ struct ProjectileCatapult : ProjectileBase
|
|||||||
struct ProjectileRay : ProjectileBase
|
struct ProjectileRay : ProjectileBase
|
||||||
{
|
{
|
||||||
void show(Canvas & canvas) override;
|
void show(Canvas & canvas) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
|
|
||||||
std::vector<CCreature::CreatureAnimation::RayColor> rayConfig;
|
std::vector<CCreature::CreatureAnimation::RayColor> rayConfig;
|
||||||
};
|
};
|
||||||
@ -102,7 +106,10 @@ public:
|
|||||||
BattleProjectileController(BattleInterface & owner);
|
BattleProjectileController(BattleInterface & owner);
|
||||||
|
|
||||||
/// renders all currently active projectiles
|
/// renders all currently active projectiles
|
||||||
void showProjectiles(Canvas & canvas);
|
void render(Canvas & canvas);
|
||||||
|
|
||||||
|
/// updates positioning / animations of all projectiles
|
||||||
|
void tick(uint32_t msPassed);
|
||||||
|
|
||||||
/// returns true if stack has projectile that is yet to hit target
|
/// returns true if stack has projectile that is yet to hit target
|
||||||
bool hasActiveProjectile(const CStack * stack, bool emittedOnly) const;
|
bool hasActiveProjectile(const CStack * stack, bool emittedOnly) const;
|
||||||
|
@ -335,13 +335,12 @@ void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stackAnimation[stack->unitId()]->nextFrame(canvas, fullFilter, facingRight(stack)); // do actual blit
|
stackAnimation[stack->unitId()]->nextFrame(canvas, fullFilter, facingRight(stack)); // do actual blit
|
||||||
stackAnimation[stack->unitId()]->incrementFrame(float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleStacksController::update()
|
void BattleStacksController::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
updateHoveredStacks();
|
updateHoveredStacks();
|
||||||
updateBattleAnimations();
|
updateBattleAnimations(msPassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleStacksController::initializeBattleAnimations()
|
void BattleStacksController::initializeBattleAnimations()
|
||||||
@ -352,21 +351,30 @@ void BattleStacksController::initializeBattleAnimations()
|
|||||||
elem->tryInitialize();
|
elem->tryInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleStacksController::stepFrameBattleAnimations()
|
void BattleStacksController::tickFrameBattleAnimations(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
|
for (auto stack : owner.curInt->cb->battleGetAllStacks(false))
|
||||||
|
{
|
||||||
|
if (stackAnimation.find(stack->unitId()) == stackAnimation.end()) //e.g. for summoned but not yet handled stacks
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stackAnimation[stack->unitId()]->incrementFrame(msPassed / 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
// operate on copy - to prevent potential iterator invalidation due to push_back's
|
// operate on copy - to prevent potential iterator invalidation due to push_back's
|
||||||
// FIXME? : remove remaining calls to addNewAnim from BattleAnimation::nextFrame (only Catapult explosion at the time of writing)
|
// FIXME? : remove remaining calls to addNewAnim from BattleAnimation::nextFrame (only Catapult explosion at the time of writing)
|
||||||
|
|
||||||
auto copiedVector = currentAnimations;
|
auto copiedVector = currentAnimations;
|
||||||
for (auto & elem : copiedVector)
|
for (auto & elem : copiedVector)
|
||||||
if (elem && elem->isInitialized())
|
if (elem && elem->isInitialized())
|
||||||
elem->nextFrame();
|
elem->tick(msPassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleStacksController::updateBattleAnimations()
|
void BattleStacksController::updateBattleAnimations(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
bool hadAnimations = !currentAnimations.empty();
|
bool hadAnimations = !currentAnimations.empty();
|
||||||
initializeBattleAnimations();
|
initializeBattleAnimations();
|
||||||
stepFrameBattleAnimations();
|
tickFrameBattleAnimations(msPassed);
|
||||||
vstd::erase(currentAnimations, nullptr);
|
vstd::erase(currentAnimations, nullptr);
|
||||||
|
|
||||||
if (hadAnimations && currentAnimations.empty())
|
if (hadAnimations && currentAnimations.empty())
|
||||||
|
@ -91,9 +91,9 @@ class BattleStacksController
|
|||||||
void removeExpiredColorFilters();
|
void removeExpiredColorFilters();
|
||||||
|
|
||||||
void initializeBattleAnimations();
|
void initializeBattleAnimations();
|
||||||
void stepFrameBattleAnimations();
|
void tickFrameBattleAnimations(uint32_t msPassed);
|
||||||
|
|
||||||
void updateBattleAnimations();
|
void updateBattleAnimations(uint32_t msPassed);
|
||||||
void updateHoveredStacks();
|
void updateHoveredStacks();
|
||||||
|
|
||||||
std::vector<const CStack *> selectHoveredStacks();
|
std::vector<const CStack *> selectHoveredStacks();
|
||||||
@ -138,7 +138,7 @@ public:
|
|||||||
const CStack* getActiveStack() const;
|
const CStack* getActiveStack() const;
|
||||||
const std::vector<uint32_t> getHoveredStacksUnitIds() const;
|
const std::vector<uint32_t> getHoveredStacksUnitIds() const;
|
||||||
|
|
||||||
void update();
|
void tick(uint32_t msPassed);
|
||||||
|
|
||||||
/// returns position of animation needed to place stack in specific hex
|
/// returns position of animation needed to place stack in specific hex
|
||||||
Point getStackPositionAtHex(BattleHex hexNum, const CStack * creature) const;
|
Point getStackPositionAtHex(BattleHex hexNum, const CStack * creature) const;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "CIntObject.h"
|
#include "CIntObject.h"
|
||||||
#include "CursorHandler.h"
|
#include "CursorHandler.h"
|
||||||
#include "ShortcutHandler.h"
|
#include "ShortcutHandler.h"
|
||||||
|
#include "FramerateManager.h"
|
||||||
|
|
||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../render/Colors.h"
|
#include "../render/Colors.h"
|
||||||
@ -100,7 +101,7 @@ void CGuiHandler::init()
|
|||||||
{
|
{
|
||||||
screenHandlerInstance = std::make_unique<ScreenHandler>();
|
screenHandlerInstance = std::make_unique<ScreenHandler>();
|
||||||
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
|
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
|
||||||
mainFPSmng = new CFramerateManager(settings["video"]["targetfps"].Integer());
|
framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer());
|
||||||
|
|
||||||
isPointerRelativeMode = settings["general"]["userRelativePointer"].Bool();
|
isPointerRelativeMode = settings["general"]["userRelativePointer"].Bool();
|
||||||
pointerSpeedMultiplier = settings["general"]["relativePointerSpeedMultiplier"].Float();
|
pointerSpeedMultiplier = settings["general"]["relativePointerSpeedMultiplier"].Float();
|
||||||
@ -193,7 +194,7 @@ void CGuiHandler::totalRedraw()
|
|||||||
|
|
||||||
void CGuiHandler::updateTime()
|
void CGuiHandler::updateTime()
|
||||||
{
|
{
|
||||||
int ms = mainFPSmng->getElapsedMilliseconds();
|
int ms = framerateManager().getElapsedMilliseconds();
|
||||||
std::list<CIntObject*> hlp = timeinterested;
|
std::list<CIntObject*> hlp = timeinterested;
|
||||||
for (auto & elem : hlp)
|
for (auto & elem : hlp)
|
||||||
{
|
{
|
||||||
@ -692,10 +693,9 @@ void CGuiHandler::renderFrame()
|
|||||||
disposed.clear();
|
disposed.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mainFPSmng->framerateDelay(); // holds a constant FPS
|
framerateManager().framerateDelay(); // holds a constant FPS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGuiHandler::CGuiHandler()
|
CGuiHandler::CGuiHandler()
|
||||||
: lastClick(-500, -500)
|
: lastClick(-500, -500)
|
||||||
, lastClickTime(0)
|
, lastClickTime(0)
|
||||||
@ -705,7 +705,6 @@ CGuiHandler::CGuiHandler()
|
|||||||
, mouseButtonsMask(0)
|
, mouseButtonsMask(0)
|
||||||
, continueEventHandling(true)
|
, continueEventHandling(true)
|
||||||
, curInt(nullptr)
|
, curInt(nullptr)
|
||||||
, mainFPSmng(nullptr)
|
|
||||||
, statusbar(nullptr)
|
, statusbar(nullptr)
|
||||||
{
|
{
|
||||||
terminate_cond = new CondSh<bool>(false);
|
terminate_cond = new CondSh<bool>(false);
|
||||||
@ -713,15 +712,21 @@ CGuiHandler::CGuiHandler()
|
|||||||
|
|
||||||
CGuiHandler::~CGuiHandler()
|
CGuiHandler::~CGuiHandler()
|
||||||
{
|
{
|
||||||
delete mainFPSmng;
|
|
||||||
delete terminate_cond;
|
delete terminate_cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutHandler & CGuiHandler::shortcutsHandler()
|
ShortcutHandler & CGuiHandler::shortcutsHandler()
|
||||||
{
|
{
|
||||||
|
assert(shortcutsHandlerInstance);
|
||||||
return *shortcutsHandlerInstance;
|
return *shortcutsHandlerInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FramerateManager & CGuiHandler::framerateManager()
|
||||||
|
{
|
||||||
|
assert(framerateManagerInstance);
|
||||||
|
return *framerateManagerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
void CGuiHandler::moveCursorToPosition(const Point & position)
|
void CGuiHandler::moveCursorToPosition(const Point & position)
|
||||||
{
|
{
|
||||||
SDL_WarpMouseInWindow(mainWindow, position.x, position.y);
|
SDL_WarpMouseInWindow(mainWindow, position.x, position.y);
|
||||||
@ -783,7 +788,7 @@ void CGuiHandler::drawFPSCounter()
|
|||||||
static SDL_Rect overlay = { 0, 0, 64, 32};
|
static SDL_Rect overlay = { 0, 0, 64, 32};
|
||||||
uint32_t black = SDL_MapRGB(screen->format, 10, 10, 10);
|
uint32_t black = SDL_MapRGB(screen->format, 10, 10, 10);
|
||||||
SDL_FillRect(screen, &overlay, black);
|
SDL_FillRect(screen, &overlay, black);
|
||||||
std::string fps = std::to_string(mainFPSmng->getFramerate());
|
std::string fps = std::to_string(framerateManager().getFramerate());
|
||||||
graphics->fonts[FONT_BIG]->renderTextLeft(screen, fps, Colors::YELLOW, Point(10, 10));
|
graphics->fonts[FONT_BIG]->renderTextLeft(screen, fps, Colors::YELLOW, Point(10, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,55 +828,3 @@ void CGuiHandler::onScreenResize()
|
|||||||
|
|
||||||
totalRedraw();
|
totalRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CFramerateManager::CFramerateManager(int newRate)
|
|
||||||
: rate(0)
|
|
||||||
, rateticks(0)
|
|
||||||
, fps(0)
|
|
||||||
, accumulatedFrames(0)
|
|
||||||
, accumulatedTime(0)
|
|
||||||
, lastticks(0)
|
|
||||||
, timeElapsed(0)
|
|
||||||
{
|
|
||||||
init(newRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFramerateManager::init(int newRate)
|
|
||||||
{
|
|
||||||
rate = newRate;
|
|
||||||
rateticks = 1000.0 / rate;
|
|
||||||
this->lastticks = SDL_GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFramerateManager::framerateDelay()
|
|
||||||
{
|
|
||||||
ui32 currentTicks = SDL_GetTicks();
|
|
||||||
|
|
||||||
timeElapsed = currentTicks - lastticks;
|
|
||||||
accumulatedFrames++;
|
|
||||||
|
|
||||||
// FPS is higher than it should be, then wait some time
|
|
||||||
if(timeElapsed < rateticks)
|
|
||||||
{
|
|
||||||
int timeToSleep = (uint32_t)ceil(this->rateticks) - timeElapsed;
|
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(timeToSleep));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTicks = SDL_GetTicks();
|
|
||||||
// recalculate timeElapsed for external calls via getElapsed()
|
|
||||||
// limit it to 100 ms to avoid breaking animation in case of huge lag (e.g. triggered breakpoint)
|
|
||||||
timeElapsed = std::min<ui32>(currentTicks - lastticks, 100);
|
|
||||||
|
|
||||||
lastticks = SDL_GetTicks();
|
|
||||||
|
|
||||||
accumulatedTime += timeElapsed;
|
|
||||||
|
|
||||||
if(accumulatedFrames >= 100)
|
|
||||||
{
|
|
||||||
//about 2 second should be passed
|
|
||||||
fps = static_cast<int>(ceil(1000.0 / (accumulatedTime / accumulatedFrames)));
|
|
||||||
accumulatedTime = 0;
|
|
||||||
accumulatedFrames = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@ union SDL_Event;
|
|||||||
struct SDL_MouseMotionEvent;
|
struct SDL_MouseMotionEvent;
|
||||||
|
|
||||||
class ShortcutHandler;
|
class ShortcutHandler;
|
||||||
class CFramerateManager;
|
class FramerateManager;
|
||||||
class IStatusBar;
|
class IStatusBar;
|
||||||
class CIntObject;
|
class CIntObject;
|
||||||
class IUpdateable;
|
class IUpdateable;
|
||||||
@ -44,32 +44,11 @@ enum class EUserEvent
|
|||||||
FORCE_QUIT, //quit client without question
|
FORCE_QUIT, //quit client without question
|
||||||
};
|
};
|
||||||
|
|
||||||
// A fps manager which holds game updates at a constant rate
|
|
||||||
class CFramerateManager
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
double rateticks;
|
|
||||||
ui32 lastticks;
|
|
||||||
ui32 timeElapsed;
|
|
||||||
int rate;
|
|
||||||
int fps; // the actual fps value
|
|
||||||
ui32 accumulatedTime;
|
|
||||||
ui32 accumulatedFrames;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFramerateManager(int newRate); // initializes the manager with a given fps rate
|
|
||||||
void init(int newRate); // needs to be called directly before the main game loop to reset the internal timer
|
|
||||||
void framerateDelay(); // needs to be called every game update cycle
|
|
||||||
ui32 getElapsedMilliseconds() const {return this->timeElapsed;}
|
|
||||||
ui32 getFrameNumber() const { return accumulatedFrames; }
|
|
||||||
ui32 getFramerate() const { return fps; };
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handles GUI logic and drawing
|
// Handles GUI logic and drawing
|
||||||
class CGuiHandler
|
class CGuiHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CFramerateManager * mainFPSmng; //to keep const framerate
|
|
||||||
std::list<std::shared_ptr<IShowActivatable>> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
|
std::list<std::shared_ptr<IShowActivatable>> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
|
||||||
std::shared_ptr<IStatusBar> statusbar;
|
std::shared_ptr<IStatusBar> statusbar;
|
||||||
|
|
||||||
@ -97,6 +76,7 @@ private:
|
|||||||
CIntObjectList textInterested;
|
CIntObjectList textInterested;
|
||||||
|
|
||||||
std::unique_ptr<IScreenHandler> screenHandlerInstance;
|
std::unique_ptr<IScreenHandler> screenHandlerInstance;
|
||||||
|
std::unique_ptr<FramerateManager> framerateManagerInstance;
|
||||||
|
|
||||||
void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed);
|
void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed);
|
||||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||||
@ -113,11 +93,15 @@ public:
|
|||||||
public:
|
public:
|
||||||
//objs to blit
|
//objs to blit
|
||||||
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
|
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
|
||||||
|
|
||||||
/// returns current position of mouse cursor, relative to vcmi window
|
/// returns current position of mouse cursor, relative to vcmi window
|
||||||
const Point & getCursorPosition() const;
|
const Point & getCursorPosition() const;
|
||||||
|
|
||||||
ShortcutHandler & shortcutsHandler();
|
ShortcutHandler & shortcutsHandler();
|
||||||
|
FramerateManager & framerateManager();
|
||||||
|
|
||||||
|
/// Returns current logical screen dimensions
|
||||||
|
/// May not match size of window if user has UI scaling different from 100%
|
||||||
Point screenDimensions() const;
|
Point screenDimensions() const;
|
||||||
|
|
||||||
/// returns true if at least one mouse button is pressed
|
/// returns true if at least one mouse button is pressed
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "CursorHandler.h"
|
#include "CursorHandler.h"
|
||||||
|
|
||||||
#include "CGuiHandler.h"
|
#include "CGuiHandler.h"
|
||||||
|
#include "FramerateManager.h"
|
||||||
#include "../renderSDL/CursorSoftware.h"
|
#include "../renderSDL/CursorSoftware.h"
|
||||||
#include "../renderSDL/CursorHardware.h"
|
#include "../renderSDL/CursorHardware.h"
|
||||||
#include "../render/CAnimation.h"
|
#include "../render/CAnimation.h"
|
||||||
@ -250,7 +251,7 @@ void CursorHandler::updateSpellcastCursor()
|
|||||||
{
|
{
|
||||||
static const float frameDisplayDuration = 0.1f; // H3 uses 100 ms per frame
|
static const float frameDisplayDuration = 0.1f; // H3 uses 100 ms per frame
|
||||||
|
|
||||||
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
frameTime += GH.framerateManager().getElapsedMilliseconds() / 1000.f;
|
||||||
size_t newFrame = frame;
|
size_t newFrame = frame;
|
||||||
|
|
||||||
while (frameTime >= frameDisplayDuration)
|
while (frameTime >= frameDisplayDuration)
|
||||||
|
57
client/gui/FramerateManager.cpp
Normal file
57
client/gui/FramerateManager.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* FramerateManager.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "FramerateManager.h"
|
||||||
|
|
||||||
|
FramerateManager::FramerateManager(int targetFrameRate)
|
||||||
|
: targetFrameTime(Duration(boost::chrono::seconds(1)) / targetFrameRate)
|
||||||
|
, lastFrameIndex(0)
|
||||||
|
, lastFrameTimes({})
|
||||||
|
, lastTimePoint (Clock::now())
|
||||||
|
{
|
||||||
|
boost::range::fill(lastFrameTimes, targetFrameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramerateManager::framerateDelay()
|
||||||
|
{
|
||||||
|
Duration timeSpentBusy = Clock::now() - lastTimePoint;
|
||||||
|
|
||||||
|
// FPS is higher than it should be, then wait some time
|
||||||
|
if(timeSpentBusy < targetFrameTime)
|
||||||
|
boost::this_thread::sleep_for(targetFrameTime - timeSpentBusy);
|
||||||
|
|
||||||
|
// compute actual timeElapsed taking into account actual sleep interval
|
||||||
|
// limit it to 100 ms to avoid breaking animation in case of huge lag (e.g. triggered breakpoint)
|
||||||
|
TimePoint currentTicks = Clock::now();
|
||||||
|
Duration timeElapsed = currentTicks - lastTimePoint;
|
||||||
|
if(timeElapsed > boost::chrono::milliseconds(100))
|
||||||
|
timeElapsed = boost::chrono::milliseconds(100);
|
||||||
|
|
||||||
|
lastTimePoint = currentTicks;
|
||||||
|
lastFrameIndex = (lastFrameIndex + 1) % lastFrameTimes.size();
|
||||||
|
lastFrameTimes[lastFrameIndex] = timeElapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui32 FramerateManager::getElapsedMilliseconds() const
|
||||||
|
{
|
||||||
|
return lastFrameTimes[lastFrameIndex] / boost::chrono::milliseconds(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui32 FramerateManager::getFramerate() const
|
||||||
|
{
|
||||||
|
Duration accumulatedTime = std::accumulate(lastFrameTimes.begin(), lastFrameTimes.end(), Duration());
|
||||||
|
|
||||||
|
auto actualFrameTime = accumulatedTime / lastFrameTimes.size();
|
||||||
|
if(actualFrameTime == actualFrameTime.zero())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return std::round(boost::chrono::duration<double>(1) / actualFrameTime);
|
||||||
|
};
|
40
client/gui/FramerateManager.h
Normal file
40
client/gui/FramerateManager.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* FramerateManager.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// Framerate manager controls current game frame rate by constantly trying to reach targeted frame rate
|
||||||
|
class FramerateManager
|
||||||
|
{
|
||||||
|
using Clock = boost::chrono::high_resolution_clock;
|
||||||
|
using TimePoint = Clock::time_point;
|
||||||
|
using Duration = Clock::duration;
|
||||||
|
|
||||||
|
/// cyclic buffer of durations of last frames
|
||||||
|
std::array<Duration, 60> lastFrameTimes;
|
||||||
|
|
||||||
|
Duration targetFrameTime;
|
||||||
|
TimePoint lastTimePoint;
|
||||||
|
|
||||||
|
/// index of last measured frome in lastFrameTimes array
|
||||||
|
ui32 lastFrameIndex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FramerateManager(int targetFramerate);
|
||||||
|
|
||||||
|
/// must be called every frame
|
||||||
|
/// updates framerate calculations and executes sleep to maintain target frame rate
|
||||||
|
void framerateDelay();
|
||||||
|
|
||||||
|
/// returns duration of last frame in seconds
|
||||||
|
ui32 getElapsedMilliseconds() const;
|
||||||
|
|
||||||
|
/// returns current estimation of frame rate
|
||||||
|
ui32 getFramerate() const;
|
||||||
|
};
|
@ -55,6 +55,8 @@ BasicMapView::BasicMapView(const Point & offset, const Point & dimensions)
|
|||||||
pos += offset;
|
pos += offset;
|
||||||
pos.w = dimensions.x;
|
pos.w = dimensions.x;
|
||||||
pos.h = dimensions.y;
|
pos.h = dimensions.y;
|
||||||
|
|
||||||
|
addUsedEvents(TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicMapView::render(Canvas & target, bool fullUpdate)
|
void BasicMapView::render(Canvas & target, bool fullUpdate)
|
||||||
@ -64,21 +66,22 @@ void BasicMapView::render(Canvas & target, bool fullUpdate)
|
|||||||
tilesCache->render(controller->getContext(), targetClipped, fullUpdate);
|
tilesCache->render(controller->getContext(), targetClipped, fullUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BasicMapView::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
|
controller->tick(msPassed);
|
||||||
|
}
|
||||||
|
|
||||||
void BasicMapView::show(SDL_Surface * to)
|
void BasicMapView::show(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
controller->updateBefore(GH.mainFPSmng->getElapsedMilliseconds());
|
|
||||||
|
|
||||||
Canvas target(to);
|
Canvas target(to);
|
||||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||||
render(target, false);
|
render(target, false);
|
||||||
|
|
||||||
controller->updateAfter(GH.mainFPSmng->getElapsedMilliseconds());
|
controller->afterRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicMapView::showAll(SDL_Surface * to)
|
void BasicMapView::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
controller->updateBefore(0);
|
|
||||||
|
|
||||||
Canvas target(to);
|
Canvas target(to);
|
||||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||||
render(target, true);
|
render(target, true);
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
BasicMapView(const Point & offset, const Point & dimensions);
|
BasicMapView(const Point & offset, const Point & dimensions);
|
||||||
~BasicMapView() override;
|
~BasicMapView() override;
|
||||||
|
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
};
|
};
|
||||||
|
@ -89,7 +89,7 @@ std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewController::updateBefore(uint32_t timeDelta)
|
void MapViewController::tick(uint32_t timeDelta)
|
||||||
{
|
{
|
||||||
// confirmed to match H3 for
|
// confirmed to match H3 for
|
||||||
// - hero embarking on boat (500 ms)
|
// - hero embarking on boat (500 ms)
|
||||||
@ -158,7 +158,7 @@ void MapViewController::updateBefore(uint32_t timeDelta)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewController::updateAfter(uint32_t timeDelta)
|
void MapViewController::afterRender()
|
||||||
{
|
{
|
||||||
if(movementContext)
|
if(movementContext)
|
||||||
{
|
{
|
||||||
|
@ -83,8 +83,8 @@ public:
|
|||||||
void setViewCenter(const int3 & position);
|
void setViewCenter(const int3 & position);
|
||||||
void setViewCenter(const Point & position, int level);
|
void setViewCenter(const Point & position, int level);
|
||||||
void setTileSize(const Point & tileSize);
|
void setTileSize(const Point & tileSize);
|
||||||
void updateBefore(uint32_t timeDelta);
|
void tick(uint32_t timePassed);
|
||||||
void updateAfter(uint32_t timeDelta);
|
void afterRender();
|
||||||
|
|
||||||
void activateAdventureContext(uint32_t animationTime);
|
void activateAdventureContext(uint32_t animationTime);
|
||||||
void activateAdventureContext();
|
void activateAdventureContext();
|
||||||
|
@ -320,6 +320,8 @@ CShowableAnim::CShowableAnim(int x, int y, std::string name, ui8 Flags, ui32 fra
|
|||||||
pos.h = anim->getImage(0, group)->height();
|
pos.h = anim->getImage(0, group)->height();
|
||||||
pos.x+= x;
|
pos.x+= x;
|
||||||
pos.y+= y;
|
pos.y+= y;
|
||||||
|
|
||||||
|
addUsedEvents(TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
CShowableAnim::~CShowableAnim()
|
CShowableAnim::~CShowableAnim()
|
||||||
@ -391,11 +393,14 @@ void CShowableAnim::show(SDL_Surface * to)
|
|||||||
if ( flags & BASE )// && frame != first) // FIXME: results in graphical glytch in Fortress, upgraded hydra's dwelling
|
if ( flags & BASE )// && frame != first) // FIXME: results in graphical glytch in Fortress, upgraded hydra's dwelling
|
||||||
blitImage(first, group, to);
|
blitImage(first, group, to);
|
||||||
blitImage(frame, group, to);
|
blitImage(frame, group, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CShowableAnim::tick(uint32_t msPassed)
|
||||||
|
{
|
||||||
if ((flags & PLAY_ONCE) && frame + 1 == last)
|
if ((flags & PLAY_ONCE) && frame + 1 == last)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
frameTimePassed += GH.mainFPSmng->getElapsedMilliseconds();
|
frameTimePassed += msPassed;
|
||||||
|
|
||||||
if(frameTimePassed >= frameTimeTotal)
|
if(frameTimePassed >= frameTimeTotal)
|
||||||
{
|
{
|
||||||
|
@ -190,6 +190,7 @@ public:
|
|||||||
//show current frame and increase counter
|
//show current frame and increase counter
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creature-dependend animations like attacking, moving,...
|
/// Creature-dependend animations like attacking, moving,...
|
||||||
|
@ -68,7 +68,7 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
|||||||
area(nullptr),
|
area(nullptr),
|
||||||
stateTimeCounter(BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
stateTimeCounter(BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
||||||
{
|
{
|
||||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
addUsedEvents(LCLICK | RCLICK | HOVER | TIME);
|
||||||
pos.x += str->pos.x;
|
pos.x += str->pos.x;
|
||||||
pos.y += str->pos.y;
|
pos.y += str->pos.y;
|
||||||
|
|
||||||
@ -163,16 +163,6 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Color multiplyColors(const SDL_Color & b, const SDL_Color & a, double f)
|
|
||||||
{
|
|
||||||
SDL_Color ret;
|
|
||||||
ret.r = static_cast<uint8_t>(a.r * f + b.r * (1 - f));
|
|
||||||
ret.g = static_cast<uint8_t>(a.g * f + b.g * (1 - f));
|
|
||||||
ret.b = static_cast<uint8_t>(a.b * f + b.b * (1 - f));
|
|
||||||
ret.a = static_cast<uint8_t>(a.a * f + b.b * (1 - f));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBuildingRect::show(SDL_Surface * to)
|
void CBuildingRect::show(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
uint32_t stageDelay = BUILDING_APPEAR_TIMEPOINT;
|
uint32_t stageDelay = BUILDING_APPEAR_TIMEPOINT;
|
||||||
@ -213,9 +203,12 @@ void CBuildingRect::show(SDL_Surface * to)
|
|||||||
|
|
||||||
border->draw(to, pos.x, pos.y);
|
border->draw(to, pos.x, pos.y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(stateTimeCounter < BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
void CBuildingRect::tick(uint32_t msPassed)
|
||||||
stateTimeCounter += GH.mainFPSmng->getElapsedMilliseconds();
|
{
|
||||||
|
CShowableAnim::tick(msPassed);
|
||||||
|
stateTimeCounter += msPassed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBuildingRect::showAll(SDL_Surface * to)
|
void CBuildingRect::showAll(SDL_Surface * to)
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
void clickLeft(tribool down, bool previousState) override;
|
void clickLeft(tribool down, bool previousState) override;
|
||||||
void clickRight(tribool down, bool previousState) override;
|
void clickRight(tribool down, bool previousState) override;
|
||||||
void mouseMoved (const Point & cursorPosition) override;
|
void mouseMoved (const Point & cursorPosition) override;
|
||||||
|
void tick(uint32_t msPassed) override;
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user