From 927b3df18b65a961a76ae869c85ee61ccb44f62a Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 16 Mar 2007 01:34:54 +0000 Subject: [PATCH] Further unify codes. Allow using hold-button, multiple-presses and sequences in the same code. Allow handling repeats and releases. changes: MenuLeft,MenuRight -> MenuLeft,MenuRight (sequence) MenuLeft-MenuRight -> MenuLeft-MenuRight (tap) MenuLeft+MenuRight -> @MenuLeft-MenuRight (hold-and-press) new: @MenuLeft-+MenuRight press MenuRighthold while holding MenuLeft; triggers on MenuRight repeats @MenuLeft-+MenuRight release MenuRight while holding MenuLeft @MenuLeft-MenuRight,@MenuLeft-MenuRight press MenuRight twice while holding MenuLeft MenuLeft-MenuRight,MenuUp-MenuDown press MenuLeft and MenuRight simultaneously, then press MenuUp and MenuDown simultaneously --- stepmania/src/InputQueue.cpp | 137 +++++++++++++++++------------------ stepmania/src/InputQueue.h | 6 +- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/stepmania/src/InputQueue.cpp b/stepmania/src/InputQueue.cpp index f6528c977e..8659fe1bf2 100644 --- a/stepmania/src/InputQueue.cpp +++ b/stepmania/src/InputQueue.cpp @@ -9,6 +9,7 @@ InputQueue* INPUTQUEUE = NULL; // global and accessable from anywhere in our program +const unsigned MAX_INPUT_QUEUE_LENGTH = 32; InputQueue::InputQueue() { @@ -20,8 +21,6 @@ void InputQueue::RememberInput( const InputEventPlus &iep ) { if( !iep.GameI.IsValid() ) return; - if( iep.type != IET_FIRST_PRESS ) - return; int c = iep.GameI.controller; if( m_aQueue[c].size() >= MAX_INPUT_QUEUE_LENGTH ) // full @@ -72,23 +71,28 @@ bool InputQueueCode::EnteredCode( GameController controller ) const int iQueueIndex = aQueue.size()-1; while( iQueueIndex >= 0 ) { + /* If the buttons are too old, stop searching because we're not going to find a match. */ + if( aQueue[iQueueIndex].DeviceI.ts < OldestTimeAllowed ) + return false; + + /* If the last press is an input type we're not interested in, skip it + * and look again. */ + const ButtonPress &Press = m_aPresses[iSequenceIndex]; + if( !Press.m_InputTypes[aQueue[iQueueIndex].type] ) { - const InputEventPlus &iep = aQueue[iQueueIndex]; - if( iep.DeviceI.ts < OldestTimeAllowed ) - return false; + --iQueueIndex; + continue; } /* Search backwards for all of Press.m_aButtonsToPress pressed within g_fTapThreshold seconds - * with m_aButtonsToHold pressed. */ - const ButtonPress &Press = m_aPresses[iSequenceIndex]; + * with m_aButtonsToHold pressed. Start looking at iQueueIndex. */ + RageTimer OldestTimeAllowedForTap( aQueue[iQueueIndex].DeviceI.ts ); + OldestTimeAllowedForTap += -g_fSimultaneousThreshold; + bool bMatched = false; int iMinSearchIndexUsed = iQueueIndex; for( int b=0; b<(int) Press.m_aButtonsToPress.size(); ++b ) { - /* Search backwards for the buttons in this tap, within the tap threshold since iQueueIndex. */ - RageTimer OldestTimeAllowedForTap( aQueue[iQueueIndex].DeviceI.ts ); - OldestTimeAllowedForTap += -g_fSimultaneousThreshold; - const InputEventPlus *pIEP = NULL; int iQueueSearchIndex = iQueueIndex; for( ; iQueueSearchIndex>=0; --iQueueSearchIndex ) // iterate newest to oldest @@ -97,6 +101,9 @@ bool InputQueueCode::EnteredCode( GameController controller ) const if( iep.DeviceI.ts < OldestTimeAllowedForTap ) // buttons are too old. Stop searching because we're not going to find a match break; + if( !Press.m_InputTypes[iep.type] ) + continue; + if( iep.GameI.button == Press.m_aButtonsToPress[b] ) { pIEP = &iep; @@ -152,72 +159,64 @@ bool InputQueueCode::Load( RString sButtonsNames ) { m_aPresses.clear(); - vector asButtonNames; - - bool bHasAPlus = sButtonsNames.find( '+' ) != string::npos; - bool bHasADash = sButtonsNames.find( '-' ) != string::npos; - - if( bHasAPlus ) + vector asPresses; + split( sButtonsNames, ",", asPresses, false ); + FOREACH( RString, asPresses, sPress ) { - // press all buttons simultaneously - split( sButtonsNames, "+", asButtonNames, false ); - } - else if( bHasADash ) - { - // hold the first iNumButtons-1 buttons, then press the last - split( sButtonsNames, "-", asButtonNames, false ); - } - else - { - // press the buttons in sequence - split( sButtonsNames, ",", asButtonNames, false ); - } + vector asButtonNames; - if( asButtonNames.size() < 1 ) - { - if( sButtonsNames != "" ) - LOG->Trace( "Ignoring empty code \"%s\".", sButtonsNames.c_str() ); - return false; - } + split( *sPress, "-", asButtonNames, false ); - vector buttons; - for( unsigned i=0; iGetInputScheme()->ButtonNameToIndex( sButtonName ); - if( gb == GameButton_Invalid ) + if( asButtonNames.size() < 1 ) { - LOG->Trace( "The code \"%s\" contains an unrecognized button \"%s\".", sButtonsNames.c_str(), sButtonName.c_str() ); - m_aPresses.clear(); + if( sButtonsNames != "" ) + LOG->Trace( "Ignoring empty code \"%s\".", sButtonsNames.c_str() ); return false; } - buttons.push_back( gb ); - } + m_aPresses.push_back( ButtonPress() ); + for( unsigned i=0; iGetInputScheme()->ButtonNameToIndex( sButtonName ); + if( gb == GameButton_Invalid ) + { + LOG->Trace( "The code \"%s\" contains an unrecognized button \"%s\".", sButtonsNames.c_str(), sButtonName.c_str() ); + m_aPresses.clear(); + return false; + } + + if( bHold ) + m_aPresses.back().m_aButtonsToHold.push_back( gb ); + else + m_aPresses.back().m_aButtonsToPress.push_back( gb ); } } diff --git a/stepmania/src/InputQueue.h b/stepmania/src/InputQueue.h index 27050b1953..112055c6b1 100644 --- a/stepmania/src/InputQueue.h +++ b/stepmania/src/InputQueue.h @@ -4,8 +4,8 @@ #define INPUT_QUEUE_H #include "GameInput.h" +#include "InputFilter.h" -const unsigned MAX_INPUT_QUEUE_LENGTH = 16; class InputEventPlus; class RageTimer; @@ -32,9 +32,11 @@ public: private: struct ButtonPress { - ButtonPress() { m_bAllowIntermediatePresses = true; } + ButtonPress() { m_bAllowIntermediatePresses = false; memset( m_InputTypes, 0, sizeof(m_InputTypes) ); m_InputTypes[IET_FIRST_PRESS] = true; } vector m_aButtonsToHold; vector m_aButtonsToPress; + + bool m_InputTypes[NUM_InputEventType]; bool m_bAllowIntermediatePresses; }; vector m_aPresses;