From c239e439a0d9f8c7110618cb01a7ad00f52d28ce Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Thu, 26 Jul 2012 17:27:45 -0500 Subject: [PATCH] [ScreenDebugOverlay] Added BackgroundColor metric. --- Docs/Changelog_sm5.txt | 10 +- Themes/_fallback/metrics.ini | 2 + src/ScreenDebugOverlay.cpp | 2483 +++++++++++++++++----------------- 3 files changed, 1251 insertions(+), 1244 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index d6676d32ee..b9d91cf003 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -4,9 +4,9 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt. ________________________________________________________________________________ -================================================================================ -StepMania 5.0 alpha 3 | 20120711 --------------------------------------------------------------------------------- +2012/07/26 +---------- +* [ScreenDebugOverlay] Added BackgroundColor metric. [AJ] 2012/07/19 ---------- @@ -17,6 +17,10 @@ StepMania 5.0 alpha 3 | 20120711 ---------- * [SongManager] Fix a bug where DVNO wouldn't always be gold. [AJ] +================================================================================ +StepMania 5.0 alpha 3 | 20120711 +-------------------------------------------------------------------------------- + 2012/07/11 ---------- * [ScreenEditMenu] Don't use "Blank" in the description for blank steps; diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index a130753520..70c838403c 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -1504,6 +1504,8 @@ ShowCreditDisplay=false Class="ScreenDebugOverlay" Fallback="Screen" +BackgroundColor=color("0,0,0,0.5") + LineOnColor=color("1,1,1,1") LineOffColor=color("0.6,0.6,0.6,1") LineStartY=SCREEN_TOP+50 diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp index e992da578a..c7db4f9964 100644 --- a/src/ScreenDebugOverlay.cpp +++ b/src/ScreenDebugOverlay.cpp @@ -1,1241 +1,1242 @@ -#include "global.h" -#include "ScreenDebugOverlay.h" -#include "ScreenDimensions.h" -#include "ScreenManager.h" -#include "PrefsManager.h" -#include "GamePreferences.h" -#include "RageLog.h" -#include "GameState.h" -#include "PlayerState.h" -#include "StepMania.h" -#include "GameCommand.h" -#include "ScreenGameplay.h" -#include "RageSoundManager.h" -#include "GameSoundManager.h" -#include "RageTextureManager.h" -#include "MemoryCardManager.h" -#include "NoteSkinManager.h" -#include "Bookkeeper.h" -#include "ProfileManager.h" -#include "CodeDetector.h" -#include "RageInput.h" -#include "RageDisplay.h" -#include "InputEventPlus.h" -#include "LocalizedString.h" -#include "Profile.h" -#include "SongManager.h" -#include "GameLoop.h" -#include "Song.h" -#include "ScreenSyncOverlay.h" -#include "ThemeMetric.h" - -static bool g_bIsDisplayed = false; -static bool g_bIsSlow = false; -static bool g_bIsHalt = false; -static RageTimer g_HaltTimer(RageZeroTimer); -static float g_fImageScaleCurrent = 1; -static float g_fImageScaleDestination = 1; - -// DebugLine theming -static const ThemeMetric LINE_ON_COLOR ("ScreenDebugOverlay", "LineOnColor"); -static const ThemeMetric LINE_OFF_COLOR ("ScreenDebugOverlay", "LineOffColor"); -static const ThemeMetric LINE_START_Y ("ScreenDebugOverlay", "LineStartY"); -static const ThemeMetric LINE_SPACING ("ScreenDebugOverlay", "LineSpacing"); -static const ThemeMetric LINE_BUTTON_X ("ScreenDebugOverlay", "LineButtonX"); -static const ThemeMetric LINE_FUNCTION_X ("ScreenDebugOverlay", "LineFunctionX"); -static const ThemeMetric PAGE_START_X ("ScreenDebugOverlay", "PageStartX"); -static const ThemeMetric PAGE_SPACING_X ("ScreenDebugOverlay", "PageSpacingX"); - -// self-registering debug lines -// We don't use SubscriptionManager, because we want to keep the line order. -static LocalizedString ON ( "ScreenDebugOverlay", "on" ); -static LocalizedString OFF ( "ScreenDebugOverlay", "off" ); - -class IDebugLine; -static vector *g_pvpSubscribers = NULL; -class IDebugLine -{ -public: - IDebugLine() - { - if( g_pvpSubscribers == NULL ) - g_pvpSubscribers = new vector; - g_pvpSubscribers->push_back( this ); - } - virtual ~IDebugLine() { } - enum Type { all_screens, gameplay_only }; - virtual Type GetType() const { return all_screens; } - virtual RString GetDisplayTitle() = 0; - virtual RString GetDisplayValue() { return IsEnabled() ? ON.GetValue():OFF.GetValue(); } - virtual RString GetPageName() const { return "Main"; } - virtual bool ForceOffAfterUse() const { return false; } - virtual bool IsEnabled() = 0; - virtual void DoAndLog( RString &sMessageOut ) - { - RString s1 = GetDisplayTitle(); - RString s2 = GetDisplayValue(); - if( !s2.empty() ) - s1 += " - "; - sMessageOut = s1 + s2; - }; - - DeviceInput m_Button; -}; - -static bool IsGameplay() -{ - return SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == gameplay; -} - - -REGISTER_SCREEN_CLASS( ScreenDebugOverlay ); - -ScreenDebugOverlay::~ScreenDebugOverlay() -{ - this->RemoveAllChildren(); - - FOREACH( BitmapText*, m_vptextPages, p ) - SAFE_DELETE( *p ); - FOREACH( BitmapText*, m_vptextButton, p ) - SAFE_DELETE( *p ); - m_vptextButton.clear(); - FOREACH( BitmapText*, m_vptextFunction, p ) - SAFE_DELETE( *p ); - m_vptextFunction.clear(); -} - -const int MAX_DEBUG_LINES = 30; -struct MapDebugToDI -{ - DeviceInput holdForDebug1; - DeviceInput holdForDebug2; - DeviceInput holdForSlow; - DeviceInput holdForFast; - DeviceInput debugButton[MAX_DEBUG_LINES]; - DeviceInput gameplayButton[MAX_DEBUG_LINES]; - map pageButton; - void Clear() - { - holdForDebug1.MakeInvalid(); - holdForDebug2.MakeInvalid(); - holdForSlow.MakeInvalid(); - holdForFast.MakeInvalid(); - for( int i=0; iGetDeviceSpecificInputString(pLine->m_Button); - switch( pLine->GetType() ) - { - case IDebugLine::all_screens: - return s; - case IDebugLine::gameplay_only: - return ssprintf( IN_GAMEPLAY.GetValue(), s.c_str() ); - default: - ASSERT(0); - } -} - -template -static bool GetKeyFromMap( const map &m, const V &val, U &key ) -{ - for( typename map::const_iterator iter = m.begin(); iter != m.end(); ++iter ) - { - if( iter->second == val ) - { - key = iter->first; - return true; - } - } - return false; -} - -static LocalizedString DEBUG_MENU( "ScreenDebugOverlay", "Debug Menu" ); -void ScreenDebugOverlay::Init() -{ - Screen::Init(); - - // Init debug mappings - // TODO: Arch-specific? - { - g_Mappings.Clear(); - - g_Mappings.holdForDebug1 = DeviceInput(DEVICE_KEYBOARD, KEY_F3); - g_Mappings.holdForDebug2.MakeInvalid(); - g_Mappings.holdForSlow = DeviceInput(DEVICE_KEYBOARD, KEY_ACCENT); - g_Mappings.holdForFast = DeviceInput(DEVICE_KEYBOARD, KEY_TAB); - - /* TODO: Find a better way of indicating which option is which here. - * Maybe we should take a page from ScreenEdit's menus and make - * RowDefs()? */ - - int i=0; - g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F8); - g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F7); - g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F6); - i=0; - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C1); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C2); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C3); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C4); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C5); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C6); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C7); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C8); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C9); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C0); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cq); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cw); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ce); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cr); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cy); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cu); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ci); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Co); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cp); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_UP); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_DOWN); - g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_BACK); - g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F5)] = 0; - g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F6)] = 1; - g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F7)] = 2; - g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F8)] = 3; - } - - map iNextDebugButton; - int iNextGameplayButton = 0; - FOREACH( IDebugLine*, *g_pvpSubscribers, p ) - { - RString sPageName = (*p)->GetPageName(); - - DeviceInput di; - switch( (*p)->GetType() ) - { - case IDebugLine::all_screens: - di = g_Mappings.debugButton[iNextDebugButton[sPageName]++]; - break; - case IDebugLine::gameplay_only: - di = g_Mappings.gameplayButton[iNextGameplayButton++]; - break; - } - (*p)->m_Button = di; - - if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() ) - m_asPages.push_back( sPageName ); - } - - m_iCurrentPage = 0; - m_bForcedHidden = false; - - m_Quad.StretchTo( RectF( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ) ); - m_Quad.SetDiffuse( RageColor(0, 0, 0, 0.5f) ); - this->AddChild( &m_Quad ); - - // if you're going to add user commands, make sure to have the overrides - // set after parsing the metrics. -aj - m_textHeader.SetName( "HeaderText" ); - m_textHeader.LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "header") ); - LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textHeader ); - m_textHeader.SetText( DEBUG_MENU ); - this->AddChild( &m_textHeader ); - - FOREACH_CONST( RString, m_asPages, s ) - { - int iPage = s - m_asPages.begin(); - - DeviceInput di; - bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di ); - ASSERT( b ); - - RString sButton = INPUTMAN->GetDeviceSpecificInputString( di ); - - BitmapText *p = new BitmapText; - p->SetName( "PageText" ); - p->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "page") ); - LOAD_ALL_COMMANDS_AND_ON_COMMAND( p ); - // todo: Y value is still hardcoded. -aj - p->SetXY( PAGE_START_X+iPage*PAGE_SPACING_X, SCREEN_TOP+20 ); - p->SetText( *s + " (" + sButton + ")" ); - m_vptextPages.push_back( p ); - this->AddChild( p ); - } - - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) - { - { - BitmapText *bt = new BitmapText; - bt->SetName( "ButtonText" ); - bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") ); - bt->SetHorizAlign( align_right ); - bt->SetText( "blah" ); - LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt ); - m_vptextButton.push_back( bt ); - this->AddChild( bt ); - } - { - BitmapText *bt = new BitmapText; - bt->SetName( "FunctionText" ); - bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") ); - bt->SetHorizAlign( align_left ); - bt->SetText( "blah" ); - LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt ); - m_vptextFunction.push_back( bt ); - this->AddChild( bt ); - } - } - - this->SetVisible( false ); -} - -void ScreenDebugOverlay::Update( float fDeltaTime ) -{ - { - float fRate = 1; - if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForFast) ) - { - if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) ) - fRate = 0; // both; stop time - else - fRate *= 4; - } - else if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) ) - { - fRate /= 4; - } - - if( g_bIsHalt ) - fRate = 0; - else if( g_bIsSlow ) - fRate /= 4; - - GameLoop::SetUpdateRate( fRate ); - } - - bool bCenteringNeedsUpdate = g_fImageScaleCurrent != g_fImageScaleDestination; - fapproach( g_fImageScaleCurrent, g_fImageScaleDestination, fDeltaTime ); - if( bCenteringNeedsUpdate ) - { - DISPLAY->ChangeCentering( - PREFSMAN->m_iCenterImageTranslateX, - PREFSMAN->m_iCenterImageTranslateY, - PREFSMAN->m_fCenterImageAddWidth - (int)SCREEN_WIDTH + (int)(g_fImageScaleCurrent*SCREEN_WIDTH), - PREFSMAN->m_fCenterImageAddHeight - (int)SCREEN_HEIGHT + (int)(g_fImageScaleCurrent*SCREEN_HEIGHT) ); - } - - Screen::Update(fDeltaTime); - - this->SetVisible( g_bIsDisplayed && !m_bForcedHidden ); - if( !g_bIsDisplayed ) - return; - - UpdateText(); -} - -void ScreenDebugOverlay::UpdateText() -{ - FOREACH_CONST( RString, m_asPages, s ) - { - int iPage = s - m_asPages.begin(); - m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" ); - } - - // todo: allow changing of various spacing/location things -aj - int iOffset = 0; - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) - { - RString sPageName = (*p)->GetPageName(); - - int i = p-g_pvpSubscribers->begin(); - - float fY = LINE_START_Y + iOffset * LINE_SPACING; - - BitmapText &txt1 = *m_vptextButton[i]; - BitmapText &txt2 = *m_vptextFunction[i]; - if( sPageName != GetCurrentPageName() ) - { - txt1.SetVisible( false ); - txt2.SetVisible( false ); - continue; - } - txt1.SetVisible( true ); - txt2.SetVisible( true ); - ++iOffset; - - txt1.SetX( LINE_BUTTON_X ); - txt1.SetY( fY ); - - txt2.SetX( LINE_FUNCTION_X ); - txt2.SetY( fY ); - - RString s1 = (*p)->GetDisplayTitle(); - RString s2 = (*p)->GetDisplayValue(); - - bool bOn = (*p)->IsEnabled(); - - txt1.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR ); - txt2.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR ); - - RString sButton = GetDebugButtonName( *p ); - if( !sButton.empty() ) - sButton += ": "; - txt1.SetText( sButton ); - if( !s2.empty() ) - s1 += " - "; - txt2.SetText( s1 + s2 ); - } - - if( g_bIsHalt ) - { - /* More than once I've paused the game accidentally and wasted time - * figuring out why, so warn. */ - if( g_HaltTimer.Ago() >= 5.0f ) - { - g_HaltTimer.Touch(); - LOG->Warn( "Game halted" ); - } - } -} - -template -static bool GetValueFromMap( const map &m, const U &key, V &val ) -{ - typename map::const_iterator it = m.find(key); - if( it == m.end() ) - return false; - val = it->second; - return true; -} - -bool ScreenDebugOverlay::OverlayInput( const InputEventPlus &input ) -{ - if( input.DeviceI == g_Mappings.holdForDebug1 || - input.DeviceI == g_Mappings.holdForDebug2 ) - { - bool bHoldingNeither = - (!g_Mappings.holdForDebug1.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) && - (!g_Mappings.holdForDebug2.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2)); - bool bHoldingBoth = - (!g_Mappings.holdForDebug1.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) && - (!g_Mappings.holdForDebug2.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2)); - if( bHoldingNeither ) - m_bForcedHidden = false; - - if( bHoldingBoth ) - g_bIsDisplayed = true; - else - g_bIsDisplayed = false; - } - - int iPage = 0; - if( g_bIsDisplayed && GetValueFromMap(g_Mappings.pageButton, input.DeviceI, iPage) ) - { - if( input.type != IET_FIRST_PRESS ) - return true; // eat the input but do nothing - m_iCurrentPage = iPage; - CLAMP( m_iCurrentPage, 0, (int) m_asPages.size()-1 ); - return true; - } - - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) - { - RString sPageName = (*p)->GetPageName(); - - int i = p-g_pvpSubscribers->begin(); - - // Gameplay buttons are available only in gameplay. Non-gameplay buttons - // are only available when the screen is displayed. - switch( (*p)->GetType() ) - { - case IDebugLine::all_screens: - if( !g_bIsDisplayed ) - continue; - if( sPageName != GetCurrentPageName() ) - continue; - break; - case IDebugLine::gameplay_only: - if( !IsGameplay() ) - continue; - break; - default: - ASSERT(0); - } - - if( input.DeviceI == (*p)->m_Button ) - { - if( input.type != IET_FIRST_PRESS ) - return true; // eat the input but do nothing - - // do the action - RString sMessage; - (*p)->DoAndLog( sMessage ); - if( !sMessage.empty() ) - LOG->Trace("DEBUG: %s", sMessage.c_str() ); - if( (*p)->ForceOffAfterUse() ) - m_bForcedHidden = true; - - // update text to show the effect of what changed above - UpdateText(); - - // show what changed - BitmapText &bt = *m_vptextButton[i]; - bt.FinishTweening(); - bt.PlayCommand("Toggled"); - - return true; - } - } - - return false; -} - - -// DebugLine helpers -static void SetSpeed() -{ - // PauseMusic( g_bIsHalt ); -} - -void ChangeVolume( float fDelta ) -{ - Preference *pRet = Preference::GetPreferenceByName("SoundVolume"); - float fVol = pRet->Get(); - fVol += fDelta; - CLAMP( fVol, 0.0f, 1.0f ); - pRet->Set( fVol ); - SOUNDMAN->SetMixVolume(); -} - -void ChangeVisualDelay( float fDelta ) -{ - Preference *pRet = Preference::GetPreferenceByName("VisualDelaySeconds"); - float fSecs = pRet->Get(); - fSecs += fDelta; - CLAMP( fSecs, -1.0f, 1.0f ); - pRet->Set( fSecs ); -} - -// DebugLines -static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" ); -static LocalizedString ASSIST ( "ScreenDebugOverlay", "Assist" ); -static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" ); -static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" ); -static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" ); -static LocalizedString LIGHTS_DEBUG ( "ScreenDebugOverlay", "Lights Debug" ); -static LocalizedString MONKEY_INPUT ( "ScreenDebugOverlay", "Monkey Input" ); -static LocalizedString RENDERING_STATS ( "ScreenDebugOverlay", "Rendering Stats" ); -static LocalizedString VSYNC ( "ScreenDebugOverlay", "Vsync" ); -static LocalizedString MULTITEXTURE ( "ScreenDebugOverlay", "Multitexture" ); -static LocalizedString SCREEN_TEST_MODE ( "ScreenDebugOverlay", "Screen Test Mode" ); -static LocalizedString SCREEN_SHOW_MASKS ( "ScreenDebugOverlay", "Show Masks" ); -static LocalizedString PROFILE ( "ScreenDebugOverlay", "Profile" ); -static LocalizedString CLEAR_PROFILE_STATS ( "ScreenDebugOverlay", "Clear Profile Stats" ); -static LocalizedString FILL_PROFILE_STATS ( "ScreenDebugOverlay", "Fill Profile Stats" ); -static LocalizedString SEND_NOTES_ENDED ( "ScreenDebugOverlay", "Send Notes Ended" ); -static LocalizedString RELOAD ( "ScreenDebugOverlay", "Reload" ); -static LocalizedString RESTART ( "ScreenDebugOverlay", "Restart" ); -static LocalizedString SCREEN_ON ( "ScreenDebugOverlay", "Send On To Screen" ); -static LocalizedString SCREEN_OFF ( "ScreenDebugOverlay", "Send Off To Screen" ); -static LocalizedString RELOAD_THEME_AND_TEXTURES( "ScreenDebugOverlay", "Reload Theme and Textures" ); -static LocalizedString WRITE_PROFILES ( "ScreenDebugOverlay", "Write Profiles" ); -static LocalizedString WRITE_PREFERENCES ( "ScreenDebugOverlay", "Write Preferences" ); -static LocalizedString MENU_TIMER ( "ScreenDebugOverlay", "Menu Timer" ); -static LocalizedString FLUSH_LOG ( "ScreenDebugOverlay", "Flush Log" ); -static LocalizedString PULL_BACK_CAMERA ( "ScreenDebugOverlay", "Pull Back Camera" ); -static LocalizedString VISUAL_DELAY_UP ( "ScreenDebugOverlay", "Visual Delay Up" ); -static LocalizedString VISUAL_DELAY_DOWN ( "ScreenDebugOverlay", "Visual Delay Down" ); -static LocalizedString VOLUME_UP ( "ScreenDebugOverlay", "Volume Up" ); -static LocalizedString VOLUME_DOWN ( "ScreenDebugOverlay", "Volume Down" ); -static LocalizedString UPTIME ( "ScreenDebugOverlay", "Uptime" ); -static LocalizedString FORCE_CRASH ( "ScreenDebugOverlay", "Force Crash" ); -static LocalizedString SLOW ( "ScreenDebugOverlay", "Slow" ); -static LocalizedString CPU ( "ScreenDebugOverlay", "CPU" ); -static LocalizedString SONG ( "ScreenDebugOverlay", "Song" ); -static LocalizedString MACHINE ( "ScreenDebugOverlay", "Machine" ); -static LocalizedString SYNC_TEMPO ( "ScreenDebugOverlay", "Tempo" ); - -class DebugLineAutoplay : public IDebugLine -{ - virtual RString GetDisplayTitle() { return AUTO_PLAY.GetValue() + " (+Shift = AI) (+Alt = hide)"; } - virtual RString GetDisplayValue() - { - switch( GamePreferences::m_AutoPlay.Get() ) - { - case PC_HUMAN: return OFF.GetValue(); break; - case PC_AUTOPLAY: return ON.GetValue(); break; - case PC_CPU: return CPU.GetValue(); break; - default: ASSERT(0); return RString(); - } - } - virtual Type GetType() const { return IDebugLine::gameplay_only; } - virtual bool IsEnabled() { return GamePreferences::m_AutoPlay.Get() != PC_HUMAN; } - virtual void DoAndLog( RString &sMessageOut ) - { - ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID ); - PlayerController pc = GAMESTATE->m_pPlayerState[GAMESTATE->GetMasterPlayerNumber()]->m_PlayerController; - bool bHoldingShift = - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ) || - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT) ); - if( bHoldingShift ) - pc = (pc==PC_CPU) ? PC_HUMAN : PC_CPU; - else - pc = (pc==PC_AUTOPLAY) ? PC_HUMAN : PC_AUTOPLAY; - GamePreferences::m_AutoPlay.Set( pc ); - FOREACH_HumanPlayer(p) - GAMESTATE->m_pPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay; - FOREACH_MultiPlayer(p) - GAMESTATE->m_pMultiPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay; - - // Hide Autoplay if Alt is held down - bool bHoldingAlt = - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT) ) || - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT) ); - ScreenSyncOverlay::SetShowAutoplay( !bHoldingAlt ); - - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineAssist : public IDebugLine -{ - virtual RString GetDisplayTitle() { return ASSIST.GetValue(); } - virtual Type GetType() const { return gameplay_only; } - virtual RString GetDisplayValue() { - SongOptions so; - so.m_bAssistClap = GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; - so.m_bAssistMetronome = GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; - if( so.m_bAssistClap || so.m_bAssistMetronome ) - return so.GetLocalizedString(); - else - return OFF.GetValue(); - } - virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistClap || GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; } - virtual void DoAndLog( RString &sMessageOut ) - { - ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID ); - bool bHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ); - bool b; - if( bHoldingShift ) - b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; - else - b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; - if( bHoldingShift ) - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistMetronome, b ); - else - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistClap, b ); - - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineAutosync : public IDebugLine -{ - virtual RString GetDisplayTitle() { return AUTOSYNC.GetValue(); } - virtual RString GetDisplayValue() - { - switch( GAMESTATE->m_SongOptions.GetSong().m_AutosyncType ) - { - case SongOptions::AUTOSYNC_OFF: return OFF.GetValue(); break; - case SongOptions::AUTOSYNC_SONG: return SONG.GetValue(); break; - case SongOptions::AUTOSYNC_MACHINE: return MACHINE.GetValue(); break; - case SongOptions::AUTOSYNC_TEMPO: return SYNC_TEMPO.GetValue(); break; - default: ASSERT(0); - } - } - virtual Type GetType() const { return IDebugLine::gameplay_only; } - virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_AutosyncType!=SongOptions::AUTOSYNC_OFF; } - virtual void DoAndLog( RString &sMessageOut ) - { - int as = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType + 1; - bool bAllowSongAutosync = !GAMESTATE->IsCourseMode(); - if( !bAllowSongAutosync && - ( as == SongOptions::AUTOSYNC_SONG || as == SongOptions::AUTOSYNC_TEMPO ) ) - as = SongOptions::AUTOSYNC_MACHINE; - wrap( as, SongOptions::NUM_AUTOSYNC_TYPES ); - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_AutosyncType, SongOptions::AutosyncType(as) ); - MESSAGEMAN->Broadcast( Message_AutosyncChanged ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineCoinMode : public IDebugLine -{ - virtual RString GetDisplayTitle() { return COIN_MODE.GetValue(); } - virtual RString GetDisplayValue() { return CoinModeToString(GamePreferences::m_CoinMode); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - int cm = GamePreferences::m_CoinMode+1; - wrap( cm, NUM_CoinMode ); - GamePreferences::m_CoinMode.Set( CoinMode(cm) ); - SCREENMAN->RefreshCreditsMessages(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineSlow : public IDebugLine -{ - virtual RString GetDisplayTitle() { return SLOW.GetValue(); } - virtual bool IsEnabled() { return g_bIsSlow; } - virtual void DoAndLog( RString &sMessageOut ) - { - g_bIsSlow = !g_bIsSlow; - SetSpeed(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineHalt : public IDebugLine -{ - virtual RString GetDisplayTitle() { return HALT.GetValue(); } - virtual bool IsEnabled() { return g_bIsHalt; } - virtual void DoAndLog( RString &sMessageOut ) - { - g_bIsHalt = !g_bIsHalt; - g_HaltTimer.Touch(); - SetSpeed(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineLightsDebug : public IDebugLine -{ - virtual RString GetDisplayTitle() { return LIGHTS_DEBUG.GetValue(); } - virtual bool IsEnabled() { return PREFSMAN->m_bDebugLights.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bDebugLights.Set( !PREFSMAN->m_bDebugLights ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineMonkeyInput : public IDebugLine -{ - virtual RString GetDisplayTitle() { return MONKEY_INPUT.GetValue(); } - virtual bool IsEnabled() { return PREFSMAN->m_bMonkeyInput.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bMonkeyInput.Set( !PREFSMAN->m_bMonkeyInput ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineStats : public IDebugLine -{ - virtual RString GetDisplayTitle() { return RENDERING_STATS.GetValue(); } - virtual bool IsEnabled() { return PREFSMAN->m_bShowStats.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bShowStats.Set( !PREFSMAN->m_bShowStats ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineVsync : public IDebugLine -{ - virtual RString GetDisplayTitle() { return VSYNC.GetValue(); } - virtual bool IsEnabled() { return PREFSMAN->m_bVsync.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bVsync.Set( !PREFSMAN->m_bVsync ); - StepMania::ApplyGraphicOptions(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineAllowMultitexture : public IDebugLine -{ - virtual RString GetDisplayTitle() { return MULTITEXTURE.GetValue(); } - virtual bool IsEnabled() { return PREFSMAN->m_bAllowMultitexture.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bAllowMultitexture.Set( !PREFSMAN->m_bAllowMultitexture ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineShowMasks : public IDebugLine -{ - virtual RString GetDisplayTitle() { return SCREEN_SHOW_MASKS.GetValue(); } - virtual bool IsEnabled() { return GetPref()->Get(); } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - GetPref()->Set( !GetPref()->Get() ); - IDebugLine::DoAndLog( sMessageOut ); - } - - Preference *GetPref() - { - return Preference::GetPreferenceByName("ShowMasks"); - } -}; - -static ProfileSlot g_ProfileSlot = ProfileSlot_Machine; -static bool IsSelectProfilePersistent() -{ - if( g_ProfileSlot == ProfileSlot_Machine ) - return true; - return PROFILEMAN->IsPersistentProfile( (PlayerNumber) g_ProfileSlot ); -} - -class DebugLineProfileSlot : public IDebugLine -{ - virtual RString GetDisplayTitle() { return PROFILE.GetValue(); } - virtual RString GetDisplayValue() - { - switch( g_ProfileSlot ) - { - case ProfileSlot_Machine: return "Machine"; - case ProfileSlot_Player1: return "Player 1"; - case ProfileSlot_Player2: return "Player 2"; - default: return RString(); - } - } - virtual bool IsEnabled() { return IsSelectProfilePersistent(); } - virtual RString GetPageName() const { return "Profiles"; } - virtual void DoAndLog( RString &sMessageOut ) - { - enum_add( g_ProfileSlot, +1 ); - if( g_ProfileSlot == NUM_ProfileSlot ) - g_ProfileSlot = ProfileSlot_Player1; - - IDebugLine::DoAndLog( sMessageOut ); - } -}; - - -class DebugLineClearProfileStats : public IDebugLine -{ - virtual RString GetDisplayTitle() { return CLEAR_PROFILE_STATS.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return IsSelectProfilePersistent(); } - virtual RString GetPageName() const { return "Profiles"; } - virtual void DoAndLog( RString &sMessageOut ) - { - Profile *pProfile = PROFILEMAN->GetProfile( g_ProfileSlot ); - pProfile->ClearStats(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -static HighScore MakeRandomHighScore( float fPercentDP ) -{ - HighScore hs; - hs.SetName( "FAKE" ); - Grade g = (Grade)SCALE( RandomInt(6), 0, 4, Grade_Tier01, Grade_Tier06 ); - if( g == Grade_Tier06 ) - g = Grade_Failed; - hs.SetGrade( g ); - hs.SetScore( RandomInt(100*1000) ); - hs.SetPercentDP( fPercentDP ); - hs.SetAliveSeconds( randomf(30.0f, 100.0f) ); - PlayerOptions po; - po.ChooseRandomModifiers(); - hs.SetModifiers( po.GetString() ); - hs.SetDateTime( DateTime::GetNowDateTime() ); - hs.SetPlayerGuid( Profile::MakeGuid() ); - hs.SetMachineGuid( Profile::MakeGuid() ); - hs.SetProductID( RandomInt(10) ); - FOREACH_ENUM( TapNoteScore, tns ) - hs.SetTapNoteScore( tns, RandomInt(100) ); - FOREACH_ENUM( HoldNoteScore, hns ) - hs.SetHoldNoteScore( hns, RandomInt(100) ); - RadarValues rv; - FOREACH_ENUM( RadarCategory, rc ) - rv.m_Values.f[rc] = randomf( 0, 1 ); - hs.SetRadarValues( rv ); - - return hs; -} - -static void FillProfileStats( Profile *pProfile ) -{ - pProfile->InitSongScores(); - pProfile->InitCourseScores(); - - static int s_iCount = 0; - // Choose a percent for all scores. This is useful for testing unlocks - // where some elements are unlocked at a certain percent complete. - float fPercentDP = s_iCount ? randomf( 0.6f, 1.0f ) : 1.0f; - s_iCount = (s_iCount+1)%2; - - - int iCount = pProfile->IsMachine()? - PREFSMAN->m_iMaxHighScoresPerListForMachine.Get(): - PREFSMAN->m_iMaxHighScoresPerListForPlayer.Get(); - - vector vpAllSongs = SONGMAN->GetAllSongs(); - FOREACH( Song*, vpAllSongs, pSong ) - { - vector vpAllSteps = (*pSong)->GetAllSteps(); - FOREACH( Steps*, vpAllSteps, pSteps ) - { - if( rand() % 5 ) - pProfile->IncrementStepsPlayCount( *pSong, *pSteps ); - for( int i=0; iAddStepsHighScore( *pSong, *pSteps, MakeRandomHighScore(fPercentDP), iIndex ); - } - } - } - - vector vpAllCourses; - SONGMAN->GetAllCourses( vpAllCourses, true ); - FOREACH( Course*, vpAllCourses, pCourse ) - { - vector vpAllTrails; - (*pCourse)->GetAllTrails( vpAllTrails ); - FOREACH( Trail*, vpAllTrails, pTrail ) - { - if( rand() % 5 ) - pProfile->IncrementCoursePlayCount( *pCourse, *pTrail ); - for( int i=0; iAddCourseHighScore( *pCourse, *pTrail, MakeRandomHighScore(fPercentDP), iIndex ); - } - } - } - - SCREENMAN->ZeroNextUpdate(); -} - -class DebugLineFillProfileStats : public IDebugLine -{ - virtual RString GetDisplayTitle() { return FILL_PROFILE_STATS.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return IsSelectProfilePersistent(); } - virtual RString GetPageName() const { return "Profiles"; } - virtual void DoAndLog( RString &sMessageOut ) - { - Profile* pProfile = PROFILEMAN->GetProfile( g_ProfileSlot ); - FillProfileStats( pProfile ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineSendNotesEnded : public IDebugLine -{ - virtual RString GetDisplayTitle() { return SEND_NOTES_ENDED.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineReloadCurrentScreen : public IDebugLine -{ - virtual RString GetDisplayTitle() { return RELOAD.GetValue(); } - virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } - virtual bool IsEnabled() { return true; } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - RString sScreenName = SCREENMAN->GetScreen(0)->GetName(); - SCREENMAN->PopAllScreens(); - - SOUND->StopMusic(); - StepMania::ResetGame(); - - SCREENMAN->SetNewScreen( sScreenName ); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut = ""; - } -}; - -class DebugLineRestartCurrentScreen : public IDebugLine -{ - virtual RString GetDisplayTitle() { return RESTART.GetValue(); } - virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } - virtual bool IsEnabled() { return true; } - virtual bool ForceOffAfterUse() const { return true; } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - SCREENMAN->GetTopScreen()->BeginScreen(); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut = ""; - } -}; - -class DebugLineCurrentScreenOn : public IDebugLine -{ - virtual RString GetDisplayTitle() { return SCREEN_ON.GetValue(); } - virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } - virtual bool IsEnabled() { return true; } - virtual bool ForceOffAfterUse() const { return true; } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - SCREENMAN->GetTopScreen()->PlayCommand("On"); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut = ""; - } -}; - -class DebugLineCurrentScreenOff : public IDebugLine -{ - virtual RString GetDisplayTitle() { return SCREEN_OFF.GetValue(); } - virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } - virtual bool IsEnabled() { return true; } - virtual bool ForceOffAfterUse() const { return true; } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - SCREENMAN->GetTopScreen()->PlayCommand("Off"); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut = ""; - } -}; - -class DebugLineReloadTheme : public IDebugLine -{ - virtual RString GetDisplayTitle() { return RELOAD_THEME_AND_TEXTURES.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual RString GetPageName() const { return "Theme"; } - virtual void DoAndLog( RString &sMessageOut ) - { - THEME->ReloadMetrics(); - TEXTUREMAN->ReloadAll(); - NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_pCurGame ); - CodeDetector::RefreshCacheItems(); - // HACK: Don't update text below. Return immediately because this screen - // was just destroyed as part of the theme reload. - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineWriteProfiles : public IDebugLine -{ - virtual RString GetDisplayTitle() { return WRITE_PROFILES.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return IsSelectProfilePersistent(); } - virtual RString GetPageName() const { return "Profiles"; } - virtual void DoAndLog( RString &sMessageOut ) - { - // Also save bookkeeping and profile info for debugging - // so we don't have to play through a whole song to get new output. - if( g_ProfileSlot == ProfileSlot_Machine ) - GAMESTATE->SaveLocalData(); - else - { - PlayerNumber pn = (PlayerNumber) g_ProfileSlot; - GAMESTATE->SaveCurrentSettingsToProfile(pn); - GAMESTATE->SavePlayerProfile( pn ); - } - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineWritePreferences : public IDebugLine -{ - virtual RString GetDisplayTitle() { return WRITE_PREFERENCES.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->SavePrefsToDisk(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineMenuTimer : public IDebugLine -{ - virtual RString GetDisplayTitle() { return MENU_TIMER.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return PREFSMAN->m_bMenuTimer.Get(); } - virtual void DoAndLog( RString &sMessageOut ) - { - PREFSMAN->m_bMenuTimer.Set( !PREFSMAN->m_bMenuTimer ); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineFlushLog : public IDebugLine -{ - virtual RString GetDisplayTitle() { return FLUSH_LOG.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - LOG->Flush(); - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLinePullBackCamera : public IDebugLine -{ - virtual RString GetDisplayTitle() { return PULL_BACK_CAMERA.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return g_fImageScaleDestination != 1; } - virtual void DoAndLog( RString &sMessageOut ) - { - if( g_fImageScaleDestination == 1 ) - g_fImageScaleDestination = 0.5f; - else - g_fImageScaleDestination = 1; - IDebugLine::DoAndLog( sMessageOut ); - } -}; - -class DebugLineVolumeUp : public IDebugLine -{ - virtual RString GetDisplayTitle() { return VOLUME_UP.GetValue(); } - virtual RString GetDisplayValue() { return ssprintf("%.0f%%", GetPref()->Get()*100); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - ChangeVolume( +0.1f ); - IDebugLine::DoAndLog( sMessageOut ); - } - Preference *GetPref() - { - return Preference::GetPreferenceByName("SoundVolume"); - } -}; - -class DebugLineVolumeDown : public IDebugLine -{ - virtual RString GetDisplayTitle() { return VOLUME_DOWN.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - ChangeVolume( -0.1f ); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut += " - " + ssprintf("%.0f%%",GetPref()->Get()*100); - } - Preference *GetPref() - { - return Preference::GetPreferenceByName("SoundVolume"); - } -}; - -class DebugLineVisualDelayUp : public IDebugLine -{ - virtual RString GetDisplayTitle() { return VISUAL_DELAY_UP.GetValue(); } - virtual RString GetDisplayValue() { return ssprintf("%.03f",GetPref()->Get()); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - ChangeVisualDelay( +0.001f ); - IDebugLine::DoAndLog( sMessageOut ); - } - Preference *GetPref() - { - return Preference::GetPreferenceByName("VisualDelaySeconds"); - } -}; - -class DebugLineVisualDelayDown : public IDebugLine -{ - virtual RString GetDisplayTitle() { return VISUAL_DELAY_DOWN.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return true; } - virtual void DoAndLog( RString &sMessageOut ) - { - ChangeVisualDelay( -0.001f ); - IDebugLine::DoAndLog( sMessageOut ); - sMessageOut += " - " + ssprintf("%.03f",GetPref()->Get()); - } - Preference *GetPref() - { - return Preference::GetPreferenceByName("VisualDelaySeconds"); - } -}; - -class DebugLineForceCrash : public IDebugLine -{ - virtual RString GetDisplayTitle() { return FORCE_CRASH.GetValue(); } - virtual RString GetDisplayValue() { return RString(); } - virtual bool IsEnabled() { return false; } - virtual void DoAndLog( RString &sMessageOut ) { FAIL_M("DebugLineCrash"); } -}; - -class DebugLineUptime : public IDebugLine -{ - virtual RString GetDisplayTitle() { return UPTIME.GetValue(); } - virtual RString GetDisplayValue() { return SecondsToMMSSMsMsMs(RageTimer::GetTimeSinceStart()); } - virtual bool IsEnabled() { return false; } - virtual void DoAndLog( RString &sMessageOut ) {} -}; - -/* #ifdef out the lines below if you don't want them to appear on certain - * platforms. This is easier than #ifdefing the whole DebugLine definitions - * that can span pages. - */ - -#define DECLARE_ONE( x ) static x g_##x -DECLARE_ONE( DebugLineAutoplay ); -DECLARE_ONE( DebugLineAssist ); -DECLARE_ONE( DebugLineAutosync ); -DECLARE_ONE( DebugLineCoinMode ); -DECLARE_ONE( DebugLineSlow ); -DECLARE_ONE( DebugLineHalt ); -DECLARE_ONE( DebugLineLightsDebug ); -DECLARE_ONE( DebugLineMonkeyInput ); -DECLARE_ONE( DebugLineStats ); -DECLARE_ONE( DebugLineVsync ); -DECLARE_ONE( DebugLineAllowMultitexture ); -DECLARE_ONE( DebugLineShowMasks ); -DECLARE_ONE( DebugLineProfileSlot ); -DECLARE_ONE( DebugLineClearProfileStats ); -DECLARE_ONE( DebugLineFillProfileStats ); -DECLARE_ONE( DebugLineSendNotesEnded ); -DECLARE_ONE( DebugLineReloadCurrentScreen ); -DECLARE_ONE( DebugLineRestartCurrentScreen ); -DECLARE_ONE( DebugLineCurrentScreenOn ); -DECLARE_ONE( DebugLineCurrentScreenOff ); -DECLARE_ONE( DebugLineReloadTheme ); -DECLARE_ONE( DebugLineWriteProfiles ); -DECLARE_ONE( DebugLineWritePreferences ); -DECLARE_ONE( DebugLineMenuTimer ); -DECLARE_ONE( DebugLineFlushLog ); -DECLARE_ONE( DebugLinePullBackCamera ); -DECLARE_ONE( DebugLineVolumeDown ); -DECLARE_ONE( DebugLineVolumeUp ); -DECLARE_ONE( DebugLineVisualDelayDown ); -DECLARE_ONE( DebugLineVisualDelayUp ); -DECLARE_ONE( DebugLineForceCrash ); -DECLARE_ONE( DebugLineUptime ); - - -/* - * (c) 2001-2005 Chris Danford, Glenn Maynard - * 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. - */ +#include "global.h" +#include "ScreenDebugOverlay.h" +#include "ScreenDimensions.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "GamePreferences.h" +#include "RageLog.h" +#include "GameState.h" +#include "PlayerState.h" +#include "StepMania.h" +#include "GameCommand.h" +#include "ScreenGameplay.h" +#include "RageSoundManager.h" +#include "GameSoundManager.h" +#include "RageTextureManager.h" +#include "MemoryCardManager.h" +#include "NoteSkinManager.h" +#include "Bookkeeper.h" +#include "ProfileManager.h" +#include "CodeDetector.h" +#include "RageInput.h" +#include "RageDisplay.h" +#include "InputEventPlus.h" +#include "LocalizedString.h" +#include "Profile.h" +#include "SongManager.h" +#include "GameLoop.h" +#include "Song.h" +#include "ScreenSyncOverlay.h" +#include "ThemeMetric.h" + +static bool g_bIsDisplayed = false; +static bool g_bIsSlow = false; +static bool g_bIsHalt = false; +static RageTimer g_HaltTimer(RageZeroTimer); +static float g_fImageScaleCurrent = 1; +static float g_fImageScaleDestination = 1; + +// DebugLine theming +static const ThemeMetric BACKGROUND_COLOR ("ScreenDebugOverlay", "BackgroundColor"); +static const ThemeMetric LINE_ON_COLOR ("ScreenDebugOverlay", "LineOnColor"); +static const ThemeMetric LINE_OFF_COLOR ("ScreenDebugOverlay", "LineOffColor"); +static const ThemeMetric LINE_START_Y ("ScreenDebugOverlay", "LineStartY"); +static const ThemeMetric LINE_SPACING ("ScreenDebugOverlay", "LineSpacing"); +static const ThemeMetric LINE_BUTTON_X ("ScreenDebugOverlay", "LineButtonX"); +static const ThemeMetric LINE_FUNCTION_X ("ScreenDebugOverlay", "LineFunctionX"); +static const ThemeMetric PAGE_START_X ("ScreenDebugOverlay", "PageStartX"); +static const ThemeMetric PAGE_SPACING_X ("ScreenDebugOverlay", "PageSpacingX"); + +// self-registering debug lines +// We don't use SubscriptionManager, because we want to keep the line order. +static LocalizedString ON ( "ScreenDebugOverlay", "on" ); +static LocalizedString OFF ( "ScreenDebugOverlay", "off" ); + +class IDebugLine; +static vector *g_pvpSubscribers = NULL; +class IDebugLine +{ +public: + IDebugLine() + { + if( g_pvpSubscribers == NULL ) + g_pvpSubscribers = new vector; + g_pvpSubscribers->push_back( this ); + } + virtual ~IDebugLine() { } + enum Type { all_screens, gameplay_only }; + virtual Type GetType() const { return all_screens; } + virtual RString GetDisplayTitle() = 0; + virtual RString GetDisplayValue() { return IsEnabled() ? ON.GetValue():OFF.GetValue(); } + virtual RString GetPageName() const { return "Main"; } + virtual bool ForceOffAfterUse() const { return false; } + virtual bool IsEnabled() = 0; + virtual void DoAndLog( RString &sMessageOut ) + { + RString s1 = GetDisplayTitle(); + RString s2 = GetDisplayValue(); + if( !s2.empty() ) + s1 += " - "; + sMessageOut = s1 + s2; + }; + + DeviceInput m_Button; +}; + +static bool IsGameplay() +{ + return SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == gameplay; +} + + +REGISTER_SCREEN_CLASS( ScreenDebugOverlay ); + +ScreenDebugOverlay::~ScreenDebugOverlay() +{ + this->RemoveAllChildren(); + + FOREACH( BitmapText*, m_vptextPages, p ) + SAFE_DELETE( *p ); + FOREACH( BitmapText*, m_vptextButton, p ) + SAFE_DELETE( *p ); + m_vptextButton.clear(); + FOREACH( BitmapText*, m_vptextFunction, p ) + SAFE_DELETE( *p ); + m_vptextFunction.clear(); +} + +const int MAX_DEBUG_LINES = 30; +struct MapDebugToDI +{ + DeviceInput holdForDebug1; + DeviceInput holdForDebug2; + DeviceInput holdForSlow; + DeviceInput holdForFast; + DeviceInput debugButton[MAX_DEBUG_LINES]; + DeviceInput gameplayButton[MAX_DEBUG_LINES]; + map pageButton; + void Clear() + { + holdForDebug1.MakeInvalid(); + holdForDebug2.MakeInvalid(); + holdForSlow.MakeInvalid(); + holdForFast.MakeInvalid(); + for( int i=0; iGetDeviceSpecificInputString(pLine->m_Button); + switch( pLine->GetType() ) + { + case IDebugLine::all_screens: + return s; + case IDebugLine::gameplay_only: + return ssprintf( IN_GAMEPLAY.GetValue(), s.c_str() ); + default: + ASSERT(0); + } +} + +template +static bool GetKeyFromMap( const map &m, const V &val, U &key ) +{ + for( typename map::const_iterator iter = m.begin(); iter != m.end(); ++iter ) + { + if( iter->second == val ) + { + key = iter->first; + return true; + } + } + return false; +} + +static LocalizedString DEBUG_MENU( "ScreenDebugOverlay", "Debug Menu" ); +void ScreenDebugOverlay::Init() +{ + Screen::Init(); + + // Init debug mappings + // TODO: Arch-specific? + { + g_Mappings.Clear(); + + g_Mappings.holdForDebug1 = DeviceInput(DEVICE_KEYBOARD, KEY_F3); + g_Mappings.holdForDebug2.MakeInvalid(); + g_Mappings.holdForSlow = DeviceInput(DEVICE_KEYBOARD, KEY_ACCENT); + g_Mappings.holdForFast = DeviceInput(DEVICE_KEYBOARD, KEY_TAB); + + /* TODO: Find a better way of indicating which option is which here. + * Maybe we should take a page from ScreenEdit's menus and make + * RowDefs()? */ + + int i=0; + g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F8); + g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F7); + g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F6); + i=0; + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C1); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C2); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C3); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C4); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C5); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C6); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C7); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C8); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C9); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C0); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cq); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cw); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ce); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cr); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cy); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cu); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ci); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Co); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cp); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_UP); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_DOWN); + g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_BACK); + g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F5)] = 0; + g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F6)] = 1; + g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F7)] = 2; + g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F8)] = 3; + } + + map iNextDebugButton; + int iNextGameplayButton = 0; + FOREACH( IDebugLine*, *g_pvpSubscribers, p ) + { + RString sPageName = (*p)->GetPageName(); + + DeviceInput di; + switch( (*p)->GetType() ) + { + case IDebugLine::all_screens: + di = g_Mappings.debugButton[iNextDebugButton[sPageName]++]; + break; + case IDebugLine::gameplay_only: + di = g_Mappings.gameplayButton[iNextGameplayButton++]; + break; + } + (*p)->m_Button = di; + + if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() ) + m_asPages.push_back( sPageName ); + } + + m_iCurrentPage = 0; + m_bForcedHidden = false; + + m_Quad.StretchTo( RectF( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ) ); + m_Quad.SetDiffuse( BACKGROUND_COLOR ); + this->AddChild( &m_Quad ); + + // if you're going to add user commands, make sure to have the overrides + // set after parsing the metrics. -aj + m_textHeader.SetName( "HeaderText" ); + m_textHeader.LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "header") ); + LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textHeader ); + m_textHeader.SetText( DEBUG_MENU ); + this->AddChild( &m_textHeader ); + + FOREACH_CONST( RString, m_asPages, s ) + { + int iPage = s - m_asPages.begin(); + + DeviceInput di; + bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di ); + ASSERT( b ); + + RString sButton = INPUTMAN->GetDeviceSpecificInputString( di ); + + BitmapText *p = new BitmapText; + p->SetName( "PageText" ); + p->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "page") ); + LOAD_ALL_COMMANDS_AND_ON_COMMAND( p ); + // todo: Y value is still hardcoded. -aj + p->SetXY( PAGE_START_X+iPage*PAGE_SPACING_X, SCREEN_TOP+20 ); + p->SetText( *s + " (" + sButton + ")" ); + m_vptextPages.push_back( p ); + this->AddChild( p ); + } + + FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + { + { + BitmapText *bt = new BitmapText; + bt->SetName( "ButtonText" ); + bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") ); + bt->SetHorizAlign( align_right ); + bt->SetText( "blah" ); + LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt ); + m_vptextButton.push_back( bt ); + this->AddChild( bt ); + } + { + BitmapText *bt = new BitmapText; + bt->SetName( "FunctionText" ); + bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") ); + bt->SetHorizAlign( align_left ); + bt->SetText( "blah" ); + LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt ); + m_vptextFunction.push_back( bt ); + this->AddChild( bt ); + } + } + + this->SetVisible( false ); +} + +void ScreenDebugOverlay::Update( float fDeltaTime ) +{ + { + float fRate = 1; + if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForFast) ) + { + if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) ) + fRate = 0; // both; stop time + else + fRate *= 4; + } + else if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) ) + { + fRate /= 4; + } + + if( g_bIsHalt ) + fRate = 0; + else if( g_bIsSlow ) + fRate /= 4; + + GameLoop::SetUpdateRate( fRate ); + } + + bool bCenteringNeedsUpdate = g_fImageScaleCurrent != g_fImageScaleDestination; + fapproach( g_fImageScaleCurrent, g_fImageScaleDestination, fDeltaTime ); + if( bCenteringNeedsUpdate ) + { + DISPLAY->ChangeCentering( + PREFSMAN->m_iCenterImageTranslateX, + PREFSMAN->m_iCenterImageTranslateY, + PREFSMAN->m_fCenterImageAddWidth - (int)SCREEN_WIDTH + (int)(g_fImageScaleCurrent*SCREEN_WIDTH), + PREFSMAN->m_fCenterImageAddHeight - (int)SCREEN_HEIGHT + (int)(g_fImageScaleCurrent*SCREEN_HEIGHT) ); + } + + Screen::Update(fDeltaTime); + + this->SetVisible( g_bIsDisplayed && !m_bForcedHidden ); + if( !g_bIsDisplayed ) + return; + + UpdateText(); +} + +void ScreenDebugOverlay::UpdateText() +{ + FOREACH_CONST( RString, m_asPages, s ) + { + int iPage = s - m_asPages.begin(); + m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" ); + } + + // todo: allow changing of various spacing/location things -aj + int iOffset = 0; + FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + { + RString sPageName = (*p)->GetPageName(); + + int i = p-g_pvpSubscribers->begin(); + + float fY = LINE_START_Y + iOffset * LINE_SPACING; + + BitmapText &txt1 = *m_vptextButton[i]; + BitmapText &txt2 = *m_vptextFunction[i]; + if( sPageName != GetCurrentPageName() ) + { + txt1.SetVisible( false ); + txt2.SetVisible( false ); + continue; + } + txt1.SetVisible( true ); + txt2.SetVisible( true ); + ++iOffset; + + txt1.SetX( LINE_BUTTON_X ); + txt1.SetY( fY ); + + txt2.SetX( LINE_FUNCTION_X ); + txt2.SetY( fY ); + + RString s1 = (*p)->GetDisplayTitle(); + RString s2 = (*p)->GetDisplayValue(); + + bool bOn = (*p)->IsEnabled(); + + txt1.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR ); + txt2.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR ); + + RString sButton = GetDebugButtonName( *p ); + if( !sButton.empty() ) + sButton += ": "; + txt1.SetText( sButton ); + if( !s2.empty() ) + s1 += " - "; + txt2.SetText( s1 + s2 ); + } + + if( g_bIsHalt ) + { + /* More than once I've paused the game accidentally and wasted time + * figuring out why, so warn. */ + if( g_HaltTimer.Ago() >= 5.0f ) + { + g_HaltTimer.Touch(); + LOG->Warn( "Game halted" ); + } + } +} + +template +static bool GetValueFromMap( const map &m, const U &key, V &val ) +{ + typename map::const_iterator it = m.find(key); + if( it == m.end() ) + return false; + val = it->second; + return true; +} + +bool ScreenDebugOverlay::OverlayInput( const InputEventPlus &input ) +{ + if( input.DeviceI == g_Mappings.holdForDebug1 || + input.DeviceI == g_Mappings.holdForDebug2 ) + { + bool bHoldingNeither = + (!g_Mappings.holdForDebug1.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) && + (!g_Mappings.holdForDebug2.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2)); + bool bHoldingBoth = + (!g_Mappings.holdForDebug1.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) && + (!g_Mappings.holdForDebug2.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2)); + if( bHoldingNeither ) + m_bForcedHidden = false; + + if( bHoldingBoth ) + g_bIsDisplayed = true; + else + g_bIsDisplayed = false; + } + + int iPage = 0; + if( g_bIsDisplayed && GetValueFromMap(g_Mappings.pageButton, input.DeviceI, iPage) ) + { + if( input.type != IET_FIRST_PRESS ) + return true; // eat the input but do nothing + m_iCurrentPage = iPage; + CLAMP( m_iCurrentPage, 0, (int) m_asPages.size()-1 ); + return true; + } + + FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + { + RString sPageName = (*p)->GetPageName(); + + int i = p-g_pvpSubscribers->begin(); + + // Gameplay buttons are available only in gameplay. Non-gameplay buttons + // are only available when the screen is displayed. + switch( (*p)->GetType() ) + { + case IDebugLine::all_screens: + if( !g_bIsDisplayed ) + continue; + if( sPageName != GetCurrentPageName() ) + continue; + break; + case IDebugLine::gameplay_only: + if( !IsGameplay() ) + continue; + break; + default: + ASSERT(0); + } + + if( input.DeviceI == (*p)->m_Button ) + { + if( input.type != IET_FIRST_PRESS ) + return true; // eat the input but do nothing + + // do the action + RString sMessage; + (*p)->DoAndLog( sMessage ); + if( !sMessage.empty() ) + LOG->Trace("DEBUG: %s", sMessage.c_str() ); + if( (*p)->ForceOffAfterUse() ) + m_bForcedHidden = true; + + // update text to show the effect of what changed above + UpdateText(); + + // show what changed + BitmapText &bt = *m_vptextButton[i]; + bt.FinishTweening(); + bt.PlayCommand("Toggled"); + + return true; + } + } + + return false; +} + + +// DebugLine helpers +static void SetSpeed() +{ + // PauseMusic( g_bIsHalt ); +} + +void ChangeVolume( float fDelta ) +{ + Preference *pRet = Preference::GetPreferenceByName("SoundVolume"); + float fVol = pRet->Get(); + fVol += fDelta; + CLAMP( fVol, 0.0f, 1.0f ); + pRet->Set( fVol ); + SOUNDMAN->SetMixVolume(); +} + +void ChangeVisualDelay( float fDelta ) +{ + Preference *pRet = Preference::GetPreferenceByName("VisualDelaySeconds"); + float fSecs = pRet->Get(); + fSecs += fDelta; + CLAMP( fSecs, -1.0f, 1.0f ); + pRet->Set( fSecs ); +} + +// DebugLines +static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" ); +static LocalizedString ASSIST ( "ScreenDebugOverlay", "Assist" ); +static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" ); +static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" ); +static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" ); +static LocalizedString LIGHTS_DEBUG ( "ScreenDebugOverlay", "Lights Debug" ); +static LocalizedString MONKEY_INPUT ( "ScreenDebugOverlay", "Monkey Input" ); +static LocalizedString RENDERING_STATS ( "ScreenDebugOverlay", "Rendering Stats" ); +static LocalizedString VSYNC ( "ScreenDebugOverlay", "Vsync" ); +static LocalizedString MULTITEXTURE ( "ScreenDebugOverlay", "Multitexture" ); +static LocalizedString SCREEN_TEST_MODE ( "ScreenDebugOverlay", "Screen Test Mode" ); +static LocalizedString SCREEN_SHOW_MASKS ( "ScreenDebugOverlay", "Show Masks" ); +static LocalizedString PROFILE ( "ScreenDebugOverlay", "Profile" ); +static LocalizedString CLEAR_PROFILE_STATS ( "ScreenDebugOverlay", "Clear Profile Stats" ); +static LocalizedString FILL_PROFILE_STATS ( "ScreenDebugOverlay", "Fill Profile Stats" ); +static LocalizedString SEND_NOTES_ENDED ( "ScreenDebugOverlay", "Send Notes Ended" ); +static LocalizedString RELOAD ( "ScreenDebugOverlay", "Reload" ); +static LocalizedString RESTART ( "ScreenDebugOverlay", "Restart" ); +static LocalizedString SCREEN_ON ( "ScreenDebugOverlay", "Send On To Screen" ); +static LocalizedString SCREEN_OFF ( "ScreenDebugOverlay", "Send Off To Screen" ); +static LocalizedString RELOAD_THEME_AND_TEXTURES( "ScreenDebugOverlay", "Reload Theme and Textures" ); +static LocalizedString WRITE_PROFILES ( "ScreenDebugOverlay", "Write Profiles" ); +static LocalizedString WRITE_PREFERENCES ( "ScreenDebugOverlay", "Write Preferences" ); +static LocalizedString MENU_TIMER ( "ScreenDebugOverlay", "Menu Timer" ); +static LocalizedString FLUSH_LOG ( "ScreenDebugOverlay", "Flush Log" ); +static LocalizedString PULL_BACK_CAMERA ( "ScreenDebugOverlay", "Pull Back Camera" ); +static LocalizedString VISUAL_DELAY_UP ( "ScreenDebugOverlay", "Visual Delay Up" ); +static LocalizedString VISUAL_DELAY_DOWN ( "ScreenDebugOverlay", "Visual Delay Down" ); +static LocalizedString VOLUME_UP ( "ScreenDebugOverlay", "Volume Up" ); +static LocalizedString VOLUME_DOWN ( "ScreenDebugOverlay", "Volume Down" ); +static LocalizedString UPTIME ( "ScreenDebugOverlay", "Uptime" ); +static LocalizedString FORCE_CRASH ( "ScreenDebugOverlay", "Force Crash" ); +static LocalizedString SLOW ( "ScreenDebugOverlay", "Slow" ); +static LocalizedString CPU ( "ScreenDebugOverlay", "CPU" ); +static LocalizedString SONG ( "ScreenDebugOverlay", "Song" ); +static LocalizedString MACHINE ( "ScreenDebugOverlay", "Machine" ); +static LocalizedString SYNC_TEMPO ( "ScreenDebugOverlay", "Tempo" ); + +class DebugLineAutoplay : public IDebugLine +{ + virtual RString GetDisplayTitle() { return AUTO_PLAY.GetValue() + " (+Shift = AI) (+Alt = hide)"; } + virtual RString GetDisplayValue() + { + switch( GamePreferences::m_AutoPlay.Get() ) + { + case PC_HUMAN: return OFF.GetValue(); break; + case PC_AUTOPLAY: return ON.GetValue(); break; + case PC_CPU: return CPU.GetValue(); break; + default: ASSERT(0); return RString(); + } + } + virtual Type GetType() const { return IDebugLine::gameplay_only; } + virtual bool IsEnabled() { return GamePreferences::m_AutoPlay.Get() != PC_HUMAN; } + virtual void DoAndLog( RString &sMessageOut ) + { + ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID ); + PlayerController pc = GAMESTATE->m_pPlayerState[GAMESTATE->GetMasterPlayerNumber()]->m_PlayerController; + bool bHoldingShift = + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT) ); + if( bHoldingShift ) + pc = (pc==PC_CPU) ? PC_HUMAN : PC_CPU; + else + pc = (pc==PC_AUTOPLAY) ? PC_HUMAN : PC_AUTOPLAY; + GamePreferences::m_AutoPlay.Set( pc ); + FOREACH_HumanPlayer(p) + GAMESTATE->m_pPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay; + FOREACH_MultiPlayer(p) + GAMESTATE->m_pMultiPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay; + + // Hide Autoplay if Alt is held down + bool bHoldingAlt = + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT) ) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT) ); + ScreenSyncOverlay::SetShowAutoplay( !bHoldingAlt ); + + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineAssist : public IDebugLine +{ + virtual RString GetDisplayTitle() { return ASSIST.GetValue(); } + virtual Type GetType() const { return gameplay_only; } + virtual RString GetDisplayValue() { + SongOptions so; + so.m_bAssistClap = GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; + so.m_bAssistMetronome = GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; + if( so.m_bAssistClap || so.m_bAssistMetronome ) + return so.GetLocalizedString(); + else + return OFF.GetValue(); + } + virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistClap || GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; } + virtual void DoAndLog( RString &sMessageOut ) + { + ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID ); + bool bHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ); + bool b; + if( bHoldingShift ) + b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; + else + b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; + if( bHoldingShift ) + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistMetronome, b ); + else + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistClap, b ); + + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineAutosync : public IDebugLine +{ + virtual RString GetDisplayTitle() { return AUTOSYNC.GetValue(); } + virtual RString GetDisplayValue() + { + switch( GAMESTATE->m_SongOptions.GetSong().m_AutosyncType ) + { + case SongOptions::AUTOSYNC_OFF: return OFF.GetValue(); break; + case SongOptions::AUTOSYNC_SONG: return SONG.GetValue(); break; + case SongOptions::AUTOSYNC_MACHINE: return MACHINE.GetValue(); break; + case SongOptions::AUTOSYNC_TEMPO: return SYNC_TEMPO.GetValue(); break; + default: ASSERT(0); + } + } + virtual Type GetType() const { return IDebugLine::gameplay_only; } + virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_AutosyncType!=SongOptions::AUTOSYNC_OFF; } + virtual void DoAndLog( RString &sMessageOut ) + { + int as = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType + 1; + bool bAllowSongAutosync = !GAMESTATE->IsCourseMode(); + if( !bAllowSongAutosync && + ( as == SongOptions::AUTOSYNC_SONG || as == SongOptions::AUTOSYNC_TEMPO ) ) + as = SongOptions::AUTOSYNC_MACHINE; + wrap( as, SongOptions::NUM_AUTOSYNC_TYPES ); + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_AutosyncType, SongOptions::AutosyncType(as) ); + MESSAGEMAN->Broadcast( Message_AutosyncChanged ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineCoinMode : public IDebugLine +{ + virtual RString GetDisplayTitle() { return COIN_MODE.GetValue(); } + virtual RString GetDisplayValue() { return CoinModeToString(GamePreferences::m_CoinMode); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + int cm = GamePreferences::m_CoinMode+1; + wrap( cm, NUM_CoinMode ); + GamePreferences::m_CoinMode.Set( CoinMode(cm) ); + SCREENMAN->RefreshCreditsMessages(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineSlow : public IDebugLine +{ + virtual RString GetDisplayTitle() { return SLOW.GetValue(); } + virtual bool IsEnabled() { return g_bIsSlow; } + virtual void DoAndLog( RString &sMessageOut ) + { + g_bIsSlow = !g_bIsSlow; + SetSpeed(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineHalt : public IDebugLine +{ + virtual RString GetDisplayTitle() { return HALT.GetValue(); } + virtual bool IsEnabled() { return g_bIsHalt; } + virtual void DoAndLog( RString &sMessageOut ) + { + g_bIsHalt = !g_bIsHalt; + g_HaltTimer.Touch(); + SetSpeed(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineLightsDebug : public IDebugLine +{ + virtual RString GetDisplayTitle() { return LIGHTS_DEBUG.GetValue(); } + virtual bool IsEnabled() { return PREFSMAN->m_bDebugLights.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bDebugLights.Set( !PREFSMAN->m_bDebugLights ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineMonkeyInput : public IDebugLine +{ + virtual RString GetDisplayTitle() { return MONKEY_INPUT.GetValue(); } + virtual bool IsEnabled() { return PREFSMAN->m_bMonkeyInput.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bMonkeyInput.Set( !PREFSMAN->m_bMonkeyInput ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineStats : public IDebugLine +{ + virtual RString GetDisplayTitle() { return RENDERING_STATS.GetValue(); } + virtual bool IsEnabled() { return PREFSMAN->m_bShowStats.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bShowStats.Set( !PREFSMAN->m_bShowStats ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineVsync : public IDebugLine +{ + virtual RString GetDisplayTitle() { return VSYNC.GetValue(); } + virtual bool IsEnabled() { return PREFSMAN->m_bVsync.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bVsync.Set( !PREFSMAN->m_bVsync ); + StepMania::ApplyGraphicOptions(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineAllowMultitexture : public IDebugLine +{ + virtual RString GetDisplayTitle() { return MULTITEXTURE.GetValue(); } + virtual bool IsEnabled() { return PREFSMAN->m_bAllowMultitexture.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bAllowMultitexture.Set( !PREFSMAN->m_bAllowMultitexture ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineShowMasks : public IDebugLine +{ + virtual RString GetDisplayTitle() { return SCREEN_SHOW_MASKS.GetValue(); } + virtual bool IsEnabled() { return GetPref()->Get(); } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + GetPref()->Set( !GetPref()->Get() ); + IDebugLine::DoAndLog( sMessageOut ); + } + + Preference *GetPref() + { + return Preference::GetPreferenceByName("ShowMasks"); + } +}; + +static ProfileSlot g_ProfileSlot = ProfileSlot_Machine; +static bool IsSelectProfilePersistent() +{ + if( g_ProfileSlot == ProfileSlot_Machine ) + return true; + return PROFILEMAN->IsPersistentProfile( (PlayerNumber) g_ProfileSlot ); +} + +class DebugLineProfileSlot : public IDebugLine +{ + virtual RString GetDisplayTitle() { return PROFILE.GetValue(); } + virtual RString GetDisplayValue() + { + switch( g_ProfileSlot ) + { + case ProfileSlot_Machine: return "Machine"; + case ProfileSlot_Player1: return "Player 1"; + case ProfileSlot_Player2: return "Player 2"; + default: return RString(); + } + } + virtual bool IsEnabled() { return IsSelectProfilePersistent(); } + virtual RString GetPageName() const { return "Profiles"; } + virtual void DoAndLog( RString &sMessageOut ) + { + enum_add( g_ProfileSlot, +1 ); + if( g_ProfileSlot == NUM_ProfileSlot ) + g_ProfileSlot = ProfileSlot_Player1; + + IDebugLine::DoAndLog( sMessageOut ); + } +}; + + +class DebugLineClearProfileStats : public IDebugLine +{ + virtual RString GetDisplayTitle() { return CLEAR_PROFILE_STATS.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return IsSelectProfilePersistent(); } + virtual RString GetPageName() const { return "Profiles"; } + virtual void DoAndLog( RString &sMessageOut ) + { + Profile *pProfile = PROFILEMAN->GetProfile( g_ProfileSlot ); + pProfile->ClearStats(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +static HighScore MakeRandomHighScore( float fPercentDP ) +{ + HighScore hs; + hs.SetName( "FAKE" ); + Grade g = (Grade)SCALE( RandomInt(6), 0, 4, Grade_Tier01, Grade_Tier06 ); + if( g == Grade_Tier06 ) + g = Grade_Failed; + hs.SetGrade( g ); + hs.SetScore( RandomInt(100*1000) ); + hs.SetPercentDP( fPercentDP ); + hs.SetAliveSeconds( randomf(30.0f, 100.0f) ); + PlayerOptions po; + po.ChooseRandomModifiers(); + hs.SetModifiers( po.GetString() ); + hs.SetDateTime( DateTime::GetNowDateTime() ); + hs.SetPlayerGuid( Profile::MakeGuid() ); + hs.SetMachineGuid( Profile::MakeGuid() ); + hs.SetProductID( RandomInt(10) ); + FOREACH_ENUM( TapNoteScore, tns ) + hs.SetTapNoteScore( tns, RandomInt(100) ); + FOREACH_ENUM( HoldNoteScore, hns ) + hs.SetHoldNoteScore( hns, RandomInt(100) ); + RadarValues rv; + FOREACH_ENUM( RadarCategory, rc ) + rv.m_Values.f[rc] = randomf( 0, 1 ); + hs.SetRadarValues( rv ); + + return hs; +} + +static void FillProfileStats( Profile *pProfile ) +{ + pProfile->InitSongScores(); + pProfile->InitCourseScores(); + + static int s_iCount = 0; + // Choose a percent for all scores. This is useful for testing unlocks + // where some elements are unlocked at a certain percent complete. + float fPercentDP = s_iCount ? randomf( 0.6f, 1.0f ) : 1.0f; + s_iCount = (s_iCount+1)%2; + + + int iCount = pProfile->IsMachine()? + PREFSMAN->m_iMaxHighScoresPerListForMachine.Get(): + PREFSMAN->m_iMaxHighScoresPerListForPlayer.Get(); + + vector vpAllSongs = SONGMAN->GetAllSongs(); + FOREACH( Song*, vpAllSongs, pSong ) + { + vector vpAllSteps = (*pSong)->GetAllSteps(); + FOREACH( Steps*, vpAllSteps, pSteps ) + { + if( rand() % 5 ) + pProfile->IncrementStepsPlayCount( *pSong, *pSteps ); + for( int i=0; iAddStepsHighScore( *pSong, *pSteps, MakeRandomHighScore(fPercentDP), iIndex ); + } + } + } + + vector vpAllCourses; + SONGMAN->GetAllCourses( vpAllCourses, true ); + FOREACH( Course*, vpAllCourses, pCourse ) + { + vector vpAllTrails; + (*pCourse)->GetAllTrails( vpAllTrails ); + FOREACH( Trail*, vpAllTrails, pTrail ) + { + if( rand() % 5 ) + pProfile->IncrementCoursePlayCount( *pCourse, *pTrail ); + for( int i=0; iAddCourseHighScore( *pCourse, *pTrail, MakeRandomHighScore(fPercentDP), iIndex ); + } + } + } + + SCREENMAN->ZeroNextUpdate(); +} + +class DebugLineFillProfileStats : public IDebugLine +{ + virtual RString GetDisplayTitle() { return FILL_PROFILE_STATS.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return IsSelectProfilePersistent(); } + virtual RString GetPageName() const { return "Profiles"; } + virtual void DoAndLog( RString &sMessageOut ) + { + Profile* pProfile = PROFILEMAN->GetProfile( g_ProfileSlot ); + FillProfileStats( pProfile ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineSendNotesEnded : public IDebugLine +{ + virtual RString GetDisplayTitle() { return SEND_NOTES_ENDED.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineReloadCurrentScreen : public IDebugLine +{ + virtual RString GetDisplayTitle() { return RELOAD.GetValue(); } + virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } + virtual bool IsEnabled() { return true; } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + RString sScreenName = SCREENMAN->GetScreen(0)->GetName(); + SCREENMAN->PopAllScreens(); + + SOUND->StopMusic(); + StepMania::ResetGame(); + + SCREENMAN->SetNewScreen( sScreenName ); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut = ""; + } +}; + +class DebugLineRestartCurrentScreen : public IDebugLine +{ + virtual RString GetDisplayTitle() { return RESTART.GetValue(); } + virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } + virtual bool IsEnabled() { return true; } + virtual bool ForceOffAfterUse() const { return true; } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + SCREENMAN->GetTopScreen()->BeginScreen(); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut = ""; + } +}; + +class DebugLineCurrentScreenOn : public IDebugLine +{ + virtual RString GetDisplayTitle() { return SCREEN_ON.GetValue(); } + virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } + virtual bool IsEnabled() { return true; } + virtual bool ForceOffAfterUse() const { return true; } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + SCREENMAN->GetTopScreen()->PlayCommand("On"); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut = ""; + } +}; + +class DebugLineCurrentScreenOff : public IDebugLine +{ + virtual RString GetDisplayTitle() { return SCREEN_OFF.GetValue(); } + virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); } + virtual bool IsEnabled() { return true; } + virtual bool ForceOffAfterUse() const { return true; } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + SCREENMAN->GetTopScreen()->PlayCommand("Off"); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut = ""; + } +}; + +class DebugLineReloadTheme : public IDebugLine +{ + virtual RString GetDisplayTitle() { return RELOAD_THEME_AND_TEXTURES.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual RString GetPageName() const { return "Theme"; } + virtual void DoAndLog( RString &sMessageOut ) + { + THEME->ReloadMetrics(); + TEXTUREMAN->ReloadAll(); + NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_pCurGame ); + CodeDetector::RefreshCacheItems(); + // HACK: Don't update text below. Return immediately because this screen + // was just destroyed as part of the theme reload. + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineWriteProfiles : public IDebugLine +{ + virtual RString GetDisplayTitle() { return WRITE_PROFILES.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return IsSelectProfilePersistent(); } + virtual RString GetPageName() const { return "Profiles"; } + virtual void DoAndLog( RString &sMessageOut ) + { + // Also save bookkeeping and profile info for debugging + // so we don't have to play through a whole song to get new output. + if( g_ProfileSlot == ProfileSlot_Machine ) + GAMESTATE->SaveLocalData(); + else + { + PlayerNumber pn = (PlayerNumber) g_ProfileSlot; + GAMESTATE->SaveCurrentSettingsToProfile(pn); + GAMESTATE->SavePlayerProfile( pn ); + } + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineWritePreferences : public IDebugLine +{ + virtual RString GetDisplayTitle() { return WRITE_PREFERENCES.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->SavePrefsToDisk(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineMenuTimer : public IDebugLine +{ + virtual RString GetDisplayTitle() { return MENU_TIMER.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return PREFSMAN->m_bMenuTimer.Get(); } + virtual void DoAndLog( RString &sMessageOut ) + { + PREFSMAN->m_bMenuTimer.Set( !PREFSMAN->m_bMenuTimer ); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineFlushLog : public IDebugLine +{ + virtual RString GetDisplayTitle() { return FLUSH_LOG.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + LOG->Flush(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLinePullBackCamera : public IDebugLine +{ + virtual RString GetDisplayTitle() { return PULL_BACK_CAMERA.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return g_fImageScaleDestination != 1; } + virtual void DoAndLog( RString &sMessageOut ) + { + if( g_fImageScaleDestination == 1 ) + g_fImageScaleDestination = 0.5f; + else + g_fImageScaleDestination = 1; + IDebugLine::DoAndLog( sMessageOut ); + } +}; + +class DebugLineVolumeUp : public IDebugLine +{ + virtual RString GetDisplayTitle() { return VOLUME_UP.GetValue(); } + virtual RString GetDisplayValue() { return ssprintf("%.0f%%", GetPref()->Get()*100); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + ChangeVolume( +0.1f ); + IDebugLine::DoAndLog( sMessageOut ); + } + Preference *GetPref() + { + return Preference::GetPreferenceByName("SoundVolume"); + } +}; + +class DebugLineVolumeDown : public IDebugLine +{ + virtual RString GetDisplayTitle() { return VOLUME_DOWN.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + ChangeVolume( -0.1f ); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut += " - " + ssprintf("%.0f%%",GetPref()->Get()*100); + } + Preference *GetPref() + { + return Preference::GetPreferenceByName("SoundVolume"); + } +}; + +class DebugLineVisualDelayUp : public IDebugLine +{ + virtual RString GetDisplayTitle() { return VISUAL_DELAY_UP.GetValue(); } + virtual RString GetDisplayValue() { return ssprintf("%.03f",GetPref()->Get()); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + ChangeVisualDelay( +0.001f ); + IDebugLine::DoAndLog( sMessageOut ); + } + Preference *GetPref() + { + return Preference::GetPreferenceByName("VisualDelaySeconds"); + } +}; + +class DebugLineVisualDelayDown : public IDebugLine +{ + virtual RString GetDisplayTitle() { return VISUAL_DELAY_DOWN.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + ChangeVisualDelay( -0.001f ); + IDebugLine::DoAndLog( sMessageOut ); + sMessageOut += " - " + ssprintf("%.03f",GetPref()->Get()); + } + Preference *GetPref() + { + return Preference::GetPreferenceByName("VisualDelaySeconds"); + } +}; + +class DebugLineForceCrash : public IDebugLine +{ + virtual RString GetDisplayTitle() { return FORCE_CRASH.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return false; } + virtual void DoAndLog( RString &sMessageOut ) { FAIL_M("DebugLineCrash"); } +}; + +class DebugLineUptime : public IDebugLine +{ + virtual RString GetDisplayTitle() { return UPTIME.GetValue(); } + virtual RString GetDisplayValue() { return SecondsToMMSSMsMsMs(RageTimer::GetTimeSinceStart()); } + virtual bool IsEnabled() { return false; } + virtual void DoAndLog( RString &sMessageOut ) {} +}; + +/* #ifdef out the lines below if you don't want them to appear on certain + * platforms. This is easier than #ifdefing the whole DebugLine definitions + * that can span pages. + */ + +#define DECLARE_ONE( x ) static x g_##x +DECLARE_ONE( DebugLineAutoplay ); +DECLARE_ONE( DebugLineAssist ); +DECLARE_ONE( DebugLineAutosync ); +DECLARE_ONE( DebugLineCoinMode ); +DECLARE_ONE( DebugLineSlow ); +DECLARE_ONE( DebugLineHalt ); +DECLARE_ONE( DebugLineLightsDebug ); +DECLARE_ONE( DebugLineMonkeyInput ); +DECLARE_ONE( DebugLineStats ); +DECLARE_ONE( DebugLineVsync ); +DECLARE_ONE( DebugLineAllowMultitexture ); +DECLARE_ONE( DebugLineShowMasks ); +DECLARE_ONE( DebugLineProfileSlot ); +DECLARE_ONE( DebugLineClearProfileStats ); +DECLARE_ONE( DebugLineFillProfileStats ); +DECLARE_ONE( DebugLineSendNotesEnded ); +DECLARE_ONE( DebugLineReloadCurrentScreen ); +DECLARE_ONE( DebugLineRestartCurrentScreen ); +DECLARE_ONE( DebugLineCurrentScreenOn ); +DECLARE_ONE( DebugLineCurrentScreenOff ); +DECLARE_ONE( DebugLineReloadTheme ); +DECLARE_ONE( DebugLineWriteProfiles ); +DECLARE_ONE( DebugLineWritePreferences ); +DECLARE_ONE( DebugLineMenuTimer ); +DECLARE_ONE( DebugLineFlushLog ); +DECLARE_ONE( DebugLinePullBackCamera ); +DECLARE_ONE( DebugLineVolumeDown ); +DECLARE_ONE( DebugLineVolumeUp ); +DECLARE_ONE( DebugLineVisualDelayDown ); +DECLARE_ONE( DebugLineVisualDelayUp ); +DECLARE_ONE( DebugLineForceCrash ); +DECLARE_ONE( DebugLineUptime ); + + +/* + * (c) 2001-2005 Chris Danford, Glenn Maynard + * 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. + */