void BGAnimationLayer::LoadFromAniLayerFile( const RString& sPath ) { /* Generic BGAs are new. Animation directories with no INI are old and obsolete. * Don't combine them. */ RString lcPath = sPath; lcPath.MakeLower(); if( lcPath.find("usesongbg") != RString::npos ) { const Song* pSong = GAMESTATE->m_pCurSong; RString sSongBGPath; if( pSong && pSong->HasBackground() ) sSongBGPath = pSong->GetBackgroundPath(); else sSongBGPath = THEME->GetPathG("Common","fallback background"); Sprite* pSprite = new Sprite; pSprite->Load( Sprite::SongBGTexture(sSongBGPath) ); pSprite->StretchTo( FullScreenRectF ); this->AddChild( pSprite ); return; // this will ignore other effects in the file name } 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 }; const RString EFFECT_STRING[NUM_EFFECTS] = { "center", "stretchstill", "stretchscrollleft", "stretchscrollright", "stretchscrollup", "stretchscrolldown", "stretchwater", "stretchbubble", "stretchtwist", "stretchspin", "particlesspiralout", "particlesspiralin", "particlesfloatup", "particlesfloatdown", "particlesfloatleft", "particlesfloatright", "particlesbounce", "tilestill", "tilescrollleft", "tilescrollright", "tilescrollup", "tilescrolldown", "tileflipx", "tileflipy", "tilepulse", }; Effect effect = EFFECT_CENTER; for( int i=0; i<NUM_EFFECTS; i++ ) if( lcPath.find(EFFECT_STRING[i]) != string::npos ) effect = (Effect)i; switch( effect ) { case EFFECT_CENTER: { m_Type = TYPE_SPRITE; Sprite* pSprite = new Sprite; this->AddChild( pSprite ); pSprite->Load( sPath ); pSprite->SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y ); } 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: { m_Type = TYPE_SPRITE; Sprite* pSprite = new Sprite; this->AddChild( pSprite ); RageTextureID ID(sPath); ID.bStretch = true; pSprite->Load( Sprite::SongBGTexture(ID) ); pSprite->StretchTo( FullScreenRectF ); pSprite->SetCustomTextureRect( RectF(0,0,1,1) ); switch( effect ) { 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; default: break; } } break; case EFFECT_STRETCH_SPIN: { m_Type = TYPE_SPRITE; Sprite* pSprite = new Sprite; this->AddChild( pSprite ); pSprite->Load( Sprite::SongBGTexture(sPath) ); const RectF StretchedFullScreenRectF( FullScreenRectF.left-200, FullScreenRectF.top-200, FullScreenRectF.right+200, FullScreenRectF.bottom+200 ); pSprite->ScaleToCover( StretchedFullScreenRectF ); pSprite->SetEffectSpin( RageVector3(0,0,60) ); } break; case EFFECT_PARTICLES_SPIRAL_OUT: case EFFECT_PARTICLES_SPIRAL_IN: case EFFECT_PARTICLES_FLOAT_UP: case EFFECT_PARTICLES_FLOAT_DOWN: case EFFECT_PARTICLES_FLOAT_LEFT: case EFFECT_PARTICLES_FLOAT_RIGHT: case EFFECT_PARTICLES_BOUNCE: { m_Type = TYPE_PARTICLES; Sprite s; s.Load( sPath ); int iSpriteArea = int( s.GetUnzoomedWidth()*s.GetUnzoomedHeight() ); const int iMaxArea = int(SCREEN_WIDTH*SCREEN_HEIGHT); int iNumParticles = iMaxArea / iSpriteArea; iNumParticles = min( iNumParticles, MAX_SPRITES ); for( int i=0; i<iNumParticles; i++ ) { Sprite* pSprite = new Sprite; this->AddChild( pSprite ); pSprite->Load( sPath ); pSprite->SetZoom( 0.7f + 0.6f*i/(float)iNumParticles ); switch( effect ) { case EFFECT_PARTICLES_BOUNCE: pSprite->SetX( randomf( GetGuardRailLeft(pSprite), GetGuardRailRight(pSprite) ) ); pSprite->SetY( randomf( GetGuardRailTop(pSprite), GetGuardRailBottom(pSprite) ) ); break; default: pSprite->SetX( randomf( GetOffScreenLeft(pSprite), GetOffScreenRight(pSprite) ) ); pSprite->SetY( randomf( GetOffScreenTop(pSprite), GetOffScreenBottom(pSprite) ) ); break; } switch( effect ) { case EFFECT_PARTICLES_FLOAT_UP: case EFFECT_PARTICLES_SPIRAL_OUT: m_vParticleVelocity.push_back( RageVector3( 0, -PARTICLE_SPEED*pSprite->GetZoom(), 0 ) ); break; case EFFECT_PARTICLES_FLOAT_DOWN: case EFFECT_PARTICLES_SPIRAL_IN: m_vParticleVelocity.push_back( RageVector3( 0, PARTICLE_SPEED*pSprite->GetZoom(), 0 ) ); break; case EFFECT_PARTICLES_FLOAT_LEFT: m_vParticleVelocity.push_back( RageVector3( -PARTICLE_SPEED*pSprite->GetZoom(), 0, 0 ) ); break; case EFFECT_PARTICLES_FLOAT_RIGHT: m_vParticleVelocity.push_back( RageVector3( +PARTICLE_SPEED*pSprite->GetZoom(), 0, 0 ) ); break; case EFFECT_PARTICLES_BOUNCE: m_bParticlesBounce = true; pSprite->SetZoom( 1 ); m_vParticleVelocity.push_back( RageVector3( randomf(), randomf(), 0 ) ); RageVec3Normalize( &m_vParticleVelocity[i], &m_vParticleVelocity[i] ); m_vParticleVelocity[i].x *= PARTICLE_SPEED; m_vParticleVelocity[i].y *= PARTICLE_SPEED; break; default: FAIL_M(ssprintf("Unrecognized layer effect: %i", effect)); } } } 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: { m_Type = TYPE_TILES; RageTextureID ID(sPath); ID.bStretch = true; Sprite s; s.Load( ID ); m_iNumTilesWide = 2+int(SCREEN_WIDTH /s.GetUnzoomedWidth()); m_iNumTilesWide = min( m_iNumTilesWide, MAX_TILES_WIDE ); m_iNumTilesHigh = 2+int(SCREEN_HEIGHT/s.GetUnzoomedHeight()); 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(); for( int x=0; x<m_iNumTilesWide; x++ ) { for( int y=0; y<m_iNumTilesHigh; y++ ) { Sprite* pSprite = new Sprite; this->AddChild( pSprite ); pSprite->Load( ID ); pSprite->SetTextureWrapping( true ); // gets rid of some "cracks" 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(180,0,0) ); break; case EFFECT_TILE_FLIP_Y: pSprite->SetEffectSpin( RageVector3(0,180,0) ); break; case EFFECT_TILE_PULSE: pSprite->SetEffectPulse( 1, 0.3f, 1.f ); break; default: FAIL_M(ssprintf("Not a tile effect: %i", effect)); } } } } break; default: FAIL_M(ssprintf("Unrecognized layer effect: %i", effect)); } RString sHint = sPath; sHint.MakeLower(); if( sHint.find("cyclecolor") != RString::npos ) for( unsigned i=0; i<m_SubActors.size(); i++ ) m_SubActors[i]->SetEffectRainbow( 5 ); if( sHint.find("cyclealpha") != RString::npos ) for( unsigned i=0; i<m_SubActors.size(); i++ ) m_SubActors[i]->SetEffectDiffuseShift( 2, RageColor(1,1,1,1), RageColor(1,1,1,0) ); if( sHint.find("startonrandomframe") != RString::npos ) for( unsigned i=0; i<m_SubActors.size(); i++ ) m_SubActors[i]->SetState( RandomInt(m_SubActors[i]->GetNumStates()) ); if( sHint.find("dontanimate") != RString::npos ) for( unsigned i=0; i<m_SubActors.size(); i++ ) m_SubActors[i]->StopAnimating(); if( sHint.find("add") != RString::npos ) for( unsigned i=0; i<m_SubActors.size(); i++ ) m_SubActors[i]->SetBlendMode( BLEND_ADD ); }
void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn ) { ASSERT( m_SubActors.size() == 0 ); /* Find the largest combo. */ int MaxComboSize = 0; unsigned i; for( i = 0; i < s.ComboList[pn].size(); ++i ) MaxComboSize = max( MaxComboSize, s.ComboList[pn][i].GetStageCnt() ); float width = -1; for( i = 0; i < s.ComboList[pn].size(); ++i ) { const StageStats::Combo_t &combo = s.ComboList[pn][i]; if( combo.GetStageCnt() < MinComboSizeToShow ) continue; /* too small */ const bool IsMax = (combo.GetStageCnt() == MaxComboSize); LOG->Trace("combo %i is %f+%f", i, combo.fStartSecond, combo.fSizeSeconds); Sprite *sprite = new Sprite; sprite->SetName( "ComboBar" ); const CString path = ssprintf( "%s %s", Path.c_str(), IsMax? "max":"normal" ); sprite->Load( THEME->GetPathToG(path) ); const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f ); const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f ); sprite->SetCropLeft ( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) ); sprite->SetCropRight( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) ); sprite->BeginTweening( .5f ); sprite->SetCropLeft( start ); sprite->SetCropRight( 1 - (size + start) ); if( width < 0 ) width = sprite->GetUnzoomedWidth(); m_Sprites.push_back( sprite ); this->AddChild( sprite ); } for( i = 0; i < s.ComboList[pn].size(); ++i ) { const StageStats::Combo_t &combo = s.ComboList[pn][i]; if( combo.GetStageCnt() < MinComboSizeToShow ) continue; /* too small */ if( !MaxComboSize ) continue; const bool IsMax = (combo.GetStageCnt() == MaxComboSize); if( !IsMax ) continue; BitmapText *text = new BitmapText; text->SetName( "ComboMaxNumber" ); text->LoadFromFont( THEME->GetPathToF(Path) ); const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f ); const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f ); const float CenterPercent = start + size/2; const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f ); text->SetX( CenterXPos ); text->SetText( ssprintf("%i",combo.GetStageCnt()) ); ON_COMMAND( text ); m_Numbers.push_back( text ); this->AddChild( text ); } }