From 69fd514b68bbbd2693730c6da9b9136db36c985c Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 1 Feb 2004 03:14:37 +0000 Subject: [PATCH] add 3D scrolling to ActorScroller generalize BGAnimation, BGAnimationLayer to eliminate shared code with ActorFrame --- stepmania/Themes/default/metrics.ini | 15 ++ stepmania/src/Actor.cpp | 4 +- stepmania/src/Actor.h | 10 +- stepmania/src/ActorFrame.cpp | 20 +++ stepmania/src/ActorFrame.h | 4 + stepmania/src/ActorScroller.cpp | 71 +++++++-- stepmania/src/ActorScroller.h | 27 +++- stepmania/src/ActorUtil.cpp | 14 +- stepmania/src/ActorUtil.h | 18 +-- stepmania/src/BGAnimation.cpp | 143 ++++++------------ stepmania/src/BGAnimation.h | 27 +--- stepmania/src/BGAnimationLayer.cpp | 9 -- stepmania/src/Screen.cpp | 9 +- stepmania/src/ScreenAttract.cpp | 10 +- stepmania/src/ScreenCredits.cpp | 12 +- stepmania/src/ScreenGameplay.cpp | 16 +- stepmania/src/ScreenSelectMaster.cpp | 140 ++++++++--------- stepmania/src/ScreenSelectMaster.h | 6 +- stepmania/src/ThemeManager.cpp | 29 ++-- .../arch/MovieTexture/MovieTexture_Null.cpp | 2 + 20 files changed, 324 insertions(+), 262 deletions(-) diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 627e991ab0..c4e530e524 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -3342,6 +3342,8 @@ MemoryCardIcons=0 TimerSeconds=0 [ScreenUnlock] +Fallback=ScreenAttract + UseUnlocksDat=1 TypeOfPointsToDisplay=DP TimeToDisplay=10 @@ -3477,6 +3479,8 @@ Unlock20X=250 Unlock20Y=325 [ScreenRanking] +Fallback=ScreenAttract + StepsTypesToHide=dance-couple,dance-solo,pump-halfdouble ShowCategories=1 CoursesToShow=Courses/DDRMAX/NaokiStandard.crs,Courses/DDRMAX/ParanoiaBrothers.crs,Courses/Samples/PlayersBest1-4.crs @@ -3597,21 +3601,32 @@ Line3=conf,AttractSoundFrequency Line4=conf,SoundVolume [ScreenIntroMovie] +Class=ScreenAttract +Fallback=ScreenAttract NextScreen=ScreenDemonstration [ScreenMemoryCard] +Class=ScreenAttract +Fallback=ScreenAttract NextScreen=ScreenWarning [ScreenWarning] +Class=ScreenAttract +Fallback=ScreenAttract NextScreen=ScreenCompany [ScreenCompany] +Class=ScreenAttract +Fallback=ScreenAttract NextScreen=ScreenLogo [ScreenAlbums] +Class=ScreenAttract +Fallback=ScreenAttract NextScreen=ScreenLogo [ScreenLogo] +Fallback=ScreenAttract LogoOnCommand=x,320;y,240;zoomy,0;sleep,0.5;bounceend,0.5;zoomy,1;glowshift;effectperiod,2.5;effectcolor1,1,1,1,0.1;effectcolor2,1,1,1,0.3 NextScreen=ScreenHowToPlay diff --git a/stepmania/src/Actor.cpp b/stepmania/src/Actor.cpp index 2090d19cd2..065b28fcac 100644 --- a/stepmania/src/Actor.cpp +++ b/stepmania/src/Actor.cpp @@ -709,7 +709,7 @@ void Actor::AddRotationR( float rot ) RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromR(rot) ); } -float Actor::Command( CString sCommands ) +void Actor::Command( CString sCommands ) { sCommands.MakeLower(); @@ -718,8 +718,6 @@ float Actor::Command( CString sCommands ) for( unsigned i=0; iHandleCommand( vCommands[i] ); - - return GetTweenTimeLeft(); } void Actor::HandleCommand( const ParsedCommand &command ) diff --git a/stepmania/src/Actor.h b/stepmania/src/Actor.h index 24ebabbbc7..f3dd8e9c94 100644 --- a/stepmania/src/Actor.h +++ b/stepmania/src/Actor.h @@ -294,7 +294,7 @@ public: void FadeOn( float fSleepSeconds, CString sFadeString, float fFadeSeconds ) { Fade(fSleepSeconds,sFadeString,fFadeSeconds,false); }; void FadeOff( float fSleepSeconds, CString sFadeString, float fFadeSeconds ) { Fade(fSleepSeconds,sFadeString,fFadeSeconds,true); }; - float Command( CString sCommands ); // return length in seconds to execute command + void Command( CString sCommands ); // return length in seconds to execute command virtual void HandleCommand( const ParsedCommand &command ); // derivable static float GetCommandLength( CString command ); @@ -302,6 +302,14 @@ public: virtual void SetSecondsIntoAnimation( float fSeconds ) {}; virtual int GetNumStates() { return 1; }; + // + // BGAnimation stuff + // + virtual void GainingFocus( float fRate, bool bRewindMovie, bool bLoop ) {} + virtual void LosingFocus() {} + virtual void PlayOffCommand() { this->PlayCommand("Off"); } + virtual void PlayCommand( const CString &sCommandName ) {} + protected: struct TweenInfo diff --git a/stepmania/src/ActorFrame.cpp b/stepmania/src/ActorFrame.cpp index 543184ecdc..7356b41f08 100644 --- a/stepmania/src/ActorFrame.cpp +++ b/stepmania/src/ActorFrame.cpp @@ -149,3 +149,23 @@ void ActorFrame::HandleCommand( const ParsedCommand &command ) // base class handles the rest... Actor::HandleCommand( command ); } + +void ActorFrame::GainingFocus( float fRate, bool bRewindMovie, bool bLoop ) +{ + for( unsigned i=0; iGainingFocus( fRate, bRewindMovie, bLoop ); + + SetDiffuse( RageColor(1,1,1,1) ); +} + +void ActorFrame::LosingFocus() +{ + for( unsigned i=0; iLosingFocus(); +} + +void ActorFrame::PlayCommand( const CString &sCommandName ) +{ + for( unsigned i=0; iPlayCommand( sCommandName ); +} diff --git a/stepmania/src/ActorFrame.h b/stepmania/src/ActorFrame.h index 25e2ce8e1c..7cd87ee43c 100644 --- a/stepmania/src/ActorFrame.h +++ b/stepmania/src/ActorFrame.h @@ -42,6 +42,10 @@ public: /* Amount of time until all tweens (and all children's tweens) have stopped: */ virtual float GetTweenTimeLeft() const; + virtual void GainingFocus( float fRate, bool bRewindMovie, bool bLoop ); + virtual void LosingFocus(); + virtual void PlayCommand( const CString &sCommandName ); + protected: vector m_SubActors; }; diff --git a/stepmania/src/ActorScroller.cpp b/stepmania/src/ActorScroller.cpp index 2032027500..f8fd5f9594 100644 --- a/stepmania/src/ActorScroller.cpp +++ b/stepmania/src/ActorScroller.cpp @@ -14,37 +14,80 @@ #include "ActorCollision.h" #include #include "RageUtil.h" +#include "RageDisplay.h" ActorScroller::ActorScroller() { + m_bLoaded = false; m_fCurrentItem = 0; m_fDestinationItem = 0; + m_fSecondsPerItem = 1; + m_iNumItemsToDraw = 7; + + m_vRotationDegrees = RageVector3(0,0,0); + m_vTranslateTerm0 = RageVector3(0,0,0); + m_vTranslateTerm1 = RageVector3(0,0,0); + m_vTranslateTerm2 = RageVector3(0,0,0); } -void ActorScroller::Load( float fScrollSecondsPerItem, float fSpacingX, float fSpacingY ) +void ActorScroller::Load( + float fSecondsPerItem, + int iNumItemsToDraw, + const RageVector3 &vRotationDegrees, + const RageVector3 &vTranslateTerm0, + const RageVector3 &vTranslateTerm1, + const RageVector3 &vTranslateTerm2 + ) { - ASSERT( fScrollSecondsPerItem > 0 ); - m_fScrollSecondsPerItem = fScrollSecondsPerItem; - m_vSpacing.x = fSpacingX; - m_vSpacing.y = fSpacingY; + ASSERT( fSecondsPerItem > 0 ); + m_fSecondsPerItem = fSecondsPerItem; + m_iNumItemsToDraw = iNumItemsToDraw; + m_vRotationDegrees = vRotationDegrees; + m_vTranslateTerm0 = vTranslateTerm0; + m_vTranslateTerm1 = vTranslateTerm1; + m_vTranslateTerm2 = vTranslateTerm2; + + m_bLoaded = true; } void ActorScroller::Update( float fDeltaTime ) { ActorFrame::Update( fDeltaTime ); - fapproach( m_fCurrentItem, m_fDestinationItem, fDeltaTime/m_fScrollSecondsPerItem ); + fapproach( m_fCurrentItem, m_fDestinationItem, fDeltaTime/m_fSecondsPerItem ); +} - for( unsigned i=0; iSetXY( fX, fY ); + if( m_vRotationDegrees[0] ) + DISPLAY->RotateX( m_vRotationDegrees[0]*fItemOffset ); + if( m_vRotationDegrees[1] ) + DISPLAY->RotateY( m_vRotationDegrees[1]*fItemOffset ); + if( m_vRotationDegrees[2] ) + DISPLAY->RotateZ( m_vRotationDegrees[2]*fItemOffset ); + + RageVector3 vTranslation = + m_vTranslateTerm0 + // m_vTranslateTerm0*itemOffset^0 + m_vTranslateTerm1 * fItemOffset + // m_vTranslateTerm1*itemOffset^1 + m_vTranslateTerm2 * fItemOffset*fItemOffset; // m_vTranslateTerm2*itemOffset^2 + DISPLAY->Translate( + vTranslation[0], + vTranslation[1], + vTranslation[2] + ); + + m_SubActors[i]->Draw(); + } + } + else + { + ActorFrame::DrawPrimitives(); } } diff --git a/stepmania/src/ActorScroller.h b/stepmania/src/ActorScroller.h index 4da9ce53e9..8d37c1ff1c 100644 --- a/stepmania/src/ActorScroller.h +++ b/stepmania/src/ActorScroller.h @@ -19,19 +19,38 @@ class ActorScroller : public ActorFrame public: ActorScroller(); - void Load( float fScrollSecondsPerItem, float fSpacingX, float fSpacingY ); + void Load( + float fScrollSecondsPerItem, + int iNumItemsToDraw, + const RageVector3 &vRotationDegrees, + const RageVector3 &vTranslateTerm0, + const RageVector3 &vTranslateTerm1, + const RageVector3 &vTranslateTerm2 ); virtual void Update( float fDelta ); - virtual void DrawPrimitives() {} // doesn't draw! + virtual void DrawPrimitives(); // DOES draw void SetDestinationItem( int iItem ) { m_fDestinationItem = float(iItem); } void SetCurrentAndDestinationItem( int iItem ) { m_fCurrentItem = m_fDestinationItem = float(iItem); } protected: + bool m_bLoaded; float m_fCurrentItem; // usually between 0 and m_SubActors.size() float m_fDestinationItem; - float m_fScrollSecondsPerItem; - RageVector2 m_vSpacing; + float m_fSecondsPerItem; + int m_iNumItemsToDraw; + + // Note: Rotation is applied before translation. + + // rot = m_vRotationDegrees*itemOffset^1 + RageVector3 m_vRotationDegrees; + + // trans = m_vTranslateTerm0*itemOffset^0 + + // m_vTranslateTerm1*itemOffset^1 + + // m_vTranslateTerm2*itemOffset^2 + RageVector3 m_vTranslateTerm0; + RageVector3 m_vTranslateTerm1; + RageVector3 m_vTranslateTerm2; }; diff --git a/stepmania/src/ActorUtil.cpp b/stepmania/src/ActorUtil.cpp index 44c96330f3..4f3c9035f5 100644 --- a/stepmania/src/ActorUtil.cpp +++ b/stepmania/src/ActorUtil.cpp @@ -26,6 +26,7 @@ #include "song.h" #include "GameState.h" #include "RageTextureManager.h" +#include "SongManager.h" Actor* LoadFromActorFile( CString sIniPath, CString sLayer ) @@ -95,7 +96,10 @@ Actor* LoadFromActorFile( CString sIniPath, CString sLayer ) } else if( sFile.CompareNoCase("songbanner")==0 ) { - const Song *pSong = GAMESTATE->m_pCurSong; + Song *pSong = GAMESTATE->m_pCurSong; + if( pSong == NULL ) + pSong = SONGMAN->GetRandomSong(); + if( pSong && pSong->HasBanner() ) sFile = pSong->GetBannerPath(); else @@ -187,14 +191,14 @@ void UtilSetXY( Actor& actor, CString sClassName ) actor.SetXY( THEME->GetMetricF(sClassName,actor.GetID()+"X"), THEME->GetMetricF(sClassName,actor.GetID()+"Y") ); } -float UtilCommand( Actor& actor, CString sClassName, CString sCommandName ) +void UtilCommand( Actor& actor, CString sClassName, CString sCommandName ) { // If Actor is hidden, it won't get updated or drawn, so don't bother tweening. /* ... but we might be unhiding it, or setting state for when we unhide it later */ // if( actor.GetHidden() ) // return 0; - float ret = actor.Command( "playcommand," + sCommandName ); + actor.Command( "playcommand," + sCommandName ); // HACK: It's very often that we command things to TweenOffScreen // that we aren't drawing. We know that an Actor is not being @@ -203,11 +207,11 @@ float UtilCommand( Actor& actor, CString sClassName, CString sCommandName ) if( sCommandName=="Off" ) { if( actor.GetID().empty() ) - return ret; + return; } else { RAGE_ASSERT_M( !actor.GetID().empty(), ssprintf("!actor.GetID().empty() ('%s', '%s')", sClassName.c_str(), sCommandName.c_str()) ); } - return max( ret, actor.Command( THEME->GetMetric(sClassName,actor.GetID()+sCommandName+"Command") ) ); + actor.Command( THEME->GetMetric(sClassName,actor.GetID()+sCommandName+"Command") ); } diff --git a/stepmania/src/ActorUtil.h b/stepmania/src/ActorUtil.h index 7f91a3214e..e27c04b1c9 100644 --- a/stepmania/src/ActorUtil.h +++ b/stepmania/src/ActorUtil.h @@ -26,21 +26,21 @@ void UtilSetXY( Actor& actor, CString sClassName ); inline void UtilSetXY( Actor* pActor, CString sClassName ) { UtilSetXY( *pActor, sClassName ); } -float UtilCommand( Actor& actor, CString sClassName, CString sCommandName ); +void UtilCommand( Actor& actor, CString sClassName, CString sCommandName ); -inline float UtilOnCommand( Actor& actor, CString sClassName ) { return UtilCommand( actor, sClassName, "On" ); } -inline float UtilOffCommand( Actor& actor, CString sClassName ) { return UtilCommand( actor, sClassName, "Off" ); } -inline float UtilSetXYAndOnCommand( Actor& actor, CString sClassName ) +inline void UtilOnCommand( Actor& actor, CString sClassName ) { UtilCommand( actor, sClassName, "On" ); } +inline void UtilOffCommand( Actor& actor, CString sClassName ) { UtilCommand( actor, sClassName, "Off" ); } +inline void UtilSetXYAndOnCommand( Actor& actor, CString sClassName ) { UtilSetXY( actor, sClassName ); - return UtilOnCommand( actor, sClassName ); + UtilOnCommand( actor, sClassName ); } /* convenience */ -inline float UtilCommand( Actor* pActor, CString sClassName, CString sCommandName ) { return UtilCommand( *pActor, sClassName, sCommandName ); } -inline float UtilOnCommand( Actor* pActor, CString sClassName ) { return UtilOnCommand( *pActor, sClassName ); } -inline float UtilOffCommand( Actor* pActor, CString sClassName ) { return UtilOffCommand( *pActor, sClassName ); } -inline float UtilSetXYAndOnCommand( Actor* pActor, CString sClassName ) { return UtilSetXYAndOnCommand( *pActor, sClassName ); } +inline void UtilCommand( Actor* pActor, CString sClassName, CString sCommandName ) { UtilCommand( *pActor, sClassName, sCommandName ); } +inline void UtilOnCommand( Actor* pActor, CString sClassName ) { UtilOnCommand( *pActor, sClassName ); } +inline void UtilOffCommand( Actor* pActor, CString sClassName ) { UtilOffCommand( *pActor, sClassName ); } +inline void UtilSetXYAndOnCommand( Actor* pActor, CString sClassName ) { UtilSetXYAndOnCommand( *pActor, sClassName ); } // Return a Sprite, BitmapText, or Model depending on the file type Actor* LoadFromActorFile( CString sIniPath, CString sLayer = "Actor" ); diff --git a/stepmania/src/BGAnimation.cpp b/stepmania/src/BGAnimation.cpp index a92e15b82a..d4924c1f8b 100644 --- a/stepmania/src/BGAnimation.cpp +++ b/stepmania/src/BGAnimation.cpp @@ -21,6 +21,7 @@ #include "ThemeManager.h" #include "RageFile.h" #include "ActorUtil.h" +#include "arch/ArchHooks/ArchHooks.h" const int MAX_LAYERS = 1000; @@ -38,9 +39,7 @@ BGAnimation::~BGAnimation() void BGAnimation::Unload() { - for( unsigned i=0; iLoadFromStaticGraphic( sPath ); - m_Layers.push_back( pLayer ); + AddChild( pLayer ); } -void AddLayersFromAniDir( CString sAniDir, vector &layersAddTo, bool Generic ) +void AddLayersFromAniDir( CString sAniDir, vector &layersAddTo, bool Generic ) { if( sAniDir.empty() ) return; @@ -111,40 +110,62 @@ void BGAnimation::LoadFromAniDir( CString sAniDir ) if( DoesFileExist(sPathToIni) ) { // This is a new style BGAnimation (using .ini) - AddLayersFromAniDir( sAniDir, m_Layers, m_bGeneric ); // TODO: Check for circular load + AddLayersFromAniDir( sAniDir, m_SubActors, m_bGeneric ); // TODO: Check for circular load IniFile ini(sPathToIni); ini.ReadFile(); if( !ini.GetValue( "BGAnimation", "LengthSeconds", m_fLengthSeconds ) ) { - m_fLengthSeconds = 0; /* XXX: if m_bGeneric, simply constructing the BG layer won't run "On", * so at this point GetMaxTweenTimeLeft is probably 0 */ - for( int i=0; (unsigned)i < m_Layers.size(); i++ ) - m_fLengthSeconds = max(m_fLengthSeconds, m_Layers[i]->GetMaxTweenTimeLeft()); + m_fLengthSeconds = this->GetTweenTimeLeft(); } bool bUseScroller; if( ini.GetValue( "BGAnimation", "UseScroller", bUseScroller ) && bUseScroller ) { + // TODO: Move this into ActorScroller + #define REQUIRED_GET_VALUE( szName, valueOut ) \ - if( !ini.GetValue( "BGAnimation", szName, valueOut ) ) \ - RageException::Throw( "File '%s' is missing the value BGAnimation::%s", sPathToIni.c_str(), szName ); + if( !ini.GetValue( "Scroller", szName, valueOut ) ) \ + HOOKS->MessageBoxOK( ssprintf("File '%s' is missing the value Scroller::%s", sPathToIni.c_str(), szName) ); - float fScrollSecondsPerItem, fSpacingX, fSpacingY, fItemPaddingStart, fItemPaddingEnd; - REQUIRED_GET_VALUE( "ScrollSecondsPerItem", fScrollSecondsPerItem ); - REQUIRED_GET_VALUE( "ScrollSpacingX", fSpacingX ); - REQUIRED_GET_VALUE( "ScrollSpacingY", fSpacingY ); + float fSecondsPerItem = 1; + int iNumItemsToDraw = 7; + RageVector3 vRotationDegrees = RageVector3(0,0,0); + RageVector3 vTranslateTerm0 = RageVector3(0,0,0); + RageVector3 vTranslateTerm1 = RageVector3(0,0,0); + RageVector3 vTranslateTerm2 = RageVector3(0,0,0); + float fItemPaddingStart = 0; + float fItemPaddingEnd = 0; + + REQUIRED_GET_VALUE( "SecondsPerItem", fSecondsPerItem ); + REQUIRED_GET_VALUE( "NumItemsToDraw", iNumItemsToDraw ); + REQUIRED_GET_VALUE( "RotationDegreesX", vRotationDegrees[0] ); + REQUIRED_GET_VALUE( "RotationDegreesY", vRotationDegrees[1] ); + REQUIRED_GET_VALUE( "RotationDegreesZ", vRotationDegrees[2] ); + REQUIRED_GET_VALUE( "TranslateTerm0X", vTranslateTerm0[0] ); + REQUIRED_GET_VALUE( "TranslateTerm0Y", vTranslateTerm0[1] ); + REQUIRED_GET_VALUE( "TranslateTerm0Z", vTranslateTerm0[2] ); + REQUIRED_GET_VALUE( "TranslateTerm1X", vTranslateTerm1[0] ); + REQUIRED_GET_VALUE( "TranslateTerm1Y", vTranslateTerm1[1] ); + REQUIRED_GET_VALUE( "TranslateTerm1Z", vTranslateTerm1[2] ); + REQUIRED_GET_VALUE( "TranslateTerm2X", vTranslateTerm2[0] ); + REQUIRED_GET_VALUE( "TranslateTerm2Y", vTranslateTerm2[1] ); + REQUIRED_GET_VALUE( "TranslateTerm2Z", vTranslateTerm2[2] ); REQUIRED_GET_VALUE( "ItemPaddingStart", fItemPaddingStart ); REQUIRED_GET_VALUE( "ItemPaddingEnd", fItemPaddingEnd ); #undef REQUIRED_GET_VALUE - m_Scroller.Load( fScrollSecondsPerItem, fSpacingX, fSpacingY ); - for( unsigned i=0; iAddChild( &m_Scroller ); + ActorScroller::Load( + fSecondsPerItem, + iNumItemsToDraw, + vRotationDegrees, + vTranslateTerm0, + vTranslateTerm1, + vTranslateTerm2 ); + ActorScroller::SetCurrentAndDestinationItem( int(-fItemPaddingStart) ); + ActorScroller::SetDestinationItem( int(m_SubActors.size()-1+fItemPaddingEnd) ); } CString InitCommand; @@ -181,7 +202,7 @@ void BGAnimation::LoadFromAniDir( CString sAniDir ) continue; // don't directly load files starting with an underscore BGAnimationLayer* pLayer = new BGAnimationLayer( m_bGeneric ); pLayer->LoadFromAniLayerFile( asImagePaths[i] ); - m_Layers.push_back( pLayer ); + AddChild( pLayer ); } } } @@ -192,7 +213,7 @@ void BGAnimation::LoadFromMovie( CString sMoviePath ) BGAnimationLayer* pLayer = new BGAnimationLayer( m_bGeneric ); pLayer->LoadFromMovie( sMoviePath ); - m_Layers.push_back( pLayer ); + AddChild( pLayer ); } void BGAnimation::LoadFromVisualization( CString sVisPath ) @@ -205,82 +226,10 @@ void BGAnimation::LoadFromVisualization( CString sVisPath ) pLayer = new BGAnimationLayer( m_bGeneric ); pLayer->LoadFromStaticGraphic( sSongBGPath ); - m_Layers.push_back( pLayer ); + AddChild( pLayer ); pLayer = new BGAnimationLayer( m_bGeneric ); pLayer->LoadFromVisualization( sVisPath ); - m_Layers.push_back( pLayer ); -} - - -void BGAnimation::Update( float fDeltaTime ) -{ - for( unsigned i=0; iUpdate( fDeltaTime ); - ActorFrame::Update( fDeltaTime ); -} - -void BGAnimation::DrawPrimitives() -{ - for( unsigned i=0; iDraw(); -} - -void BGAnimation::GainingFocus( float fRate, bool bRewindMovie, bool bLoop ) -{ - for( unsigned i=0; iGainingFocus( fRate, bRewindMovie, bLoop ); - - SetDiffuse( RageColor(1,1,1,1) ); -} - -void BGAnimation::LosingFocus() -{ - for( unsigned i=0; iLosingFocus(); -} - -void BGAnimation::SetDiffuse( const RageColor &c ) -{ - for( unsigned i=0; iSetDiffuse(c); - ActorFrame::SetDiffuse( c ); -} - -float BGAnimation::GetTweenTimeLeft() const -{ - float ret = 0; - - for( unsigned i=0; iGetMaxTweenTimeLeft() ); - - return max( ret, Actor::GetTweenTimeLeft() ); -} - -void BGAnimation::FinishTweening() -{ - for( unsigned i=0; iFinishTweening(); - ActorFrame::FinishTweening(); -} - -void BGAnimation::PlayCommand( const CString &cmd ) -{ - for( unsigned i=0; iPlayCommand( cmd ); -} - -void BGAnimation::HandleCommand( const ParsedCommand &command ) -{ - HandleParams; - - if( sParam(0)=="playcommand" ) PlayCommand( sParam(1) ); - else - { - Actor::HandleCommand( command ); - return; - } - - CheckHandledParams; + AddChild( pLayer ); } diff --git a/stepmania/src/BGAnimation.h b/stepmania/src/BGAnimation.h index 7d9b63f5ca..cc40f5d663 100644 --- a/stepmania/src/BGAnimation.h +++ b/stepmania/src/BGAnimation.h @@ -4,7 +4,7 @@ ----------------------------------------------------------------------------- Class: BGAnimation - Desc: Particles that play in the background of ScreenGameplay + Desc: An ActorFrame that loads itself Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. Ben Nordstrom @@ -12,14 +12,9 @@ ----------------------------------------------------------------------------- */ -#include "ActorFrame.h" #include "ActorScroller.h" - -class BGAnimationLayer; - - -class BGAnimation : public ActorFrame +class BGAnimation : public ActorScroller { public: BGAnimation( bool Generic=false ); @@ -32,29 +27,11 @@ public: void LoadFromMovie( CString sMoviePath ); void LoadFromVisualization( CString sMoviePath ); - virtual void Update( float fDeltaTime ); - virtual void DrawPrimitives(); - - virtual void SetDiffuse( const RageColor &c ); - - void GainingFocus( float fRate, bool bRewindMovie, bool bLoop ); - void LosingFocus(); - float GetLengthSeconds() const { return m_fLengthSeconds; } - virtual void HandleCommand( const ParsedCommand &command ); - void PlayOffCommand() { PlayCommand("Off"); } - void PlayCommand( const CString &cmd ); - - float GetTweenTimeLeft() const; - void FinishTweening(); - protected: - vector m_Layers; float m_fLengthSeconds; bool m_bGeneric; - - ActorScroller m_Scroller; }; diff --git a/stepmania/src/BGAnimationLayer.cpp b/stepmania/src/BGAnimationLayer.cpp index d252b96c4e..e4f0c1168a 100644 --- a/stepmania/src/BGAnimationLayer.cpp +++ b/stepmania/src/BGAnimationLayer.cpp @@ -651,15 +651,6 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) PlayCommand( "On" ); } -float BGAnimationLayer::GetMaxTweenTimeLeft() const -{ - float ret = 0; - - for( unsigned i=0; iGetTweenTimeLeft()); - - return ret; -} void BGAnimationLayer::FinishTweening() { diff --git a/stepmania/src/Screen.cpp b/stepmania/src/Screen.cpp index febdf2070e..c2b751e5af 100644 --- a/stepmania/src/Screen.cpp +++ b/stepmania/src/Screen.cpp @@ -339,8 +339,15 @@ Screen* Screen::Create( CString sClassName ) CString sName = sClassName; if( parts.size() == 2 ) { - sClassName = parts[1]; sName = parts[0]; + sClassName = parts[1]; + } + // This is the new, preferred method for specifying the screen class. + // Look up the class in the metrics group sName + else + { + if( THEME->HasMetric(sClassName,"Class") ) + sClassName = THEME->GetMetric(sClassName,"Class"); } #define IF_RETURN(X) if(sClassName.CompareNoCase(#X)==0) return new X(sName); diff --git a/stepmania/src/ScreenAttract.cpp b/stepmania/src/ScreenAttract.cpp index 0a14f88e7c..dc0e3b64b3 100644 --- a/stepmania/src/ScreenAttract.cpp +++ b/stepmania/src/ScreenAttract.cpp @@ -30,12 +30,12 @@ #define INITIAL_SCREEN THEME->GetMetric("Common","InitialScreen") -ScreenAttract::ScreenAttract( CString sClassName, bool bResetGameState ) : Screen( sClassName ) +ScreenAttract::ScreenAttract( CString sName, bool bResetGameState ) : Screen( sName ) { - LOG->Trace( "ScreenAttract::ScreenAttract(%s)", sClassName.c_str() ); + LOG->Trace( "ScreenAttract::ScreenAttract(%s)", m_sName.c_str() ); // increment times through attract count - if( sClassName == INITIAL_SCREEN ) + if( m_sName == INITIAL_SCREEN ) GAMESTATE->m_iNumTimesThroughAttract++; if( bResetGameState ) @@ -46,11 +46,11 @@ ScreenAttract::ScreenAttract( CString sClassName, bool bResetGameState ) : Scree m_Background.LoadFromAniDir( THEME->GetPathToB(m_sName+" background") ); this->AddChild( &m_Background ); - m_In.Load( THEME->GetPathToB("ScreenAttract in") ); + m_In.Load( THEME->GetPathToB(m_sName+" in") ); m_In.StartTransitioning(); this->AddChild( &m_In ); - m_Out.Load( THEME->GetPathToB("ScreenAttract out") ); + m_Out.Load( THEME->GetPathToB(m_sName+" out") ); this->AddChild( &m_Out ); SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo(m_sName) ); diff --git a/stepmania/src/ScreenCredits.cpp b/stepmania/src/ScreenCredits.cpp index 9223464320..dc869b79a5 100644 --- a/stepmania/src/ScreenCredits.cpp +++ b/stepmania/src/ScreenCredits.cpp @@ -172,10 +172,12 @@ ScreenCredits::ScreenCredits( CString sName ) : ScreenAttract( sName ) SONGMAN->GetSongs( arraySongs ); SortSongPointerArrayByTitle( arraySongs ); - m_ScrollerBackgrounds.Load( BACKGROUNDS_SCROLL_SECONDS_PER_ITEM, BACKGROUNDS_SPACING_X, BACKGROUNDS_SPACING_Y ); - this->AddChild( &m_ScrollerBackgrounds ); - m_ScrollerFrames.Load( BACKGROUNDS_SCROLL_SECONDS_PER_ITEM, BACKGROUNDS_SPACING_X, BACKGROUNDS_SPACING_Y ); - this->AddChild( &m_ScrollerFrames ); + // FIXME: Redo this screen with a BGA +// m_ScrollerBackgrounds.Load( +// BACKGROUNDS_SCROLL_SECONDS_PER_ITEM, BACKGROUNDS_SPACING_X, BACKGROUNDS_SPACING_Y ); +// this->AddChild( &m_ScrollerBackgrounds ); +// m_ScrollerFrames.Load( BACKGROUNDS_SCROLL_SECONDS_PER_ITEM, BACKGROUNDS_SPACING_X, BACKGROUNDS_SPACING_Y ); +// this->AddChild( &m_ScrollerFrames ); { for( int i=0; iAddChild( &m_ScrollerTexts ); { diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 72ce195e88..b553d17f15 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -1566,9 +1566,23 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ { PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay; UpdateAutoPlayText(); + bool bIsHoldingShift = + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, SDLK_RSHIFT)) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, SDLK_LSHIFT)); for( int p=0; pIsHumanPlayer(p) ) - GAMESTATE->m_PlayerController[p] = PREFSMAN->m_bAutoPlay?PC_AUTOPLAY:PC_HUMAN; + { + if( bIsHoldingShift ) + { + GAMESTATE->m_PlayerController[p] = PREFSMAN->m_bAutoPlay ? PC_CPU : PC_HUMAN; + } + else + { + GAMESTATE->m_PlayerController[p] = PREFSMAN->m_bAutoPlay ? PC_AUTOPLAY : PC_HUMAN; + } + } + } } break; case SDLK_F9: diff --git a/stepmania/src/ScreenSelectMaster.cpp b/stepmania/src/ScreenSelectMaster.cpp index 2b7c35f461..fb60e21d51 100644 --- a/stepmania/src/ScreenSelectMaster.cpp +++ b/stepmania/src/ScreenSelectMaster.cpp @@ -88,7 +88,13 @@ ScreenSelectMaster::ScreenSelectMaster( CString sClassName ) : ScreenSelect( sCl { if( SHARED_PREVIEW_AND_CURSOR ) { - m_Scroller[0].Load( SCROLLER_SECONDS_PER_ITEM, SCROLLER_SPACING_X, SCROLLER_SPACING_Y ); + m_Scroller[0].Load( + SCROLLER_SECONDS_PER_ITEM, + 7, + RageVector3( 0, 0, 0 ), + RageVector3( 0, 0, 0 ), + RageVector3( SCROLLER_SPACING_X, SCROLLER_SPACING_Y, 0 ), + RageVector3( 0, 0, 0 ) ); m_Scroller[0].SetName( "Scroller" ); this->AddChild( &m_Scroller[0] ); @@ -109,7 +115,13 @@ ScreenSelectMaster::ScreenSelectMaster( CString sClassName ) : ScreenSelect( sCl if( !GAMESTATE->IsPlayerEnabled(p) ) continue; // skip - m_Scroller[p].Load( SCROLLER_SECONDS_PER_ITEM, SCROLLER_SPACING_X, SCROLLER_SPACING_Y ); + m_Scroller[p].Load( + SCROLLER_SECONDS_PER_ITEM, + 7, + RageVector3( 0, 0, 0 ), + RageVector3( 0, 0, 0 ), + RageVector3( SCROLLER_SPACING_X, SCROLLER_SPACING_Y, 0 ), + RageVector3( 0, 0, 0 ) ); m_Scroller[p].SetName( ssprintf("ScrollerP%d",p+1) ); this->AddChild( &m_Scroller[p] ); @@ -228,7 +240,7 @@ ScreenSelectMaster::ScreenSelectMaster( CString sClassName ) : ScreenSelect( sCl this->UpdateSelectableChoices(); - m_fLockInputSecs = TweenOnScreen(); + m_fLockInputSecs = this->GetTweenTimeLeft(); } void ScreenSelectMaster::Update( float fDelta ) @@ -245,14 +257,12 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM ) { case SM_PlayPostSwitchPage: { - float fSecs = 0; - if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) { m_sprCursor[i][p].SetXY( GetCursorX((PlayerNumber)p,i), GetCursorY((PlayerNumber)p,i) ); - fSecs = max( fSecs, COMMAND( m_sprCursor[i][p], "PostSwitchPage" ) ); + COMMAND( m_sprCursor[i][p], "PostSwitchPage" ); } } if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) - fSecs = max( fSecs, COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PostSwitchPage" ) ); + COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PostSwitchPage" ); } m_fLockInputSecs = POST_SWITCH_PAGE_SECONDS; } break; case SM_BeginFadingOut: - float fSecs = TweenOffScreen(); - /* This can be used to allow overlap between the main tween-off and the MenuElements - * tweenoff. */ - fSecs += EXTRA_SLEEP_AFTER_TWEEN_OFF_SECONDS; - fSecs = max( fSecs, 0 ); - SCREENMAN->PostMessageToTopScreen( SM_AllDoneChoosing, fSecs ); // nofify parent that we're finished - m_Menu.StopTimer(); + { + TweenOffScreen(); + float fSecs = GetTweenTimeLeft(); + /* This can be used to allow overlap between the main tween-off and the MenuElements + * tweenoff. */ + fSecs += EXTRA_SLEEP_AFTER_TWEEN_OFF_SECONDS; + fSecs = max( fSecs, 0 ); + SCREENMAN->PostMessageToTopScreen( SM_AllDoneChoosing, fSecs ); // nofify parent that we're finished + m_Menu.StopTimer(); + } break; } } @@ -375,44 +388,42 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice ) if( GAMESTATE->IsHumanPlayer(p) && m_bChosen[p] ) return false; - float fSecs = 0; - if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsHumanPlayer(p) ) - fSecs = max( fSecs, COMMAND( m_sprCursor[i][p], "PreSwitchPage" ) ); + COMMAND( m_sprCursor[i][p], "PreSwitchPage" ); } const CString sIconAndExplanationCommand = ssprintf( "SwitchToPage%d", newPage+1 ); for( unsigned c=0; cIsPlayerEnabled(p) ) - fSecs = max( fSecs, COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PreSwitchPage" ) ); + COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PreSwitchPage" ); } for( int page=0; pageIsHumanPlayer(p) ) { ASSERT( !m_bChosen[p] ); - fSecs = max( fSecs, DoMenuStart( (PlayerNumber)p ) ); + DoMenuStart( (PlayerNumber)p ); } - } else { - fSecs = max( fSecs, DoMenuStart(pn) ); + } + else + { + DoMenuStart(pn); // check to see if everyone has chosen for( int p=0; pIsHumanPlayer((PlayerNumber)p) ) @@ -577,7 +587,7 @@ void ScreenSelectMaster::MenuStart( PlayerNumber pn ) } if( bAllDone ) - this->PostScreenMessage( SM_BeginFadingOut, fSecs );// tell our owner it's time to move on + this->PostScreenMessage( SM_BeginFadingOut, GetTweenTimeLeft() );// tell our owner it's time to move on } /* @@ -592,17 +602,15 @@ void ScreenSelectMaster::MenuStart( PlayerNumber pn ) * This means that the focus command should be position neutral; eg. only use "addx", * not "x". */ -float ScreenSelectMaster::TweenOnScreen() +void ScreenSelectMaster::TweenOnScreen() { - float fSecs = 0; - for( unsigned c=0; cFinishTweening(); - fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_sprIcon[i][c] ) ); + SET_XY_AND_ON_COMMAND( m_sprIcon[i][c] ); } if( SHARED_PREVIEW_AND_CURSOR ) @@ -612,7 +620,7 @@ float ScreenSelectMaster::TweenOnScreen() { COMMAND( m_sprPreview[i][c][p], (int(c) == m_iChoice[p])? "GainFocus":"LoseFocus" ); m_sprPreview[i][c][p]->FinishTweening(); - fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_sprPreview[i][c][p] ) ); + SET_XY_AND_ON_COMMAND( m_sprPreview[i][c][p] ); } } else @@ -623,7 +631,7 @@ float ScreenSelectMaster::TweenOnScreen() { COMMAND( m_sprPreview[i][c][p], int(c) == m_iChoice[p]? "GainFocus":"LoseFocus" ); m_sprPreview[i][c][p]->FinishTweening(); - fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_sprPreview[i][c][p] ) ); + SET_XY_AND_ON_COMMAND( m_sprPreview[i][c][p] ); } } } @@ -634,7 +642,7 @@ float ScreenSelectMaster::TweenOnScreen() for( int i=0; iIsPlayerEnabled(p) ) { m_sprCursor[i][p].SetXY( GetCursorX((PlayerNumber)p,i), GetCursorY((PlayerNumber)p,i) ); - fSecs = max( fSecs, ON_COMMAND( m_sprCursor[i][p] ) ); + ON_COMMAND( m_sprCursor[i][p] ); } } @@ -653,44 +661,40 @@ float ScreenSelectMaster::TweenOnScreen() if( SHARED_PREVIEW_AND_CURSOR ) { m_Scroller[0].SetCurrentAndDestinationItem( m_iChoice[0] ); - fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_Scroller[0] ) ); + SET_XY_AND_ON_COMMAND( m_Scroller[0] ); for( unsigned c=0; cIsPlayerEnabled(p) ) { m_Scroller[p].SetCurrentAndDestinationItem( m_iChoice[p] ); - fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_Scroller[p] ) ); + SET_XY_AND_ON_COMMAND( m_Scroller[p] ); for( unsigned c=0; cSortByZ(); - - return fSecs; } -float ScreenSelectMaster::TweenOffScreen() +void ScreenSelectMaster::TweenOffScreen() { - float fSecs = 0; - if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) - fSecs = max( fSecs, OFF_COMMAND( m_sprCursor[i][p] ) ); + OFF_COMMAND( m_sprCursor[i][p] ); } for( unsigned c=0; cIsPlayerEnabled(p) ) { - fSecs = max( fSecs, OFF_COMMAND( m_sprPreview[i][c][p] ) ); - fSecs = max( fSecs, COMMAND( m_sprPreview[i][c][0], SelectedByEitherPlayer? "OffFocused":"OffUnfocused" ) ); + OFF_COMMAND( m_sprPreview[i][c][p] ); + COMMAND( m_sprPreview[i][c][0], SelectedByEitherPlayer? "OffFocused":"OffUnfocused" ); } } } @@ -739,16 +743,14 @@ float ScreenSelectMaster::TweenOffScreen() if( SHOW_SCROLLER ) { if( SHARED_PREVIEW_AND_CURSOR ) - fSecs = max( fSecs, OFF_COMMAND( m_Scroller[0] ) ); + OFF_COMMAND( m_Scroller[0] ); else for( int p=0; pMessageBoxAbortRetryIgnore(message) ) + { + FlushDirCache(); + ReloadMetrics(); goto try_element_again; + } RageException::Throw( "%s", message.c_str() ); } @@ -353,12 +359,11 @@ CString ThemeManager::GetPathTo( ElementCategory category, CString sClassName, C return i->second; } - // TODO: Use HOOKS->MessageBox() try_element_again: - CString sBaseClass; - sBaseClass = ""; - m_pIniMetrics->GetValue(sClassName,"BaseClass",sBaseClass); + CString sFallback; + sFallback = ""; + m_pIniMetrics->GetValue(sClassName,"Fallback",sFallback); // search the requested current theme and requested class CString ret = GetPathToRaw( m_sCurThemeName, category, sClassName, sElement); @@ -368,10 +373,10 @@ try_element_again: return ret; } - // search the requested current theme and base class - if( !sBaseClass.empty() ) + // search the requested current theme and fallback class + if( !sFallback.empty() ) { - CString ret = GetPathToRaw( m_sCurThemeName, category, sBaseClass, sElement); + CString ret = GetPathToRaw( m_sCurThemeName, category, sFallback, sElement); if( !ret.empty() ) // we found something { Cache[sFileName] = ret; @@ -387,10 +392,10 @@ try_element_again: return ret; } - // search the base theme and base class - if( !sBaseClass.empty() ) + // search the base theme and fallback class + if( !sFallback.empty() ) { - ret = GetPathToRaw( BASE_THEME_NAME, category, sBaseClass, sElement); + ret = GetPathToRaw( BASE_THEME_NAME, category, sFallback, sElement); if( !ret.empty() ) // we found something { Cache[sFileName] = ret; @@ -408,6 +413,8 @@ try_element_again: /* We can't fall back on _missing in Other: the file types are unknown. */ CString sMessage = "The theme element '" + sCategory + "/" + sFileName +"' is missing."; + if( !sFallback.empty() ) + sMessage += " And it's fallback, '" + ClassAndElementToFileName(sFallback,sElement) + "' isn't present either."; ArchHooks::MessageBoxResult res; if( category != Other ) res = HOOKS->MessageBoxAbortRetryIgnore(sMessage, "MissingThemeElement"); @@ -417,7 +424,7 @@ try_element_again: { case ArchHooks::retry: FlushDirCache(); - g_ThemePathCache[category].clear(); + ReloadMetrics(); goto try_element_again; case ArchHooks::ignore: LOG->Warn( diff --git a/stepmania/src/arch/MovieTexture/MovieTexture_Null.cpp b/stepmania/src/arch/MovieTexture/MovieTexture_Null.cpp index f20f673286..51c2a1dd21 100644 --- a/stepmania/src/arch/MovieTexture/MovieTexture_Null.cpp +++ b/stepmania/src/arch/MovieTexture/MovieTexture_Null.cpp @@ -61,7 +61,9 @@ MovieTexture_Null::MovieTexture_Null(RageTextureID ID) : RageMovieTexture(ID) { const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); SDL_Surface *img = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, size, size, pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); + texHandle = DISPLAY->CreateTexture(pixfmt, img, false); + //DISPLAY->UpdateTexture(texHandle, img, 0, 0, size, size); SDL_FreeSurface(img); }