From d67d60e178b36a0d6c7085f11760d2b0431f203b Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 19 May 2005 23:29:39 +0000 Subject: [PATCH] sync controls cleanup: move sync display/saving out of complicated ScreenGameplay show sync UI in editor playback as well as gameplay revert sync from in-memory backup, not from disk move more functions into debug overlay --- stepmania/src/GameState.cpp | 44 +++- stepmania/src/GameState.h | 9 +- stepmania/src/Makefile.am | 4 +- stepmania/src/MessageManager.cpp | 2 + stepmania/src/MessageManager.h | 6 +- stepmania/src/Player.cpp | 18 +- stepmania/src/Player.h | 1 + stepmania/src/RageUtil.cpp | 4 +- stepmania/src/RageUtil.h | 2 +- stepmania/src/Screen.cpp | 2 + stepmania/src/Screen.h | 12 ++ stepmania/src/ScreenAttract.h | 2 + stepmania/src/ScreenDebugOverlay.cpp | 208 ++++++++++++++----- stepmania/src/ScreenDebugOverlay.h | 11 +- stepmania/src/ScreenDemonstration.h | 2 + stepmania/src/ScreenEdit.cpp | 10 +- stepmania/src/ScreenEdit.h | 4 +- stepmania/src/ScreenGameplay.cpp | 246 +--------------------- stepmania/src/ScreenGameplay.h | 7 +- stepmania/src/ScreenManager.cpp | 12 +- stepmania/src/ScreenPrompt.cpp | 16 +- stepmania/src/ScreenPrompt.h | 3 +- stepmania/src/ScreenSaveSync.cpp | 135 ++++++++++++ stepmania/src/ScreenSaveSync.h | 40 ++++ stepmania/src/ScreenSelectMusic.cpp | 4 +- stepmania/src/ScreenSyncOverlay.cpp | 297 +++++++++++++++++++++++++++ stepmania/src/ScreenSyncOverlay.h | 56 +++++ stepmania/src/ScreenSystemLayer.cpp | 2 +- stepmania/src/SongOptions.h | 3 +- stepmania/src/StepMania.cpp | 37 +--- stepmania/src/StepMania.dsp | 20 +- stepmania/src/StepMania.vcproj | 12 ++ stepmania/src/TimingData.cpp | 20 +- stepmania/src/TimingData.h | 34 +++ 34 files changed, 902 insertions(+), 383 deletions(-) create mode 100644 stepmania/src/ScreenSaveSync.cpp create mode 100644 stepmania/src/ScreenSaveSync.h create mode 100644 stepmania/src/ScreenSyncOverlay.cpp create mode 100644 stepmania/src/ScreenSyncOverlay.h diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index d8c24eecf2..384d836d32 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -63,7 +63,6 @@ GameState::GameState() : m_pCurGame = NULL; m_iCoins = 0; m_timeGameStarted.SetZero(); - m_bIsOnSystemMenu = false; ReloadCharacters(); @@ -82,6 +81,8 @@ GameState::GameState() : m_Environment = new LuaTable; + m_pTimingDataOriginal = new TimingData; + /* Don't reset yet; let the first screen do it, so we can * use PREFSMAN and THEME. */ // Reset(); @@ -95,7 +96,9 @@ GameState::~GameState() FOREACH_PlayerNumber( p ) SAFE_DELETE( m_pPlayerState[p] ); - delete m_Environment; + SAFE_DELETE( m_Environment ); + + SAFE_DELETE( m_pTimingDataOriginal ); } void GameState::ApplyGameCommand( const CString &sCommand, PlayerNumber pn ) @@ -300,7 +303,7 @@ void GameState::PlayersFinalized() if( MEMCARDMAN->GetCardsLocked() ) return; - MESSAGEMAN->Broadcast( PLAYERS_FINALIZED ); + MESSAGEMAN->Broadcast( MESSAGE_PLAYERS_FINALIZED ); MEMCARDMAN->LockCards(); @@ -678,6 +681,8 @@ void GameState::ResetStageStatistics() // Reset the round seed. Do this here and not in FinishStage so that players // get new shuffle patterns if they Back out of gameplay and play again. GAMESTATE->m_iStageSeed = rand(); + + ResetOriginalSyncData(); } void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) @@ -1906,6 +1911,37 @@ bool GameState::PlayerIsUsingModifier( PlayerNumber pn, const CString &sModifier return po == GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions && so == GAMESTATE->m_SongOptions; } +void GameState::ResetOriginalSyncData() +{ + if( m_pCurSong ) + *m_pTimingDataOriginal = m_pCurSong->m_Timing; + else + *m_pTimingDataOriginal = TimingData(); + m_fGlobalOffsetSecondsOriginal = PREFSMAN->m_fGlobalOffsetSeconds; +} + +bool GameState::IsSyncDataChanged() +{ + if( m_pCurSong && *m_pTimingDataOriginal != m_pCurSong->m_Timing ) + return true; + if( m_fGlobalOffsetSecondsOriginal != PREFSMAN->m_fGlobalOffsetSeconds ) + return true; + + return false; +} + +void GameState::SaveSyncChanges() +{ + GAMESTATE->m_pCurSong->Save(); + PREFSMAN->SaveGlobalPrefsToDisk(); +} + +void GameState::RevertSyncChanges() +{ + PREFSMAN->m_fGlobalOffsetSeconds.Set( GAMESTATE->m_fGlobalOffsetSecondsOriginal ); + GAMESTATE->m_pCurSong->m_Timing = *GAMESTATE->m_pTimingDataOriginal; +} + // lua start #include "LuaBinding.h" @@ -2014,6 +2050,7 @@ public: static int GetNumSidesJoined( T* p, lua_State *L ) { lua_pushnumber(L, p->GetNumSidesJoined() ); return 1; } static int GetCoinMode( T* p, lua_State *L ) { lua_pushnumber(L, p->GetCoinMode() ); return 1; } static int GetPremium( T* p, lua_State *L ) { lua_pushnumber(L, p->GetPremium() ); return 1; } + static int IsSyncDataChanged( T* p, lua_State *L ) { lua_pushboolean(L, p->IsSyncDataChanged() ); return 1; } static void Register(lua_State *L) { @@ -2058,6 +2095,7 @@ public: ADD_METHOD( GetNumSidesJoined ) ADD_METHOD( GetCoinMode ) ADD_METHOD( GetPremium ) + ADD_METHOD( IsSyncDataChanged ) Luna::Register( L ); diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index 3133265563..c0efd6edb1 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -55,7 +55,6 @@ public: PlayMode m_PlayMode; // many screens display different info depending on this value int m_iCoins; // not "credits" PlayerNumber m_MasterPlayerNumber; // used in Styles where one player controls both sides - bool m_bIsOnSystemMenu; // system screens will not be effected by the operator key -- Miryokuteki BroadcastOnChange1D m_PreferredCourseDifficulty;// used in nonstop bool DifficultiesLocked(); bool ChangePreferredDifficulty( PlayerNumber pn, Difficulty dc ); @@ -302,6 +301,14 @@ public: float GetGoalPercentComplete( PlayerNumber pn ); bool IsGoalComplete( PlayerNumber pn ) { return GetGoalPercentComplete( pn ) >= 1; } + // Sync changes stuff + TimingData *m_pTimingDataOriginal; + float m_fGlobalOffsetSecondsOriginal; + void ResetOriginalSyncData(); + bool IsSyncDataChanged(); + void SaveSyncChanges(); + void RevertSyncChanges(); + // Lua void PushSelf( lua_State *L ); }; diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index 3b281086e7..53fc105cd4 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -42,7 +42,9 @@ ScreenNameEntry.cpp ScreenNameEntry.h ScreenNameEntryTraditional.cpp ScreenNameE ScreenOptions.cpp ScreenOptions.h ScreenOptionsMaster.cpp ScreenOptionsMaster.h \ ScreenOptionsMasterPrefs.cpp ScreenOptionsMasterPrefs.h ScreenPackages.cpp ScreenPackages.h ScreenPlayerOptions.cpp ScreenPlayerOptions.h ScreenNetworkOptions.h \ ScreenNetworkOptions.cpp ScreenProfileOptions.cpp ScreenProfileOptions.h ScreenPrompt.cpp ScreenPrompt.h ScreenRanking.cpp ScreenRanking.h \ -ScreenReloadSongs.cpp ScreenReloadSongs.h ScreenSandbox.cpp ScreenSandbox.h \ +ScreenReloadSongs.cpp ScreenReloadSongs.h \ +ScreenSandbox.cpp ScreenSandbox.h \ +ScreenSaveSync.cpp ScreenSaveSync.h \ ScreenSelect.cpp ScreenSelect.h ScreenSelectCharacter.cpp ScreenSelectCharacter.h \ ScreenSelectDifficulty.cpp ScreenSelectDifficulty.h ScreenSelectGroup.cpp ScreenSelectGroup.h \ ScreenSelectMaster.cpp ScreenSelectMaster.h ScreenSelectMode.cpp ScreenSelectMode.h \ diff --git a/stepmania/src/MessageManager.cpp b/stepmania/src/MessageManager.cpp index 5958116bf0..ff6aea8c9d 100644 --- a/stepmania/src/MessageManager.cpp +++ b/stepmania/src/MessageManager.cpp @@ -46,6 +46,8 @@ static const CString MessageNames[] = { "SideJoinedP1", "SideJoinedP2", "PlayersFinalized", + "AssistTickChanged", + "AutosyncChanged", }; XToString( Message, NUM_MESSAGES ); diff --git a/stepmania/src/MessageManager.h b/stepmania/src/MessageManager.h index e80d191648..8c6f3a2ada 100644 --- a/stepmania/src/MessageManager.h +++ b/stepmania/src/MessageManager.h @@ -52,7 +52,9 @@ enum Message MESSAGE_COIN_INSERTED, MESSAGE_SIDE_JOINED_P1, MESSAGE_SIDE_JOINED_P2, - PLAYERS_FINALIZED, + MESSAGE_PLAYERS_FINALIZED, + MESSAGE_ASSIST_TICK_CHANGED, + MESSAGE_AUTOSYNC_CHANGED, NUM_MESSAGES, MESSAGE_INVALID }; @@ -118,7 +120,7 @@ private: Message mSendWhenChanged; T *val; public: - BroadcastOnChangePtr( Message m ) { mSendWhenChanged = m; } + BroadcastOnChangePtr( Message m ) { mSendWhenChanged = m; val = NULL; } const T* Get() const { return val; } void Set( T* t ) { val = t; if(MESSAGEMAN) MESSAGEMAN->Broadcast( MessageToString(mSendWhenChanged) ); } operator T* () const { return val; } diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 1926aa5d22..b8af2d91bf 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -77,6 +77,8 @@ Player::Player() PlayerAI::InitFromDisk(); m_pNoteField = new NoteField; + + this->SubscribeToMessage( MESSAGE_AUTOSYNC_CHANGED ); } Player::~Player() @@ -1140,7 +1142,9 @@ void Player::HandleAutosync(float fNoteOffset) if( GAMESTATE->m_SongOptions.m_AutosyncType == SongOptions::AUTOSYNC_OFF ) return; - m_fOffset[m_iOffsetSample++] = fNoteOffset; + m_fOffset[m_iOffsetSample] = fNoteOffset; + m_iOffsetSample++; + if( m_iOffsetSample < SAMPLE_COUNT ) return; /* need more */ @@ -1174,11 +1178,11 @@ void Player::HandleAutosync(float fNoteOffset) ASSERT(0); } - SCREENMAN->SystemMessage( ssprintf(sAutosyncType+": Offset corrected by %f. Error in steps: %f seconds.", mean, stddev) ); + SCREENMAN->SystemMessage( "Autosync: Correction applied." ); } else { - SCREENMAN->SystemMessage( ssprintf(sAutosyncType+": Offset NOT corrected. Average offset: %f seconds. Error: %f seconds.", mean, stddev) ); + SCREENMAN->SystemMessage( "Autosync: Correction NOT applied.\n Timing deviation too high." ); } m_iOffsetSample = 0; @@ -1646,6 +1650,14 @@ bool Player::IsPlayingBeginner() const } } +void Player::HandleMessage( const CString& sMessage ) +{ + // Reset autosync samples when toggling + if( sMessage == MessageToString(MESSAGE_AUTOSYNC_CHANGED) ) + m_iOffsetSample = 0; +} + + /* * (c) 2001-2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index 87fab2a849..a037048fef 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -31,6 +31,7 @@ public: virtual void Update( float fDeltaTime ); virtual void DrawPrimitives(); + virtual void HandleMessage( const CString& sMessage ); void Init( const CString &sType, diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 75cb06975f..d70e506e45 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -1,6 +1,6 @@ #include "global.h" -#include "RageMath.h" #include "RageUtil.h" +#include "RageMath.h" #include "RageLog.h" #include "RageFile.h" @@ -179,7 +179,7 @@ CString Commify( int iNum ) return sReturn; } -CString AddNumberSuffix( int i ) +CString FormatNumberAndSuffix( int i ) { CString sSuffix; switch( i%10 ) diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index 4f20cc7667..5fcb97c478 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -219,7 +219,7 @@ CString SecondsToMMSSMsMsMs( float fSecs ); CString PrettyPercent( float fNumerator, float fDenominator ); inline CString PrettyPercent( int fNumerator, int fDenominator ) { return PrettyPercent( float(fNumerator), float(fDenominator) ); } CString Commify( int iNum ); -CString AddNumberSuffix( int i ); +CString FormatNumberAndSuffix( int i ); struct tm GetLocalTime(); diff --git a/stepmania/src/Screen.cpp b/stepmania/src/Screen.cpp index 88522df872..68883db6bf 100644 --- a/stepmania/src/Screen.cpp +++ b/stepmania/src/Screen.cpp @@ -17,6 +17,8 @@ Screen::Screen( CString sName ) { SetName( sName ); m_bIsTransparent = false; + + ALLOW_OPERATOR_MENU_BUTTON.Load( sName, "AllowOperatorMenuButton" ); } Screen::~Screen() diff --git a/stepmania/src/Screen.h b/stepmania/src/Screen.h index 4a3902b8b8..06cfc49b92 100644 --- a/stepmania/src/Screen.h +++ b/stepmania/src/Screen.h @@ -10,6 +10,7 @@ #include "MenuInput.h" #include "StyleInput.h" #include "ScreenManager.h" +#include "ThemeMetric.h" // Each Screen class should have a REGISTER_SCREEN_CLASS in its CPP file. #define REGISTER_SCREEN_CLASS( className ) \ @@ -20,6 +21,14 @@ }; \ static Register##className register_##className; +enum ScreenType +{ + attract, + game_menu, + gameplay, + system_menu +}; + class Screen : public ActorFrame { public: @@ -40,6 +49,7 @@ public: bool IsTransparent() const { return m_bIsTransparent; } virtual bool UsesBackground() const { return true; } // override and set false if this screen shouldn't load a background + virtual ScreenType GetScreenType() const { return ALLOW_OPERATOR_MENU_BUTTON ? system_menu : game_menu; } static bool JoinInput( const MenuInput &MenuI ); // return true if a player joined @@ -54,6 +64,8 @@ protected: bool m_bIsTransparent; // screens below us need to be drawn first + ThemeMetric ALLOW_OPERATOR_MENU_BUTTON; + public: // let subclass override if they want diff --git a/stepmania/src/ScreenAttract.h b/stepmania/src/ScreenAttract.h index b32a137e6f..8fa8be5115 100644 --- a/stepmania/src/ScreenAttract.h +++ b/stepmania/src/ScreenAttract.h @@ -21,6 +21,8 @@ public: virtual void Update( float fDelta ); virtual void HandleScreenMessage( const ScreenMessage SM ); + virtual ScreenType GetScreenType() const { return attract; } + protected: virtual void StartPlayingMusic(); }; diff --git a/stepmania/src/ScreenDebugOverlay.cpp b/stepmania/src/ScreenDebugOverlay.cpp index 4427a8c37a..771ee7c8d7 100644 --- a/stepmania/src/ScreenDebugOverlay.cpp +++ b/stepmania/src/ScreenDebugOverlay.cpp @@ -9,6 +9,12 @@ #include "GameCommand.h" #include "ScreenGameplay.h" #include "RageSoundManager.h" +#include "GameSoundManager.h" +#include "RageTextureManager.h" +#include "NoteSkinManager.h" +#include "Bookkeeper.h" +#include "ProfileManager.h" +#include "CodeDetector.h" static bool g_bIsDisplayed = false; static bool g_bIsSlow = false; @@ -16,6 +22,11 @@ static bool g_bIsHalt = false; static RageTimer g_HaltTimer(RageZeroTimer); static bool g_bMute = false; +static bool IsGameplay() +{ + return SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == gameplay; +} + REGISTER_SCREEN_CLASS( ScreenDebugOverlay ); ScreenDebugOverlay::ScreenDebugOverlay( const CString &sName ) : Screen(sName) { @@ -27,13 +38,17 @@ ScreenDebugOverlay::~ScreenDebugOverlay() struct MapDebugToDI { - DeviceInput holdForMenu; - DeviceInput button[NUM_DEBUG_LINES]; + DeviceInput holdForDebug; + DeviceInput debugButton[NUM_DEBUG_LINES]; + DeviceInput gameplayButton[NUM_DEBUG_LINES]; void Clear() { - holdForMenu.MakeInvalid(); + holdForDebug.MakeInvalid(); FOREACH_DebugLine(i) - button[i].MakeInvalid(); + { + debugButton[i].MakeInvalid(); + gameplayButton[i].MakeInvalid(); + } } }; static MapDebugToDI g_Mappings; @@ -41,7 +56,12 @@ static MapDebugToDI g_Mappings; static CString GetDebugButtonName( DebugLine i ) { // TODO: Make arch appropriate. - return g_Mappings.button[i].toString(); + vector v; + if( g_Mappings.debugButton[i].IsValid() ) + v.push_back( g_Mappings.debugButton[i].toString() ); + if( g_Mappings.gameplayButton[i].IsValid() ) + v.push_back( g_Mappings.gameplayButton[i].toString()+" in gameplay" ); + return join( " or ", v ); } void ScreenDebugOverlay::Init() @@ -53,20 +73,26 @@ void ScreenDebugOverlay::Init() { g_Mappings.Clear(); - g_Mappings.holdForMenu = DeviceInput(DEVICE_KEYBOARD, KEY_F3); - g_Mappings.button[0] = DeviceInput(DEVICE_KEYBOARD, KEY_C1); - g_Mappings.button[1] = DeviceInput(DEVICE_KEYBOARD, KEY_C2); - g_Mappings.button[2] = DeviceInput(DEVICE_KEYBOARD, KEY_C3); - g_Mappings.button[3] = DeviceInput(DEVICE_KEYBOARD, KEY_C4); - g_Mappings.button[4] = DeviceInput(DEVICE_KEYBOARD, KEY_C5); - g_Mappings.button[5] = DeviceInput(DEVICE_KEYBOARD, KEY_C6); - g_Mappings.button[6] = DeviceInput(DEVICE_KEYBOARD, KEY_C7); - g_Mappings.button[7] = DeviceInput(DEVICE_KEYBOARD, KEY_C8); - g_Mappings.button[8] = DeviceInput(DEVICE_KEYBOARD, KEY_C9); - g_Mappings.button[9] = DeviceInput(DEVICE_KEYBOARD, KEY_C0); - g_Mappings.button[10] = DeviceInput(DEVICE_KEYBOARD, KEY_UNDERSCORE); - g_Mappings.button[11] = DeviceInput(DEVICE_KEYBOARD, KEY_EQUAL); - g_Mappings.button[12] = DeviceInput(DEVICE_KEYBOARD, KEY_PAUSE); + g_Mappings.holdForDebug = DeviceInput(DEVICE_KEYBOARD, KEY_F3); + + g_Mappings.gameplayButton[0] = DeviceInput(DEVICE_KEYBOARD, KEY_F8); + g_Mappings.gameplayButton[1] = DeviceInput(DEVICE_KEYBOARD, KEY_F7); + g_Mappings.gameplayButton[2] = DeviceInput(DEVICE_KEYBOARD, KEY_F6); + g_Mappings.debugButton[3] = DeviceInput(DEVICE_KEYBOARD, KEY_C1); + g_Mappings.debugButton[4] = DeviceInput(DEVICE_KEYBOARD, KEY_C2); + g_Mappings.debugButton[5] = DeviceInput(DEVICE_KEYBOARD, KEY_C3); + g_Mappings.debugButton[6] = DeviceInput(DEVICE_KEYBOARD, KEY_C4); + g_Mappings.debugButton[7] = DeviceInput(DEVICE_KEYBOARD, KEY_C5); + g_Mappings.debugButton[8] = DeviceInput(DEVICE_KEYBOARD, KEY_C6); + g_Mappings.debugButton[9] = DeviceInput(DEVICE_KEYBOARD, KEY_C7); + g_Mappings.debugButton[10] = DeviceInput(DEVICE_KEYBOARD, KEY_C8); + g_Mappings.debugButton[11] = DeviceInput(DEVICE_KEYBOARD, KEY_C9); + g_Mappings.debugButton[12] = DeviceInput(DEVICE_KEYBOARD, KEY_C0); + g_Mappings.debugButton[13] = DeviceInput(DEVICE_KEYBOARD, KEY_HYPHEN); + g_Mappings.debugButton[14] = DeviceInput(DEVICE_KEYBOARD, KEY_EQUAL); + g_Mappings.debugButton[15] = DeviceInput(DEVICE_KEYBOARD, KEY_LBRACKET); + g_Mappings.debugButton[16] = DeviceInput(DEVICE_KEYBOARD, KEY_RBRACKET); + g_Mappings.debugButton[17] = DeviceInput(DEVICE_KEYBOARD, KEY_BACKSLASH); } @@ -74,20 +100,27 @@ void ScreenDebugOverlay::Init() m_Quad.SetDiffuse( RageColor(0, 0, 0, 0.5f) ); this->AddChild( &m_Quad ); - m_Header.LoadFromFont( THEME->GetPathToF("Common normal") ); - m_Header.SetHorizAlign( Actor::align_left ); - m_Header.SetX( 20 ); - m_Header.SetY( SCREEN_TOP+20 ); - m_Header.SetZoom( 1.0f ); - m_Header.SetText( "Debug Menu" ); - this->AddChild( &m_Header ); + m_textHeader.LoadFromFont( THEME->GetPathToF("Common normal") ); + m_textHeader.SetHorizAlign( Actor::align_left ); + m_textHeader.SetX( SCREEN_LEFT+20 ); + m_textHeader.SetY( SCREEN_TOP+20 ); + m_textHeader.SetZoom( 1.0f ); + m_textHeader.SetText( "Debug Menu" ); + this->AddChild( &m_textHeader ); FOREACH_DebugLine( i ) { - BitmapText &txt = m_Text[i]; - txt.LoadFromFont( THEME->GetPathToF("Common normal") ); - txt.SetHorizAlign( Actor::align_left ); - this->AddChild( &txt ); + BitmapText &txt1 = m_textButton[i]; + txt1.LoadFromFont( THEME->GetPathToF("Common normal") ); + txt1.SetHorizAlign( Actor::align_right ); + txt1.SetShadowLength( 2 ); + this->AddChild( &txt1 ); + + BitmapText &txt2 = m_textFunction[i]; + txt2.LoadFromFont( THEME->GetPathToF("Common normal") ); + txt2.SetHorizAlign( Actor::align_left ); + txt2.SetShadowLength( 2 ); + this->AddChild( &txt2 ); } Update( 0 ); @@ -133,28 +166,37 @@ void ScreenDebugOverlay::UpdateText() FOREACH_DebugLine( i ) { - BitmapText &txt = m_Text[i]; - txt.SetX( 100 ); - txt.SetY( SCALE(i, 0, NUM_DEBUG_LINES-1, SCREEN_TOP+60, SCREEN_BOTTOM-40) ); - txt.SetZoom( 0.8f ); + BitmapText &txt1 = m_textButton[i]; + txt1.SetX( SCREEN_CENTER_X-50 ); + txt1.SetY( SCALE(i, 0, NUM_DEBUG_LINES-1, SCREEN_TOP+60, SCREEN_BOTTOM-40) ); + txt1.SetZoom( 0.7f ); + + BitmapText &txt2 = m_textFunction[i]; + txt2.SetX( SCREEN_CENTER_X-30 ); + txt2.SetY( SCALE(i, 0, NUM_DEBUG_LINES-1, SCREEN_TOP+60, SCREEN_BOTTOM-40) ); + txt2.SetZoom( 0.7f ); CString s1; switch( i ) { case DebugLine_Autoplay: s1="AutoPlay"; break; + case DebugLine_AssistTick: s1="AssistTick"; break; + case DebugLine_Autosync: s1="AutoSync"; break; case DebugLine_CoinMode: s1="CoinMode"; break; case DebugLine_Slow: s1="Slow"; break; case DebugLine_Halt: s1="Halt"; break; case DebugLine_LightsDebug: s1="Lights Debug"; break; case DebugLine_MonkeyInput: s1="MonkeyInput"; break; - case DebugLine_Stats: s1="Stats"; break; + case DebugLine_Stats: s1="Rendering Stats"; break; case DebugLine_Vsync: s1="Vsync"; break; case DebugLine_ScreenTestMode: s1="Screen Test Mode"; break; case DebugLine_ClearMachineStats: s1="Clear Machine Stats"; break; case DebugLine_FillMachineStats: s1="Fill Machine Stats"; break; case DebugLine_SendNotesEnded: s1="Send Notes Ended"; break; case DebugLine_Volume: s1="Mute"; break; - case DebugLine_CurrentScreen: s1="Screen"; break; + case DebugLine_ReloadCurrentScreen: s1="Reload"; break; + case DebugLine_ReloadTheme: s1="Reload Theme"; break; + case DebugLine_WriteProfiles: s1="Write Profiles"; break; case DebugLine_Uptime: s1="Uptime"; break; default: ASSERT(0); } @@ -163,6 +205,8 @@ void ScreenDebugOverlay::UpdateText() switch( i ) { case DebugLine_Autoplay: bOn=PREFSMAN->m_AutoPlay.Get() != PC_HUMAN; break; + case DebugLine_AssistTick: bOn=GAMESTATE->m_SongOptions.m_bAssistTick; break; + case DebugLine_Autosync: bOn=GAMESTATE->m_SongOptions.m_AutosyncType!=SongOptions::AUTOSYNC_OFF; break; case DebugLine_CoinMode: bOn=true; break; case DebugLine_Slow: bOn=g_bIsSlow; break; case DebugLine_Halt: bOn=g_bIsHalt; break; @@ -175,7 +219,9 @@ void ScreenDebugOverlay::UpdateText() case DebugLine_FillMachineStats: bOn=true; break; case DebugLine_SendNotesEnded: bOn=true; break; case DebugLine_Volume: bOn=g_bMute; break; - case DebugLine_CurrentScreen: bOn=false; break; + case DebugLine_ReloadCurrentScreen: bOn=true; break; + case DebugLine_ReloadTheme: bOn=true; break; + case DebugLine_WriteProfiles: bOn=true; break; case DebugLine_Uptime: bOn=false; break; default: ASSERT(0); } @@ -192,6 +238,16 @@ void ScreenDebugOverlay::UpdateText() default: ASSERT(0); } break; + case DebugLine_AssistTick: s2=bOn ? "on":"off"; break; + case DebugLine_Autosync: + switch( GAMESTATE->m_SongOptions.m_AutosyncType ) + { + case SongOptions::AUTOSYNC_OFF: s2="off"; break; + case SongOptions::AUTOSYNC_SONG: s2="Song"; break; + case SongOptions::AUTOSYNC_MACHINE: s2="Machine"; break; + default: ASSERT(0); + } + break; case DebugLine_CoinMode: s2=CoinModeToString(PREFSMAN->m_CoinMode); break; case DebugLine_Slow: s2=bOn ? "on":"off"; break; case DebugLine_Halt: s2=bOn ? "on":"off"; break; @@ -204,19 +260,23 @@ void ScreenDebugOverlay::UpdateText() case DebugLine_FillMachineStats: s2=""; break; case DebugLine_SendNotesEnded: s2=""; break; case DebugLine_Volume: s2=bOn ? "on":"off"; break; - case DebugLine_CurrentScreen: s2=SCREENMAN ? SCREENMAN->GetTopScreen()->m_sName:""; break; + case DebugLine_ReloadCurrentScreen: s2=SCREENMAN ? SCREENMAN->GetTopScreen()->m_sName:""; break; + case DebugLine_ReloadTheme: s2=""; break; + case DebugLine_WriteProfiles: s2=""; break; case DebugLine_Uptime: s2=SecondsToMMSSMsMsMs(RageTimer::GetTimeSinceStart()); break; default: ASSERT(0); } - txt.SetDiffuse( bOn ? on:off ); + txt1.SetDiffuse( bOn ? on:off ); + txt2.SetDiffuse( bOn ? on:off ); CString sButton = GetDebugButtonName(i); if( !sButton.empty() ) sButton += ": "; + txt1.SetText( sButton ); if( !s2.empty() ) s1 += " - "; - txt.SetText( sButton + s1 + s2 ); + txt2.SetText( s1 + s2 ); } if( g_bIsHalt ) @@ -233,7 +293,7 @@ void ScreenDebugOverlay::UpdateText() bool ScreenDebugOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) { - if( DeviceI == g_Mappings.holdForMenu ) + if( DeviceI == g_Mappings.holdForDebug ) { if( type == IET_FIRST_PRESS ) g_bIsDisplayed = true; @@ -241,23 +301,22 @@ bool ScreenDebugOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEv g_bIsDisplayed = false; } - if( !g_bIsDisplayed ) - return false; - if( type != IET_FIRST_PRESS ) - return false; /* eat the input but do nothing */ + return true; /* eat the input but do nothing */ FOREACH_DebugLine( i ) { - if( DeviceI == g_Mappings.button[i] ) + if( (g_bIsDisplayed && DeviceI == g_Mappings.debugButton[i]) || + (IsGameplay() && DeviceI == g_Mappings.gameplayButton[i]) ) { - BitmapText &txt = m_Text[i]; + BitmapText &txt1 = m_textButton[i]; + txt1.FinishTweening(); + float fZoom = txt1.GetZoom(); + txt1.SetZoom( fZoom * 1.2f ); + txt1.BeginTweening( 0.2f, Actor::TWEEN_LINEAR ); + txt1.SetZoom( fZoom ); - txt.FinishTweening(); - float fZoom = txt.GetZoom(); - txt.SetZoom( fZoom * 1.2f ); - txt.BeginTweening( 0.2f, Actor::TWEEN_LINEAR ); - txt.SetZoom( fZoom ); + BitmapText &txt2 = m_textFunction[i]; switch( i ) { @@ -270,6 +329,26 @@ bool ScreenDebugOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEv GAMESTATE->m_pPlayerState[pn]->m_PlayerController = PREFSMAN->m_AutoPlay; } break; + case DebugLine_AssistTick: + { + if( type != IET_FIRST_PRESS ) + return true; /* eat the input but do nothing */ + GAMESTATE->m_SongOptions.m_bAssistTick = !GAMESTATE->m_SongOptions.m_bAssistTick; + /* Store this change, so it sticks if we change songs: */ + GAMESTATE->m_StoredSongOptions.m_bAssistTick = GAMESTATE->m_SongOptions.m_bAssistTick; + MESSAGEMAN->Broadcast( MESSAGE_ASSIST_TICK_CHANGED ); + } + break; + case DebugLine_Autosync: + { + if( type != IET_FIRST_PRESS ) + return true; /* eat the input but do nothing */ + SongOptions::AutosyncType as = (SongOptions::AutosyncType)(GAMESTATE->m_SongOptions.m_AutosyncType+1); + wrap( (int&)as, SongOptions::NUM_AUTOSYNC_TYPES ); + GAMESTATE->m_SongOptions.m_AutosyncType = as; + MESSAGEMAN->Broadcast( MESSAGE_AUTOSYNC_CHANGED ); + } + break; case DebugLine_CoinMode: { CoinMode cm = (CoinMode)(PREFSMAN->m_CoinMode+1); @@ -324,7 +403,24 @@ bool ScreenDebugOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEv g_bMute = !g_bMute; SOUNDMAN->SetPrefs( g_bMute ? 0 : PREFSMAN->GetSoundVolume() ); break; - case DebugLine_CurrentScreen: + case DebugLine_ReloadCurrentScreen: + SOUND->StopMusic(); + ResetGame( true ); + break; + case DebugLine_ReloadTheme: + THEME->ReloadMetrics(); + TEXTUREMAN->ReloadAll(); + NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_pCurGame ); + CodeDetector::RefreshCacheItems(); + break; + case DebugLine_WriteProfiles: + // HACK: Also save bookkeeping and profile info for debugging + // so we don't have to play through a whole song to get new output. + BOOKKEEPER->WriteToDisk(); + PROFILEMAN->SaveMachineProfile(); + FOREACH_PlayerNumber( p ) + if( PROFILEMAN->IsPersistentProfile(p) ) + PROFILEMAN->SaveProfile( p ); break; case DebugLine_Uptime: break; @@ -333,11 +429,13 @@ bool ScreenDebugOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEv UpdateText(); - SCREENMAN->SystemMessage( txt.GetText() ); + SCREENMAN->SystemMessage( txt2.GetText() ); + + return true; } } - return true; + return false; } diff --git a/stepmania/src/ScreenDebugOverlay.h b/stepmania/src/ScreenDebugOverlay.h index ab2bda1ef0..f85d04f34c 100644 --- a/stepmania/src/ScreenDebugOverlay.h +++ b/stepmania/src/ScreenDebugOverlay.h @@ -10,6 +10,8 @@ enum DebugLine { DebugLine_Autoplay, + DebugLine_AssistTick, + DebugLine_Autosync, DebugLine_CoinMode, DebugLine_Slow, DebugLine_Halt, @@ -22,7 +24,9 @@ enum DebugLine DebugLine_FillMachineStats, DebugLine_SendNotesEnded, DebugLine_Volume, - DebugLine_CurrentScreen, + DebugLine_ReloadCurrentScreen, + DebugLine_ReloadTheme, + DebugLine_WriteProfiles, DebugLine_Uptime, NUM_DEBUG_LINES }; @@ -43,8 +47,9 @@ private: void UpdateText(); Quad m_Quad; - BitmapText m_Header; - BitmapText m_Text[NUM_DEBUG_LINES]; + BitmapText m_textHeader; + BitmapText m_textButton[NUM_DEBUG_LINES]; + BitmapText m_textFunction[NUM_DEBUG_LINES]; }; diff --git a/stepmania/src/ScreenDemonstration.h b/stepmania/src/ScreenDemonstration.h index 565335668a..a5d6d1907a 100644 --- a/stepmania/src/ScreenDemonstration.h +++ b/stepmania/src/ScreenDemonstration.h @@ -13,6 +13,8 @@ public: virtual void Init(); virtual void HandleScreenMessage( const ScreenMessage SM ); + + virtual ScreenType GetScreenType() const { return attract; } }; #endif diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 6abad3d325..76fd4350da 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -477,13 +477,13 @@ static Menu g_CourseMode( int g_iLastInsertAttackTrack = -1; float g_fLastInsertAttackDurationSeconds = -1; +#define PREV_SCREEN THEME->GetMetric(m_sName,"PrevScreen") + REGISTER_SCREEN_CLASS( ScreenEdit ); ScreenEdit::ScreenEdit( CString sName ) : ScreenWithMenuElements( sName ) { LOG->Trace( "ScreenEdit::ScreenEdit()" ); - PREV_SCREEN.Load( sName, "PrevScreen" ); - ASSERT( GAMESTATE->m_pCurSong ); ASSERT( GAMESTATE->m_pCurSteps[0] ); } @@ -1482,6 +1482,11 @@ void ScreenEdit::TransitionEditState( EditState em ) { EditState old = m_EditState; + if( old == STATE_PLAYING ) + { + SCREENMAN->AddNewScreenToTop( "ScreenSaveSync" ); + } + switch( em ) { case STATE_EDITING: @@ -1522,6 +1527,7 @@ void ScreenEdit::TransitionEditState( EditState em ) case STATE_RECORDING: break; case STATE_PLAYING: + GAMESTATE->ResetOriginalSyncData(); break; default: ASSERT(0); diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h index ca2ddae434..74a495e90d 100644 --- a/stepmania/src/ScreenEdit.h +++ b/stepmania/src/ScreenEdit.h @@ -139,8 +139,8 @@ public: virtual void HandleScreenMessage( const ScreenMessage SM ); protected: - ThemeMetric PREV_SCREEN; - + virtual ScreenType GetScreenType() const { return m_EditState==STATE_PLAYING ? gameplay : system_menu; } + enum EditState { STATE_EDITING, STATE_RECORDING, STATE_PLAYING, NUM_EDIT_STATES, STATE_INVALID }; void TransitionEditState( EditState em ); void PlayTicks(); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index d950c34e35..cf3d2e9ac2 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -65,9 +65,6 @@ static ThemeMetric INITIAL_BACKGROUND_BRIGHTNESS ("ScreenGameplay","InitialBackgroundBrightness"); static ThemeMetric SECONDS_BETWEEN_COMMENTS ("ScreenGameplay","SecondsBetweenComments"); -/* Global, so it's accessible from ShowSavePrompt: */ -static float g_fOldOffset; // used on offset screen to calculate difference - AutoScreenMessage( SM_PlayGo ) // received while STATE_DANCING @@ -76,7 +73,6 @@ AutoScreenMessage( SM_StartLoadingNextSong ) // received while STATE_OUTRO -AutoScreenMessage( SM_SaveChangedBeforeGoingBack ) AutoScreenMessage( SM_GoToScreenAfterBack ) AutoScreenMessage( SM_BeginFailed ) @@ -102,8 +98,6 @@ ScreenGameplay::ScreenGameplay( CString sName ) : ScreenWithMenuElements(sName) FAIL_AFTER_30_MISSES.Load( sName, "FailAfter30Misses" ); USE_FORCED_MODIFIERS_IN_BEGINNER.Load( sName, "UseForcedModifiersInBeginner" ); FORCED_MODIFIERS_IN_BEGINNER.Load( sName, "ForcedModifiersInBeginner" ); - - this->SubscribeToMessage( PREFSMAN->m_AutoPlay.GetName()+"Changed" ); } void ScreenGameplay::Init() @@ -212,8 +206,6 @@ void ScreenGameplay::Init() } } - m_bChangedOffsetOrBPM = GAMESTATE->m_SongOptions.m_AutosyncType == SongOptions::AUTOSYNC_SONG; - m_DancingState = STATE_INTRO; // Set this in LoadNextSong() @@ -221,12 +213,6 @@ void ScreenGameplay::Init() m_bZeroDeltaOnNextUpdate = false; - // init old offset in case offset changes in song - if( GAMESTATE->IsCourseMode() ) - g_fOldOffset = -1000; - else - g_fOldOffset = GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds; - m_SongBackground.SetName( "SongBackground" ); m_SongBackground.SetDrawOrder( DRAW_ORDER_BEFORE_EVERYTHING ); @@ -548,14 +534,6 @@ void ScreenGameplay::Init() this->AddChild( &m_LyricDisplay ); - m_textAutoPlay.LoadFromFont( THEME->GetPathF(m_sName,"autoplay") ); - m_textAutoPlay.SetName( "AutoPlay" ); - SET_XY( m_textAutoPlay ); - if( !GAMESTATE->m_bDemonstrationOrJukebox ) // only load if we're not in demonstration or jukebox - this->AddChild( &m_textAutoPlay ); - UpdateAutoPlayText(); - - m_BPMDisplay.SetName( "BPMDisplay" ); m_BPMDisplay.Load(); SET_XY( m_BPMDisplay ); @@ -1834,7 +1812,7 @@ void ScreenGameplay::BackOutFromGameplay() m_soundAssistTick.StopPlaying(); /* Stop any queued assist ticks. */ this->ClearMessageQueue(); - m_Cancel.StartTransitioning( SM_SaveChangedBeforeGoingBack ); + m_Cancel.StartTransitioning( SM_GoToScreenAfterBack ); } void ScreenGameplay::AbortGiveUp( bool bShowText ) @@ -1936,102 +1914,6 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ /* Nothing below cares about releases. */ if(type == IET_RELEASE) return; - // Handle special keys to adjust the offset - if( DeviceI.device == DEVICE_KEYBOARD ) - { - switch( DeviceI.button ) - { - case KEY_F6: - { - bool bHoldingShift = - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT)) || - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT)); - - // toggle - if( GAMESTATE->m_SongOptions.m_AutosyncType != SongOptions::AUTOSYNC_OFF ) - GAMESTATE->m_SongOptions.m_AutosyncType = SongOptions::AUTOSYNC_OFF; - else - GAMESTATE->m_SongOptions.m_AutosyncType = bHoldingShift ? SongOptions::AUTOSYNC_MACHINE : SongOptions::AUTOSYNC_SONG; - - m_bChangedOffsetOrBPM |= !bHoldingShift; - UpdateAutoPlayText(); - } - break; - case KEY_F7: - GAMESTATE->m_SongOptions.m_bAssistTick ^= 1; - - /* Store this change, so it sticks if we change songs: */ - GAMESTATE->m_StoredSongOptions.m_bAssistTick = GAMESTATE->m_SongOptions.m_bAssistTick; - - m_textDebug.SetText( ssprintf("Assist Tick is %s", GAMESTATE->m_SongOptions.m_bAssistTick?"ON":"OFF") ); - m_textDebug.StopTweening(); - m_textDebug.SetDiffuse( RageColor(1,1,1,1) ); - m_textDebug.BeginTweening( 3 ); // sleep - m_textDebug.BeginTweening( 0.5f ); // fade out - m_textDebug.SetDiffuse( RageColor(1,1,1,0) ); - break; - case KEY_F9: - case KEY_F10: - { - m_bChangedOffsetOrBPM = true; - - float fOffsetDelta; - switch( DeviceI.button ) - { - case KEY_F9: fOffsetDelta = -0.020f; break; - case KEY_F10: fOffsetDelta = +0.020f; break; - default: ASSERT(0); return; - } - if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT)) || - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT)) ) - fOffsetDelta /= 2; /* .010 */ - else if( type == IET_FAST_REPEAT ) - fOffsetDelta *= 10; - BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat ); - - seg.m_fBPS += fOffsetDelta; - - m_textDebug.SetText( ssprintf("Cur BPM = %.2f", seg.GetBPM()) ); - m_textDebug.StopTweening(); - m_textDebug.SetDiffuse( RageColor(1,1,1,1) ); - m_textDebug.BeginTweening( 3 ); // sleep - m_textDebug.BeginTweening( 0.5f ); // fade out - m_textDebug.SetDiffuse( RageColor(1,1,1,0) ); - } - break; - case KEY_F11: - case KEY_F12: - { - m_bChangedOffsetOrBPM = true; - - float fOffsetDelta; - switch( DeviceI.button ) - { - case KEY_F11: fOffsetDelta = -0.02f; break; - case KEY_F12: fOffsetDelta = +0.02f; break; - default: ASSERT(0); return; - } - if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT)) || - INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT)) ) - fOffsetDelta /= 20; /* 1ms */ - else switch( type ) - { - case IET_SLOW_REPEAT: fOffsetDelta *= 10; break; - case IET_FAST_REPEAT: fOffsetDelta *= 40; break; - } - - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; - - m_textDebug.SetText( ssprintf("Offset = %.3f", GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds) ); - m_textDebug.StopTweening(); - m_textDebug.SetDiffuse( RageColor(1,1,1,1) ); - m_textDebug.BeginTweening( 3 ); // sleep - m_textDebug.BeginTweening( 0.5f ); // fade out - m_textDebug.SetDiffuse( RageColor(1,1,1,0) ); - } - break; - } - } // // handle a step or battle item activate @@ -2045,111 +1927,9 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ if( PREFSMAN->m_AutoPlay == PC_HUMAN ) m_Player[StyleI.player].Step( StyleI.col, DeviceI.ts ); } -// else if( type==IET_FIRST_PRESS && -// !PREFSMAN->m_bAutoPlay && -// MenuI.IsValifd() && -// GAMESTATE->IsPlayerEnabled( MenuI.player ) && -// GAMESTATE->IsBattleMode() ) -// { -// int iItemSlot; -// switch( MenuI.button ) -// { -// case MENU_BUTTON_LEFT: iItemSlot = 0; break; -// case MENU_BUTTON_START: iItemSlot = 1; break; -// case MENU_BUTTON_RIGHT: iItemSlot = 2; break; -// default: iItemSlot = -1; break; -// } -// -// if( iItemSlot != -1 ) -// m_pInventory[MenuI.player]->UseItem( iItemSlot ); -// } } -void ScreenGameplay::UpdateAutoPlayText() -{ - vector vsText; - switch( PREFSMAN->m_AutoPlay ) - { - case PC_HUMAN: break; - case PC_AUTOPLAY: vsText.push_back("AutoPlay"); break; - case PC_CPU: vsText.push_back("AutoPlay CPU"); break; - default: ASSERT(0); - } - switch( GAMESTATE->m_SongOptions.m_AutosyncType ) - { - case SongOptions::AUTOSYNC_OFF: break; - case SongOptions::AUTOSYNC_SONG: vsText.push_back("AutosyncSong"); break; - case SongOptions::AUTOSYNC_MACHINE: vsText.push_back("AutosyncMachine"); break; - default: ASSERT(0); - } - - CString sText = join( " ", vsText ); - m_textAutoPlay.SetText( sText ); -} - -void SaveChanges( void* papSongsQueue ) -{ - vector& apSongsQueue = *(vector*)papSongsQueue; - for( unsigned i=0; iSave(); -} - -void RevertChanges( void* papSongsQueue ) -{ - vector& apSongsQueue = *(vector*)papSongsQueue; - FOREACH( Song*, apSongsQueue, pSong ) - { - SONGMAN->RevertFromDisk( *pSong ); - } -} - -void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone ) -{ - CString sMessage; - switch( GAMESTATE->m_PlayMode ) - { - case PLAY_MODE_REGULAR: - case PLAY_MODE_BATTLE: - case PLAY_MODE_RAVE: - sMessage = ssprintf( - "You have changed the offset or BPM of\n" - "%s\n", - GAMESTATE->m_pCurSong->GetFullDisplayTitle().c_str() ); - - if( fabs(GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds - g_fOldOffset) > 0.001 ) - { - sMessage += ssprintf( - "\n" - "Offset was changed from %.3f to %.3f (%.3f).\n", - g_fOldOffset, - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds, - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds - g_fOldOffset ); - } - - sMessage += - "\n" - "Would you like to save these changes back\n" - "to the song file?\n" - "Choosing NO will discard your changes."; - - break; - case PLAY_MODE_NONSTOP: - case PLAY_MODE_ONI: - case PLAY_MODE_ENDLESS: - sMessage = ssprintf( - "You have changed the offset or BPM of\n" - "one or more songs in this course.\n" - "Would you like to save these changes back\n" - "to the song file(s)?\n" - "Choosing NO will discard your changes." ); - break; - default: - ASSERT(0); - } - - SCREENMAN->Prompt( SM_SendWhenDone, sMessage, PROMPT_YES_NO, ANSWER_NO, SaveChanges, RevertChanges, &m_apSongsQueue ); -} /* * Saving StageStats that are affected by the note pattern is a little tricky: @@ -2461,18 +2241,6 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) int iDamageLevel = SM-SM_BattleDamageLevel1+1; PlayAnnouncer( ssprintf("gameplay battle damage level%d",iDamageLevel), 3 ); } - else if( SM == SM_SaveChangedBeforeGoingBack ) - { - if( m_bChangedOffsetOrBPM ) - { - m_bChangedOffsetOrBPM = false; - ShowSavePrompt( SM_GoToScreenAfterBack ); - } - else - { - HandleScreenMessage( SM_GoToScreenAfterBack ); - } - } else if( SM == SM_GoToScreenAfterBack ) { SongFinished(); @@ -2484,13 +2252,6 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_GoToNextScreen ) { - if( m_bChangedOffsetOrBPM ) - { - m_bChangedOffsetOrBPM = false; - ShowSavePrompt( SM_GoToNextScreen ); - return; - } - SongFinished(); StageFinished( false ); } @@ -2626,11 +2387,6 @@ void ScreenGameplay::ShowOniGameOver( PlayerNumber pn ) m_sprOniGameOver[pn].PlayCommand( "Die" ); } -void ScreenGameplay::HandleMessage( const CString& sMessage ) -{ - if( sMessage == PREFSMAN->m_AutoPlay.GetName()+"Changed" ) - UpdateAutoPlayText(); -} /* * (c) 2001-2004 Chris Danford, Glenn Maynard diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index bc45d14d00..62dd02ef53 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -40,9 +40,9 @@ public: virtual void Update( float fDeltaTime ); virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); virtual void HandleScreenMessage( const ScreenMessage SM ); - virtual void HandleMessage( const CString& sMessage ); virtual bool UsesBackground() const { return false; } + virtual ScreenType GetScreenType() const { return gameplay; } protected: ThemeMetric PLAYER_TYPE; @@ -67,7 +67,6 @@ protected: float StartPlayingSong(float MinTimeToNotes, float MinTimeToMusic); void LoadLights(); void PauseGame( bool bPause, GameController gc = GAME_CONTROLLER_INVALID ); - void ShowSavePrompt( ScreenMessage SM_SendWhenDone ); void PlayAnnouncer( CString type, float fSeconds ); void UpdateLights(); void SendCrossedMessages(); @@ -93,7 +92,6 @@ protected: vector m_vpStepsQueue[NUM_PLAYERS]; // size may be >1 if playing a course vector m_asModifiersQueue[NUM_PLAYERS];// size may be >1 if playing a course - bool m_bChangedOffsetOrBPM; float m_fTimeSinceLastDancingComment; // this counter is only running while STATE_DANCING LyricDisplay m_LyricDisplay; @@ -133,9 +131,6 @@ protected: RageTimer m_GiveUpTimer; void AbortGiveUp( bool bShowText ); - BitmapText m_textAutoPlay; // for AutoPlay, AutoAdjust - void UpdateAutoPlayText(); - BitmapText m_MaxCombo; Transition m_Ready; diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 4a7f66b27c..d22be4fdd2 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -446,15 +446,11 @@ retry: m_sLastLoadedBackgroundPath = sNewBGA; } - bool bWasOnSystemMenu = GAMESTATE->m_bIsOnSystemMenu; - - if( THEME->HasMetric(sScreenName,"AllowOperatorMenuButton") ) - GAMESTATE->m_bIsOnSystemMenu = !THEME->GetMetricB( sScreenName,"AllowOperatorMenuButton" ); - else - GAMESTATE->m_bIsOnSystemMenu = false; + bool bWasOnSystemMenu = pOldTopScreen && pOldTopScreen->GetScreenType() == system_menu; + bool bIsOnSystemMenu = pNewScreen->GetScreenType() == system_menu; // If we're exiting a system menu, persist settings in case we don't exit normally - if( bWasOnSystemMenu && !GAMESTATE->m_bIsOnSystemMenu ) + if( bWasOnSystemMenu && !bIsOnSystemMenu ) PREFSMAN->SaveGlobalPrefsToDisk(); LOG->Trace("... SetFromNewScreen"); @@ -484,7 +480,7 @@ void ScreenManager::Prompt( ScreenMessage smSendOnPop, const CString &sText, Pro m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus ); // add the new state onto the back of the array - Screen *pNewScreen = new ScreenPrompt( smSendOnPop, sText, type, defaultAnswer, OnYes, OnNo, pCallbackData); + Screen *pNewScreen = new ScreenPrompt( "ScreenPrompt", smSendOnPop, sText, type, defaultAnswer, OnYes, OnNo, pCallbackData); pNewScreen->Init(); this->ZeroNextUpdate(); SetFromNewScreen( pNewScreen, true ); diff --git a/stepmania/src/ScreenPrompt.cpp b/stepmania/src/ScreenPrompt.cpp index b0c6fc01ef..12edca03cc 100644 --- a/stepmania/src/ScreenPrompt.cpp +++ b/stepmania/src/ScreenPrompt.cpp @@ -17,6 +17,7 @@ bool ScreenPrompt::s_bCancelledLast = false; //REGISTER_SCREEN_CLASS( ScreenPrompt ); ScreenPrompt::ScreenPrompt( + const CString &sScreenName, ScreenMessage smSendOnPop, CString sText, PromptType type, @@ -25,7 +26,7 @@ ScreenPrompt::ScreenPrompt( void(*OnNo)(void*), void* pCallbackData ) : - Screen("ScreenPrompt") + Screen( sScreenName ) { m_bIsTransparent = true; // draw screens below us @@ -130,9 +131,14 @@ void ScreenPrompt::HandleScreenMessage( const ScreenMessage SM ) case SM_DoneOpeningWipingLeft: break; case SM_DoneOpeningWipingRight: - SCREENMAN->PopTopScreen( m_smSendOnPop ); + if( SCREENMAN->IsStackedScreen(this) ) + SCREENMAN->PopTopScreen( m_smSendOnPop ); + else + this->HandleScreenMessage( SM_GoToNextScreen ); break; } + + Screen::HandleScreenMessage( SM ); } void ScreenPrompt::Change( int dir ) @@ -160,11 +166,17 @@ void ScreenPrompt::MenuRight( PlayerNumber pn ) void ScreenPrompt::MenuStart( PlayerNumber pn ) { + if( m_Out.IsTransitioning() || m_Cancel.IsTransitioning() ) + return; + End( false ); } void ScreenPrompt::MenuBack( PlayerNumber pn ) { + if( m_Out.IsTransitioning() || m_Cancel.IsTransitioning() ) + return; + switch( m_PromptType ) { case PROMPT_OK: diff --git a/stepmania/src/ScreenPrompt.h b/stepmania/src/ScreenPrompt.h index 878defe75f..6c49f08fd2 100644 --- a/stepmania/src/ScreenPrompt.h +++ b/stepmania/src/ScreenPrompt.h @@ -15,9 +15,10 @@ class ScreenPrompt : public Screen { public: - ScreenPrompt( CString sName ); + ScreenPrompt( const CString &sScreenName ); virtual void Init(); ScreenPrompt( + const CString &sScreenName, ScreenMessage smSendOnPop, CString sText, PromptType type = PROMPT_OK, diff --git a/stepmania/src/ScreenSaveSync.cpp b/stepmania/src/ScreenSaveSync.cpp new file mode 100644 index 0000000000..f06d598a1c --- /dev/null +++ b/stepmania/src/ScreenSaveSync.cpp @@ -0,0 +1,135 @@ +#include "global.h" +#include "ScreenSaveSync.h" +#include "GameState.h" +#include "song.h" +#include "PrefsManager.h" + + +static CString GetPromptText() +{ + CString s; + + { + float fOld = GAMESTATE->m_fGlobalOffsetSecondsOriginal; + float fNew = PREFSMAN->m_fGlobalOffsetSeconds; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "You have changed the Machine Global Offset\nfrom %.3f to %.3f (%+.3f).\n\n", + fOld, + fNew, + fDelta ); + } + } + + s += ssprintf( + "You have changed the timing of\n\n" + "%s:\n\n", + GAMESTATE->m_pCurSong->GetFullDisplayTitle().c_str() ); + + { + float fOld = GAMESTATE->m_pTimingDataOriginal->m_fBeat0OffsetInSeconds; + float fNew = GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "The song offset changed from %.3f to %.3f (%+.3f).\n\n", + fOld, + fNew, + fDelta ); + } + } + + for( int i=0; im_pCurSong->m_Timing.m_BPMSegments.size(); i++ ) + { + float fOld = GAMESTATE->m_pTimingDataOriginal->m_BPMSegments[i].m_fBPS; + float fNew = GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments[i].m_fBPS; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "The %s BPM segment changed from %.3f BPS to %.3f BPS (%+.3f).\n\n", + FormatNumberAndSuffix(i+1).c_str(), + fOld, + fNew, + fDelta ); + } + } + + for( int i=0; im_pCurSong->m_Timing.m_StopSegments.size(); i++ ) + { + float fOld = GAMESTATE->m_pTimingDataOriginal->m_StopSegments[i].m_fStopSeconds; + float fNew = GAMESTATE->m_pCurSong->m_Timing.m_StopSegments[i].m_fStopSeconds; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "The %s Stop segment changed from %.3f seconds to %.3f seconds (%+.3f).\n\n", + FormatNumberAndSuffix(i+1).c_str(), + fOld, + fNew, + fDelta ); + } + } + + s +="\n\nWould you like to save these changes to the song file?\n" + "Choosing NO will discard your changes."; + + return s; +} + +static void SaveSyncChanges( void* pThrowAway ) +{ + GAMESTATE->SaveSyncChanges(); +} + +static void RevertSyncChanges( void* pThrowAway ) +{ + GAMESTATE->RevertSyncChanges(); +} + +REGISTER_SCREEN_CLASS( ScreenSaveSync ); +ScreenSaveSync::ScreenSaveSync( const CString &sScreenName ) : + ScreenPrompt( + sScreenName, + SM_None, + GetPromptText(), + PROMPT_YES_NO, + ANSWER_YES, + SaveSyncChanges, + RevertSyncChanges, + NULL ) +{ +} + + +/* + * (c) 2001-2005 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/ScreenSaveSync.h b/stepmania/src/ScreenSaveSync.h new file mode 100644 index 0000000000..e5b41d3b8a --- /dev/null +++ b/stepmania/src/ScreenSaveSync.h @@ -0,0 +1,40 @@ +/* ScreenSaveSync - */ + +#ifndef ScreenSaveSync_H +#define ScreenSaveSync_H + +#include "ScreenPrompt.h" + +class ScreenSaveSync : public ScreenPrompt +{ +public: + ScreenSaveSync( const CString &sScreenName ); +}; + + +#endif + +/* + * (c) 2001-2005 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/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index f46fbfeff9..0507ebe537 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -1618,7 +1618,7 @@ void ScreenSelectMusic::AfterMusicChange() const vector best = SONGMAN->GetBestSongs( PROFILE_SLOT_MACHINE ); const int index = FindIndex( best.begin(), best.end(), pSong ); if( index != -1 ) - m_MachineRank.SetText( AddNumberSuffix( index+1 ) ); + m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) ); m_DifficultyDisplay.SetDifficulties( pSong, GAMESTATE->GetCurrentStyle()->m_StepsType ); @@ -1753,7 +1753,7 @@ void ScreenSelectMusic::AfterMusicChange() const vector best = SONGMAN->GetBestCourses( ct, PROFILE_SLOT_MACHINE ); const int index = FindCourseIndexOfSameMode( best.begin(), best.end(), pCourse ); if( index != -1 ) - m_MachineRank.SetText( AddNumberSuffix( index+1 ) ); + m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) ); diff --git a/stepmania/src/ScreenSyncOverlay.cpp b/stepmania/src/ScreenSyncOverlay.cpp new file mode 100644 index 0000000000..f9a73274f9 --- /dev/null +++ b/stepmania/src/ScreenSyncOverlay.cpp @@ -0,0 +1,297 @@ +#include "global.h" +#include "ScreenSyncOverlay.h" +#include "ScreenDimensions.h" +#include "GameState.h" +#include "song.h" +#include "PrefsManager.h" + +static bool IsGameplay() +{ + return SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == gameplay; +} + +REGISTER_SCREEN_CLASS( ScreenSyncOverlay ); +ScreenSyncOverlay::ScreenSyncOverlay( const CString &sName ) : Screen(sName) +{ +} + +ScreenSyncOverlay::~ScreenSyncOverlay() +{ +} + +void ScreenSyncOverlay::Init() +{ + Screen::Init(); + + m_quad.SetDiffuse( RageColor(0,0,0,0) ); + m_quad.SetHorizAlign( Actor::align_left ); + m_quad.SetXY( SCREEN_CENTER_X+10, SCREEN_TOP+100 ); + this->AddChild( &m_quad ); + + m_textHelp.LoadFromFont( THEME->GetPathToF("Common normal") ); + m_textHelp.SetHorizAlign( Actor::align_left ); + m_textHelp.SetXY( SCREEN_CENTER_X+20, SCREEN_TOP+100 ); + m_textHelp.SetDiffuseAlpha( 0 ); + m_textHelp.SetZoom( 0.6f ); + m_textHelp.SetShadowLength( 2 ); + m_textHelp.SetText( + "Revert sync changes:\n" + " F4\n" + "Adjust current BPM:\n" + " F9/F10 (hold Alt for smaller)\n" + "Adjust song offset:\n" + " F11/F12 (hold Alt for smaller)\n" + "Adjust machine offset:\n" + " Shift + F11/F12 (hold Alt for smaller)" ); + this->AddChild( &m_textHelp ); + + m_quad.ZoomToWidth( m_textHelp.GetZoomedWidth()+20 ); + m_quad.ZoomToHeight( m_textHelp.GetZoomedHeight()+20 ); + + m_textStatus.LoadFromFont( THEME->GetPathToF("Common normal") ); + m_textStatus.SetHorizAlign( Actor::align_center ); + m_textStatus.SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y+150 ); + m_textStatus.SetZoom( 0.8f ); + m_textStatus.SetShadowLength( 2 ); + this->AddChild( &m_textStatus ); + + Update( 0 ); +} + +void ScreenSyncOverlay::Update( float fDeltaTime ) +{ + this->SetVisible( IsGameplay() ); + if( !IsGameplay() ) + { + m_quad.SetDiffuseAlpha( 0 ); + m_textHelp.SetDiffuseAlpha( 0 ); + return; + } + + Screen::Update(fDeltaTime); + + // TODO: Only update when changed. + UpdateText(); +} + +void ScreenSyncOverlay::UpdateText() +{ + CString s; + + switch( PREFSMAN->m_AutoPlay ) + { + case PC_HUMAN: break; + case PC_AUTOPLAY: s+="AutoPlay\n"; break; + case PC_CPU: s+="AutoPlayCPU\n"; break; + default: ASSERT(0); + } + + switch( GAMESTATE->m_SongOptions.m_AutosyncType ) + { + case SongOptions::AUTOSYNC_OFF: break; + case SongOptions::AUTOSYNC_SONG: s+="AutoSync Song\n"; break; + case SongOptions::AUTOSYNC_MACHINE: s+="AutoSync Machine\n";break; + default: ASSERT(0); + } + + if( GAMESTATE->m_pCurSong == NULL ) + { + m_textStatus.SetText( "" ); + return; + } + + { + float fOld = GAMESTATE->m_fGlobalOffsetSecondsOriginal; + float fNew = PREFSMAN->m_fGlobalOffsetSeconds; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "Machine global offset: %.3fs (%+.3f)\n", + fNew, + fDelta ); + } + } + + { + float fOld = GAMESTATE->m_pTimingDataOriginal->m_fBeat0OffsetInSeconds; + float fNew = GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "Song offset: %.3fs (%+.3f)\n", + fNew, + fDelta ); + } + } + + ASSERT( GAMESTATE->m_pTimingDataOriginal->m_BPMSegments.size() == GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments.size() ); + + for( int i=0; im_pCurSong->m_Timing.m_BPMSegments.size(); i++ ) + { + float fOld = GAMESTATE->m_pTimingDataOriginal->m_BPMSegments[i].m_fBPS; + float fNew = GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments[i].m_fBPS; + float fDelta = fNew - fOld; + + if( fabs(fDelta) > 0.00001 ) + { + s += ssprintf( + "%s tempo segment: %.3f BPS (%+.3f)\n", + FormatNumberAndSuffix(i+1).c_str(), + fNew, + fDelta ); + } + } + + + m_textStatus.SetText( s ); +} + +bool ScreenSyncOverlay::OverlayInput( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( !IsGameplay() ) + return false; + + if( DeviceI.device != DEVICE_KEYBOARD ) + return false; + + switch( DeviceI.button ) + { + case KEY_F4: + SCREENMAN->SystemMessage( "Sync changes reverted." ); + break; + case KEY_F9: + case KEY_F10: + case KEY_F11: + case KEY_F12: + if( GAMESTATE->IsCourseMode() ) + { + SCREENMAN->SystemMessage( "Can't sync while playing a course." ); + return true; + } + break; + default: + return false; + } + + switch( DeviceI.button ) + { + case KEY_F4: + GAMESTATE->RevertSyncChanges(); + break; + case KEY_F9: + case KEY_F10: + { + float fDelta; + switch( DeviceI.button ) + { + case KEY_F9: fDelta = -0.02f; break; + case KEY_F10: fDelta = +0.02f; break; + default: ASSERT(0); + } + if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT)) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT)) ) + fDelta /= 20; + switch( type ) + { + case IET_RELEASE: fDelta *= 0; break; + case IET_SLOW_REPEAT: fDelta *= 0; break; + case IET_FAST_REPEAT: fDelta *= 10; break; + } + if( GAMESTATE->m_pCurSong != NULL ) + { + BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat ); + seg.m_fBPS += fDelta; + } + } + break; + case KEY_F11: + case KEY_F12: + { + float fDelta; + switch( DeviceI.button ) + { + case KEY_F11: fDelta = -0.02f; break; + case KEY_F12: fDelta = +0.02f; break; + default: ASSERT(0); + } + if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT)) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT)) ) + fDelta /= 20; /* 1ms */ + switch( type ) + { + case IET_RELEASE: fDelta *= 0; break; + case IET_SLOW_REPEAT: fDelta *= 0; break; + case IET_FAST_REPEAT: fDelta *= 10; break; + } + + if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT)) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT)) ) + { + PREFSMAN->m_fGlobalOffsetSeconds.Set( PREFSMAN->m_fGlobalOffsetSeconds + fDelta ); + } + else + { + if( GAMESTATE->m_pCurSong != NULL ) + GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + } + } + break; + default: + ASSERT(0); + } + + ShowHelp(); + UpdateText(); + return true; +} + +void ScreenSyncOverlay::ShowHelp() +{ + m_quad.StopTweening(); + m_quad.BeginTweening( 0.3f, Actor::TWEEN_LINEAR ); + m_quad.SetDiffuseAlpha( 0.5f ); + + m_textHelp.StopTweening(); + m_textHelp.BeginTweening( 0.3f, Actor::TWEEN_LINEAR ); + m_textHelp.SetDiffuseAlpha( 1 ); + + if( !GAMESTATE->IsSyncDataChanged() ) + { + m_quad.Sleep( 4 ); + m_quad.BeginTweening( 0.3f, Actor::TWEEN_LINEAR ); + m_quad.SetDiffuseAlpha( 0 ); + + m_textHelp.Sleep( 4 ); + m_textHelp.BeginTweening( 0.3f, Actor::TWEEN_LINEAR ); + m_textHelp.SetDiffuseAlpha( 0 ); + } +} + +/* + * (c) 2001-2005 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/ScreenSyncOverlay.h b/stepmania/src/ScreenSyncOverlay.h new file mode 100644 index 0000000000..c337839c06 --- /dev/null +++ b/stepmania/src/ScreenSyncOverlay.h @@ -0,0 +1,56 @@ +/* ScreenSyncOverlay - credits and statistics drawn on top of everything else. */ + +#ifndef ScreenSyncOverlay_H +#define ScreenSyncOverlay_H + +#include "Screen.h" +#include "BitmapText.h" +#include "Quad.h" + +class ScreenSyncOverlay : public Screen +{ +public: + ScreenSyncOverlay( const CString &sName ); + virtual ~ScreenSyncOverlay(); + virtual void Init(); + + bool OverlayInput( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + + void Update( float fDeltaTime ); + +private: + void UpdateText(); + void ShowHelp(); + + Quad m_quad; + BitmapText m_textHelp; + BitmapText m_textStatus; +}; + + +#endif + +/* + * (c) 2001-2005 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.cpp b/stepmania/src/ScreenSystemLayer.cpp index 25d61934fd..968f4ab73b 100644 --- a/stepmania/src/ScreenSystemLayer.cpp +++ b/stepmania/src/ScreenSystemLayer.cpp @@ -118,7 +118,7 @@ CString ScreenSystemLayer::GetCreditsMessage( PlayerNumber pn ) const return ""; bool bShowCreditsMessage; - if( GAMESTATE->m_bIsOnSystemMenu ) + if( SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == system_menu ) bShowCreditsMessage = true; else if( MEMCARDMAN->GetCardsLocked() ) bShowCreditsMessage = !GAMESTATE->IsPlayerEnabled( pn ); diff --git a/stepmania/src/SongOptions.h b/stepmania/src/SongOptions.h index 0640f52a52..d791882845 100644 --- a/stepmania/src/SongOptions.h +++ b/stepmania/src/SongOptions.h @@ -31,7 +31,8 @@ struct SongOptions enum AutosyncType { AUTOSYNC_OFF, AUTOSYNC_SONG, - AUTOSYNC_MACHINE + AUTOSYNC_MACHINE, + NUM_AUTOSYNC_TYPES }; AutosyncType m_AutosyncType; bool m_bSaveScore; diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 4fe72a3b6a..69ab3e0188 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -1281,7 +1281,7 @@ bool HandleGlobalInputs( DeviceInput DeviceI, InputEventType type, GameInput Gam /* Global operator key, to get quick access to the options menu. Don't * do this if we're on a "system menu", which includes the editor * (to prevent quitting without storing changes). */ - if( !GAMESTATE->m_bIsOnSystemMenu ) + if( SCREENMAN->GetTopScreen()->GetScreenType() != system_menu ) { SCREENMAN->DeletePreparedScreens(); SCREENMAN->SystemMessage( "Service switch pressed" ); @@ -1301,41 +1301,6 @@ bool HandleGlobalInputs( DeviceInput DeviceI, InputEventType type, GameInput Gam return false; // Attract need to know because they go to TitleMenu on > 1 credit } - if(DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_F2)) - { - bool bShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ); - bool bCtrl = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LCTRL) ); - if( bShift ) - { - // HACK: Also save bookkeeping and profile info for debugging - // so we don't have to play through a whole song to get new output. - BOOKKEEPER->WriteToDisk(); - PROFILEMAN->SaveMachineProfile(); - FOREACH_PlayerNumber( p ) - if( PROFILEMAN->IsPersistentProfile(p) ) - PROFILEMAN->SaveProfile( p ); - SCREENMAN->SystemMessage( "Stats saved" ); - } - else - { - THEME->ReloadMetrics(); - TEXTUREMAN->ReloadAll(); - NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_pCurGame ); - CodeDetector::RefreshCacheItems(); - - - /* If we're in screen test mode, reload the screen. */ - if( PREFSMAN->m_bScreenTestMode || bCtrl ) - { - SOUND->StopMusic(); - ResetGame( true ); - } - else - SCREENMAN->SystemMessage( "Reloaded metrics and textures" ); - } - - return true; - } #ifndef DARWIN if(DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_F4)) { diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index f0661e9995..17f076fc2b 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 @@ -2836,6 +2836,14 @@ SOURCE=.\ScreenSandbox.h # End Source File # Begin Source File +SOURCE=.\ScreenSaveSync.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScreenSaveSync.h +# End Source File +# Begin Source File + SOURCE=.\ScreenSelect.cpp # End Source File # Begin Source File @@ -2948,6 +2956,14 @@ SOURCE=.\ScreenStyleSplash.h # End Source File # Begin Source File +SOURCE=.\ScreenSyncOverlay.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScreenSyncOverlay.h +# End Source File +# Begin Source File + SOURCE=.\ScreenSystemLayer.cpp # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 853c6f1e4b..28a4bec082 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -505,6 +505,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + @@ -583,6 +589,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/TimingData.cpp b/stepmania/src/TimingData.cpp index 24bf1f14b9..989f98860f 100644 --- a/stepmania/src/TimingData.cpp +++ b/stepmania/src/TimingData.cpp @@ -165,16 +165,28 @@ float TimingData::GetBPMAtBeat( float fBeat ) const return m_BPMSegments[i].GetBPM(); } -BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat ) +int TimingData::GetBPMSegmentIndexAtBeat( float fBeat ) { int iIndex = BeatToNoteRow( fBeat ); - unsigned i; - for( i=0; i iIndex ) break; - return m_BPMSegments[i]; + return i; } +BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat ) +{ + static BPMSegment empty; + if( m_BPMSegments.empty() ) + { + empty = BPMSegment(); + return empty; + } + + int i = GetBPMSegmentIndexAtBeat( fBeat ); + return m_BPMSegments[i]; +} void TimingData::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const { diff --git a/stepmania/src/TimingData.h b/stepmania/src/TimingData.h index 87196bea70..300998c53f 100644 --- a/stepmania/src/TimingData.h +++ b/stepmania/src/TimingData.h @@ -5,6 +5,8 @@ #include "NoteTypes.h" +#define COMPARE(x) if(x!=other.x) return false; + struct BPMSegment { BPMSegment() { m_iStartIndex = -1; m_fBPS = -1; } @@ -14,6 +16,14 @@ struct BPMSegment void SetBPM( float f ); float GetBPM() const; + + bool operator==( const BPMSegment &other ) + { + COMPARE( m_iStartIndex ); + COMPARE( m_fBPS ); + return true; + } + bool operator!=( const BPMSegment &other ) { return !operator==(other); } }; struct StopSegment @@ -22,6 +32,14 @@ struct StopSegment StopSegment( int s, float f ) { m_iStartRow = s; m_fStopSeconds = f; } int m_iStartRow; float m_fStopSeconds; + + bool operator==( const StopSegment &other ) + { + COMPARE( m_iStartRow ); + COMPARE( m_fStopSeconds ); + return true; + } + bool operator!=( const StopSegment &other ) { return !operator==(other); } }; class TimingData @@ -36,6 +54,7 @@ public: void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ); void AddBPMSegment( const BPMSegment &seg ); void AddStopSegment( const StopSegment &seg ); + int GetBPMSegmentIndexAtBeat( float fBeat ); BPMSegment& GetBPMSegmentAtBeat( float fBeat ); void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const; @@ -49,6 +68,19 @@ public: float GetElapsedTimeFromBeat( float fBeat ) const; bool HasBpmChangesOrStops() const; + bool operator==( const TimingData &other ) + { + COMPARE( m_BPMSegments.size() ); + for( int i=0; i