 /* 'mrAnimation.cpp' */

 /* Komplementarny plik nagłówka */
#include "mrAnimation.h"

 /* Konstruktor domyślny */
mrAnimation::mrAnimation (void)
{
 m_pkFramesID    = NULL;
 m_iFrames       = 0;
 m_iCurrentFrame = 0;
}

 /* Destruktor domyślny */
mrAnimation::~mrAnimation (void)
{
 m_iFrames       = 0;
 m_iCurrentFrame = 0;

 if (NULL != m_pkFramesID)
 {
  delete [] m_pkFramesID;
  m_pkFramesID    = NULL;
 }
}

 /* Utwórz animację */
void mrAnimation::Create (mrTemplateSet * pkTemplateSet, 
                          mrUInt32 iFrames, mrCellID * pkFramesID)
{
 m_iFrames       = iFrames;
 m_iCurrentFrame = 0;

 m_pkFramesID = new mrCellID [iFrames];

 memcpy (&m_kTemplateSet, pkTemplateSet, sizeof (mrTemplateSet));
 memcpy (m_pkFramesID, pkFramesID, sizeof (mrCellID) * iFrames);
}

 /* Aktualizuje animację (zmienia kadr) */
void mrAnimation::Update (void)
{
 m_iCurrentFrame ++;
 if (m_iCurrentFrame >= m_iFrames)
 {
  m_iCurrentFrame = 0;
 }
}

 /* Renderuje animację */
mrError32 mrAnimation::Render (RECT kDestRect, mrUInt32 iColor, 
                               mrReal32 fAngle)
{
 mrRectText kTextCoord;

 mrReal32 fX1;
 mrReal32 fY1;
 mrReal32 fX2;
 mrReal32 fY2;
 mrReal32 fX3;
 mrReal32 fY3;
 mrReal32 fX4;
 mrReal32 fY4;
 
 if (fAngle != 0)
 {
  /* Zamienia stopnie na radiany */
 fAngle *= 0.0174f;

  /* Tworzy względny prostokąt */
 RECT       kRotRect;
 kRotRect.left   = - (kDestRect.right >> 1);
 kRotRect.top    = - (kDestRect.bottom >> 1);
 kRotRect.right  =   (kDestRect.right >> 1);
 kRotRect.bottom =   (kDestRect.bottom >> 1);
 
  /* Obraca wszystkie wierzchołki */
 fX1 = (mrReal32)(kRotRect.left * cos (fAngle) + 
                           kRotRect.top * sin (fAngle));
 fY1 = (mrReal32)(kRotRect.left * sin (fAngle) - 
                  kRotRect.top * cos (fAngle));

 fX2 = (mrReal32)(kRotRect.right * cos (fAngle) + 
                           kRotRect.top * sin (fAngle));
 fY2 = (mrReal32)(kRotRect.right * sin (fAngle) - 
                  kRotRect.top * cos (fAngle));

 fX3 = (mrReal32)(kRotRect.left * cos (fAngle) + 
                  kRotRect.bottom * sin (fAngle));
 fY3 = (mrReal32)(kRotRect.left * sin (fAngle) - 
                           kRotRect.bottom * cos (fAngle));

 fX4 = (mrReal32)(kRotRect.right * cos (fAngle) + 
                  kRotRect.bottom * sin (fAngle));
 fY4 = (mrReal32)(kRotRect.right * sin (fAngle) - 
                  kRotRect.bottom * cos (fAngle));
 }
  /* Nie obraca */
 else
 {
  fX1 = (mrReal32) -(kDestRect.right >> 1);
  fY1 = (mrReal32)  (kDestRect.bottom >> 1);
  fX2 = (mrReal32)  (kDestRect.right >> 1);
  fY2 = (mrReal32)  (kDestRect.bottom >> 1);
  fX3 = (mrReal32) -(kDestRect.right >> 1);
  fY3 = (mrReal32) -(kDestRect.bottom >> 1);
  fX4 = (mrReal32)  (kDestRect.right >> 1);
  fY4 = (mrReal32) -(kDestRect.bottom >> 1);
 }

  /* Przekształcenie na współrzędne bezwzględne */
 fX1 += kDestRect.left;
 fY1 += kDestRect.top;
 fX2 += kDestRect.left;
 fY2 += kDestRect.top;
 fX3 += kDestRect.left;
 fY3 += kDestRect.top;
 fX4 += kDestRect.left;
 fY4 += kDestRect.top;

  /* Pobierz prostokąt UV ze zbioru szablonów */
 m_kTemplateSet.GetUV (m_pkFramesID [m_iCurrentFrame], &kTextCoord);

  /* Utwórz wierchołki prostokąta */
 mrVertex kVertices [] =
 {  /* x, y, z, w, kolor, współrzędne tekstury (u,v) */
  {fX3, fY3, 0, 1.0f, iColor, kTextCoord.m_fLeft, kTextCoord.m_fTop},
  {fX4, fY4, 0, 1.0f, iColor, kTextCoord.m_fRight, kTextCoord.m_fTop},
  {fX2, fY2, 0, 1.0f, iColor, kTextCoord.m_fRight, kTextCoord.m_fBottom},
  {fX1, fY1, 0, 1.0f, iColor, kTextCoord.m_fLeft, kTextCoord.m_fBottom},
 };
 
  /* Ustaw jako teksturę aktywną */
 m_kTemplateSet.SetActiveTexture ();

  /* Narysuj obrócony prostokąt */
 mrScreen::GetSingleton ()->GetDevice ()->SetVertexShader (
                                      D3DFVF_MIRUSVERTEX);
 if (FAILED (mrScreen::GetSingleton ()->GetDevice ()->DrawPrimitiveUP (
                                      D3DPT_TRIANGLEFAN, 2, kVertices, 
                                      sizeof (mrVertex))) )
 {
  return mrErrorDrawPrimitive;
 }

 return mrNoError;
}

 /* Ustawia bieżący kadr */
void mrAnimation::SetCurrentFrame (mrUInt32 iFrame)
{
 m_iCurrentFrame = iFrame;
}

 /* Zwraca bieżący kadr */
mrUInt32 mrAnimation::GetCurrentFrame (void)
{
 return m_iCurrentFrame;
} 
