Files
itgmania212121/stepmania/src/BGAnimationLayer.cpp
T

1050 lines
29 KiB
C++
Raw Normal View History

2003-02-16 04:01:45 +00:00
#include "global.h"
2002-09-29 05:06:18 +00:00
#include "BGAnimationLayer.h"
#include "PrefsManager.h"
#include "GameState.h"
#include "IniFile.h"
#include "RageMath.h"
2003-03-05 02:52:40 +00:00
#include "RageTimer.h"
#include "RageLog.h"
2003-03-10 05:07:00 +00:00
#include "song.h"
2003-04-03 22:10:40 +00:00
#include "ActorCollision.h"
#include "Sprite.h"
#include "RageDisplay.h"
#include "ActorUtil.h"
#include "arch/ArchHooks/ArchHooks.h"
#include "RageTextureManager.h"
2003-07-22 07:47:27 +00:00
#include "RageFile.h"
2004-02-14 23:22:23 +00:00
#include "LuaHelpers.h"
2002-09-29 05:06:18 +00:00
2003-03-05 02:52:40 +00:00
const float PARTICLE_SPEED = 300;
2002-09-29 05:06:18 +00:00
const float SPIRAL_MAX_ZOOM = 2;
const float SPIRAL_MIN_ZOOM = 0.3f;
2004-09-21 08:41:17 +00:00
#define MAX_TILES_WIDE int(SCREEN_WIDTH/32+2)
#define MAX_TILES_HIGH int(SCREEN_HEIGHT/32+2)
#define MAX_SPRITES (MAX_TILES_WIDE*MAX_TILES_HIGH)
2002-09-29 05:06:18 +00:00
2004-09-24 02:52:07 +00:00
#define FullScreenRectF RectF(SCREEN_LEFT,SCREEN_TOP,SCREEN_RIGHT,SCREEN_BOTTOM)
2003-10-31 00:01:16 +00:00
2002-09-29 05:06:18 +00:00
BGAnimationLayer::BGAnimationLayer( bool Generic )
2002-09-29 05:06:18 +00:00
{
/* If Generic is false, this is a layer in a real BGA--one that was loaded
* by simply constructing a BGAnimation. These normally have a position
* of 0,0 (top-left of the screen). Loaded images are given a default position
* of 320x240, centered in the screen. Additionally, the "On" command will
* be run automatically. Example:
*
* BGAnimation bga;
* bga.Load( path );
* this->AddChind( &bga );
*
* If Generic is true, then we act like any other actor. We assume we don't
* know anything about where we're positioned. Loaded images are given a
* default position of 0x0. The "On" command is not run; we'll receive that
* from the owner through COMMAND(). Example:
*
* AutoActor image;
* image.Load( path );
* ON_COMMAND( image );
* this->AddChind( &image );
*
* TYPE_PARTICLES and TYPE_TILES are currently not supported in this mode.
*
*/
m_bGeneric = Generic;
2003-03-05 02:52:40 +00:00
Init();
}
BGAnimationLayer::~BGAnimationLayer()
{
Unload();
}
void BGAnimationLayer::Unload()
{
2004-01-25 22:22:40 +00:00
ActorFrame::DeleteAllChildren();
}
2003-03-05 02:52:40 +00:00
void BGAnimationLayer::Init()
{
Unload();
m_fRepeatCommandEverySeconds = -1;
2003-10-24 08:49:48 +00:00
m_fSecondsUntilNextCommand = 0;
m_fUpdateRate = 1;
m_fFOV = -1; // no change
m_bLighting = false;
2003-03-05 02:52:40 +00:00
// m_bCycleColor = false;
// m_bCycleAlpha = false;
// m_Effect = EFFECT_STRETCH_STILL;
m_vParticleVelocity.clear();
2003-03-05 02:52:40 +00:00
m_Type = TYPE_SPRITE;
2003-10-31 00:01:16 +00:00
m_fTexCoordVelocityX = 0;
m_fTexCoordVelocityY = 0;
2003-03-05 02:52:40 +00:00
m_fZoomMin = 1;
m_fZoomMax = 1;
m_fVelocityXMin = 10;
m_fVelocityXMax = 10;
m_fVelocityYMin = 0;
m_fVelocityYMax = 0;
m_fVelocityZMin = 0;
m_fVelocityZMax = 0;
m_fOverrideSpeed = 0;
m_iNumParticles = 10;
m_bParticlesBounce = false;
2003-03-09 09:25:32 +00:00
m_iNumTilesWide = -1;
m_iNumTilesHigh = -1;
2003-03-05 02:52:40 +00:00
m_fTilesStartX = 0;
m_fTilesStartY = 0;
2003-03-09 09:25:32 +00:00
m_fTilesSpacingX = -1;
m_fTilesSpacingY = -1;
2003-03-05 02:52:40 +00:00
m_fTileVelocityX = 0;
m_fTileVelocityY = 0;
/*
m_PosX = m_PosY = 0;
m_Zoom = 0;
m_Rot = 0;
m_ShowTime = 0;
m_HideTime = 0;
m_TweenStartTime = 0;
m_TweenX = m_TweenY = 0.0;
m_TweenSpeed = 0;
m_TweenState = 0;
m_TweenPassedX = m_TweenPassedY = 0;
2003-03-05 02:52:40 +00:00
*/
2002-09-29 05:06:18 +00:00
}
2003-01-09 04:47:23 +00:00
/* Static background layers are simple, uncomposited background images with nothing
* behind them. Since they have nothing behind them, they have no need for alpha,
* so turn that off. */
void BGAnimationLayer::LoadFromStaticGraphic( const CString& sPath )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
Init();
Sprite* pSprite = new Sprite;
2004-03-26 08:05:07 +00:00
pSprite->LoadBG( sPath );
2004-09-24 02:52:07 +00:00
pSprite->StretchTo( FullScreenRectF );
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
2002-09-29 05:06:18 +00:00
}
void BGAnimationLayer::LoadFromMovie( const CString& sMoviePath )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
Init();
Sprite* pSprite = new Sprite;
pSprite->LoadBG( sMoviePath );
2004-09-24 02:52:07 +00:00
pSprite->StretchTo( FullScreenRectF );
pSprite->EnableAnimation( false );
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
2002-09-29 05:06:18 +00:00
}
void BGAnimationLayer::LoadFromVisualization( const CString& sMoviePath )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
Init();
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->LoadBG( sMoviePath );
2004-09-24 02:52:07 +00:00
pSprite->StretchTo( FullScreenRectF );
pSprite->SetBlendMode( BLEND_ADD );
2002-09-29 05:06:18 +00:00
}
2003-03-05 02:52:40 +00:00
void BGAnimationLayer::LoadFromAniLayerFile( const CString& sPath )
2002-09-29 05:06:18 +00:00
{
/* Generic BGAs are new. Animation directories with no INI are old and obsolete.
* Don't combine them. */
ASSERT( !m_bGeneric );
2003-03-05 02:52:40 +00:00
Init();
2003-02-14 22:46:45 +00:00
CString lcPath = sPath;
lcPath.MakeLower();
2002-09-29 05:06:18 +00:00
2003-02-14 22:46:45 +00:00
if( lcPath.Find("usesongbg") != -1 )
2002-09-29 05:06:18 +00:00
{
2003-10-30 20:34:38 +00:00
const Song* pSong = GAMESTATE->m_pCurSong;
CString sSongBGPath;
if( pSong && pSong->HasBackground() )
sSongBGPath = pSong->GetBackgroundPath();
else
sSongBGPath = THEME->GetPathToG("Common fallback background");
2002-09-29 05:06:18 +00:00
LoadFromStaticGraphic( sSongBGPath );
return; // this will ignore other effects in the file name
}
const CString EFFECT_STRING[NUM_EFFECTS] = {
"center",
"stretchstill",
"stretchscrollleft",
2002-09-29 05:06:18 +00:00
"stretchscrollright",
"stretchscrollup",
"stretchscrolldown",
"stretchwater",
"stretchbubble",
"stretchtwist",
"stretchspin",
"particlesspiralout",
"particlesspiralin",
"particlesfloatup",
"particlesfloatdown",
"particlesfloatleft",
"particlesfloatright",
"particlesbounce",
"tilestill",
"tilescrollleft",
"tilescrollright",
"tilescrollup",
"tilescrolldown",
"tileflipx",
"tileflipy",
"tilepulse",
};
2003-03-05 02:52:40 +00:00
Effect effect = EFFECT_CENTER;
2002-09-29 05:06:18 +00:00
for( int i=0; i<NUM_EFFECTS; i++ )
2003-02-14 22:46:45 +00:00
if( lcPath.Find(EFFECT_STRING[i]) != -1 )
2003-03-05 02:52:40 +00:00
effect = (Effect)i;
2002-09-29 05:06:18 +00:00
2003-03-05 02:52:40 +00:00
switch( effect )
2002-09-29 05:06:18 +00:00
{
case EFFECT_CENTER:
{
m_Type = TYPE_SPRITE;
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->Load( sPath );
2004-11-05 06:35:10 +00:00
pSprite->SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y );
}
2002-09-29 05:06:18 +00:00
break;
case EFFECT_STRETCH_STILL:
case EFFECT_STRETCH_SCROLL_LEFT:
case EFFECT_STRETCH_SCROLL_RIGHT:
case EFFECT_STRETCH_SCROLL_UP:
case EFFECT_STRETCH_SCROLL_DOWN:
case EFFECT_STRETCH_WATER:
case EFFECT_STRETCH_BUBBLE:
case EFFECT_STRETCH_TWIST:
{
2003-10-31 00:01:16 +00:00
m_Type = TYPE_SPRITE;
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
RageTextureID ID(sPath);
ID.bStretch = true;
pSprite->LoadBG( ID );
2004-09-24 02:52:07 +00:00
pSprite->StretchTo( FullScreenRectF );
pSprite->SetCustomTextureRect( RectF(0,0,1,1) );
2003-03-05 02:52:40 +00:00
switch( effect )
{
2003-10-31 00:01:16 +00:00
case EFFECT_STRETCH_SCROLL_LEFT: m_fTexCoordVelocityX = +0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_RIGHT: m_fTexCoordVelocityX = -0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_UP: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = +0.5f; break;
case EFFECT_STRETCH_SCROLL_DOWN: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = -0.5f; break;
break;
}
2002-09-29 05:06:18 +00:00
}
break;
2003-03-05 02:52:40 +00:00
case EFFECT_STRETCH_SPIN:
{
2003-10-31 00:01:16 +00:00
m_Type = TYPE_SPRITE;
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->LoadBG( sPath );
2004-09-24 02:52:07 +00:00
const RectF StretchedFullScreenRectF(
FullScreenRectF.left-200,
FullScreenRectF.top-200,
FullScreenRectF.right+200,
FullScreenRectF.bottom+200 );
2003-10-30 22:00:08 +00:00
2004-09-24 02:52:07 +00:00
pSprite->ScaleToCover( StretchedFullScreenRectF );
pSprite->SetEffectSpin( RageVector3(0,0,60) );
}
break;
2002-09-29 05:06:18 +00:00
case EFFECT_PARTICLES_SPIRAL_OUT:
case EFFECT_PARTICLES_SPIRAL_IN:
2003-10-31 00:01:16 +00:00
case EFFECT_PARTICLES_FLOAT_UP:
2002-09-29 05:06:18 +00:00
case EFFECT_PARTICLES_FLOAT_DOWN:
case EFFECT_PARTICLES_FLOAT_LEFT:
case EFFECT_PARTICLES_FLOAT_RIGHT:
case EFFECT_PARTICLES_BOUNCE:
{
2003-03-05 02:52:40 +00:00
m_Type = TYPE_PARTICLES;
Sprite s;
s.Load( sPath );
int iSpriteArea = int( s.GetUnzoomedWidth()*s.GetUnzoomedHeight() );
2004-09-21 08:41:17 +00:00
const int iMaxArea = int(SCREEN_WIDTH*SCREEN_HEIGHT);
m_iNumParticles = iMaxArea / iSpriteArea;
m_iNumParticles = min( m_iNumParticles, MAX_SPRITES );
for( int i=0; i<m_iNumParticles; i++ )
2002-09-29 05:06:18 +00:00
{
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->Load( sPath );
pSprite->SetZoom( 0.7f + 0.6f*i/(float)m_iNumParticles );
pSprite->SetX( randomf( GetGuardRailLeft(pSprite), GetGuardRailRight(pSprite) ) );
pSprite->SetY( randomf( GetGuardRailTop(pSprite), GetGuardRailBottom(pSprite) ) );
2002-09-29 05:06:18 +00:00
2003-03-05 02:52:40 +00:00
switch( effect )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
case EFFECT_PARTICLES_FLOAT_UP:
case EFFECT_PARTICLES_SPIRAL_OUT:
2003-10-30 00:08:20 +00:00
m_vParticleVelocity.push_back( RageVector3( 0, -PARTICLE_SPEED*pSprite->GetZoom(), 0 ) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_PARTICLES_FLOAT_DOWN:
case EFFECT_PARTICLES_SPIRAL_IN:
2003-10-30 00:08:20 +00:00
m_vParticleVelocity.push_back( RageVector3( 0, PARTICLE_SPEED*pSprite->GetZoom(), 0 ) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_PARTICLES_FLOAT_LEFT:
2003-10-30 00:08:20 +00:00
m_vParticleVelocity.push_back( RageVector3( -PARTICLE_SPEED*pSprite->GetZoom(), 0, 0 ) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_PARTICLES_FLOAT_RIGHT:
2003-10-30 00:08:20 +00:00
m_vParticleVelocity.push_back( RageVector3( +PARTICLE_SPEED*pSprite->GetZoom(), 0, 0 ) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_PARTICLES_BOUNCE:
m_bParticlesBounce = true;
pSprite->SetZoom( 1 );
2003-10-30 00:08:20 +00:00
m_vParticleVelocity.push_back( RageVector3( randomf(), randomf(), 0 ) );
2003-03-05 02:52:40 +00:00
RageVec3Normalize( &m_vParticleVelocity[i], &m_vParticleVelocity[i] );
break;
default:
ASSERT(0);
2002-09-29 05:06:18 +00:00
}
}
}
break;
case EFFECT_TILE_STILL:
case EFFECT_TILE_SCROLL_LEFT:
case EFFECT_TILE_SCROLL_RIGHT:
case EFFECT_TILE_SCROLL_UP:
case EFFECT_TILE_SCROLL_DOWN:
case EFFECT_TILE_FLIP_X:
case EFFECT_TILE_FLIP_Y:
case EFFECT_TILE_PULSE:
{
2003-03-05 02:52:40 +00:00
m_Type = TYPE_TILES;
RageTextureID ID(sPath);
ID.bStretch = true;
Sprite s;
s.Load( ID );
m_iNumTilesWide = 2+int(SCREEN_WIDTH /s.GetUnzoomedWidth());
2003-03-05 02:52:40 +00:00
m_iNumTilesWide = min( m_iNumTilesWide, MAX_TILES_WIDE );
m_iNumTilesHigh = 2+int(SCREEN_HEIGHT/s.GetUnzoomedHeight());
2003-03-05 02:52:40 +00:00
m_iNumTilesHigh = min( m_iNumTilesHigh, MAX_TILES_HIGH );
m_fTilesStartX = s.GetUnzoomedWidth() / 2;
m_fTilesStartY = s.GetUnzoomedHeight() / 2;
m_fTilesSpacingX = s.GetUnzoomedWidth();
m_fTilesSpacingY = s.GetUnzoomedHeight();
2003-03-05 02:52:40 +00:00
for( int x=0; x<m_iNumTilesWide; x++ )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
for( int y=0; y<m_iNumTilesHigh; y++ )
2002-09-29 05:06:18 +00:00
{
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->Load( ID );
pSprite->SetTextureWrapping( true ); // gets rid of some "cracks"
2003-03-05 02:52:40 +00:00
switch( effect )
{
case EFFECT_TILE_STILL:
break;
case EFFECT_TILE_SCROLL_LEFT:
m_fTileVelocityX = -PARTICLE_SPEED;
break;
case EFFECT_TILE_SCROLL_RIGHT:
m_fTileVelocityX = +PARTICLE_SPEED;
break;
case EFFECT_TILE_SCROLL_UP:
m_fTileVelocityY = -PARTICLE_SPEED;
break;
case EFFECT_TILE_SCROLL_DOWN:
m_fTileVelocityY = +PARTICLE_SPEED;
break;
case EFFECT_TILE_FLIP_X:
pSprite->SetEffectSpin( RageVector3(2,0,0) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_TILE_FLIP_Y:
pSprite->SetEffectSpin( RageVector3(0,2,0) );
2003-03-05 02:52:40 +00:00
break;
case EFFECT_TILE_PULSE:
pSprite->SetEffectPulse( 1, 0.3f, 1.f );
2003-03-05 02:52:40 +00:00
break;
default:
ASSERT(0);
}
2002-09-29 05:06:18 +00:00
}
}
}
break;
default:
ASSERT(0);
}
2004-12-27 10:28:41 +00:00
CString sHint = sPath;
sHint.MakeLower();
2003-03-05 02:52:40 +00:00
2004-12-27 10:28:41 +00:00
if( sHint.Find("cyclecolor") != -1 )
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->SetEffectRainbow( 5 );
2003-03-05 02:52:40 +00:00
2004-12-27 10:28:41 +00:00
if( sHint.Find("cyclealpha") != -1 )
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->SetEffectDiffuseShift( 2, RageColor(1,1,1,1), RageColor(1,1,1,0) );
2002-09-29 05:06:18 +00:00
2004-12-27 10:28:41 +00:00
if( sHint.Find("startonrandomframe") != -1 )
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->SetState( rand()%m_SubActors[i]->GetNumStates() );
2002-09-29 05:06:18 +00:00
2004-12-27 10:28:41 +00:00
if( sHint.Find("dontanimate") != -1 )
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->StopAnimating();
2002-09-29 05:06:18 +00:00
2004-12-27 10:28:41 +00:00
if( sHint.Find("add") != -1 )
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->SetBlendMode( BLEND_ADD );
2002-09-29 05:06:18 +00:00
}
void BGAnimationLayer::LoadFromIni( const CString& sAniDir_, const IniKey& layer )
2003-03-05 02:52:40 +00:00
{
CString sAniDir = sAniDir_;
2003-03-05 02:52:40 +00:00
Init();
2003-12-10 09:44:16 +00:00
if( sAniDir.Right(1) != "/" )
sAniDir += "/";
2003-03-05 02:52:40 +00:00
DEBUG_ASSERT( IsADirectory(sAniDir) );
2003-03-05 02:52:40 +00:00
CHECKPOINT_M( ssprintf( "BGAnimationLayer::LoadFromIni \"%s\" %s",
sAniDir.c_str(), m_bGeneric? "(generic) ":"" ) );
2004-01-12 22:06:39 +00:00
{
CString sPlayer;
if( layer.GetValue("Player", sPlayer) )
ASSERT_M( 0, "The BGAnimation parameter 'Player' is deprecated. Please use 'Condition=IsPlayerEnabled(p)'." );
2004-01-12 22:06:39 +00:00
}
2003-03-05 02:52:40 +00:00
2004-02-14 23:22:23 +00:00
{
CString expr;
if( layer.GetValue("Cond",expr) || layer.GetValue("Condition",expr) )
2004-02-14 23:22:23 +00:00
{
2004-09-24 02:52:07 +00:00
if( !Lua::RunExpressionB( expr ) )
2004-02-14 23:22:23 +00:00
return;
}
}
bool bStretch = false;
2003-10-31 00:01:16 +00:00
{
CString type = "sprite";
layer.GetValue( "Type", type );
2003-10-31 00:01:16 +00:00
type.MakeLower();
/* The preferred way of stretching a sprite to fit the screen is "Type=sprite"
* and "stretch=1". "type=1" is for backwards-compatibility. */
layer.GetValue( "Stretch", bStretch );
2003-10-31 00:01:16 +00:00
// Check for string match first, then do integer match.
// "if(atoi(type)==0)" was matching against all string matches.
// -Chris
if( stricmp(type,"sprite")==0 )
{
m_Type = TYPE_SPRITE;
}
else if( stricmp(type,"particles")==0 )
{
m_Type = TYPE_PARTICLES;
}
else if( stricmp(type,"tiles")==0 )
{
m_Type = TYPE_TILES;
}
else if( atoi(type) == 1 )
{
m_Type = TYPE_SPRITE;
bStretch = true;
}
else if( atoi(type) == 2 )
{
m_Type = TYPE_PARTICLES;
}
else if( atoi(type) == 3 )
{
m_Type = TYPE_TILES;
}
2003-10-31 00:01:16 +00:00
else
{
m_Type = TYPE_SPRITE;
}
2003-10-31 00:01:16 +00:00
}
2003-10-31 01:55:17 +00:00
{
for( IniKey::const_iterator i = layer.begin();
i != layer.end(); ++i)
2003-10-31 01:55:17 +00:00
{
CString KeyName = i->first; /* "OnCommand" */
KeyName.MakeLower();
if( KeyName.Right(7) != "command" )
continue; /* not a command */
const CString &sData = i->second;
Commands cmds = ParseCommands( sData );
CString sCmdName;
2003-10-31 01:55:17 +00:00
/* Special case: "Command=foo" -> "OnCommand=foo" */
if( KeyName.size() == 7 )
sCmdName="on";
2003-10-31 01:55:17 +00:00
else
sCmdName = KeyName.Left( KeyName.size()-7 );
m_mapNameToCommands[sCmdName] = cmds;
2003-10-31 01:55:17 +00:00
}
}
layer.GetValue( "CommandRepeatSeconds", m_fRepeatCommandEverySeconds );
2003-10-24 08:49:48 +00:00
m_fSecondsUntilNextCommand = m_fRepeatCommandEverySeconds;
layer.GetValue( "FOV", m_fFOV );
layer.GetValue( "Lighting", m_bLighting );
layer.GetValue( "TexCoordVelocityX", m_fTexCoordVelocityX );
layer.GetValue( "TexCoordVelocityY", m_fTexCoordVelocityY );
layer.GetValue( "DrawCond", m_sDrawCond );
2004-03-27 00:23:29 +00:00
2003-10-31 00:01:16 +00:00
// compat:
layer.GetValue( "StretchTexCoordVelocityX", m_fTexCoordVelocityX );
layer.GetValue( "StretchTexCoordVelocityY", m_fTexCoordVelocityY );
layer.GetValue( "ZoomMin", m_fZoomMin );
layer.GetValue( "ZoomMax", m_fZoomMax );
layer.GetValue( "VelocityXMin", m_fVelocityXMin );
layer.GetValue( "VelocityXMax", m_fVelocityXMax );
layer.GetValue( "VelocityYMin", m_fVelocityYMin );
layer.GetValue( "VelocityYMax", m_fVelocityYMax );
layer.GetValue( "VelocityZMin", m_fVelocityZMin );
layer.GetValue( "VelocityZMax", m_fVelocityZMax );
layer.GetValue( "OverrideSpeed", m_fOverrideSpeed );
layer.GetValue( "NumParticles", m_iNumParticles );
layer.GetValue( "ParticlesBounce", m_bParticlesBounce );
layer.GetValue( "TilesStartX", m_fTilesStartX );
layer.GetValue( "TilesStartY", m_fTilesStartY );
layer.GetValue( "TilesSpacingX", m_fTilesSpacingX );
layer.GetValue( "TilesSpacingY", m_fTilesSpacingY );
layer.GetValue( "TileVelocityX", m_fTileVelocityX );
layer.GetValue( "TileVelocityY", m_fTileVelocityY );
2003-03-05 02:52:40 +00:00
2003-10-31 00:01:16 +00:00
bool NeedTextureStretch = false;
if( m_fTexCoordVelocityX != 0 ||
m_fTexCoordVelocityY != 0 )
NeedTextureStretch = true;
2003-03-05 02:52:40 +00:00
switch( m_Type )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
case TYPE_SPRITE:
{
Actor* pActor = LoadFromActorFile( sAniDir, layer );
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pActor );
if( !m_bGeneric )
{
if( bStretch )
2004-09-24 02:52:07 +00:00
pActor->StretchTo( FullScreenRectF );
else
2004-11-05 06:35:10 +00:00
pActor->SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y );
}
2002-09-29 05:06:18 +00:00
}
2003-03-05 02:52:40 +00:00
break;
case TYPE_PARTICLES:
2002-09-29 05:06:18 +00:00
{
2004-01-25 22:22:40 +00:00
CString sFile;
layer.GetValue( "File", sFile );
2004-01-25 22:22:40 +00:00
FixSlashesInPlace( sFile );
CString sPath = sAniDir+sFile;
CollapsePath( sPath );
ASSERT( !m_bGeneric );
for( int i=0; i<m_iNumParticles; i++ )
2003-03-05 02:52:40 +00:00
{
Actor* pActor = MakeActor( sPath );
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pActor );
2004-09-24 02:52:07 +00:00
pActor->SetXY( randomf(float(FullScreenRectF.left),float(FullScreenRectF.right)),
randomf(float(FullScreenRectF.top),float(FullScreenRectF.bottom)) );
pActor->SetZoom( randomf(m_fZoomMin,m_fZoomMax) );
m_vParticleVelocity.push_back( RageVector3(
2003-03-05 02:52:40 +00:00
randomf(m_fVelocityXMin,m_fVelocityXMax),
randomf(m_fVelocityYMin,m_fVelocityYMax),
randomf(m_fVelocityZMin,m_fVelocityZMax) ) );
2003-03-05 02:52:40 +00:00
if( m_fOverrideSpeed != 0 )
{
RageVec3Normalize( &m_vParticleVelocity[i], &m_vParticleVelocity[i] );
m_vParticleVelocity[i] *= m_fOverrideSpeed;
}
}
2002-09-29 05:06:18 +00:00
}
2003-03-05 02:52:40 +00:00
break;
case TYPE_TILES:
{
2004-01-25 22:22:40 +00:00
CString sFile;
layer.GetValue( "File", sFile );
2004-01-25 22:22:40 +00:00
FixSlashesInPlace( sFile );
CString sPath = sAniDir+sFile;
CollapsePath( sPath );
ASSERT( !m_bGeneric );
Sprite s;
RageTextureID ID(sPath);
ID.bStretch = true;
s.Load( ID );
2003-03-09 09:25:32 +00:00
if( m_fTilesSpacingX == -1 )
2003-03-25 19:32:17 +00:00
m_fTilesSpacingX = s.GetUnzoomedWidth();
2003-03-09 09:25:32 +00:00
if( m_fTilesSpacingY == -1 )
2003-03-25 19:32:17 +00:00
m_fTilesSpacingY = s.GetUnzoomedHeight();
2003-03-05 02:52:40 +00:00
m_iNumTilesWide = 2+(int)(SCREEN_WIDTH /m_fTilesSpacingX);
m_iNumTilesHigh = 2+(int)(SCREEN_HEIGHT/m_fTilesSpacingY);
unsigned NumSprites = m_iNumTilesWide * m_iNumTilesHigh;
for( unsigned i=0; i<NumSprites; i++ )
2003-03-05 02:52:40 +00:00
{
Sprite* pSprite = new Sprite;
2004-01-25 22:22:40 +00:00
m_SubActors.push_back( pSprite );
pSprite->Load( ID );
pSprite->SetTextureWrapping( true ); // gets rid of some "cracks"
pSprite->SetZoom( randomf(m_fZoomMin,m_fZoomMax) );
2003-03-05 02:52:40 +00:00
}
}
break;
default:
ASSERT(0);
2002-09-29 05:06:18 +00:00
}
2003-03-05 02:52:40 +00:00
bool bStartOnRandomFrame = false;
layer.GetValue( "StartOnRandomFrame", bStartOnRandomFrame );
2003-03-05 02:52:40 +00:00
if( bStartOnRandomFrame )
{
2004-01-25 22:22:40 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->SetState( rand()%m_SubActors[i]->GetNumStates() );
2003-03-05 02:52:40 +00:00
}
if( !m_bGeneric )
PlayCommand( "On" );
2003-03-05 02:52:40 +00:00
}
void BGAnimationLayer::Update( float fDeltaTime )
{
if( m_fHibernateSecondsLeft > 0 )
return;
fDeltaTime *= m_fUpdateRate;
2003-03-05 02:52:40 +00:00
const float fSongBeat = GAMESTATE->m_fSongBeat;
2002-09-29 05:06:18 +00:00
2004-09-21 07:53:39 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
2004-01-25 22:22:40 +00:00
m_SubActors[i]->Update( fDeltaTime );
2002-09-29 05:06:18 +00:00
2003-03-05 02:52:40 +00:00
switch( m_Type )
2002-09-29 05:06:18 +00:00
{
2003-03-05 02:52:40 +00:00
case TYPE_SPRITE:
if( m_fTexCoordVelocityX || m_fTexCoordVelocityY )
2002-09-29 05:06:18 +00:00
{
for( unsigned i=0; i<m_SubActors.size(); i++ )
{
Sprite *pSprite = (Sprite*)m_SubActors[i];
pSprite->StretchTexCoords(
2003-10-31 00:01:16 +00:00
fDeltaTime*m_fTexCoordVelocityX,
fDeltaTime*m_fTexCoordVelocityY );
}
2003-03-05 02:52:40 +00:00
}
2002-09-29 05:06:18 +00:00
break;
2003-03-05 02:52:40 +00:00
/* case EFFECT_PARTICLES_SPIRAL_OUT:
2002-09-29 05:06:18 +00:00
for( i=0; i<m_iNumSprites; i++ )
{
2004-01-25 22:22:40 +00:00
m_SubActors[i].SetZoom( m_SubActors[i].GetZoom() + fDeltaTime );
if( m_SubActors[i].GetZoom() > SPIRAL_MAX_ZOOM )
m_SubActors[i].SetZoom( SPIRAL_MIN_ZOOM );
2002-09-29 05:06:18 +00:00
2004-01-25 22:22:40 +00:00
m_SubActors[i].SetRotationZ( m_SubActors[i].GetRotationZ() + fDeltaTime );
2002-09-29 05:06:18 +00:00
2004-01-25 22:22:40 +00:00
float fRadius = (m_SubActors[i].GetZoom()-SPIRAL_MIN_ZOOM);
2002-09-29 05:06:18 +00:00
fRadius *= fRadius;
fRadius *= 200;
2004-11-05 06:35:10 +00:00
m_SubActors[i].SetX( SCREEN_CENTER_X + cosf(m_SubActors[i].GetRotationZ())*fRadius );
m_SubActors[i].SetY( SCREEN_CENTER_Y + sinf(m_SubActors[i].GetRotationZ())*fRadius );
2002-09-29 05:06:18 +00:00
}
break;
case EFFECT_PARTICLES_SPIRAL_IN:
for( i=0; i<m_iNumSprites; i++ )
{
2004-01-25 22:22:40 +00:00
m_SubActors[i].SetZoom( m_SubActors[i].GetZoom() - fDeltaTime );
if( m_SubActors[i].GetZoom() < SPIRAL_MIN_ZOOM )
m_SubActors[i].SetZoom( SPIRAL_MAX_ZOOM );
2002-09-29 05:06:18 +00:00
2004-01-25 22:22:40 +00:00
m_SubActors[i].SetRotationZ( m_SubActors[i].GetRotationZ() - fDeltaTime );
2002-09-29 05:06:18 +00:00
2004-01-25 22:22:40 +00:00
float fRadius = (m_SubActors[i].GetZoom()-SPIRAL_MIN_ZOOM);
2002-09-29 05:06:18 +00:00
fRadius *= fRadius;
fRadius *= 200;
2004-11-05 06:35:10 +00:00
m_SubActors[i].SetX( SCREEN_CENTER_X + cosf(m_SubActors[i].GetRotationZ())*fRadius );
m_SubActors[i].SetY( SCREEN_CENTER_Y + sinf(m_SubActors[i].GetRotationZ())*fRadius );
2002-09-29 05:06:18 +00:00
}
break;
2003-03-05 02:52:40 +00:00
*/
case TYPE_PARTICLES:
2004-09-21 07:53:39 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
2002-09-29 05:06:18 +00:00
{
2004-01-25 22:22:40 +00:00
Actor* pActor = m_SubActors[i];
RageVector3 &vel = m_vParticleVelocity[i];
2004-01-25 22:22:40 +00:00
m_SubActors[i]->SetX( pActor->GetX() + fDeltaTime*vel.x );
m_SubActors[i]->SetY( pActor->GetY() + fDeltaTime*vel.y );
pActor->SetZ( pActor->GetZ() + fDeltaTime*vel.z );
2003-03-05 02:52:40 +00:00
if( m_bParticlesBounce )
2003-01-13 08:31:34 +00:00
{
if( HitGuardRailLeft(pActor) )
2003-03-05 02:52:40 +00:00
{
vel.x *= -1;
pActor->SetX( GetGuardRailLeft(pActor) );
2003-03-05 02:52:40 +00:00
}
if( HitGuardRailRight(pActor) )
2003-03-05 02:52:40 +00:00
{
vel.x *= -1;
pActor->SetX( GetGuardRailRight(pActor) );
2003-03-05 02:52:40 +00:00
}
if( HitGuardRailTop(pActor) )
2003-03-05 02:52:40 +00:00
{
vel.y *= -1;
pActor->SetY( GetGuardRailTop(pActor) );
2003-03-05 02:52:40 +00:00
}
if( HitGuardRailBottom(pActor) )
2003-03-05 02:52:40 +00:00
{
vel.y *= -1;
pActor->SetY( GetGuardRailBottom(pActor) );
2003-03-05 02:52:40 +00:00
}
2003-01-13 08:31:34 +00:00
}
2003-03-05 02:52:40 +00:00
else // !m_bParticlesBounce
2003-01-13 08:31:34 +00:00
{
if( vel.x<0 && IsOffScreenLeft(pActor) )
pActor->SetX( GetOffScreenRight(pActor) );
if( vel.x>0 && IsOffScreenRight(pActor) )
pActor->SetX( GetOffScreenLeft(pActor) );
if( vel.y<0 && IsOffScreenTop(pActor) )
pActor->SetY( GetOffScreenBottom(pActor) );
if( vel.y>0 && IsOffScreenBottom(pActor) )
pActor->SetY( GetOffScreenTop(pActor) );
2003-01-13 08:31:34 +00:00
}
2002-09-29 05:06:18 +00:00
}
break;
2003-03-05 02:52:40 +00:00
case TYPE_TILES:
{
float fSecs = RageTimer::GetTimeSinceStart();
float fTotalWidth = m_iNumTilesWide * m_fTilesSpacingX;
float fTotalHeight = m_iNumTilesHigh * m_fTilesSpacingY;
2004-01-25 22:22:40 +00:00
ASSERT( int(m_SubActors.size()) == m_iNumTilesWide * m_iNumTilesHigh );
2003-03-05 02:52:40 +00:00
for( int x=0; x<m_iNumTilesWide; x++ )
{
for( int y=0; y<m_iNumTilesHigh; y++ )
{
int i = y*m_iNumTilesWide + x;
float fX = m_fTilesStartX + m_fTilesSpacingX * x + fSecs * m_fTileVelocityX;
float fY = m_fTilesStartY + m_fTilesSpacingY * y + fSecs * m_fTileVelocityY;
fX += m_fTilesSpacingX/2;
fY += m_fTilesSpacingY/2;
fX = fmodf( fX, fTotalWidth );
fY = fmodf( fY, fTotalHeight );
if( fX < 0 ) fX += fTotalWidth;
if( fY < 0 ) fY += fTotalHeight;
fX -= m_fTilesSpacingX/2;
fY -= m_fTilesSpacingY/2;
2004-01-25 22:22:40 +00:00
m_SubActors[i]->SetX( fX );
m_SubActors[i]->SetY( fY );
2003-03-05 02:52:40 +00:00
}
}
/*
2002-09-29 05:06:18 +00:00
for( i=0; i<m_iNumSprites; i++ )
{
2004-01-25 22:22:40 +00:00
m_SubActors[i].SetX( m_SubActors[i].GetX() + fDeltaTime* );
m_SubActors[i].SetY( m_SubActors[i].GetY() + fDeltaTime*m_vParticleVelocity[i].y );
m_SubActors[i].SetZ( m_SubActors[i].GetZ() + fDeltaTime*m_vParticleVelocity[i].z );
if( IsOffScreenLeft(&m_SubActors[i]) )
m_SubActors[i].SetX( m_SubActors[i].GetX()-GetOffScreenLeft(&m_SubActors[i]) + GetOffScreenRight(&m_SubActors[i]) );
if( IsOffScreenRight(&m_SubActors[i]) )
m_SubActors[i].SetX( m_SubActors[i].GetX()-GetOffScreenRight(&m_SubActors[i]) + GetOffScreenLeft(&m_SubActors[i]) );
if( IsOffScreenTop(&m_SubActors[i]) )
m_SubActors[i].SetY( m_SubActors[i].GetY()-GetOffScreenTop(&m_SubActors[i]) + GetOffScreenBottom(&m_SubActors[i]) );
if( IsOffScreenBottom(&m_SubActors[i]) )
m_SubActors[i].SetY( m_SubActors[i].GetY()-GetOffScreenBottom(&m_SubActors[i]) + GetOffScreenTop(&m_SubActors[i]) );
2003-03-05 02:52:40 +00:00
*/
2002-09-29 05:06:18 +00:00
}
break;
case EFFECT_TILE_PULSE:
2004-09-21 07:53:39 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
2004-01-25 22:22:40 +00:00
m_SubActors[i]->SetZoom( sinf( fSongBeat*PI/2 ) );
2002-09-29 05:06:18 +00:00
break;
default:
ASSERT(0);
}
2003-01-12 00:57:53 +00:00
2003-03-05 02:52:40 +00:00
/*
2003-01-12 00:57:53 +00:00
if(m_TweenStartTime != 0 && !(m_TweenStartTime < 0))
{
m_TweenStartTime -= fDeltaTime;
if(m_TweenStartTime <= 0) // if we've gone past the magic point... show the beast....
{
2004-01-25 22:22:40 +00:00
// m_SubActors[0].SetXY( m_TweenX, m_TweenY);
2003-01-12 00:57:53 +00:00
// WHAT WOULD BE NICE HERE:
// Set the Sprite Tweening To m_TweenX and m_TweenY
// Going as fast as m_TweenSpeed specifies.
// however, TWEEN falls over on its face at this point.
// Lovely.
// Instead: Manual tweening. Blah.
m_TweenState = 1;
if(m_PosX == m_TweenX)
{
m_TweenPassedX = 1;
}
if(m_PosY == m_TweenY)
{
m_TweenPassedY = 1;
}
2003-01-12 00:57:53 +00:00
}
}
if(m_TweenState) // A FAR from perfect Tweening Mechanism.
{
if(m_TweenPassedY != 1) // Check to see if we still need to Tween Along the Y Axis
{
2004-01-25 22:22:40 +00:00
if(m_SubActors[0].GetY() < m_TweenY) // it needs to travel down
{
// Speed = Distance / Time....
// Take away from the current position... the distance it has to travel divided by the time they want it done in...
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetY(m_SubActors[0].GetY() + ((m_TweenY - m_PosY)/(m_TweenSpeed*60)));
2004-01-25 22:22:40 +00:00
if(m_SubActors[0].GetY() > m_TweenY) // passed the location we wanna go to?
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetY(m_TweenY); // set it to the exact location we want
m_TweenPassedY = 1; // say we passed it.
}
}
else // travelling up
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetY(m_SubActors[0].GetY() - ((m_TweenY + m_PosY)/(m_TweenSpeed*60)));
2004-01-25 22:22:40 +00:00
if(m_SubActors[0].GetY() < m_TweenY)
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetY(m_TweenY);
m_TweenPassedY = 1;
}
}
}
if(m_TweenPassedX != 1) // Check to see if we still need to Tween Along the X Axis
{
2004-01-25 22:22:40 +00:00
if(m_SubActors[0].GetX() < m_TweenX) // it needs to travel right
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetX(m_SubActors[0].GetX() + ((m_TweenX - m_PosX)/(m_TweenSpeed*60)));
if(m_SubActors[0].GetX() > m_TweenX)
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetX(m_TweenX);
m_TweenPassedX = 1;
}
}
else // travelling left
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetX(m_SubActors[0].GetX() - ((m_TweenX + m_PosX)/(m_TweenSpeed*60)));
if(m_SubActors[0].GetX() < m_TweenX)
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetX(m_TweenX);
m_TweenPassedX = 1;
}
}
}
if(m_TweenPassedY == 1 && m_TweenPassedX == 1) // totally passed both X and Y? Stop tweening.
{
m_TweenState = 0;
}
}
2003-01-12 00:57:53 +00:00
if(m_ShowTime != 0 && !(m_ShowTime < 0))
{
m_ShowTime -= fDeltaTime;
if(m_ShowTime <= 0) // if we've gone past the magic point... show the beast....
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetDiffuse( RageColor(1,1,1,1) );
2003-01-12 00:57:53 +00:00
}
}
if(m_HideTime != 0 && !(m_HideTime < 0)) // make sure it's not 0 or less than 0...
{
m_HideTime -= fDeltaTime;
if(m_HideTime <= 0) // if we've gone past the magic point... hide the beast....
{
2004-01-25 22:22:40 +00:00
m_SubActors[0].SetDiffuse( RageColor(0,0,0,0) );
2003-01-12 00:57:53 +00:00
}
}
2003-03-05 02:52:40 +00:00
*/
if( m_fRepeatCommandEverySeconds != -1 ) // if repeating
{
2003-10-24 08:49:48 +00:00
m_fSecondsUntilNextCommand -= fDeltaTime;
if( m_fSecondsUntilNextCommand <= 0 )
{
2003-10-31 01:55:17 +00:00
PlayCommand( "On" );
2003-10-24 08:49:48 +00:00
m_fSecondsUntilNextCommand += m_fRepeatCommandEverySeconds;
2004-04-15 23:22:32 +00:00
/* In case we delayed a long time, don't queue two repeats at once. */
wrap( m_fSecondsUntilNextCommand, m_fRepeatCommandEverySeconds );
}
}
2002-09-29 05:06:18 +00:00
}
2004-03-27 00:23:29 +00:00
bool BGAnimationLayer::EarlyAbortDraw()
{
if( m_sDrawCond.empty() )
return false;
2004-09-24 02:52:07 +00:00
if( !Lua::RunExpressionB( m_sDrawCond ) )
2004-03-27 00:23:29 +00:00
return true;
return false;
}
2004-01-25 22:22:40 +00:00
void BGAnimationLayer::DrawPrimitives()
2002-09-29 05:06:18 +00:00
{
if( m_fFOV != -1 )
{
DISPLAY->CameraPushMatrix();
2004-11-05 06:35:10 +00:00
DISPLAY->LoadMenuPerspective( m_fFOV, SCREEN_CENTER_X, SCREEN_CENTER_Y );
}
2003-07-07 20:24:51 +00:00
if( m_bLighting )
{
DISPLAY->SetLighting( true );
DISPLAY->SetLightDirectional(
0,
2004-01-23 08:23:22 +00:00
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageVector3(0,0,1) );
2003-07-07 20:24:51 +00:00
}
2004-01-25 22:22:40 +00:00
ActorFrame::DrawPrimitives();
2003-07-07 20:24:51 +00:00
if( m_fFOV != -1 )
{
DISPLAY->CameraPopMatrix();
}
2003-07-07 20:24:51 +00:00
if( m_bLighting )
{
DISPLAY->SetLightOff( 0 );
DISPLAY->SetLighting( false );
}
2003-03-05 02:52:40 +00:00
}
2004-08-22 02:16:31 +00:00
void BGAnimationLayer::GainFocus( float fRate, bool bRewindMovie, bool bLoop )
2002-09-29 05:06:18 +00:00
{
2003-04-14 04:56:57 +00:00
m_fUpdateRate = fRate;
2004-01-25 22:22:40 +00:00
if( !m_SubActors.size() )
2004-01-20 06:01:50 +00:00
return;
//
// The order of these actions is important.
2004-08-22 02:16:31 +00:00
// At this point, the movie is probably paused (by LoseFocus()).
// Play the movie, then set the playback rate (which can
// potentially pause the movie again).
//
2004-08-22 02:16:31 +00:00
// TODO: Don't special case subActor[0]. The movie layer should be set up with
// a LoseFocusCommand that pauses, and a GainFocusCommand that plays.
if( bRewindMovie )
2004-12-03 05:19:46 +00:00
RunCommandOnChildren( ParseCommands("position,0") );
RunCommandOnChildren( ParseCommands(ssprintf("loop,%i",bLoop)) );
RunCommandOnChildren( ParseCommands("play") );
RunCommandOnChildren( ParseCommands(ssprintf("rate,%f",fRate)) );
2003-03-05 02:52:40 +00:00
if( m_fRepeatCommandEverySeconds == -1 ) // if not repeating
{
2004-08-12 06:10:54 +00:00
/* Yuck. We send OnCommand on load, since that's what's wanted for
* most backgrounds. However, gameplay backgrounds (loaded from Background)
2004-08-22 02:16:31 +00:00
* should run OnCommand when they're actually displayed, when GainFocus
2004-08-12 06:10:54 +00:00
* gets called. We've already run OnCommand; abort it so we don't run tweens
* twice. */
2004-12-03 05:19:46 +00:00
RunCommandOnChildren( ParseCommands("stoptweening") );
2003-10-31 01:55:17 +00:00
PlayCommand( "On" );
}
PlayCommand( "GainFocus" );
ActorFrame::GainFocus( fRate, bRewindMovie, bLoop );
2002-09-29 05:06:18 +00:00
}
2004-08-22 02:16:31 +00:00
void BGAnimationLayer::LoseFocus()
2002-09-29 05:06:18 +00:00
{
2004-01-25 22:22:40 +00:00
if( !m_SubActors.size() )
2004-01-20 06:01:50 +00:00
return;
2004-12-03 05:19:46 +00:00
RunCommandOnChildren( ParseCommands("pause") );
PlayCommand( "LoseFocus" );
2002-09-29 05:06:18 +00:00
}
2003-07-10 03:37:13 +00:00
2004-02-01 04:41:48 +00:00
void BGAnimationLayer::PlayCommand( const CString &sCommandName )
2003-07-10 03:37:13 +00:00
{
// Don't call base version.
//Actor::PlayCommand( sCommandName );
2004-09-21 07:53:39 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
2004-12-03 05:19:46 +00:00
m_SubActors[i]->RunCommands( ParseCommands("playcommand,"+sCommandName) );
2003-11-17 01:44:59 +00:00
2004-02-01 04:41:48 +00:00
CString sKey = sCommandName;
sKey.MakeLower();
map<CString, Commands>::const_iterator it = m_mapNameToCommands.find( sKey );
2003-10-31 01:55:17 +00:00
if( it == m_mapNameToCommands.end() )
2003-10-31 01:55:17 +00:00
return;
2004-09-21 07:53:39 +00:00
for( unsigned i=0; i<m_SubActors.size(); i++ )
m_SubActors[i]->RunCommands( it->second );
2003-07-15 20:21:25 +00:00
}
2004-06-01 00:53:06 +00:00
/*
* (c) 2001-2004 Ben Nordstrom, Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/