From 09af8c086232936a35330de6141cb822fab408fb Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 17 Nov 2003 06:08:30 +0000 Subject: [PATCH] add PaneDisplay --- stepmania/src/PaneDisplay.cpp | 349 +++++++++++++++++++++++++++++++++ stepmania/src/PaneDisplay.h | 92 +++++++++ stepmania/src/StepMania.dsp | 57 ++++-- stepmania/src/StepMania.vcproj | 6 + 4 files changed, 485 insertions(+), 19 deletions(-) create mode 100644 stepmania/src/PaneDisplay.cpp create mode 100644 stepmania/src/PaneDisplay.h diff --git a/stepmania/src/PaneDisplay.cpp b/stepmania/src/PaneDisplay.cpp new file mode 100644 index 0000000000..c3398af0f0 --- /dev/null +++ b/stepmania/src/PaneDisplay.cpp @@ -0,0 +1,349 @@ +#include "global.h" +#include "PaneDisplay.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "song.h" +#include "RageLog.h" +#include "ProfileManager.h" +#include "SongManager.h" +#include "Course.h" +#include "StyleDef.h" + +#define SHIFT_X(p) THEME->GetMetricF(m_sName, ssprintf("ShiftP%iX", p+1)) +#define SHIFT_Y(p) THEME->GetMetricF(m_sName, ssprintf("ShiftP%iY", p+1)) + +enum { NEED_NOTES=1, NEED_COURSE=2, NEED_PROFILE=4 }; +struct Content_t +{ + const char *name; + PaneTypes type; + int req; +}; + +static const Content_t g_Contents[NUM_PANE_CONTENTS] = +{ + { "DifficultyStream", PANE_SONG_DIFFICULTY, NEED_NOTES }, + { "DifficultyChaos", PANE_SONG_DIFFICULTY, NEED_NOTES }, + { "DifficultyFreeze", PANE_SONG_DIFFICULTY, NEED_NOTES }, + { "DifficultyAir", NUM_PANES, NEED_NOTES }, // hide + { "DifficultyVoltage", NUM_PANES, NEED_NOTES }, + { "DifficultyHands", NUM_PANES, NEED_NOTES }, + { "DifficultyMines", NUM_PANES, NEED_NOTES }, + { "MachineHighScore", PANE_SONG_MACHINE_SCORES, NEED_NOTES }, + { "MachineNumPlays", PANE_SONG_MACHINE_SCORES, NEED_NOTES }, + { "MachineRank", PANE_SONG_MACHINE_SCORES, NEED_NOTES }, + { "ProfileHighScore", PANE_SONG_PROFILE_SCORES, NEED_NOTES|NEED_PROFILE }, + { "ProfileNumPlays", PANE_SONG_PROFILE_SCORES, NEED_NOTES|NEED_PROFILE }, + { "ProfileRank", PANE_SONG_PROFILE_SCORES, NEED_NOTES|NEED_PROFILE }, + { "CourseMachineHighScore", PANE_COURSE_MACHINE_SCORES, NEED_COURSE }, + { "CourseMachineNumPlays", PANE_COURSE_MACHINE_SCORES, NEED_COURSE }, + { "CourseMachineRank", PANE_COURSE_MACHINE_SCORES, NEED_COURSE }, + { "CourseProfileHighScore", PANE_COURSE_PROFILE_SCORES, NEED_COURSE|NEED_PROFILE }, + { "CourseProfileNumPlays", PANE_COURSE_PROFILE_SCORES, NEED_COURSE|NEED_PROFILE }, + { "CourseProfileRank", PANE_COURSE_PROFILE_SCORES, NEED_COURSE|NEED_PROFILE } +}; + +static const PaneModes PaneMode[NUM_PANES] = +{ + PANEMODE_SONG, + PANEMODE_SONG, + PANEMODE_SONG, +// PANEMODE_SONG, + PANEMODE_BATTLE, + PANEMODE_COURSE, + PANEMODE_COURSE +// PANEMODE_COURSE +}; + +static MemoryCard PlayerMemCard( PlayerNumber pn ) +{ + switch( pn ) + { + case PLAYER_1: return MEMORY_CARD_PLAYER_1; + default: ASSERT(0); + case PLAYER_2: return MEMORY_CARD_PLAYER_2; + }; +} + +PaneDisplay::PaneDisplay() +{ + m_CurPane = PANE_INVALID; + m_CurMode = PANEMODE_SONG; +} + +void PaneDisplay::Load( PlayerNumber pn ) +{ + m_PlayerNumber = pn; + m_PreferredPaneForMode[PANEMODE_SONG] = PANE_SONG_DIFFICULTY; + m_PreferredPaneForMode[PANEMODE_BATTLE] = PANE_BATTLE_DIFFICULTY; + m_PreferredPaneForMode[PANEMODE_COURSE] = PANE_COURSE_PROFILE_SCORES; + + m_sprPaneUnder.Load( THEME->GetPathToG( ssprintf("PaneDisplay under p%i", pn+1)) ); + m_sprPaneUnder->SetName( "Under" ); + ON_COMMAND( m_sprPaneUnder ); + this->AddChild( m_sprPaneUnder ); + + int p; + for( p = 0; p < NUM_PANE_CONTENTS; ++p ) + { + m_textContents[p].LoadFromFont( THEME->GetPathToF( "PaneDisplay text" ) ); + m_textContents[p].SetName( ssprintf("%sText", g_Contents[p].name) ); + SET_XY_AND_ON_COMMAND( m_textContents[p] ); + m_ContentsFrame.AddChild( &m_textContents[p] ); + + m_Labels[p].Load( THEME->GetPathToG( ssprintf("PaneDisplay %s label", g_Contents[p].name)) ); + m_Labels[p]->SetName( ssprintf("%sLabel", g_Contents[p].name) ); + SET_XY_AND_ON_COMMAND( m_Labels[p] ); + m_ContentsFrame.AddChild( m_Labels[p] ); + } + + m_ContentsFrame.SetXY( SHIFT_X(m_PlayerNumber), SHIFT_Y(m_PlayerNumber) ); + this->AddChild( &m_ContentsFrame ); + + m_sprPaneOver.Load( THEME->GetPathToG( ssprintf("PaneDisplay over p%i", pn+1)) ); + m_sprPaneOver->SetName( "Over" ); + ON_COMMAND( m_sprPaneOver ); + this->AddChild( m_sprPaneOver ); + + for( unsigned i = 0; i < NUM_PANE_CONTENTS; ++i ) + { + COMMAND( m_textContents[i], "LoseFocus" ); + COMMAND( m_Labels[i], "LoseFocus" ); + m_textContents[i].FinishTweening(); + m_Labels[i]->FinishTweening(); + } + + m_CurMode = GetMode(); + SetFocus( GetNext( m_PreferredPaneForMode[m_CurMode], 0 ) ); +} + +void PaneDisplay::Update( float fDeltaTime ) +{ + ActorFrame::Update( fDeltaTime ); +} + +template +int FindIndex( const T &array, const Song *s ) +{ + T::const_iterator it = find( array.begin(), array.end(), s ); + if( it == array.end() ) + return -1; + return it - array.begin(); +} + +void PaneDisplay::SetContent( PaneContents c ) +{ + m_textContents[c].SetText( "" ); + + if( (g_Contents[c].req&NEED_NOTES) && !GAMESTATE->m_pCurNotes[m_PlayerNumber] ) + return; + if( (g_Contents[c].req&NEED_COURSE) && !GAMESTATE->m_pCurCourse ) + return; + if( (g_Contents[c].req&NEED_PROFILE) && !PROFILEMAN->IsUsingProfile( m_PlayerNumber ) ) + return; + + const float *fRadarValues = NULL; + if( GAMESTATE->m_pCurNotes[m_PlayerNumber] ) + fRadarValues = GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetRadarValues(); + + float val = 0; + CString str; + switch( c ) + { + case SONG_DIFFICULTY_RADAR_STREAM: val = fRadarValues[RADAR_STREAM]; break; + case SONG_DIFFICULTY_RADAR_VOLTAGE: val = fRadarValues[RADAR_VOLTAGE]; break; + case SONG_DIFFICULTY_RADAR_AIR: val = fRadarValues[RADAR_AIR]; break; + case SONG_DIFFICULTY_RADAR_FREEZE: val = fRadarValues[RADAR_FREEZE]; break; + case SONG_DIFFICULTY_RADAR_CHAOS: val = fRadarValues[RADAR_CHAOS]; break; + + case SONG_PROFILE_HIGH_SCORE: + val = 100.0f * GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetTopScore( PlayerMemCard(m_PlayerNumber) ).fPercentDP; + break; + case SONG_PROFILE_NUM_PLAYS: + val = (float) GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetNumTimesPlayed( PlayerMemCard(m_PlayerNumber) ); + break; + + + case SONG_PROFILE_RANK: + val = (float) FindIndex( SONGMAN->GetBestSongs( PlayerMemCard(m_PlayerNumber) ), GAMESTATE->m_pCurSong ); + val += 1; + break; + + case COURSE_MACHINE_HIGH_SCORE: + // XXX add percentdp + val = 100.0f; // * GAMESTATE->m_pCurCourse->GetTopScore( GAMESTATE->GetCurrentStyleDef()->m_StepsType, MEMORY_CARD_MACHINE ).HighScore; + break; + + case COURSE_MACHINE_NUM_PLAYS: + val = (float) GAMESTATE->m_pCurCourse->GetNumTimesPlayed( MEMORY_CARD_MACHINE ); + break; + + case COURSE_MACHINE_RANK: + { + const vector best = SONGMAN->GetBestCourses( MEMORY_CARD_MACHINE ); + val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurCourse ); + val += 1; + } + break; + + case COURSE_PROFILE_HIGH_SCORE: + // XXX add percentdp + val = 100.0f; // * GAMESTATE->m_pCurCourse->GetTopScore( GAMESTATE->GetCurrentStyleDef()->m_StepsType, PlayerMemCard(m_PlayerNumber) ).HighScore; + break; + case COURSE_PROFILE_NUM_PLAYS: + val = (float) GAMESTATE->m_pCurCourse->GetNumTimesPlayed( PlayerMemCard(m_PlayerNumber) ); + break; + + case COURSE_PROFILE_RANK: + const vector best = SONGMAN->GetBestCourses( PlayerMemCard(m_PlayerNumber) ); + val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurCourse ); + val += 1; + break; + }; + + /* Scale, round, clamp, etc. for floats: */ + switch( c ) + { + case SONG_DIFFICULTY_RADAR_STREAM: + case SONG_DIFFICULTY_RADAR_VOLTAGE: + case SONG_DIFFICULTY_RADAR_AIR: + case SONG_DIFFICULTY_RADAR_FREEZE: + case SONG_DIFFICULTY_RADAR_CHAOS: + val = roundf( SCALE( val, 0, 1, 0, 10 ) ); + val = clamp( val, 0, 10 ); + str = ssprintf( "%.0f", val ); + break; + } + + switch( c ) + { + case SONG_MACHINE_HIGH_SCORE: + case COURSE_MACHINE_HIGH_SCORE: + case SONG_PROFILE_HIGH_SCORE: + case COURSE_PROFILE_HIGH_SCORE: + str = ssprintf( "%.2f%%", val ); + break; + case SONG_MACHINE_NUM_PLAYS: + case COURSE_MACHINE_NUM_PLAYS: + case SONG_PROFILE_NUM_PLAYS: + case COURSE_PROFILE_NUM_PLAYS: + case SONG_MACHINE_RANK: + case COURSE_MACHINE_RANK: + case SONG_PROFILE_RANK: + case COURSE_PROFILE_RANK: + str = ssprintf( "%.0f", val ); + } + + m_textContents[c].SetText( str ); + + +//#define ITEM_COLOR THEME->GetMetricC(m_sName,"FOVCenterY") +// "0-3.5=1,0,0,1: 3.5-6.5=0,1,0,1: 6.5-1000=0,0,1,1" + RageColor color(1,0,1,1); + m_textContents[c].SetDiffuse( color ); +} + +void PaneDisplay::SetFromGameState() +{ + m_CurMode = GetMode(); + if( PaneMode[m_CurPane] != m_CurMode ) + SetFocus( GetNext( m_PreferredPaneForMode[m_CurMode], 0 ) ); + + /* Don't update text that doesn't apply to the current mode. It's still tweening off. */ + for( unsigned i = 0; i < NUM_PANE_CONTENTS; ++i ) + { + if( g_Contents[i].type != m_CurPane ) + continue; + SetContent( (PaneContents) i ); + } +} + +PaneModes PaneDisplay::GetMode() const +{ + switch( GAMESTATE->m_SongSortOrder ) + { + case SORT_ALL_COURSES: + case SORT_NONSTOP_COURSES: + case SORT_ONI_COURSES: + case SORT_ENDLESS_COURSES: + return PANEMODE_COURSE; + case SORT_MENU: + return m_CurMode; // leave it + default: + return PANEMODE_SONG; + } +} + + +void PaneDisplay::SetFocus( PaneTypes NewPane ) +{ + if( m_CurPane == NewPane ) + return; + + for( unsigned i = 0; i < NUM_PANE_CONTENTS; ++i ) + { + if( g_Contents[i].type == m_CurPane ) + { + COMMAND( m_textContents[i], "LoseFocus" ); + COMMAND( m_Labels[i], "LoseFocus" ); + } + else if( g_Contents[i].type == NewPane ) + { + COMMAND( m_textContents[i], "GainFocus" ); + COMMAND( m_Labels[i], "GainFocus" ); + } + } + + m_CurPane = NewPane; + m_PreferredPaneForMode[m_CurMode] = NewPane; + + SetFromGameState(); +} + +bool PaneDisplay::PaneIsValid( PaneTypes p ) const +{ + if( PaneMode[p] != m_CurMode ) + return false; + + switch( p ) + { + case PANE_SONG_PROFILE_SCORES: + case PANE_COURSE_PROFILE_SCORES: + if( !PROFILEMAN->IsUsingProfile( m_PlayerNumber ) ) + return false; + } + + return true; +} + +PaneTypes PaneDisplay::GetNext( PaneTypes current, int dir ) const +{ + if( dir == 0 ) + { + /* Only move the selection if the current selection is invalid. */ + if( PaneIsValid( current ) ) + return current; + + dir = 1; + } + + PaneTypes ret = current; + while( 1 ) + { + ret = (PaneTypes) (ret + dir); + wrap( (int&) ret, NUM_PANES ); + + if( PaneIsValid( ret ) ) + break; + } + + LOG->Trace("pane %i", ret); + + return ret; +} + +void PaneDisplay::Move( int dir ) +{ + const PaneTypes NewPane = GetNext( m_CurPane, dir ); + SetFocus( NewPane ); +} diff --git a/stepmania/src/PaneDisplay.h b/stepmania/src/PaneDisplay.h new file mode 100644 index 0000000000..299b293c5d --- /dev/null +++ b/stepmania/src/PaneDisplay.h @@ -0,0 +1,92 @@ +#ifndef PANE_DISPLAY_H +#define PANE_DISPLAY_H + +#include "ActorFrame.h" +#include "Sprite.h" +#include "PlayerNumber.h" +#include "BitmapText.h" +#include "ActorUtil.h" +#include "GameConstantsAndTypes.h" + +enum PaneTypes +{ + PANE_SONG_DIFFICULTY, + PANE_SONG_PROFILE_SCORES, + PANE_SONG_MACHINE_SCORES, +// PANE_SONG_STATISTICS, + PANE_BATTLE_DIFFICULTY, + PANE_COURSE_MACHINE_SCORES, + PANE_COURSE_PROFILE_SCORES, +// PANE_COURSE_DIFFICULTY, + NUM_PANES, + PANE_INVALID +}; + +enum PaneModes +{ + PANEMODE_SONG, + PANEMODE_BATTLE, + PANEMODE_COURSE, + NUM_PANE_MODES +}; + +/* If the same piece of data is in multiple panes, use separate contents entries, + * so it can be themed differently. */ +enum PaneContents +{ + SONG_DIFFICULTY_RADAR_STREAM, + SONG_DIFFICULTY_RADAR_CHAOS, + SONG_DIFFICULTY_RADAR_FREEZE, + SONG_DIFFICULTY_RADAR_AIR, + SONG_DIFFICULTY_RADAR_VOLTAGE, + SONG_DIFFICULTY_HANDS, + SONG_DIFFICULTY_MINES, + SONG_MACHINE_HIGH_SCORE, + SONG_MACHINE_NUM_PLAYS, + SONG_MACHINE_RANK, + SONG_PROFILE_HIGH_SCORE, + SONG_PROFILE_NUM_PLAYS, + SONG_PROFILE_RANK, + COURSE_MACHINE_HIGH_SCORE, + COURSE_MACHINE_NUM_PLAYS, + COURSE_MACHINE_RANK, + COURSE_PROFILE_HIGH_SCORE, + COURSE_PROFILE_NUM_PLAYS, + COURSE_PROFILE_RANK, + NUM_PANE_CONTENTS +}; + +class PaneDisplay: public ActorFrame +{ +public: + PaneDisplay(); + + void Load( PlayerNumber pn ); + void SetFromGameState(); + void Move( int dir ); + + void Update( float fDeltaTime ); + +private: + bool PaneIsValid( PaneTypes p ) const; + PaneTypes GetNext( PaneTypes current, int dir ) const; + void SetFocus( PaneTypes NewPane ); +// void SetMode(); + PaneModes GetMode() const; + void SetContent( PaneContents c ); + + AutoActor m_sprPaneUnder; + AutoActor m_sprPaneOver; + + BitmapText m_textContents[NUM_PANE_CONTENTS]; + AutoActor m_Labels[NUM_PANE_CONTENTS]; + ActorFrame m_ContentsFrame; + + PaneTypes m_CurPane; + PaneModes m_CurMode; + PlayerNumber m_PlayerNumber; + + PaneTypes m_PreferredPaneForMode[NUM_PANE_MODES]; +}; + +#endif diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 811d60e290..094ac5d579 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -2854,25 +2854,6 @@ SOURCE=.\DifficultyIcon.h # End Source File # Begin Source File -SOURCE=.\DifficultyList.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=.\DifficultyList.h -# End Source File -# Begin Source File - SOURCE=.\FadingBanner.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" @@ -3607,6 +3588,25 @@ SOURCE=.\DifficultyDisplay.h # End Source File # Begin Source File +SOURCE=.\DifficultyList.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=.\DifficultyList.h +# End Source File +# Begin Source File + SOURCE=.\DifficultyMeter.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" @@ -4025,6 +4025,25 @@ SOURCE=.\OptionsCursor.h # End Source File # Begin Source File +SOURCE=.\PaneDisplay.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=.\PaneDisplay.h +# End Source File +# Begin Source File + SOURCE=.\ScrollBar.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 006844498c..0ee6c9d492 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -1263,6 +1263,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +