#include "global.h" /* * Styles define a set of columns for each player, and information about those * columns, like what Instruments are used play those columns and what track * to use to populate the column's notes. * A "track" is the term used to descibe a particular vertical sting of note * in NoteData. * A "column" is the term used to describe the vertical string of notes that * a player sees on the screen while they're playing. Column notes are * picked from a track, but columns and tracks don't have a 1-to-1 * correspondance. For example, dance-versus has 8 columns but only 4 tracks * because two players place from the same set of 4 tracks. */ #include "Style.h" #include "GameState.h" #include "RageLog.h" #include "RageUtil.h" #include "InputMapper.h" #include "NoteData.h" #include bool Style::GetUsesCenteredArrows() const { switch( m_StyleType ) { case StyleType_OnePlayerTwoSides: case StyleType_TwoPlayersSharedSides: return true; default: return false; } } void Style::GetTransformedNoteDataForStyle( PlayerNumber pn, const NoteData& original, NoteData& noteDataOut ) const { ASSERT( pn >=0 && pn <= NUM_PLAYERS ); int iNewToOriginalTrack[MAX_COLS_PER_PLAYER]; for( int col=0; col& ret ) const { ASSERT_M( pn < NUM_PLAYERS && iCol < MAX_COLS_PER_PLAYER, ssprintf("P%i C%i", pn, iCol) ); bool bUsingOneSide = m_StyleType != StyleType_OnePlayerTwoSides && m_StyleType != StyleType_TwoPlayersSharedSides; FOREACH_ENUM( GameController, gc) { if( bUsingOneSide && gc != (int) pn ) continue; int iButtonsPerController = INPUTMAPPER->GetInputScheme()->m_iButtonsPerController; for( GameButton gb=GAME_BUTTON_NEXT; gb < iButtonsPerController; gb=(GameButton)(gb+1) ) { int iThisInputCol = m_iInputColumn[gc][gb-GAME_BUTTON_NEXT]; if( iThisInputCol == END_MAPPING ) break; // A style can have multiple game inputs mapped to a single column, so // we have to return all the game inputs that are valid. If only the // first is returned, then holds will drop on other inputs that should // be valid. -Kyz if( iThisInputCol == iCol ) { ret.push_back(GameInput( gc, gb )); } } } if(unlikely(ret.empty())) { FAIL_M( ssprintf("Invalid column number %i for player %i in the style %s", iCol, pn, m_szName) ); } }; int Style::GameInputToColumn( const GameInput &GameI ) const { if( GameI.button < GAME_BUTTON_NEXT ) return Column_Invalid; int iColumnIndex = GameI.button - GAME_BUTTON_NEXT; if( m_iInputColumn[GameI.controller][iColumnIndex] == NO_MAPPING ) return Column_Invalid; for( int i = 0; i <= iColumnIndex; ++i ) { if( m_iInputColumn[GameI.controller][i] == END_MAPPING ) { return Column_Invalid; } } return m_iInputColumn[GameI.controller][iColumnIndex]; } void Style::GetMinAndMaxColX( PlayerNumber pn, float& fMixXOut, float& fMaxXOut ) const { ASSERT( pn != PLAYER_INVALID ); fMixXOut = FLT_MAX; fMaxXOut = FLT_MIN; for( int i=0; i(m_iColsPerPlayer-1)); } RString Style::ColToButtonName( int iCol ) const { const char *pzColumnName = m_ColumnInfo[PLAYER_1][iCol].pzName; if( pzColumnName != nullptr ) return pzColumnName; std::vector GI; StyleInputToGameInput( iCol, PLAYER_1, GI ); return INPUTMAPPER->GetInputScheme()->GetGameButtonName(GI[0].button); } // Lua bindings #include "LuaBinding.h" /** @brief Allow Lua to have access to the Style. */ class LunaStyle: public Luna