Files
itgmania212121/stepmania/src/BGAnimationLayer.cpp
T

683 lines
19 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 "GameState.h"
2005-09-03 00:30:46 +00:00
#include "XmlFile.h"
#include "RageMath.h"
2003-03-05 02:52:40 +00:00
#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"
2005-01-24 02:26:55 +00:00
#include "LuaManager.h"
2005-07-06 05:09:52 +00:00
#include "AutoActor.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
BGAnimationLayer::BGAnimationLayer()
2002-09-29 05:06:18 +00:00
{
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_fUpdateRate = 1;
m_fFOV = -1; // no change
m_bLighting = false;
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_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;
2002-09-29 05:06:18 +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. */
2003-02-14 22:46:45 +00:00
CString lcPath = sPath;
lcPath.MakeLower();
2002-09-29 05:06:18 +00:00
2005-05-18 02:01:00 +00:00
if( lcPath.find("usesongbg") != CString::npos )
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
2005-02-06 03:32:53 +00:00
sSongBGPath = THEME->GetPathG("Common","fallback background");
2003-10-30 20:34:38 +00:00
2005-01-15 20:48:20 +00:00
Sprite* pSprite = new Sprite;
pSprite->LoadBG( sSongBGPath );
pSprite->StretchTo( FullScreenRectF );
this->AddChild( pSprite );
2002-09-29 05:06:18 +00:00
return; // this will ignore other effects in the file name
}
2005-01-15 22:58:27 +00:00
enum Effect {
EFFECT_CENTER,
EFFECT_STRETCH_STILL,
EFFECT_STRETCH_SCROLL_LEFT,
EFFECT_STRETCH_SCROLL_RIGHT,
EFFECT_STRETCH_SCROLL_UP,
EFFECT_STRETCH_SCROLL_DOWN,
EFFECT_STRETCH_WATER,
EFFECT_STRETCH_BUBBLE,
EFFECT_STRETCH_TWIST,
EFFECT_STRETCH_SPIN,
EFFECT_PARTICLES_SPIRAL_OUT,
EFFECT_PARTICLES_SPIRAL_IN,
EFFECT_PARTICLES_FLOAT_UP,
EFFECT_PARTICLES_FLOAT_DOWN,
EFFECT_PARTICLES_FLOAT_LEFT,
EFFECT_PARTICLES_FLOAT_RIGHT,
EFFECT_PARTICLES_BOUNCE,
EFFECT_TILE_STILL,
EFFECT_TILE_SCROLL_LEFT,
EFFECT_TILE_SCROLL_RIGHT,
EFFECT_TILE_SCROLL_UP,
EFFECT_TILE_SCROLL_DOWN,
EFFECT_TILE_FLIP_X,
EFFECT_TILE_FLIP_Y,
EFFECT_TILE_PULSE,
NUM_EFFECTS, // leave this at the end
EFFECT_INVALID
};
2002-09-29 05:06:18 +00:00
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;
2005-01-05 01:12:56 +00:00
this->AddChild( 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;
2005-01-05 01:12:56 +00:00
this->AddChild( 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;
2005-01-05 01:12:56 +00:00
this->AddChild( 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);
int iNumParticles = iMaxArea / iSpriteArea;
iNumParticles = min( iNumParticles, MAX_SPRITES );
for( int i=0; i<iNumParticles; i++ )
2002-09-29 05:06:18 +00:00
{
Sprite* pSprite = new Sprite;
2005-01-05 01:12:56 +00:00
this->AddChild( pSprite );
pSprite->Load( sPath );
pSprite->SetZoom( 0.7f + 0.6f*i/(float)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;
2005-01-05 01:12:56 +00:00
this->AddChild( 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::LoadFromNode( const CString& sDir, const XNode* pNode )
2003-03-05 02:52:40 +00:00
{
CString sAniDir = sDir;
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\"", sAniDir.c_str() ) );
2004-02-14 23:22:23 +00:00
{
CString expr;
2005-08-31 19:56:46 +00:00
if( pNode->GetAttrValue("Condition", expr) )
2004-02-14 23:22:23 +00:00
{
2005-06-16 06:23:59 +00:00
if( !LuaHelpers::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";
pNode->GetAttrValue( "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. */
pNode->GetAttrValue( "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
pNode->GetAttrValue( "FOV", m_fFOV );
pNode->GetAttrValue( "Lighting", m_bLighting );
pNode->GetAttrValue( "TexCoordVelocityX", m_fTexCoordVelocityX );
pNode->GetAttrValue( "TexCoordVelocityY", m_fTexCoordVelocityY );
pNode->GetAttrValue( "DrawCond", m_sDrawCond );
2004-03-27 00:23:29 +00:00
2003-10-31 00:01:16 +00:00
// compat:
pNode->GetAttrValue( "StretchTexCoordVelocityX", m_fTexCoordVelocityX );
pNode->GetAttrValue( "StretchTexCoordVelocityY", m_fTexCoordVelocityY );
// particle and tile stuff
float fZoomMin = 1;
float fZoomMax = 1;
pNode->GetAttrValue( "ZoomMin", fZoomMin );
pNode->GetAttrValue( "ZoomMax", fZoomMax );
float fVelocityXMin = 10, fVelocityXMax = 10;
float fVelocityYMin = 0, fVelocityYMax = 0;
float fVelocityZMin = 0, fVelocityZMax = 0;
float fOverrideSpeed = 0; // 0 means don't override speed
pNode->GetAttrValue( "VelocityXMin", fVelocityXMin );
pNode->GetAttrValue( "VelocityXMax", fVelocityXMax );
pNode->GetAttrValue( "VelocityYMin", fVelocityYMin );
pNode->GetAttrValue( "VelocityYMax", fVelocityYMax );
pNode->GetAttrValue( "VelocityZMin", fVelocityZMin );
pNode->GetAttrValue( "VelocityZMax", fVelocityZMax );
pNode->GetAttrValue( "OverrideSpeed", fOverrideSpeed );
int iNumParticles = 10;
pNode->GetAttrValue( "NumParticles", iNumParticles );
pNode->GetAttrValue( "ParticlesBounce", m_bParticlesBounce );
pNode->GetAttrValue( "TilesStartX", m_fTilesStartX );
pNode->GetAttrValue( "TilesStartY", m_fTilesStartY );
pNode->GetAttrValue( "TilesSpacingX", m_fTilesSpacingX );
pNode->GetAttrValue( "TilesSpacingY", m_fTilesSpacingY );
pNode->GetAttrValue( "TileVelocityX", m_fTileVelocityX );
pNode->GetAttrValue( "TileVelocityY", m_fTileVelocityY );
2003-03-05 02:52:40 +00:00
2003-10-31 00:01:16 +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:
{
Actor* pActor = ActorUtil::LoadFromNode( sAniDir, pNode );
2005-01-05 01:12:56 +00:00
this->AddChild( pActor );
if( bStretch )
pActor->StretchTo( FullScreenRectF );
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;
pNode->GetAttrValue( "File", sFile );
2004-01-25 22:22:40 +00:00
FixSlashesInPlace( sFile );
CString sPath = sAniDir+sFile;
CollapsePath( sPath );
for( int i=0; i<iNumParticles; i++ )
2003-03-05 02:52:40 +00:00
{
2005-01-17 05:42:52 +00:00
Actor* pActor = ActorUtil::MakeActor( sPath );
2005-01-17 04:08:08 +00:00
if( pActor == NULL )
continue;
2005-01-05 01:12:56 +00:00
this->AddChild( 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(fZoomMin,fZoomMax) );
m_vParticleVelocity.push_back( RageVector3(
randomf(fVelocityXMin,fVelocityXMax),
randomf(fVelocityYMin,fVelocityYMax),
randomf(fVelocityZMin,fVelocityZMax) ) );
if( fOverrideSpeed != 0 )
2003-03-05 02:52:40 +00:00
{
RageVec3Normalize( &m_vParticleVelocity[i], &m_vParticleVelocity[i] );
m_vParticleVelocity[i] *= fOverrideSpeed;
2003-03-05 02:52:40 +00:00
}
}
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;
pNode->GetAttrValue( "File", sFile );
2004-01-25 22:22:40 +00:00
FixSlashesInPlace( sFile );
CString sPath = sAniDir+sFile;
CollapsePath( sPath );
2005-07-06 05:09:52 +00:00
AutoActor s;
s.Load( sPath );
2003-03-09 09:25:32 +00:00
if( m_fTilesSpacingX == -1 )
2005-07-06 05:09:52 +00:00
m_fTilesSpacingX = s->GetUnzoomedWidth();
2003-03-09 09:25:32 +00:00
if( m_fTilesSpacingY == -1 )
2005-07-06 05:09:52 +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
{
2005-07-06 05:09:52 +00:00
Actor* pSprite = ActorUtil::MakeActor( sPath );
2005-01-05 01:12:56 +00:00
this->AddChild( pSprite );
pSprite->SetTextureWrapping( true ); // gets rid of some "cracks"
pSprite->SetZoom( randomf(fZoomMin,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;
pNode->GetAttrValue( "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
}
}
void BGAnimationLayer::UpdateInternal( float fDeltaTime )
2003-03-05 02:52:40 +00:00
{
ActorFrame::UpdateInternal( fDeltaTime );
2002-09-29 05:06:18 +00:00
fDeltaTime *= m_fUpdateRate;
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++ )
{
/* XXX: there's no longer any guarantee that this is a Sprite */
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 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::GetTimeSinceStartFast();
2003-03-05 02:52:40 +00:00
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
}
break;
default:
ASSERT(0);
}
}
2005-08-25 00:57:53 +00:00
bool BGAnimationLayer::EarlyAbortDraw() const
2004-03-27 00:23:29 +00:00
{
if( m_sDrawCond.empty() )
return false;
2005-02-16 00:16:14 +00:00
// TODO: Is it ok to evaluate this every frame?
2005-06-16 06:23:59 +00:00
if( !LuaHelpers::RunExpressionB(m_sDrawCond) )
2004-03-27 00:23:29 +00:00
return true;
return false;
}
2005-01-07 22:01:57 +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.
*/