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
|
Easier2=MenuUp,MenuUp
|
||||||
Harder1=Down,Down
|
Harder1=Down,Down
|
||||||
Harder2=MenuDown,MenuDown
|
Harder2=MenuDown,MenuDown
|
||||||
NextSort1=Up,Down,Up,Down
|
NextSort1=MenuLeft-MenuRight-Start
|
||||||
NextSort2=MenuUp,MenuDown,MenuUp,MenuDown
|
NextSort2=MenuLeft+MenuRight
|
||||||
|
AllSorts1=Up,Down,Up,Down
|
||||||
|
AllSorts2=MenuUp,MenuDown,MenuUp,MenuDown
|
||||||
Mirror=Up,Left,Right,Left,Right
|
Mirror=Up,Left,Right,Left,Right
|
||||||
Left=Up,Down,Right,Left
|
Left=Up,Down,Right,Left
|
||||||
Right=Up,Down,Left,Right
|
Right=Up,Down,Left,Right
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "PlayerOptions.h"
|
#include "PlayerOptions.h"
|
||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "InputQueue.h"
|
#include "InputQueue.h"
|
||||||
|
#include "InputMapper.h"
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "GameDef.h"
|
#include "GameDef.h"
|
||||||
@@ -28,6 +29,8 @@ const CString g_sCodeNames[CodeDetector::NUM_CODES] = {
|
|||||||
"Harder2",
|
"Harder2",
|
||||||
"NextSort1",
|
"NextSort1",
|
||||||
"NextSort2",
|
"NextSort2",
|
||||||
|
"AllSorts1",
|
||||||
|
"AllSorts2",
|
||||||
"Mirror",
|
"Mirror",
|
||||||
"Left",
|
"Left",
|
||||||
"Right",
|
"Right",
|
||||||
@@ -62,6 +65,12 @@ const unsigned MAX_CODE_LENGTH = 10;
|
|||||||
struct CodeCacheItem {
|
struct CodeCacheItem {
|
||||||
int iNumButtons;
|
int iNumButtons;
|
||||||
GameButton buttons[MAX_CODE_LENGTH];
|
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;
|
float fMaxSecondsBack;
|
||||||
};
|
};
|
||||||
CodeCacheItem g_CodeCacheItems[CodeDetector::NUM_CODES];
|
CodeCacheItem g_CodeCacheItems[CodeDetector::NUM_CODES];
|
||||||
@@ -73,7 +82,29 @@ bool CodeDetector::EnteredCode( GameController controller, Code code )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const CodeCacheItem& item = g_CodeCacheItems[code];
|
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 )
|
void RefreshCacheItem( int iIndex )
|
||||||
@@ -83,7 +114,25 @@ void RefreshCacheItem( int iIndex )
|
|||||||
CString sCodeName = g_sCodeNames[iIndex];
|
CString sCodeName = g_sCodeNames[iIndex];
|
||||||
CString sButtonsNames = THEME->GetMetric("CodeDetector",sCodeName);
|
CString sButtonsNames = THEME->GetMetric("CodeDetector",sCodeName);
|
||||||
CStringArray asButtonNames;
|
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 )
|
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
|
// 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);
|
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 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;
|
#define FLOAT_TOGGLE(v) if(v!=1.f) v=1.f; else v=0.f;
|
||||||
// XXX: Read the metrics file instead!
|
// XXX: Read the metrics file instead!
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ public:
|
|||||||
CODE_HARDER2,
|
CODE_HARDER2,
|
||||||
CODE_NEXT_SORT1,
|
CODE_NEXT_SORT1,
|
||||||
CODE_NEXT_SORT2,
|
CODE_NEXT_SORT2,
|
||||||
|
CODE_ALL_SORTS1,
|
||||||
|
CODE_ALL_SORTS2,
|
||||||
CODE_MIRROR,
|
CODE_MIRROR,
|
||||||
CODE_LEFT,
|
CODE_LEFT,
|
||||||
CODE_RIGHT,
|
CODE_RIGHT,
|
||||||
@@ -57,6 +59,7 @@ public:
|
|||||||
static bool EnteredEasierDifficulty( GameController controller );
|
static bool EnteredEasierDifficulty( GameController controller );
|
||||||
static bool EnteredHarderDifficulty( GameController controller );
|
static bool EnteredHarderDifficulty( GameController controller );
|
||||||
static bool EnteredNextSort( GameController controller );
|
static bool EnteredNextSort( GameController controller );
|
||||||
|
static bool EnteredAllSorts( GameController controller );
|
||||||
static bool DetectAndAdjustMusicOptions( GameController controller );
|
static bool DetectAndAdjustMusicOptions( GameController controller );
|
||||||
static bool EnteredCode( GameController controller, Code code );
|
static bool EnteredCode( GameController controller, Code code );
|
||||||
static bool EnteredNextBannerGroup( GameController controller );
|
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()) );
|
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 )
|
if( fMaxSecondsBack == -1 )
|
||||||
fMaxSecondsBack = 0.4f + iNumButtons*0.15f;
|
fMaxSecondsBack = 0.4f + iNumButtons*0.15f;
|
||||||
@@ -65,7 +65,7 @@ bool InputQueue::MatchesPattern( const GameController c, const MenuButton* butto
|
|||||||
return false;
|
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;
|
float fOldestTimeAllowed = RageTimer::GetTimeSinceStart() - fMaxSecondsBack;
|
||||||
|
|
||||||
@@ -87,3 +87,29 @@ bool InputQueue::MatchesPattern( const GameController c, const GameButton* butto
|
|||||||
}
|
}
|
||||||
return false;
|
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();
|
InputQueue();
|
||||||
|
|
||||||
void RememberInput( GameInput );
|
void RememberInput( GameInput );
|
||||||
bool MatchesPattern( const GameController c, const GameButton* button_sequence, const int iNumButtons, float fMaxSecondsBack );
|
bool MatchesSequence( GameController c, const GameButton* button_sequence, int iNumButtons, float fMaxSecondsBack );
|
||||||
bool MatchesPattern( const GameController c, const MenuButton* button_sequence, const 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:
|
protected:
|
||||||
struct GameButtonAndTime
|
struct GameButtonAndTime
|
||||||
|
|||||||
@@ -383,13 +383,14 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, int iNewChoice )
|
|||||||
if( GetPage(m_iChoice[pn]) != GetPage(iNewChoice) )
|
if( GetPage(m_iChoice[pn]) != GetPage(iNewChoice) )
|
||||||
return ChangePage( iNewChoice );
|
return ChangePage( iNewChoice );
|
||||||
|
|
||||||
|
bool bMoveAll = SHARED_PREVIEW_AND_CURSOR || GetCurrentPage()!=PAGE_1;
|
||||||
|
|
||||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||||
{
|
{
|
||||||
if( !GAMESTATE->IsHumanPlayer(p) )
|
if( !GAMESTATE->IsHumanPlayer(p) )
|
||||||
continue; // skip
|
continue; // skip
|
||||||
|
|
||||||
if( !SHARED_PREVIEW_AND_CURSOR &&
|
if( !bMoveAll && p!=pn )
|
||||||
(p!=pn && GetCurrentPage()==PAGE_1) )
|
|
||||||
continue; // skip
|
continue; // skip
|
||||||
|
|
||||||
const int iOldChoice = m_iChoice[p];
|
const int iOldChoice = m_iChoice[p];
|
||||||
|
|||||||
@@ -653,7 +653,6 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type,
|
|||||||
dir--;
|
dir--;
|
||||||
|
|
||||||
m_MusicWheel.Move(dir);
|
m_MusicWheel.Move(dir);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( type == IET_RELEASE ) return; // don't care
|
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 );
|
PlayerNumber pn = GAMESTATE->GetCurrentStyleDef()->ControllerToPlayerNumber( GameI.controller );
|
||||||
|
|
||||||
if( CodeDetector::EnteredEasierDifficulty(GameI.controller) )
|
if( type == IET_FIRST_PRESS )
|
||||||
{
|
{
|
||||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
if( CodeDetector::EnteredEasierDifficulty(GameI.controller) )
|
||||||
m_soundLocked.Play();
|
{
|
||||||
else
|
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||||
EasierDifficulty( pn );
|
m_soundLocked.Play();
|
||||||
return;
|
else
|
||||||
}
|
EasierDifficulty( pn );
|
||||||
if( CodeDetector::EnteredHarderDifficulty(GameI.controller) )
|
return;
|
||||||
{
|
}
|
||||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
if( CodeDetector::EnteredHarderDifficulty(GameI.controller) )
|
||||||
m_soundLocked.Play();
|
{
|
||||||
else
|
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||||
HarderDifficulty( pn );
|
m_soundLocked.Play();
|
||||||
return;
|
else
|
||||||
}
|
HarderDifficulty( pn );
|
||||||
if( CodeDetector::EnteredNextSort(GameI.controller) )
|
return;
|
||||||
{
|
}
|
||||||
if( ( GAMESTATE->IsExtraStage() && !PREFSMAN->m_bPickExtraStage ) || GAMESTATE->IsExtraStage2() )
|
if( CodeDetector::EnteredAllSorts(GameI.controller) )
|
||||||
m_soundLocked.Play();
|
{
|
||||||
else
|
if( ( GAMESTATE->IsExtraStage() && !PREFSMAN->m_bPickExtraStage ) || GAMESTATE->IsExtraStage2() )
|
||||||
m_MusicWheel.ChangeSort( SORT_MENU );
|
m_soundLocked.Play();
|
||||||
return;
|
else
|
||||||
}
|
m_MusicWheel.ChangeSort( SORT_MENU );
|
||||||
if( !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() && CodeDetector::DetectAndAdjustMusicOptions(GameI.controller) )
|
return;
|
||||||
{
|
}
|
||||||
m_soundOptionsChange.Play();
|
if( CodeDetector::EnteredNextSort(GameI.controller) )
|
||||||
UpdateOptionsDisplays();
|
{
|
||||||
return;
|
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
|
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 )
|
void ScreenSelectMusic::MenuStart( PlayerNumber pn )
|
||||||
{
|
{
|
||||||
if( pn != PLAYER_INVALID &&
|
// if( pn != PLAYER_INVALID &&
|
||||||
INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_LEFT) ) &&
|
// INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_LEFT) ) &&
|
||||||
INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_RIGHT) ) )
|
// INPUTMAPPER->IsButtonDown( MenuInput(pn, MENU_BUTTON_RIGHT) ) )
|
||||||
{
|
// {
|
||||||
// if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
// if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||||
// m_soundLocked.Play();
|
// m_soundLocked.Play();
|
||||||
// else
|
// else
|
||||||
{
|
// {
|
||||||
m_MusicWheel.NextSort();
|
// m_MusicWheel.NextSort();
|
||||||
}
|
// }
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
// this needs to check whether valid Steps are selected!
|
// this needs to check whether valid Steps are selected!
|
||||||
|
|||||||
Reference in New Issue
Block a user