diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index 4854100d01..4fb201ecd3 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -44,7 +44,8 @@ ScreenReloadSongs.cpp ScreenReloadSongs.h ScreenResetToDefaults.cpp ScreenResetT ScreenSelect.cpp ScreenSelect.h ScreenSelectCharacter.cpp ScreenSelectCharacter.h \ ScreenSelectDifficulty.cpp ScreenSelectDifficulty.h ScreenSelectGroup.cpp ScreenSelectGroup.h \ ScreenSelectMaster.cpp ScreenSelectMaster.h ScreenSelectMode.cpp ScreenSelectMode.h \ -ScreenSelectMusic.cpp ScreenSelectMusic.h ScreenSelectStyle.cpp ScreenSelectStyle.h ScreenSetTime.cpp ScreenSetTime.h \ +ScreenSelectMusic.cpp ScreenSelectMusic.h ScreenSelectStyle.cpp ScreenSelectStyle.h \ +ScreenSystemLayer.cpp ScreenSystemLayer.h ScreenSetTime.cpp ScreenSetTime.h \ ScreenSongOptions.cpp ScreenSongOptions.h ScreenStage.cpp ScreenStage.h ScreenStyleSplash.cpp ScreenStyleSplash.h \ ScreenTest.cpp ScreenTest.h ScreenTestFonts.cpp ScreenTestFonts.h ScreenTestInput.cpp ScreenTestInput.h \ ScreenTestLights.cpp ScreenTestLights.h ScreenTestSound.cpp ScreenTestSound.h ScreenTextEntry.cpp ScreenTextEntry.h \ diff --git a/stepmania/src/Screen.h b/stepmania/src/Screen.h index 5cd10e94b2..a63c380f6f 100644 --- a/stepmania/src/Screen.h +++ b/stepmania/src/Screen.h @@ -1,4 +1,4 @@ -/* Screen - Class representing a game state. It also holds Actors. */ +/* Screen - Class that holds a screen-full of Actors. */ #ifndef SCREEN_H #define SCREEN_H diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 31ab5e8c5b..86a9209011 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -19,330 +19,19 @@ #include "global.h" #include "ScreenManager.h" -#include "IniFile.h" -#include "GameConstantsAndTypes.h" #include "PrefsManager.h" #include "RageLog.h" -#include "ActorUtil.h" +#include "RageUtil.h" #include "GameState.h" -#include "RageException.h" -#include "RageTimer.h" #include "GameSoundManager.h" -#include "ThemeManager.h" #include "RageDisplay.h" -#include "Screen.h" #include "SongManager.h" -#include "BitmapText.h" -#include "Quad.h" #include "RageTextureManager.h" -#include "ProfileManager.h" #include "ThemeManager.h" -#include "MemoryCardManager.h" -#include "CodeDetector.h" -#include "StepMania.h" +#include "ScreenSystemLayer.h" ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program - -#define CREDITS_PRESS_START THEME->GetMetric ("ScreenSystemLayer","CreditsPressStart") -#define CREDITS_INSERT_CARD THEME->GetMetric ("ScreenSystemLayer","CreditsInsertCard") -#define CREDITS_CARD_ERROR THEME->GetMetric ("ScreenSystemLayer","CreditsCardError") -#define CREDITS_CARD_TOO_LATE THEME->GetMetric ("ScreenSystemLayer","CreditsCardTooLate") -#define CREDITS_CARD_NO_NAME THEME->GetMetric ("ScreenSystemLayer","CreditsCardNoName") -#define CREDITS_CARD_READY THEME->GetMetric ("ScreenSystemLayer","CreditsCardReady") -#define CREDITS_FREE_PLAY THEME->GetMetric ("ScreenSystemLayer","CreditsFreePlay") -#define CREDITS_CREDITS THEME->GetMetric ("ScreenSystemLayer","CreditsCredits") -#define CREDITS_NOT_PRESENT THEME->GetMetric ("ScreenSystemLayer","CreditsNotPresent") -#define CREDITS_LOAD_FAILED THEME->GetMetric ("ScreenSystemLayer","CreditsLoadFailed") -#define CREDITS_LOADED_FROM_LAST_GOOD_APPEND THEME->GetMetric ("ScreenSystemLayer","CreditsLoadedFromLastGoodAppend") -#define CREDITS_JOIN_ONLY THEME->GetMetricB("ScreenSystemLayer","CreditsJoinOnly") - -const int NUM_SKIPS_TO_SHOW = 5; - -/* This screen is drawn on top of everything else, and receives updates, - * but not input. */ -class ScreenSystemLayer: public Screen -{ - BitmapText m_textStats; - BitmapText m_textMessage; - BitmapText m_textCredits[NUM_PLAYERS]; - BitmapText m_textTime; - BitmapText m_textSkips[NUM_SKIPS_TO_SHOW]; - int m_LastSkip; - Quad m_SkipBackground; - - RageTimer SkipTimer; - void AddTimestampLine( const CString &txt, RageColor color ); - void UpdateTimestampAndSkips(); - -public: - ScreenSystemLayer(); - void SystemMessage( CString sMessage ); - void SystemMessageNoAnimate( CString sMessage ); - void ReloadCreditsText(); - void RefreshCreditsMessages(); - void Update( float fDeltaTime ); -}; - -ScreenSystemLayer::ScreenSystemLayer() : Screen("ScreenSystemLayer") -{ - this->AddChild(&m_textMessage); - this->AddChild(&m_textStats); - this->AddChild(&m_textTime); - FOREACH_PlayerNumber( p ) - this->AddChild(&m_textCredits[p]); - - - /* "Was that a skip?" This displays a message when an update takes - * abnormally long, to quantify skips more precisely, verify them - * when they're subtle, and show the time it happened, so you can pinpoint - * the time in the log. Put a dim quad behind it to make it easier to - * read. */ - m_LastSkip = 0; - const float SKIP_LEFT = 320.0f, SKIP_TOP = 60.0f, - SKIP_WIDTH = 160.0f, SKIP_Y_DIST = 16.0f; - - m_SkipBackground.StretchTo(RectF(SKIP_LEFT-8, SKIP_TOP-8, - SKIP_LEFT+SKIP_WIDTH, SKIP_TOP+SKIP_Y_DIST*NUM_SKIPS_TO_SHOW)); - m_SkipBackground.SetDiffuse( RageColor(0,0,0,0.4f) ); - m_SkipBackground.SetHidden( !PREFSMAN->m_bTimestamping ); - this->AddChild(&m_SkipBackground); - - for( int i=0; iGetPathToF("Common normal") ); - m_textSkips[i].SetXY( SKIP_LEFT, SKIP_TOP + SKIP_Y_DIST*i ); - m_textSkips[i].SetHorizAlign( Actor::align_left ); - m_textSkips[i].SetVertAlign( Actor::align_top ); - m_textSkips[i].SetZoom( 0.5f ); - m_textSkips[i].SetDiffuse( RageColor(1,1,1,0) ); - m_textSkips[i].SetShadowLength( 0 ); - this->AddChild(&m_textSkips[i]); - } - - ReloadCreditsText(); - /* This will be done when we set up the first screen, after GAMESTATE->Reset has - * been called. */ - // RefreshCreditsMessages(); -} - -void ScreenSystemLayer::ReloadCreditsText() -{ - m_textMessage.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer message") ); - m_textMessage.SetName( "Message" ); - SET_XY_AND_ON_COMMAND( m_textMessage ); - - m_textStats.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer stats") ); - m_textStats.SetName( "Stats" ); - SET_XY_AND_ON_COMMAND( m_textStats ); - - m_textTime.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer time") ); - m_textTime.SetName( "Time" ); - m_textTime.SetHidden( !PREFSMAN->m_bTimestamping ); - SET_XY_AND_ON_COMMAND( m_textTime ); - - FOREACH_PlayerNumber( p ) - { - m_textCredits[p].LoadFromFont( THEME->GetPathToF("ScreenManager credits") ); - m_textCredits[p].SetName( ssprintf("CreditsP%d",p+1) ); - SET_XY_AND_ON_COMMAND( &m_textCredits[p] ); - } -} - -void ScreenSystemLayer::SystemMessage( CString sMessage ) -{ - m_textMessage.SetText( sMessage ); - static const ActorCommands cmds = ParseActorCommands("finishtweening;diffusealpha,1;addx,-640;linear,0.5;addx,+640;sleep,5;linear,0.5;diffusealpha,0"); - m_textMessage.Command( cmds ); -} - -void ScreenSystemLayer::SystemMessageNoAnimate( CString sMessage ) -{ - m_textMessage.FinishTweening(); - m_textMessage.SetText( sMessage ); - m_textMessage.SetX( 4 ); - m_textMessage.SetDiffuseAlpha( 1 ); - m_textMessage.BeginTweening( 5 ); - m_textMessage.BeginTweening( 0.5f ); - m_textMessage.SetDiffuse( RageColor(1,1,1,0) ); -} - -void ScreenSystemLayer::RefreshCreditsMessages() -{ - // update joined - FOREACH_PlayerNumber( p ) - { - CString sCredits; - - bool bShowCreditsMessage; - if( GAMESTATE->m_bIsOnSystemMenu ) - bShowCreditsMessage = true; - else if( GAMESTATE->m_bPlayersFinalized ) - bShowCreditsMessage = !GAMESTATE->IsPlayerEnabled( p ); - else - bShowCreditsMessage = !GAMESTATE->m_bSideIsJoined[p]; - - if( !bShowCreditsMessage ) - { - MemoryCardState mcs = MEMCARDMAN->GetCardState( p ); - Profile* pProfile = PROFILEMAN->GetProfile( p ); - switch( mcs ) - { - case MEMORY_CARD_STATE_NO_CARD: - // this is a local machine profile - if( PROFILEMAN->LastLoadWasFromLastGood(p) && pProfile ) - sCredits = pProfile->GetDisplayName() + CREDITS_LOADED_FROM_LAST_GOOD_APPEND; - else if( PROFILEMAN->LastLoadWasTamperedOrCorrupt(p) ) - sCredits = CREDITS_LOAD_FAILED; - // Prefer the name of the profile over the name of the card. - else if( pProfile ) - sCredits = pProfile->GetDisplayName(); - else if( GAMESTATE->PlayersCanJoin() ) - sCredits = CREDITS_INSERT_CARD; - else - sCredits = ""; - break; - case MEMORY_CARD_STATE_WRITE_ERROR: - sCredits = CREDITS_CARD_ERROR; - break; - case MEMORY_CARD_STATE_TOO_LATE: - sCredits = CREDITS_CARD_TOO_LATE; - break; - case MEMORY_CARD_STATE_READY: - if( PROFILEMAN->LastLoadWasFromLastGood(p) && pProfile ) - sCredits = pProfile->GetDisplayName() + CREDITS_LOADED_FROM_LAST_GOOD_APPEND; - else if( PROFILEMAN->LastLoadWasTamperedOrCorrupt(p) ) - sCredits = CREDITS_LOAD_FAILED; - // Prefer the name of the profile over the name of the card. - else if( pProfile ) - sCredits = pProfile->GetDisplayName(); - else if( !MEMCARDMAN->IsNameAvailable(p) ) - sCredits = CREDITS_CARD_READY; - else if( !MEMCARDMAN->GetName(p).empty() ) - sCredits = MEMCARDMAN->GetName(p); - else - sCredits = CREDITS_CARD_NO_NAME; - break; - default: - ASSERT(0); - } - } - else // bShowCreditsMessage - { - switch( PREFSMAN->GetCoinMode() ) - { - case COIN_HOME: - if( GAMESTATE->PlayersCanJoin() ) - sCredits = CREDITS_PRESS_START; - else - sCredits = CREDITS_NOT_PRESENT; - break; - case COIN_PAY: - { - int Credits = GAMESTATE->m_iCoins / PREFSMAN->m_iCoinsPerCredit; - int Coins = GAMESTATE->m_iCoins % PREFSMAN->m_iCoinsPerCredit; - sCredits = CREDITS_CREDITS; - if( Credits > 0 || PREFSMAN->m_iCoinsPerCredit == 1 ) - sCredits += ssprintf(" %d", Credits); - if( PREFSMAN->m_iCoinsPerCredit > 1 ) - sCredits += ssprintf(" %d/%d", Coins, PREFSMAN->m_iCoinsPerCredit ); - } - break; - case COIN_FREE: - if( GAMESTATE->PlayersCanJoin() ) - sCredits = CREDITS_FREE_PLAY; - else - sCredits = CREDITS_NOT_PRESENT; - break; - default: - ASSERT(0); - } - } - - if( CREDITS_JOIN_ONLY && !GAMESTATE->PlayersCanJoin() ) - sCredits = ""; - m_textCredits[p].SetText( sCredits ); - } -} - -void ScreenSystemLayer::AddTimestampLine( const CString &txt, RageColor color ) -{ - m_textSkips[m_LastSkip].SetText( txt ); - m_textSkips[m_LastSkip].StopTweening(); - m_textSkips[m_LastSkip].SetDiffuse( RageColor(1,1,1,1) ); - m_textSkips[m_LastSkip].BeginTweening( 0.2f ); - m_textSkips[m_LastSkip].SetDiffuse( color ); - m_textSkips[m_LastSkip].BeginTweening( 3.0f ); - m_textSkips[m_LastSkip].BeginTweening( 0.2f ); - m_textSkips[m_LastSkip].SetDiffuse( RageColor(1,1,1,0) ); - - m_LastSkip++; - m_LastSkip %= NUM_SKIPS_TO_SHOW; -} - -void ScreenSystemLayer::UpdateTimestampAndSkips() -{ - /* Use our own timer, so we ignore `/tab. */ - const float UpdateTime = SkipTimer.GetDeltaTime(); - - /* FPS is 0 for a little while after we load a screen; don't report - * during this time. Do clear the timer, though, so we don't report - * a big "skip" after this period passes. */ - if(DISPLAY->GetFPS()) - { - /* We want to display skips. We expect to get updates of about 1.0/FPS ms. */ - const float ExpectedUpdate = 1.0f / DISPLAY->GetFPS(); - - /* These are thresholds for severity of skips. The smallest - * is slightly above expected, to tolerate normal jitter. */ - const float Thresholds[] = { - ExpectedUpdate * 2.0f, ExpectedUpdate * 4.0f, 0.1f, -1 - }; - - int skip = 0; - while(Thresholds[skip] != -1 && UpdateTime > Thresholds[skip]) - skip++; - - if(skip) - { - CString time(SecondsToMMSSMsMs(RageTimer::GetTimeSinceStart())); - - static const RageColor colors[] = { - RageColor(0,0,0,0), /* unused */ - RageColor(0.2f,0.2f,1,1), /* light blue */ - RageColor(1,1,0,1), /* yellow */ - RageColor(1,0.2f,0.2f,1) /* light red */ - }; - - if( PREFSMAN->m_bTimestamping ) - AddTimestampLine( ssprintf("%s: %.0fms (%.0f)", time.c_str(), 1000*UpdateTime, UpdateTime/ExpectedUpdate), - colors[skip] ); - if( PREFSMAN->m_bLogSkips ) - LOG->Trace( "Frame skip: %.0fms (%.0f)", 1000*UpdateTime, UpdateTime/ExpectedUpdate ); - } - } - - if( PREFSMAN->m_bTimestamping ) - m_textTime.SetText( SecondsToMMSSMsMs(RageTimer::GetTimeSinceStart()) ); -} - -void ScreenSystemLayer::Update( float fDeltaTime ) -{ - Screen::Update(fDeltaTime); - - if( PREFSMAN && PREFSMAN->m_bShowStats ) - { - m_textStats.SetDiffuse( RageColor(1,1,1,0.7f) ); - m_textStats.SetText( DISPLAY->GetStats() ); - } else - m_textStats.SetDiffuse( RageColor(1,1,1,0) ); /* hide */ - - UpdateTimestampAndSkips(); -} - ScreenManager::ScreenManager() { m_SystemLayer = NULL; @@ -386,8 +75,7 @@ void ScreenManager::ThemeChanged() m_soundBack.Load( THEME->GetPathS("Common","back") ); // reload system layer - delete m_SystemLayer; - m_SystemLayer = NULL; // new ScreenSystemLayer may throw + SAFE_DELETE( m_SystemLayer ); m_SystemLayer = new ScreenSystemLayer; m_SystemLayer->RefreshCreditsMessages(); } diff --git a/stepmania/src/ScreenSystemLayer.cpp b/stepmania/src/ScreenSystemLayer.cpp new file mode 100644 index 0000000000..be1044919d --- /dev/null +++ b/stepmania/src/ScreenSystemLayer.cpp @@ -0,0 +1,310 @@ +#include "global.h" +#include "ScreenSystemLayer.h" +#include "PrefsManager.h" +#include "ThemeManager.h" +#include "ActorUtil.h" +#include "GameState.h" +#include "MemoryCardManager.h" +#include "Profile.h" +#include "ProfileManager.h" +#include "RageDisplay.h" +#include "RageLog.h" + + +#define CREDITS_PRESS_START THEME->GetMetric ("ScreenSystemLayer","CreditsPressStart") +#define CREDITS_INSERT_CARD THEME->GetMetric ("ScreenSystemLayer","CreditsInsertCard") +#define CREDITS_CARD_ERROR THEME->GetMetric ("ScreenSystemLayer","CreditsCardError") +#define CREDITS_CARD_TOO_LATE THEME->GetMetric ("ScreenSystemLayer","CreditsCardTooLate") +#define CREDITS_CARD_NO_NAME THEME->GetMetric ("ScreenSystemLayer","CreditsCardNoName") +#define CREDITS_CARD_READY THEME->GetMetric ("ScreenSystemLayer","CreditsCardReady") +#define CREDITS_FREE_PLAY THEME->GetMetric ("ScreenSystemLayer","CreditsFreePlay") +#define CREDITS_CREDITS THEME->GetMetric ("ScreenSystemLayer","CreditsCredits") +#define CREDITS_NOT_PRESENT THEME->GetMetric ("ScreenSystemLayer","CreditsNotPresent") +#define CREDITS_LOAD_FAILED THEME->GetMetric ("ScreenSystemLayer","CreditsLoadFailed") +#define CREDITS_LOADED_FROM_LAST_GOOD_APPEND THEME->GetMetric ("ScreenSystemLayer","CreditsLoadedFromLastGoodAppend") +#define CREDITS_JOIN_ONLY THEME->GetMetricB("ScreenSystemLayer","CreditsJoinOnly") + + +ScreenSystemLayer::ScreenSystemLayer() : Screen("ScreenSystemLayer") +{ + this->AddChild(&m_textMessage); + this->AddChild(&m_textStats); + this->AddChild(&m_textTime); + FOREACH_PlayerNumber( p ) + this->AddChild(&m_textCredits[p]); + + + /* "Was that a skip?" This displays a message when an update takes + * abnormally long, to quantify skips more precisely, verify them + * when they're subtle, and show the time it happened, so you can pinpoint + * the time in the log. Put a dim quad behind it to make it easier to + * read. */ + m_LastSkip = 0; + const float SKIP_LEFT = 320.0f, SKIP_TOP = 60.0f, + SKIP_WIDTH = 160.0f, SKIP_Y_DIST = 16.0f; + + m_SkipBackground.StretchTo(RectF(SKIP_LEFT-8, SKIP_TOP-8, + SKIP_LEFT+SKIP_WIDTH, SKIP_TOP+SKIP_Y_DIST*NUM_SKIPS_TO_SHOW)); + m_SkipBackground.SetDiffuse( RageColor(0,0,0,0.4f) ); + m_SkipBackground.SetHidden( !PREFSMAN->m_bTimestamping ); + this->AddChild(&m_SkipBackground); + + for( int i=0; iGetPathToF("Common normal") ); + m_textSkips[i].SetXY( SKIP_LEFT, SKIP_TOP + SKIP_Y_DIST*i ); + m_textSkips[i].SetHorizAlign( Actor::align_left ); + m_textSkips[i].SetVertAlign( Actor::align_top ); + m_textSkips[i].SetZoom( 0.5f ); + m_textSkips[i].SetDiffuse( RageColor(1,1,1,0) ); + m_textSkips[i].SetShadowLength( 0 ); + this->AddChild(&m_textSkips[i]); + } + + ReloadCreditsText(); + /* This will be done when we set up the first screen, after GAMESTATE->Reset has + * been called. */ + // RefreshCreditsMessages(); +} + +void ScreenSystemLayer::ReloadCreditsText() +{ + m_textMessage.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer message") ); + m_textMessage.SetName( "Message" ); + SET_XY_AND_ON_COMMAND( m_textMessage ); + + m_textStats.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer stats") ); + m_textStats.SetName( "Stats" ); + SET_XY_AND_ON_COMMAND( m_textStats ); + + m_textTime.LoadFromFont( THEME->GetPathToF("ScreenSystemLayer time") ); + m_textTime.SetName( "Time" ); + m_textTime.SetHidden( !PREFSMAN->m_bTimestamping ); + SET_XY_AND_ON_COMMAND( m_textTime ); + + FOREACH_PlayerNumber( p ) + { + m_textCredits[p].LoadFromFont( THEME->GetPathToF("ScreenManager credits") ); + m_textCredits[p].SetName( ssprintf("CreditsP%d",p+1) ); + SET_XY_AND_ON_COMMAND( &m_textCredits[p] ); + } +} + +void ScreenSystemLayer::SystemMessage( CString sMessage ) +{ + m_textMessage.SetText( sMessage ); + static const ActorCommands cmds = ParseActorCommands("finishtweening;diffusealpha,1;addx,-640;linear,0.5;addx,+640;sleep,5;linear,0.5;diffusealpha,0"); + m_textMessage.Command( cmds ); +} + +void ScreenSystemLayer::SystemMessageNoAnimate( CString sMessage ) +{ + m_textMessage.FinishTweening(); + m_textMessage.SetText( sMessage ); + m_textMessage.SetX( 4 ); + m_textMessage.SetDiffuseAlpha( 1 ); + m_textMessage.BeginTweening( 5 ); + m_textMessage.BeginTweening( 0.5f ); + m_textMessage.SetDiffuse( RageColor(1,1,1,0) ); +} + +void ScreenSystemLayer::RefreshCreditsMessages() +{ + // update joined + FOREACH_PlayerNumber( p ) + { + CString sCredits; + + bool bShowCreditsMessage; + if( GAMESTATE->m_bIsOnSystemMenu ) + bShowCreditsMessage = true; + else if( GAMESTATE->m_bPlayersFinalized ) + bShowCreditsMessage = !GAMESTATE->IsPlayerEnabled( p ); + else + bShowCreditsMessage = !GAMESTATE->m_bSideIsJoined[p]; + + if( !bShowCreditsMessage ) + { + MemoryCardState mcs = MEMCARDMAN->GetCardState( p ); + Profile* pProfile = PROFILEMAN->GetProfile( p ); + switch( mcs ) + { + case MEMORY_CARD_STATE_NO_CARD: + // this is a local machine profile + if( PROFILEMAN->LastLoadWasFromLastGood(p) && pProfile ) + sCredits = pProfile->GetDisplayName() + CREDITS_LOADED_FROM_LAST_GOOD_APPEND; + else if( PROFILEMAN->LastLoadWasTamperedOrCorrupt(p) ) + sCredits = CREDITS_LOAD_FAILED; + // Prefer the name of the profile over the name of the card. + else if( pProfile ) + sCredits = pProfile->GetDisplayName(); + else if( GAMESTATE->PlayersCanJoin() ) + sCredits = CREDITS_INSERT_CARD; + else + sCredits = ""; + break; + case MEMORY_CARD_STATE_WRITE_ERROR: + sCredits = CREDITS_CARD_ERROR; + break; + case MEMORY_CARD_STATE_TOO_LATE: + sCredits = CREDITS_CARD_TOO_LATE; + break; + case MEMORY_CARD_STATE_READY: + if( PROFILEMAN->LastLoadWasFromLastGood(p) && pProfile ) + sCredits = pProfile->GetDisplayName() + CREDITS_LOADED_FROM_LAST_GOOD_APPEND; + else if( PROFILEMAN->LastLoadWasTamperedOrCorrupt(p) ) + sCredits = CREDITS_LOAD_FAILED; + // Prefer the name of the profile over the name of the card. + else if( pProfile ) + sCredits = pProfile->GetDisplayName(); + else if( !MEMCARDMAN->IsNameAvailable(p) ) + sCredits = CREDITS_CARD_READY; + else if( !MEMCARDMAN->GetName(p).empty() ) + sCredits = MEMCARDMAN->GetName(p); + else + sCredits = CREDITS_CARD_NO_NAME; + break; + default: + ASSERT(0); + } + } + else // bShowCreditsMessage + { + switch( PREFSMAN->GetCoinMode() ) + { + case COIN_HOME: + if( GAMESTATE->PlayersCanJoin() ) + sCredits = CREDITS_PRESS_START; + else + sCredits = CREDITS_NOT_PRESENT; + break; + case COIN_PAY: + { + int Credits = GAMESTATE->m_iCoins / PREFSMAN->m_iCoinsPerCredit; + int Coins = GAMESTATE->m_iCoins % PREFSMAN->m_iCoinsPerCredit; + sCredits = CREDITS_CREDITS; + if( Credits > 0 || PREFSMAN->m_iCoinsPerCredit == 1 ) + sCredits += ssprintf(" %d", Credits); + if( PREFSMAN->m_iCoinsPerCredit > 1 ) + sCredits += ssprintf(" %d/%d", Coins, PREFSMAN->m_iCoinsPerCredit ); + } + break; + case COIN_FREE: + if( GAMESTATE->PlayersCanJoin() ) + sCredits = CREDITS_FREE_PLAY; + else + sCredits = CREDITS_NOT_PRESENT; + break; + default: + ASSERT(0); + } + } + + if( CREDITS_JOIN_ONLY && !GAMESTATE->PlayersCanJoin() ) + sCredits = ""; + m_textCredits[p].SetText( sCredits ); + } +} + +void ScreenSystemLayer::AddTimestampLine( const CString &txt, RageColor color ) +{ + m_textSkips[m_LastSkip].SetText( txt ); + m_textSkips[m_LastSkip].StopTweening(); + m_textSkips[m_LastSkip].SetDiffuse( RageColor(1,1,1,1) ); + m_textSkips[m_LastSkip].BeginTweening( 0.2f ); + m_textSkips[m_LastSkip].SetDiffuse( color ); + m_textSkips[m_LastSkip].BeginTweening( 3.0f ); + m_textSkips[m_LastSkip].BeginTweening( 0.2f ); + m_textSkips[m_LastSkip].SetDiffuse( RageColor(1,1,1,0) ); + + m_LastSkip++; + m_LastSkip %= NUM_SKIPS_TO_SHOW; +} + +void ScreenSystemLayer::UpdateTimestampAndSkips() +{ + /* Use our own timer, so we ignore `/tab. */ + const float UpdateTime = SkipTimer.GetDeltaTime(); + + /* FPS is 0 for a little while after we load a screen; don't report + * during this time. Do clear the timer, though, so we don't report + * a big "skip" after this period passes. */ + if(DISPLAY->GetFPS()) + { + /* We want to display skips. We expect to get updates of about 1.0/FPS ms. */ + const float ExpectedUpdate = 1.0f / DISPLAY->GetFPS(); + + /* These are thresholds for severity of skips. The smallest + * is slightly above expected, to tolerate normal jitter. */ + const float Thresholds[] = { + ExpectedUpdate * 2.0f, ExpectedUpdate * 4.0f, 0.1f, -1 + }; + + int skip = 0; + while(Thresholds[skip] != -1 && UpdateTime > Thresholds[skip]) + skip++; + + if(skip) + { + CString time(SecondsToMMSSMsMs(RageTimer::GetTimeSinceStart())); + + static const RageColor colors[] = { + RageColor(0,0,0,0), /* unused */ + RageColor(0.2f,0.2f,1,1), /* light blue */ + RageColor(1,1,0,1), /* yellow */ + RageColor(1,0.2f,0.2f,1) /* light red */ + }; + + if( PREFSMAN->m_bTimestamping ) + AddTimestampLine( ssprintf("%s: %.0fms (%.0f)", time.c_str(), 1000*UpdateTime, UpdateTime/ExpectedUpdate), + colors[skip] ); + if( PREFSMAN->m_bLogSkips ) + LOG->Trace( "Frame skip: %.0fms (%.0f)", 1000*UpdateTime, UpdateTime/ExpectedUpdate ); + } + } + + if( PREFSMAN->m_bTimestamping ) + m_textTime.SetText( SecondsToMMSSMsMs(RageTimer::GetTimeSinceStart()) ); +} + +void ScreenSystemLayer::Update( float fDeltaTime ) +{ + Screen::Update(fDeltaTime); + + if( PREFSMAN && PREFSMAN->m_bShowStats ) + { + m_textStats.SetDiffuse( RageColor(1,1,1,0.7f) ); + m_textStats.SetText( DISPLAY->GetStats() ); + } else + m_textStats.SetDiffuse( RageColor(1,1,1,0) ); /* hide */ + + UpdateTimestampAndSkips(); +} + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenSystemLayer.h b/stepmania/src/ScreenSystemLayer.h new file mode 100644 index 0000000000..68d0e401bd --- /dev/null +++ b/stepmania/src/ScreenSystemLayer.h @@ -0,0 +1,64 @@ +/* ScreenSystemLayer - + * This screen is drawn on top of everything else, and receives updates, + * but not input. + */ + +#ifndef ScreenSystemLayer_H +#define ScreenSystemLayer_H + +#include "Screen.h" +#include "BitmapText.h" +#include "Quad.h" + +const int NUM_SKIPS_TO_SHOW = 5; + +class ScreenSystemLayer : public Screen +{ + BitmapText m_textStats; + BitmapText m_textMessage; + BitmapText m_textCredits[NUM_PLAYERS]; + BitmapText m_textTime; + BitmapText m_textSkips[NUM_SKIPS_TO_SHOW]; + int m_LastSkip; + Quad m_SkipBackground; + + RageTimer SkipTimer; + void AddTimestampLine( const CString &txt, RageColor color ); + void UpdateTimestampAndSkips(); + +public: + ScreenSystemLayer(); + void SystemMessage( CString sMessage ); + void SystemMessageNoAnimate( CString sMessage ); + void ReloadCreditsText(); + void RefreshCreditsMessages(); + void Update( float fDeltaTime ); +}; + + +#endif + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 84e0ff0660..5c79f947ae 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -62,7 +62,7 @@ IntDir=.\../Debug6 TargetDir=\stepmania\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -99,7 +99,7 @@ IntDir=.\../Release6 TargetDir=\stepmania\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -2832,6 +2832,14 @@ SOURCE=.\ScreenStyleSplash.h # End Source File # Begin Source File +SOURCE=.\ScreenSystemLayer.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScreenSystemLayer.h +# End Source File +# Begin Source File + SOURCE=.\ScreenTest.cpp # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 345d6a461d..08ebf7a73a 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -374,10 +374,10 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ RelativePath="ScreenNetEvaluation.h"> + RelativePath="ScreenNetRoom.cpp"> + RelativePath="ScreenNetRoom.h"> @@ -386,10 +386,10 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ RelativePath="ScreenNetSelectBase.h"> + RelativePath="ScreenNetSelectMusic.cpp"> + RelativePath="ScreenNetSelectMusic.h"> @@ -967,6 +967,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +