diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index 320ea9b02b..69ed8f670f 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -22,6 +22,7 @@ #include #include "XmlFile.h" #include "BackgroundUtil.h" +#include "song.h" ThemeMetric LEFT_EDGE ("Background","LeftEdge"); ThemeMetric TOP_EDGE ("Background","TopEdge"); @@ -35,6 +36,99 @@ ThemeMetric CLAMP_OUTPUT_PERCENT ("Background","ClampOutputPercent"); static float g_fBackgroundCenterWidth = 40; // What is this for? -Chris + + +class BrightnessOverlay: public ActorFrame +{ +public: + BrightnessOverlay(); + void Update( float fDeltaTime ); + + void FadeToActualBrightness(); + void SetActualBrightness(); + void Set( float fBrightness ); + +private: + Quad m_quadBGBrightness[NUM_PLAYERS]; + Quad m_quadBGBrightnessFade; +}; + +struct BackgroundTransition +{ + apActorCommands cmdLeaves; + apActorCommands cmdRoot; +}; + + +class BackgroundImpl : public ActorFrame +{ +public: + BackgroundImpl(); + ~BackgroundImpl(); + void Init(); + + virtual void LoadFromSong( const Song *pSong ); + virtual void Unload(); + + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + + void FadeToActualBrightness() { m_Brightness.FadeToActualBrightness(); } + void SetBrightness( float fBrightness ) { m_Brightness.Set(fBrightness); } /* overrides pref and Cover */ + + DancingCharacters* GetDancingCharacters() { return m_pDancingCharacters; }; + + +protected: + bool m_bInitted; + DancingCharacters* m_pDancingCharacters; + const Song *m_pSong; + map m_mapNameToTransition; + deque m_RandomBGAnimations; // random background to choose from. These may or may not be loaded into m_BGAnimations. + + void LoadFromRandom( float fFirstBeat, float fLastBeat, const BackgroundChange &change ); + bool IsDangerAllVisible(); + + class Layer + { + public: + Layer(); + void Unload(); + + // return true if created and added to m_BGAnimations + bool CreateBackground( const Song *pSong, const BackgroundDef &bd ); + // return def of the background that was created and added to m_BGAnimations. calls CreateBackground + BackgroundDef CreateRandomBGA( const Song *pSong, deque &RandomBGAnimations ); + + int FindBGSegmentForBeat( float fBeat ) const; + void UpdateCurBGChange( const Song *pSong, float fLastMusicSeconds, float fCurrentTime, const map &mapNameToTransition ); + + map m_BGAnimations; + vector m_aBGChanges; + int m_iCurBGChangeIndex; + Actor *m_pCurrentBGA; + Actor *m_pFadingBGA; + float m_fSecsLeftInFade; + }; + Layer m_Layer[NUM_BackgroundLayer]; + + float m_fLastMusicSeconds; + + BGAnimation m_DangerPlayer[NUM_PLAYERS]; + BGAnimation m_DangerAll; + + BGAnimation m_DeadPlayer[NUM_PLAYERS]; + + // cover up the edge of animations that might hang outside of the background rectangle + Quad m_quadBorderLeft, m_quadBorderTop, m_quadBorderRight, m_quadBorderBottom; + + BrightnessOverlay m_Brightness; + + BackgroundDef STATIC_BACKGROUND_DEF; +}; + + + static RageColor GetBrightnessColor( float fBrightnessPercent ) { RageColor cBrightness = RageColor( 0,0,0,1-fBrightnessPercent ); @@ -51,14 +145,14 @@ static RageColor GetBrightnessColor( float fBrightnessPercent ) return ret; } -Background::Background() +BackgroundImpl::BackgroundImpl() { m_bInitted = false; m_pDancingCharacters = NULL; m_pSong = NULL; } -Background::Layer::Layer() +BackgroundImpl::Layer::Layer() { m_iCurBGChangeIndex = -1; m_pCurrentBGA = NULL; @@ -66,7 +160,7 @@ Background::Layer::Layer() m_fSecsLeftInFade = 0; } -void Background::Init() +void BackgroundImpl::Init() { if( m_bInitted ) return; @@ -139,22 +233,22 @@ void Background::Init() this->AddChild( &m_Brightness ); } -Background::~Background() +BackgroundImpl::~BackgroundImpl() { Unload(); delete m_pDancingCharacters; } -void Background::Unload() +void BackgroundImpl::Unload() { - for( int i=0; i::iterator iter = m_BGAnimations.begin(); iter != m_BGAnimations.end(); @@ -201,7 +295,7 @@ Actor *MakeMovie( const CString &sMoviePath ) return pSprite; } -bool Background::Layer::CreateBackground( const Song *pSong, const BackgroundDef &bd ) +bool BackgroundImpl::Layer::CreateBackground( const Song *pSong, const BackgroundDef &bd ) { ASSERT( m_BGAnimations.find(bd) == m_BGAnimations.end() ); @@ -300,7 +394,7 @@ bool Background::Layer::CreateBackground( const Song *pSong, const BackgroundDef return true; } -BackgroundDef Background::Layer::CreateRandomBGA( const Song *pSong, deque &RandomBGAnimations ) +BackgroundDef BackgroundImpl::Layer::CreateRandomBGA( const Song *pSong, deque &RandomBGAnimations ) { if( PREFSMAN->m_BackgroundMode == PrefsManager::BGMODE_OFF ) return BackgroundDef(); @@ -325,7 +419,7 @@ BackgroundDef Background::Layer::CreateRandomBGA( const Song *pSong, dequem_Timing; @@ -337,7 +431,7 @@ void Background::LoadFromRandom( float fFirstBeat, float fLastBeat, const Backgr if( !bd.IsEmpty() ) { BackgroundChange c = change; - (BackgroundDef&)c = bd; + c.m_def = bd; c.m_fStartBeat = f; m_Layer[0].m_aBGChanges.push_back( c ); } @@ -360,14 +454,14 @@ void Background::LoadFromRandom( float fFirstBeat, float fLastBeat, const Backgr if( !bd.IsEmpty() ) { BackgroundChange c = change; - (BackgroundDef&)c = bd; + c.m_def = bd; c.m_fStartBeat = NoteRowToBeat(bpmseg.m_iStartIndex); m_Layer[0].m_aBGChanges.push_back( c ); } } } -void Background::LoadFromSong( const Song* pSong ) +void BackgroundImpl::LoadFromSong( const Song* pSong ) { Init(); Unload(); @@ -425,15 +519,15 @@ void Background::LoadFromSong( const Song* pSong ) if( pSong->HasBGChanges() ) { - for( int i=0; im_BackgroundChanges[i], bgc ) + FOREACH_CONST( BackgroundChange, pSong->GetBackgroundChanges(i), bgc ) { BackgroundChange change = *bgc; - BackgroundDef &bd = change; + BackgroundDef &bd = change.m_def; bool bIsAlreadyLoaded = layer.m_BGAnimations.find(bd) != layer.m_BGAnimations.end(); @@ -475,7 +569,7 @@ void Background::LoadFromSong( const Song* pSong ) // sort segments - for( int i=0; im_def; if( bd == STATIC_BACKGROUND_DEF ) { bStaticBackgroundUsed = true; @@ -524,7 +618,7 @@ void Background::LoadFromSong( const Song* pSong ) for( unsigned i=0; i &mapNameToTransition ) +void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMusicSeconds, float fCurrentTime, const map &mapNameToTransition ) { ASSERT( fCurrentTime != GameState::MUSIC_SECONDS_INVALID ); @@ -634,7 +728,7 @@ void Background::Layer::UpdateCurBGChange( const Song *pSong, float fLastMusicSe m_pFadingBGA = m_pCurrentBGA; - map::const_iterator iter = m_BGAnimations.find( (BackgroundDef)change ); + map::const_iterator iter = m_BGAnimations.find( change.m_def ); ASSERT( iter != m_BGAnimations.end() ); m_pCurrentBGA = iter->second; @@ -694,7 +788,7 @@ void Background::Layer::UpdateCurBGChange( const Song *pSong, float fLastMusicSe m_pFadingBGA->Update( fDeltaTimeMusicRate ); } -void Background::Update( float fDeltaTime ) +void BackgroundImpl::Update( float fDeltaTime ) { ActorFrame::Update( fDeltaTime ); @@ -719,7 +813,7 @@ void Background::Update( float fDeltaTime ) * Otherwise, we'll stop updating movies during danger (which may stop them from * playing), and we won't start clips at the right time, which will throw backgrounds * off sync. */ - for( int i=0; im_fMusicSeconds, m_mapNameToTransition ); @@ -727,7 +821,7 @@ void Background::Update( float fDeltaTime ) m_fLastMusicSeconds = GAMESTATE->m_fMusicSeconds; } -void Background::DrawPrimitives() +void BackgroundImpl::DrawPrimitives() { if( PREFSMAN->m_fBGBrightness == 0.0f ) return; @@ -745,7 +839,7 @@ void Background::DrawPrimitives() if( m_pDancingCharacters ) m_pDancingCharacters->m_bDrawDangerLight = false; - for( int i=0; iGetPlayerFailType(p) == SongOptions::FAIL_OFF ) @@ -859,6 +953,18 @@ void BrightnessOverlay::FadeToActualBrightness() SetActualBrightness(); } + + +Background::Background() { m_pImpl = new BackgroundImpl; this->AddChild(m_pImpl); } +Background::~Background() { SAFE_DELETE( m_pImpl ); } +void Background::Init() { m_pImpl->Init(); } +void Background::LoadFromSong( const Song *pSong ) { m_pImpl->LoadFromSong(pSong); } +void Background::Unload() { m_pImpl->Unload(); } +void Background::FadeToActualBrightness() { m_pImpl->FadeToActualBrightness(); } +void Background::SetBrightness( float fBrightness ) { m_pImpl->SetBrightness(fBrightness); } +DancingCharacters* Background::GetDancingCharacters() { return m_pImpl->GetDancingCharacters(); } + + /* * (c) 2001-2004 Chris Danford, Ben Nordstrom * All rights reserved. diff --git a/stepmania/src/Background.h b/stepmania/src/Background.h index b4887e5125..732f799784 100644 --- a/stepmania/src/Background.h +++ b/stepmania/src/Background.h @@ -3,36 +3,17 @@ #ifndef BACKGROUND_H #define BACKGROUND_H -#include "Sprite.h" -#include "Quad.h" #include "ActorFrame.h" +#include "Quad.h" #include "BGAnimation.h" -#include "song.h" +#include "PlayerNumber.h" +#include "BackgroundUtil.h" #include #include class DancingCharacters; - -class BrightnessOverlay: public ActorFrame -{ -public: - BrightnessOverlay(); - void Update( float fDeltaTime ); - - void FadeToActualBrightness(); - void SetActualBrightness(); - void Set( float fBrightness ); - -private: - Quad m_quadBGBrightness[NUM_PLAYERS]; - Quad m_quadBGBrightnessFade; -}; - -struct BackgroundTransition -{ - apActorCommands cmdLeaves; - apActorCommands cmdRoot; -}; +class Song; +class BackgroundImpl; class Background : public ActorFrame { @@ -44,61 +25,13 @@ public: virtual void LoadFromSong( const Song *pSong ); virtual void Unload(); - virtual void Update( float fDeltaTime ); - virtual void DrawPrimitives(); - - void FadeToActualBrightness() { m_Brightness.FadeToActualBrightness(); } - void SetBrightness( float fBrightness ) { m_Brightness.Set(fBrightness); } /* overrides pref and Cover */ + void FadeToActualBrightness(); + void SetBrightness( float fBrightness ); /* overrides pref and Cover */ - DancingCharacters* GetDancingCharacters() { return m_pDancingCharacters; }; - + DancingCharacters* GetDancingCharacters(); protected: - bool m_bInitted; - DancingCharacters* m_pDancingCharacters; - const Song *m_pSong; - map m_mapNameToTransition; - deque m_RandomBGAnimations; // random background to choose from. These may or may not be loaded into m_BGAnimations. - - void LoadFromRandom( float fFirstBeat, float fLastBeat, const BackgroundChange &change ); - bool IsDangerAllVisible(); - - class Layer - { - public: - Layer(); - void Unload(); - - // return true if created and added to m_BGAnimations - bool CreateBackground( const Song *pSong, const BackgroundDef &bd ); - // return def of the background that was created and added to m_BGAnimations. calls CreateBackground - BackgroundDef CreateRandomBGA( const Song *pSong, deque &RandomBGAnimations ); - - int FindBGSegmentForBeat( float fBeat ) const; - void UpdateCurBGChange( const Song *pSong, float fLastMusicSeconds, float fCurrentTime, const map &mapNameToTransition ); - - map m_BGAnimations; - vector m_aBGChanges; - int m_iCurBGChangeIndex; - Actor *m_pCurrentBGA; - Actor *m_pFadingBGA; - float m_fSecsLeftInFade; - }; - Layer m_Layer[NUM_BACKGROUND_LAYERS]; - - float m_fLastMusicSeconds; - - BGAnimation m_DangerPlayer[NUM_PLAYERS]; - BGAnimation m_DangerAll; - - BGAnimation m_DeadPlayer[NUM_PLAYERS]; - - // cover up the edge of animations that might hang outside of the background rectangle - Quad m_quadBorderLeft, m_quadBorderTop, m_quadBorderRight, m_quadBorderBottom; - - BrightnessOverlay m_Brightness; - - BackgroundDef STATIC_BACKGROUND_DEF; + BackgroundImpl *m_pImpl; }; diff --git a/stepmania/src/BackgroundUtil.cpp b/stepmania/src/BackgroundUtil.cpp index 509002126f..c32186a8c1 100644 --- a/stepmania/src/BackgroundUtil.cpp +++ b/stepmania/src/BackgroundUtil.cpp @@ -185,7 +185,7 @@ void BackgroundUtil::GetGlobalRandomMovies( const Song *pSong, const CString &sM if( !vsPathsOut.empty() ) goto found_files; - if( sMatch != "-nosongbg-" ) + if( sMatch != NO_SONG_BG_FILE ) LOG->Warn( "Background missing: %s", sMatch.c_str() ); } diff --git a/stepmania/src/BackgroundUtil.h b/stepmania/src/BackgroundUtil.h index e41dd83920..e65dff8443 100644 --- a/stepmania/src/BackgroundUtil.h +++ b/stepmania/src/BackgroundUtil.h @@ -12,7 +12,8 @@ const CString SBE_StretchRewind = "StretchRewind"; const CString SBT_CrossFade = "CrossFade"; const CString RANDOM_BACKGROUND_FILE = "-random-"; -const CString SONG_BACKGROUND_FILE = "songbackground"; +const CString NO_SONG_BG_FILE = "-nosongbg-"; +const CString SONG_BACKGROUND_FILE = "songbackground"; struct BackgroundDef { @@ -41,7 +42,7 @@ struct BackgroundDef CString m_sFile2; // may be "" }; -struct BackgroundChange : public BackgroundDef +struct BackgroundChange { BackgroundChange() { @@ -58,12 +59,13 @@ struct BackgroundChange : public BackgroundDef ) { m_fStartBeat=s; - m_sFile1=f1; - m_sFile2=f2; + m_def.m_sFile1=f1; + m_def.m_sFile2=f2; m_fRate=r; - m_sEffect=e; + m_def.m_sEffect=e; m_sTransition=t; } + BackgroundDef m_def; float m_fStartBeat; float m_fRate; CString m_sTransition; diff --git a/stepmania/src/DifficultyDisplay.cpp b/stepmania/src/DifficultyDisplay.cpp index 746d8818ab..c13b211908 100644 --- a/stepmania/src/DifficultyDisplay.cpp +++ b/stepmania/src/DifficultyDisplay.cpp @@ -3,6 +3,7 @@ #include "song.h" #include "ThemeMetric.h" #include "Command.h" +#include "RageUtil.h" ThemeMetric ICONONCOMMAND ("DifficultyDisplay","IconOnCommand"); ThemeMetric ICONOFFCOMMAND ("DifficultyDisplay","IconOffCommand"); diff --git a/stepmania/src/Foreground.cpp b/stepmania/src/Foreground.cpp index ab54ba108a..e35b82c183 100644 --- a/stepmania/src/Foreground.cpp +++ b/stepmania/src/Foreground.cpp @@ -6,6 +6,8 @@ #include "RageTextureManager.h" #include "ActorUtil.h" #include "song.h" +#include "BackgroundUtil.h" +#include "Foreach.h" Foreground::~Foreground() { @@ -29,10 +31,10 @@ void Foreground::LoadFromSong( const Song *pSong ) TEXTUREMAN->SetDefaultTexturePolicy( RageTextureID::TEX_VOLATILE ); m_pSong = pSong; - for( unsigned i=0; im_ForegroundChanges.size(); i++ ) + FOREACH_CONST( BackgroundChange, pSong->GetForegroundChanges(), bgc ) { - const BackgroundChange &change = pSong->m_ForegroundChanges[i]; - CString sBGName = change.m_sFile1; + const BackgroundChange &change = *bgc; + CString sBGName = change.m_def.m_sFile1; LoadedBGA bga; bga.m_bga = ActorUtil::MakeActor( pSong->GetSongDir() + sBGName ); diff --git a/stepmania/src/Foreground.h b/stepmania/src/Foreground.h index b3aa2834af..716b9cea0b 100644 --- a/stepmania/src/Foreground.h +++ b/stepmania/src/Foreground.h @@ -4,6 +4,7 @@ #include "ActorFrame.h" class Song; + class Foreground: public ActorFrame { public: diff --git a/stepmania/src/MusicList.cpp b/stepmania/src/MusicList.cpp index 6327a925fe..11316147f9 100644 --- a/stepmania/src/MusicList.cpp +++ b/stepmania/src/MusicList.cpp @@ -2,6 +2,7 @@ #include "MusicList.h" #include "ThemeManager.h" #include "ThemeMetric.h" +#include "RageUtil.h" /* If this actor is used anywhere other than SelectGroup, we * can add a setting that changes which metric group we pull diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index f9229ade23..4838db4e2d 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -19,6 +19,7 @@ #include "Style.h" #include "CommonMetrics.h" #include +#include "BackgroundUtil.h" NoteField::NoteField() { @@ -533,18 +534,18 @@ void NoteField::DrawPrimitives() break; case EDIT_MODE_FULL: { - vector::iterator iter[NUM_BACKGROUND_LAYERS]; - for( int i=0; im_pCurSong->m_BackgroundChanges[i].begin(); + vector::iterator iter[NUM_BackgroundLayer]; + FOREACH_BackgroundLayer( i ) + iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin(); while( 1 ) { float fLowestBeat = FLT_MAX; - vector viLowestIndex; + vector viLowestIndex; - for( int i=0; im_pCurSong->m_BackgroundChanges[i].end() ) + if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() ) continue; float fBeat = iter[i]->m_fStartBeat; @@ -566,23 +567,23 @@ void NoteField::DrawPrimitives() if( IS_ON_SCREEN(fLowestBeat) ) { vector vs; - FOREACH_CONST( int, viLowestIndex, i ) + FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) { - ASSERT( iter[*i] != GAMESTATE->m_pCurSong->m_BackgroundChanges[*i].end() ); + ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() ); const BackgroundChange& change = *iter[*i]; vs.push_back( ssprintf("%s%s%s%s%s%s", ((*i!=0) ? ssprintf("%d: ",*i) : CString()).c_str(), - (!change.m_sFile1.empty() ? " "+change.m_sFile1 : CString()).c_str(), - (!change.m_sFile2.empty() ? " "+change.m_sFile2 : CString()).c_str(), + (!change.m_def.m_sFile1.empty() ? " "+change.m_def.m_sFile1 : CString()).c_str(), + (!change.m_def.m_sFile2.empty() ? " "+change.m_def.m_sFile2 : CString()).c_str(), ((change.m_fRate!=1.0f) ? ssprintf("%.2f%%",change.m_fRate*100) : CString()).c_str(), (!change.m_sTransition.empty() ? " "+change.m_sTransition : CString()).c_str(), - (!change.m_sEffect.empty() ? " "+change.m_sEffect : CString()).c_str() + (!change.m_def.m_sEffect.empty() ? " "+change.m_def.m_sEffect : CString()).c_str() ) ); } DrawBGChangeText( fLowestBeat, join("\n",vs) ); } - FOREACH_CONST( int, viLowestIndex, i ) + FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) iter[*i]++; } } diff --git a/stepmania/src/NotesLoaderSM.cpp b/stepmania/src/NotesLoaderSM.cpp index fc210c26cf..dc1fd98835 100644 --- a/stepmania/src/NotesLoaderSM.cpp +++ b/stepmania/src/NotesLoaderSM.cpp @@ -8,6 +8,7 @@ #include "SongManager.h" #include "RageFileManager.h" #include "NoteTypes.h" +#include "BackgroundUtil.h" #define MAX_EDIT_SIZE_BYTES 20*1024 // 20 KB @@ -170,20 +171,20 @@ bool LoadFromBGChangesString( BackgroundChange &change, const CString &sBGChange // m_sEffect may be overwritten by param 7 below. if( bRewindMovie ) - change.m_sEffect = SBE_StretchRewind; + change.m_def.m_sEffect = SBE_StretchRewind; if( !bLoop ) - change.m_sEffect = SBE_StretchNoLoop; + change.m_def.m_sEffect = SBE_StretchNoLoop; } if( aBGChangeValues.size() >= 9 ) { - change.m_sEffect = aBGChangeValues[6]; - change.m_sFile2 = aBGChangeValues[7]; + change.m_def.m_sEffect = aBGChangeValues[6]; + change.m_def.m_sFile2 = aBGChangeValues[7]; change.m_sTransition = aBGChangeValues[8]; } if( aBGChangeValues.size() >= 2 ) { change.m_fStartBeat = strtof( aBGChangeValues[0], NULL ); - change.m_sFile1 = aBGChangeValues[1]; + change.m_def.m_sFile1 = aBGChangeValues[1]; return true; } else @@ -334,10 +335,10 @@ bool SMLoader::LoadFromSMFile( CString sPath, Song &out ) else if( sValueName=="BGCHANGES" || sValueName=="ANIMATIONS" ) { - int iLayer = 0; + BackgroundLayer iLayer = BACKGROUND_LAYER_1; sscanf( sValueName, "BGCHANGES%d", &iLayer ); - if( iLayer < 0 && iLayer >= NUM_BACKGROUND_LAYERS ) + if( iLayer < 0 && iLayer >= NUM_BackgroundLayer ) { LOG->Warn( "The song file '%s' has a BGCHANGES tag '%s' that is out of range.", sPath.c_str(), sValueName.c_str() ); } @@ -548,7 +549,7 @@ void SMLoader::TidyUpData( Song &song, bool cache ) * have to add an explicit song BG tag if they want it. This is really a * formatting hack only; nothing outside of SMLoader ever sees "-nosongbg-". */ - vector &bg = song.m_BackgroundChanges[0]; + vector &bg = song.GetBackgroundChanges(BACKGROUND_LAYER_1); if( !bg.empty() ) { /* BGChanges have been sorted. On the odd chance that a BGChange exists @@ -557,7 +558,7 @@ void SMLoader::TidyUpData( Song &song, bool cache ) for( unsigned i = 0; !bHasNoSongBgTag && i < bg.size(); ++i ) { - if( !bg[i].m_sFile1.CompareNoCase("-nosongbg-") ) + if( !bg[i].m_def.m_sFile1.CompareNoCase(NO_SONG_BG_FILE) ) { bg.erase( bg.begin()+i ); bHasNoSongBgTag = true; @@ -578,7 +579,7 @@ void SMLoader::TidyUpData( Song &song, bool cache ) break; /* If the last BGA is already the song BGA, don't add a duplicate. */ - if( !bg.empty() && !bg.back().m_sFile1.CompareNoCase(song.m_sBackgroundFile) ) + if( !bg.empty() && !bg.back().m_def.m_sFile1.CompareNoCase(song.m_sBackgroundFile) ) break; if( !IsAFile( song.GetBackgroundPath() ) ) diff --git a/stepmania/src/NotesWriterSM.cpp b/stepmania/src/NotesWriterSM.cpp index 38d90aae13..940778b503 100644 --- a/stepmania/src/NotesWriterSM.cpp +++ b/stepmania/src/NotesWriterSM.cpp @@ -11,19 +11,20 @@ #include #include #include "Foreach.h" +#include "BackgroundUtil.h" static CString BackgroundChangeToString( const BackgroundChange &bgc ) { return ssprintf( "%.3f=%s=%.3f=%d=%d=%d=%s=%s=%s,", bgc.m_fStartBeat, - bgc.m_sFile1.c_str(), + bgc.m_def.m_sFile1.c_str(), bgc.m_fRate, bgc.m_sTransition == SBT_CrossFade, // backward compat - bgc.m_sEffect == SBE_StretchRewind, // backward compat - bgc.m_sEffect != SBE_StretchNoLoop, // backward compat - bgc.m_sEffect.c_str(), - bgc.m_sFile2.c_str(), + bgc.m_def.m_sEffect == SBE_StretchRewind, // backward compat + bgc.m_def.m_sEffect != SBE_StretchNoLoop, // backward compat + bgc.m_def.m_sEffect.c_str(), + bgc.m_def.m_sFile2.c_str(), bgc.m_sTransition.c_str() ); } @@ -95,31 +96,31 @@ void NotesWriterSM::WriteGlobalTags( RageFile &f, const Song &out ) } f.PutLine( ";" ); - for( int b=0; bGetMetricF("ScreenCredits","BackgroundsSpacingX") diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index f285f2edb4..2e9764247a 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -2083,9 +2083,9 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns bool bAlreadyBGChangeHere = false; int iLayer = 0; BackgroundChange bgChange; - for( int l=0; lm_BackgroundChanges[l], bgc ) + FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(l), bgc ) { if( bgc->m_fStartBeat == GAMESTATE->m_fSongBeat ) { @@ -2114,24 +2114,24 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns // set default choices - g_BackgroundChange.rows[layer]. SetDefaultChoiceIfPresent( ssprintf("%d",iLayer) ); - g_BackgroundChange.rows[rate]. SetDefaultChoiceIfPresent( ssprintf("%2.0f%%",bgChange.m_fRate*100) ); - g_BackgroundChange.rows[transition]. SetDefaultChoiceIfPresent( bgChange.m_sTransition ); - g_BackgroundChange.rows[effect]. SetDefaultChoiceIfPresent( bgChange.m_sEffect ); + g_BackgroundChange.rows[layer]. SetDefaultChoiceIfPresent( ssprintf("%d",iLayer) ); + g_BackgroundChange.rows[rate]. SetDefaultChoiceIfPresent( ssprintf("%2.0f%%",bgChange.m_fRate*100) ); + g_BackgroundChange.rows[transition]. SetDefaultChoiceIfPresent( bgChange.m_sTransition ); + g_BackgroundChange.rows[effect]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sEffect ); g_BackgroundChange.rows[file1_type].iDefaultChoice = none; - if( bgChange.m_sFile1 == RANDOM_BACKGROUND_FILE ) g_BackgroundChange.rows[file1_type].iDefaultChoice = pick_random; - if( g_BackgroundChange.rows[file1_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_bganimation; - if( g_BackgroundChange.rows[file1_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_movie; - if( g_BackgroundChange.rows[file1_song_still]. SetDefaultChoiceIfPresent( bgChange.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_bitmap; - if( g_BackgroundChange.rows[file1_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = global_bganimation; - if( g_BackgroundChange.rows[file1_global_random_movie]. SetDefaultChoiceIfPresent( bgChange.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = global_movie; + if( bgChange.m_def.m_sFile1 == RANDOM_BACKGROUND_FILE ) g_BackgroundChange.rows[file1_type].iDefaultChoice = pick_random; + if( g_BackgroundChange.rows[file1_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_bganimation; + if( g_BackgroundChange.rows[file1_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_movie; + if( g_BackgroundChange.rows[file1_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = song_bitmap; + if( g_BackgroundChange.rows[file1_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = global_bganimation; + if( g_BackgroundChange.rows[file1_global_random_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) g_BackgroundChange.rows[file1_type].iDefaultChoice = global_movie; g_BackgroundChange.rows[file2_type].iDefaultChoice = none; - if( bgChange.m_sFile2 == RANDOM_BACKGROUND_FILE ) g_BackgroundChange.rows[file2_type].iDefaultChoice = pick_random; - if( g_BackgroundChange.rows[file2_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_bganimation; - if( g_BackgroundChange.rows[file2_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_movie; - if( g_BackgroundChange.rows[file2_song_still]. SetDefaultChoiceIfPresent( bgChange.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_bitmap; - if( g_BackgroundChange.rows[file2_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = global_bganimation; - if( g_BackgroundChange.rows[file2_global_random_movie]. SetDefaultChoiceIfPresent( bgChange.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = global_movie; + if( bgChange.m_def.m_sFile2 == RANDOM_BACKGROUND_FILE ) g_BackgroundChange.rows[file2_type].iDefaultChoice = pick_random; + if( g_BackgroundChange.rows[file2_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_bganimation; + if( g_BackgroundChange.rows[file2_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_movie; + if( g_BackgroundChange.rows[file2_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = song_bitmap; + if( g_BackgroundChange.rows[file2_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = global_bganimation; + if( g_BackgroundChange.rows[file2_global_random_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) g_BackgroundChange.rows[file2_type].iDefaultChoice = global_movie; SCREENMAN->MiniMenu( &g_BackgroundChange, SM_BackFromBGChange ); @@ -2643,16 +2643,16 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAnswers ) { - int iLayer = atoi( g_BackgroundChange.rows[layer].choices[iAnswers[layer]] ); + BackgroundLayer iLayer = (BackgroundLayer)atoi( g_BackgroundChange.rows[layer].choices[iAnswers[layer]] ); BackgroundChange newChange; - FOREACH( BackgroundChange, m_pSong->m_BackgroundChanges[iLayer], iter ) + FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(iLayer), iter ) { if( iter->m_fStartBeat == GAMESTATE->m_fSongBeat ) { newChange = *iter; // delete the old change. We'll add a new one below. - m_pSong->m_BackgroundChanges[iLayer].erase( iter ); + m_pSong->GetBackgroundChanges(iLayer).erase( iter ); break; } } @@ -2663,12 +2663,12 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns newChange.m_fStartBeat = GAMESTATE->m_fSongBeat; newChange.m_fRate = strtof( g_BackgroundChange.rows[rate].choices[iAnswers[rate]], NULL )/100.f; newChange.m_sTransition = g_BackgroundChange.rows[transition].choices[iAnswers[transition]]; - newChange.m_sEffect = g_BackgroundChange.rows[effect].choices[iAnswers[effect]]; + newChange.m_def.m_sEffect = g_BackgroundChange.rows[effect].choices[iAnswers[effect]]; switch( iAnswers[file1_type] ) { default: ASSERT(0); - case none: newChange.m_sFile1 = ""; break; - case pick_random: newChange.m_sFile1 = RANDOM_BACKGROUND_FILE; break; + case none: newChange.m_def.m_sFile1 = ""; break; + case pick_random: newChange.m_def.m_sFile1 = RANDOM_BACKGROUND_FILE; break; case song_bganimation: case song_movie: case song_bitmap: @@ -2676,15 +2676,15 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns case global_movie: { BGChangeChoice row1 = (BGChangeChoice)(file1_song_bganimation + iAnswers[file1_type]-2); - newChange.m_sFile1 = g_BackgroundChange.rows[row1].choices[iAnswers[row1]]; + newChange.m_def.m_sFile1 = g_BackgroundChange.rows[row1].choices[iAnswers[row1]]; } break; } switch( iAnswers[file2_type] ) { default: ASSERT(0); - case none: newChange.m_sFile2 = ""; break; - case pick_random: newChange.m_sFile2 = RANDOM_BACKGROUND_FILE; break; + case none: newChange.m_def.m_sFile2 = ""; break; + case pick_random: newChange.m_def.m_sFile2 = RANDOM_BACKGROUND_FILE; break; case song_bganimation: case song_movie: case song_bitmap: @@ -2692,7 +2692,7 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns case global_movie: { BGChangeChoice row2 = (BGChangeChoice)(file2_song_bganimation + iAnswers[file2_type]-2); - newChange.m_sFile2 = g_BackgroundChange.rows[row2].choices[iAnswers[row2]]; + newChange.m_def.m_sFile2 = g_BackgroundChange.rows[row2].choices[iAnswers[row2]]; } break; } diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index d5bf172445..b24e20e67e 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -24,6 +24,7 @@ #include "ProfileManager.h" #include "Foreach.h" #include "UnlockManager.h" +#include "BackgroundUtil.h" #include "NotesLoaderSM.h" #include "NotesLoaderDWI.h" @@ -49,6 +50,11 @@ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; ////////////////////////////// Song::Song() { + FOREACH_BackgroundLayer( i ) + m_BackgroundChanges[i] = new vector; + m_ForegroundChanges = new vector; + + m_LoadedFromProfile = PROFILE_SLOT_INVALID; m_fMusicSampleStartSeconds = -1; m_fMusicSampleLengthSeconds = DEFAULT_MUSIC_SAMPLE_LENGTH; @@ -66,6 +72,10 @@ Song::Song() Song::~Song() { + FOREACH_BackgroundLayer( i ) + SAFE_DELETE( m_BackgroundChanges[i] ); + SAFE_DELETE( m_ForegroundChanges ); + FOREACH( Steps*, m_vpSteps, s ) SAFE_DELETE( *s ); m_vpSteps.clear(); @@ -98,17 +108,17 @@ void Song::Reset() } -void Song::AddBackgroundChange( int iLayer, BackgroundChange seg ) +void Song::AddBackgroundChange( BackgroundLayer iLayer, BackgroundChange seg ) { - ASSERT( iLayer >= 0 && iLayer < NUM_BACKGROUND_LAYERS ); - m_BackgroundChanges[iLayer].push_back( seg ); - BackgroundUtil::SortBackgroundChangesArray( m_BackgroundChanges[iLayer] ); + ASSERT( iLayer >= 0 && iLayer < NUM_BackgroundLayer ); + GetBackgroundChanges(iLayer).push_back( seg ); + BackgroundUtil::SortBackgroundChangesArray( GetBackgroundChanges(iLayer) ); } void Song::AddForegroundChange( BackgroundChange seg ) { - m_ForegroundChanges.push_back( seg ); - BackgroundUtil::SortBackgroundChangesArray( m_ForegroundChanges ); + GetForegroundChanges().push_back( seg ); + BackgroundUtil::SortBackgroundChangesArray( GetForegroundChanges() ); } void Song::AddLyricSegment( LyricSegment seg ) @@ -132,13 +142,12 @@ void Song::GetDisplayBpms( DisplayBpms &AddTo ) const } } -const BackgroundChange &Song::GetBackgroundAtBeat( int iLayer, float fBeat ) const +const BackgroundChange &Song::GetBackgroundAtBeat( BackgroundLayer iLayer, float fBeat ) const { - unsigned i; - for( i=0; i fBeat ) - break; - return m_BackgroundChanges[iLayer][i]; + for( unsigned i=0; i fBeat ) + return GetBackgroundChanges(iLayer)[i]; + return GetBackgroundChanges(iLayer)[0]; } @@ -709,7 +718,7 @@ void Song::TidyUpData() /* Use this->GetBeatFromElapsedTime(0) instead of 0 to start when the * music starts. */ if( arrayPossibleMovies.size() == 1 ) - this->AddBackgroundChange( 0, BackgroundChange(0,arrayPossibleMovies[0],"",1.f,SBE_StretchNoLoop) ); + this->AddBackgroundChange( BACKGROUND_LAYER_1, BackgroundChange(0,arrayPossibleMovies[0],"",1.f,SBE_StretchNoLoop) ); } @@ -1200,14 +1209,33 @@ bool Song::HasBackground() const {return m_sBackgroundFile != "" && IsAFile(G bool Song::HasCDTitle() const {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); } bool Song::HasBGChanges() const { - for( int i=0; i &Song::GetBackgroundChanges( BackgroundLayer bl ) const +{ + return *(m_BackgroundChanges[bl]); +} +vector &Song::GetBackgroundChanges( BackgroundLayer bl ) +{ + return *(m_BackgroundChanges[bl]); +} + +const vector &Song::GetForegroundChanges() const +{ + return *m_ForegroundChanges; +} +vector &Song::GetForegroundChanges() +{ + return *m_ForegroundChanges; +} + + CString GetSongAssetPath( CString sPath, const CString &sSongPath ) { if( sPath == "" ) diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index 52ad700c3d..3942a41cae 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -29,6 +29,7 @@ #include "Foreach.h" #include "StatsManager.h" #include "Style.h" +#include "BackgroundUtil.h" SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program @@ -232,7 +233,7 @@ void SongManager::LoadStepManiaSongDir( CString sDir, LoadingWindow *ld ) } } -// Why Symlink instead of allowing membership in multiple groups via song tags? +// Instead of "symlinks", songs should have membership in multiple groups. // -Chris void SongManager::LoadGroupSymLinks(CString sDir, CString sGroupFolder) { @@ -257,8 +258,8 @@ void SongManager::LoadGroupSymLinks(CString sDir, CString sGroupFolder) while( vpSteps.size() ) pNewSong->RemoveSteps( vpSteps[0] ); - for( int i=0; im_BackgroundChanges[i].clear(); + FOREACH_BackgroundLayer( i ) + pNewSong->GetBackgroundChanges(i).clear(); pNewSong->m_bIsSymLink = true; // Very important so we don't double-parse later pNewSong->m_sGroupName = sGroupFolder; diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 8bf5b3aad9..66937bca76 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -3,11 +3,9 @@ #ifndef SONG_H #define SONG_H -#include "PlayerNumber.h" -#include "BackgroundUtil.h" -#include "Grade.h" #include "TimingData.h" #include "Difficulty.h" +#include "EnumHelper.h" class Steps; class Style; @@ -16,13 +14,20 @@ class LyricsLoader; class Profile; class StepsID; struct lua_State; +struct BackgroundChange; const int MAX_EDITS_PER_SONG_PER_PROFILE = 5; const int MAX_EDITS_PER_SONG = 5*NUM_PROFILE_SLOTS; extern const int FILE_CACHE_VERSION; -const int NUM_BACKGROUND_LAYERS = 2; +enum BackgroundLayer +{ + BACKGROUND_LAYER_1, + BACKGROUND_LAYER_2, + NUM_BackgroundLayer +}; +#define FOREACH_BackgroundLayer( bl ) FOREACH_ENUM( BackgroundLayer, NUM_BackgroundLayer, bl ) struct LyricSegment { @@ -141,18 +146,26 @@ public: bool Matches(CString sGroup, CString sSong) const; TimingData m_Timing; - vector m_BackgroundChanges[NUM_BACKGROUND_LAYERS]; // these must be sorted before gameplay - vector m_ForegroundChanges; // this must be sorted before gameplay + +private: + vector *m_BackgroundChanges[NUM_BackgroundLayer]; // these must be sorted before gameplay + vector *m_ForegroundChanges; // this must be sorted before gameplay +public: + const vector &GetBackgroundChanges( BackgroundLayer bl ) const; + vector &GetBackgroundChanges( BackgroundLayer bl ); + const vector &GetForegroundChanges() const; + vector &GetForegroundChanges(); + vector m_LyricSegments; // this must be sorted before gameplay void AddBPMSegment( const BPMSegment &seg ) { m_Timing.AddBPMSegment( seg ); } void AddStopSegment( const StopSegment &seg ) { m_Timing.AddStopSegment( seg ); } - void AddBackgroundChange( int iLayer, BackgroundChange seg ); + void AddBackgroundChange( BackgroundLayer blLayer, BackgroundChange seg ); void AddForegroundChange( BackgroundChange seg ); void AddLyricSegment( LyricSegment seg ); void GetDisplayBpms( DisplayBpms &AddTo ) const; - const BackgroundChange &GetBackgroundAtBeat( int iLayer, float fBeat ) const; + const BackgroundChange &GetBackgroundAtBeat( BackgroundLayer iLayer, float fBeat ) const; float GetBPMAtBeat( float fBeat ) const { return m_Timing.GetBPMAtBeat( fBeat ); } void SetBPMAtBeat( float fBeat, float fBPM ) { m_Timing.SetBPMAtBeat( fBeat, fBPM ); }