diff --git a/stepmania/src/ArrowEffects.cpp b/stepmania/src/ArrowEffects.cpp index 67624feacb..de8820f322 100644 --- a/stepmania/src/ArrowEffects.cpp +++ b/stepmania/src/ArrowEffects.cpp @@ -200,14 +200,13 @@ float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCo float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float fYOffset ) { - float fPixelOffsetFromCenter = 0; + float fPixelOffsetFromCenter = 0; // fill this in below + const Style* pStyle = GAMESTATE->GetCurrentStyle(); const float* fEffects = pPlayerState->m_CurrentPlayerOptions.m_fEffects; if( fEffects[PlayerOptions::EFFECT_TORNADO] != 0 ) { - const Style* pStyle = GAMESTATE->GetCurrentStyle(); - // TRICKY: Tornado is very unplayable in doubles, so use a smaller // tornado width if there are many columns bool bWideField = pStyle->m_iColsPerPlayer > 4; @@ -230,7 +229,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float fMaxX = max( fMaxX, pStyle->m_ColumnInfo[pn][i].fXOffset ); } - const float fRealPixelOffset = GAMESTATE->GetCurrentStyle()->m_ColumnInfo[pn][iColNum].fXOffset; + const float fRealPixelOffset = pStyle->m_ColumnInfo[pn][iColNum].fXOffset; const float fPositionBetween = SCALE( fRealPixelOffset, fMinX, fMaxX, -1, 1 ); float fRads = acosf( fPositionBetween ); fRads += fYOffset * 6 / SCREEN_HEIGHT; @@ -247,11 +246,56 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float // TODO: Don't index by PlayerNumber. PlayerNumber pn = pPlayerState->m_PlayerNumber; -// fPixelOffsetFromCenter *= SCALE(fEffects[PlayerOptions::EFFECT_FLIP], 0.f, 1.f, 1.f, -1.f); - const float fRealPixelOffset = GAMESTATE->GetCurrentStyle()->m_ColumnInfo[pn][iColNum].fXOffset; - const float fDistance = -fRealPixelOffset * 2; + const int iNumCols = pStyle->m_iColsPerPlayer; + int iFirstCol = 0; + int iLastCol = iNumCols-1; + const int iNewCol = SCALE( iColNum, iFirstCol, iLastCol, iLastCol, iFirstCol ); + const float fOldPixelOffset = pStyle->m_ColumnInfo[pn][iColNum].fXOffset; + const float fNewPixelOffset = pStyle->m_ColumnInfo[pn][iNewCol].fXOffset; + const float fDistance = fNewPixelOffset - fOldPixelOffset; fPixelOffsetFromCenter += fDistance * fEffects[PlayerOptions::EFFECT_FLIP]; } + if( fEffects[PlayerOptions::EFFECT_INVERT] != 0 ) + { + // TODO: Don't index by PlayerNumber. + PlayerNumber pn = pPlayerState->m_PlayerNumber; + + const int iNumCols = pStyle->m_iColsPerPlayer; + const int iNumSides = pStyle->m_StyleType==ONE_PLAYER_TWO_SIDES ? 2 : 1; + const int iNumColsPerSide = iNumCols / iNumSides; + const int iSideIndex = iColNum / iNumColsPerSide; + const int iColOnSide = iColNum % iNumColsPerSide; + + const int iColLeftOfMiddle = (iNumColsPerSide-1)/2; + const int iColRightOfMidde = (iNumColsPerSide+1)/2; + + int iFirstColOnSide = -1; + int iLastColOnSide = -1; + if( iColOnSide <= iColLeftOfMiddle ) + { + iFirstColOnSide = 0; + iLastColOnSide = iColLeftOfMiddle; + } + else if( iColOnSide >= iColRightOfMidde ) + { + iFirstColOnSide = iColRightOfMidde; + iLastColOnSide = iNumColsPerSide-1; + } + else + { + iFirstColOnSide = iColOnSide/2; + iLastColOnSide = iColOnSide/2; + } + + // mirror + const int iNewColOnSide = SCALE( iColOnSide, iFirstColOnSide, iLastColOnSide, iLastColOnSide, iFirstColOnSide ); + const int iNewCol = iSideIndex*iNumColsPerSide + iNewColOnSide; + + const float fOldPixelOffset = pStyle->m_ColumnInfo[pn][iColNum].fXOffset; + const float fNewPixelOffset = pStyle->m_ColumnInfo[pn][iNewCol].fXOffset; + const float fDistance = fNewPixelOffset - fOldPixelOffset; + fPixelOffsetFromCenter += fDistance * fEffects[PlayerOptions::EFFECT_INVERT]; + } if( fEffects[PlayerOptions::EFFECT_BEAT] != 0 ) do { diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index 5af76a9385..3a213b7096 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -118,6 +118,7 @@ void PlayerOptions::GetMods( vector &AddTo ) const AddPart( AddTo, m_fEffects[EFFECT_DIZZY], "Dizzy" ); AddPart( AddTo, m_fEffects[EFFECT_MINI], "Mini" ); AddPart( AddTo, m_fEffects[EFFECT_FLIP], "Flip" ); + AddPart( AddTo, m_fEffects[EFFECT_INVERT], "Invert" ); AddPart( AddTo, m_fEffects[EFFECT_TORNADO], "Tornado" ); AddPart( AddTo, m_fEffects[EFFECT_TIPSY], "Tipsy" ); AddPart( AddTo, m_fEffects[EFFECT_BUMPY], "Bumpy" ); @@ -262,6 +263,7 @@ void PlayerOptions::FromString( CString sOptions, bool bWarnOnInvalid ) else if( sBit == "dizzy" ) SET_FLOAT( fEffects[EFFECT_DIZZY] ) else if( sBit == "mini" ) SET_FLOAT( fEffects[EFFECT_MINI] ) else if( sBit == "flip" ) SET_FLOAT( fEffects[EFFECT_FLIP] ) + else if( sBit == "invert" ) SET_FLOAT( fEffects[EFFECT_INVERT] ) else if( sBit == "tornado" ) SET_FLOAT( fEffects[EFFECT_TORNADO] ) else if( sBit == "tipsy" ) SET_FLOAT( fEffects[EFFECT_TIPSY] ) else if( sBit == "bumpy" ) SET_FLOAT( fEffects[EFFECT_BUMPY] ) diff --git a/stepmania/src/PlayerOptions.h b/stepmania/src/PlayerOptions.h index 205f0e7993..e1602ed6b3 100644 --- a/stepmania/src/PlayerOptions.h +++ b/stepmania/src/PlayerOptions.h @@ -41,6 +41,7 @@ struct PlayerOptions EFFECT_DIZZY, EFFECT_MINI, EFFECT_FLIP, + EFFECT_INVERT, EFFECT_TORNADO, EFFECT_TIPSY, EFFECT_BUMPY,