From f0ae06ba888612bb236be63e4530dd7ab24b08b4 Mon Sep 17 00:00:00 2001 From: Paolo Capriotti Date: Wed, 1 Aug 2007 17:04:16 +0200 Subject: [PATCH] Ported DropAnimatorMixin. --- src/hlvariant/animator.h | 4 +- src/hlvariant/dropanimator.h | 133 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/hlvariant/dropanimator.h diff --git a/src/hlvariant/animator.h b/src/hlvariant/animator.h index 9afb1e3..bac5d14 100644 --- a/src/hlvariant/animator.h +++ b/src/hlvariant/animator.h @@ -25,8 +25,10 @@ namespace HLVariant { * A generic animator. * Can be used as a base class for other specialized animators. */ -template +template class BaseAnimator { +public: + typedef _Variant Variant; protected: typedef typename UnwrappedGraphicalAPIPtr::type API; typedef typename VariantData::GameState GameState; diff --git a/src/hlvariant/dropanimator.h b/src/hlvariant/dropanimator.h new file mode 100644 index 0000000..d53fcfa --- /dev/null +++ b/src/hlvariant/dropanimator.h @@ -0,0 +1,133 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + + +#ifndef HLVARIANT__DROPANIMATOR_H +#define HLVARIANT__DROPANIMATOR_H + +namespace HLVariant { + +template +class DropAnimatorMixin : public Base { + typedef typename Base::Variant Variant; + using Base::m_cinterface; +protected: + typedef typename Base::API API; + typedef typename Base::GameState GameState; + typedef typename Base::Piece Piece; + typedef typename Base::Move Move; + + virtual void updatePool(const GameState& final); +public: + DropAnimatorMixin(API cinterface); + + virtual AnimationGroupPtr warp(const GameState& final); + virtual AnimationGroupPtr forward(const GameState& final, const Move& move); + virtual AnimationGroupPtr back(const GameState& final, const Move& move); +}; + +// IMPLEMENTATION + +template +DropAnimatorMixin::DropAnimatorMixin(API cinterface) +: Base(cinterface) { } + + +template +void DropAnimatorMixin::updatePool(const GameState& final) { + for(int color = 0; color < 2; color++) { + typename Piece::Color c = static_cast(color); + const typename GameState::PlayerPool& before = m_cinterface->position()->rawPool(c); + const typename GameState::PlayerPool& after = final.rawPool(c); + typename GameState::PlayerPool::const_iterator before_it = before.begin(); + typename GameState::PlayerPool::const_iterator after_it = after.begin(); + + int pos = 0; + + // oh, a nice bunch of write-only magic shit + while (before_it != before.end() || after_it != after.end()) { + bool skip_after = (after_it == after.end() || (before_it != before.end() + && before_it->first < after_it->first )); + bool skip_before = (before_it == before.end() || (after_it != after.end() + && after_it->first < before_it->first )); + int na = skip_after ? 0 : after_it->second; + int nb = skip_before ? 0 : before_it->second; + + if (nb < na) { + for(int i = nb; i < na; i++) + m_cinterface->insertPoolPiece(color, pos + (i - nb), Piece(c, after_it->first) ); + } + else if (na < nb) { + for (int i = na; i < nb; i++) + m_cinterface->removePoolSprite(color, pos); + } + + if (!skip_before) + ++before_it; + if (!skip_after) { + pos += after_it->second; + ++after_it; + } + } + } +} + +template +AnimationGroupPtr DropAnimatorMixin::warp(const GameState& final) { + updatePool(final); + return Base::warp(final); +} + +template +AnimationGroupPtr DropAnimatorMixin::forward(const GameState& final, const Move& move) { + AnimationFactory res(m_cinterface->inner()); + + if (move.drop() != Piece()) { + std::pair dropped = m_cinterface->droppedPoolPiece(); + if (dropped.first != -1 && dropped.second != -1 + && m_cinterface->position()->pool(dropped.first).get(dropped.second) == move.drop()) { + NamedSprite drop = m_cinterface->takePoolSprite(dropped.first, dropped.second); + m_cinterface->setSprite(move.to(), drop); + res.addPreAnimation(Animate::move(drop, move.to())); + return res; + } + else { + NamedSprite drop = m_cinterface->setPiece(move.to(), move.drop(), false); + res.addPreAnimation(Animate::appear(drop)); + } + } + else { + res.setGroup(Base::forward(final, move)); + } + + updatePool(final); + return res; +} + +template +AnimationGroupPtr DropAnimatorMixin::back(const GameState& final, const Move& move) { + AnimationFactory res(m_cinterface->inner()); + + if(move.drop() != Piece()) { + NamedSprite drop = m_cinterface->takeSprite(move.to()); + res.addPostAnimation(Animate::disappear(drop)); + } + else { + res.setGroup(Base::back(final, move)); + } + + updatePool(final); + return res; +} + +} + +#endif // HLVARIANT__DROPANIMATOR_H + -- 2.11.4.GIT