diff --git a/stepmania/src/Foreground.cpp b/stepmania/src/Foreground.cpp new file mode 100644 index 0000000000..2c4859bc3a --- /dev/null +++ b/stepmania/src/Foreground.cpp @@ -0,0 +1,64 @@ +#include "global.h" +#include "Foreground.h" +#include "BGAnimation.h" +#include "RageUtil.h" +#include "IniFile.h" +#include "GameState.h" + +Foreground::~Foreground() +{ + Unload(); +} + +void Foreground::Unload() +{ + for( unsigned i=0; i < m_BGAnimations.size(); ++i ) + delete m_BGAnimations[i].m_bga; + m_BGAnimations.clear(); +} + +void Foreground::LoadFromSong( const Song *pSong ) +{ + for( unsigned i=0; im_ForegroundChanges.size(); i++ ) + { + const BackgroundChange &change = pSong->m_ForegroundChanges[i]; + CString sBGName = change.m_sBGName; + + const CString sAniDir = pSong->GetSongDir()+sBGName; + if( !IsADirectory(sAniDir) ) + RageException::Throw( "The song foreground BGA \"%s\" is not a directory", sAniDir.c_str() ); + + LoadedBGA bga; + bga.m_bga = new BGAnimation; + bga.m_bga->LoadFromAniDir( sAniDir ); + bga.m_fStartBeat = change.m_fStartBeat; + + const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat ); + const float fStopSecond = fStartSecond + bga.m_bga->GetLengthSeconds(); + bga.m_fStopBeat = pSong->m_Timing.GetBeatFromElapsedTime( fStopSecond ); + + bga.m_bga->SetHidden( true ); + + this->AddChild( bga.m_bga ); + m_BGAnimations.push_back( bga ); + } + + this->SortByZ(); +} + +void Foreground::Update( float fDeltaTime ) +{ + if( GAMESTATE->m_fMusicSeconds == GameState::MUSIC_SECONDS_INVALID ) + return; /* hasn't been updated yet */ + + for( unsigned i=0; i < m_BGAnimations.size(); ++i ) + { + LoadedBGA &bga = m_BGAnimations[i]; + + const bool Shown = bga.m_fStartBeat <= GAMESTATE->m_fSongBeat && GAMESTATE->m_fSongBeat <= bga.m_fStopBeat; + bga.m_bga->SetHidden( !Shown ); + if( Shown ) + bga.m_bga->Update( fDeltaTime ); + } +} + diff --git a/stepmania/src/Foreground.h b/stepmania/src/Foreground.h new file mode 100644 index 0000000000..81e93be4d3 --- /dev/null +++ b/stepmania/src/Foreground.h @@ -0,0 +1,31 @@ +#ifndef FOREGROUND_H +#define FOREGROUND_H + +#include "ActorFrame.h" +#include "song.h" +class BGAnimation; + +class Foreground: public ActorFrame +{ +public: + ~Foreground(); + + void Unload(); + + void LoadFromSong( const Song *pSong ); + + virtual void Update( float fDeltaTime ); + +protected: + void LoadFromAniDir( CString sAniDir ); + struct LoadedBGA + { + BGAnimation *m_bga; + float m_fStartBeat; + float m_fStopBeat; + }; + + vector m_BGAnimations; +}; + +#endif diff --git a/stepmania/src/NotesLoaderSM.cpp b/stepmania/src/NotesLoaderSM.cpp index 86068d8b45..3d249d65de 100644 --- a/stepmania/src/NotesLoaderSM.cpp +++ b/stepmania/src/NotesLoaderSM.cpp @@ -132,6 +132,29 @@ void SMLoader::LoadTimingFromSMFile( MsdFile &msd, TimingData &out ) } } +bool LoadFromBGChangesString( BackgroundChange &change, const CString &sBGChangeExpression ) +{ + CStringArray aBGChangeValues; + split( sBGChangeExpression, "=", aBGChangeValues ); + + switch( aBGChangeValues.size() ) + { + case 6: + change.m_fRate = (float)atof( aBGChangeValues[2] ); + change.m_bFadeLast = atoi( aBGChangeValues[3] ) != 0; + change.m_bRewindMovie = atoi( aBGChangeValues[4] ) != 0; + change.m_bLoop = atoi( aBGChangeValues[5] ) != 0; + // fall through + case 2: + change.m_fStartBeat = (float)atof( aBGChangeValues[0] ); + change.m_sBGName = aBGChangeValues[1]; + return true; + default: + LOG->Warn("Invalid #BGCHANGES value \"%s\" was ignored", sBGChangeExpression.c_str()); + return false; + } +} + bool SMLoader::LoadFromSMFile( CString sPath, Song &out ) { LOG->Trace( "Song::LoadFromSMFile(%s)", sPath.c_str() ); @@ -271,30 +294,22 @@ bool SMLoader::LoadFromSMFile( CString sPath, Song &out ) for( unsigned b=0; b &lines, bool SkipLeadingBlankLines, bool OmitLastNewline ) diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index f53fa4eb96..363744c2b4 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -273,6 +273,10 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S m_Background.SetDiffuse( RageColor(0.4f,0.4f,0.4f,1) ); m_Background.SetZ( 2 ); // behind everything else this->AddChild( &m_Background ); + + m_Foreground.SetZ( -1 ); // on top of everything else except transitions + this->AddChild( &m_Foreground ); + m_sprStaticBackground.SetName( "StaticBG" ); m_sprStaticBackground.Load( THEME->GetPathToG("ScreenGameplay Static Background")); @@ -317,8 +321,10 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S this->AddChild(&m_TimingAssist); + m_NextSongIn.SetZ( -2 ); // on top of everything else this->AddChild( &m_NextSongIn ); + m_NextSongOut.SetZ( -2 ); // on top of everything else this->AddChild( &m_NextSongOut ); @@ -611,9 +617,11 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S this->AddChild( &m_Go ); m_Cleared.Load( THEME->GetPathToB("ScreenGameplay cleared") ); + m_Cleared.SetZ( -2 ); // on top of everything else this->AddChild( &m_Cleared ); m_Failed.Load( THEME->GetPathToB("ScreenGameplay failed") ); + m_Failed.SetZ( -2 ); // on top of everything else this->AddChild( &m_Failed ); if( PREFSMAN->m_bAllowExtraStage && GAMESTATE->IsFinalStage() ) // only load if we're going to use it @@ -638,6 +646,7 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S } m_In.Load( THEME->GetPathToB("ScreenGameplay in") ); + m_In.SetZ( -2 ); // on top of everything else this->AddChild( &m_In ); @@ -648,6 +657,7 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S m_Back.Load( THEME->GetPathToB("Common back") ); + m_Back.SetZ( -2 ); // on top of everything else this->AddChild( &m_Back ); @@ -663,7 +673,6 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S } - /* LoadNextSong first, since that positions some elements which need to be * positioned before we TweenOnScreen. */ LoadNextSong(); @@ -980,6 +989,7 @@ void ScreenGameplay::LoadNextSong() m_Background.BeginTweening( 2 ); m_Background.SetDiffuse( RageColor(1,1,1,1) ); + m_Foreground.LoadFromSong( GAMESTATE->m_pCurSong ); m_fTimeLeftBeforeDancingComment = GAMESTATE->m_pCurSong->m_fFirstBeat + SECONDS_BETWEEN_COMMENTS; diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index 5b402479ae..62ac4e028b 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -19,6 +19,7 @@ #include "RandomSample.h" #include "RageSound.h" #include "Background.h" +#include "Foreground.h" #include "LifeMeter.h" #include "ScoreDisplay.h" #include "DifficultyIcon.h" @@ -102,6 +103,7 @@ protected: TimingAssist m_TimingAssist; Background m_Background; + Foreground m_Foreground; Transition m_NextSongIn; // shows between songs in a course Transition m_NextSongOut; // shows between songs in a course diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 398d9f0c49..5f43069edf 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -117,6 +117,11 @@ void Song::AddBackgroundChange( BackgroundChange seg ) SortBackgroundChangesArray( m_BackgroundChanges ); } +void Song::AddForegroundChange( BackgroundChange seg ) +{ + m_ForegroundChanges.push_back( seg ); + SortBackgroundChangesArray( m_ForegroundChanges ); +} void Song::AddLyricSegment( LyricSegment seg ) { diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 798ac5730a..5a0ddd1b78 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -65,7 +65,7 @@ IntDir=.\../Debug6 TargetDir=\temp\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -82,24 +82,24 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" -LINK32=link.exe -# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP -# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo CPP=cl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_XBOX" /D "_DEBUG" /YX /FD /G6 /Ztmp /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /D "OGG_ONLY" /YX /FD /G6 /Ztmp /c +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP +# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \ - verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \ + verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -139,7 +139,7 @@ IntDir=.\../Release6 TargetDir=\temp\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -157,27 +157,27 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "StepMania___Xbox_Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c +# SUBTRACT CPP /Fr +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 $(intdir)\verstub.obj xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /pdb:"../debug6/StepMania-debug.pdb" /map /debug /machine:IX86 /nodefaultlib:"libcmtd.lib" /out:"../StepMania-debug.exe" # SUBTRACT BASE LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # ADD LINK32 $(intdir)\verstub.obj xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xnet.lib xboxkrnl.lib libcmt.lib /nologo /incremental:no /pdb:"../release6xbox/StepMania.pdb" /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"libcmtd" /out:"../StepManiaXbox.exe" /subsystem:xbox /fixed:no /TMP /OPT:REF # SUBTRACT LINK32 /pdb:none /map /debug -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -CPP=cl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c -# SUBTRACT CPP /Fr +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \ - verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \ + verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -3212,6 +3212,25 @@ SOURCE=.\DancingCharacters.h # End Source File # Begin Source File +SOURCE=.\Foreground.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Foreground.h +# End Source File +# Begin Source File + SOURCE=.\GhostArrow.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 346f1951db..88546e8fed 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -1415,6 +1415,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 40c598f8d9..1ded5acbcb 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -155,11 +155,13 @@ public: TimingData m_Timing; vector m_BackgroundChanges; // this must be sorted before gameplay - vector m_LyricSegments; // same + vector m_ForegroundChanges; // this must be sorted before gameplay + 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( BackgroundChange seg ); + void AddForegroundChange( BackgroundChange seg ); void AddLyricSegment( LyricSegment seg ); void GetDisplayBPM( float &fMinBPMOut, float &fMaxBPMOut ) const;