I made a quick sprite class that allows me to read in a simple format and animate it based on a time interval, however for some reason when matched with the intervals from the original gif file they seem off. A lot. The one in the program seems somewhere around one and a half times as fast as the gif and I can't really explain it.
If you need an example here is a
compiled version, and here is the
original gif.
The interval that is used for all frames is 50ms.
Any ideas what may be causing this?
Thanks
struct _sprfheader;
struct _sprfaction;
struct _sprfframe;
struct _spraction;
struct _sprframe;
struct _sprfheader{
DWORD id; // SPRL
char texture[256];
DWORD nactions;
DWORD nframes;
};
struct _sprfaction{
char actionname[50];
DWORD nframes;
D3DXVECTOR2 center;
};
struct _sprfframe{
D3DXVECTOR2 position;
D3DXVECTOR2 textureoffset;
D3DXVECTOR2 texturesize;
D3DXVECTOR2 center;
float rotation;
DWORD duration;
char depth;
};
struct _spraction : _sprfaction{
_sprframe * frames;
};
struct _sprframe : _sprfframe{
_sprframe* next;
};
class cSpriteAnimation{
private:
cGraphics* m_pGraphics;
D3DXMATRIX m_mat;
cTexture m_texture;
_sprframe* m_currentframe;
float m_currenttime;
stdext::hash_map<std::string, _spraction*> m_actions;
// std::map<const char*, _spraction*> m_actions;
public:
cSpriteAnimation();
~cSpriteAnimation();
void SetMatrix(D3DXMATRIX* mat);
bool Create(cGraphics* pGraphics, LPCSTR filename);
void Draw(DWORD timeoffset, float distance = 0.0f);
bool SetAction(const char* action);
void Free(void);
};
cSpriteAnimation::cSpriteAnimation()
{
Free();
};
cSpriteAnimation::~cSpriteAnimation()
{
Free();
};
void cSpriteAnimation::SetMatrix(D3DXMATRIX* mat)
{
if(mat != NULL)
m_mat = (*mat);
};
bool cSpriteAnimation::Create(cGraphics* pGraphics, LPCSTR filename)
{
Free();
FILE* fp;
_sprfheader sprfileheader;
_sprfaction* sprfileaction;
_sprfframe* sprfileframes;
_spraction* sprtempaction;
_sprframe* sprtempframes;
bool ret = true;
if((m_pGraphics = pGraphics) == NULL)
return false;
if((fp = fopen(filename, "rb")) == NULL)
return false;
if((fread(&sprfileheader, sizeof(sprfileheader), 1, fp) != 1) || (sprfileheader.id != 'SPRL')){
ret = false;
}
if(m_texture.Load(m_pGraphics, sprfileheader.texture) == false){
ret = false;
}
sprfileaction = new _sprfaction[sprfileheader.nactions];
sprfileframes = new _sprfframe[sprfileheader.nframes];
if(fread(sprfileaction, sizeof(_sprfaction)*sprfileheader.nactions, 1, fp) != 1 ||
fread(sprfileframes, sizeof(_sprfframe)*sprfileheader.nframes, 1, fp) != 1){
ret = false;
}
fclose(fp);
if(ret == true){
DWORD framecountdone = 0;
for(DWORD iact = 0; iact < sprfileheader.nactions; iact++){
sprtempaction = new _spraction;
memcpy(sprtempaction, &sprfileaction[iact], sizeof(_sprfaction));
sprtempframes = new _sprframe[sprtempaction->nframes];
sprtempaction->frames = sprtempframes;
sprtempframes[sprtempaction->nframes-1].next = &sprtempframes[0];
for(DWORD ifrm = 0; ifrm < sprtempaction->nframes; ifrm++){
memcpy(&sprtempframes[ifrm], &sprfileframes[framecountdone + ifrm], sizeof(_sprfframe));
if(ifrm < sprtempaction->nframes - 1)
sprtempframes[ifrm].next = &sprtempframes[ifrm + 1];
}
framecountdone += sprtempaction->nframes - 1;
m_actions[sprtempaction->actionname] = sprtempaction;
}
}
delete [] sprfileaction;
delete [] sprfileframes;
return ret;
};
void cSpriteAnimation::Draw(DWORD timeoffset, float distance)
{
if(m_currentframe == NULL)
return;
m_currenttime += timeoffset;
while(m_currenttime > m_currentframe->duration){
m_currenttime -= m_currentframe->duration;
m_currentframe = m_currentframe->next;
}
D3DXMATRIX mat;
D3DXMATRIX trans;
RECT mask;
D3DXVECTOR3 tempcenter(m_currentframe->center.x, m_currentframe->center.y, 0.0f);
D3DXVECTOR3 temptranslation(m_currentframe->position.x, m_currentframe->position.y, distance); // Fix it for depth
D3DXQUATERNION temprotation;
D3DXQuaternionRotationYawPitchRoll(&temprotation, 0.0f, 0.0f, m_currentframe->rotation);
D3DXMatrixTransformation(&mat, &tempcenter, NULL, NULL, &tempcenter, &temprotation, &temptranslation);
SetRect(&mask, (int)m_currentframe->textureoffset.x, (int)m_currentframe->textureoffset.y, (int)m_currentframe->textureoffset.x + (int)m_currentframe->texturesize.x, (int)m_currentframe->textureoffset.y + (int)m_currentframe->texturesize.y);
// D3DXMatrixMultiplyTranspose(&mat, &mat, &m_mat);
m_pGraphics->GetSprite()->SetTransform(&mat);
m_pGraphics->GetSprite()->Draw(m_texture.GetTexture(), &mask, NULL, NULL, 0xFFFFFFFF);
return;
};
bool cSpriteAnimation::SetAction(const char* action)
{
if(m_actions.count(action) == 0){
m_currentframe = NULL;
return false;
}
m_currentframe = &m_actions[action]->frames[0];
return true;
};
void cSpriteAnimation::Free(void)
{
m_pGraphics = NULL;
ZeroMemory(&m_mat, sizeof(D3DXMATRIX));
m_currentframe = NULL;;
m_currenttime = 0;
m_texture.Free();
};