From 4c12a0921bb6d77a288cf7451006caf402c2882e Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 1 Aug 2002 13:42:56 +0000 Subject: [PATCH] Fixes to Extra Stage --- stepmania/src/Course.cpp | 12 ++-- stepmania/src/Course.h | 7 +- stepmania/src/LifeMeterBattery.cpp | 44 +++++++----- stepmania/src/MenuElements.cpp | 6 +- stepmania/src/MenuElements.h | 2 + stepmania/src/MusicWheel.cpp | 80 ++++++++++++---------- stepmania/src/MusicWheel.h | 4 +- stepmania/src/Notes.cpp | 19 ++++-- stepmania/src/Notes.h | 3 +- stepmania/src/PlayerOptions.cpp | 70 ++++++++++++++++++- stepmania/src/PlayerOptions.h | 3 +- stepmania/src/RageUtil.cpp | 7 ++ stepmania/src/RageUtil.h | 2 +- stepmania/src/ScoreDisplayNormal.cpp | 1 + stepmania/src/ScoreDisplayOni.cpp | 11 +-- stepmania/src/ScreenEdit.cpp | 20 +++++- stepmania/src/ScreenEdit.h | 2 + stepmania/src/ScreenEditMenu.cpp | 2 +- stepmania/src/ScreenEvaluation.cpp | 6 +- stepmania/src/ScreenGameplay.cpp | 80 +++++++++++++++++----- stepmania/src/ScreenGameplay.h | 3 + stepmania/src/ScreenPlayerOptions.cpp | 14 ++-- stepmania/src/ScreenSelectGame.cpp | 6 ++ stepmania/src/ScreenSelectGroup.cpp | 6 +- stepmania/src/ScreenSelectMusic.h | 8 ++- stepmania/src/ScreenTitleMenu.cpp | 1 + stepmania/src/Song.cpp | 2 +- stepmania/src/SongManager.cpp | 98 ++++++++++++++++++++++++++- stepmania/src/SongManager.h | 2 + stepmania/src/SongOptions.cpp | 72 ++++++++++++++++++++ stepmania/src/SongOptions.h | 8 ++- 31 files changed, 480 insertions(+), 121 deletions(-) diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index 6f5b23345d..2af0e71f80 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -70,6 +70,7 @@ void Course::LoadFromCRSFile( CString sPath, CArray &apSongs ) { CString sSongDir = "Songs\\" + sParams[1] + "\\"; CString sNotesDescription = sParams[2]; + CString sModifiers = sParams[3]; int i; @@ -83,7 +84,7 @@ void Course::LoadFromCRSFile( CString sPath, CArray &apSongs ) if( pSong == NULL ) // we didn't find the Song continue; // skip this song - AddStage( pSong, sNotesDescription ); + AddStage( pSong, sNotesDescription, sModifiers ); } else @@ -110,7 +111,7 @@ void Course::CreateEndlessCourseFromGroupAndDifficultyClass( CString sGroupName, for( int s=0; s& apSongsOut, CArray apNotesOut[NUM_PLAYERS] ) +void Course::GetSongAndNotesForCurrentStyle( CArray& apSongsOut, CArray& apNotesOut, CStringArray& asModifiersOut ) { for( int i=0; i &apSongs ); void CreateEndlessCourseFromGroupAndDifficultyClass( CString sGroupName, DifficultyClass dc, CArray &apSongsInGroup ); - void AddStage( Song* pSong, CString sDescription ) + void AddStage( Song* pSong, CString sDescription, CString sModifiers ) { ASSERT( m_iStages <= MAX_COURSE_STAGES - 1 ); m_apSongs[m_iStages] = pSong; m_asDescriptions[m_iStages] = sDescription; + m_asModifiers[m_iStages] = sModifiers; m_iStages++; } - void GetSongAndNotesForCurrentStyle( CArray& apSongsOut, CArray apNotesOut[NUM_PLAYERS] ); + void GetSongAndNotesForCurrentStyle( CArray& apSongsOut, CArray& apNotesOut, CStringArray& asModifiersOut ); D3DXCOLOR GetColor(); }; diff --git a/stepmania/src/LifeMeterBattery.cpp b/stepmania/src/LifeMeterBattery.cpp index a31f250c6d..f30776671a 100644 --- a/stepmania/src/LifeMeterBattery.cpp +++ b/stepmania/src/LifeMeterBattery.cpp @@ -34,24 +34,6 @@ LifeMeterBattery::LifeMeterBattery() m_fBatteryBlinkTime = 0; - m_sprFrame.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_LIFEMETER_ONI) ); - this->AddSubActor( &m_sprFrame ); - - m_sprBattery.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_LIFEMETER_BATTERY) ); - m_sprBattery.StopAnimating(); - this->AddSubActor( &m_sprBattery ); - - m_textNumLives.Load( THEME->GetPathTo(FONT_HEADER1) ); - m_textNumLives.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // pink - m_textNumLives.SetZoom( 1.1f ); - m_textNumLives.TurnShadowOff(); - this->AddSubActor( &m_textNumLives ); - - m_textPercent.Load( THEME->GetPathTo(FONT_SCORE_NUMBERS) ); - m_textPercent.TurnShadowOff(); - m_textPercent.SetZoom( 0.7f ); - m_textPercent.SetText( "00.0" ); - this->AddSubActor( &m_textPercent ); m_soundGainLife.Load( THEME->GetPathTo(SOUND_GAMEPLAY_ONI_GAIN_LIFE) ); m_soundLoseLife.Load( THEME->GetPathTo(SOUND_GAMEPLAY_ONI_LOSE_LIFE) ); @@ -63,6 +45,32 @@ void LifeMeterBattery::Load( PlayerNumber pn ) { LifeMeter::Load( pn ); + bool bPlayerEnabled = GAMESTATE->IsPlayerEnabled(pn); + + m_sprFrame.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_LIFEMETER_ONI) ); + this->AddSubActor( &m_sprFrame ); + + m_sprBattery.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_LIFEMETER_BATTERY) ); + m_sprBattery.StopAnimating(); + if( bPlayerEnabled ) + this->AddSubActor( &m_sprBattery ); + + m_textNumLives.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textNumLives.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // pink + m_textNumLives.SetZoom( 1.1f ); + m_textNumLives.TurnShadowOff(); + if( bPlayerEnabled ) + this->AddSubActor( &m_textNumLives ); + + m_textPercent.Load( THEME->GetPathTo(FONT_SCORE_NUMBERS) ); + m_textPercent.TurnShadowOff(); + m_textPercent.SetZoom( 0.7f ); + m_textPercent.SetText( "00.0" ); + if( bPlayerEnabled ) + this->AddSubActor( &m_textPercent ); + + + m_sprFrame.SetZoomX( pn==PLAYER_1 ? 1.0f : -1.0f ); m_sprBattery.SetZoomX( pn==PLAYER_1 ? 1.0f : -1.0f ); m_sprBattery.SetX( BATTERY_X[pn] ); diff --git a/stepmania/src/MenuElements.cpp b/stepmania/src/MenuElements.cpp index ddad02cfe8..b4895d0938 100644 --- a/stepmania/src/MenuElements.cpp +++ b/stepmania/src/MenuElements.cpp @@ -250,5 +250,7 @@ void MenuElements::StopTimer() m_MenuTimer.StopTimer(); } - - +void MenuElements::OverrideCreditsMessage( PlayerNumber p, CString sNewString ) +{ + m_textCreditInfo[p].SetText( sNewString ); +} diff --git a/stepmania/src/MenuElements.h b/stepmania/src/MenuElements.h index 62edb2d23f..5618638b48 100644 --- a/stepmania/src/MenuElements.h +++ b/stepmania/src/MenuElements.h @@ -39,6 +39,8 @@ public: void SetTimer( int iTimerSeconds ); void StopTimer(); + void OverrideCreditsMessage( PlayerNumber p, CString sNewString ); + void DrawTopLayer(); void DrawBottomLayer(); diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 6dc68e624a..23ebfbca26 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -376,41 +376,53 @@ MusicWheel::MusicWheel() for( int so=0; soIsExtraStage() || GAMESTATE->IsExtraStage2() ) + if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) { - m_bUseRandomExtra = true; - Course cCourse; - for( int i=0; i< SONGMAN->m_aExtraCourses.GetSize(); i++ ) + // make the preferred group the group of the last song played. + if( GAMESTATE->m_sPreferredGroup == "ALL MUSIC" ) + GAMESTATE->m_sPreferredGroup = GAMESTATE->m_pCurSong->m_sGroupName; + + Song* pSong; + Notes* pNotes; + PlayerOptions po; + SongOptions so; + SONGMAN->GetExtraStageInfo( + GAMESTATE->IsExtraStage2(), + GAMESTATE->m_sPreferredGroup, + GAMESTATE->GetCurrentStyleDef()->m_NotesType, + pSong, + pNotes, + po, + so ); + GAMESTATE->m_pCurSong = pSong; + for( int p=0; pm_aExtraCourses[i]; - if( cCourse.m_sName == GAMESTATE->m_sPreferredGroup ) + if( GAMESTATE->IsPlayerEnabled(p) ) { - if( ( GAMESTATE->IsExtraStage() && cCourse.m_iExtra == 1 ) || - ( GAMESTATE->IsExtraStage2() && cCourse.m_iExtra == 2 ) || 1 ) // force extra whatever - { - GAMESTATE->m_pCurSong = SONGMAN->m_aExtraCourses[i].m_apSongs[0]; - m_bUseRandomExtra = false; - break; - } + GAMESTATE->m_pCurNotes[p] = pNotes; + GAMESTATE->m_PlayerOptions[p] = po; } } + GAMESTATE->m_SongOptions = so; } - // Select a song in case we can't find the last selected song below. - if( GAMESTATE->m_pCurSong == NULL && // if there is no currently selected song - SONGMAN->m_pSongs.GetSize() > 0 ) // and there is at least one song + // If there is no currently selected song, select one. + if( GAMESTATE->m_pCurSong == NULL ) { - CArray arraySongs; - SONGMAN->GetSongsInGroup( GAMESTATE->m_sPreferredGroup, arraySongs ); - // even tho separating these loops makes more code, in the end it'll be executed faster... - //else - if( arraySongs.GetSize() > 0 && GAMESTATE->m_pCurSong == NULL) // still nothing selected - GAMESTATE->m_pCurSong = arraySongs[0]; // select the first song + CStringArray asGroupNames; + SONGMAN->GetGroupNames( asGroupNames ); + if( asGroupNames.GetSize() > 0 ) + { + CArray arraySongs; + SONGMAN->GetSongsInGroup( asGroupNames[0], arraySongs ); + if( arraySongs.GetSize() > 0 ) // still nothing selected + GAMESTATE->m_pCurSong = arraySongs[0]; // select the first song + } } // Select the the previously selected song (if any) - if( GAMESTATE->m_pCurSong != NULL ) + if( GAMESTATE->m_pCurSong ) { for( int i=0; iIsExtraStage() || GAMESTATE->IsExtraStage2() ) { - if ( m_bUseRandomExtra ) - { - MUSIC->Stop(); - m_soundExpand.Play(); - m_WheelState = STATE_ROULETTE_SPINNING; - m_SortOrder = SORT_GROUP; - m_MusicSortDisplay.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); - m_MusicSortDisplay.SetEffectNone(); - BuildWheelItemDatas( m_WheelItemDatas[SORT_GROUP], SORT_GROUP, true ); - } - else +// if ( m_bUseRandomExtra ) +// { +// MUSIC->Stop(); +// m_soundExpand.Play(); +// m_WheelState = STATE_ROULETTE_SPINNING; +// m_SortOrder = SORT_GROUP; +// m_MusicSortDisplay.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); +// m_MusicSortDisplay.SetEffectNone(); +// BuildWheelItemDatas( m_WheelItemDatas[SORT_GROUP], SORT_GROUP, true ); +// } +// else { m_WheelState = STATE_LOCKED; m_soundStart.Play(); diff --git a/stepmania/src/MusicWheel.h b/stepmania/src/MusicWheel.h index 08bc30ca92..69de96c4e4 100644 --- a/stepmania/src/MusicWheel.h +++ b/stepmania/src/MusicWheel.h @@ -167,9 +167,9 @@ protected: float m_fTimeLeftInState; float m_fPositionOffsetFromSelection; - bool m_bUseRandomExtra; +// bool m_bUseRandomExtra; - // having sounds here causes a crash in Bass. What the heck!?!?! + // having sounds here causes a crash in BASS. What the heck!?!?! RageSoundSample m_soundChangeMusic; RageSoundSample m_soundChangeSort; RageSoundSample m_soundExpand; diff --git a/stepmania/src/Notes.cpp b/stepmania/src/Notes.cpp index 31aba26049..c88d63be3a 100644 --- a/stepmania/src/Notes.cpp +++ b/stepmania/src/Notes.cpp @@ -791,24 +791,29 @@ int CompareNotesPointersByMeter(const void *arg1, const void *arg2) return 1; } -int CompareNotesPointersByDifficultyClass(const void *arg1, const void *arg2) +int CompareNotesPointersByDifficulty(Notes* pNotes1, Notes* pNotes2) { - Notes* pNotes1 = *(Notes**)arg1; - Notes* pNotes2 = *(Notes**)arg2; - DifficultyClass class1 = pNotes1->m_DifficultyClass; DifficultyClass class2 = pNotes2->m_DifficultyClass; if( class1 < class2 ) return -1; else if( class1 == class2 ) - return CompareNotesPointersByMeter( arg1, arg2 ); + return CompareNotesPointersByMeter( &pNotes1, &pNotes2 ); else return 1; } -void SortNotesArrayByDifficultyClass( CArray &arraySteps ) +int CompareNotesPointersByDifficulty2(const void *arg1, const void *arg2) { - qsort( arraySteps.GetData(), arraySteps.GetSize(), sizeof(Notes*), CompareNotesPointersByDifficultyClass ); + Notes* pNotes1 = *(Notes**)arg1; + Notes* pNotes2 = *(Notes**)arg2; + + return CompareNotesPointersByDifficulty( pNotes1, pNotes2 ); +} + +void SortNotesArrayByDifficulty( CArray &arraySteps ) +{ + qsort( arraySteps.GetData(), arraySteps.GetSize(), sizeof(Notes*), CompareNotesPointersByDifficulty2 ); } diff --git a/stepmania/src/Notes.h b/stepmania/src/Notes.h index 8f3a8b8e32..a6816da7c9 100644 --- a/stepmania/src/Notes.h +++ b/stepmania/src/Notes.h @@ -84,4 +84,5 @@ protected: }; -void SortNotesArrayByDifficultyClass( CArray &arrayNotess ); +int CompareNotesPointersByDifficulty(Notes* pNotes1, Notes* pNotes2); +void SortNotesArrayByDifficulty( CArray &arrayNotess ); diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index 0bada2a74e..f0afa54f96 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -17,8 +17,15 @@ CString PlayerOptions::GetString() { CString sReturn; + if( m_fArrowScrollSpeed != 1 ) - sReturn += ssprintf( "%2.1fX, ", m_fArrowScrollSpeed ); + { + CString s = ssprintf( "%2.2f", m_fArrowScrollSpeed ); + if( s[s.GetLength()-1] == '0' ) + s.Delete(s.GetLength()-1); + sReturn += s + "X, "; + } + switch( m_EffectType ) { case EFFECT_NONE: break; @@ -30,15 +37,17 @@ CString PlayerOptions::GetString() case EFFECT_MINI: sReturn += "Mini, "; break; default: ASSERT(0); // invalid EFFECT } + switch( m_AppearanceType ) { case APPEARANCE_VISIBLE: break; case APPEARANCE_HIDDEN: sReturn += "Hidden, "; break; case APPEARANCE_SUDDEN: sReturn += "Sudden, "; break; case APPEARANCE_STEALTH: sReturn += "Stealth, "; break; - case APPEARANCE_BLINK: sReturn += "Blink, "; break; + case APPEARANCE_BLINK: sReturn += "Blink, "; break; default: ASSERT(0); // invalid EFFECT } + switch( m_TurnType ) { case TURN_NONE: break; @@ -48,11 +57,27 @@ CString PlayerOptions::GetString() case TURN_SHUFFLE: sReturn += "Shuffle, "; break; default: ASSERT(0); // invalid EFFECT } + if( m_bLittle ) sReturn += "Little, "; + if( m_bReverseScroll ) sReturn += "Reverse, "; + switch( m_ColorType ) + { + case COLOR_ARCADE: break; + case COLOR_NOTE: sReturn += "Note, "; break; + case COLOR_FLAT: sReturn += "Flat, "; break; + case COLOR_PLAIN: sReturn += "Plain, "; break; + }; + + if( !m_bHoldNotes ) + sReturn += "NoHolds, "; + + if( m_bDark ) + sReturn += "Dark, "; + if( sReturn.GetLength() > 2 ) sReturn.Delete( sReturn.GetLength()-2, 2 ); // delete the trailing ", " return sReturn; @@ -60,4 +85,45 @@ CString PlayerOptions::GetString() void PlayerOptions::FromString( CString sOptions ) { + Init(); + sOptions.MakeLower(); + CStringArray asBits; + split( sOptions, ",", asBits, true ); + + for( int i=0; iGetPlayerSurviveTime(m_PlayerNumber); + float fSecsIntoPlay; + if( GAMESTATE->IsPlayerEnabled(m_PlayerNumber) ) + fSecsIntoPlay = GAMESTATE->GetPlayerSurviveTime(m_PlayerNumber); + else + fSecsIntoPlay = 0; - int iMinsDisplay = (int)fSecsIntoPlay/60; - int iSecsDisplay = (int)fSecsIntoPlay - iMinsDisplay*60; - int iLeftoverDisplay = int( (fSecsIntoPlay - iMinsDisplay*60 - iSecsDisplay) * 100 ); - SetText( ssprintf( "%02d:%02d:%02d", iMinsDisplay, iSecsDisplay, iLeftoverDisplay ) ); + SetText( SecondsToTime(fSecsIntoPlay) ); BitmapText::Draw(); } diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index d28a354139..2002c06477 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -65,6 +65,7 @@ const CString HELP_TEXT = " 4th / 8th / 12th / 16th / 12th or 16th\n" "P: Play selected area\n" "R: Record in selected area\n" + "T: Toggle Play/Record rate\n" "X: Cut selected area\n" "C: Copy selected area\n" "V: Paste at current beat\n" @@ -124,6 +125,8 @@ ScreenEdit::ScreenEdit() m_fBeat = 0.0f; GAMESTATE->m_fSongBeat = m_fBeat; + + m_fMusicRate = 1; GAMESTATE->m_PlayerOptions[PLAYER_1].m_fArrowScrollSpeed = 1; GAMESTATE->m_PlayerOptions[PLAYER_1].m_ColorType = PlayerOptions::COLOR_NOTE; @@ -309,6 +312,7 @@ void ScreenEdit::Update( float fDeltaTime ) "Snap = %s\n" "Beat = %.2f\n" "Selection = begin: %.2f, end: %.2f\n" + "Play/Record rate: %.1f\n" "Difficulty = %s\n" "Description = %s\n" "Num notes tap: %d, hold: %d\n" @@ -317,6 +321,7 @@ void ScreenEdit::Update( float fDeltaTime ) sNoteType, m_fBeat, m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker, + m_fMusicRate, DifficultyClassToString( m_pNotes->m_DifficultyClass ), GAMESTATE->m_pCurNotes[PLAYER_1] ? GAMESTATE->m_pCurNotes[PLAYER_1]->m_sDescription : "no description", iNumTapNotes, iNumHoldNotes, @@ -580,7 +585,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); m_soundMusic.SetPositionSeconds( fElapsedSeconds ); m_soundMusic.Play(); - m_soundMusic.SetPlaybackRate( 1.0f ); + m_soundMusic.SetPlaybackRate( m_fMusicRate ); } break; case DIK_R: @@ -607,9 +612,20 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); m_soundMusic.SetPositionSeconds( fElapsedSeconds ); m_soundMusic.Play(); - m_soundMusic.SetPlaybackRate( 0.5f ); + m_soundMusic.SetPlaybackRate( m_fMusicRate ); } break; + case DIK_T: + if( m_fMusicRate == 1.0f ) m_fMusicRate = 0.9f; + else if( m_fMusicRate == 0.9f ) m_fMusicRate = 0.8f; + else if( m_fMusicRate == 0.8f ) m_fMusicRate = 0.7f; + else if( m_fMusicRate == 0.7f ) m_fMusicRate = 1.5f; + else if( m_fMusicRate == 1.5f ) m_fMusicRate = 1.4f; + else if( m_fMusicRate == 1.4f ) m_fMusicRate = 1.3f; + else if( m_fMusicRate == 1.3f ) m_fMusicRate = 1.2f; + else if( m_fMusicRate == 1.2f ) m_fMusicRate = 1.1f; + else if( m_fMusicRate == 1.1f ) m_fMusicRate = 1.0f; + break; case DIK_INSERT: case DIK_DELETE: { diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h index a34d28ceb3..e3ec087347 100644 --- a/stepmania/src/ScreenEdit.h +++ b/stepmania/src/ScreenEdit.h @@ -61,6 +61,8 @@ protected: NoteData m_Clipboard; + float m_fMusicRate; + RageSoundSample m_soundChangeLine; RageSoundSample m_soundChangeSnap; RageSoundSample m_soundMarker; diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp index 14b13990b1..3bf5126114 100644 --- a/stepmania/src/ScreenEditMenu.cpp +++ b/stepmania/src/ScreenEditMenu.cpp @@ -237,7 +237,7 @@ void ScreenEditMenu::OnNotesTypeChange() m_pNotess.RemoveAll(); GetSelectedSong()->GetNotesThatMatch( GetSelectedNotesType(), m_pNotess ); - SortNotesArrayByDifficultyClass( m_pNotess ); + SortNotesArrayByDifficulty( m_pNotess ); m_pNotess.Add( NULL ); // marker for "(NEW)" m_iSelectedNotes = 0; diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 5d73ffa914..11c8192e07 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -291,7 +291,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary ) //Less - D //Fail - E float fPercentDancePoints = iActualDancePoints[p] / (float)iPossibleDancePoints[p]; - fPercentDancePoints = min( fPercentDancePoints, 0 ); + fPercentDancePoints = max( fPercentDancePoints, 0 ); if ( fPercentDancePoints >= 1.00 ) grade[p] = GRADE_AAA; else if( fPercentDancePoints >= 0.93 ) grade[p] = GRADE_AA; @@ -767,8 +767,10 @@ void ScreenEvaluation::MenuStart( const PlayerNumber p ) { if( m_bTryExtraStage ) m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic ); - else if( m_ResultMode == RM_ARCADE_STAGE && GAMESTATE->m_iCurrentStageIndex >= PREFSMAN->m_iNumArcadeStages-1 ) + else if( m_ResultMode == RM_ARCADE_STAGE && GAMESTATE->m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages-1 ) m_Menu.TweenOffScreenToMenu( SM_GoToFinalEvaluation ); + else if( m_ResultMode == RM_ARCADE_STAGE && GAMESTATE->m_iCurrentStageIndex != PREFSMAN->m_iNumArcadeStages-1 ) + m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic ); else m_Menu.TweenOffScreenToBlack( SM_GoToMusicScroll, false ); } diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 7c3b2b920f..972d862a0c 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -61,6 +61,9 @@ const float DIFFICULTY_Y[NUM_PLAYERS] = { SCREEN_BOTTOM-70, SCREEN_BOTTOM-70 }; const float DEBUG_X = CENTER_X; const float DEBUG_Y = CENTER_Y-70; +const float SURVIVE_TIME_X = CENTER_X; +const float SURVIVE_TIME_Y = CENTER_Y+100; + const float TIME_BETWEEN_DANCING_COMMENTS = 13; @@ -111,12 +114,13 @@ ScreenGameplay::ScreenGameplay() Course* pCourse = GAMESTATE->m_pCurCourse; CArray apSongs; - CArray apNotes[NUM_PLAYERS]; - pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes ); + CArray apNotes; + CStringArray asModifiers; + pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers ); - for( int i=0; iGetNoteData( ¬edata ); + apNotes[i]->GetNoteData( ¬edata ); int iPossibleDancePoints = notedata.GetPossibleDancePoints(); GAMESTATE->m_iPossibleDancePoints[p] += iPossibleDancePoints; } @@ -228,7 +232,8 @@ ScreenGameplay::ScreenGameplay() case PLAY_MODE_ONI: case PLAY_MODE_ENDLESS: for( int p=0; pIsPlayerEnabled(p) ) + m_frameTop.AddSubActor( &m_textCourseSongNumber[p] ); break; default: ASSERT(0); // invalid GameMode @@ -313,7 +318,7 @@ ScreenGameplay::ScreenGameplay() float fDifficultyY = DIFFICULTY_Y[p]; if( GAMESTATE->m_PlayerOptions[p].m_bReverseScroll ) - fDifficultyY = SCREEN_HEIGHT - DIFFICULTY_Y[p]; + fDifficultyY = SCREEN_HEIGHT - DIFFICULTY_Y[p] -10; // HACK: move difficulty banner up 10 if reverse m_DifficultyBanner[p].SetXY( DIFFICULTY_X[p], fDifficultyY ); this->AddSubActor( &m_DifficultyBanner[p] ); @@ -363,6 +368,14 @@ ScreenGameplay::ScreenGameplay() this->AddSubActor( &m_Fade ); + m_textSurviveTime.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textSurviveTime.TurnShadowOff(); + m_textSurviveTime.SetXY( SURVIVE_TIME_X, SURVIVE_TIME_Y ); + m_textSurviveTime.SetText( "" ); + m_textSurviveTime.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddSubActor( &m_textSurviveTime ); + + m_soundFail.Load( THEME->GetPathTo(SOUND_GAMEPLAY_FAILED) ); m_announcerReady.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_READY) ); @@ -429,8 +442,9 @@ bool ScreenGameplay::IsLastSong() return false; CArray apSongs; - CArray apNotes[NUM_PLAYERS]; - pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes ); + CArray apNotes; + CStringArray asModifiers; + pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers ); return GAMESTATE->m_iSongsIntoCourse >= apSongs.GetSize(); // there are no more songs left } @@ -457,8 +471,9 @@ void ScreenGameplay::LoadNextSong( bool bFirstLoad ) Course* pCourse = GAMESTATE->m_pCurCourse; CArray apSongs; - CArray apNotes[NUM_PLAYERS]; - pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes ); + CArray apNotes; + CStringArray asModifiers; + pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers ); int iPlaySongIndex = -1; if( pCourse->m_bRandomize ) @@ -468,7 +483,11 @@ void ScreenGameplay::LoadNextSong( bool bFirstLoad ) GAMESTATE->m_pCurSong = apSongs[iPlaySongIndex]; for( int p=0; pm_pCurNotes[p] = apNotes[p][iPlaySongIndex]; + { + GAMESTATE->m_pCurNotes[p] = apNotes[iPlaySongIndex]; + if( asModifiers[iPlaySongIndex] != "" ) // some modifiers specified + GAMESTATE->m_PlayerOptions[p].FromString( asModifiers[iPlaySongIndex] ); // put them into effect + } } break; default: @@ -777,14 +796,18 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ if( MenuI.IsValid() && MenuI.button == MENU_BUTTON_BACK && - type == IET_SLOW_REPEAT && m_DancingState != STATE_OUTRO && !m_Fade.IsClosing() ) { - SOUND->PlayOnceStreamed( THEME->GetPathTo(SOUND_MENU_BACK) ); - m_soundMusic.Stop(); - this->ClearMessageQueue(); - m_Fade.CloseWipingLeft( SM_SaveChangedBeforeGoingBack ); + if( (DeviceI.device==DEVICE_KEYBOARD && type==IET_SLOW_REPEAT) || + (DeviceI.device!=DEVICE_KEYBOARD && type==IET_FAST_REPEAT) ) + { + m_DancingState = STATE_OUTRO; + SOUND->PlayOnceStreamed( THEME->GetPathTo(SOUND_MENU_BACK) ); + m_soundMusic.Stop(); + this->ClearMessageQueue(); + m_Fade.CloseWipingLeft( SM_SaveChangedBeforeGoingBack ); + } } // @@ -1079,8 +1102,10 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) { m_bChangedOffsetOrBPM = false; ShowSavePrompt( SM_GoToScreenAfterBack ); - break; } + else + this->SendScreenMessage( SM_GoToScreenAfterBack, 0 ); + break; case SM_GoToScreenAfterBack: switch( GAMESTATE->m_PlayMode ) @@ -1110,6 +1135,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_DancingState = STATE_OUTRO; m_soundMusic.Pause(); m_StarWipe.CloseWipingRight( SM_None ); + this->SendScreenMessage( SM_ShowFailed, 0.2f ); break; case SM_ShowFailed: @@ -1130,6 +1156,20 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_sprFailed.SetTweenZoom( 1.0f ); // come to rest m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0.7f) ); // and fade in + // show the survive time if extra stage + if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) + { + float fMaxSurviveSeconds = -1; + for( int p=0; pIsPlayerEnabled(p) ) + fMaxSurviveSeconds = max( fMaxSurviveSeconds, GAMESTATE->GetPlayerSurviveTime((PlayerNumber)p) ); + ASSERT( fMaxSurviveSeconds != -1 ); + m_textSurviveTime.SetText( "TIME " + SecondsToTime(fMaxSurviveSeconds) ); + m_textSurviveTime.BeginTweening( 0.3f ); // sleep + m_textSurviveTime.BeginTweeningQueued( 0.3f ); // fade in + m_textSurviveTime.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + } + SCREENMAN->SendMessageToTopScreen( SM_PlayFailComment, 1.5f ); SCREENMAN->SendMessageToTopScreen( SM_HideFailed, 3.0f ); break; @@ -1141,6 +1181,10 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_sprFailed.BeginTweening(1.0f); m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_textSurviveTime.BeginTweening( 0.5f ); // sleep + m_textSurviveTime.BeginTweeningQueued( 0.5f ); // fade out + m_textSurviveTime.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + SCREENMAN->SendMessageToTopScreen( SM_GoToScreenAfterFail, 1.5f ); break; case SM_GoToScreenAfterFail: @@ -1152,6 +1196,8 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) } if( PREFSMAN->m_bEventMode ) this->SendScreenMessage( SM_GoToScreenAfterBack, 0 ); + else if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) + SCREENMAN->SetNewScreen( new ScreenEvaluation(true) ); else SCREENMAN->SetNewScreen( new ScreenGameOver ); break; diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index 78d5761533..242da6f230 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -103,6 +103,9 @@ private: FocusingSprite m_sprCleared; MotionBlurSprite m_sprFailed; + BitmapText m_textSurviveTime; // only shown in extra stage + + Player m_Player[NUM_PLAYERS]; DifficultyBanner m_DifficultyBanner[NUM_PLAYERS]; diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 1b42d12c3b..f87da4a550 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -39,9 +39,9 @@ enum { NUM_PLAYER_OPTIONS_LINES }; OptionLineData g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = { - { "Speed", 8, {"x0.5","x0.75","x1","x1.5","x2","x3","x5","x8"} }, + { "Speed", 9, {"x0.5","x0.75","x1","x1.5","x2","x3","x4","x5","x8"} }, { "Effect", 7, {"OFF","BOOST","WAVE", "DRUNK", "DIZZY","SPACE","MINI"} }, - { "Appear", 5, {"VISIBLE","HIDDEN","SUDDEN","STEALTH", "BLINK"} }, + { "Appear", 4, {"VISIBLE","HIDDEN","SUDDEN","STEALTH"} }, { "Turn", 5, {"OFF","MIRROR","LEFT","RIGHT","SHUFFLE"} }, { "Little", 2, {"OFF","ON"} }, { "Scroll", 2, {"STANDARD","REVERSE"} }, @@ -81,8 +81,9 @@ void ScreenPlayerOptions::ImportOptions() 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 == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 6; - else if( po.m_fArrowScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 7; + 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; m_iSelectedOption[p][PO_EFFECT] = po.m_EffectType; @@ -110,8 +111,9 @@ void ScreenPlayerOptions::ExportOptions() case 3: po.m_fArrowScrollSpeed = 1.5f; break; case 4: po.m_fArrowScrollSpeed = 2.0f; break; case 5: po.m_fArrowScrollSpeed = 3.0f; break; - case 6: po.m_fArrowScrollSpeed = 5.0f; break; - case 7: po.m_fArrowScrollSpeed = 8.0f; break; + case 6: po.m_fArrowScrollSpeed = 4.0f; break; + case 7: po.m_fArrowScrollSpeed = 5.0f; break; + case 8: po.m_fArrowScrollSpeed = 8.0f; break; } diff --git a/stepmania/src/ScreenSelectGame.cpp b/stepmania/src/ScreenSelectGame.cpp index 0bf1c71c6a..3901ca8e80 100644 --- a/stepmania/src/ScreenSelectGame.cpp +++ b/stepmania/src/ScreenSelectGame.cpp @@ -58,6 +58,12 @@ ScreenSelectGame::ScreenSelectGame() : g_SelectGameLines[0].iNumOptions = arrayGameNames.GetSize(); + // HACK: Chris: Temporarily disable EZ2Dancer. The EZ2 menus aren't working correctly, + // and I have to leave for California in 4 hours - not enough time to fix this and do a + // release. + g_SelectGameLines[0].iNumOptions = 2; + + Init( INPUTMODE_P1_ONLY, g_SelectGameLines, diff --git a/stepmania/src/ScreenSelectGroup.cpp b/stepmania/src/ScreenSelectGroup.cpp index d8a59b0c68..f1b72093da 100644 --- a/stepmania/src/ScreenSelectGroup.cpp +++ b/stepmania/src/ScreenSelectGroup.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" /* ----------------------------------------------------------------------------- - File: ScreenSelectGroup.cpp + Class: ScreenSelectGroup Desc: See header. @@ -447,7 +447,7 @@ void ScreenSelectGroup::MenuUp( const PlayerNumber p ) m_iSelection = m_iSelection-1 % m_arrayGroupNames.GetSize(); if( m_iSelection < 0 ) - m_iSelection += m_arrayGroupNames.GetSize(); + m_iSelection += min( m_arrayGroupNames.GetSize(), MAX_GROUPS ); AfterChange(); @@ -462,7 +462,7 @@ void ScreenSelectGroup::MenuDown( const PlayerNumber p ) BeforeChange(); - m_iSelection = (m_iSelection+1) % m_arrayGroupNames.GetSize(); + m_iSelection = (m_iSelection+1) % min( m_arrayGroupNames.GetSize(), MAX_GROUPS ); AfterChange(); diff --git a/stepmania/src/ScreenSelectMusic.h b/stepmania/src/ScreenSelectMusic.h index 90a7799216..26ec05bd6c 100644 --- a/stepmania/src/ScreenSelectMusic.h +++ b/stepmania/src/ScreenSelectMusic.h @@ -50,6 +50,8 @@ protected: void AfterMusicChange(); void PlayMusicSample(); + void UpdateOptionsDisplays(); + CArray m_arrayNotes; int m_iSelection[NUM_PLAYERS]; @@ -59,6 +61,7 @@ protected: Sprite m_sprDifficultyFrame; DifficultyIcon m_DifficultyIcon[NUM_PLAYERS]; GrooveRadar m_GrooveRadar; + BitmapText m_textSongOptions; Sprite m_sprMeterFrame; FootMeter m_FootMeter[NUM_PLAYERS]; MusicWheel m_MusicWheel; @@ -67,8 +70,9 @@ protected: bool m_bGoToOptions; BitmapText m_textHoldForOptions; - RandomSample m_soundSelect; - RandomSample m_soundChangeNotes; + RageSoundSample m_soundSelect; + RageSoundSample m_soundChangeNotes; + RageSoundSample m_soundLocked; }; diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index f901344320..f2d14041ac 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -75,6 +75,7 @@ ScreenTitleMenu::ScreenTitleMenu() PREFSMAN->ReadGamePrefsFromDisk(); INPUTMAPPER->ReadMappingsFromDisk(); + int i; m_sprBG.Load( THEME->GetPathTo(GRAPHIC_TITLE_MENU_BACKGROUND) ); diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 680d9bbabf..9c43cedc42 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1286,7 +1286,7 @@ Grade Song::GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc ) { CArray aNotes; this->GetNotesThatMatch( nt, aNotes ); - SortNotesArrayByDifficultyClass( aNotes ); + SortNotesArrayByDifficulty( aNotes ); for( int i=0; i apSongs; + SONGMAN->GetSongsInGroup( GAMESTATE->m_sPreferredGroup, apSongs ); + for( int s=0; s apNotes; + pSong->GetNotesThatMatch( nt, apNotes ); + for( int n=0; n 8 + if( bExtra2 && pNotes->m_iMeter > 8 ) + continue; // skip + if( pExtra2Notes == NULL || CompareNotesPointersByDifficulty(pExtra2Notes,pNotes) == -1 ) // pNotes is harder than pHardestNotes + { + pExtra2Song = pSong; + pExtra2Notes = pNotes; + } + } + } + + if( pExtra2Song == NULL && pExtra1Song != NULL ) + { + pExtra2Song = pExtra1Song; + pExtra2Notes = pExtra1Notes; + } + + // If there are any notes at all that match this NotesType, everything should be filled out. + // Also, it's guaranteed that there is at least one Notes that matches the NotesType because the player + // had to play something before reaching the extra stage! + ASSERT( pExtra2Song && pExtra1Song && pExtra2Notes && pExtra1Notes ); + + pSongOut = (bExtra2 ? pExtra2Song : pExtra1Song); + pNotesOut = (bExtra2 ? pExtra2Notes : pExtra1Notes); + + + po_out.Init(); + so_out.Init(); + po_out.m_bReverseScroll = true; + po_out.m_fArrowScrollSpeed = 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? + int iSongHash = GetHashForString( pSongOut->m_sSongDir ); + switch( iSongHash % 6 ) + { + case 0: po_out.m_EffectType = PlayerOptions::EFFECT_DIZZY; break; + case 1: po_out.m_bDark = true; break; + case 2: po_out.m_EffectType = PlayerOptions::EFFECT_DRUNK; break; + case 3: po_out.m_EffectType = PlayerOptions::EFFECT_MINI; break; + case 4: po_out.m_EffectType = PlayerOptions::EFFECT_SPACE; break; + case 5: po_out.m_EffectType = PlayerOptions::EFFECT_WAVE; break; + default: ASSERT(0); + } +} diff --git a/stepmania/src/SongManager.h b/stepmania/src/SongManager.h index d49d818898..4bcb80682b 100644 --- a/stepmania/src/SongManager.h +++ b/stepmania/src/SongManager.h @@ -55,6 +55,8 @@ public: void InitCoursesFromDisk(); void ReloadCourses(); + void GetExtraStageInfo( bool bExtra2, CString sPreferredGroup, NotesType nt, + Song*& pSongOut, Notes*& pNotesOut, PlayerOptions& po_out, SongOptions& so_out ); protected: void LoadStepManiaSongDir( CString sDir, void(*callback)() ); diff --git a/stepmania/src/SongOptions.cpp b/stepmania/src/SongOptions.cpp index 967da2237e..d3803c62b4 100644 --- a/stepmania/src/SongOptions.cpp +++ b/stepmania/src/SongOptions.cpp @@ -10,3 +10,75 @@ ----------------------------------------------------------------------------- */ +#include "SongOptions.h" +#include "RageUtil.h" + + +CString SongOptions::GetString() +{ + CString sReturn; + + switch( m_LifeType ) + { + case LIFE_BAR: + switch( m_DrainType ) + { + case DRAIN_NORMAL: break; + case DRAIN_NO_RECOVER: sReturn += "NoRecover, "; break; + case DRAIN_SUDDEN_DEATH: sReturn += "SuddenDeath, "; break; + } + break; + case LIFE_BATTERY: + sReturn += ssprintf( "%dLives, ", m_iBatteryLives ); + break; + } + + + switch( m_FailType ) + { + case FAIL_ARCADE: break; + case FAIL_END_OF_SONG: sReturn += "FailEndOfSong, "; break; + case FAIL_OFF: sReturn += "FailOff, "; break; + } + + if( m_fMusicRate != 1 ) + { + CString s = ssprintf( "%2.2fxMusic", m_fMusicRate ); + if( s[s.GetLength()-1] == '0' ) + s.Delete(s.GetLength()); + sReturn += s + ", "; + } + + if( sReturn.GetLength() > 2 ) + sReturn.Delete( sReturn.GetLength()-2, 2 ); // delete the trailing ", " + return sReturn; +} + +void SongOptions::FromString( CString sOptions ) +{ + Init(); + sOptions.MakeLower(); + CStringArray asBits; + split( sOptions, ",", asBits, true ); + + for( int i=0; i