diff --git a/stepmania/src/GameplayAssist.cpp b/stepmania/src/GameplayAssist.cpp new file mode 100644 index 0000000000..5a93f2ccd0 --- /dev/null +++ b/stepmania/src/GameplayAssist.cpp @@ -0,0 +1,82 @@ +#include "global.h" +#include "GameplayAssist.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "RageSoundManager.h" +#include "CommonMetrics.h" +#include "song.h" +#include "NoteData.h" + +void GameplayAssist::Init() +{ + m_soundAssistTick.Load( THEME->GetPathS("ScreenEdit","assist tick"), true ); +} + +void GameplayAssist::PlayTicks( const NoteData &nd ) +{ + if( !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ) + return; + + /* Sound cards have a latency between when a sample is Play()ed and when the sound + * will start coming out the speaker. Compensate for this by boosting fPositionSeconds + * ahead. This is just to make sure that we request the sound early enough for it to + * come out on time; the actual precise timing is handled by SetStartTime. */ + float fPositionSeconds = GAMESTATE->m_fMusicSeconds; + fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f; + const float fSongBeat = GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); + + const int iSongRow = max( 0, BeatToNoteRowNotRounded( fSongBeat ) ); + static int iRowLastCrossed = -1; + if( iSongRow < iRowLastCrossed ) + iRowLastCrossed = iSongRow; + + int iTickRow = -1; + // for each index we crossed since the last update: + FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) + if( nd.IsThereATapOrHoldHeadAtRow( r ) ) + iTickRow = r; + + iRowLastCrossed = iSongRow; + + if( iTickRow != -1 ) + { + const float fTickBeat = NoteRowToBeat( iTickRow ); + const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); + float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; + fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ + + RageSoundParams p; + p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); + m_soundAssistTick.Play( &p ); + } +} + +void GameplayAssist::StopPlaying() +{ + m_soundAssistTick.StopPlaying(); +} + +/* + * (c) 2003-2006 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/GameplayAssist.h b/stepmania/src/GameplayAssist.h new file mode 100644 index 0000000000..87bc0f3c28 --- /dev/null +++ b/stepmania/src/GameplayAssist.h @@ -0,0 +1,46 @@ +/* GameplayAssist - Encapsulate playing of handclap and metronome. */ + +#ifndef GameplayAssist_H +#define GameplayAssist_H + +#include "RageSound.h" + +class NoteData; + +class GameplayAssist +{ +public: + void Init(); + void PlayTicks( const NoteData &nd ); + void StopPlaying(); +private: + RageSound m_soundAssistTick; + +}; + +#endif + +/* + * (c) 2003-2006 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/Makefile.am b/stepmania/src/Makefile.am index e661144600..2c6c311e23 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -102,6 +102,7 @@ EnumHelper.cpp EnumHelper.h \ Font.cpp Font.h \ FontCharAliases.cpp FontCharAliases.h \ FontCharmaps.cpp FontCharmaps.h Game.cpp Game.h GameCommand.cpp GameCommand.h \ +GameplayAssist.cpp GameplayAssist.h \ GameConstantsAndTypes.cpp GameConstantsAndTypes.h \ GamePreferences.cpp GamePreferences.h \ GameInput.cpp GameInput.h Grade.cpp Grade.h \ diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 2a911dbcbb..5a9fb0675a 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -771,7 +771,7 @@ void ScreenEdit::Init() m_soundValueDecrease.Load( THEME->GetPathS("ScreenEdit","value decrease"), true ); m_soundSwitchSteps.Load( THEME->GetPathS("ScreenEdit","switch steps") ); m_soundSave.Load( THEME->GetPathS("ScreenEdit","save") ); - m_soundAssistTick.Load( THEME->GetPathS("ScreenEdit","assist tick"), true ); + m_GameplayAssist.Init(); m_soundMusic.Load( m_pSong->GetMusicPath() ); @@ -804,42 +804,10 @@ void ScreenEdit::EndScreen() // play assist ticks void ScreenEdit::PlayTicks() { - if( !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick || m_EditState != STATE_PLAYING ) + if( m_EditState != STATE_PLAYING ) return; - - /* Sound cards have a latency between when a sample is Play()ed and when the sound - * will start coming out the speaker. Compensate for this by boosting fPositionSeconds - * ahead. This is just to make sure that we request the sound early enough for it to - * come out on time; the actual precise timing is handled by SetStartTime. */ - float fPositionSeconds = GAMESTATE->m_fMusicSeconds; - fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f; - const float fSongBeat = GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); - const int iSongRow = max( 0, BeatToNoteRowNotRounded( fSongBeat ) ); - static int iRowLastCrossed = -1; - if( iSongRow < iRowLastCrossed ) - iRowLastCrossed = iSongRow; - - int iTickRow = -1; - const NoteData &nd = m_Player->GetNoteData(); - // for each index we crossed since the last update: - FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) - if( nd.IsThereATapOrHoldHeadAtRow( r ) ) - iTickRow = r; - - iRowLastCrossed = iSongRow; - - if( iTickRow != -1 ) - { - const float fTickBeat = NoteRowToBeat( iTickRow ); - const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); - float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; - fSecondsUntil /= m_soundMusic.GetPlaybackRate(); /* 2x music rate means the time until the tick is halved */ - - RageSoundParams p; - p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); - m_soundAssistTick.Play( &p ); - } + m_GameplayAssist.PlayTicks( m_Player->GetNoteData() ); } void ScreenEdit::PlayPreviewMusic() @@ -2136,7 +2104,7 @@ void ScreenEdit::TransitionEditState( EditState em ) /* If we're playing music, sample music or assist ticks when changing modes, stop. */ SOUND->StopMusic(); m_soundMusic.StopPlaying(); - m_soundAssistTick.StopPlaying(); + m_GameplayAssist.StopPlaying(); GAMESTATE->m_bGameplayLeadIn.Set( true ); if( bStateChanging ) diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h index 114f4d378d..8874eb398f 100644 --- a/stepmania/src/ScreenEdit.h +++ b/stepmania/src/ScreenEdit.h @@ -16,6 +16,7 @@ #include "ThemeMetric.h" #include "PlayerState.h" #include "GameInput.h" +#include "GameplayAssist.h" #include @@ -278,7 +279,7 @@ protected: float m_fBeatToReturnTo; RageSound m_soundMusic; - RageSound m_soundAssistTick; + GameplayAssist m_GameplayAssist; ThemeMetric EDIT_MODE; diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 25992e72f5..aa0a4d1b96 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -746,7 +746,7 @@ void ScreenGameplay::Init() m_textDebug.SetDrawOrder( DRAW_ORDER_TRANSITIONS-1 ); // just under transitions, over the foreground this->AddChild( &m_textDebug ); - m_soundAssistTick.Load( THEME->GetPathS(m_sName,"assist tick"), true ); + m_GameplayAssist.Init(); if( GAMESTATE->IsAnExtraStage() ) // only load if we're going to use it { @@ -913,7 +913,7 @@ ScreenGameplay::~ScreenGameplay() if( m_pSoundMusic ) m_pSoundMusic->StopPlaying(); - m_soundAssistTick.StopPlaying(); /* Stop any queued assist ticks. */ + m_GameplayAssist.StopPlaying(); NSMAN->ReportSongOver(); } @@ -1399,43 +1399,9 @@ void ScreenGameplay::PauseGame( bool bPause, GameController gc ) // play assist ticks void ScreenGameplay::PlayTicks() { - if( !GAMESTATE->m_SongOptions.GetCurrent().m_bAssistTick ) - return; - - /* Sound cards have a latency between when a sample is Play()ed and when the sound - * will start coming out the speaker. Compensate for this by boosting fPositionSeconds - * ahead. This is just to make sure that we request the sound early enough for it to - * come out on time; the actual precise timing is handled by SetStartTime. */ - float fPositionSeconds = GAMESTATE->m_fMusicSeconds; - fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f; - const float fSongBeat = GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); - - const int iSongRow = max( 0, BeatToNoteRowNotRounded( fSongBeat ) ); - static int iRowLastCrossed = -1; - if( iSongRow < iRowLastCrossed ) - iRowLastCrossed = -1; - - int iTickRow = -1; - // for each index we crossed since the last update: Player &player = *m_vPlayerInfo[0].m_pPlayer; const NoteData &nd = player.GetNoteData(); - FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) - if( nd.IsThereATapOrHoldHeadAtRow( r ) ) - iTickRow = r; - - iRowLastCrossed = iSongRow; - - if( iTickRow != -1 ) - { - const float fTickBeat = NoteRowToBeat( iTickRow ); - const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); - float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; - fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ - - RageSoundParams p; - p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); - m_soundAssistTick.Play( &p ); - } + m_GameplayAssist.PlayTicks( nd ); } /* Play announcer "type" if it's been at least fSeconds since the last announcer. */ @@ -2083,7 +2049,7 @@ void ScreenGameplay::BeginBackingOutFromGameplay() AbortGiveUp( false ); m_pSoundMusic->StopPlaying(); - m_soundAssistTick.StopPlaying(); /* Stop any queued assist ticks. */ + m_GameplayAssist.StopPlaying(); /* Stop any queued assist ticks. */ this->ClearMessageQueue(); @@ -2570,7 +2536,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_DancingState = STATE_OUTRO; AbortGiveUp( false ); m_pSoundMusic->StopPlaying(); - m_soundAssistTick.StopPlaying(); /* Stop any queued assist ticks. */ + m_GameplayAssist.StopPlaying(); /* Stop any queued assist ticks. */ TweenOffScreen(); m_Failed.StartTransitioning( SM_DoNextScreen ); diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index 796da85187..a83c9e0f3e 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -19,6 +19,7 @@ #include "PlayerState.h" #include "InputEventPlus.h" #include "SoundEffectControl.h" +#include "GameplayAssist.h" class LyricsLoader; class ActiveAttackList; @@ -220,7 +221,7 @@ protected: bool m_bZeroDeltaOnNextUpdate; - RageSound m_soundAssistTick; + GameplayAssist m_GameplayAssist; RageSound *m_pSoundMusic; BeginnerHelper m_BeginnerHelper; diff --git a/stepmania/src/StepMania-net2003.vcproj b/stepmania/src/StepMania-net2003.vcproj index 4697f4ce5d..5f0130d26e 100644 --- a/stepmania/src/StepMania-net2003.vcproj +++ b/stepmania/src/StepMania-net2003.vcproj @@ -899,6 +899,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +