From 4fd2111fda6798e2eb18c9903a97e89f886d49ea Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 11 Jan 2004 09:42:37 +0000 Subject: [PATCH] Fix music wheel weirdness: tap Left + tap Right would sometimes jump 2 songs in one direction wheel stuck spinning if button release while wheel is flying_off_before_sort or flying_off_after_sort --- stepmania/src/MusicWheel.cpp | 17 +++++--- stepmania/src/ScreenSelectMusic.cpp | 67 ++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index dd366fdb5b..de68648fe6 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -1418,8 +1418,18 @@ void MusicWheel::Move(int n) /* If we're not selecting, discard this. We won't ignore it; we'll * get called again every time the key is repeated. */ - if( m_WheelState != STATE_SELECTING_MUSIC ) - return; + /* Still process Move(0) so we sometimes continue moving immediate + * after the sort change finished and before the repeat event causes a + * Move(0). -Chris */ + switch( m_WheelState ) + { + case STATE_SELECTING_MUSIC: + case STATE_FLYING_OFF_BEFORE_NEXT_SORT: + case STATE_FLYING_ON_AFTER_NEXT_SORT: + break; + default: + return; // don't continue + } if(m_Moving != 0 && n == 0 && m_TimeBeforeMovingBegins == 0) { @@ -1437,9 +1447,6 @@ void MusicWheel::Move(int n) m_TimeBeforeMovingBegins = 1/4.0f; m_SpinSpeed = float(PREFSMAN->m_iMusicWheelSwitchSpeed); m_Moving = n; - - if( fabsf(m_fPositionOffsetFromSelection) > 0.5f ) // wheel is very busy spinning - return; if(m_Moving) ChangeMusic(m_Moving); diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index 774d9aee7f..fcb3ba0e85 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -637,6 +637,7 @@ void ScreenSelectMusic::Update( float fDeltaTime ) void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) { // LOG->Trace( "ScreenSelectMusic::Input()" ); + if( DeviceI.device == DEVICE_KEYBOARD && DeviceI.button == SDLK_F9 ) { @@ -649,22 +650,66 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type, return; } + if( MenuI.button == MENU_BUTTON_RIGHT || MenuI.button == MENU_BUTTON_LEFT ) { - if( !MenuI.IsValid() ) return; if( !GAMESTATE->IsHumanPlayer(MenuI.player) ) return; /* If we're rouletting, hands off. */ if(m_MusicWheel.IsRouletting()) return; - int dir = 0; - if(INPUTMAPPER->IsButtonDown( MenuInput(MenuI.player, MENU_BUTTON_RIGHT) ) ) - dir++; - if(INPUTMAPPER->IsButtonDown( MenuInput(MenuI.player, MENU_BUTTON_LEFT) ) ) - dir--; - - m_MusicWheel.Move(dir); + // TRICKY: There's lots of weirdness that can happen here when tapping + // Left and Right quickly, like when changing sort. + bool bLeftPressed = INPUTMAPPER->IsButtonDown( MenuInput(MenuI.player, MENU_BUTTON_LEFT) ); + bool bRightPressed = INPUTMAPPER->IsButtonDown( MenuInput(MenuI.player, MENU_BUTTON_RIGHT) ); + bool bLeftAndRightPressed = bLeftPressed && bRightPressed; + bool bLeftOrRightPressed = bLeftPressed || bRightPressed; + + switch( type ) + { + case IET_RELEASE: + // when a key is released, stop moving the wheel + if( !bLeftOrRightPressed ) + m_MusicWheel.Move( 0 ); + + // Reset the repeat timer when a key is released. + // This fixes jumping when you release Left and Right at the same + // time (e.g. after tapping Left+Right to change sort). + INPUTMAPPER->ResetKeyRepeat( MenuInput(MenuI.player, MENU_BUTTON_LEFT) ); + INPUTMAPPER->ResetKeyRepeat( MenuInput(MenuI.player, MENU_BUTTON_RIGHT) ); + break; + case IET_FIRST_PRESS: + if( MenuI.button == MENU_BUTTON_RIGHT ) + m_MusicWheel.Move( +1 ); + else + m_MusicWheel.Move( -1 ); + + // The wheel moves faster than one item between FIRST_PRESS + // and SLOW_REPEAT. Stop the wheel immediately after moving one + // item if both Left and Right are held. This way, we won't move + // another item + if( bLeftAndRightPressed ) + m_MusicWheel.Move( 0 ); + break; + case IET_SLOW_REPEAT: + case IET_FAST_REPEAT: + // We need to handle the repeat events to start the wheel spinning again + // when Left and Right are being held, then one is released. + if( bLeftAndRightPressed ) + { + // Don't spin if holding both buttons + m_MusicWheel.Move( 0 ); + } + else + { + if( MenuI.button == MENU_BUTTON_RIGHT ) + m_MusicWheel.Move( +1 ); + else + m_MusicWheel.Move( -1 ); + } + break; + } } if( type == IET_RELEASE ) return; // don't care @@ -693,6 +738,10 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type, PlayerNumber pn = GAMESTATE->GetCurrentStyleDef()->ControllerToPlayerNumber( GameI.controller ); + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler + + // TRICKY: Process codes after handing MenuLeft, MenuRight, MenuStart. + // This if( type == IET_FIRST_PRESS ) { if( CodeDetector::EnteredEasierDifficulty(GameI.controller) ) @@ -742,8 +791,6 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type, return; } } - - Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler }