diff --git a/stepmania/src/AnnouncerManager.cpp b/stepmania/src/AnnouncerManager.cpp index a84352bdde..2e8eb74cf0 100644 --- a/stepmania/src/AnnouncerManager.cpp +++ b/stepmania/src/AnnouncerManager.cpp @@ -92,34 +92,28 @@ CString AnnouncerManager::GetPathTo( AnnouncerElement ae, CString sAnnouncerName case ANNOUNCER_GAMEPLAY_900_COMBO: sAssetDir = "gameplay 900 combo"; break; case ANNOUNCER_GAMEPLAY_CLEARED: sAssetDir = "gameplay cleared"; break; case ANNOUNCER_GAMEPLAY_COMBO_STOPPED: sAssetDir = "gameplay combo stopped"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_BAD: sAssetDir = "gameplay comment bad"; break; + case ANNOUNCER_GAMEPLAY_COMMENT_DANGER: sAssetDir = "gameplay comment danger"; break; case ANNOUNCER_GAMEPLAY_COMMENT_GOOD: sAssetDir = "gameplay comment good"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_OK: sAssetDir = "gameplay comment ok"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_VERY_BAD: sAssetDir = "gameplay comment very bad"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_BOTH: sAssetDir = "gameplay comment very good both"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_P1: sAssetDir = "gameplay comment very good p1"; break; - case ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_P2: sAssetDir = "gameplay comment very good p2"; break; + case ANNOUNCER_GAMEPLAY_COMMENT_HOT: sAssetDir = "gameplay comment hot"; break; case ANNOUNCER_GAMEPLAY_FAILED: sAssetDir = "gameplay failed"; break; case ANNOUNCER_GAMEPLAY_HERE_WE_GO_EXTRA: sAssetDir = "gameplay here we go extra"; break; case ANNOUNCER_GAMEPLAY_HERE_WE_GO_FINAL: sAssetDir = "gameplay here we go final"; break; case ANNOUNCER_GAMEPLAY_HERE_WE_GO_NORMAL: sAssetDir = "gameplay here we go normal"; break; case ANNOUNCER_GAMEPLAY_READY: sAssetDir = "gameplay ready"; break; - case ANNOUNCER_FINAL_RESULT_A: sAssetDir = "final result a"; break; - case ANNOUNCER_FINAL_RESULT_AA: sAssetDir = "final result aa"; break; - case ANNOUNCER_FINAL_RESULT_AAA: sAssetDir = "final result aaa"; break; - case ANNOUNCER_FINAL_RESULT_B: sAssetDir = "final result b"; break; - case ANNOUNCER_FINAL_RESULT_C: sAssetDir = "final result c"; break; - case ANNOUNCER_FINAL_RESULT_D: sAssetDir = "final result d"; break; - case ANNOUNCER_FINAL_RESULT_E: sAssetDir = "final result e"; break; + case ANNOUNCER_EVALUATION_FINAL_A: sAssetDir = "evaluation final a"; break; + case ANNOUNCER_EVALUATION_FINAL_AA: sAssetDir = "evaluation final aa"; break; + case ANNOUNCER_EVALUATION_FINAL_AAA: sAssetDir = "evaluation final aaa"; break; + case ANNOUNCER_EVALUATION_FINAL_B: sAssetDir = "evaluation final b"; break; + case ANNOUNCER_EVALUATION_FINAL_C: sAssetDir = "evaluation final c"; break; + case ANNOUNCER_EVALUATION_FINAL_D: sAssetDir = "evaluation final d"; break; case ANNOUNCER_GAME_OVER: sAssetDir = "game over"; break; case ANNOUNCER_MUSIC_SCROLL: sAssetDir = "music scroll"; break; - case ANNOUNCER_RESULT_A: sAssetDir = "result a"; break; - case ANNOUNCER_RESULT_AA: sAssetDir = "result aa"; break; - case ANNOUNCER_RESULT_AAA: sAssetDir = "result aaa"; break; - case ANNOUNCER_RESULT_B: sAssetDir = "result b"; break; - case ANNOUNCER_RESULT_C: sAssetDir = "result c"; break; - case ANNOUNCER_RESULT_D: sAssetDir = "result d"; break; - case ANNOUNCER_RESULT_E: sAssetDir = "result e"; break; + case ANNOUNCER_EVALUATION_A: sAssetDir = "evaluation a"; break; + case ANNOUNCER_EVALUATION_AA: sAssetDir = "evaluation aa"; break; + case ANNOUNCER_EVALUATION_AAA: sAssetDir = "evaluation aaa"; break; + case ANNOUNCER_EVALUATION_B: sAssetDir = "evaluation b"; break; + case ANNOUNCER_EVALUATION_C: sAssetDir = "evaluation c"; break; + case ANNOUNCER_EVALUATION_D: sAssetDir = "evaluation d"; break; case ANNOUNCER_SELECT_COURSE_INTRO: sAssetDir = "select course intro"; break; case ANNOUNCER_SELECT_DIFFICULTY_COMMENT_EASY: sAssetDir = "select difficulty comment easy"; break; case ANNOUNCER_SELECT_DIFFICULTY_COMMENT_HARD: sAssetDir = "select difficulty comment hard"; break; diff --git a/stepmania/src/AnnouncerManager.h b/stepmania/src/AnnouncerManager.h index 2bb42324eb..a29b478dfe 100644 --- a/stepmania/src/AnnouncerManager.h +++ b/stepmania/src/AnnouncerManager.h @@ -28,34 +28,30 @@ enum AnnouncerElement { ANNOUNCER_GAMEPLAY_900_COMBO, ANNOUNCER_GAMEPLAY_CLEARED, ANNOUNCER_GAMEPLAY_COMBO_STOPPED, - ANNOUNCER_GAMEPLAY_COMMENT_BAD, + ANNOUNCER_GAMEPLAY_COMMENT_DANGER, ANNOUNCER_GAMEPLAY_COMMENT_GOOD, - ANNOUNCER_GAMEPLAY_COMMENT_OK, - ANNOUNCER_GAMEPLAY_COMMENT_VERY_BAD, - ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_BOTH, - ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_P1, - ANNOUNCER_GAMEPLAY_COMMENT_VERY_GOOD_P2, + ANNOUNCER_GAMEPLAY_COMMENT_HOT, ANNOUNCER_GAMEPLAY_FAILED, ANNOUNCER_GAMEPLAY_HERE_WE_GO_EXTRA, ANNOUNCER_GAMEPLAY_HERE_WE_GO_FINAL, ANNOUNCER_GAMEPLAY_HERE_WE_GO_NORMAL, ANNOUNCER_GAMEPLAY_READY, - ANNOUNCER_FINAL_RESULT_A, - ANNOUNCER_FINAL_RESULT_AA, - ANNOUNCER_FINAL_RESULT_AAA, - ANNOUNCER_FINAL_RESULT_B, - ANNOUNCER_FINAL_RESULT_C, - ANNOUNCER_FINAL_RESULT_D, - ANNOUNCER_FINAL_RESULT_E, + ANNOUNCER_EVALUATION_FINAL_A, + ANNOUNCER_EVALUATION_FINAL_AA, + ANNOUNCER_EVALUATION_FINAL_AAA, + ANNOUNCER_EVALUATION_FINAL_B, + ANNOUNCER_EVALUATION_FINAL_C, + ANNOUNCER_EVALUATION_FINAL_D, + ANNOUNCER_EVALUATION_FINAL_E, ANNOUNCER_GAME_OVER, ANNOUNCER_MUSIC_SCROLL, - ANNOUNCER_RESULT_A, - ANNOUNCER_RESULT_AA, - ANNOUNCER_RESULT_AAA, - ANNOUNCER_RESULT_B, - ANNOUNCER_RESULT_C, - ANNOUNCER_RESULT_D, - ANNOUNCER_RESULT_E, + ANNOUNCER_EVALUATION_A, + ANNOUNCER_EVALUATION_AA, + ANNOUNCER_EVALUATION_AAA, + ANNOUNCER_EVALUATION_B, + ANNOUNCER_EVALUATION_C, + ANNOUNCER_EVALUATION_D, + ANNOUNCER_EVALUATION_E, ANNOUNCER_SELECT_COURSE_INTRO, ANNOUNCER_SELECT_DIFFICULTY_COMMENT_EASY, ANNOUNCER_SELECT_DIFFICULTY_COMMENT_HARD, diff --git a/stepmania/src/BannerWithFrame.cpp b/stepmania/src/BannerWithFrame.cpp index c6727ae1c4..6d4d8577f9 100644 --- a/stepmania/src/BannerWithFrame.cpp +++ b/stepmania/src/BannerWithFrame.cpp @@ -20,7 +20,7 @@ BannerWithFrame::BannerWithFrame() { - m_sprBannerFrame.Load( THEME->GetPathTo(GRAPHIC_RESULTS_BANNER_FRAME) ); + m_sprBannerFrame.Load( THEME->GetPathTo(GRAPHIC_EVALUATION_BANNER_FRAME) ); m_Banner.SetCroppedSize( m_sprBannerFrame.GetUnzoomedWidth()-6, m_sprBannerFrame.GetUnzoomedHeight()-6 ); this->AddActor( &m_Banner ); diff --git a/stepmania/src/Combo.cpp b/stepmania/src/Combo.cpp index 920b972362..963696631e 100644 --- a/stepmania/src/Combo.cpp +++ b/stepmania/src/Combo.cpp @@ -38,9 +38,9 @@ Combo::Combo() } -void Combo::ContinueCombo( const int iNumNotesHit ) +void Combo::ContinueCombo() { - m_iCurCombo += iNumNotesHit; + m_iCurCombo++; // new max combo if( m_iCurCombo > m_iMaxCombo ) diff --git a/stepmania/src/Combo.h b/stepmania/src/Combo.h index df9638a699..db16dc9fcc 100644 --- a/stepmania/src/Combo.h +++ b/stepmania/src/Combo.h @@ -24,7 +24,7 @@ class Combo : public ActorFrame public: Combo(); - void ContinueCombo( const int iNumNotesHit ); + void ContinueCombo(); void EndCombo(); int GetCurrentCombo(); diff --git a/stepmania/src/DifficultyIcon.h b/stepmania/src/DifficultyIcon.h index 833b8416b4..8ebc52c95f 100644 --- a/stepmania/src/DifficultyIcon.h +++ b/stepmania/src/DifficultyIcon.h @@ -22,7 +22,7 @@ class DifficultyIcon : public Sprite public: DifficultyIcon() { - Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_DIFFICULTY_BANNER_ICONS) ); + Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_DIFFICULTY_ICONS) ); StopAnimating(); SetFromNotes( NULL ); diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index 2f9c7919fb..4d6a6eed6f 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -121,8 +121,8 @@ enum RadarCatrgory // starting from 12-o'clock rotating clockwise RADAR_STREAM = 0, RADAR_VOLTAGE, RADAR_AIR, - RADAR_CHAOS, RADAR_FREEZE, + RADAR_CHAOS, NUM_RADAR_VALUES // leave this at the end }; @@ -216,14 +216,15 @@ enum PlayMode { PLAY_MODE_ARCADE, PLAY_MODE_ONI, - NUM_PLAY_MODES + NUM_PLAY_MODES, + PLAY_MODE_INVALID }; enum PlayerNumber { PLAYER_1 = 0, PLAYER_2, NUM_PLAYERS, // leave this at the end - PLAYER_NONE + PLAYER_INVALID }; inline D3DXCOLOR PlayerToColor( const PlayerNumber p ) @@ -256,7 +257,7 @@ enum Game GAME_PUMP, // Pump It Up GAME_EZ2, // Ez2dancer NUM_GAMES, // leave this at the end - GAME_NONE, + GAME_INVALID, }; enum Style @@ -392,3 +393,75 @@ struct SongOptions }; + + + +/////////////////////////// +// Scoring stuff +/////////////////////////// + +enum TapNoteScore { + TNS_NONE, + TNS_MISS, + TNS_BOO, + TNS_GOOD, + TNS_GREAT, + TNS_PERFECT, +}; + +inline int TapNoteScoreToDancePoints( TapNoteScore tns ) +{ + // What "Aaron in Japan" says: + /* + switch( tns ) + { + case TNS_PERFECT: return +2; + case TNS_GREAT: return +1; + case TNS_GOOD: return +0; + case TNS_BOO: return -4; + case TNS_MISS: return -8; + case TNS_NONE: return -8; + default: ASSERT(0); + } + */ + // What seems more realistic to me: + switch( tns ) + { + case TNS_PERFECT: return +2; + case TNS_GREAT: return +1; + case TNS_GOOD: return +0; + case TNS_BOO: return 0; + case TNS_MISS: return -2; + case TNS_NONE: return -4; + default: ASSERT(0); return 0; + } +} + +//enum TapNoteTiming { +// TNT_NONE, +// TNT_EARLY, +// TNT_LATE +//}; + + +enum HoldNoteScore +{ + HNS_NONE, // this HoldNote has not been scored yet + HNS_OK, // the HoldNote has passed and was successfully held all the way through + HNS_NG // the HoldNote has passed and they missed it +}; + + +inline int HoldNoteScoreToDancePoints( HoldNoteScore hns ) +{ + switch( hns ) + { + case HNS_OK: return +6; + case HNS_NG: return +0; + default: ASSERT(0); return 0; + } +} + + + + diff --git a/stepmania/src/GameDef.h b/stepmania/src/GameDef.h index b032b7926a..d54e50e201 100644 --- a/stepmania/src/GameDef.h +++ b/stepmania/src/GameDef.h @@ -71,7 +71,7 @@ public: if( m_iMenuButtons[b] == GameI.button ) return MenuInput( p, (MenuButton)b ); } - return MenuInput( PLAYER_NONE, MENU_BUTTON_NONE ); + return MenuInput( PLAYER_INVALID, MENU_BUTTON_INVALID ); }; inline GameInput MenuInputToGameInput( const MenuInput MenuI ) { diff --git a/stepmania/src/GhostArrow.h b/stepmania/src/GhostArrow.h index 3719a512b5..fb29e88e64 100644 --- a/stepmania/src/GhostArrow.h +++ b/stepmania/src/GhostArrow.h @@ -1,23 +1,19 @@ +#pragma once /* ----------------------------------------------------------------------------- - File: GhostArrow.h + Class: GhostArrow - Desc: Class used to represent a color arrow on the screen. + Desc: The trail a note leaves when it is destroyed. - Copyright (c) 2001 Ben Norstrom. All rights reserved. + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Ben Nordstrom + Chris Danford ----------------------------------------------------------------------------- */ -class GhostArrow; - -#ifndef _GhostArrow_H_ -#define _GhostArrow_H_ - - #include "Sprite.h" -#include "Notes.h" - +#include "GameConstantsAndTypes.h" class GhostArrow : public Sprite { @@ -32,4 +28,3 @@ public: float m_fVisibilityCountdown; }; -#endif diff --git a/stepmania/src/GradeDisplay.cpp b/stepmania/src/GradeDisplay.cpp index e2e8b16aef..06995a1098 100644 --- a/stepmania/src/GradeDisplay.cpp +++ b/stepmania/src/GradeDisplay.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" /* ----------------------------------------------------------------------------- - File: Grade.cpp + Class: GradeDisplay - Desc: A graphic displayed in the Grade during Dancing. + Desc: See header. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford ----------------------------------------------------------------------------- */ @@ -25,7 +26,7 @@ const float GRADES_TO_SCROLL = NUM_GRADE_FRAMES*4; GradeDisplay::GradeDisplay() { - Load( THEME->GetPathTo(GRAPHIC_RESULTS_GRADES) ); + Load( THEME->GetPathTo(GRAPHIC_EVALUATION_GRADES) ); StopAnimating(); m_fTimeLeftInScroll = 0; diff --git a/stepmania/src/GradeDisplay.h b/stepmania/src/GradeDisplay.h index 310effcbb8..17c3ff2ca9 100644 --- a/stepmania/src/GradeDisplay.h +++ b/stepmania/src/GradeDisplay.h @@ -1,11 +1,12 @@ #pragma once /* ----------------------------------------------------------------------------- - File: GradeDisplay.h + Class: GradeDisplay - Desc: A graphic displayed in the GradeDisplay during Dancing. + Desc: The grade shows on ScreenEvaluation Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford ----------------------------------------------------------------------------- */ diff --git a/stepmania/src/InputMapper.cpp b/stepmania/src/InputMapper.cpp index 4e0080b35c..95334b4ef1 100644 --- a/stepmania/src/InputMapper.cpp +++ b/stepmania/src/InputMapper.cpp @@ -177,7 +177,7 @@ void InputMapper::UpdateTempDItoGI() bool InputMapper::DeviceToGame( DeviceInput DeviceI, GameInput& GameI ) // return true if there is a mapping from device to pad { GameI = m_tempDItoGI[DeviceI.device][DeviceI.button]; - return GameI.number != PLAYER_NONE; + return GameI.number != PLAYER_INVALID; } bool InputMapper::GameToDevice( GameInput GameI, int iSoltNum, DeviceInput& DeviceI ) // return true if there is a mapping from pad to device @@ -216,7 +216,7 @@ MenuInput InputMapper::DeviceToMenu( DeviceInput DeviceI ) } } - return MenuInput( PLAYER_NONE, MENU_BUTTON_NONE ); + return MenuInput( PLAYER_INVALID, MENU_BUTTON_INVALID ); } DeviceInput InputMapper::MenuToDevice( MenuInput MenuI ) diff --git a/stepmania/src/LifeMeter.h b/stepmania/src/LifeMeter.h index bfefeaec52..4ef84bb6d1 100644 --- a/stepmania/src/LifeMeter.h +++ b/stepmania/src/LifeMeter.h @@ -25,7 +25,8 @@ public: void SetBeat( float fSongBeat ) { m_fSongBeat = fSongBeat; }; virtual void ChangeLife( TapNoteScore score ) = 0; - virtual bool IsAboutToFail() = 0; + virtual bool IsInDanger() = 0; + virtual bool IsHot() = 0; virtual bool HasFailed() = 0; protected: diff --git a/stepmania/src/LifeMeterBar.cpp b/stepmania/src/LifeMeterBar.cpp index f15b731048..e35cb1b0f1 100644 --- a/stepmania/src/LifeMeterBar.cpp +++ b/stepmania/src/LifeMeterBar.cpp @@ -18,36 +18,40 @@ const int NUM_SECTIONS = 3; const float SECTION_WIDTH = 1.0f/NUM_SECTIONS; +const float DANGER_THRESHOLD = -0.3f; +const float FAIL_THRESHOLD = 0; + LifeMeterBar::LifeMeterBar() { m_fLifePercentage = 0.5f; m_fTrailingLifePercentage = 0; m_fLifeVelocity = 0; + m_bHasFailed = false; ResetBarVelocity(); } void LifeMeterBar::ChangeLife( TapNoteScore score ) { - bool bWasDoingGreat = IsDoingGreat(); + bool bWasHot = IsHot(); float fDeltaLife; switch( score ) { - case TNS_PERFECT: fDeltaLife = +0.02f; break; - case TNS_GREAT: fDeltaLife = +0.01f; break; - case TNS_GOOD: fDeltaLife = +0.00f; break; - case TNS_BOO: fDeltaLife = -0.06f; break; - case TNS_MISS: fDeltaLife = -0.12f; break; + case TNS_PERFECT: fDeltaLife = +0.015f; break; + case TNS_GREAT: fDeltaLife = +0.008f; break; + case TNS_GOOD: fDeltaLife = +0.000f; break; + case TNS_BOO: fDeltaLife = -0.050f; break; + case TNS_MISS: fDeltaLife = -0.100f; break; } - if( bWasDoingGreat && !IsDoingGreat() ) - fDeltaLife = -0.12f; // make it take a while to get back to "doing great" + if( bWasHot && !IsHot() ) + fDeltaLife = -0.10f; // make it take a while to get back to "doing great" m_fLifePercentage += fDeltaLife; - m_fLifePercentage = clamp( m_fLifePercentage, 0, 1 ); + m_fLifePercentage = min( m_fLifePercentage, 1 ); - if( m_fLifePercentage == 0 ) + if( m_fLifePercentage < FAIL_THRESHOLD ) m_bHasFailed = true; ResetBarVelocity(); @@ -61,14 +65,14 @@ void LifeMeterBar::ResetBarVelocity() m_fLifeVelocity = fDelta * 5; // change in life percent per second } -bool LifeMeterBar::IsDoingGreat() +bool LifeMeterBar::IsHot() { return m_fLifePercentage >= 1; } -bool LifeMeterBar::IsAboutToFail() +bool LifeMeterBar::IsInDanger() { - return m_fLifePercentage < 0.3f; + return m_fLifePercentage < DANGER_THRESHOLD; } bool LifeMeterBar::HasFailed() @@ -86,7 +90,7 @@ void LifeMeterBar::Update( float fDeltaTime ) float fNewDelta = m_fLifePercentage - m_fTrailingLifePercentage; if( fDelta * fNewDelta < 0 ) // the deltas have different signs - m_fLifeVelocity /= 4; + m_fLifeVelocity /= 4; // make some drag m_fTrailingLifePercentage = clamp( m_fTrailingLifePercentage, 0, 1 ); } @@ -116,7 +120,7 @@ void LifeMeterBar::DrawPrimitives() int iNumV = 0; - float fPercentIntoSection = (TIMER->GetTimeSinceStart()/0.3f)*SECTION_WIDTH; + float fPercentIntoSection = (TIMER->GetTimeSinceStart()/0.3f* (IsHot() ? 2 : 1) )*SECTION_WIDTH; fPercentIntoSection -= (int)fPercentIntoSection; fPercentIntoSection = 1-fPercentIntoSection; fPercentIntoSection -= (int)fPercentIntoSection; diff --git a/stepmania/src/LifeMeterBar.h b/stepmania/src/LifeMeterBar.h index ebabd82dda..87b9f051d4 100644 --- a/stepmania/src/LifeMeterBar.h +++ b/stepmania/src/LifeMeterBar.h @@ -24,8 +24,8 @@ public: virtual void DrawPrimitives(); virtual void ChangeLife( TapNoteScore score ); - virtual bool IsDoingGreat(); - virtual bool IsAboutToFail(); + virtual bool IsInDanger(); + virtual bool IsHot(); virtual bool HasFailed(); private: diff --git a/stepmania/src/MenuElements.cpp b/stepmania/src/MenuElements.cpp index d2d6d8e640..63da1bb5e4 100644 --- a/stepmania/src/MenuElements.cpp +++ b/stepmania/src/MenuElements.cpp @@ -108,9 +108,9 @@ void MenuElements::Load( CString sBackgroundPath, CString sTopEdgePath, CString if( GAMEMAN->m_CurStyle == STYLE_NONE ) m_textCreditInfo[p].SetText( "PRESS START" ); else if( GAMEMAN->IsPlayerEnabled( (PlayerNumber)p ) ) - m_textCreditInfo[p].SetText( "PRESENT" ); + m_textCreditInfo[p].SetText( "" ); else // not enabled - m_textCreditInfo[p].SetText( "CREDIT(S): 0 / 0" ); + m_textCreditInfo[p].SetText( "NOT PRESENT" ); m_textCreditInfo[p].SetZoom( 0.5f ); diff --git a/stepmania/src/MenuInput.h b/stepmania/src/MenuInput.h index 7ed78672ae..bcab3a861e 100644 --- a/stepmania/src/MenuInput.h +++ b/stepmania/src/MenuInput.h @@ -22,7 +22,7 @@ enum MenuButton MENU_BUTTON_START, MENU_BUTTON_BACK, NUM_MENU_BUTTONS, // leave this at the end - MENU_BUTTON_NONE + MENU_BUTTON_INVALID }; @@ -37,9 +37,9 @@ struct MenuInput bool operator==( const MenuInput &other ) { return player == other.player && button == other.button; }; - inline bool IsBlank() const { return player == PLAYER_NONE; }; + inline bool IsBlank() const { return player == PLAYER_INVALID; }; inline bool IsValid() const { return !IsBlank(); }; - inline void MakeBlank() { player = PLAYER_NONE; button = MENU_BUTTON_NONE; }; + inline void MakeBlank() { player = PLAYER_INVALID; button = MENU_BUTTON_INVALID; }; }; diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 2ff353daa8..4321149e94 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -23,7 +23,11 @@ const float FADE_TIME = 1.0f; -const float SWITCH_MUSIC_TIME = 0.3f; +const float SWITCH_MUSIC_TIME = 0.15f; +const float ROULETTE_SWITCH_MUSIC_TIME = SWITCH_MUSIC_TIME/2; +const int ROULETTE_SWITCHES_IN_SLOWING_DOWN = 5; + +const float LOCKED_WHEEL_INITIAL_VELOCITY = 7; const float SORT_ICON_ON_SCREEN_X = -140; const float SORT_ICON_ON_SCREEN_Y = -180; @@ -51,6 +55,8 @@ D3DXCOLOR SECTION_COLORS[] = { }; const int NUM_SECTION_COLORS = sizeof(SECTION_COLORS)/sizeof(D3DXCOLOR); + + inline D3DXCOLOR GetNextSectionColor() { static int i=0; @@ -58,8 +64,6 @@ inline D3DXCOLOR GetNextSectionColor() return SECTION_COLORS[i++]; } - - WheelItemData::WheelItemData() { m_pSong = NULL; @@ -325,12 +329,15 @@ MusicWheel::MusicWheel() this->AddActor( &m_ScrollBar ); - m_soundChangeMusic.Load( THEME->GetPathTo(SOUND_SELECT_MUSIC_CHANGE_MUSIC), 10 ); + m_soundChangeMusic.Load( THEME->GetPathTo(SOUND_SELECT_MUSIC_CHANGE_MUSIC), 16 ); m_soundChangeSort.Load( THEME->GetPathTo(SOUND_SELECT_MUSIC_CHANGE_SORT) ); m_soundExpand.Load( THEME->GetPathTo(SOUND_SELECT_MUSIC_SECTION_EXPAND) ); - m_soundExpand.Load( THEME->GetPathTo(SOUND_MENU_START) ); + m_soundStart.Load( THEME->GetPathTo(SOUND_MENU_START) ); + m_soundLocked.Load( THEME->GetPathTo(SOUND_SELECT_MUSIC_WHEEL_LOCKED) ); + m_fTimeLeftBeforePlayMusicSample = 0; + // init m_mapGroupNameToBannerColor CArray arraySongs; @@ -349,10 +356,11 @@ MusicWheel::MusicWheel() m_iSelection = 0; - m_WheelState = STATE_IDLE; - m_fTimeLeftInState = FADE_TIME; + m_WheelState = STATE_SELECTING_MUSIC; + m_fTimeLeftInState = 0; m_fPositionOffsetFromSelection = 0; + m_iSwitchesLeftInSpinDown = 0; // build all of the wheel item datas for( int so=0; soGetTimeSinceStart()-fDeltaTime, SWITCH_MUSIC_TIME ); - float fNewMod = fmodf( TIMER->GetTimeSinceStart(), SWITCH_MUSIC_TIME ); - if( fNewMod < fOldMod ) // wrapped - NextMusic(); + NextMusic(); // spin as fast as possible + } + + if( m_fTimeLeftBeforePlayMusicSample > 0 ) + { + m_fTimeLeftBeforePlayMusicSample -= fDeltaTime; + if( m_fTimeLeftBeforePlayMusicSample < 0 ) + SCREENMAN->SendMessageToTopScreen( SM_PlaySongSample, 0 ); } // update wheel state @@ -721,10 +735,6 @@ void MusicWheel::Update( float fDeltaTime ) { switch( m_WheelState ) { - case STATE_SWITCHING_MUSIC: - m_WheelState = STATE_IDLE; // now, wait for input - SCREENMAN->SendMessageToTopScreen( SM_PlaySongSample, 0 ); - break; case STATE_FLYING_OFF_BEFORE_NEXT_SORT: { m_WheelState = STATE_FLYING_ON_AFTER_NEXT_SORT; @@ -779,46 +789,112 @@ void MusicWheel::Update( float fDeltaTime ) break; case STATE_FLYING_ON_AFTER_NEXT_SORT: SCREENMAN->SendMessageToTopScreen( SM_PlaySongSample, 0 ); - m_WheelState = STATE_IDLE; // now, wait for input + m_WheelState = STATE_SELECTING_MUSIC; // now, wait for input break; case STATE_TWEENING_ON_SCREEN: SCREENMAN->SendMessageToTopScreen( SM_PlaySongSample, 0 ); - m_WheelState = STATE_IDLE; + m_WheelState = STATE_SELECTING_MUSIC; m_fTimeLeftInState = 0; break; case STATE_TWEENING_OFF_SCREEN: m_WheelState = STATE_WAITING_OFF_SCREEN; m_fTimeLeftInState = 0; break; - case STATE_IDLE: + case STATE_SELECTING_MUSIC: m_fTimeLeftInState = 0; break; + case STATE_ROULETTE_SPINNING: + break; + case STATE_WAITING_OFF_SCREEN: + break; + case STATE_LOCKED: + break; case STATE_ROULETTE_SLOWING_DOWN: - m_WheelState = STATE_IDLE; - m_fTimeLeftInState = 0; + if( m_iSwitchesLeftInSpinDown == 0 ) + { + m_WheelState = STATE_LOCKED; + m_fTimeLeftInState = 0; + m_soundStart.Play(); + m_fLockedWheelVelocity = 0; + } + else + { + m_iSwitchesLeftInSpinDown--; + switch( m_iSwitchesLeftInSpinDown ) + { + case 4: m_fTimeLeftInState = 0.2f; break; + case 3: m_fTimeLeftInState = 0.4f; break; + case 2: m_fTimeLeftInState = 0.8f; break; + case 1: m_fTimeLeftInState = 1.3f; break; + case 0: m_fTimeLeftInState = 0.5f; break; + default: ASSERT(0); + } + + LOG->WriteLine( "m_iSwitchesLeftInSpinDown id %d, m_fTimeLeftInState is %f", m_iSwitchesLeftInSpinDown, m_fTimeLeftInState ); + + if( m_iSwitchesLeftInSpinDown < 2 ) + randomf(0,1) >= 0.5f ? NextMusic() : PrevMusic(); + else + NextMusic(); + } + break; + default: + ASSERT(0); // all state changes should be handled explitily break; } } - // "rotate" wheel toward selected song - if( fabsf(m_fPositionOffsetFromSelection) < 0.02f ) - m_fPositionOffsetFromSelection = 0; + if( m_WheelState == STATE_LOCKED ) + { + m_fPositionOffsetFromSelection = clamp( m_fPositionOffsetFromSelection, -0.3f, +0.3f ); + + float fSpringForce = - m_fPositionOffsetFromSelection*LOCKED_WHEEL_INITIAL_VELOCITY; + m_fLockedWheelVelocity += fSpringForce; + + float fDrag = -m_fLockedWheelVelocity * fDeltaTime*4; + m_fLockedWheelVelocity += fDrag; + + m_fPositionOffsetFromSelection += m_fLockedWheelVelocity*fDeltaTime; + + if( fabsf(m_fPositionOffsetFromSelection) < 0.01f && fabsf(m_fLockedWheelVelocity) < 0.01f ) + { + m_fPositionOffsetFromSelection = 0; + m_fLockedWheelVelocity = 0; + } + } else { - m_fPositionOffsetFromSelection -= fDeltaTime * m_fPositionOffsetFromSelection*4; // linear - float fSign = m_fPositionOffsetFromSelection / fabsf(m_fPositionOffsetFromSelection); - m_fPositionOffsetFromSelection -= fDeltaTime * fSign; // constant + // "rotate" wheel toward selected song + float fSpinSpeed; + if( m_WheelState == STATE_ROULETTE_SPINNING ) + fSpinSpeed = 1.0f/ROULETTE_SWITCH_MUSIC_TIME; + else + fSpinSpeed = 0.6f + fabsf(m_fPositionOffsetFromSelection)/SWITCH_MUSIC_TIME; + + if( m_fPositionOffsetFromSelection > 0 ) + m_fPositionOffsetFromSelection = max( 0, m_fPositionOffsetFromSelection - fSpinSpeed*fDeltaTime ); + else if( m_fPositionOffsetFromSelection < 0 ) + m_fPositionOffsetFromSelection = min( 0, m_fPositionOffsetFromSelection + fSpinSpeed*fDeltaTime ); } } void MusicWheel::PrevMusic() { + if( m_WheelState == STATE_LOCKED ) + { + m_fLockedWheelVelocity = LOCKED_WHEEL_INITIAL_VELOCITY; + m_soundLocked.Play(); + return; + } + + if( fabsf(m_fPositionOffsetFromSelection) > 0.5f ) // wheel is busy spinning + return; + switch( m_WheelState ) { - case STATE_IDLE: - case STATE_SWITCHING_MUSIC: + case STATE_SELECTING_MUSIC: case STATE_ROULETTE_SPINNING: case STATE_ROULETTE_SLOWING_DOWN: break; // fall through @@ -843,21 +919,29 @@ void MusicWheel::PrevMusic() m_fPositionOffsetFromSelection -= 1; - m_WheelState = STATE_SWITCHING_MUSIC; - m_fTimeLeftInState = SWITCH_MUSIC_TIME; m_soundChangeMusic.Play(); } void MusicWheel::NextMusic() { + if( m_WheelState == STATE_LOCKED ) + { + m_fLockedWheelVelocity = -LOCKED_WHEEL_INITIAL_VELOCITY; + m_soundLocked.Play(); + return; + } + + if( fabsf(m_fPositionOffsetFromSelection) > 0.5 ) // wheel is very busy spinning + return; + switch( m_WheelState ) { - case STATE_IDLE: - case STATE_SWITCHING_MUSIC: + case STATE_SELECTING_MUSIC: case STATE_ROULETTE_SPINNING: case STATE_ROULETTE_SLOWING_DOWN: break; // fall through default: + LOG->WriteLine( "NextMusic() ignored" ); return; // don't continue } @@ -878,8 +962,6 @@ void MusicWheel::NextMusic() m_fPositionOffsetFromSelection += 1; - m_WheelState = STATE_SWITCHING_MUSIC; - m_fTimeLeftInState = SWITCH_MUSIC_TIME; m_soundChangeMusic.Play(); } @@ -892,8 +974,7 @@ void MusicWheel::NextSort() { switch( m_WheelState ) { - case STATE_IDLE: - case STATE_SWITCHING_MUSIC: + case STATE_SELECTING_MUSIC: case STATE_FLYING_ON_AFTER_NEXT_SORT: break; // fall through default: @@ -914,10 +995,13 @@ void MusicWheel::NextSort() bool MusicWheel::Select() // return true of a playable item was chosen { + LOG->WriteLine( "MusicWheel::Select()" ); + if( m_WheelState == STATE_ROULETTE_SPINNING ) { m_WheelState = STATE_ROULETTE_SLOWING_DOWN; - m_fTimeLeftInState = 20; + m_iSwitchesLeftInSpinDown = ROULETTE_SWITCHES_IN_SLOWING_DOWN; + m_fTimeLeftInState = 0.1f; return false; } @@ -1057,4 +1141,4 @@ void MusicWheel::TweenOffScreen() -} \ No newline at end of file +} diff --git a/stepmania/src/MusicWheel.h b/stepmania/src/MusicWheel.h index 41074af1ce..34bde465a0 100644 --- a/stepmania/src/MusicWheel.h +++ b/stepmania/src/MusicWheel.h @@ -131,6 +131,7 @@ protected: MusicSortDisplay m_MusicSortDisplay; ActorFrame m_frameOverlay; + // Actors inside of m_frameOverlay Sprite m_sprSelectionOverlay; Sprite m_sprHighScoreFrame[NUM_PLAYERS]; @@ -145,10 +146,12 @@ protected: int m_iSelection; // index into GetCurWheelItemDatas() CString m_sExpandedSectionName; + int m_iSwitchesLeftInSpinDown; + float m_fLockedWheelVelocity; + float m_fTimeLeftBeforePlayMusicSample; // Triggers a message send when crosses 0 enum WheelState { - STATE_IDLE, - STATE_SWITCHING_MUSIC, + STATE_SELECTING_MUSIC, STATE_FLYING_OFF_BEFORE_NEXT_SORT, STATE_FLYING_ON_AFTER_NEXT_SORT, STATE_TWEENING_ON_SCREEN, @@ -168,6 +171,7 @@ protected: RageSoundSample m_soundChangeSort; RageSoundSample m_soundExpand; RageSoundSample m_soundStart; + RageSoundSample m_soundLocked; @@ -205,4 +209,3 @@ protected: }; }; - diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index 40141831f8..302a5bef43 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -21,6 +21,11 @@ NoteData::NoteData() +{ + Init(); +} + +void NoteData::Init() { memset( m_TapNotes, '0', MAX_NOTE_TRACKS*MAX_TAP_NOTE_ROWS ); m_iNumTracks = 0; @@ -176,6 +181,24 @@ void NoteData::RemoveHoldNote( int index ) m_iNumHoldNotes--; } +bool NoteData::IsThereANoteAtRow( int iRow ) +{ + for( int t=0; t= fHoldStartBeat && fStartBeat < fEndBeat ) - iNumSteps++; - + HoldNote &hn = m_HoldNotes[i]; + if( iStartIndex <= hn.m_iStartIndex && hn.m_iEndIndex <= iEndIndex ) + iNumHolds++; } - return iNumSteps; + return iNumHolds; } int NoteData::GetPossibleDancePoints() @@ -708,8 +730,9 @@ float NoteData::GetStreamRadarValue( float fSongSeconds ) { // density of steps int iNumNotes = GetNumTapNotes() + GetNumHoldNotes(); - float fBeatsPerSecond = iNumNotes/fSongSeconds; - return fBeatsPerSecond / 5; + float fNotesPerSecond = iNumNotes/fSongSeconds; + float fReturn = fNotesPerSecond / 5; + return min( fReturn, 1.2f ); } float NoteData::GetVoltageRadarValue( float fSongSeconds ) @@ -729,26 +752,30 @@ float NoteData::GetVoltageRadarValue( float fSongSeconds ) fMaxDensityPerSecSoFar = fDensityPerSecThisMeasure; } - return fMaxDensityPerSecSoFar; + float fReturn = fMaxDensityPerSecSoFar*10; + return min( fReturn, 1.2f ); } float NoteData::GetAirRadarValue( float fSongSeconds ) { // number of doubles int iNumDoubles = GetNumDoubles(); - return iNumDoubles / fSongSeconds * 2; + float fReturn = iNumDoubles / fSongSeconds * 2; + return min( fReturn, 1.2f ); } float NoteData::GetChaosRadarValue( float fSongSeconds ) { // irregularity of steps - return fabsf( GetStreamRadarValue(fSongSeconds) - GetVoltageRadarValue(fSongSeconds) ); + float fReturn = fabsf( GetStreamRadarValue(fSongSeconds) - GetVoltageRadarValue(fSongSeconds) ) * 2.5f; + return min( fReturn, 1.2f ); } float NoteData::GetFreezeRadarValue( float fSongSeconds ) { // number of hold steps - return GetNumHoldNotes() / fSongSeconds * 10; + float fReturn = GetNumHoldNotes() / fSongSeconds * 3; + return min( fReturn, 1.2f ); } @@ -789,3 +816,4 @@ void NoteData::LoadTransformed( NoteData* pOriginal, int iNewNumTracks, int iNew } } + diff --git a/stepmania/src/NoteData.h b/stepmania/src/NoteData.h index 498a428e78..de5a809ef9 100644 --- a/stepmania/src/NoteData.h +++ b/stepmania/src/NoteData.h @@ -21,33 +21,7 @@ // ... for future expansion -enum TapNoteScore { - TNS_NONE, - TNS_MISS, - TNS_BOO, - TNS_GOOD, - TNS_GREAT, - TNS_PERFECT, -}; -inline int TapNoteScoreToDancePoints( TapNoteScore tns ) -{ - switch( tns ) - { - case TNS_PERFECT: return +2; - case TNS_GREAT: return +1; - case TNS_GOOD: return +0; - case TNS_BOO: return -4; - case TNS_MISS: return +8; - default: return 0; - } -} - -//enum TapNoteTiming { -// TNT_NONE, -// TNT_EARLY, -// TNT_LATE -//}; struct HoldNote @@ -57,28 +31,10 @@ struct HoldNote int m_iEndIndex; }; -enum HoldNoteScore -{ - HNS_NONE, // this HoldNote has not been scored yet - HNS_OK, // the HoldNote has passed and was successfully held all the way through - HNS_NG // the HoldNote has passed and they missed it -}; - - -inline int HoldNoteScoreToDancePoints( HoldNoteScore hns ) -{ - switch( hns ) - { - case HNS_OK: return +6; - case HNS_NG: return +0; - default: ASSERT(0); return 0; - } -} - inline int BeatToNoteRow( float fBeatNum ) { return int( fBeatNum * ELEMENTS_PER_BEAT + 0.5f); }; // round -inline int BeatToNoteIndexNotRounded( float fBeatNum ){ return (int)( fBeatNum * ELEMENTS_PER_BEAT ); }; -inline float NoteRowToBeat( float fNoteIndex ) { return fNoteIndex / (float)ELEMENTS_PER_BEAT; }; +inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ELEMENTS_PER_BEAT ); }; +inline float NoteRowToBeat( float fNoteIndex ) { return fNoteIndex / (float)ELEMENTS_PER_BEAT; }; inline float NoteRowToBeat( int iNoteIndex ) { return NoteRowToBeat( (float)iNoteIndex ); }; @@ -88,6 +44,7 @@ class NoteData { public: NoteData(); + void Init(); ~NoteData(); // used for loading @@ -109,7 +66,7 @@ public: void ClearRange( int iNoteIndexBegin, int iNoteIndexEnd ); void ClearAll() { ClearRange( 0, MAX_TAP_NOTE_ROWS ); }; void CopyRange( NoteData* pFrom, int iNoteIndexBegin, int iNoteIndexEnd ); - void CopyAll( NoteData* pFrom ) { m_iNumTracks = pFrom->m_iNumTracks; CopyRange( pFrom, 0, MAX_TAP_NOTE_ROWS ); }; + void CopyAll( NoteData* pFrom ) { m_iNumTracks = pFrom->m_iNumTracks; m_iNumHoldNotes = 0; CopyRange( pFrom, 0, MAX_TAP_NOTE_ROWS ); }; inline bool IsRowEmpty( int index ) { @@ -124,6 +81,7 @@ public: void RemoveHoldNote( int index ); // statistics + bool IsThereANoteAtRow( int iRow ); float GetLastBeat(); // return the beat number of the last note int GetLastRow(); int GetNumTapNotes( const float fStartBeat = 0, const float fEndBeat = MAX_BEATS ); @@ -140,16 +98,16 @@ public: case RADAR_STREAM: return GetStreamRadarValue( fSongSeconds ); break; case RADAR_VOLTAGE: return GetVoltageRadarValue( fSongSeconds ); break; case RADAR_AIR: return GetAirRadarValue( fSongSeconds ); break; - case RADAR_CHAOS: return GetChaosRadarValue( fSongSeconds ); break; case RADAR_FREEZE: return GetFreezeRadarValue( fSongSeconds ); break; + case RADAR_CHAOS: return GetChaosRadarValue( fSongSeconds ); break; default: ASSERT(0); return 0; } }; float GetStreamRadarValue( float fSongSeconds ); float GetVoltageRadarValue( float fSongSeconds ); float GetAirRadarValue( float fSongSeconds ); - float GetChaosRadarValue( float fSongSeconds ); float GetFreezeRadarValue( float fSongSeconds ); + float GetChaosRadarValue( float fSongSeconds ); // Transformations void LoadTransformed( NoteData* pOriginal, int iNewNumTracks, int iNewToOriginalTrack[] ); @@ -167,3 +125,4 @@ public: void ConvertHoldNotesTo2sAnd3s(); }; + diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index 5d20f78d22..34bd8f995f 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -237,8 +237,7 @@ void NoteField::DrawPrimitives() const int iCol = hn.m_iTrack; const float fHoldNoteLife = m_HoldNoteLife[i]; - const bool bActive = NoteRowToBeat(hn.m_iStartIndex) > m_fSongBeat && m_fSongBeat < NoteRowToBeat(hn.m_iEndIndex); - + const bool bActive = NoteRowToBeat(hn.m_iStartIndex-1) <= m_fSongBeat && m_fSongBeat <= NoteRowToBeat(hn.m_iEndIndex); // hack: added -1 because hn.m_iStartIndex changes as note is held // parts of the hold const float fStartDrawingAtBeat = froundf( (float)hn.m_iStartIndex, ROWS_BETWEEN_HOLD_BITS ); @@ -306,4 +305,4 @@ void NoteField::RemoveTapNoteRow( int iIndex ) void NoteField::SetHoldNoteLife( int iIndex, float fLife ) { m_HoldNoteLife[iIndex] = fLife; -} \ No newline at end of file +} diff --git a/stepmania/src/Notes.cpp b/stepmania/src/Notes.cpp index 1caa789c3a..9572f1d726 100644 --- a/stepmania/src/Notes.cpp +++ b/stepmania/src/Notes.cpp @@ -456,7 +456,7 @@ void DWIcharToNote( char c, InstrumentNumber i, DanceNote ¬e1Out, DanceNote & bool Notes::LoadFromDWITokens( const CString &sMode, const CString &sDescription, - const CString &sNumFeet, + const int &iNumFeet, const CString &sStepData1, const CString &sStepData2 ) { LOG->WriteLine( "Notes::LoadFromDWITokens()" ); @@ -501,7 +501,7 @@ bool Notes::LoadFromDWITokens( m_sDescription = sDescription; - m_iMeter = atoi( sNumFeet ); + m_iMeter = iNumFeet; if( m_sDescription == "BASIC" ) m_DifficultyClass = CLASS_EASY; else if( m_sDescription == "ANOTHER" ) m_DifficultyClass = CLASS_MEDIUM; @@ -644,6 +644,17 @@ bool Notes::LoadFromNotesFile( const CString &sPath ) sFileText += buffer + "\n"; file.Close(); + // strip comments out of sFileText + while( sFileText.Find("//") != -1 ) + { + int iIndexCommentStart = sFileText.Find("//"); + int iIndexCommentEnd = sFileText.Find("\n", iIndexCommentStart); + if( iIndexCommentEnd == -1 ) // comment doesn't have an end? + sFileText.Delete( iIndexCommentStart, 2 ); + else + sFileText.Delete( iIndexCommentStart, iIndexCommentEnd-iIndexCommentStart ); + } + // split sFileText into strings containing each value expression CStringArray arrayValueStrings; split( sFileText, ";", arrayValueStrings ); @@ -682,12 +693,9 @@ bool Notes::LoadFromNotesFile( const CString &sPath ) { arrayValueTokens.RemoveAt( 0 ); - ASSERT( m_pNoteData == NULL ); // if not, then we're loading this Notes twice + ASSERT( m_pNoteData == NULL ); // if not, then we're loading this NoteData twice m_pNoteData = new NoteData; - CString sFirstMeasure = arrayValueTokens[0]; - int result = sFirstMeasure.Find( '\n' ); - m_pNoteData->SetFromMeasureStrings( arrayValueTokens ); } @@ -695,6 +703,23 @@ bool Notes::LoadFromNotesFile( const CString &sPath ) LOG->WriteLine( "Unexpected value named '%s'", sValueName ); } + + if ( stricmp(m_sDescription, "BASIC") == 0 ) m_DifficultyClass = CLASS_EASY; + else if( stricmp(m_sDescription, "TRICK") == 0 ) m_DifficultyClass = CLASS_MEDIUM; + else if( stricmp(m_sDescription, "STANDARD") == 0 ) m_DifficultyClass = CLASS_MEDIUM; + else if( stricmp(m_sDescription, "ANOTHER") == 0 ) m_DifficultyClass = CLASS_MEDIUM; + else if( stricmp(m_sDescription, "SSR") == 0 ) m_DifficultyClass = CLASS_HARD; + else if( stricmp(m_sDescription, "MANIAC") == 0 ) m_DifficultyClass = CLASS_HARD; + else if( stricmp(m_sDescription, "HEAVY") == 0 ) m_DifficultyClass = CLASS_HARD; + else if( stricmp(m_sDescription, "SMANIAC") == 0 ) m_DifficultyClass = CLASS_HARD; + else + { + // guess difficulty class from m_iMeter + if( m_iMeter <= 3 ) m_DifficultyClass = CLASS_EASY; + else if( m_iMeter <= 6 ) m_DifficultyClass = CLASS_MEDIUM; + else m_DifficultyClass = CLASS_HARD; + } + return true; } @@ -704,8 +729,6 @@ void Notes::SaveToSMDir( CString sSongDir ) { LOG->WriteLine( "Notes::Save( '%s' )", sSongDir ); - int i; - CString sNewNotesFilePath = sSongDir + ssprintf("%s-%s.notes", NotesTypeToString(m_NotesType), m_sDescription); CStdioFile file; @@ -714,18 +737,14 @@ void Notes::SaveToSMDir( CString sSongDir ) file.WriteString( ssprintf("#TYPE:%s;\n", NotesTypeToString(m_NotesType)) ); file.WriteString( ssprintf("#DESCRIPTION:%s;\n", m_sDescription) ); - file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) ); file.WriteString( ssprintf("#METER:%d;\n", m_iMeter) ); + file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) ); - file.WriteString( "#NOTES\n" ); + file.WriteString( "#NOTES:\n" ); CStringArray sMeasureStrings; GetNoteData()->GetMeasureStrings( sMeasureStrings ); - for( i=0; iWriteLine( "Player::Load()", ); this->CopyAll( pNoteData ); @@ -83,7 +83,7 @@ void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteD m_pLifeMeter = pLM; m_pScore = pScore; if( m_pScore ) - m_pScore->Init( player_no, m_PlayerOptions, pNoteData->GetNumTapNotes(), SONGMAN->GetCurrentNotes(player_no)->m_iMeter ); + m_pScore->Init( player_no, m_PlayerOptions, iOriginalNumNotes, SONGMAN->GetCurrentNotes(player_no)->m_iMeter ); if( !po.m_bHoldNotes ) this->RemoveHoldNotes(); @@ -95,12 +95,6 @@ void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteD m_NoteField.Load( (NoteData*)this, player_no, pStyleDef, po, 1.5f, 5.5f, NoteField::MODE_DANCING ); - for( int t=0; tm_iNumTracks; t++ ) - { - for( int r=0; rm_TapNotes[t][r]; - } - m_GrayArrowRow.Load( player_no, pStyleDef, po ); m_GhostArrowRow.Load( player_no, pStyleDef, po ); @@ -108,8 +102,10 @@ void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteD m_Combo.SetY( po.m_bReverseScroll ? -COMBO_Y_OFFSET : COMBO_Y_OFFSET ); m_Judgement.SetY( po.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET ); - for( int c=0; cm_iColsPerPlayer; c++ ) m_HoldJudgement[c].SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - HOLD_JUDGEMENT_Y : HOLD_JUDGEMENT_Y ); + for( c=0; cm_iColsPerPlayer; c++ ) + m_HoldJudgement[c].SetX( (float)pStyleDef->m_ColumnInfo[player_no][c].fXOffset ); m_NoteField.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y ); m_GrayArrowRow.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y ); @@ -142,7 +138,6 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference float fStartBeat = NoteRowToBeat( (float)hn.m_iStartIndex ); float fEndBeat = NoteRowToBeat( (float)hn.m_iEndIndex ); - const int iCol = hn.m_iTrack; const StyleInput StyleI( m_PlayerNumber, hn.m_iTrack ); const GameInput GameI = GAMEMAN->GetCurrentStyleDef()->StyleInputToGameInput( StyleI ); @@ -150,9 +145,9 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference // update the life if( fStartBeat < m_fSongBeat && m_fSongBeat < fEndBeat ) // if the song beat is in the range of this hold { - const bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI ); + const bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI ) || PREFSMAN->m_bAutoPlay; // if they got a bad score or haven't stepped on the corresponding tap yet - const bool bSteppedOnTapNote = m_TapNoteScores[hn.m_iStartIndex] >= TNS_GREAT; + const bool bSteppedOnTapNote = m_TapNoteScores[hn.m_iTrack][hn.m_iStartIndex] >= TNS_GREAT; if( bIsHoldingButton && bSteppedOnTapNote ) @@ -163,7 +158,7 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference m_NoteField.m_HoldNotes[i].m_iStartIndex = BeatToNoteRow( m_fSongBeat ); // move the start of this Hold - m_GhostArrowRow.HoldNote( iCol ); // update the "electric ghost" effect + m_GhostArrowRow.HoldNote( hn.m_iTrack ); // update the "electric ghost" effect } else // !bIsHoldingButton { @@ -181,7 +176,8 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference if( fLife == 0 ) // the player has not pressed the button for a long time! { hns = HNS_NG; - m_HoldJudgement[iCol].SetHoldJudgement( HNS_NG ); + m_Combo.EndCombo(); + m_HoldJudgement[hn.m_iTrack].SetHoldJudgement( HNS_NG ); } // check for OK @@ -190,7 +186,7 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference // At this point fLife > 0, or else we would have marked it NG above fLife = 1; hns = HNS_OK; - m_HoldJudgement[iCol].SetHoldJudgement( HNS_OK ); + m_HoldJudgement[hn.m_iTrack].SetHoldJudgement( HNS_OK ); m_NoteField.SetHoldNoteLife( i, fLife ); // update the NoteField display } } @@ -260,26 +256,6 @@ void Player::DrawPrimitives() m_HoldJudgement[c].Draw(); } -bool Player::IsThereANoteAtIndex( int iIndex ) -{ - for( int t=0; tWriteLine( "Player::HandlePlayerStep()" ); @@ -288,13 +264,6 @@ void Player::HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff ) m_GrayArrowRow.Step( col ); - CheckForCompleteRow( fSongBeat, col, fMaxBeatDiff ); -} - - -void Player::CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ) -{ - //LOG->WriteLine( "Player::CheckForCompleteRow()" ); // look for the closest matching step int iIndexStartLookingAt = BeatToNoteRow( fSongBeat ); @@ -304,7 +273,7 @@ void Player::CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ) int iIndexOverlappingNote = -1; // leave as -1 if we don't find any - // Start at iIndexStartLookingAt and search outward. The first one that overlaps the player's step is the closest match. + // Start at iIndexStartLookingAt and search outward. The first one note overlaps the player's hit (this is the closest match). for( int delta=0; delta <= iNumElementsToExamine; delta++ ) { int iCurrentIndexEarlier = iIndexStartLookingAt - delta; @@ -318,7 +287,8 @@ void Player::CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ) // check the step to the left of iIndexStartLookingAt //////////////////////////// //LOG->WriteLine( "Checking Notes[%d]", iCurrentIndexEarlier ); - if( m_TapNotes[col][iCurrentIndexEarlier] != '0' ) // these Notes overlap + if( m_TapNotes[col][iCurrentIndexEarlier] != '0' && // there is a note here + m_TapNoteScores[col][iCurrentIndexEarlier] == TNS_NONE ) // this note doesn't have a score { iIndexOverlappingNote = iCurrentIndexEarlier; break; @@ -329,7 +299,8 @@ void Player::CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ) // check the step to the right of iIndexStartLookingAt //////////////////////////// //LOG->WriteLine( "Checking Notes[%d]", iCurrentIndexLater ); - if( m_TapNotes[col][iCurrentIndexLater] != '0' ) // these Notes overlap + if( m_TapNotes[col][iCurrentIndexLater] != '0' && // there is a note here + m_TapNoteScores[col][iCurrentIndexLater] == TNS_NONE ) // this note doesn't have a score { iIndexOverlappingNote = iCurrentIndexLater; break; @@ -338,13 +309,28 @@ void Player::CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ) if( iIndexOverlappingNote != -1 ) { - m_TapNotes[col][iIndexOverlappingNote] = '0'; // mark hit - + // compute the score for this hit + const float fStepBeat = NoteRowToBeat( (float)iIndexOverlappingNote ); + const float fBeatsUntilStep = fStepBeat - fSongBeat; + const float fPercentFromPerfect = fabsf( fBeatsUntilStep / fMaxBeatDiff ); + + TapNoteScore &score = m_TapNoteScores[col][iIndexOverlappingNote]; + + if( fPercentFromPerfect < 0.35f ) score = TNS_PERFECT; + else if( fPercentFromPerfect < 0.6f ) score = TNS_GREAT; + else if( fPercentFromPerfect < 0.8f ) score = TNS_GOOD; + else score = TNS_BOO; + + bool bRowDestroyed = true; for( int t=0; tWriteLine( "fBeatsUntilStep: %f, fPercentFromPerfect: %f", // fBeatsUntilStep, fPercentFromPerfect ); - - // compute what the score should be for the note we stepped on - TapNoteScore &score = m_TapNoteScores[iIndexThatWasSteppedOn]; - - if( fPercentFromPerfect < 0.25f ) score = TNS_PERFECT; - else if( fPercentFromPerfect < 0.50f ) score = TNS_GREAT; - else if( fPercentFromPerfect < 0.75f ) score = TNS_GOOD; - else score = TNS_BOO; + + // find the minimum score of the row + TapNoteScore score = TNS_PERFECT; + for( int t=0; t= TNS_BOO ) + score = min( score, m_TapNoteScores[t][iIndexThatWasSteppedOn] ); // update the judgement, score, and life m_Judgement.SetJudgement( score ); - m_pScore->AddToScore( score, m_Combo.GetCurrentCombo() ); m_pLifeMeter->ChangeLife( score ); @@ -380,31 +357,27 @@ void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int i if ( ( score == TNS_PERFECT ) || ( score == TNS_GREAT ) ) m_NoteField.RemoveTapNoteRow( iIndexThatWasSteppedOn ); - // show ghost arrows for( int c=0; c100 ); // show the ghost arrow for this column - } + + m_pScore->AddToScore( score, m_Combo.GetCurrentCombo() ); // update score - called once per note in this row - int iNumNotesDestroyed = 0; - for( c=0; cGetCurrentSong(); - Notes* pNotes = SONGMAN->GetCurrentNotes(m_PlayerNumber); - GSout.dc = pNotes->m_DifficultyClass; - GSout.meter = pNotes->m_iMeter; - GSout.iPossibleDancePoints = ((NoteData*)this)->GetPossibleDancePoints(); - GSout.iActualDancePoints = 0; - - for( int i=0; iGetScore() : 0; - - GSout.failed = this->m_pLifeMeter->HasFailed(); - - - for( int r=0; rGetRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->GetMusicLengthSeconds() ); - GSout.fRadarActual[r] = randomf(0, GSout.fRadarPossible[r]); - } -} - - int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat ) { //LOG->WriteLine( "Notes::UpdateTapNotesMissedOlderThan(%f)", fMissIfOlderThanThisBeat ); @@ -482,17 +407,19 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat ) int iStartCheckingAt = max( 0, iMissIfOlderThanThisIndex-10 ); //LOG->WriteLine( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex ); - for( int i=iStartCheckingAt; iIsRowEmpty( i ) ) + for( int r=iStartCheckingAt; rChangeLife( TNS_MISS ); + bool bFoundAMissInThisRow = false; + if( m_TapNotes[t][r] != '0' && m_TapNoteScores[t][r] == TNS_NONE ) + { + m_TapNoteScores[t][r] = TNS_MISS; + iNumMissesFound++; + bFoundAMissInThisRow = true; + } + if( bFoundAMissInThisRow ) + m_pLifeMeter->ChangeLife( TNS_MISS ); } } @@ -506,8 +433,77 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat ) } +void Player::CrossedRow( int iNoteRow, float fSongBeat, float fMaxBeatDiff ) +{ + if( PREFSMAN->m_bAutoPlay ) + { + // check to see if there's at the crossed row + for( int t=0; tHandlePlayerStep( fSongBeat, t, fMaxBeatDiff ); + } + } +} +GameplayStatistics Player::GetGameplayStatistics() +{ + GameplayStatistics GSreturn; + + GSreturn.pSong = SONGMAN->GetCurrentSong(); + Notes* pNotes = SONGMAN->GetCurrentNotes(m_PlayerNumber); + GSreturn.dc = pNotes->m_DifficultyClass; + GSreturn.meter = pNotes->m_iMeter; + GSreturn.iPossibleDancePoints = ((NoteData*)this)->GetPossibleDancePoints(); + GSreturn.iActualDancePoints = 0; + + for( int t=0; tGetScore() : 0; + + GSreturn.failed = this->m_pLifeMeter->HasFailed(); + for( int r=0; rGetRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->GetMusicLengthSeconds() ); + GSreturn.fRadarActual[r] = this->GetActualRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->GetMusicLengthSeconds() ); + + GSreturn.fRadarPossible[r] = clamp( GSreturn.fRadarPossible[r], 0, 1 ); + GSreturn.fRadarActual[r] = clamp( GSreturn.fRadarActual[r], 0, 1 ); + } + + return GSreturn; +} diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index 1ffb7f1260..4028ba6cd3 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -31,11 +31,12 @@ #include "NoteField.h" #include "GrayArrowRow.h" #include "GhostArrowRow.h" +#include "NoteDataWithScoring.h" struct GameplayStatistics; -class Player : public NoteData, public ActorFrame +class Player : public NoteDataWithScoring, public ActorFrame { public: Player(); @@ -43,33 +44,27 @@ public: void Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference ); void DrawPrimitives(); - void Load( PlayerNumber player_no, StyleDef *pStyleDef, NoteData* pNoteData, const PlayerOptions& po, LifeMeterBar* pLM, ScoreDisplayRolling* pScore ); - void CrossedIndex( int iIndex ); + void Load( PlayerNumber player_no, StyleDef *pStyleDef, NoteData* pNoteData, const PlayerOptions& po, LifeMeterBar* pLM, ScoreDisplayRolling* pScore, int iOriginalNumNotes ); + void CrossedRow( int iNoteRow, float fSongBeat, float fMaxBeatDiff ); void HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff ); int UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat ); - void GetGameplayStatistics( GameplayStatistics& GSout ); + GameplayStatistics GetGameplayStatistics(); - bool IsThereANoteAtIndex( int iIndex ); protected: - void CheckForCompleteRow( float fSongBeat, int col, float fMaxBeatDiff ); void OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int iStepIndex ); float m_fSongBeat; PlayerNumber m_PlayerNumber; PlayerOptions m_PlayerOptions; - // maintain this extra data in addition to the NoteData - TapNote m_TapNotesOriginal[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ROWS]; // the original Notes that were loaded into player - TapNoteScore m_TapNoteScores[MAX_TAP_NOTE_ROWS]; float m_fHoldNoteLife[MAX_TAP_NOTE_ROWS]; // 1.0 means this HoldNote has full life. // 0.0 means this HoldNote is dead // When this value hits 0.0 for the first time, // m_HoldScore becomes HSS_NG. // If the life is > 0.0 when the HoldNote ends, then // m_HoldScore becomes HSS_OK. - HoldNoteScore m_HoldNoteScores[MAX_HOLD_NOTE_ELEMENTS]; GrayArrowRow m_GrayArrowRow; diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index 3c43162a6c..897957274c 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -25,16 +25,17 @@ PrefsManager::PrefsManager() m_bHighTextureDetail = true; m_bIgnoreJoyAxes = false; m_bShowFPS = false; - m_bUseRandomVis = false; + m_visMode = VIS_MODE_ANIMATION; m_bAnnouncer = true; m_bEventMode = true; m_iNumArcadeStages = 3; - m_iDifficulty = 4; + m_bAutoPlay = false; + m_fJudgeWindow = 0.10f; for( int p=0; pGetStageNumber(), sNumberSuffix ); + return ssprintf( "%d%s", iStageNo, sNumberSuffix ); +} + +D3DXCOLOR PrefsManager::GetStageColor() +{ + if( IsFinalStage() ) + return D3DXCOLOR(1,0.1f,0.1f,1); // red + else if( IsExtraStage() || IsExtraStage2() ) + return D3DXCOLOR(1,1,0.3f,1); // yellow + else + return D3DXCOLOR(0.3f,1,0.3f,1); // green } diff --git a/stepmania/src/PrefsManager.h b/stepmania/src/PrefsManager.h index 45773548e4..f790b08266 100644 --- a/stepmania/src/PrefsManager.h +++ b/stepmania/src/PrefsManager.h @@ -17,6 +17,14 @@ const int NUM_PAD_TO_DEVICE_SLOTS = 3; // three device inputs may map to one pad input + +enum VisualizationMode { + VIS_MODE_NONE = 0, + VIS_MODE_ANIMATION, + VIS_MODE_MOVIE, +}; + + class PrefsManager { public: @@ -29,11 +37,12 @@ public: bool m_bHighTextureDetail; bool m_bIgnoreJoyAxes; bool m_bShowFPS; - bool m_bUseRandomVis; + int m_visMode; bool m_bAnnouncer; bool m_bEventMode; int m_iNumArcadeStages; - int m_iDifficulty; + bool m_bAutoPlay; + float m_fJudgeWindow; void ReadPrefsFromDisk(); void SavePrefsToDisk(); @@ -46,9 +55,11 @@ public: int m_iCurrentStageIndex; // starts at 0, and is incremented with each Stage Clear int GetStageIndex(); - int GetStageNumber(); bool IsFinalStage(); + bool IsExtraStage(); + bool IsExtraStage2(); CString GetStageText(); + D3DXCOLOR GetStageColor(); PlayerOptions m_PlayerOptions[NUM_PLAYERS]; diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index b1f2ffac0e..b3c78e8a95 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -25,13 +25,14 @@ RageSound* SOUND = NULL; RageSound::RageSound( HWND hWnd ) { LOG->WriteLine( "RageSound::RageSound()" ); + // save the HWND if( !hWnd ) throw RageException( "RageSound called with NULL hWnd." ); m_hWndApp = hWnd; - if( BASS_GetVersion() != MAKELONG(1,5) ) - throw RageException( "BASS version 1.5 DLL could not be loaded. Verify that Bass.dll exists in the program directory."); + if( BASS_GetVersion() != MAKELONG(1,6) ) + throw RageException( "BASS version 1.6 DLL could not be loaded. Verify that Bass.dll exists in the program directory."); if( !BASS_Init( -1, 44100, BASS_DEVICE_LEAVEVOL|BASS_DEVICE_LATENCY, m_hWndApp ) ) { @@ -72,6 +73,8 @@ RageSound::RageSound( HWND hWnd ) RageSound::~RageSound() { + LOG->WriteLine( "RageSound::~RageSound()" ); + BASS_Stop(); BASS_Free(); } @@ -85,7 +88,7 @@ void RageSound::PlayOnceStreamed( CString sPath ) if( FALSE == BASS_StreamPlay( hStream, FALSE, 0 ) ) throw RageException( "RageSound: Error playing a sound stream." ); - // this stream will free itself when stopped + // this stream will free itself when stopped } void RageSound::PlayOnceStreamedFromDir( CString sDir ) diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 917b0bfc99..ec931ccbbd 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -74,18 +74,18 @@ CString vssprintf( LPCTSTR fmt, va_list argList) // Name: join() // Desc: //----------------------------------------------------------------------------- -CString join(CString Deliminator, CStringArray& Source) +CString join( const CString &Deliminator, const CStringArray& Source) { CString csReturn; CString csTmp; // Loop through the Array and Append the Deliminator - for( int iNum = 0; iNum < Source.GetSize(); iNum++ ) { + for( int iNum = 0; iNum < Source.GetSize()-1; iNum++ ) { csTmp += Source.GetAt(iNum); csTmp += Deliminator; } - csReturn = csTmp.Left(csTmp.GetLength() - 1); - return csReturn; + csTmp += Source.GetAt( Source.GetSize()-1 ); + return csTmp; } diff --git a/stepmania/src/ScoreDisplayRolling.cpp b/stepmania/src/ScoreDisplayRolling.cpp index f7c34e83c1..7cfced67f0 100644 --- a/stepmania/src/ScoreDisplayRolling.cpp +++ b/stepmania/src/ScoreDisplayRolling.cpp @@ -14,6 +14,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "ThemeManager.h" +#include "RageLog.h" const float SCORE_TWEEN_TIME = 0.5f; @@ -33,11 +34,11 @@ ScoreDisplayRolling::ScoreDisplayRolling() } -void ScoreDisplayRolling::Init( PlayerNumber pn, PlayerOptions po, int iTotalTapNotes, int iNotesMeter ) +void ScoreDisplayRolling::Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter ) { m_PlayerNumber = pn; m_PlayerOptions = po; - m_iTotalTapNotes = iTotalTapNotes; + m_iTotalNotes = iOriginalNumNotes; m_iNotesMeter = iNotesMeter; } @@ -90,7 +91,6 @@ void ScoreDisplayRolling::Draw() } - void ScoreDisplayRolling::AddToScore( TapNoteScore score, int iCurCombo ) { //A single step's points are calculated as follows: @@ -120,6 +120,11 @@ void ScoreDisplayRolling::AddToScore( TapNoteScore score, int iCurCombo ) // //Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible score for any song is the number of feet difficulty X 10,000,000. + static int iNumTimesCalled = 0; + iNumTimesCalled ++; + LOG->WriteLine("Called %d times.",iNumTimesCalled); + + int p; // score multiplier switch( score ) { @@ -128,12 +133,16 @@ void ScoreDisplayRolling::AddToScore( TapNoteScore score, int iCurCombo ) default: p = 0; break; } - int N = m_iTotalTapNotes; - int n = iCurCombo; + int N = m_iTotalNotes; + int n = iCurCombo+1; int B = m_iNotesMeter * 1000000; - int S = (1+N)*N/2; + float S = (1+N)*N/2.0f; + + int one_step_score = roundf( p * (B/S) * n ); + + // HACK: The total score is off by a factor of 0.5. For now, multiply by two... + one_step_score *= 2; - int one_step_score = p * (B/S) * n; m_iScore += one_step_score; ASSERT( m_iScore >= 0 ); diff --git a/stepmania/src/ScoreDisplayRolling.h b/stepmania/src/ScoreDisplayRolling.h index bb83b49ecc..92deb91dea 100644 --- a/stepmania/src/ScoreDisplayRolling.h +++ b/stepmania/src/ScoreDisplayRolling.h @@ -24,7 +24,7 @@ class ScoreDisplayRolling : public BitmapText public: ScoreDisplayRolling(); - void Init( PlayerNumber pn, PlayerOptions po, int iTotalTapNotes, int iNotesMeter ); + void Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter ); void SetScore( int iNewScore ); int GetScore(); @@ -36,7 +36,7 @@ public: protected: PlayerNumber m_PlayerNumber; PlayerOptions m_PlayerOptions; - int m_iTotalTapNotes; + int m_iTotalNotes; int m_iNotesMeter; int m_iScore; diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 6e69a53eeb..4f1e5479be 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -14,7 +14,7 @@ #include "SongManager.h" #include "ScreenManager.h" #include "ScreenSelectMusic.h" -#include "ScreenResults.h" +#include "ScreenEvaluation.h" #include "GameConstantsAndTypes.h" #include "ThemeManager.h" #include "GameManager.h" @@ -97,7 +97,7 @@ ScreenEdit::ScreenEdit() m_NoteFieldRecord.SetZoom( 1.0f ); m_NoteFieldRecord.Load( ¬eData, PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_PlayerOptions, 2, 5, NoteField::MODE_EDITING ); - m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), ¬eData, PlayerOptions(), NULL, NULL ); + m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), ¬eData, PlayerOptions(), NULL, NULL, 1 ); m_Player.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); m_Fade.SetClosed(); @@ -234,7 +234,7 @@ void ScreenEdit::Update( float fDeltaTime ) m_NoteFieldEdit.Update( fDeltaTime, m_fTrailingBeat ); - int iIndexNow = BeatToNoteIndexNotRounded( m_fBeat ); + int iIndexNow = BeatToNoteRowNotRounded( m_fBeat ); CString sNoteType; @@ -499,7 +499,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ m_Mode = MODE_PLAY; - m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL ); + m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL, 1 ); m_rectRecordBack.BeginTweening( 0.5f ); m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp new file mode 100644 index 0000000000..388ef66109 --- /dev/null +++ b/stepmania/src/ScreenEvaluation.cpp @@ -0,0 +1,673 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: ScreenEvaluation + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenEvaluation.h" +#include "ScreenSelectMusic.h" +#include "SongManager.h" +#include "ScreenManager.h" +#include "GameManager.h" +#include "RageUtil.h" +#include "GameConstantsAndTypes.h" +#include "Notes.h" +#include "ThemeManager.h" +#include "RageLog.h" +#include "AnnouncerManager.h" +#include "ScreenMusicScroll.h" + + +const float BANNER_X = CENTER_X; +const float BANNER_Y = SCREEN_TOP + 100; + +const float GRADE_X[NUM_PLAYERS] = { CENTER_X-226, CENTER_X+226 }; +const float GRADE_Y = BANNER_Y; + +const float JUDGE_LABELS_X = CENTER_X; +const float JUDGE_NUMBERS_X[NUM_PLAYERS]= { CENTER_X-88, CENTER_X+88 }; +const float JUDGE_START_Y = CENTER_Y - 70; +const float JUDGE_SPACING = 32; + +const float SCORE_LABEL_X = CENTER_X; +const float SCORE_DISPLAY_X[NUM_PLAYERS]= { CENTER_X-170, CENTER_X+170 }; +const float SCORE_Y = CENTER_Y + 140; + +const float BONUS_FRAME_X[NUM_PLAYERS] = { CENTER_X-220, CENTER_X+220 }; +const float BONUS_FRAME_Y = CENTER_Y+10; + +const float NEW_RECORD_X[NUM_PLAYERS] = { SCORE_DISPLAY_X[0], SCORE_DISPLAY_X[1] }; +const float NEW_RECORD_Y = SCORE_Y - 20; + +const float TRY_EXTRA_STAGE_X = CENTER_X; +const float TRY_EXTRA_STAGE_Y = SCREEN_BOTTOM - 60; + + +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User+1); + + +ScreenEvaluation::ScreenEvaluation( bool bSummary ) +{ + LOG->WriteLine( "ScreenEvaluation::ScreenEvaluation()" ); + + int l, p; // for counting + + + /////////////////////////// + // Set m_ResultMode. This enum will make our life easier later when we init different pieces depending on context. + /////////////////////////// + switch( PREFSMAN->m_PlayMode ) + { + case PLAY_MODE_ARCADE: + m_ResultMode = bSummary ? RM_ARCADE_SUMMARY : RM_ARCADE_STAGE; + break; + case PLAY_MODE_ONI: + m_ResultMode = RM_ONI; + break; + default: + ASSERT(0); + } + +/* + ////////////////////////// + // Fill in some fake information for debugging + ////////////////////////// + m_ResultMode = RM_ARCADE_SUMMARY; + GAMEMAN->m_CurStyle = STYLE_DANCE_SINGLE; + SONGMAN->SetCurrentSong( SONGMAN->m_pSongs[0] ); + for( p=0; pSetCurrentNotes((PlayerNumber)p, SONGMAN->GetCurrentSong()->m_arrayNotes[0]); + { + SONGMAN->m_aGameplayStatistics[p].Add( GameplayStatistics() ); + GameplayStatistics &GS = SONGMAN->m_aGameplayStatistics[p][SONGMAN->m_aGameplayStatistics[p].GetSize()-1]; + GS.pSong = SONGMAN->m_pSongs[0]; + GS.dc = CLASS_EASY; + GS.meter = 5; + GS.iPossibleDancePoints = 300; + GS.iActualDancePoints = 255; + GS.failed = false; + + GS.perfect = GS.great = GS.good = GS.boo = GS.miss = GS.ok = GS.ng = GS.max_combo = 100; + GS.score = 100; + for( int r=0; rm_aGameplayStatistics[p].Add( GameplayStatistics() ); + GameplayStatistics &GS = SONGMAN->m_aGameplayStatistics[p][SONGMAN->m_aGameplayStatistics[p].GetSize()-1]; + GS.pSong = SONGMAN->m_pSongs[0]; + GS.dc = CLASS_EASY; + GS.meter = 5; + GS.iPossibleDancePoints = 300; + GS.iActualDancePoints = 255; + GS.failed = false; + + GS.perfect = GS.great = GS.good = GS.boo = GS.miss = GS.ok = GS.ng = GS.max_combo = 100; + GS.score = 100; + for( int r=0; rm_aGameplayStatistics[p].Add( GameplayStatistics() ); + GameplayStatistics &GS = SONGMAN->m_aGameplayStatistics[p][SONGMAN->m_aGameplayStatistics[p].GetSize()-1]; + GS.pSong = SONGMAN->m_pSongs[0]; + GS.dc = CLASS_EASY; + GS.meter = 5; + GS.iPossibleDancePoints = 300; + GS.iActualDancePoints = 255; + GS.failed = false; + + GS.perfect = GS.great = GS.good = GS.boo = GS.miss = GS.ok = GS.ng = GS.max_combo = 100; + GS.score = 100; + for( int r=0; rIsPlayerEnabled(pn) ) + continue; // skip + + switch( m_ResultMode ) + { + case RM_ARCADE_STAGE: + total_statistics[p] = SONGMAN->GetLatestGameplayStatistics((PlayerNumber)p); + break; + case RM_ARCADE_SUMMARY: + { + int iStageIndex = PREFSMAN->GetStageIndex(); + int s = 0; + for( int i=max(0,iStageIndex-STAGES_TO_SHOW_IN_SUMMARY); i<=iStageIndex; i++, s++ ) + { + total_statistics[p] = SONGMAN->GetLatestGameplayStatistics((PlayerNumber)p); + } + } + break; + case RM_ONI: + { + int iStageIndex = PREFSMAN->GetStageIndex(); + int s = 0; + for( int i=0; i<=iStageIndex; i++ ) + total_statistics[p] = SONGMAN->GetLatestGameplayStatistics((PlayerNumber)p); + } + break; + } + } + + + + /////////////////////////// + // Init the song banners depending on m_ResultMode + /////////////////////////// + switch( m_ResultMode ) + { + case RM_ARCADE_STAGE: + m_BannerWithFrame[0].LoadFromSong( SONGMAN->GetCurrentSong() ); + m_BannerWithFrame[0].SetXY( BANNER_X, BANNER_Y ); + this->AddActor( &m_BannerWithFrame[0] ); + break; + case RM_ARCADE_SUMMARY: + { + if( SONGMAN->m_aGameplayStatistics[0].GetSize() > STAGES_TO_SHOW_IN_SUMMARY ) + { + // crop down to 3 + for( int p=0; pm_aGameplayStatistics[p].RemoveAt( 0, SONGMAN->m_aGameplayStatistics[p].GetSize() - STAGES_TO_SHOW_IN_SUMMARY ); + } + + const int iSongsToShow = SONGMAN->m_aGameplayStatistics[0].GetSize(); + ASSERT( iSongsToShow > 0 ); + + for( int i=0; im_aGameplayStatistics[0][i]; + m_BannerWithFrame[i].LoadFromSong( GS.pSong ); + float fBannerOffset = i - (iSongsToShow-1)/2.0f; + m_BannerWithFrame[i].SetXY( BANNER_X + fBannerOffset*32, BANNER_Y + fBannerOffset*16 ); + m_BannerWithFrame[i].SetZoom( 0.70f ); + this->AddActor( &m_BannerWithFrame[i] ); + } + } + break; + case RM_ONI: + m_BannerWithFrame[0].LoadFromGroup( SONGMAN->m_sPreferredGroup ); + m_BannerWithFrame[0].SetXY( BANNER_X, BANNER_Y ); + this->AddActor( &m_BannerWithFrame[0] ); + break; + } + + + + + ////////////////////////// + // Init graphic elements + ////////////////////////// + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_EVALUATION_BACKGROUND), + m_ResultMode==RM_ARCADE_SUMMARY ? THEME->GetPathTo(GRAPHIC_EVALUATION_SUMMARY_TOP_EDGE) : THEME->GetPathTo(GRAPHIC_EVALUATION_TOP_EDGE), + "Press START to continue." + ); + this->AddActor( &m_Menu ); + + + + for( l=0; lGetPathTo(GRAPHIC_EVALUATION_JUDGE_LABELS) ); + m_sprJudgeLabels[l].StopAnimating(); + m_sprJudgeLabels[l].SetState( l ); + m_sprJudgeLabels[l].SetXY( JUDGE_LABELS_X, JUDGE_START_Y + l*JUDGE_SPACING ); + m_sprJudgeLabels[l].SetZoom( 1.0f ); + this->AddActor( &m_sprJudgeLabels[l] ); + + for( int p=0; pGetPathTo(FONT_SCORE_NUMBERS) ); + m_textJudgeNumbers[l][p].TurnShadowOff(); + m_textJudgeNumbers[l][p].SetXY( JUDGE_NUMBERS_X[p], JUDGE_START_Y + l*JUDGE_SPACING ); + m_textJudgeNumbers[l][p].SetZoom( 0.7f ); + m_textJudgeNumbers[l][p].SetDiffuseColor( PlayerToColor(p) ); + this->AddActor( &m_textJudgeNumbers[l][p] ); + } + } + + m_sprScoreLabel.Load( THEME->GetPathTo(GRAPHIC_EVALUATION_SCORE_LABELS) ); + m_sprScoreLabel.StopAnimating(); + m_sprScoreLabel.SetXY( SCORE_LABEL_X, SCORE_Y ); + m_sprScoreLabel.SetZoom( 1.0f ); + this->AddActor( &m_sprScoreLabel ); + + for( p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + m_ScoreDisplay[p].SetXY( SCORE_DISPLAY_X[p], SCORE_Y ); + m_ScoreDisplay[p].SetZoomY( 0.9f ); + m_ScoreDisplay[p].SetDiffuseColor( PlayerToColor(p) ); + this->AddActor( &m_ScoreDisplay[p] ); + } + + + + + Grade grade[NUM_PLAYERS]; + + ////////////////////////// + // Set Numbers + ////////////////////////// + for( p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + GameplayStatistics GS[NUM_PLAYERS]; // fill this in depending on m_ResultMode + + switch( m_ResultMode ) + { + case RM_ARCADE_STAGE: + { + GS[p] = SONGMAN->m_aGameplayStatistics[p][SONGMAN->m_aGameplayStatistics[p].GetSize()-1]; + } + break; + case RM_ARCADE_SUMMARY: + case RM_ONI: + { + const int iSongsToShow = SONGMAN->m_aGameplayStatistics[0].GetSize(); + ASSERT( iSongsToShow > 0 ); + + for( int i=0; im_aGameplayStatistics[p][i]; + + GS[p].iPossibleDancePoints += GSstage.iPossibleDancePoints; + GS[p].iActualDancePoints += GSstage.iActualDancePoints; + + GS[p].perfect += GSstage.perfect; + GS[p].great += GSstage.great; + GS[p].good += GSstage.good; + GS[p].boo += GSstage.boo; + GS[p].miss += GSstage.miss; + GS[p].ok += GSstage.ok; + GS[p].ng += GSstage.ng; + GS[p].max_combo += GSstage.max_combo; + GS[p].score += GSstage.score; + for( int i=0; iGetCurrentNotes((PlayerNumber)p); + pNotes->m_iNumTimesPlayed++; + + if( GS[p].max_combo > pNotes->m_iMaxCombo ) + pNotes->m_iMaxCombo = GS[p].max_combo; + + if( GS[p].score > pNotes->m_iTopScore ) + { + pNotes->m_iTopScore = (int)GS[p].score; + m_bNewRecord[p] = true; + } + + if( grade[p] > pNotes->m_TopGrade ) + pNotes->m_TopGrade = grade[p]; + break; + } + } + + + + Grade max_grade = GRADE_NO_DATA; + for( p=0; pIsFinalStage() || PREFSMAN->IsExtraStage()) && m_ResultMode==RM_ARCADE_STAGE ) + { + for( p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + if( SONGMAN->GetCurrentNotes((PlayerNumber)p)->m_DifficultyClass == CLASS_HARD && grade[p] >= GRADE_AA ) + m_bTryExtraStage = true; + } + } + + + for( p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + m_sprGradeFrame[p].Load( THEME->GetPathTo(GRAPHIC_EVALUATION_GRADE_FRAME) ); + m_sprGradeFrame[p].StopAnimating(); + m_sprGradeFrame[p].SetState( p ); + m_sprGradeFrame[p].SetXY( GRADE_X[p], GRADE_Y ); + this->AddActor( &m_sprGradeFrame[p] ); + + switch( m_ResultMode ) + { + case RM_ONI: + m_textOniPercent[p].Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textOniPercent[p].SetXY( GRADE_X[p], GRADE_Y ); + m_textOniPercent[p].SetShadowLength( 2 ); + m_textOniPercent[p].SetZoom( 3 ); + m_textOniPercent[p].SetEffectGlowing( 1.0f ); + this->AddActor( &m_textOniPercent[p] ); + break; + case RM_ARCADE_STAGE: + case RM_ARCADE_SUMMARY: + m_Grades[p].SetXY( GRADE_X[p], GRADE_Y ); + m_Grades[p].SetZ( -2 ); + m_Grades[p].SetZoom( 1.0f ); + m_Grades[p].SetEffectGlowing( 1.0f ); + this->AddActor( &m_Grades[p] ); + break; + } + + m_BonusInfoFrame[p].SetXY( BONUS_FRAME_X[p], BONUS_FRAME_Y ); + this->AddActor( &m_BonusInfoFrame[p] ); + + m_bNewRecord[p] = false; + + if( m_bNewRecord[p] ) + { + m_textNewRecord[p].Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textNewRecord[p].SetXY( NEW_RECORD_X[p], NEW_RECORD_Y ); + m_textNewRecord[p].SetShadowLength( 2 ); + m_textNewRecord[p].SetText( "IT'S A NEW RECORD!" ); + m_textNewRecord[p].SetZoom( 0.5f ); + m_textNewRecord[p].SetEffectGlowing( 1.0f ); + this->AddActor( &m_textNewRecord[p] ); + } + } + + + if( m_bTryExtraStage ) + { + m_textTryExtraStage.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textTryExtraStage.SetXY( TRY_EXTRA_STAGE_X, TRY_EXTRA_STAGE_Y ); + if( PREFSMAN->IsExtraStage() ) + m_textTryExtraStage.SetText( "Try Another Extra Stage!" ); + else + m_textTryExtraStage.SetText( "Try Extra Stage!" ); + m_textTryExtraStage.SetZoom( 1 ); + m_textTryExtraStage.SetEffectGlowing( 1.0f ); + this->AddActor( &m_textTryExtraStage ); + + SOUND->PlayOnceStreamed( THEME->GetPathTo(SOUND_EVALUATION_EXTRA_STAGE) ); + } + else + { + + switch( max_grade ) + { + case GRADE_E: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_E) ); break; + case GRADE_D: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_D) ); break; + case GRADE_C: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_C) ); break; + case GRADE_B: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_B) ); break; + case GRADE_A: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_A) ); break; + case GRADE_AA: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_AA) ); break; + case GRADE_AAA: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_EVALUATION_AAA) ); break; + case GRADE_NO_DATA: + default: + ASSERT(0); // invalid grade + } + } + + m_Menu.TweenOnScreenFromBlack( SM_None ); +} + +void ScreenEvaluation::TweenOnScreen() +{ + int i, p; + + m_Menu.TweenOnScreenFromBlack( SM_None ); + + float fOriginalX, fOriginalY; + + for( i=0; iWriteLine( "ScreenEvaluation::Input()" ); + + if( m_Menu.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenEvaluation::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_MenuTimer: + MenuStart( PLAYER_INVALID ); + break; + case SM_GoToNextState: + switch( m_ResultMode ) + { + case RM_ARCADE_SUMMARY: + SCREENMAN->SetNewScreen( new ScreenMusicScroll ); + return; + case RM_ARCADE_STAGE: + if( m_bTryExtraStage ) + SCREENMAN->SetNewScreen( new ScreenSelectMusic ); + else + SCREENMAN->SetNewScreen( new ScreenEvaluation(true) ); + return; + case RM_ONI: + SCREENMAN->SetNewScreen( new ScreenMusicScroll ); + return; + break; + } + } +} + +void ScreenEvaluation::MenuBack( const PlayerNumber p ) +{ + MenuStart( p ); +} + +void ScreenEvaluation::MenuStart( const PlayerNumber p ) +{ + TweenOffScreen(); + + m_Menu.TweenOffScreenToMenu( SM_GoToNextState ); + + PREFSMAN->m_iCurrentStageIndex++; // increment the stage number before constructing the next screen +} + diff --git a/stepmania/src/ScreenEvaluation.h b/stepmania/src/ScreenEvaluation.h new file mode 100644 index 0000000000..92354d70fb --- /dev/null +++ b/stepmania/src/ScreenEvaluation.h @@ -0,0 +1,71 @@ +/* +----------------------------------------------------------------------------- + Class: ScreenEvaluation + + Desc: Shows the user their score after gameplay has ended. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "Screen.h" +#include "Sprite.h" +#include "Score.h" +#include "RandomStream.h" +#include "BitmapText.h" +#include "GradeDisplay.h" +#include "MenuElements.h" +#include "Banner.h" +#include "ScoreDisplayRolling.h" +#include "BonusInfoFrame.h" +#include "BannerWithFrame.h" + + +const int NUM_JUDGE_LINES = 6; // perfect, great, good, boo, miss, ok +const int STAGES_TO_SHOW_IN_SUMMARY = 3; // only show the latest three stages in a summary + +class ScreenEvaluation : public Screen +{ +public: + ScreenEvaluation( bool bSummary ); + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + virtual void TweenOnScreen(); + virtual void TweenOffScreen(); + virtual void MenuBack( const PlayerNumber p ); + virtual void MenuStart( const PlayerNumber p ); + +protected: + enum ResultMode { RM_ARCADE_STAGE, RM_ARCADE_SUMMARY, RM_ONI }; + ResultMode m_ResultMode; + + MenuElements m_Menu; + + BannerWithFrame m_BannerWithFrame[STAGES_TO_SHOW_IN_SUMMARY]; + + Sprite m_sprGradeFrame[NUM_PLAYERS]; + GradeDisplay m_Grades[NUM_PLAYERS]; + BitmapText m_textOniPercent[NUM_PLAYERS]; + + BonusInfoFrame m_BonusInfoFrame[NUM_PLAYERS]; + + Sprite m_sprJudgeLabels[NUM_JUDGE_LINES]; + BitmapText m_textJudgeNumbers[NUM_JUDGE_LINES][NUM_PLAYERS]; + + Sprite m_sprScoreLabel; + ScoreDisplayRolling m_ScoreDisplay[NUM_PLAYERS]; + + bool m_bNewRecord[NUM_PLAYERS]; + BitmapText m_textNewRecord[NUM_PLAYERS]; + + bool m_bTryExtraStage; + BitmapText m_textTryExtraStage; +}; + + + diff --git a/stepmania/src/ScreenEz2SelectPlayer.cpp b/stepmania/src/ScreenEz2SelectPlayer.cpp index 1ce13edce6..40f38c4f54 100644 --- a/stepmania/src/ScreenEz2SelectPlayer.cpp +++ b/stepmania/src/ScreenEz2SelectPlayer.cpp @@ -229,7 +229,7 @@ void ScreenEz2SelectPlayer::HandleScreenMessage( const ScreenMessage SM ) switch( SM ) { case SM_MenuTimer: - MenuStart(PLAYER_NONE); + MenuStart(PLAYER_INVALID); break; case SM_GoToPrevState: MUSIC->Stop(); diff --git a/stepmania/src/ScreenEz2SelectStyle.cpp b/stepmania/src/ScreenEz2SelectStyle.cpp index 29299c60fc..8e0c48e182 100644 --- a/stepmania/src/ScreenEz2SelectStyle.cpp +++ b/stepmania/src/ScreenEz2SelectStyle.cpp @@ -21,6 +21,7 @@ Andrew Livy #include "GameManager.h" #include "RageLog.h" #include "AnnouncerManager.h" +#include "GameConstantsAndTypes.h" /* Constants */ @@ -192,7 +193,7 @@ void ScreenEz2SelectStyle::HandleScreenMessage( const ScreenMessage SM ) switch( SM ) { case SM_MenuTimer: - MenuStart(PLAYER_NONE); + MenuStart(PLAYER_INVALID); break; case SM_GoToPrevState: MUSIC->Stop(); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index e4f5f11de2..443744db4f 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -15,7 +15,7 @@ #include "ScreenManager.h" #include "ScreenSelectMusic.h" -#include "ScreenResults.h" +#include "ScreenEvaluation.h" #include "GameConstantsAndTypes.h" #include "ThemeManager.h" #include "GameManager.h" @@ -43,7 +43,8 @@ const float PLAYER_OPTIONS_LOCAL_Y[NUM_PLAYERS] = { -10, +10 }; const float DIFFICULTY_X[NUM_PLAYERS] = { SCREEN_LEFT+60, SCREEN_RIGHT-60 }; const float DIFFICULTY_Y[NUM_PLAYERS] = { SCREEN_BOTTOM-70, SCREEN_BOTTOM-70 }; -const float MAX_SECONDS_CAN_BE_OFF_BY = 0.25f; +const float DEBUG_X = CENTER_X; +const float DEBUG_Y = CENTER_Y-70; const float TIME_BETWEEN_DANCING_COMMENTS = 15; @@ -150,12 +151,8 @@ ScreenGameplay::ScreenGameplay() m_textStageNumber.Load( THEME->GetPathTo(FONT_HEADER2) ); m_textStageNumber.TurnShadowOff(); m_textStageNumber.SetXY( STAGE_NUMBER_LOCAL_X, STAGE_NUMBER_LOCAL_Y ); - CString sStageText = PREFSMAN->GetStageText(); - m_textStageNumber.SetText( sStageText ); - if( stricmp(sStageText, "Final") == 0 ) - m_textStageNumber.SetDiffuseColor( D3DXCOLOR(1,0.1f,0.1f,1) ); // red - else - m_textStageNumber.SetDiffuseColor( D3DXCOLOR(0.3f,1,0.3f,1) ); // green + m_textStageNumber.SetText( PREFSMAN->GetStageText() ); + m_textStageNumber.SetDiffuseColor( PREFSMAN->GetStageColor() ); m_frameTop.AddActor( &m_textStageNumber ); @@ -178,6 +175,7 @@ ScreenGameplay::ScreenGameplay() m_ScoreDisplay[p].SetXY( SCORE_LOCAL_X[p], SCORE_LOCAL_Y[p] ); m_ScoreDisplay[p].SetZoom( 0.8f ); + m_ScoreDisplay[p].SetDiffuseColor( PlayerToColor(p) ); m_frameBottom.AddActor( &m_ScoreDisplay[p] ); m_textPlayerOptions[p].Load( THEME->GetPathTo(FONT_NORMAL) ); @@ -207,9 +205,13 @@ ScreenGameplay::ScreenGameplay() } + m_textDebug.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textDebug.SetXY( DEBUG_X, DEBUG_Y ); + m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + this->AddActor( &m_textDebug ); - + m_StarWipe.SetClosed(); @@ -240,8 +242,9 @@ ScreenGameplay::ScreenGameplay() m_soundFail.Load( THEME->GetPathTo(SOUND_GAMEPLAY_FAILED) ); m_announcerReady.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_READY) ); m_announcerHereWeGo.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_HERE_WE_GO_NORMAL) ); + m_announcerDanger.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_DANGER) ); m_announcerGood.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_GOOD) ); - m_announcerBad.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_BAD) ); + m_announcerHot.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_HOT) ); m_announcerCleared.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_CLEARED) ); m_announcerFailComment.Load(ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_FAILED) ); @@ -262,10 +265,31 @@ ScreenGameplay::~ScreenGameplay() } +void ScreenGameplay::SaveSummary() +{ + // save score summaries + if( m_pCurSong != NULL ) + { + for( int p=0; pIsPlayerEnabled((PlayerNumber)p) ) + continue; // skip + + SONGMAN->m_aGameplayStatistics[p].Add( m_Player[p].GetGameplayStatistics() ); + } + + m_pCurSong = NULL; + } +} + + void ScreenGameplay::LoadNextSong() { int p; + + SaveSummary(); + m_pCurSong = m_apSongQueue[m_apSongQueue.GetSize()-1]; m_apSongQueue.RemoveAt(m_apSongQueue.GetSize()-1); @@ -291,7 +315,7 @@ void ScreenGameplay::LoadNextSong() NoteData* pOriginalNoteData = pNotes[p]->GetNoteData(); NoteData newNoteData; - pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, pOriginalNoteData, newNoteData ); + pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, pOriginalNoteData, &newNoteData ); m_Player[p].Load( (PlayerNumber)p, @@ -299,11 +323,13 @@ void ScreenGameplay::LoadNextSong() &newNoteData, PREFSMAN->m_PlayerOptions[p], &m_LifeMeter[p], - &m_ScoreDisplay[p] + &m_ScoreDisplay[p], + pNotes[p]->GetNoteData()->GetNumTapNotes() + pNotes[p]->GetNoteData()->GetNumHoldNotes() ); } m_soundMusic.Load( m_pCurSong->GetMusicPath() ); + m_soundMusic.SetPlaybackRate( PREFSMAN->m_SongOptions.m_fMusicRate ); m_Background.LoadFromSong( m_pCurSong ); m_Background.SetDiffuseColor( D3DXCOLOR(0.5f,0.5f,0.5f,1) ); @@ -318,17 +344,22 @@ void ScreenGameplay::Update( float fDeltaTime ) Screen::Update( fDeltaTime ); + if( m_pCurSong == NULL ) + return; + + float fSongBeat, fBPS; float fPositionSeconds = m_soundMusic.GetPositionSeconds(); m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); + m_Background.SetSongBeat( fSongBeat ); //LOG->WriteLine( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() ); - float fMaxBeatDifference = fBPS*MAX_SECONDS_CAN_BE_OFF_BY; + const float fMaxBeatDifference = fBPS * PREFSMAN->m_fJudgeWindow * PREFSMAN->m_SongOptions.m_fMusicRate; for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) continue; - if( !m_LifeMeter[p].IsAboutToFail() ) - { - bAllAboutToFail = false; + if( !m_LifeMeter[p].IsInDanger() ) + bAllInDanger = false; + + if( !m_LifeMeter[p].HasFailed() ) bAllFailed = false; - } - else if( !m_LifeMeter[p].HasFailed() ) - { - bAllFailed = false; - } - break; } - if( bAllAboutToFail ) m_Background.TurnDangerOn(); - else m_Background.TurnDangerOff(); + + if( bAllInDanger ) m_Background.TurnDangerOn(); + else m_Background.TurnDangerOff(); if( bAllFailed ) { @@ -398,8 +425,20 @@ void ScreenGameplay::Update( float fDeltaTime ) { m_fTimeLeftBeforeDancingComment = TIME_BETWEEN_DANCING_COMMENTS; // reset for the next comment - if( m_Background.IsDangerOn() ) - m_announcerBad.PlayRandom(); + bool bAllInDanger = true; + for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + m_Player[p].CrossedRow( r, fSongBeat, fMaxBeatDifference ); + } + } + + iRowLastCrossed = iRowNow; + + + + // + // play assist ticks + // + // Sound cards have a latency between when a sample is Play()ed and when the sound + // will start coming out the speaker. Compensate for this by boosting + // fPositionSeconds ahead if( PREFSMAN->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK ) { - // - // play assist ticks - // - // Sound cards have a latency between when a sample is Play()ed and when the sound - // will start coming out the speaker. Compensate for this by boosting - // fPositionSeconds ahead fPositionSeconds += (SOUND->GetPlayLatency()+0.06f) * m_soundMusic.GetPlaybackRate(); // HACK: Add 0.06 seconds to make them play a tiny bit earlier m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); - int iIndexNow = BeatToNoteIndexNotRounded( fSongBeat ); - static int iIndexLastCrossed = 0; + int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); + static int iRowLastCrossed = 0; bool bAnyoneHasANote = false; // set this to true if any player has a note at one of the indicies we crossed - for( int i=iIndexLastCrossed+1; i<=iIndexNow; i++ ) // for each index we crossed since the last update + for( int r=iRowLastCrossed+1; r<=iRowNow; r++ ) // for each index we crossed since the last update { for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) continue; // skip - bAnyoneHasANote |= m_Player[p].IsThereANoteAtIndex( i ); + m_Player[p].CrossedRow( r, fSongBeat, fMaxBeatDifference ); + bAnyoneHasANote |= m_Player[p].IsThereANoteAtRow( r ); break; // this will only play the tick for the first player that is joined } } @@ -441,7 +501,7 @@ void ScreenGameplay::Update( float fDeltaTime ) m_soundAssistTick.PlayRandom(); - iIndexLastCrossed = iIndexNow; + iRowLastCrossed = iRowNow; } } @@ -460,6 +520,44 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ float fSongBeat, fBPS; m_pCurSong->GetBeatAndBPSFromElapsedTime( m_soundMusic.GetPositionSeconds(), fSongBeat, fBPS ); + + // Handle special keys to adjust the offset + if( type == IET_FIRST_PRESS && DeviceI.device == DEVICE_KEYBOARD ) + { + switch( DeviceI.button ) + { + case DIK_F9: + m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()-0.01f ); + break; + case DIK_F10: + m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()+0.01f ); + break; + case DIK_F11: + m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()-(1/fBPS) ); + break; + case DIK_F12: + m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()+(1/fBPS) ); + break; + } + + switch( DeviceI.button ) + { + case DIK_F9: + case DIK_F10: + case DIK_F11: + case DIK_F12: + m_textDebug.SetText( ssprintf("Offset = %f.", m_pCurSong->GetBeatOffsetInSeconds()) ); + m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textDebug.StopTweening(); + m_textDebug.BeginTweeningQueued( 3 ); // sleep + m_textDebug.BeginTweeningQueued( 0.5f ); // fade out + m_textDebug.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + break; + } + + } + + if( MenuI.IsValid() ) { @@ -478,14 +576,14 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ } } - float fMaxBeatsCanBeOffBy = MAX_SECONDS_CAN_BE_OFF_BY * fBPS; + const float fMaxBeatDifference = fBPS * PREFSMAN->m_fJudgeWindow * PREFSMAN->m_SongOptions.m_fMusicRate; if( type == IET_FIRST_PRESS ) { if( StyleI.IsValid() ) { if( GAMEMAN->IsPlayerEnabled( StyleI.player ) ) - m_Player[StyleI.player].HandlePlayerStep( fSongBeat, StyleI.col, fMaxBeatsCanBeOffBy ); + m_Player[StyleI.player].HandlePlayerStep( fSongBeat, StyleI.col, fMaxBeatDifference ); } } } @@ -562,16 +660,8 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) SCREENMAN->SendMessageToTopScreen( SM_GoToResults, 1 ); break; case SM_GoToResults: - { - // send score summaries to the PREFSMAN object so ScreenResults can grab it. - for( int p=0; pIsPlayerEnabled((PlayerNumber)p) ) - continue; // skip - m_Player[p].GetGameplayStatistics( SONGMAN->m_GameplayStatistics[PREFSMAN->m_iNumArcadeStages-1][p] ); - } - SCREENMAN->SetNewScreen( new ScreenResults(false) ); - } + SaveSummary(); + SCREENMAN->SetNewScreen( new ScreenEvaluation(false) ); break; diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index fd8769f8c7..02fbac15bc 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -47,6 +47,7 @@ public: private: void TweenOnScreen(); void TweenOffScreen(); + void SaveSummary(); void LoadNextSong(); @@ -62,19 +63,19 @@ private: Background m_Background; - ActorFrame m_frameTop; Sprite m_sprTopFrame; Quad m_quadLifeMeterBG[NUM_PLAYERS]; // just a black quad to fill in hole for the life meter LifeMeterBar m_LifeMeter[NUM_PLAYERS]; BitmapText m_textStageNumber; - ActorFrame m_frameBottom; Sprite m_sprBottomFrame; ScoreDisplayRolling m_ScoreDisplay[NUM_PLAYERS]; BitmapText m_textPlayerOptions[NUM_PLAYERS]; + BitmapText m_textDebug; + TransitionStarWipe m_StarWipe; @@ -90,8 +91,9 @@ private: RandomSample m_soundFail; RandomSample m_announcerReady; RandomSample m_announcerHereWeGo; - RandomSample m_announcerGood; // these are samples because we play them often - RandomSample m_announcerBad; // these are samples because we play them often + RandomSample m_announcerDanger; + RandomSample m_announcerGood; + RandomSample m_announcerHot; RandomStream m_announcerCleared; RandomStream m_announcerFailComment; RandomStream m_announcerGameOver; @@ -100,7 +102,6 @@ private: RageSoundStream m_soundMusic; - }; diff --git a/stepmania/src/ScreenMusicScroll.cpp b/stepmania/src/ScreenMusicScroll.cpp index d81512c855..c7b72b289d 100644 --- a/stepmania/src/ScreenMusicScroll.cpp +++ b/stepmania/src/ScreenMusicScroll.cpp @@ -108,10 +108,8 @@ const CString CREDIT_LINES[] = "", "", "If your name is missing from this list,", - "", - " I apologize!", - "", - " -Chris" + " send me an e-mail!", + " -Chris" }; const int NUM_CREDIT_LINES = sizeof(CREDIT_LINES) / sizeof(CString); @@ -156,12 +154,12 @@ ScreenMusicScroll::ScreenMusicScroll() { m_textLines[i].SetZoom( 0.7f ); m_textLines[i].SetXY( CENTER_X, SCREEN_BOTTOM + 40 ); - m_textLines[i].BeginTweeningQueued( 0.20f * i ); - m_textLines[i].BeginTweeningQueued( 2.0f ); + m_textLines[i].BeginTweeningQueued( 0.30f * i ); + m_textLines[i].BeginTweeningQueued( 3.0f ); m_textLines[i].SetTweenXY( CENTER_X, SCREEN_TOP - 40 ); } - this->SendScreenMessage( SM_StartFadingOut, 0.20f * i + 3.0f ); + this->SendScreenMessage( SM_StartFadingOut, 0.3f * i + 3.0f ); this->AddActor( &m_Fade ); diff --git a/stepmania/src/ScreenSelectCourse.cpp b/stepmania/src/ScreenSelectCourse.cpp index 04b840c8ab..72d345621b 100644 --- a/stepmania/src/ScreenSelectCourse.cpp +++ b/stepmania/src/ScreenSelectCourse.cpp @@ -134,7 +134,7 @@ void ScreenSelectCourse::Input( const DeviceInput& DeviceI, const InputEventType if( m_Menu.IsClosing() ) return; // ignore - if( MenuI.player == PLAYER_NONE ) + if( MenuI.player == PLAYER_INVALID ) return; Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler @@ -174,7 +174,7 @@ void ScreenSelectCourse::HandleScreenMessage( const ScreenMessage SM ) { MUSIC->Stop(); - SCREENMAN->SetNewScreen( new ScreenStage(false) ); + SCREENMAN->SetNewScreen( new ScreenStage ); } break; } diff --git a/stepmania/src/ScreenSelectDifficulty.cpp b/stepmania/src/ScreenSelectDifficulty.cpp index aa7adb2f99..d6f6daf2b6 100644 --- a/stepmania/src/ScreenSelectDifficulty.cpp +++ b/stepmania/src/ScreenSelectDifficulty.cpp @@ -72,6 +72,10 @@ ScreenSelectDifficulty::ScreenSelectDifficulty() { LOG->WriteLine( "ScreenSelectDifficulty::ScreenSelectDifficulty()" ); + // Reset the current PlayMode + PREFSMAN->m_PlayMode = PLAY_MODE_INVALID; + + int p; m_Menu.Load( @@ -207,11 +211,22 @@ void ScreenSelectDifficulty::HandleScreenMessage( const ScreenMessage SM ) SCREENMAN->SetNewScreen( new ScreenTitleMenu ); break; case SM_GoToNextState: + { + for( int p=0; pm_PreferredDifficultyClass[p] = CLASS_EASY; break; + case 1: PREFSMAN->m_PreferredDifficultyClass[p] = CLASS_MEDIUM; break; + case 2: PREFSMAN->m_PreferredDifficultyClass[p] = CLASS_HARD; break; + } + } + switch( m_iSelection[PLAYER_1] ) { case 0: case 1: case 2: // something on page 1 was chosen + PREFSMAN->m_PlayMode = PLAY_MODE_ARCADE; SCREENMAN->SetNewScreen( new ScreenSelectGroup ); break; case 3: diff --git a/stepmania/src/ScreenSelectGroup.cpp b/stepmania/src/ScreenSelectGroup.cpp index b57a82885c..9e03e2840a 100644 --- a/stepmania/src/ScreenSelectGroup.cpp +++ b/stepmania/src/ScreenSelectGroup.cpp @@ -215,7 +215,7 @@ void ScreenSelectGroup::AfterChange() if( j == NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 1 ) sText += ssprintf( "(%d more).....", arraySongs.GetSize() - NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 2 ); else - sText += arraySongs[j]->GetMainTitle() + "\n"; + sText += arraySongs[j]->GetFullTitle() + "\n"; } } m_textContents[i].SetText( sText ); diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index e30dafa168..0236dd6aa1 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -217,7 +217,7 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, const InputEventType { LOG->WriteLine( "ScreenSelectMusic::Input()" ); - if( MenuI.player == PLAYER_NONE ) + if( MenuI.player == PLAYER_INVALID ) return; if( m_Menu.IsClosing() ) @@ -323,7 +323,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM ) { MUSIC->Stop(); - SCREENMAN->SetNewScreen( new ScreenStage(false) ); + SCREENMAN->SetNewScreen( new ScreenStage ); } break; case SM_PlaySongSample: @@ -350,64 +350,69 @@ void ScreenSelectMusic::MenuRight( const PlayerNumber p, const InputEventType ty void ScreenSelectMusic::MenuStart( const PlayerNumber p ) { // this needs to check whether valid Notes are selected! - m_MusicWheel.Select(); + bool bResult = m_MusicWheel.Select(); - switch( m_MusicWheel.GetSelectedType() ) + if( bResult ) { - case TYPE_SONG: + // a song was selected + switch( m_MusicWheel.GetSelectedType() ) { - if( !m_MusicWheel.GetSelectedSong()->HasMusic() ) + case TYPE_SONG: { - SCREENMAN->AddScreenToTop( new ScreenPrompt( "ERROR:\n \nThis song does not have a music file\n and cannot be played.", PROMPT_OK) ); - return; + if( !m_MusicWheel.GetSelectedSong()->HasMusic() ) + { + SCREENMAN->AddScreenToTop( new ScreenPrompt( "ERROR:\n \nThis song does not have a music file\n and cannot be played.", PROMPT_OK) ); + return; + } + + bool bIsNew = m_MusicWheel.GetSelectedSong()->IsNew(); + bool bIsHard = false; + for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + if( SONGMAN->GetCurrentNotes((PlayerNumber)p) && SONGMAN->GetCurrentNotes((PlayerNumber)p)->m_iMeter >= 9 ) + bIsHard = true; + } + + if( bIsNew ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_NEW) ); + else if( bIsHard ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_HARD) ); + else + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_GENERAL) ); + + + TweenOffScreen(); + + m_bMadeChoice = true; + + m_soundSelect.PlayRandom(); + + // show "hold START for options" + m_textHoldForOptions.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade in + m_textHoldForOptions.SetTweenZoomY( 1 ); + m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textHoldForOptions.BeginTweeningQueued( 2.0f ); // sleep + m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade out + m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_textHoldForOptions.SetTweenZoomY( 0 ); + + m_Menu.TweenOffScreenToBlack( SM_None, false ); + + this->SendScreenMessage( SM_GoToNextState, 2.5f ); } + break; + case TYPE_SECTION: + + break; + case TYPE_ROULETTE: - bool bIsNew = m_MusicWheel.GetSelectedSong()->IsNew(); - bool bIsHard = false; - for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) - continue; // skip - if( SONGMAN->GetCurrentNotes((PlayerNumber)p) && SONGMAN->GetCurrentNotes((PlayerNumber)p)->m_iMeter >= 9 ) - bIsHard = true; - } - - if( bIsNew ) - SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_NEW) ); - else if( bIsHard ) - SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_HARD) ); - else - SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_GENERAL) ); - - - TweenOffScreen(); - - m_bMadeChoice = true; - - m_soundSelect.PlayRandom(); - - // show "hold START for options" - m_textHoldForOptions.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); - m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade in - m_textHoldForOptions.SetTweenZoomY( 1 ); - m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); - m_textHoldForOptions.BeginTweeningQueued( 2.0f ); // sleep - m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade out - m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); - m_textHoldForOptions.SetTweenZoomY( 0 ); - - m_Menu.TweenOffScreenToBlack( SM_None, false ); - - this->SendScreenMessage( SM_GoToNextState, 2.5f ); + break; } - break; - case TYPE_SECTION: - - break; - case TYPE_ROULETTE: - - break; } + } diff --git a/stepmania/src/ScreenSelectStyle.cpp b/stepmania/src/ScreenSelectStyle.cpp index e872580d6f..2339383039 100644 --- a/stepmania/src/ScreenSelectStyle.cpp +++ b/stepmania/src/ScreenSelectStyle.cpp @@ -47,6 +47,11 @@ ScreenSelectStyle::ScreenSelectStyle() { LOG->WriteLine( "ScreenSelectStyle::ScreenSelectStyle()" ); + + // Reset the current style and game + GAMEMAN->m_CurStyle = STYLE_NONE; + + for( int s=0; sStop(); @@ -210,7 +215,7 @@ void ScreenSelectStyle::MenuRight( const PlayerNumber p ) void ScreenSelectStyle::MenuStart( const PlayerNumber p ) { - if( p != PLAYER_NONE ) + if( p != PLAYER_INVALID ) GAMEMAN->m_sMasterPlayerNumber = p; GAMEMAN->m_CurStyle = GetSelectedStyle(); diff --git a/stepmania/src/ScreenStage.cpp b/stepmania/src/ScreenStage.cpp index 25d1d8f99b..265807080b 100644 --- a/stepmania/src/ScreenStage.cpp +++ b/stepmania/src/ScreenStage.cpp @@ -29,41 +29,48 @@ const ScreenMessage SM_StartFadingOut = ScreenMessage(SM_User + 1); const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 3); -ScreenStage::ScreenStage( bool bTryExtraStage ) +ScreenStage::ScreenStage() { - m_bTryExtraStage = false; - m_textStage.Load( THEME->GetPathTo(FONT_STAGE) ); m_textStage.TurnShadowOff(); - if( bTryExtraStage ) + + if( PREFSMAN->IsExtraStage() ) { - m_textStage.SetText( "Try Extra Stage!" ); + m_textStage.SetText( "Extra Stage" ); + m_textStage.SetDiffuseColor( D3DXCOLOR(1,0.1f,0.1f,1) ); // red + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_EXTRA) ); + } + else if( PREFSMAN->IsExtraStage2() ) + { + m_textStage.SetText( "Extra Stage 2" ); // red m_textStage.SetDiffuseColor( D3DXCOLOR(1,0.1f,0.1f,1) ); SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_EXTRA) ); } - else // !bTryExtraStage + else if( PREFSMAN->IsFinalStage() ) { - int iStageNo = PREFSMAN->GetStageNumber(); - bool bFinal = PREFSMAN->IsFinalStage(); - - CString sStagePrefix = PREFSMAN->GetStageText(); - m_textStage.SetText( sStagePrefix + " Stage" ); + m_textStage.SetText( "Final Stage" ); + m_textStage.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_FINAL) ); + } + else + { + m_textStage.SetText( PREFSMAN->GetStageText() + " Stage" ); m_textStage.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); - if( bFinal ) - SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_FINAL) ); - else + const int iStageNo = PREFSMAN->GetStageIndex()+1; + switch( iStageNo ) { - switch( iStageNo ) - { - case 1: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_1) ); break; - case 2: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_2) ); break; - case 3: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_3) ); break; - case 4: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_4) ); break; - case 5: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_5) ); break; - } + case 1: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_1) ); break; + case 2: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_2) ); break; + case 3: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_3) ); break; + case 4: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_4) ); break; + case 5: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_5) ); break; + default: ; break; // play nothing } + } + + m_textStage.SetXY( CENTER_X, CENTER_Y ); m_textStage.SetZoomX( 2 ); m_textStage.SetZoomY( 0 ); diff --git a/stepmania/src/ScreenStage.h b/stepmania/src/ScreenStage.h index 9d5f3bb75c..3c209e370f 100644 --- a/stepmania/src/ScreenStage.h +++ b/stepmania/src/ScreenStage.h @@ -17,7 +17,6 @@ class ScreenStage : public Screen { public: ScreenStage(); - ScreenStage( bool bTryExtraStage ); virtual void HandleScreenMessage( const ScreenMessage SM ); diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 413fb181a0..b56a42948f 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" /* ----------------------------------------------------------------------------- - File: Song.h + Class: Song Desc: Holds metadata for a song and the song's step data. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford ----------------------------------------------------------------------------- */ @@ -85,6 +86,20 @@ Song::~Song() } +void Song::AddBPMSegment( BPMSegment seg ) +{ + m_BPMSegments.Add( seg ); + SortBPMSegmentsArray( m_BPMSegments ); +} + + +void Song::AddFreezeSegment( FreezeSegment seg ) +{ + m_FreezeSegments.Add( seg ); + SortFreezeSegmentsArray( m_FreezeSegments ); +} + + void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut ) { // LOG->WriteLine( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime ); @@ -184,14 +199,15 @@ float Song::GetElapsedTimeFromBeat( float fBeat ) void Song::GetMainAndSubTitlesFromFullTitle( CString sFullTitle, CString &sMainTitleOut, CString &sSubTitleOut ) { - char szSeps[] = { '-', '~' }; - for( int i=0; iWriteLine( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fFreezeSeconds ); - - m_FreezeSegments.Add( new_seg ); // add to back for now (we'll sort later) - SortFreezeSegmentsArray( m_FreezeSegments ); - + AddFreezeSegment( FreezeSegment(fFreezeBeat, fFreezeSeconds) ); + LOG->WriteLine( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds ); } } @@ -566,13 +587,7 @@ bool Song::LoadFromDWIFile( CString sPath ) float fBeat = NoteRowToBeat( fIndex ); float fNewBPM = (float)atoi( arrayBPMChangeValues[1] ); - BPMSegment new_seg; - new_seg.m_fStartBeat = fBeat; - new_seg.m_fBPM = fNewBPM; - - // add and sort - m_BPMSegments.Add( new_seg ); - SortBPMSegmentsArray( m_BPMSegments ); + AddBPMSegment( BPMSegment(fBeat, fNewBPM) ); } } @@ -582,7 +597,7 @@ bool Song::LoadFromDWIFile( CString sPath ) pNewNotes->LoadFromDWITokens( arrayValueTokens[0], arrayValueTokens[1], - arrayValueTokens[2], + atoi(arrayValueTokens[2]), arrayValueTokens[3], arrayValueTokens.GetSize() == 5 ? arrayValueTokens[4] : "" ); @@ -652,6 +667,17 @@ bool Song::LoadFromSMDir( CString sDir ) sFileText += buffer; file.Close(); + // strip comments out of sFileText + while( sFileText.Find("//") != -1 ) + { + int iIndexCommentStart = sFileText.Find("//"); + int iIndexCommentEnd = sFileText.Find("\n", iIndexCommentStart); + if( iIndexCommentEnd == -1 ) // comment doesn't have an end? + sFileText.Delete( iIndexCommentStart, 2 ); + else + sFileText.Delete( iIndexCommentStart, iIndexCommentEnd-iIndexCommentStart ); + } + // split sFileText into strings containing each value expression CStringArray arrayValueStrings; split( sFileText, ";", arrayValueStrings, false ); @@ -890,8 +916,8 @@ void Song::TidyUpData() pNM->m_fRadarValues[RADAR_STREAM] = pNM->GetNoteData()->GetStreamRadarValue( fMusicLength ); pNM->m_fRadarValues[RADAR_VOLTAGE] = pNM->GetNoteData()->GetVoltageRadarValue( fMusicLength ); pNM->m_fRadarValues[RADAR_AIR] = pNM->GetNoteData()->GetAirRadarValue( fMusicLength ); - pNM->m_fRadarValues[RADAR_CHAOS] = pNM->GetNoteData()->GetChaosRadarValue( fMusicLength ); pNM->m_fRadarValues[RADAR_FREEZE] = pNM->GetNoteData()->GetFreezeRadarValue( fMusicLength ); + pNM->m_fRadarValues[RADAR_CHAOS] = pNM->GetNoteData()->GetChaosRadarValue( fMusicLength ); } } @@ -1138,7 +1164,7 @@ void Song::SaveToSMDir() file.Close(); // - // Save all Notess for this file + // Save all Notes for this file // for( i=0; iGetStageIndex() ][p]; + ASSERT( m_aGameplayStatistics[p].GetSize() > 0 ); + return m_aGameplayStatistics[p][ m_aGameplayStatistics[p].GetSize()-1 ]; } diff --git a/stepmania/src/SongManager.h b/stepmania/src/SongManager.h index 6c59a19b01..bf112cd7ea 100644 --- a/stepmania/src/SongManager.h +++ b/stepmania/src/SongManager.h @@ -14,12 +14,10 @@ #include "Song.h" #include "Course.h" -#include "GamePlayStatistics.h" +#include "GameplayStatistics.h" //#include // for D3DXCOLOR const int MAX_SONG_QUEUE_SIZE = 400; // this has to be gigantic to fit an "endless" number of songs -const int MAX_NUM_STAGES = 10; // the max number of stages that can be played in arcade mode - class SongManager { @@ -32,7 +30,7 @@ public: Course* m_pCurCourse; CString m_sPreferredGroup; - GameplayStatistics m_GameplayStatistics[MAX_NUM_STAGES][NUM_PLAYERS]; // for passing from Dancing to Results + CArray m_aGameplayStatistics[NUM_PLAYERS]; // for passing from Dancing to Results CArray m_pSongs; // all songs that can be played diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 896cf9ab04..99c2381b65 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -42,7 +42,7 @@ #include "ScreenSandbox.h" -#include "ScreenResults.h" +#include "ScreenEvaluation.h" #include "ScreenTitleMenu.h" #include "ScreenPlayerOptions.h" #include "ScreenMusicScroll.h" @@ -223,6 +223,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) } } // end while( WM_QUIT != msg.message ) + LOG->WriteLine( "Recieved WM_QUIT message. Shutting down..." ); // clean up after a normal exit DestroyObjects(); // deallocate our game objects and leave fullscreen @@ -236,7 +237,29 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) } catch( ... ) { - g_sErrorString = "access violation or other run-time error."; + switch( GetExceptionCode() ) + { + case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break; + case EXCEPTION_BREAKPOINT: g_sErrorString = "EXCEPTION_BREAKPOINT"; break; + case EXCEPTION_DATATYPE_MISALIGNMENT: g_sErrorString = "EXCEPTION_DATATYPE_MISALIGNMENT"; break; + case EXCEPTION_SINGLE_STEP: g_sErrorString = "EXCEPTION_SINGLE_STEP"; break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: g_sErrorString = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; break; + case EXCEPTION_FLT_DENORMAL_OPERAND: g_sErrorString = "EXCEPTION_FLT_DENORMAL_OPERAND"; break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: g_sErrorString = "EXCEPTION_FLT_DIVIDE_BY_ZERO"; break; + case EXCEPTION_FLT_INEXACT_RESULT: g_sErrorString = "EXCEPTION_FLT_INEXACT_RESULT"; break; + case EXCEPTION_FLT_INVALID_OPERATION: g_sErrorString = "EXCEPTION_FLT_INVALID_OPERATION"; break; + case EXCEPTION_FLT_OVERFLOW: g_sErrorString = "EXCEPTION_FLT_OVERFLOW"; break; + case EXCEPTION_FLT_STACK_CHECK: g_sErrorString = "EXCEPTION_FLT_STACK_CHECK"; break; + case EXCEPTION_FLT_UNDERFLOW: g_sErrorString = "EXCEPTION_FLT_UNDERFLOW"; break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: g_sErrorString = "EXCEPTION_INT_DIVIDE_BY_ZERO"; break; + case EXCEPTION_INT_OVERFLOW: g_sErrorString = "EXCEPTION_INT_OVERFLOW"; break; + case EXCEPTION_PRIV_INSTRUCTION: g_sErrorString = "EXCEPTION_PRIV_INSTRUCTION"; break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION:g_sErrorString = "EXCEPTION_NONCONTINUABLE_EXCEPTION"; break; + case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break; + case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break; + default: g_sErrorString = "Unknown exception."; break; + } + } if( g_sErrorString != "" ) @@ -510,12 +533,12 @@ HRESULT CreateObjects( HWND hWnd ) + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); //SCREENMAN->SetNewScreen( new ScreenLoading ); //SCREENMAN->SetNewScreen( new ScreenSandbox ); - //SCREENMAN->SetNewScreen( new ScreenResults(false) ); + //SCREENMAN->SetNewScreen( new ScreenEvaluation(true) ); //SCREENMAN->SetNewScreen( new ScreenSelectDifficulty ); //SCREENMAN->SetNewScreen( new ScreenPlayerOptions ); - SCREENMAN->SetNewScreen( new ScreenTitleMenu ); //SCREENMAN->SetNewScreen( new ScreenGameplay ); //SCREENMAN->SetNewScreen( new ScreenMusicScroll ); //SCREENMAN->SetNewScreen( new ScreenSelectMusic ); diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index b929cee7d0..fcb1c9c156 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -79,7 +79,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /out:"../StepMania-debug.exe" /pdbtype:sept +# ADD LINK32 /nologo /subsystem:windows /profile /debug /machine:I386 /out:"../StepMania-debug.exe" !ENDIF @@ -260,6 +260,14 @@ SOURCE=.\NoteData.h # End Source File # Begin Source File +SOURCE=.\NoteDataWithScoring.cpp +# End Source File +# Begin Source File + +SOURCE=.\NoteDataWithScoring.h +# End Source File +# Begin Source File + SOURCE=.\Notes.cpp # End Source File # Begin Source File @@ -330,6 +338,14 @@ SOURCE=.\IniFile.cpp SOURCE=.\IniFile.h # End Source File +# Begin Source File + +SOURCE=.\MSDScanner.cpp +# End Source File +# Begin Source File + +SOURCE=.\MSDScanner.h +# End Source File # End Group # Begin Group "System" @@ -676,6 +692,14 @@ SOURCE=.\Background.h # End Source File # Begin Source File +SOURCE=.\BackgroundAnimation.cpp +# End Source File +# Begin Source File + +SOURCE=.\BackgroundAnimation.h +# End Source File +# Begin Source File + SOURCE=.\ColorNote.cpp # End Source File # Begin Source File @@ -848,6 +872,14 @@ SOURCE=.\ScreenEditMenu.h # End Source File # Begin Source File +SOURCE=.\ScreenEvaluation.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScreenEvaluation.h +# End Source File +# Begin Source File + SOURCE=.\ScreenEz2SelectPlayer.cpp # End Source File # Begin Source File @@ -940,14 +972,6 @@ SOURCE=.\ScreenPrompt.h # End Source File # Begin Source File -SOURCE=.\ScreenResults.cpp -# End Source File -# Begin Source File - -SOURCE=.\ScreenResults.h -# End Source File -# Begin Source File - SOURCE=.\ScreenSandbox.cpp # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 2b8e8cf044..039fdc08e1 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -166,6 +166,24 @@ + + + + + + + + + + + + @@ -223,12 +241,6 @@ - - - - @@ -359,6 +371,12 @@ + + + + @@ -408,6 +426,12 @@ + + + + - - - - @@ -646,6 +664,12 @@ + + + + @@ -658,6 +682,12 @@ + + + + diff --git a/stepmania/src/StyleDef.cpp b/stepmania/src/StyleDef.cpp index 922f22a2d2..32392a0292 100644 --- a/stepmania/src/StyleDef.cpp +++ b/stepmania/src/StyleDef.cpp @@ -17,7 +17,7 @@ #include "IniFile.h" -void StyleDef::GetTransformedNoteDataForStyle( PlayerNumber p, NoteData* pOriginal, NoteData &newNoteData ) +void StyleDef::GetTransformedNoteDataForStyle( PlayerNumber p, NoteData* pOriginal, NoteData* pNoteDataOut ) { int iNewToOriginalTrack[MAX_COLS_PER_PLAYER]; for( int col=0; colLoadTransformed( pOriginal, m_iColsPerPlayer, iNewToOriginalTrack ); } \ No newline at end of file diff --git a/stepmania/src/StyleDef.h b/stepmania/src/StyleDef.h index 2c406ab9f7..32874946d3 100644 --- a/stepmania/src/StyleDef.h +++ b/stepmania/src/StyleDef.h @@ -79,7 +79,7 @@ public: return StyleInput(); // Didn't find a match. Return blank. } - void GetTransformedNoteDataForStyle( PlayerNumber p, NoteData* pOriginal, NoteData &newNoteData ); + void GetTransformedNoteDataForStyle( PlayerNumber p, NoteData* pOriginal, NoteData* pNoteDataOut ); }; diff --git a/stepmania/src/StyleInput.h b/stepmania/src/StyleInput.h index da197b4c6c..17066634a2 100644 --- a/stepmania/src/StyleInput.h +++ b/stepmania/src/StyleInput.h @@ -13,15 +13,15 @@ struct StyleInput { - StyleInput() { player = PLAYER_NONE; col = -1; }; + StyleInput() { player = PLAYER_INVALID; col = -1; }; StyleInput( PlayerNumber p, int c ) { player = p; col = c; }; bool operator==( const StyleInput &other ) { return player == other.player && col == other.col; }; PlayerNumber player; int col; - inline bool IsBlank() const { return player == PLAYER_NONE; }; + inline bool IsBlank() const { return player == PLAYER_INVALID; }; inline bool IsValid() const { return !IsBlank(); }; - inline void MakeBlank() { player = PLAYER_NONE; col = -1; }; + inline void MakeBlank() { player = PLAYER_INVALID; col = -1; }; }; \ No newline at end of file diff --git a/stepmania/src/TextBanner.cpp b/stepmania/src/TextBanner.cpp index 9eaa37f23c..339b04bf46 100644 --- a/stepmania/src/TextBanner.cpp +++ b/stepmania/src/TextBanner.cpp @@ -68,8 +68,8 @@ bool TextBanner::LoadFromSong( Song* pSong ) } else { - fTitleZoom = 0.8f; - fSubTitleZoom = 0.6f; + fTitleZoom = 1.0f; + fSubTitleZoom = 0.5f; fArtistZoom = 0.6f; } @@ -94,9 +94,9 @@ bool TextBanner::LoadFromSong( Song* pSong ) if( sSubTitle == "" ) { - m_textTitle.SetY( -7 ); + m_textTitle.SetY( -8 ); m_textSubTitle.SetY( 0 ); - m_textArtist.SetY( 9 ); + m_textArtist.SetY( 8 ); } else { diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp index 833447d7d9..ae8770c05d 100644 --- a/stepmania/src/ThemeManager.cpp +++ b/stepmania/src/ThemeManager.cpp @@ -124,16 +124,16 @@ CString ThemeManager::GetPathTo( ThemeElement te ) case GRAPHIC_PAD_SOLO: sAssetPrefix = "Graphics\\Pad solo"; break; case GRAPHIC_PLAYER_OPTIONS_BACKGROUND: sAssetPrefix = "Graphics\\player options background"; break; case GRAPHIC_PLAYER_OPTIONS_TOP_EDGE: sAssetPrefix = "Graphics\\player options top edge"; break; - case GRAPHIC_RESULTS_BACKGROUND: sAssetPrefix = "Graphics\\results background"; break; - case GRAPHIC_RESULTS_BANNER_FRAME: sAssetPrefix = "Graphics\\results banner frame"; break; - case GRAPHIC_RESULTS_BONUS_FRAME_P1: sAssetPrefix = "Graphics\\results bonus frame p1"; break; - case GRAPHIC_RESULTS_BONUS_FRAME_P2: sAssetPrefix = "Graphics\\results bonus frame p2"; break; - case GRAPHIC_RESULTS_GRADE_FRAME: sAssetPrefix = "Graphics\\results grade frame 1x2"; break; - case GRAPHIC_RESULTS_GRADES: sAssetPrefix = "Graphics\\results grades 1x7"; break; - case GRAPHIC_RESULTS_JUDGE_LABELS: sAssetPrefix = "Graphics\\results judge labels 1x6"; break; - case GRAPHIC_RESULTS_SCORE_LABELS: sAssetPrefix = "Graphics\\results score labels 1x2"; break; - case GRAPHIC_RESULTS_SUMMARY_TOP_EDGE: sAssetPrefix = "Graphics\\results summary top edge"; break; - case GRAPHIC_RESULTS_TOP_EDGE: sAssetPrefix = "Graphics\\results top edge"; break; + case GRAPHIC_EVALUATION_BACKGROUND: sAssetPrefix = "Graphics\\evaluation background"; break; + case GRAPHIC_EVALUATION_BANNER_FRAME: sAssetPrefix = "Graphics\\evaluation banner frame"; break; + case GRAPHIC_EVALUATION_BONUS_FRAME_P1: sAssetPrefix = "Graphics\\evaluation bonus frame p1"; break; + case GRAPHIC_EVALUATION_BONUS_FRAME_P2: sAssetPrefix = "Graphics\\evaluation bonus frame p2"; break; + case GRAPHIC_EVALUATION_GRADE_FRAME: sAssetPrefix = "Graphics\\evaluation grade frame 1x2"; break; + case GRAPHIC_EVALUATION_GRADES: sAssetPrefix = "Graphics\\evaluation grades 1x7"; break; + case GRAPHIC_EVALUATION_JUDGE_LABELS: sAssetPrefix = "Graphics\\evaluation judge labels 1x6"; break; + case GRAPHIC_EVALUATION_SCORE_LABELS: sAssetPrefix = "Graphics\\evaluation score labels 1x2"; break; + case GRAPHIC_EVALUATION_SUMMARY_TOP_EDGE: sAssetPrefix = "Graphics\\evaluation summary top edge"; break; + case GRAPHIC_EVALUATION_TOP_EDGE: sAssetPrefix = "Graphics\\evaluation top edge"; break; case GRAPHIC_SELECT_COURSE_INFO_FRAME: sAssetPrefix = "Graphics\\select course info frame"; break; case GRAPHIC_SELECT_COURSE_TOP_EDGE: sAssetPrefix = "Graphics\\select course top edge"; break; case GRAPHIC_SELECT_COURSE_BACKGROUND: sAssetPrefix = "Graphics\\select course background"; break; @@ -221,9 +221,9 @@ CString ThemeManager::GetPathTo( ThemeElement te ) case SOUND_MUSIC_SCROLL_MUSIC: sAssetPrefix = "Sounds\\music scroll music"; break; case SOUND_OPTION_CHANGE_COL: sAssetPrefix = "Sounds\\option change col"; break; case SOUND_OPTION_CHANGE_ROW: sAssetPrefix = "Sounds\\option change row"; break; - case SOUND_RESULTS_FLY_OFF: sAssetPrefix = "Sounds\\results fly off"; break; - case SOUND_RESULTS_SCORE_TICK: sAssetPrefix = "Sounds\\results score tick"; break; - case SOUND_RESULTS_EXTRA_STAGE: sAssetPrefix = "Sounds\\results extra stage"; break; + case SOUND_EVALUATION_FLY_OFF: sAssetPrefix = "Sounds\\evaluation fly off"; break; + case SOUND_EVALUATION_SCORE_TICK: sAssetPrefix = "Sounds\\evaluation score tick"; break; + case SOUND_EVALUATION_EXTRA_STAGE: sAssetPrefix = "Sounds\\evaluation extra stage"; break; case SOUND_SELECT_DIFFICULTY_CHANGE: sAssetPrefix = "Sounds\\select difficulty change"; break; case SOUND_SELECT_GROUP_CHANGE: sAssetPrefix = "Sounds\\select group change"; break; case SOUND_SELECT_MUSIC_SECTION_EXPAND: sAssetPrefix = "Sounds\\select music section expand"; break; diff --git a/stepmania/src/ThemeManager.h b/stepmania/src/ThemeManager.h index c2473951db..94cfe76c2b 100644 --- a/stepmania/src/ThemeManager.h +++ b/stepmania/src/ThemeManager.h @@ -57,16 +57,16 @@ enum ThemeElement { GRAPHIC_PAD_SOLO, GRAPHIC_PLAYER_OPTIONS_BACKGROUND, GRAPHIC_PLAYER_OPTIONS_TOP_EDGE, - GRAPHIC_RESULTS_BACKGROUND, - GRAPHIC_RESULTS_BANNER_FRAME, - GRAPHIC_RESULTS_BONUS_FRAME_P1, - GRAPHIC_RESULTS_BONUS_FRAME_P2, - GRAPHIC_RESULTS_GRADE_FRAME, - GRAPHIC_RESULTS_GRADES, - GRAPHIC_RESULTS_JUDGE_LABELS, - GRAPHIC_RESULTS_SCORE_LABELS, - GRAPHIC_RESULTS_SUMMARY_TOP_EDGE, - GRAPHIC_RESULTS_TOP_EDGE, + GRAPHIC_EVALUATION_BACKGROUND, + GRAPHIC_EVALUATION_BANNER_FRAME, + GRAPHIC_EVALUATION_BONUS_FRAME_P1, + GRAPHIC_EVALUATION_BONUS_FRAME_P2, + GRAPHIC_EVALUATION_GRADE_FRAME, + GRAPHIC_EVALUATION_GRADES, + GRAPHIC_EVALUATION_JUDGE_LABELS, + GRAPHIC_EVALUATION_SCORE_LABELS, + GRAPHIC_EVALUATION_SUMMARY_TOP_EDGE, + GRAPHIC_EVALUATION_TOP_EDGE, GRAPHIC_SELECT_COURSE_INFO_FRAME, GRAPHIC_SELECT_COURSE_TOP_EDGE, GRAPHIC_SELECT_COURSE_BACKGROUND, @@ -154,9 +154,9 @@ enum ThemeElement { SOUND_MUSIC_SCROLL_MUSIC, SOUND_OPTION_CHANGE_COL, SOUND_OPTION_CHANGE_ROW, - SOUND_RESULTS_FLY_OFF, - SOUND_RESULTS_SCORE_TICK, - SOUND_RESULTS_EXTRA_STAGE, + SOUND_EVALUATION_FLY_OFF, + SOUND_EVALUATION_SCORE_TICK, + SOUND_EVALUATION_EXTRA_STAGE, SOUND_SELECT_DIFFICULTY_CHANGE, SOUND_SELECT_GROUP_CHANGE, SOUND_SELECT_MUSIC_SECTION_EXPAND, @@ -194,7 +194,7 @@ public: void GetThemeNames( CStringArray& AddTo ); CString GetCurrentThemeName() { return m_sCurThemeName; } void SwitchTheme( CString sThemeName ); // return false if theme doesn't exist - void AssertThemeIsComplete( CString sThemeName ); // return false if theme doesn't exist + void AssertThemeIsComplete( CString sThemeName ); CString GetPathTo( ThemeElement te ); protected: diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 53bcaaa51b..0690cd3f1d 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -23,6 +23,7 @@ struct BPMSegment { BPMSegment() { m_fStartBeat = m_fBPM = -1; }; + BPMSegment( float s, float b ) { m_fStartBeat = s; m_fBPM = b; }; float m_fStartBeat; float m_fBPM; }; @@ -30,6 +31,7 @@ struct BPMSegment struct FreezeSegment { FreezeSegment() { m_fStartBeat = m_fFreezeSeconds = -1; }; + FreezeSegment( float s, float f ) { m_fStartBeat = s; m_fFreezeSeconds = f; }; float m_fStartBeat; float m_fFreezeSeconds; }; @@ -86,7 +88,7 @@ public: CString GetArtist() {return m_sArtist; }; CString GetCredit() {return m_sCredit; }; float GetBeatOffsetInSeconds() {return m_fOffsetInSeconds; }; - void SetBeatOffsetInSeconds(float fNewOffset) {m_fOffsetInSeconds = fNewOffset; }; + void SetBeatOffsetInSeconds(float fNewOffset) {m_fOffsetInSeconds = fNewOffset; SetChangedSinceLastSave(); }; void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) { fMaxBPM = 0; @@ -114,12 +116,13 @@ public: bool IsNew() { return GetNumTimesPlayed()==0; }; bool HasChangedSinceLastSave() { return m_bChangedSinceSave; } - void SetChangedSinceLastSave() { m_bChangedSinceSave = true; } Grade GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc ); private: + void SetChangedSinceLastSave() { m_bChangedSinceSave = true; } + CString m_sSongFilePath; CString m_sSongDir; CString m_sGroupName; @@ -140,6 +143,9 @@ private: CString m_sBackgroundMoviePath; CString m_sCDTitlePath; + void AddBPMSegment( BPMSegment seg ); + void AddFreezeSegment( FreezeSegment seg ); + CArray m_BPMSegments; // this must be sorted before gameplay CArray m_FreezeSegments; // this must be sorted before gameplay