Let CodeDetector detect Left+Right and Left-Right-Start codes on ScreenSelectMusic
This commit is contained in:
@@ -2023,8 +2023,10 @@ Easier1=Up,Up
|
||||
Easier2=MenuUp,MenuUp
|
||||
Harder1=Down,Down
|
||||
Harder2=MenuDown,MenuDown
|
||||
NextSort1=Up,Down,Up,Down
|
||||
NextSort2=MenuUp,MenuDown,MenuUp,MenuDown
|
||||
NextSort1=MenuLeft-MenuRight-Start
|
||||
NextSort2=MenuLeft+MenuRight
|
||||
AllSorts1=Up,Down,Up,Down
|
||||
AllSorts2=MenuUp,MenuDown,MenuUp,MenuDown
|
||||
Mirror=Up,Left,Right,Left,Right
|
||||
Left=Up,Down,Right,Left
|
||||
Right=Up,Down,Left,Right
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "PlayerOptions.h"
|
||||
#include "GameState.h"
|
||||
#include "InputQueue.h"
|
||||
#include "InputMapper.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "RageLog.h"
|
||||
#include "GameDef.h"
|
||||
@@ -28,6 +29,8 @@ const CString g_sCodeNames[CodeDetector::NUM_CODES] = {
|
||||
"Harder2",
|
||||
"NextSort1",
|
||||
"NextSort2",
|
||||
"AllSorts1",
|
||||
"AllSorts2",
|
||||
"Mirror",
|
||||
"Left",
|
||||
"Right",
|
||||
@@ -62,6 +65,12 @@ const unsigned MAX_CODE_LENGTH = 10;
|
||||
struct CodeCacheItem {
|
||||
int iNumButtons;
|
||||
GameButton buttons[MAX_CODE_LENGTH];
|
||||
enum Type {
|
||||
sequence, // press the buttons in sequence
|
||||
hold_and_press, // hold the first iNumButtons-1 buttons, then press the last
|
||||
tap // press all buttons simultaneously
|
||||
};
|
||||
Type m_Type;
|
||||
float fMaxSecondsBack;
|
||||
};
|
||||
CodeCacheItem g_CodeCacheItems[CodeDetector::NUM_CODES];
|
||||
@@ -73,7 +82,29 @@ bool CodeDetector::EnteredCode( GameController controller, Code code )
|
||||
return false;
|
||||
|
||||
const CodeCacheItem& item = g_CodeCacheItems[code];
|
||||
return INPUTQUEUE->MatchesPattern(controller, item.buttons, item.iNumButtons, item.fMaxSecondsBack);
|
||||
switch( item.m_Type )
|
||||
{
|
||||
case CodeCacheItem::sequence:
|
||||
return INPUTQUEUE->MatchesSequence(controller, item.buttons, item.iNumButtons, item.fMaxSecondsBack);
|
||||
case CodeCacheItem::hold_and_press:
|
||||
{
|
||||
// check that all but the last are being held
|
||||
for( int i=0; i<item.iNumButtons-1; i++ )
|
||||
{
|
||||
GameInput gi(controller, item.buttons[i]);
|
||||
if( !INPUTMAPPER->IsButtonDown(gi) )
|
||||
return false;
|
||||
}
|
||||
// just pressed the last button
|
||||
return INPUTQUEUE->MatchesSequence(controller, &item.buttons[item.iNumButtons-1], 1, 0.05f);
|
||||
}
|
||||
break;
|
||||
case CodeCacheItem::tap:
|
||||
return INPUTQUEUE->AllWerePressedRecently(controller, item.buttons, item.iNumButtons, item.fMaxSecondsBack);
|
||||
default:
|
||||
ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshCacheItem( int iIndex )
|
||||
@@ -83,7 +114,25 @@ void RefreshCacheItem( int iIndex )
|
||||
CString sCodeName = g_sCodeNames[iIndex];
|
||||
CString sButtonsNames = THEME->GetMetric("CodeDetector",sCodeName);
|
||||
CStringArray asButtonNames;
|
||||
split( sButtonsNames, ",", asButtonNames, false );
|
||||
|
||||
bool bHasAPlus = sButtonsNames.Find( '+' ) != -1;
|
||||
bool bHasADash = sButtonsNames.Find( '-' ) != -1;
|
||||
|
||||
if( bHasAPlus )
|
||||
{
|
||||
item.m_Type = CodeCacheItem::tap;
|
||||
split( sButtonsNames, "+", asButtonNames, false );
|
||||
}
|
||||
else if( bHasADash )
|
||||
{
|
||||
item.m_Type = CodeCacheItem::hold_and_press;
|
||||
split( sButtonsNames, "-", asButtonNames, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
item.m_Type = CodeCacheItem::sequence;
|
||||
split( sButtonsNames, ",", asButtonNames, false );
|
||||
}
|
||||
|
||||
if( asButtonNames.size() < 2 )
|
||||
{
|
||||
@@ -116,7 +165,20 @@ void RefreshCacheItem( int iIndex )
|
||||
}
|
||||
}
|
||||
|
||||
item.fMaxSecondsBack = item.iNumButtons*0.4f;
|
||||
switch( item.m_Type )
|
||||
{
|
||||
case CodeCacheItem::sequence:
|
||||
item.fMaxSecondsBack = item.iNumButtons*0.4f;
|
||||
break;
|
||||
case CodeCacheItem::hold_and_press:
|
||||
item.fMaxSecondsBack = -1.f; // not applicable
|
||||
break;
|
||||
case CodeCacheItem::tap:
|
||||
item.fMaxSecondsBack = 0.03f; // simultaneous
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
// if we make it here, we found all the buttons in the code
|
||||
}
|
||||
@@ -147,6 +209,11 @@ bool CodeDetector::EnteredNextSort( GameController controller )
|
||||
return EnteredCode(controller,CODE_NEXT_SORT1) || EnteredCode(controller,CODE_NEXT_SORT2);
|
||||
}
|
||||
|
||||
bool CodeDetector::EnteredAllSorts( GameController controller )
|
||||
{
|
||||
return EnteredCode(controller,CODE_ALL_SORTS1) || EnteredCode(controller,CODE_ALL_SORTS2);
|
||||
}
|
||||
|
||||
#define TOGGLE(v,a,b) if(v!=a) v=a; else v=b;
|
||||
#define FLOAT_TOGGLE(v) if(v!=1.f) v=1.f; else v=0.f;
|
||||
// XXX: Read the metrics file instead!
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
CODE_HARDER2,
|
||||
CODE_NEXT_SORT1,
|
||||
CODE_NEXT_SORT2,
|
||||
CODE_ALL_SORTS1,
|
||||
CODE_ALL_SORTS2,
|
||||
CODE_MIRROR,
|
||||
CODE_LEFT,
|
||||
CODE_RIGHT,
|
||||
@@ -57,6 +59,7 @@ public:
|
||||
static bool EnteredEasierDifficulty( GameController controller );
|
||||
static bool EnteredHarderDifficulty( GameController controller );
|
||||
static bool EnteredNextSort( GameController controller );
|
||||
static bool EnteredAllSorts( GameController controller );
|
||||
static bool DetectAndAdjustMusicOptions( GameController controller );
|
||||
static bool EnteredCode( GameController controller, Code code );
|
||||
static bool EnteredNextBannerGroup( GameController controller );
|
||||
|
||||
@@ -36,7 +36,7 @@ void InputQueue::RememberInput( const GameInput GameI )
|
||||
m_aQueue[c].push_back( GameButtonAndTime(GameI.button,RageTimer::GetTimeSinceStart()) );
|
||||
}
|
||||
|
||||
bool InputQueue::MatchesPattern( const GameController c, const MenuButton* button_sequence, const int iNumButtons, float fMaxSecondsBack )
|
||||
bool InputQueue::MatchesSequence( GameController c, const MenuButton* button_sequence, const int iNumButtons, float fMaxSecondsBack )
|
||||
{
|
||||
if( fMaxSecondsBack == -1 )
|
||||
fMaxSecondsBack = 0.4f + iNumButtons*0.15f;
|
||||
@@ -65,7 +65,7 @@ bool InputQueue::MatchesPattern( const GameController c, const MenuButton* butto
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputQueue::MatchesPattern( const GameController c, const GameButton* button_sequence, const int iNumButtons, float fMaxSecondsBack )
|
||||
bool InputQueue::MatchesSequence( GameController c, const GameButton* button_sequence, const int iNumButtons, float fMaxSecondsBack )
|
||||
{
|
||||
float fOldestTimeAllowed = RageTimer::GetTimeSinceStart() - fMaxSecondsBack;
|
||||
|
||||
@@ -87,3 +87,29 @@ bool InputQueue::MatchesPattern( const GameController c, const GameButton* butto
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputQueue::AllWerePressedRecently( GameController c, const GameButton* buttons, int iNumButtons, float fMaxSecondsBack )
|
||||
{
|
||||
float fOldestTimeAllowed = RageTimer::GetTimeSinceStart() - fMaxSecondsBack;
|
||||
|
||||
for( int b=0; b<iNumButtons; b++ )
|
||||
{
|
||||
GameButton button = buttons[b];
|
||||
|
||||
for( int queue_index=m_aQueue[c].size()-1; queue_index>=0; queue_index-- ) // iterate newest to oldest
|
||||
{
|
||||
GameButtonAndTime BandT = m_aQueue[c][queue_index];
|
||||
if( BandT.fTime < fOldestTimeAllowed ) // buttons are too old. Stop searching because we're not going to find a match
|
||||
return false;
|
||||
|
||||
if( BandT.button == button )
|
||||
goto found_button;
|
||||
}
|
||||
return false; // didn't find the button
|
||||
found_button:
|
||||
; // hush VC6
|
||||
}
|
||||
|
||||
m_aQueue[c].clear(); // empty the queue so we don't match on it again
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ public:
|
||||
InputQueue();
|
||||
|
||||
void RememberInput( GameInput );
|
||||
bool MatchesPattern( const GameController c, const GameButton* button_sequence, const int iNumButtons, float fMaxSecondsBack );
|
||||
bool MatchesPattern( const GameController c, const MenuButton* button_sequence, const int iNumButtons, float fMaxSecondsBack );
|
||||
bool MatchesSequence( GameController c, const GameButton* button_sequence, int iNumButtons, float fMaxSecondsBack );
|
||||
bool MatchesSequence( GameController c, const MenuButton* button_sequence, int iNumButtons, float fMaxSecondsBack );
|
||||
bool AllWerePressedRecently( GameController c, const GameButton* buttons, int iNumButtons, float fMaxSecondsBack );
|
||||
|
||||
protected:
|
||||
struct GameButtonAndTime
|
||||
|
||||
@@ -383,13 +383,14 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, int iNewChoice )
|
||||
if( GetPage(m_iChoice[pn]) != GetPage(iNewChoice) )
|
||||
return ChangePage( iNewChoice );
|
||||
|
||||
bool bMoveAll = SHARED_PREVIEW_AND_CURSOR || GetCurrentPage()!=PAGE_1;
|
||||
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(p) )
|
||||
continue; // skip
|
||||
|
||||
if( !SHARED_PREVIEW_AND_CURSOR &&
|
||||
(p!=pn && GetCurrentPage()==PAGE_1) )
|
||||
if( !bMoveAll && p!=pn )
|
||||
continue; // skip
|
||||
|
||||
const int iOldChoice = m_iChoice[p];
|
||||
|
||||
@@ -653,7 +653,6 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type,
|
||||
dir--;
|
||||
|
||||
m_MusicWheel.Move(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
if( type == IET_RELEASE ) return; // don't care
|
||||
@@ -682,35 +681,46 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type,
|
||||
|
||||
PlayerNumber pn = GAMESTATE->GetCurrentStyleDef()->ControllerToPlayerNumber( GameI.controller );
|
||||
|
||||
if( CodeDetector::EnteredEasierDifficulty(GameI.controller) )
|
||||
if( type == IET_FIRST_PRESS )
|
||||
{
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
EasierDifficulty( pn );
|
||||
return;
|
||||
}
|
||||
if( CodeDetector::EnteredHarderDifficulty(GameI.controller) )
|
||||
{
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
HarderDifficulty( pn );
|
||||
return;
|
||||
}
|
||||
if( CodeDetector::EnteredNextSort(GameI.controller) )
|
||||
{
|
||||
if( ( GAMESTATE->IsExtraStage() && !PREFSMAN->m_bPickExtraStage ) || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
m_MusicWheel.ChangeSort( SORT_MENU );
|
||||
return;
|
||||
}
|
||||
if( !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() && CodeDetector::DetectAndAdjustMusicOptions(GameI.controller) )
|
||||
{
|
||||
m_soundOptionsChange.Play();
|
||||
UpdateOptionsDisplays();
|
||||
return;
|
||||
if( CodeDetector::EnteredEasierDifficulty(GameI.controller) )
|
||||
{
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
EasierDifficulty( pn );
|
||||
return;
|
||||
}
|
||||
if( CodeDetector::EnteredHarderDifficulty(GameI.controller) )
|
||||
{
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
HarderDifficulty( pn );
|
||||
return;
|
||||
}
|
||||
if( CodeDetector::EnteredAllSorts(GameI.controller) )
|
||||
{
|
||||
if( ( GAMESTATE->IsExtraStage() && !PREFSMAN->m_bPickExtraStage ) || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
m_MusicWheel.ChangeSort( SORT_MENU );
|
||||
return;
|
||||
}
|
||||
if( CodeDetector::EnteredNextSort(GameI.controller) )
|
||||
{
|
||||
if( ( GAMESTATE->IsExtraStage() && !PREFSMAN->m_bPickExtraStage ) || GAMESTATE->IsExtraStage2() )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
m_MusicWheel.NextSort();
|
||||
return;
|
||||
}
|
||||
if( !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() && CodeDetector::DetectAndAdjustMusicOptions(GameI.controller) )
|
||||
{
|
||||
m_soundOptionsChange.Play();
|
||||
UpdateOptionsDisplays();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler
|
||||
@@ -839,18 +849,18 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
|
||||
void ScreenSelectMusic::MenuStart( PlayerNumber pn )
|
||||
{
|
||||
if( pn != PLAYER_INVALID &&
|
||||
INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_LEFT) ) &&
|
||||
INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_RIGHT) ) )
|
||||
{
|
||||
// if( pn != PLAYER_INVALID &&
|
||||
// INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_LEFT) ) &&
|
||||
// INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_RIGHT) ) )
|
||||
// {
|
||||
// if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
// m_soundLocked.Play();
|
||||
// else
|
||||
{
|
||||
m_MusicWheel.NextSort();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// {
|
||||
// m_MusicWheel.NextSort();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// this needs to check whether valid Steps are selected!
|
||||
|
||||
Reference in New Issue
Block a user