diff --git a/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/_CourseEntryDisplay bar.png b/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/_CourseEntryDisplay bar.png new file mode 100644 index 0000000000..ffe610268c Binary files /dev/null and b/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/_CourseEntryDisplay bar.png differ diff --git a/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/default.lua b/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/default.lua index d928e4c1aa..3d637068b9 100644 --- a/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/default.lua +++ b/stepmania/Themes/default/BGAnimations/ScreenSelectMusic overlay/default.lua @@ -207,6 +207,8 @@ local children = OffCommand=cmd(bouncebegin,0.5;addx,-SCREEN_WIDTH*0.6); }; Def.CourseContentsList { + VisibleItems = 5; + InitCommand=cmd(x,SCREEN_CENTER_X-160;y,SCREEN_CENTER_Y+96); OnCommand=cmd(zoomy,0;bounceend,0.3;zoom,1); OffCommand=cmd(zoomy,1;bouncebegin,0.3;zoomy,0); @@ -215,6 +217,66 @@ local children = SetCommand=function(self) self:SetFromGameState() end; CurrentTrailP1ChangedMessageCommand=cmd(playcommand,"Set"); CurrentTrailP2ChangedMessageCommand=cmd(playcommand,"Set"); + + Display = Def.ActorFrame { + InitCommand=cmd(setsize,270,44); + + LoadActor("_CourseEntryDisplay bar"); + + Def.TextBanner { + ArtistPrependString="/"; + SetCommand=TextBannerSet; + InitCommand=cmd(LoadFromString,"", "", "", "", "", ""); + Title = LoadFont("TextBannerCourseEntry","text") .. { + Name="Title"; + OnCommand=cmd(shadowlength,0); + }; + Subtitle = LoadFont("TextBannerCourseEntry","text") .. { + Name="Subtitle"; + OnCommand=cmd(shadowlength,0); + }; + Artist = LoadFont("TextBannerCourseEntry","text") .. { + Name="Artist"; + OnCommand=cmd(shadowlength,0); + }; + SetSongCommand=function(self, params) + if params.Song then + self:LoadFromSong( params.Song ); + self:diffuse( SONGMAN:GetSongColor(params.Song) ); + else + self:LoadFromString( "??????????", "??????????", "", "", "", "" ); + self:diffuse( color("#FFFFFF") ); + end + end; + }; + + LoadFont("CourseEntryDisplay","number") .. { + OnCommand=cmd(x,-118;shadowlength,0); + SetSongCommand=function(self, params) self:settext(string.format("%i", params.Number)); end; + }; + + LoadFont("Common","normal") .. { + OnCommand=cmd(x,SCREEN_CENTER_X-200;y,-8;zoom,0.7;shadowlength,0); + DifficultyChangedCommand=function(self, params) + if params.PlayerNumber ~= GAMESTATE:GetMasterPlayerNumber() then return end + self:settext( params.Meter ); + self:diffuse( DifficultyColor(params.Difficulty) ); + end; + }; + + LoadFont("Common","normal") .. { + OnCommand=cmd(x,SCREEN_CENTER_X-192;y,SCREEN_CENTER_Y-230;horizalign,right;zoom,0.5;shadowlength,0); + SetSongCommand=function(self, params) self:settext(params.Modifiers); end; + }; + + LoadFont("CourseEntryDisplay","difficulty") .. { + OnCommand=cmd(x,SCREEN_CENTER_X-222;y,-8;shadowlength,0;settext,"1"); + DifficultyChangedCommand=function(self, params) + if params.PlayerNumber ~= GAMESTATE:GetMasterPlayerNumber() then return end + self:diffuse( DifficultyColor(params.Difficulty) ); + end; + }; + }; }; Autogen(PLAYER_1) .. { diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 79c6e2c274..e8005eb8ee 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -3183,30 +3183,6 @@ TitleX=-90 SubtitleX=-90 ArtistX=-90 -[CourseEntryDisplay] -BarX=0 -BarY=0 -BarOnCommand= -TextBannerType="TextBannerCourseEntry" -TextBannerX=0 -TextBannerY=0 -TextBannerOnCommand=shadowlength,0 -NumberX=-118 -NumberY=0 -NumberOnCommand=shadowlength,0 -FootX=SCREEN_CENTER_X-222 -FootY=-8 -FootOnCommand=shadowlength,0 -FootDifficultyChangedCommand=diffuse,DifficultyColor(self.Difficulty) -SeparateCourseMeters=false -DifficultyX=SCREEN_CENTER_X-200 -DifficultyY=-8 -DifficultyOnCommand=zoom,0.7;shadowlength,0 -DifficultyDifficultyChangedCommand=diffuse,DifficultyColor(self.Difficulty) -ModifiersX=SCREEN_CENTER_X-192 -ModifiersY=SCREEN_CENTER_Y-230 -ModifiersOnCommand=horizalign,right;zoom,0.5;shadowlength,0 - [ArtistDisplay] TipShowTime=1 TipOnCommand= diff --git a/stepmania/src/CourseContentsList.cpp b/stepmania/src/CourseContentsList.cpp index 013046f61f..e078df8f73 100644 --- a/stepmania/src/CourseContentsList.cpp +++ b/stepmania/src/CourseContentsList.cpp @@ -1,52 +1,47 @@ #include "global.h" #include "CourseContentsList.h" -#include "RageUtil.h" #include "GameConstantsAndTypes.h" #include "RageLog.h" #include "Course.h" -#include "SongManager.h" -#include "ThemeManager.h" -#include "Steps.h" +#include "Trail.h" #include "GameState.h" -#include "Style.h" -#include "RageTexture.h" -#include "CourseEntryDisplay.h" +#include "XmlFile.h" #include "ActorUtil.h" - -const int MAX_VISIBLE_ITEMS = 5; -const int MAX_ITEMS = MAX_VISIBLE_ITEMS+2; +#include "RageUtil.h" +#include "Steps.h" REGISTER_ACTOR_CLASS( CourseContentsList ) CourseContentsList::CourseContentsList() { - for( int i=0; iSetNumItemsToDraw( (float)MAX_VISIBLE_ITEMS ); + m_iVisibleItems = 5; } CourseContentsList::~CourseContentsList() { - FOREACH( CourseEntryDisplay*, m_vpDisplay, d ) + FOREACH( Actor *, m_vpDisplay, d ) delete *d; m_vpDisplay.clear(); } -void CourseContentsList::Load() -{ - FOREACH( CourseEntryDisplay*, m_vpDisplay, d ) - { - (*d)->SetName( "CourseEntryDisplay" ); - (*d)->Load(); - (*d)->SetUseZBuffer( true ); - } -} - void CourseContentsList::LoadFromNode( const XNode* pNode ) { + pNode->GetAttrValue( "VisibleItems", m_iVisibleItems ); + ActorScroller::LoadFromNode( pNode ); - Load(); + const XNode *pDisplayNode = pNode->GetChild( "Display" ); + if( pDisplayNode == NULL ) + RageException::Throw( "%s: CourseContentsList: missing the Display child", ActorUtil::GetWhere(pNode).c_str() ); + + for( int i=0; iSetUseZBuffer( true ); + m_vpDisplay.push_back( pDisplay ); + } + + this->SetNumItemsToDraw( (float)m_iVisibleItems ); } void CourseContentsList::SetFromGameState() @@ -57,18 +52,16 @@ void CourseContentsList::SetFromGameState() // the same number of TrailEntries? // They have to have the same number, and of the same songs, or gameplay // isn't going to line up. - Trail* pMasterTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber]; + const Trail *pMasterTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber]; if( pMasterTrail == NULL ) return; unsigned uNumEntriesToShow = min( pMasterTrail->m_vEntries.size(), m_vpDisplay.size() ); for( int i=0; i<(int)uNumEntriesToShow; i++ ) { - CourseEntryDisplay &d = *m_vpDisplay[i]; - - this->AddChild( &d ); - - d.SetFromGameState( i ); + Actor *pDisplay = m_vpDisplay[i]; + SetItemFromGameState( pDisplay, i ); + this->AddChild( pDisplay ); } bool bLoop = pMasterTrail->m_vEntries.size() > uNumEntriesToShow; @@ -81,11 +74,99 @@ void CourseContentsList::SetFromGameState() this->SetSecondsPauseBetweenItems( 0.7f ); this->ScrollThroughAllItems(); - this->SetCurrentAndDestinationItem( (MAX_VISIBLE_ITEMS-1)/2 ); + this->SetCurrentAndDestinationItem( (m_iVisibleItems-1)/2 ); if( bLoop ) { SetPauseCountdownSeconds( 1.5f ); - this->SetDestinationItem( MAX_ITEMS+1 ); // loop forever + this->SetDestinationItem( m_vpDisplay.size()+1 ); // loop forever + } +} + +void CourseContentsList::SetItemFromGameState( Actor *pActor, int iCourseEntryIndex ) +{ + const Course *pCourse = GAMESTATE->m_pCurCourse; + + const TrailEntry *tes[NUM_PLAYERS]; + const CourseEntry *ces[NUM_PLAYERS]; + FOREACH_PlayerNumber( p ) + { + const Trail *pTrail = GAMESTATE->m_pCurTrail[p]; + if( pTrail && iCourseEntryIndex < (int) pTrail->m_vEntries.size() ) + { + tes[p] = &pTrail->m_vEntries[iCourseEntryIndex]; + ces[p] = &pCourse->m_vEntries[iCourseEntryIndex]; + } + else + { + tes[p] = NULL; + ces[p] = NULL; + } + } + + + const TrailEntry *te = tes[GAMESTATE->m_MasterPlayerNumber]; + if( te == NULL ) + return; + + FOREACH_HumanPlayer(pn) + { + const TrailEntry *te = tes[pn]; + if( te == NULL ) + continue; + + RString s; + Difficulty dc; + if( te->bSecret ) + { + const CourseEntry *ce = ces[pn]; + if( ce == NULL ) + continue; + + int iLow = ce->stepsCriteria.m_iLowMeter; + int iHigh = ce->stepsCriteria.m_iHighMeter; + + bool bLowIsSet = iLow != -1; + bool bHighIsSet = iHigh != -1; + + if( !bLowIsSet && !bHighIsSet ) + { + s = "?"; + } + if( !bLowIsSet && bHighIsSet ) + { + s = ssprintf( ">=%d", iHigh ); + } + else if( bLowIsSet && !bHighIsSet ) + { + s = ssprintf( "<=%d", iLow ); + } + else if( bLowIsSet && bHighIsSet ) + { + if( iLow == iHigh ) + s = ssprintf( "%d", iLow ); + else + s = ssprintf( "%d-%d", iLow, iHigh ); + } + + dc = te->dc; + if( dc == Difficulty_Invalid ) + dc = Difficulty_Edit; + } + else + { + s = ssprintf("%d", te->pSteps->GetMeter()); + dc = te->pSteps->GetDifficulty(); + } + + Message msg("SetSong"); + msg.SetParam( "PlayerNumber", pn ); + msg.SetParam( "Difficulty", dc ); + msg.SetParam( "Meter", s ); + msg.SetParam( "Number", iCourseEntryIndex+1 ); + msg.SetParam( "Modifiers", te->Modifiers ); + if( !te->bSecret ) + msg.SetParam( "Song", te->pSong ); + pActor->HandleMessage( msg ); } } diff --git a/stepmania/src/CourseContentsList.h b/stepmania/src/CourseContentsList.h index 3e665f022d..59e6abc4c9 100644 --- a/stepmania/src/CourseContentsList.h +++ b/stepmania/src/CourseContentsList.h @@ -13,7 +13,6 @@ public: ~CourseContentsList(); virtual CourseContentsList *Copy() const; - void Load(); void LoadFromNode( const XNode* pNode ); void SetFromGameState(); @@ -22,7 +21,10 @@ public: void PushSelf( lua_State *L ); protected: - vector m_vpDisplay; + void SetItemFromGameState( Actor *pActor, int iCourseEntryIndex ); + + int m_iVisibleItems; + vector m_vpDisplay; }; #endif