add metronome

rename tick -> clap because "tick" implies a regular interval
This commit is contained in:
Chris Danford
2007-01-25 11:03:41 +00:00
parent 7e135b6789
commit 179f1b6480
6 changed files with 111 additions and 41 deletions
+51 -10
View File
@@ -9,12 +9,16 @@
void GameplayAssist::Init() void GameplayAssist::Init()
{ {
m_soundAssistTick.Load( THEME->GetPathS("ScreenEdit","assist tick"), true ); m_soundAssistClap.Load( THEME->GetPathS("GameplayAssist","clap"), true );
m_soundAssistMetronomeMeasure.Load( THEME->GetPathS("GameplayAssist","metronome measure"), true );
m_soundAssistMetronomeBeat.Load( THEME->GetPathS("GameplayAssist","metronome beat"), true );
} }
void GameplayAssist::PlayTicks( const NoteData &nd ) void GameplayAssist::PlayTicks( const NoteData &nd )
{ {
if( !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ) bool bClap = GAMESTATE->m_SongOptions.GetCurrent().m_bAssistClap;
bool bMetronome = GAMESTATE->m_SongOptions.GetCurrent().m_bAssistMetronome;
if( !bClap && !bMetronome )
return; return;
/* Sound cards have a latency between when a sample is Play()ed and when the sound /* Sound cards have a latency between when a sample is Play()ed and when the sound
@@ -30,30 +34,67 @@ void GameplayAssist::PlayTicks( const NoteData &nd )
if( iSongRow < iRowLastCrossed ) if( iSongRow < iRowLastCrossed )
iRowLastCrossed = iSongRow; iRowLastCrossed = iSongRow;
int iTickRow = -1; if( bClap )
{
int iClapRow = -1;
// for each index we crossed since the last update: // for each index we crossed since the last update:
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 )
if( nd.IsThereATapOrHoldHeadAtRow( r ) ) if( nd.IsThereATapOrHoldHeadAtRow( r ) )
iTickRow = r; iClapRow = r;
iRowLastCrossed = iSongRow; if( iClapRow != -1 )
if( iTickRow != -1 )
{ {
const float fTickBeat = NoteRowToBeat( iTickRow ); const float fTickBeat = NoteRowToBeat( iClapRow );
const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat );
float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds;
fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */
RageSoundParams p; RageSoundParams p;
p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS);
m_soundAssistTick.Play( &p ); m_soundAssistClap.Play( &p );
} }
}
if( bMetronome )
{
//iRowLastCrossed+1, iSongRow+1
int iLastCrossedBeat = iRowLastCrossed / ROWS_PER_BEAT;
int iCurrentBeat = iSongRow / ROWS_PER_BEAT;
int iMetronomeRow = -1;
bool bIsMeasure = false;
if( iLastCrossedBeat != iCurrentBeat )
{
iMetronomeRow = iCurrentBeat * ROWS_PER_BEAT;
bIsMeasure = (iCurrentBeat % BEATS_PER_MEASURE) == 0;
}
if( iMetronomeRow != -1 )
{
const float fTickBeat = NoteRowToBeat( iMetronomeRow );
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);
if( bIsMeasure )
m_soundAssistMetronomeMeasure.Play( &p );
else
m_soundAssistMetronomeBeat.Play( &p );
}
}
iRowLastCrossed = iSongRow;
} }
void GameplayAssist::StopPlaying() void GameplayAssist::StopPlaying()
{ {
m_soundAssistTick.StopPlaying(); m_soundAssistClap.StopPlaying();
m_soundAssistMetronomeMeasure.StopPlaying();
m_soundAssistMetronomeBeat.StopPlaying();
} }
/* /*
+3 -1
View File
@@ -14,7 +14,9 @@ public:
void PlayTicks( const NoteData &nd ); void PlayTicks( const NoteData &nd );
void StopPlaying(); void StopPlaying();
private: private:
RageSound m_soundAssistTick; RageSound m_soundAssistClap;
RageSound m_soundAssistMetronomeMeasure;
RageSound m_soundAssistMetronomeBeat;
}; };
+26 -8
View File
@@ -413,7 +413,7 @@ void ChangeVolume( float fDelta )
static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" ); static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" );
static LocalizedString ASSIST_TICK ( "ScreenDebugOverlay", "AssistTick" ); static LocalizedString ASSIST ( "ScreenDebugOverlay", "Assist" );
static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" ); static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" );
static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" ); static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" );
static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" ); static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" );
@@ -478,16 +478,34 @@ class DebugLineAutoplay : public IDebugLine
} }
}; };
class DebugLineAssistTick : public IDebugLine class DebugLineAssist : public IDebugLine
{ {
virtual RString GetDescription() { return ASSIST_TICK.GetValue(); } virtual RString GetDescription() { return ASSIST.GetValue(); }
virtual Type GetType() const { return gameplay_only; } virtual Type GetType() const { return gameplay_only; }
virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistTick; } virtual RString GetValue() {
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 Do( RString &sMessageOut ) virtual void Do( RString &sMessageOut )
{ {
bool bAssistTick = !GAMESTATE->m_SongOptions.GetSong().m_bAssistTick; ASSERT( GAMESTATE->m_MasterPlayerNumber != PLAYER_INVALID );
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_bAssistTick, bAssistTick ); bool bHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) );
MESSAGEMAN->Broadcast( Message_AssistTickChanged ); 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_Song, m_bAssistMetronome, b );
else
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_bAssistClap, b );
IDebugLine::Do( sMessageOut ); IDebugLine::Do( sMessageOut );
} }
}; };
@@ -918,7 +936,7 @@ class DebugLineUptime : public IDebugLine
*/ */
DECLARE_ONE( DebugLineAutoplay ); DECLARE_ONE( DebugLineAutoplay );
DECLARE_ONE( DebugLineAssistTick ); DECLARE_ONE( DebugLineAssist );
DECLARE_ONE( DebugLineAutosync ); DECLARE_ONE( DebugLineAutosync );
DECLARE_ONE( DebugLineCoinMode ); DECLARE_ONE( DebugLineCoinMode );
DECLARE_ONE( DebugLineSlow ); DECLARE_ONE( DebugLineSlow );
+2 -2
View File
@@ -1374,7 +1374,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
DoHelp(); DoHelp();
break; break;
case EDIT_BUTTON_TOGGLE_ASSIST_TICK: case EDIT_BUTTON_TOGGLE_ASSIST_TICK:
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistTick, !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ); SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistClap, !GAMESTATE->m_SongOptions.GetStage().m_bAssistClap );
break; break;
case EDIT_BUTTON_OPEN_NEXT_STEPS: case EDIT_BUTTON_OPEN_NEXT_STEPS:
case EDIT_BUTTON_OPEN_PREV_STEPS: case EDIT_BUTTON_OPEN_PREV_STEPS:
@@ -2016,7 +2016,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
TransitionEditState( STATE_EDITING ); TransitionEditState( STATE_EDITING );
break; break;
case EDIT_BUTTON_TOGGLE_ASSIST_TICK: case EDIT_BUTTON_TOGGLE_ASSIST_TICK:
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistTick, !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ); SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistClap, !GAMESTATE->m_SongOptions.GetStage().m_bAssistClap );
break; break;
case EDIT_BUTTON_TOGGLE_AUTOPLAY: case EDIT_BUTTON_TOGGLE_AUTOPLAY:
{ {
+16 -8
View File
@@ -10,7 +10,8 @@ void SongOptions::Init()
m_DrainType = DRAIN_NORMAL; m_DrainType = DRAIN_NORMAL;
m_iBatteryLives = 4; m_iBatteryLives = 4;
m_FailType = FAIL_IMMEDIATE; m_FailType = FAIL_IMMEDIATE;
m_bAssistTick = false; m_bAssistClap = false;
m_bAssistMetronome = false;
m_fMusicRate = 1.0f; m_fMusicRate = 1.0f;
m_SpeedfMusicRate = 1.0f; m_SpeedfMusicRate = 1.0f;
m_fHaste = 0.0f; m_fHaste = 0.0f;
@@ -32,7 +33,8 @@ void SongOptions::Approach( const SongOptions& other, float fDeltaSeconds )
DO_COPY( m_iBatteryLives ); DO_COPY( m_iBatteryLives );
APPROACH( fMusicRate ); APPROACH( fMusicRate );
APPROACH( fHaste ); APPROACH( fHaste );
DO_COPY( m_bAssistTick ); DO_COPY( m_bAssistClap );
DO_COPY( m_bAssistMetronome );
DO_COPY( m_AutosyncType ); DO_COPY( m_AutosyncType );
DO_COPY( m_SoundEffectType ); DO_COPY( m_SoundEffectType );
DO_COPY( m_bSaveScore ); DO_COPY( m_bSaveScore );
@@ -107,13 +109,17 @@ void SongOptions::GetMods( vector<RString> &AddTo ) const
case SOUNDEFFECT_PITCH: AddTo.push_back("EffectPitch"); break; case SOUNDEFFECT_PITCH: AddTo.push_back("EffectPitch"); break;
default: ASSERT(0); default: ASSERT(0);
} }
if( m_bAssistClap )
AddTo.push_back( "Clap" );
if( m_bAssistMetronome )
AddTo.push_back( "Metronome" );
} }
void SongOptions::GetLocalizedMods( vector<RString> &AddTo ) const void SongOptions::GetLocalizedMods( vector<RString> &v ) const
{ {
vector<RString> vMods; GetMods( v );
GetMods( vMods ); FOREACH( RString, v, s )
FOREACH( RString, vMods, s )
{ {
*s = CommonMetrics::LocalizeOptionItem( *s, true ); *s = CommonMetrics::LocalizeOptionItem( *s, true );
} }
@@ -190,7 +196,8 @@ void SongOptions::FromString( const RString &sOptions )
m_FailType = so.m_FailType; m_FailType = so.m_FailType;
} }
else if( sBit == "assisttick" ) m_bAssistTick = on; else if( sBit == "clap" ) m_bAssistClap = on;
else if( sBit == "metronome" ) m_bAssistMetronome = on;
else if( sBit == "autosync" || sBit == "autosyncsong" ) else if( sBit == "autosync" || sBit == "autosyncsong" )
m_AutosyncType = on ? AUTOSYNC_SONG : AUTOSYNC_OFF; m_AutosyncType = on ? AUTOSYNC_SONG : AUTOSYNC_OFF;
else if( sBit == "autosyncmachine" ) else if( sBit == "autosyncmachine" )
@@ -220,7 +227,8 @@ bool SongOptions::operator==( const SongOptions &other ) const
COMPARE( m_FailType ); COMPARE( m_FailType );
COMPARE( m_fMusicRate ); COMPARE( m_fMusicRate );
COMPARE( m_fHaste ); COMPARE( m_fHaste );
COMPARE( m_bAssistTick ); COMPARE( m_bAssistClap );
COMPARE( m_bAssistMetronome );
COMPARE( m_AutosyncType ); COMPARE( m_AutosyncType );
COMPARE( m_SoundEffectType ); COMPARE( m_SoundEffectType );
COMPARE( m_bSaveScore ); COMPARE( m_bSaveScore );
+2 -1
View File
@@ -30,7 +30,8 @@ public:
FailType m_FailType; FailType m_FailType;
float m_fMusicRate, m_SpeedfMusicRate; float m_fMusicRate, m_SpeedfMusicRate;
float m_fHaste, m_SpeedfHaste; float m_fHaste, m_SpeedfHaste;
bool m_bAssistTick; bool m_bAssistClap;
bool m_bAssistMetronome;
enum AutosyncType { enum AutosyncType {
AUTOSYNC_OFF, AUTOSYNC_OFF,
AUTOSYNC_SONG, AUTOSYNC_SONG,