123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- #include "aanim.h"
- #include "mclib.h"
- #include "Estring.h"
- extern float frameRate;
- aAnimation::aAnimation()
- {
- currentTime = -1.f;
- infoCount = 0;
- infos = NULL;
- bLoops = 0;
- refX = 0;
- refY = 0;
- direction = 1.0;
- }
- aAnimation::~aAnimation()
- {
- destroy();
- }
- aAnimation& aAnimation::operator=( const aAnimation& src )
- {
- copyData( src );
- return *this;
- }
- aAnimation::aAnimation( const aAnimation& src )
- {
- copyData( src );
- }
- void aAnimation::copyData( const aAnimation& src )
- {
- if ( &src != this )
- {
- currentTime = src.currentTime;
- infoCount = src.infoCount;
- infos = NULL;
- bLoops = src.bLoops;
- refX = src.refX;
- refY = src.refY;
- //Maybe someone already inited this?
- if (infos)
- {
- delete [] infos;
- infos = NULL;
- }
- if ( src.infoCount )
- {
- infos = new MoveInfo[infoCount];
- for ( int i = 0; i < infoCount; i++ )
- {
- infos[i] = src.infos[i];
- }
- }
- }
- }
- long aAnimation::init(FitIniFile* file, const char* headerName)
- {
- EString strToCheck = headerName;
- strToCheck += "AnimationTimeStamps";
- if ( NO_ERR != file->readIdLong( strToCheck, infoCount ) )
- {
- EString strToCheck = headerName;
- strToCheck += "NumTimeStamps";
- file->readIdLong( strToCheck, infoCount );
- }
- strToCheck = headerName;
- strToCheck += "AnimationLoops";
- file->readIdBoolean( strToCheck, bLoops );
- //Maybe someone already inited this?
- if (infos)
- {
- delete [] infos;
- infos = NULL;
- }
- if ( infoCount )
- {
- infos = new MoveInfo[infoCount];
- for ( int i = 0; i < infoCount; i++ )
- {
- strToCheck.Format( "%s%s%ld", headerName, "Time", i );
- file->readIdFloat( strToCheck, infos[i].time );
- strToCheck.Format( "%s%s%ld", headerName, "Color", i );
- if ( NO_ERR != file->readIdLong( strToCheck, infos[i].color ) )
- infos[i].color = 0xffffffff;
- strToCheck.Format( "%s%s%ld%s", headerName, "Pos", i, "X" );
- long tmp;
- file->readIdLong( strToCheck, tmp );
- infos[i].positionX = tmp;
- strToCheck.Format( "%s%s%ld%s", headerName, "Pos", i, "Y" );
- file->readIdLong( strToCheck, tmp );
- infos[i].positionY = tmp;
- strToCheck.Format( "%s%s%ld", headerName, "Scale", i );
- if ( NO_ERR != file->readIdFloat( strToCheck, infos[i].scaleX ) )
- {
- // look for scaleX and scale Y
- strToCheck.Format( "%s%s%ld", headerName, "ScaleX", i );
- if ( NO_ERR != file->readIdFloat( strToCheck, infos[i].scaleX ) )
- {
- infos[i].scaleX = infos[i].scaleY = 1.0f;
- }
- else
- {
- strToCheck.Format( "%s%s%ld", headerName, "ScaleY", i );
- if ( NO_ERR != file->readIdFloat( strToCheck, infos[i].scaleY ) )
- {
- infos[i].scaleY = 1.0f;
- }
- }
- }
- else
- infos[i].scaleY = infos[i].scaleX;
- }
- }
-
- return 0;
- }
-
- void aAnimation::destroy()
- {
- if ( infos )
- delete [] infos;
- infos = NULL;
- infoCount = 0;
- currentTime = -1.f;
- }
- void aAnimation::begin()
- {
- currentTime = 0;
- direction = 1.0;
- }
- void aAnimation::reverseBegin()
- {
- if ( infos && infoCount )
- currentTime = infos[infoCount-1].time;
- else
- currentTime = 0.0;
- direction = -1.0;
- }
-
- void aAnimation::end()
- {
- currentTime = -1.f;
- }
- void aAnimation::update()
- {
- if ( currentTime != -1.f )
- currentTime += direction * frameLength;
- if ( direction < 0 && bLoops && infoCount && infos )
- {
- if ( currentTime < 0 )
- currentTime += infos[infoCount-1].time;
- }
- else if ( infos && currentTime > infos[infoCount-1].time )
- {
- if ( bLoops )
- currentTime -= infos[infoCount-1].time;
- }
- }
- float aAnimation::getXDelta() const
- {
- float t0, t1, p0, p1;
- t1 = p1 = t0 = p0 = 0.f;
- float delta = 0.f;
-
- // figure out where we are in animation
- for ( int j = 0; j < infoCount - 1; j++ )
- {
- if ( infos[j].time <= currentTime && infos[j+1].time > currentTime )
- {
- t0 = infos[j].time;
- t1 = infos[j + 1].time;
- p0 = (infos[j].positionX);
- p1 = (infos[j + 1].positionX);
- break;
- }
- }
-
- // if not done yet
- if ( t1 )
- {
- float dT = currentTime - t0;
- float currentPosition = p0 + dT * ( (p1 - p0)/(t1 -t0) );
- delta = currentPosition - refX;
- }
- else if ( infos )
- {
- delta = infos[infoCount - 1].positionX - refX;
- }
- return delta;
- }
- float aAnimation::getYDelta() const
- {
- float t0, t1, p0, p1;
- t1 = p1 = t0 = p0 = 0.f;
- float delta = 0.f;
-
- // figure out where we are in animation
- for ( int j = 0; j < infoCount - 1; j++ )
- {
- if ( infos[j].time <= currentTime && infos[j+1].time > currentTime )
- {
- t0 = infos[j].time;
- t1 = infos[j + 1].time;
- p0 = (infos[j].positionY);
- p1 = (infos[j + 1].positionY);
- break;
- }
- }
-
- // if not done yet
- if ( t1 )
- {
- float dT = currentTime - t0;
- float currentPosition = p0 + dT * ( (p1 - p0)/(t1 -t0) );
- delta = currentPosition - refY;
- }
- else if ( infos )
- {
- delta = infos[infoCount - 1].positionY - refY ;
- }
- return delta;
- }
- float aAnimation::getScaleX() const
- {
- float t0, t1, p0, p1;
- t1 = p1 = t0 = p0 = 0.f;
- float curScale = 1.0;
-
- // figure out where we are in animation
- for ( int j = 0; j < infoCount - 1; j++ )
- {
- if ( infos[j].time <= currentTime && infos[j+1].time > currentTime )
- {
- t0 = infos[j].time;
- t1 = infos[j + 1].time;
- p0 = (infos[j].scaleX);
- p1 = (infos[j + 1].scaleX);
- break;
- }
- }
-
- // if not done yet
- if ( t1 )
- {
- float dT = currentTime - t0;
- curScale = p0 + dT * ( (p1 - p0)/(t1 -t0) );
- }
- else if ( infos )
- {
- curScale = infos[infoCount - 1].scaleX ;
- }
- return curScale;
- }
- float aAnimation::getScaleY() const
- {
- float t0, t1, p0, p1;
- t1 = p1 = t0 = p0 = 0.f;
- float curScale = 1.0;
-
- // figure out where we are in animation
- for ( int j = 0; j < infoCount - 1; j++ )
- {
- if ( infos[j].time <= currentTime && infos[j+1].time > currentTime )
- {
- t0 = infos[j].time;
- t1 = infos[j + 1].time;
- p0 = (infos[j].scaleY);
- p1 = (infos[j + 1].scaleY);
- break;
- }
- }
-
- // if not done yet
- if ( t1 )
- {
- float dT = currentTime - t0;
- curScale = p0 + dT * ( (p1 - p0)/(t1 -t0) );
- }
- else if ( infos )
- {
- curScale = infos[infoCount - 1].scaleY ;
- }
- return curScale;
- }
- unsigned long aAnimation::getColor( ) const
- {
- return getColor( currentTime );
- }
- unsigned long aAnimation::getColor( float time ) const
- {
- float t0, t1;
- if ( infoCount && (time > infos[infoCount-1].time) && bLoops )
- {
- float numCycles = infos[infoCount-1].time ? time/infos[infoCount-1].time : 0;
- int numCyc = (long)numCycles;
- time -= ((float)numCyc * infos[infoCount-1].time);
- }
- t1 = t0 = 0.f;
- unsigned long color = 0xffffffff;
- unsigned long color1, color2;
- color1 = color2 = 0;
-
- // figure out where we are in animation
- for ( int j = 0; j < infoCount - 1; j++ )
- {
- if ( infos[j].time <= time && infos[j+1].time > time )
- {
- t0 = infos[j].time;
- t1 = infos[j + 1].time;
- color1 = (infos[j].color);
- color2 = (infos[j + 1].color);
- break;
- }
- }
-
- // if not done yet
- if ( t1 )
- {
- float totalTime = t1 - t0;
- float tmpTime= time - t0;
- float percent = tmpTime/totalTime;
- return interpolateColor( color1, color2, percent );
-
-
- }
- else if ( infos )
- {
- return infos[infoCount-1].color;
- }
- return color;
- }
- void aAnimation::setReferencePoints( float X, float Y )
- {
- refX = X;
- refY = Y;
- }
- bool aAnimation::isDone() const
- {
- if ( bLoops )
- return 0;
-
- if ( direction < 0 )
- return currentTime < 0 ? 1 : 0;
- else if ( infos && currentTime > infos[infoCount-1].time )
- {
- return 1;
- }
- return 0;
- }
- long aAnimation::initWithBlockName( FitIniFile* file, const char* blockName )
- {
- if ( NO_ERR != file->seekBlock( blockName ) )
- {
- char errorStr[255];
- sprintf( errorStr, "couldn't find block %s in file %s", blockName, file->getFilename() );
- Assert( 0, 0, errorStr );
- return -1;
- }
- return init( file, "" );
- }
- float aAnimation::getMaxTime()
- {
- if ( infos && infoCount)
- {
- return infos[infoCount-1].time;
- }
- return -1;
- }
- long aAnimGroup::init( FitIniFile* file, const char* blockName )
- {
- if ( NO_ERR != file->seekBlock( blockName ) )
- {
- char errorStr[255];
- sprintf( errorStr, "couldn't find block %s in file %s", blockName, file->getFilename() );
- Assert( 0, 0, errorStr );
- return -1;
- }
- animations[NORMAL].init( file, "Normal" );
- animations[HIGHLIGHT].init( file, "Highlight" );
- animations[PRESSED].init( file, "Pressed" );
- animations[PRESSEDHIGHLIGHT].init( file, "HighlightPressed" );
- animations[DISABLED].init( file, "Disabled" );
- return 0;
- }
- void aAnimGroup::update()
- {
- animations[NORMAL].update();
- animations[getState()].update();
- }
- long aAnimGroup::getCurrentColor( aAnimGroup::STATE state) const
- {
- return animations[state].getColor();
- }
- void aAnimGroup::setState( aAnimGroup::STATE newState )
- {
- if ( newState != curState )
- {
- curState = newState;
- if ( newState != NORMAL )
- animations[curState].begin();
- }
- }
- aAnimGroup::STATE aAnimGroup::getState() const
- {
- return curState;
- }
|