diff --git a/stepmania/NEWS b/stepmania/NEWS index 2fdeefc3b2..c6e2e8e17e 100644 --- a/stepmania/NEWS +++ b/stepmania/NEWS @@ -1,5 +1,16 @@ +----------------------- Version 3.02 --------------------------- +NEW FEATURE: Added 0.25x scroll speed +CHANGE: Reorganized options on Player Options screen +NEW FEATURE: New modifier: Acceleration-Land +NEW FEATURE: New modifier: Acceleration-Expand +NEW FEATURE: New modifier: Acceleration-Boomerang +CHANGE: Tweaked Acceleration-Wave for more of a challenge +CHANGE: Changed format NoteSkin tap graphic format. Existing NoteSkins will + need to update the tap graphic. + ----------------------- Version 3.01 --------------------------- -CHANGE: Simplified NoteSkin format. Old NoteSkins will need to be updated. +CHANGE: Simplified NoteSkin tap graphic format. Old NoteSkins will need to + update the tap graphic. NEW FEATURE: AutoSync status now shown during gameplay with icon NEW FEATURE: added autogen icon to select music NEW FEATURE: toggle for easter eggs in Machine Options diff --git a/stepmania/TODO.chris b/stepmania/TODO.chris index 82d79faea0..95523fe7d2 100644 --- a/stepmania/TODO.chris +++ b/stepmania/TODO.chris @@ -2,6 +2,14 @@ Fix ///////////////////////// +Hrm.. I had a few things about Stepmania I wanted to suggest, but can't think of all of them now.. Lemme list the ones I can remember: + + - In "all songs" don't have it automatically open one of the folders, or at least have it start at the very beginning of the folder + + - a "remember settings" feature or something, so when I press enter on "game mode" it automatically selects Single, Heavy, 2x, Dark, All Songs. Or whatever you specify. +ddrllama: - When pressing "Escape" on the main menu of Stepmania, don't have it go into a demo.. Either have it do nothing, or an "Are you sure you want to quit?" or something message--I'm used to DWI, pressing Escape like 10 times until it quits, and I often forget to only press it twice and then to go to "Quit" + + change space so gray arrows aren't so small groove radar goes wild when random selected diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 33a4102f52..b26c57dcb8 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -669,7 +669,7 @@ SuperShuffle=Down,Up,Left,Right Little= NextScrollSpeed= PreviousScrollSpeed= -Boost=Left,Right,Down,Up +NextAccel=Left,Right,Down,Up NextEffect=Left,Down,Right NextAppearance=Left,Up,Right NextTurn= diff --git a/stepmania/src/ArrowEffects.cpp b/stepmania/src/ArrowEffects.cpp index 84c70fd691..6e9b21ad21 100644 --- a/stepmania/src/ArrowEffects.cpp +++ b/stepmania/src/ArrowEffects.cpp @@ -21,6 +21,9 @@ #include +RageTimer g_timerExpand; +float g_fExpandSeconds = 0; + float ArrowGetYOffset( PlayerNumber pn, float fNoteBeat ) { float fSongBeat = GAMESTATE->m_fSongBeat; @@ -36,10 +39,33 @@ float ArrowGetYOffset( PlayerNumber pn, float fNoteBeat ) * * I'm not sure which is better. - glenn */ - if( GAMESTATE->m_PlayerOptions[pn].m_bBoost ) - fYOffset *= 1.4f / ((fYOffset+SCREEN_HEIGHT/1.6f)/SCREEN_HEIGHT); - if( GAMESTATE->m_PlayerOptions[pn].m_bEffects[PlayerOptions::EFFECT_WAVE] ) - fYOffset += 15.0f*sinf( fYOffset/38.0f ); + /* Boost and wave can no longer be used at the same time. -Chris */ + + if( fYOffset < 0 ) + return fYOffset; // don't mess with it after crossing the receptors + + switch( GAMESTATE->m_PlayerOptions[pn].m_AccelType ) + { + case PlayerOptions::ACCEL_BOOST: + fYOffset *= 1.5f / ((fYOffset+SCREEN_HEIGHT/1.2f)/SCREEN_HEIGHT); + break; + case PlayerOptions::ACCEL_LAND: + fYOffset *= SCALE( fYOffset, 0.f, SCREEN_HEIGHT, 0.25f, 1.5f ); + break; + case PlayerOptions::ACCEL_WAVE: + fYOffset += 20.0f*sinf( fYOffset/38.0f ); + break; + case PlayerOptions::ACCEL_EXPAND: + if( !GAMESTATE->m_bFreeze ) + g_fExpandSeconds += g_timerExpand.GetDeltaTime(); + else + g_timerExpand.GetDeltaTime(); // throw away + fYOffset *= SCALE( cosf(g_fExpandSeconds*3), -1, 1, 0.5f, 1.5f ); + break; + case PlayerOptions::ACCEL_BOOMERANG: + fYOffset *= SCALE( fYOffset, 0.f, SCREEN_HEIGHT, 1.5f, 0.5f ); + break; + } return fYOffset; } @@ -72,19 +98,27 @@ float ArrowGetXPos( PlayerNumber pn, int iColNum, float fYPos ) return fPixelOffsetFromCenter; } -float ArrowGetRotation( PlayerNumber pn, int iColNum, float fYOffset ) +float ArrowGetRotation( PlayerNumber pn, float fNoteBeat ) { float fRotation = 0; //StyleDef.m_ColumnToRotation[iColNum]; if( GAMESTATE->m_PlayerOptions[pn].m_bEffects[PlayerOptions::EFFECT_DIZZY] ) - fRotation += fYOffset/SCREEN_HEIGHT*6; - + { + float fSongBeat = GAMESTATE->m_fSongBeat; + float fBeatsUntilStep = fNoteBeat - fSongBeat; + fRotation += fBeatsUntilStep; + } return fRotation; } +float ArrowGetYPosWithoutReverse( PlayerNumber pn, float fYOffset ) +{ + return fYOffset * GAMESTATE->m_PlayerOptions[pn].m_fScrollSpeed; +} + float ArrowGetYPos( PlayerNumber pn, float fYOffset ) { - return fYOffset * GAMESTATE->m_PlayerOptions[pn].m_fArrowScrollSpeed * (GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? -1 : 1 ); + return ArrowGetYPosWithoutReverse(pn,fYOffset) * (GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? -1 : 1 ); } diff --git a/stepmania/src/ArrowEffects.h b/stepmania/src/ArrowEffects.h index 3a938b8f36..b8bf40ff0e 100644 --- a/stepmania/src/ArrowEffects.h +++ b/stepmania/src/ArrowEffects.h @@ -29,12 +29,13 @@ float ArrowGetYOffset( PlayerNumber pn, float fNoteBeat ); // fRotation is Z rotation of an arrow. This will depend on the column of // the arrow and possibly the Arrow effect and the fYOffset (in the case of // EFFECT_DIZZY). -float ArrowGetRotation( PlayerNumber pn, int iCol, float fYOffset ); +float ArrowGetRotation( PlayerNumber pn, float fNoteBeat ); // fYPos is the position of the note in pixels relative to the center. // (positive if has not yet been stepped on, negative if has already passed). // This value is fYOffset with bReverseScroll and fScrollSpeed factored in. +float ArrowGetYPosWithoutReverse( PlayerNumber pn, float fYOffset ); float ArrowGetYPos( PlayerNumber pn, float fYOffset ); diff --git a/stepmania/src/CodeDetector.cpp b/stepmania/src/CodeDetector.cpp index 8a6f3c7721..42f6934af2 100644 --- a/stepmania/src/CodeDetector.cpp +++ b/stepmania/src/CodeDetector.cpp @@ -33,7 +33,7 @@ enum Code { CODE_LITTLE, CODE_NEXT_SCROLL_SPEED, CODE_PREVIOUS_SCROLL_SPEED, - CODE_BOOST, + CODE_NEXT_ACCEL, CODE_NEXT_EFFECT, CODE_NEXT_APPEARANCE, CODE_NEXT_TURN, @@ -60,7 +60,7 @@ const CString g_sCodeNames[NUM_CODES] = { "Little", "NextScrollSpeed", "PreviousScrollSpeed", - "Boost", + "NextAccel", "NextEffect", "NextAppearance", "NextTurn", @@ -174,14 +174,14 @@ bool CodeDetector::DetectAndAdjustOptions( GameController controller ) case CODE_SHUFFLE: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_TurnType, PlayerOptions::TURN_SHUFFLE, PlayerOptions::TURN_NONE ); break; case CODE_SUPER_SHUFFLE: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_TurnType, PlayerOptions::TURN_SUPER_SHUFFLE, PlayerOptions::TURN_NONE ); break; case CODE_LITTLE: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_bLittle, true, false ); break; - case CODE_NEXT_SCROLL_SPEED:INCREMENT_SCROLL_SPEED( GAMESTATE->m_PlayerOptions[pn].m_fArrowScrollSpeed ); break; - case CODE_PREVIOUS_SCROLL_SPEED:DECREMENT_SCROLL_SPEED( GAMESTATE->m_PlayerOptions[pn].m_fArrowScrollSpeed ); break; - case CODE_BOOST: GAMESTATE->m_PlayerOptions[pn].m_bBoost ^= true; break; + case CODE_NEXT_SCROLL_SPEED:INCREMENT_SCROLL_SPEED( GAMESTATE->m_PlayerOptions[pn].m_fScrollSpeed ); break; + case CODE_PREVIOUS_SCROLL_SPEED:DECREMENT_SCROLL_SPEED( GAMESTATE->m_PlayerOptions[pn].m_fScrollSpeed ); break; + case CODE_NEXT_ACCEL: GAMESTATE->m_PlayerOptions[pn].NextAccel(); break; case CODE_NEXT_EFFECT: GAMESTATE->m_PlayerOptions[pn].NextEffect(); break; - case CODE_NEXT_APPEARANCE: GAMESTATE->m_PlayerOptions[pn].m_AppearanceType = PlayerOptions::AppearanceType((GAMESTATE->m_PlayerOptions[pn].m_AppearanceType+1) %PlayerOptions::NUM_APPEARANCE_TYPES ); break; - case CODE_NEXT_TURN: GAMESTATE->m_PlayerOptions[pn].m_TurnType = PlayerOptions::TurnType( (GAMESTATE->m_PlayerOptions[pn].m_TurnType+1) %PlayerOptions::NUM_TURN_TYPES ); break; + case CODE_NEXT_APPEARANCE: GAMESTATE->m_PlayerOptions[pn].NextAppearance();; break; + case CODE_NEXT_TURN: GAMESTATE->m_PlayerOptions[pn].NextTurn(); break; case CODE_REVERSE: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll, true, false ); break; - case CODE_NEXT_COLOR: GAMESTATE->m_PlayerOptions[pn].m_ColorType = PlayerOptions::ColorType( (GAMESTATE->m_PlayerOptions[pn].m_ColorType+1) %PlayerOptions::NUM_COLOR_TYPES ); break; + case CODE_NEXT_COLOR: GAMESTATE->m_PlayerOptions[pn].NextColor(); break; case CODE_HOLDS: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_bHoldNotes, true, false ); break; case CODE_DARK: TOGGLE( GAMESTATE->m_PlayerOptions[pn].m_bDark, true, false ); break; case CODE_CANCEL_ALL: GAMESTATE->m_PlayerOptions[pn] = PlayerOptions(); break; diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 8482d369b6..d8e43f0091 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -72,11 +72,8 @@ void GameState::Reset() m_pCurNotes[p] = NULL; m_pCurCourse = NULL; - m_fMusicSeconds = 0; - m_fSongBeat = 0; - m_fCurBPS = 0; - m_bFreeze = 0; - + ResetMusicStatistics(); + m_CurStageStats = StageStats(); m_vPassedStageStats.clear(); @@ -91,6 +88,7 @@ void GameState::ResetMusicStatistics() m_fSongBeat = 0; m_fCurBPS = 10; m_bFreeze = false; + m_bPastHereWeGo = false; } int GameState::GetStageIndex() diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index cc32583609..d94fa4cc69 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -92,6 +92,7 @@ public: float m_fSongBeat; float m_fCurBPS; bool m_bFreeze; // in the middle of a freeze + bool m_bPastHereWeGo; void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above. diff --git a/stepmania/src/GrayArrow.cpp b/stepmania/src/GrayArrow.cpp index 5768f847b9..ed5871ea07 100644 --- a/stepmania/src/GrayArrow.cpp +++ b/stepmania/src/GrayArrow.cpp @@ -39,28 +39,31 @@ void GrayArrow::Update( float fDeltaTime ) Sprite::Update( fDeltaTime ); - /* These could be metrics or configurable. I'd prefer the flash to - * start on the beat, I think ... -glenn */ + if( GAMESTATE->m_fMusicSeconds <= 0 ) // music isn't playing + { + SetState( 0 ); + } + else + { + /* These could be metrics or configurable. I'd prefer the flash to + * start on the beat, I think ... -glenn */ - /* Start flashing 10% of a beat before the beat starts. */ - const float flash_offset = -0.1f; + /* Start flashing 10% of a beat before the beat starts. */ + const float flash_offset = -0.1f; - /* Flash for 20% of a beat. */ - const float flash_length = 0.2f; + /* Flash for 20% of a beat. */ + const float flash_length = 0.2f; - float cur_beat = GAMESTATE->m_fSongBeat; + float cur_beat = GAMESTATE->m_fSongBeat; - /* Make sure that the first flash (when cur_beat is passing 0) is just as - * long as others. */ - cur_beat += 1.0f; - cur_beat -= flash_offset; + /* Beats can start in very negative territory (many BMR songs, Drop Out + * -Remix-). */ + cur_beat += 100.0f; - float fPercentIntoBeat = fmodf(cur_beat, 1); - - int iNewState = (fPercentIntoBeat < flash_length)? 0:1; - - CLAMP( iNewState, 0, Sprite::GetNumStates() ); - SetState( iNewState ); + cur_beat -= flash_offset; + float fPercentIntoBeat = fmodf(cur_beat, 1); + SetState( (fPercentIntoBeatGetPathTo(c, "receptor"); m_GrayArrow[c].Load( sPath ); - if( m_GrayArrow[c].GetNumStates() != 2 ) - RageException::Throw( "'%s' must have two frames", sPath.GetString() ); + if( m_GrayArrow[c].GetNumStates() != 3 ) + RageException::Throw( "'%s' must have 3 frames", sPath.GetString() ); m_GrayArrow[c].SetX( pStyleDef->m_ColumnInfo[pn][c].fXOffset ); } } diff --git a/stepmania/src/NoteDisplay.cpp b/stepmania/src/NoteDisplay.cpp index 733967500e..eb1682f4be 100644 --- a/stepmania/src/NoteDisplay.cpp +++ b/stepmania/src/NoteDisplay.cpp @@ -66,7 +66,6 @@ int NoteDisplay::GetTapFrameNo( const float fNoteBeat ) float fSongBeat = GAMESTATE->m_fSongBeat; float fPercentIntoMeasure = fmodf( fSongBeat, g_fTapAnimationLengthInBeats ) / g_fTapAnimationLengthInBeats; - fPercentIntoMeasure += 1/(iNumFrames*2.f); // fudge factor so that the "full white" frame shows when the arrow overlaps the receptors int iSongBeatFrameContrib = (int)roundf( fPercentIntoMeasure * iNumFrames ); float fBeatFraction = fmodf( fNoteBeat, 1.0f ); @@ -92,10 +91,10 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const bool bReverse = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_bReverseScroll; const int iCol = hn.m_iTrack; - const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fStartBeat ); - const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset ); - const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fEndBeat ); - const float fEndYPos = ArrowGetYPos( m_PlayerNumber, fEndYOffset ); + const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fStartBeat ); + const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset ); + const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fEndBeat ); + const float fEndYPos = ArrowGetYPos( m_PlayerNumber, fEndYOffset ); // draw from bottom to top const float fFrameWidth = m_sprHoldParts.GetUnzoomedWidth(); @@ -315,12 +314,12 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bOnSameRowAsHoldStart, const float fPercentFadeToFail, const float fLife ) { - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); - const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset ); - const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYPos ); - const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos, fPercentFadeToFail ); - const float fGlow = ArrowGetGlow( m_PlayerNumber, fYPos, fPercentFadeToFail ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fRotation = ArrowGetRotation( m_PlayerNumber, fBeat ); + const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYPos ); + const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos, fPercentFadeToFail ); + const float fGlow = ArrowGetGlow( m_PlayerNumber, fYPos, fPercentFadeToFail ); const int iTapFrameNo = GetTapFrameNo( fBeat ); const float fColorScale = SCALE(fLife,0,1,0.2f,1); RageColor diffuse = RageColor(fColorScale,fColorScale,fColorScale,fAlpha); diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index a0b254fb48..0ba83e406b 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -45,11 +45,11 @@ NoteField::NoteField() } -void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iPixelsToDrawBehind, int iPixelsToDrawAhead ) +void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw ) { m_PlayerNumber = pn; - m_iPixelsToDrawBehind = iPixelsToDrawBehind; - m_iPixelsToDrawAhead = iPixelsToDrawAhead; + m_iFirstPixelToDraw = iFirstPixelToDraw; + m_iLastPixelToDraw = iLastPixelToDraw; m_fPercentFadeToFail = -1; @@ -80,8 +80,8 @@ void NoteField::DrawMeasureBar( int iMeasureIndex ) const int iMeasureNoDisplay = iMeasureIndex+1; const float fBeat = float(iMeasureIndex * BEATS_PER_MEASURE); - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); m_rectMeasureBar.SetXY( 0, fYPos ); m_rectMeasureBar.SetZoomX( (float)(m_iNumTracks+1) * ARROW_SIZE ); @@ -98,8 +98,8 @@ void NoteField::DrawMeasureBar( int iMeasureIndex ) void NoteField::DrawMarkerBar( const float fBeat ) { - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); m_rectMarkerBar.SetXY( 0, fYPos ); m_rectMarkerBar.SetZoomX( (float)(m_iNumTracks+1) * ARROW_SIZE ); @@ -110,8 +110,8 @@ void NoteField::DrawMarkerBar( const float fBeat ) void NoteField::DrawBPMText( const float fBeat, const float fBPM ) { - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); m_textMeasureNumber.SetDiffuse( RageColor(1,0,0,1) ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) ); @@ -122,8 +122,8 @@ void NoteField::DrawBPMText( const float fBeat, const float fBPM ) void NoteField::DrawFreezeText( const float fBeat, const float fSecs ) { - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); m_textMeasureNumber.SetDiffuse( RageColor(0.8f,0.8f,0,1) ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) ); @@ -134,8 +134,8 @@ void NoteField::DrawFreezeText( const float fBeat, const float fSecs ) void NoteField::DrawBGChangeText( const float fBeat, const CString sNewBGName ) { - const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); - const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); + const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); + const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); m_textMeasureNumber.SetDiffuse( RageColor(0,1,0,1) ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) ); @@ -149,16 +149,41 @@ void NoteField::DrawPrimitives() //LOG->Trace( "NoteField::DrawPrimitives()" ); const float fSongBeat = GAMESTATE->m_fSongBeat; - - const float fBeatsToDrawBehind = m_iPixelsToDrawBehind * (1/(float)ARROW_SIZE) * (1/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed); - const float fBeatsToDrawAhead = m_iPixelsToDrawAhead * (1/(float)ARROW_SIZE) * (1/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed); - const float fFirstBeatToDraw = max( 0, fSongBeat - fBeatsToDrawBehind ); - /* We actually want to draw up to the last row, which is after MAX_BEATS-1 but - * before MAX_BEATS. Rely on GetTapNote to cap it for us correctly. */ - const float fLastBeatToDraw = min( MAX_BEATS, fSongBeat + fBeatsToDrawAhead ); + + // CPU OPTIMIZATION OPPORTUNITY: + // change this probing to binary search + + // probe for first note on the screen + float fFirstBeatToDraw = fSongBeat-2; // Adjust to balance of performance and showing enough notes. + while( fFirstBeatToDrawfSongBeat ) + { + float fYOffset = ArrowGetYOffset(m_PlayerNumber, fLastBeatToDraw); + float fYPosWOReverse = ArrowGetYPosWithoutReverse(m_PlayerNumber, fYOffset ); + if( fYPosWOReverse > m_iLastPixelToDraw ) // off screen + fLastBeatToDraw -= 0.1f; // move toward fSongBeat + else // on screen + break; // stop probing + } + fLastBeatToDraw += 0.1f; // fast forward since we intentionally overshot + + const int iFirstIndexToDraw = BeatToNoteRow(fFirstBeatToDraw); const int iLastIndexToDraw = BeatToNoteRow(fLastBeatToDraw); +// LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat ); // LOG->Trace( "Drawing elements %d through %d", iFirstIndexToDraw, iLastIndexToDraw ); if( GAMESTATE->m_bEditing ) diff --git a/stepmania/src/NoteField.h b/stepmania/src/NoteField.h index f55a62715b..273caf4ca4 100644 --- a/stepmania/src/NoteField.h +++ b/stepmania/src/NoteField.h @@ -32,7 +32,7 @@ public: virtual void Update( float fDeltaTime ); virtual void DrawPrimitives(); - void Load( NoteData* pNoteData, PlayerNumber pn, int iPixelsToDrawBehind, int iPixelsToDrawAhead ); + void Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw ); void RemoveTapNoteRow( int iIndex ); vector m_bIsHoldingHoldNote; // hack: Need this to know when to "light up" the center of hold notes @@ -51,8 +51,8 @@ protected: float m_fPercentFadeToFail; // -1 of not fading to fail PlayerNumber m_PlayerNumber; - int m_iPixelsToDrawBehind; - int m_iPixelsToDrawAhead; + int m_iFirstPixelToDraw; // this should be a negative number + int m_iLastPixelToDraw; // this should be a positive number // color arrows NoteDisplay m_NoteDisplay[MAX_NOTE_TRACKS]; diff --git a/stepmania/src/OptionIconRow.cpp b/stepmania/src/OptionIconRow.cpp index 6f3f697519..ff9a83c132 100644 --- a/stepmania/src/OptionIconRow.cpp +++ b/stepmania/src/OptionIconRow.cpp @@ -40,7 +40,10 @@ struct OptionColumnEntry const OptionColumnEntry g_OptionColumnEntries[] = { {"Boost", 0}, - {"Wave", 1}, + {"Land", 0}, + {"Wave", 0}, + {"Expand", 0}, + {"Boomerang",0}, {"Drunk", 1}, {"Dizzy", 1}, {"Space", 1}, diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 05f482127a..6a0e1ced7f 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -160,8 +160,8 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi if( GAMESTATE->m_PlayerOptions[pn].m_bLittle ) NoteDataUtil::MakeLittle(*this); - int iPixelsToDrawBefore = 96; - int iPixelsToDrawAfter = 384; + int iPixelsToDrawBefore = -60; + int iPixelsToDrawAfter = 350; // If both options are on, we *do* need to multiply it twice. if( GAMESTATE->m_PlayerOptions[pn].m_bEffects[PlayerOptions::EFFECT_MINI] ) diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index f1426dbded..f08badf1ce 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -13,32 +13,11 @@ #include "PlayerOptions.h" #include "RageUtil.h" -void PlayerOptions::NextEffect() -{ - if( m_bEffects[NUM_EFFECT_TYPES-1] ) - { - ZERO( m_bEffects ); - return; - } - - for( int i=0; i 1.00 */ - CString s = ssprintf( "%2.2f", m_fArrowScrollSpeed ); + CString s = ssprintf( "%2.2f", m_fScrollSpeed ); if( s[s.GetLength()-1] == '0' ) { /* -> 1.0 */ s.erase(s.GetLength()-1); // delete last char @@ -69,15 +48,23 @@ CString PlayerOptions::GetString() sReturn += s + "X, "; } - if( m_bBoost ) sReturn += "Boost, "; + switch( m_AccelType ) + { + case ACCEL_OFF: break; + case ACCEL_BOOST: sReturn += "Boost, "; break; + case ACCEL_LAND: sReturn += "Land, "; break; + case ACCEL_WAVE: sReturn += "Wave, "; break; + case ACCEL_EXPAND: sReturn += "Expand, "; break; + case ACCEL_BOOMERANG: sReturn += "Boomerang, "; break; + default: ASSERT(0); + } - if( m_bEffects[EFFECT_WAVE] ) sReturn += "Wave, "; - if( m_bEffects[EFFECT_DRUNK] ) sReturn += "Drunk, "; - if( m_bEffects[EFFECT_DIZZY] ) sReturn += "Dizzy, "; - if( m_bEffects[EFFECT_SPACE] ) sReturn += "Space, "; - if( m_bEffects[EFFECT_MINI] ) sReturn += "Mini, "; - if( m_bEffects[EFFECT_FLIP] ) sReturn += "Flip, "; - if( m_bEffects[EFFECT_TORNADO] ) sReturn += "Tornado, "; + if( m_bEffects[EFFECT_DRUNK] ) sReturn += "Drunk, "; + if( m_bEffects[EFFECT_DIZZY] ) sReturn += "Dizzy, "; + if( m_bEffects[EFFECT_SPACE] ) sReturn += "Space, "; + if( m_bEffects[EFFECT_MINI] ) sReturn += "Mini, "; + if( m_bEffects[EFFECT_FLIP] ) sReturn += "Flip, "; + if( m_bEffects[EFFECT_TORNADO] )sReturn += "Tornado, "; switch( m_AppearanceType ) { @@ -138,16 +125,20 @@ void PlayerOptions::FromString( CString sOptions ) TrimLeft(sBit); TrimRight(sBit); - if( sBit == "0.5x" ) m_fArrowScrollSpeed = 0.5f; - else if( sBit == "0.75x" ) m_fArrowScrollSpeed = 0.75f; - else if( sBit == "1.5x" ) m_fArrowScrollSpeed = 1.5f; - else if( sBit == "2.0x" ) m_fArrowScrollSpeed = 2.0f; - else if( sBit == "3.0x" ) m_fArrowScrollSpeed = 3.0f; - else if( sBit == "4.0x" ) m_fArrowScrollSpeed = 4.0f; - else if( sBit == "5.0x" ) m_fArrowScrollSpeed = 5.0f; - else if( sBit == "8.0x" ) m_fArrowScrollSpeed = 8.0f; - else if( sBit == "boost" ) m_bBoost = true; - else if( sBit == "wave" ) m_bEffects[EFFECT_WAVE] = true; + if( sBit == "0.25x" ) m_fScrollSpeed = 0.25f; + else if( sBit == "0.5x" ) m_fScrollSpeed = 0.5f; + else if( sBit == "0.75x" ) m_fScrollSpeed = 0.75f; + else if( sBit == "1.5x" ) m_fScrollSpeed = 1.5f; + else if( sBit == "2.0x" ) m_fScrollSpeed = 2.0f; + else if( sBit == "3.0x" ) m_fScrollSpeed = 3.0f; + else if( sBit == "4.0x" ) m_fScrollSpeed = 4.0f; + else if( sBit == "5.0x" ) m_fScrollSpeed = 5.0f; + else if( sBit == "8.0x" ) m_fScrollSpeed = 8.0f; + else if( sBit == "boost" ) m_AccelType = ACCEL_BOOST; + else if( sBit == "land" ) m_AccelType = ACCEL_LAND; + else if( sBit == "wave" ) m_AccelType = ACCEL_WAVE; + else if( sBit == "expand" ) m_AccelType = ACCEL_EXPAND; + else if( sBit == "boomerang" ) m_AccelType = ACCEL_BOOMERANG; else if( sBit == "drunk" ) m_bEffects[EFFECT_DRUNK] = true; else if( sBit == "dizzy" ) m_bEffects[EFFECT_DIZZY] = true; else if( sBit == "space" ) m_bEffects[EFFECT_SPACE] = true; @@ -172,3 +163,46 @@ void PlayerOptions::FromString( CString sOptions ) else if( sBit == "dark" ) m_bDark = true; } } + + +void PlayerOptions::NextAccel() +{ + m_AccelType = (AccelType) ((m_AccelType+1)%NUM_ACCEL_TYPES); +} + +void PlayerOptions::NextEffect() +{ + if( m_bEffects[NUM_EFFECT_TYPES-1] ) // last effect is on + { + ZERO( m_bEffects ); + return; + } + + for( int i=0; im_PlayerOptions[p] = PlayerOptions(); - GAMESTATE->m_PlayerOptions[p].m_fArrowScrollSpeed = .25f; + GAMESTATE->m_PlayerOptions[p].m_fScrollSpeed = .25f; GAMESTATE->m_PlayerOptions[p].m_bEffects[ PlayerOptions::EFFECT_SPACE ] = true; GAMESTATE->m_PlayerOptions[p].m_bEffects[ PlayerOptions::EFFECT_MINI ] = true; } @@ -112,7 +112,7 @@ bool SetUpSongOptions() // always return true. GAMESTATE->m_PlayerOptions[p] = PlayerOptions(); if( RandomFloat(0,1)>0.8f ) - GAMESTATE->m_PlayerOptions[p].m_fArrowScrollSpeed = 1.5f; + GAMESTATE->m_PlayerOptions[p].m_fScrollSpeed = 1.5f; GAMESTATE->m_PlayerOptions[p].m_bEffects[ rand()%PlayerOptions::NUM_EFFECT_TYPES ] = true; if( RandomFloat(0,1)>0.9f ) GAMESTATE->m_PlayerOptions[p].m_AppearanceType = PlayerOptions::APPEARANCE_HIDDEN; @@ -158,6 +158,8 @@ ScreenDemonstration::ScreenDemonstration() : ScreenGameplay(SetUpSongOptions()) ClearMessageQueue(); // remove all of the messages set in ScreenGameplay that animate "ready", "here we go", etc. + GAMESTATE->m_bPastHereWeGo = true; + m_StarWipe.SetOpened(); m_DancingState = STATE_DANCING; this->SendScreenMessage( SM_BeginFadingToNextScreen, SECONDS_TO_SHOW ); diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 31421d6594..95154856bc 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -222,7 +222,7 @@ ScreenEdit::ScreenEdit() GAMESTATE->m_SongOptions.m_fMusicRate = 1; - GAMESTATE->m_PlayerOptions[PLAYER_1].m_fArrowScrollSpeed = 1; + GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 1; GAMESTATE->m_PlayerOptions[PLAYER_1].m_ColorType = PlayerOptions::COLOR_NOTE; m_BGAnimation.LoadFromAniDir( THEME->GetPathTo("BGAnimations","edit") ); @@ -238,7 +238,7 @@ ScreenEdit::ScreenEdit() m_NoteFieldEdit.SetXY( EDIT_X, EDIT_GRAY_Y ); m_NoteFieldEdit.SetZoom( 0.5f ); - m_NoteFieldEdit.Load( ¬eData, PLAYER_1, 200, 800 ); + m_NoteFieldEdit.Load( ¬eData, PLAYER_1, -200, 800 ); m_rectRecordBack.StretchTo( RectI(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) ); m_rectRecordBack.SetDiffuse( RageColor(0,0,0,0) ); @@ -249,7 +249,7 @@ ScreenEdit::ScreenEdit() m_NoteFieldRecord.SetXY( EDIT_X, EDIT_GRAY_Y ); m_NoteFieldRecord.SetZoom( 1.0f ); - m_NoteFieldRecord.Load( ¬eData, PLAYER_1, 200, 300 ); + m_NoteFieldRecord.Load( ¬eData, PLAYER_1, -100, 300 ); m_Clipboard.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks; diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 915447af1f..045092befa 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -1015,9 +1015,11 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ // // handle a step // - if( m_DancingState == STATE_DANCING && type == IET_FIRST_PRESS && !PREFSMAN->m_bAutoPlay && StyleI.IsValid() ) - if( GAMESTATE->IsPlayerEnabled( StyleI.player ) ) - m_Player[StyleI.player].Step( StyleI.col ); + if( type==IET_FIRST_PRESS && + !PREFSMAN->m_bAutoPlay && + StyleI.IsValid() && + GAMESTATE->IsPlayerEnabled( StyleI.player ) ) + m_Player[StyleI.player].Step( StyleI.col ); } void ScreenGameplay::PositionStatusIcons() @@ -1160,18 +1162,19 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) case SM_User+1: break; case SM_User+2: - m_sprReady.StartFocusing(); + m_sprReady.BeginTweening(0.25f); + m_sprReady.SetTweenDiffuse( RageColor(1,1,1,1) ); m_announcerReady.PlayRandom(); break; case SM_User+3: break; case SM_User+4: - m_sprReady.StartBlurring(); break; case SM_User+5: - { - m_Background.FadeIn(); - } + m_sprReady.SetDiffuse( RageColor(1,1,1,0) ); + m_announcerHereWeGo.PlayRandom(); + m_Background.FadeIn(); + GAMESTATE->m_bPastHereWeGo = true; break; case SM_User+6: break; @@ -1184,7 +1187,9 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) case SM_StartHereWeGo: /* We have 2.5 seconds until the notes start. */ - m_sprHereWeGo.StartFocusing(); + + m_sprHereWeGo.SetDiffuse( RageColor(1,1,1,1) ); + m_announcerHereWeGo.PlayRandom(); /* This gives the HWG about a second of screen time. */ this->SendScreenMessage( SM_StopHereWeGo, 1.5f ); @@ -1192,7 +1197,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) case SM_StopHereWeGo: /* We have one second until the notes start. */ - m_sprHereWeGo.StartBlurring(); + m_sprHereWeGo.SetTweenDiffuse( RageColor(1,1,1,0) ); m_DancingState = STATE_DANCING; // STATE CHANGE! Now the user is allowed to press Back break; diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index b94a814cad..80f0145bbf 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -20,7 +20,6 @@ #include "BitmapText.h" #include "Player.h" #include "RandomSample.h" -#include "FocusingSprite.h" #include "RageSoundManager.h" #include "RageSound.h" #include "MotionBlurSprite.h" @@ -112,8 +111,8 @@ protected: TransitionFadeWipe m_Fade; TransitionStarWipe m_StarWipe; - FocusingSprite m_sprReady; - FocusingSprite m_sprHereWeGo; + Sprite m_sprReady; + Sprite m_sprHereWeGo; MotionBlurSprite m_sprCleared; MotionBlurSprite m_sprFailed; MotionBlurSprite m_sprTryExtraStage; diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 4c7abf8bb4..b69df07a6f 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -22,7 +22,7 @@ enum { PO_SPEED = 0, - PO_BOOST, + PO_ACCEL, PO_EFFECT, PO_APPEAR, PO_TURN, @@ -34,10 +34,10 @@ enum { NUM_PLAYER_OPTIONS_LINES }; OptionRowData g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = { - { "Speed", 9, {"x0.5","x0.75","x1","x1.5","x2","x3","x4","x5","x8"} }, - { "Boost", 2, {"OFF","ON"} }, - { "Effect", 8, {"OFF","WAVE", "DRUNK", "DIZZY","SPACE","MINI","FLIP","TORNADO"} }, - { "Appear\n-ance", 5, {"VISIBLE","HIDDEN","SUDDEN","STEALTH", "BLINK"} }, + { "Speed", 10, {"x0.25","x0.5","x0.75","x1","x1.5","x2","x3","x4","x5","x8"} }, + { "Acceler\n-ation",6, {"OFF","BOOST","LAND","WAVE","EXPAND","BOOMERANG"} }, + { "Effect", 7, {"OFF","DRUNK","DIZZY","SPACE","MINI","FLIP","TORNADO"} }, + { "Appear\n-ance", 5, {"VISIBLE","HIDDEN","SUDDEN","STEALTH","BLINK"} }, { "Turn", 6, {"OFF","MIRROR","LEFT","RIGHT","SHUFFLE","SUPER SHUFFLE"} }, { "Little", 2, {"OFF","ON"} }, { "Scroll", 2, {"STANDARD","REVERSE"} }, @@ -72,18 +72,19 @@ void ScreenPlayerOptions::ImportOptions() { PlayerOptions &po = GAMESTATE->m_PlayerOptions[p]; - if( po.m_fArrowScrollSpeed == 0.5f ) m_iSelectedOption[p][PO_SPEED] = 0; - else if( po.m_fArrowScrollSpeed == 0.75f) m_iSelectedOption[p][PO_SPEED] = 1; - else if( po.m_fArrowScrollSpeed == 1.0f ) m_iSelectedOption[p][PO_SPEED] = 2; - else if( po.m_fArrowScrollSpeed == 1.5f ) m_iSelectedOption[p][PO_SPEED] = 3; - else if( po.m_fArrowScrollSpeed == 2.0f ) m_iSelectedOption[p][PO_SPEED] = 4; - else if( po.m_fArrowScrollSpeed == 3.0f ) m_iSelectedOption[p][PO_SPEED] = 5; - else if( po.m_fArrowScrollSpeed == 4.0f ) m_iSelectedOption[p][PO_SPEED] = 6; - else if( po.m_fArrowScrollSpeed == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 7; - else if( po.m_fArrowScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 8; - else m_iSelectedOption[p][PO_SPEED] = 2; + if( po.m_fScrollSpeed == 0.25f ) m_iSelectedOption[p][PO_SPEED] = 0; + else if( po.m_fScrollSpeed == 0.5f ) m_iSelectedOption[p][PO_SPEED] = 1; + else if( po.m_fScrollSpeed == 0.75f) m_iSelectedOption[p][PO_SPEED] = 2; + else if( po.m_fScrollSpeed == 1.0f ) m_iSelectedOption[p][PO_SPEED] = 3; + else if( po.m_fScrollSpeed == 1.5f ) m_iSelectedOption[p][PO_SPEED] = 4; + else if( po.m_fScrollSpeed == 2.0f ) m_iSelectedOption[p][PO_SPEED] = 5; + else if( po.m_fScrollSpeed == 3.0f ) m_iSelectedOption[p][PO_SPEED] = 6; + else if( po.m_fScrollSpeed == 4.0f ) m_iSelectedOption[p][PO_SPEED] = 7; + else if( po.m_fScrollSpeed == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 8; + else if( po.m_fScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 9; + else m_iSelectedOption[p][PO_SPEED] = 3; - m_iSelectedOption[p][PO_BOOST] = po.m_bBoost ? 1 : 0; + m_iSelectedOption[p][PO_ACCEL] = po.m_AccelType; for( int i=0; i 0 ) diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index 00daf3235d..dc472d3b50 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -581,7 +581,7 @@ void SongManager::GetExtraStageInfo( bool bExtra2, CString sPreferredGroup, cons po_out.Init(); so_out.Init(); po_out.m_bReverseScroll = true; - po_out.m_fArrowScrollSpeed = 1.5f; + po_out.m_fScrollSpeed = 1.5f; so_out.m_DrainType = (bExtra2 ? SongOptions::DRAIN_SUDDEN_DEATH : SongOptions::DRAIN_NO_RECOVER); // should we do something fancy here, like turn on different effects? @@ -593,7 +593,6 @@ void SongManager::GetExtraStageInfo( bool bExtra2, CString sPreferredGroup, cons case 2: po_out.m_bEffects[PlayerOptions::EFFECT_DRUNK] = true; break; case 3: po_out.m_bEffects[PlayerOptions::EFFECT_MINI] = true; break; case 4: po_out.m_bEffects[PlayerOptions::EFFECT_SPACE] = true; break; - case 5: po_out.m_bEffects[PlayerOptions::EFFECT_WAVE] = true; break; default: ASSERT(0); } }