diff --git a/stepmania/src/BPMDisplay.cpp b/stepmania/src/BPMDisplay.cpp new file mode 100644 index 0000000000..5de79e2876 --- /dev/null +++ b/stepmania/src/BPMDisplay.cpp @@ -0,0 +1,106 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: BPMDisplay.h + + Desc: A graphic displayed in the BPMDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "BPMDisplay.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" + + + +BPMDisplay::BPMDisplay() +{ + m_fCurrentBPM = m_fLowBPM = m_fHighBPM = 0; + m_CountingState = holding_down; + m_fTimeLeftInState = 0; + + m_rectFrame.SetDiffuseColor( D3DXCOLOR(0,0,0,0.3f) ); + m_rectFrame.SetZoomX( 120 ); + m_rectFrame.SetZoomY( 40 ); + + m_seqBPM.LoadFromSequenceFile( "SpriteSequences\\LED Numbers.seq" ); + m_seqBPM.SetXY( CENTER_X, SCREEN_HEIGHT - 50 ); + //m_seqBPM.SetSequence( ssprintf("999") ); + m_seqBPM.SetXY( -30, 0 ); + m_seqBPM.SetZoom( 0.7f ); + m_seqBPM.SetDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_seqBPM.SetDiffuseColorBottomEdge( D3DXCOLOR(1,0.5f,0,1) ); // orange + + m_textLabel.LoadFromFontName( "Black Wolf" ); + m_textLabel.SetXY( 54, 10 ); + m_textLabel.SetText( "BPM" ); + m_textLabel.SetDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_textLabel.SetDiffuseColorBottomEdge( D3DXCOLOR(1,0.5f,0,1) ); // orange + + //this->AddActor( &m_rectFrame ); + this->AddActor( &m_seqBPM ); + this->AddActor( &m_textLabel ); +} + + +void BPMDisplay::Update( float fDeltaTime ) +{ + ActorFrame::Update( fDeltaTime ); + + m_fTimeLeftInState -= fDeltaTime; + if( m_fTimeLeftInState < 0 ) + { + // go to next state + switch( m_CountingState ) + { + case counting_up: m_CountingState = holding_up; break; + case holding_up: m_CountingState = counting_down; break; + case counting_down: m_CountingState = holding_down; break; + case holding_down: m_CountingState = counting_up; break; + } + m_fTimeLeftInState = 1; // reset timer + } + + switch( m_CountingState ) + { + case counting_down: m_fCurrentBPM = m_fLowBPM + (m_fHighBPM-m_fLowBPM)*m_fTimeLeftInState; break; + case counting_up: m_fCurrentBPM = m_fHighBPM + (m_fLowBPM-m_fHighBPM)*m_fTimeLeftInState; break; + case holding_up: m_fCurrentBPM = m_fHighBPM; break; + case holding_down: m_fCurrentBPM = m_fLowBPM; break; + } + m_seqBPM.SetSequence( ssprintf("%03.0f", m_fCurrentBPM) ); +} + + +void BPMDisplay::SetBPMRange( float fLowBPM, float fHighBPM ) +{ + m_fLowBPM = fLowBPM; + m_fHighBPM = fHighBPM; + if( m_fCurrentBPM > m_fHighBPM ) + m_CountingState = counting_down; + else + m_CountingState = counting_up; + m_fTimeLeftInState = 1; + + if( m_fLowBPM != m_fHighBPM ) + { + m_seqBPM.BeginTweening(0.5f); + m_seqBPM.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,0,0,1) ); // red + m_seqBPM.SetTweenDiffuseColorBottomEdge( D3DXCOLOR(0.6f,0,0,1) ); // dark red + m_textLabel.BeginTweening(0.5f); + m_textLabel.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,0,0,1) ); // red + m_textLabel.SetTweenDiffuseColorBottomEdge( D3DXCOLOR(0.6f,0,0,1) ); // dark red + } + else + { + m_seqBPM.BeginTweening(0.5f); + m_seqBPM.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_seqBPM.SetTweenDiffuseColorBottomEdge( D3DXCOLOR(1,0.5f,0,1) ); // orange + m_textLabel.BeginTweening(0.5f); + m_textLabel.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_textLabel.SetTweenDiffuseColorBottomEdge( D3DXCOLOR(1,0.5f,0,1) ); // orange + } + +} \ No newline at end of file diff --git a/stepmania/src/BPMDisplay.h b/stepmania/src/BPMDisplay.h new file mode 100644 index 0000000000..404b3de9d7 --- /dev/null +++ b/stepmania/src/BPMDisplay.h @@ -0,0 +1,43 @@ +/* +----------------------------------------------------------------------------- + File: BPMDisplay.h + + Desc: A graphic displayed in the BPMDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _BPMDisplay_H_ +#define _BPMDisplay_H_ + + +#include "Sprite.h" +#include "Song.h" +#include "ActorFrame.h" +#include "SpriteSequence.h" +#include "BitmapText.h" +#include "Rectangle.h" + + +class BPMDisplay : public ActorFrame +{ +public: + BPMDisplay(); + void Update( float fDeltaTime ); + void SetBPMRange( float fLowBPM, float fHighBPM ); + +protected: + SpriteSequence m_seqBPM; + BitmapText m_textLabel; + RectangleActor m_rectFrame; + + float m_fCurrentBPM; + float m_fLowBPM, m_fHighBPM; + enum CountingState{ counting_up, holding_up, counting_down, holding_down }; + CountingState m_CountingState; + float m_fTimeLeftInState; +}; + +#endif \ No newline at end of file diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index 0dbc0979b8..0598c27b0a 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -18,21 +18,44 @@ const CString sVisDir = "Visualizations\\"; void Background::LoadFromSong( Song& song ) { - Sprite::LoadFromTexture( song.GetBackgroundPath() ); - Sprite::StretchTo( CRect(0,0,640,480) ); - Sprite::SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); + CString sBGTexturePath = song.GetBackgroundPath(); + sBGTexturePath.MakeLower(); - CStringArray sVisualizationPaths; - GetDirListing( sVisDir + "*.*", sVisualizationPaths ); - if( sVisualizationPaths.GetSize() > 0 ) // there is at least one visualization + bool bIsAMovieBackground = ( sBGTexturePath.Right(3) == "avi" || + sBGTexturePath.Right(3) == "mpg" || + sBGTexturePath.Right(3) == "mpeg" ); + + if( bIsAMovieBackground ) { - int iIndexRandom = rand() % sVisualizationPaths.GetSize(); + Sprite::LoadFromTexture( sBGTexturePath ); + Sprite::StretchTo( CRect(0,480,640,0) ); // flip + Sprite::SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0.8f,1) ); - m_sprVis.LoadFromTexture( sVisDir + sVisualizationPaths[iIndexRandom] ); - m_sprVis.StretchTo( CRect(0,0,640,480) ); -// m_sprVis.SetBlendMode( TRUE ); - //m_sprVis.SetColor( D3DXCOLOR(1,1,1,0.5f) ); + // don't load m_sprVis } + else // !bIsAMovieBackground + { + Sprite::LoadFromTexture( sBGTexturePath ); + Sprite::StretchTo( CRect(0,0,640,480) ); + Sprite::SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0.8f,1) ); + + if( GAMEINFO->m_GameOptions.m_bRandomVis ) + { + // load a random visualization + CStringArray sVisualizationPaths; + GetDirListing( sVisDir + "*.*", sVisualizationPaths ); + if( sVisualizationPaths.GetSize() > 0 ) // there is at least one visualization + { + int iIndexRandom = rand() % sVisualizationPaths.GetSize(); + + m_sprVis.LoadFromTexture( sVisDir + sVisualizationPaths[iIndexRandom] ); + m_sprVis.StretchTo( CRect(0,480,640,0) ); // flip + m_sprVis.SetBlendModeAdd(); + //m_sprVis.SetColor( D3DXCOLOR(1,1,1,0.5f) ); + } + } + } + } void Background::Update( float fDeltaTime) diff --git a/stepmania/src/Banner.cpp b/stepmania/src/Banner.cpp index 88ce16ec17..26029267c4 100644 --- a/stepmania/src/Banner.cpp +++ b/stepmania/src/Banner.cpp @@ -14,53 +14,78 @@ #include "Banner.h" +const CString TEXTURE_FALLBACK_BANNER = "Textures\\Fallback Banner.png"; + bool Banner::LoadFromSong( Song &song ) { - Sprite::LoadFromTexture( song.GetBannerPath() ); + if( song.HasBanner() ) + Sprite::LoadFromTexture( song.GetBannerPath() ); + else if( song.HasBackground() && !song.BackgroundIsAMovie() ) + Sprite::LoadFromTexture( song.GetBackgroundPath() ); + else + Sprite::LoadFromTexture( TEXTURE_FALLBACK_BANNER ); //Sprite::TurnShadowOff(); - float fSourceWidth = (float)m_pTexture->GetSourceWidth(); - float fSourceHeight = (float)m_pTexture->GetSourceHeight(); + int iSourceWidth = m_pTexture->GetSourceWidth(); + int iSourceHeight = m_pTexture->GetSourceHeight(); - // first find the correct zoom - Sprite::ScaleToCover( CRect(0, 0, - BANNER_WIDTH, - BANNER_HEIGHT ) - ); - float fFinalZoom = this->GetZoom(); - - // find which dimension is larger - bool bXDimNeedsToBeCropped = GetZoomedWidth() > BANNER_WIDTH; - - if( bXDimNeedsToBeCropped ) // crop X - { - float fPercentageToCutOff = (this->GetZoomedWidth() - BANNER_WIDTH) / this->GetZoomedWidth(); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - FRECT frectNewSrc( fPercentageToCutOffEachSide, - 0, - 1 - fPercentageToCutOffEachSide, - 1 ); - Sprite::SetCustomSrcRect( frectNewSrc ); - } - else // crop Y - { - float fPercentageToCutOff = (this->GetZoomedHeight() - BANNER_HEIGHT) / this->GetZoomedHeight(); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - FRECT frectNewSrc( 0, - fPercentageToCutOffEachSide, - 1, - 1 - fPercentageToCutOffEachSide ); - Sprite::SetCustomSrcRect( frectNewSrc ); - } - SetWidth( BANNER_WIDTH ); - SetHeight( BANNER_HEIGHT ); - SetZoom( 1 ); + if( iSourceWidth == iSourceHeight ) // this is a SSR/DWI style banner + { + float fCustomTexCoords[8] = { + 0.22f, 0.98f, // bottom left + 0.02f, 0.78f, // top left + 0.98f, 0.22f, // bottom right + 0.78f, 0.02f, // top right + }; + Sprite::SetCustomTexCoords( fCustomTexCoords ); + + SetWidth( BANNER_WIDTH ); + SetHeight( BANNER_HEIGHT ); + + } + else // this is a normal sized banner + { + + // first find the correct zoom + Sprite::ScaleToCover( CRect(0, 0, + (int)BANNER_WIDTH, + (int)BANNER_HEIGHT ) + ); + float fFinalZoom = this->GetZoom(); + + // find which dimension is larger + bool bXDimNeedsToBeCropped = GetZoomedWidth() > BANNER_WIDTH; + + if( bXDimNeedsToBeCropped ) // crop X + { + float fPercentageToCutOff = (this->GetZoomedWidth() - BANNER_WIDTH) / this->GetZoomedWidth(); + float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; + + // generate a rectangle with new texture coordinates + FRECT frectNewSrc( fPercentageToCutOffEachSide, + 0, + 1 - fPercentageToCutOffEachSide, + 1 ); + Sprite::SetCustomSrcRect( frectNewSrc ); + } + else // crop Y + { + float fPercentageToCutOff = (this->GetZoomedHeight() - BANNER_HEIGHT) / this->GetZoomedHeight(); + float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; + + // generate a rectangle with new texture coordinates + FRECT frectNewSrc( 0, + fPercentageToCutOffEachSide, + 1, + 1 - fPercentageToCutOffEachSide ); + Sprite::SetCustomSrcRect( frectNewSrc ); + } + SetWidth( BANNER_WIDTH ); + SetHeight( BANNER_HEIGHT ); + SetZoom( 1 ); + } return true; } diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index 0fa3f1bc94..6ff7c6d96e 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -57,14 +57,32 @@ bool BitmapText::LoadCharWidths( CString sWidthFilePath ) // get a rectangle for the text, considering a possible text scaling. // useful to know if some text is visible or not -float BitmapText::GetWidthInSourcePixels() +float BitmapText::GetWidestLineWidthInSourcePixels() { - float fTextWidth = 0; - - for( int i=0; i fWidestLineWidth ) + fWidestLineWidth = fLineWidth; + } + + return fWidestLineWidth; +} + + +float BitmapText::GetLineWidthInSourcePixels( int iLineNo ) +{ + CString &sText = m_sTextLines[iLineNo]; + + float fLineWidth = 0; + + for( int j=0; j m_fLineWidths; }; diff --git a/stepmania/src/GhostArrow.cpp b/stepmania/src/GhostArrow.cpp index b3db605230..7d962961b4 100644 --- a/stepmania/src/GhostArrow.cpp +++ b/stepmania/src/GhostArrow.cpp @@ -7,7 +7,7 @@ #include "GhostArrow.h" -const CString GHOST_ARROW_SPRITE = "Sprites\\Ghost Arrow.sprite"; +const CString GHOST_ARROW_TEXTURE = "Textures\\Gray Arrow 1x2.png"; const float GRAY_ARROW_TWEEN_TIME = 0.5f; @@ -17,8 +17,10 @@ const float GRAY_ARROW_TWEEN_TIME = 0.5f; GhostArrow::GhostArrow() { - LoadFromSpriteFile( GHOST_ARROW_SPRITE ); + LoadFromTexture( GHOST_ARROW_TEXTURE ); + SetState( 1 ); SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + TurnShadowOff(); } void GhostArrow::SetBeat( const float fSongBeat ) @@ -30,16 +32,15 @@ void GhostArrow::Step( StepScore score ) { switch( score ) { - case perfect: SetDiffuseColor( D3DXCOLOR(1.0f,1.0f,0.3f,1.0f) ); break; // yellow - case great: SetDiffuseColor( D3DXCOLOR(0.0f,1.0f,0.4f,1.0f) ); break; // green - case good: SetDiffuseColor( D3DXCOLOR(0.3f,0.8f,1.0f,1.0f) ); break; - case boo: SetDiffuseColor( D3DXCOLOR(0.8f,0.0f,0.6f,1.0f) ); break; + case perfect: SetDiffuseColor( D3DXCOLOR(1.0f,1.0f,0.3f,0.7f) ); break; // yellow + case great: SetDiffuseColor( D3DXCOLOR(0.0f,1.0f,0.4f,0.7f) ); break; // green + case good: SetDiffuseColor( D3DXCOLOR(0.3f,0.8f,1.0f,0.7f) ); break; + case boo: SetDiffuseColor( D3DXCOLOR(0.8f,0.0f,0.6f,0.7f) ); break; case miss: ASSERT(true); break; } - SetState( 0 ); - SetZoom( 1.2f ); + SetZoom( 1.0f ); BeginTweening( 0.3f ); - SetTweenZoom( 2.5f ); + SetTweenZoom( 1.5f ); D3DXCOLOR colorTween = GetDiffuseColor(); colorTween.a = 0; SetTweenDiffuseColor( colorTween ); diff --git a/stepmania/src/GhostArrowBright.cpp b/stepmania/src/GhostArrowBright.cpp new file mode 100644 index 0000000000..c63daf248a --- /dev/null +++ b/stepmania/src/GhostArrowBright.cpp @@ -0,0 +1,48 @@ +#include "stdafx.h" +// +// GhostArrowBright.cpp: implementation of the GhostArrowBright class. +// +////////////////////////////////////////////////////////////////////// + +#include "GhostArrowBright.h" + + +const CString GHOST_ARROW_SPRITE = "Sprites\\Ghost Arrow.sprite"; +const float GRAY_ARROW_TWEEN_TIME = 0.5f; + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +GhostArrowBright::GhostArrowBright() +{ + LoadFromSpriteFile( GHOST_ARROW_SPRITE ); + SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + TurnShadowOff(); +} + +void GhostArrowBright::SetBeat( const float fSongBeat ) +{ + //SetState( fmod(fSongBeat,1)<0.25 ? 1 : 0 ); +} + +void GhostArrowBright::Step( StepScore score ) +{ + switch( score ) + { + case perfect: SetDiffuseColor( D3DXCOLOR(1.0f,1.0f,0.3f,0.9f) ); break; // yellow + case great: SetDiffuseColor( D3DXCOLOR(0.0f,1.0f,0.4f,0.9f) ); break; // green + case good: SetDiffuseColor( D3DXCOLOR(0.3f,0.8f,1.0f,0.9f) ); break; + case boo: SetDiffuseColor( D3DXCOLOR(0.8f,0.0f,0.6f,0.9f) ); break; + case miss: ASSERT(true); break; + } + SetState( 0 ); + SetZoom( 1.2f ); + BeginTweening( 0.3f ); + SetTweenZoom( 2.5f ); + D3DXCOLOR colorTween = GetDiffuseColor(); + colorTween.a = 0; + SetTweenDiffuseColor( colorTween ); + +} diff --git a/stepmania/src/GhostArrowBright.h b/stepmania/src/GhostArrowBright.h new file mode 100644 index 0000000000..ce38735e99 --- /dev/null +++ b/stepmania/src/GhostArrowBright.h @@ -0,0 +1,33 @@ +/* +----------------------------------------------------------------------------- + File: GhostArrowBright.h + + Desc: Class used to represent a color arrow on the screen. + + Copyright (c) 2001 Ben Norstrom. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +class GhostArrowBright; + +#ifndef _GhostArrowBright_H_ +#define _GhostArrowBright_H_ + + +#include "Sprite.h" +#include "Steps.h" + + +class GhostArrowBright : public Sprite +{ +public: + GhostArrowBright(); + + void SetBeat( const float fSongBeat ); + void Step( StepScore score ); + + float m_fVisibilityCountdown; +}; + +#endif diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 646baf56a5..99df406a01 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -178,6 +178,7 @@ Player::Player( PlayerOptions po, PlayerNumber pn ) for( int c=0; c < MAX_NUM_COLUMNS; c++ ) { m_GrayArrow[c].SetRotation( m_ColumnToRotation[c] ); m_GhostArrow[c].SetRotation( m_ColumnToRotation[c] ); + m_GhostArrowBright[c].SetRotation( m_ColumnToRotation[c] ); m_HoldGhostArrow[c].SetRotation( m_ColumnToRotation[c] ); m_ColorArrow[c].SetRotation( m_ColumnToRotation[c] ); } @@ -229,8 +230,12 @@ Player::Player( PlayerOptions po, PlayerNumber pn ) m_ScoreNumber.SetSequence( " " ); - SetX( CENTER_X ); + + + // assist + m_soundAssistTick.AddSound( "Sounds\\Assist Tick.wav" ); + } @@ -417,6 +422,7 @@ void Player::SetSteps( const Steps& newSteps, bool bLoadOnlyLeftSide, bool bLoad { HoldStep &oldHoldStep = tempHoldSteps[i]; HoldStep newHoldStep = oldHoldStep; + newHoldStep.m_Step = STEP_NONE; for( int j=0; j<12; j++ ) { @@ -425,9 +431,24 @@ void Player::SetSteps( const Steps& newSteps, bool bLoadOnlyLeftSide, bool bLoad } m_HoldSteps.Add( newHoldStep ); - m_HoldStepScores.Add( HOLD_SCORE_NONE ); + m_HoldStepScores.Add( HoldStepScore() ); } + + // filter out all non-quarter notes if little is enabled + if( m_PlayerOptions.m_bLittle ) + { + for( i=0; i 0 ) { SetJudgement( miss ); - m_iCurCombo = 0; - SetCombo( 0 ); + EndCombo(); for( int i=0; iIsButtonDown( PlayerI ) ) // they're not holding the button down { - m_HoldStepScores[i] = HOLD_SCORE_NG; + m_HoldStepScores[i].m_HoldScore = HoldStepScore::HOLD_SCORE_NG; int iCol = m_StepToColumnNumber[ hs.m_Step ]; - SetHoldJudgement( iCol, HOLD_SCORE_NG ); + SetHoldJudgement( iCol, HoldStepScore::HOLD_SCORE_NG ); } } } @@ -488,11 +508,11 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference float fEndBeat = StepIndexToBeat( hs.m_iEndIndex ); if( m_fSongBeat > fEndBeat && // if this hold step is in the past - m_HoldStepScores[i] == HOLD_STEPPED_ON ) // and it doesn't yet have a score + m_HoldStepScores[i].m_HoldScore == HoldStepScore::HOLD_STEPPED_ON ) // and it doesn't yet have a score { - m_HoldStepScores[i] = HOLD_SCORE_OK; + m_HoldStepScores[i].m_HoldScore = HoldStepScore::HOLD_SCORE_OK; int iCol = m_StepToColumnNumber[ hs.m_Step ]; - SetHoldJudgement( iCol, HOLD_SCORE_OK ); + SetHoldJudgement( iCol, HoldStepScore::HOLD_SCORE_OK ); } } @@ -509,6 +529,29 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference m_frameJudgementAndCombo.Update( fDeltaTime ); } +void Player::CrossedIndex( int iIndex ) +{ + if( GAMEINFO->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK ) + { + bool bThereIsANoteThisIndex = false; + + bThereIsANoteThisIndex |= (m_OriginalStep[iIndex] != STEP_NONE); + + for( int i=0; i= 100 ) + m_GhostArrowBright[index].Step( score ); + else + m_GhostArrow[index].Step( score ); } void Player::UpdateColorArrows( float fDeltaTime ) @@ -839,6 +949,7 @@ void Player::DrawColorArrows() { HoldStep &hs = m_HoldSteps[i]; + // check if this entire hold step is on the screen if( !( iIndexFirstArrowToDraw <= hs.m_iEndIndex && hs.m_iEndIndex <= iIndexLastArrowToDraw || iIndexFirstArrowToDraw <= hs.m_iStartIndex && hs.m_iStartIndex <= iIndexLastArrowToDraw || hs.m_iStartIndex < iIndexFirstArrowToDraw && hs.m_iEndIndex > iIndexLastArrowToDraw ) ) @@ -846,19 +957,19 @@ void Player::DrawColorArrows() continue; } - HoldStepScore &score = m_HoldStepScores[i]; + HoldStepScore::HoldScore &score = m_HoldStepScores[i].m_HoldScore; int iColNum = m_StepToColumnNumber[ hs.m_Step ]; switch( score ) { - case HOLD_SCORE_OK: + case HoldStepScore::HOLD_SCORE_OK: continue; // don't draw - case HOLD_SCORE_NONE: - case HOLD_SCORE_NG: + case HoldStepScore::HOLD_SCORE_NONE: + case HoldStepScore::HOLD_SCORE_NG: m_ColorArrow[iColNum].SetGrayPartClear(); break; - case HOLD_STEPPED_ON: + case HoldStepScore::HOLD_STEPPED_ON: m_ColorArrow[iColNum].SetGrayPartFull(); break; } @@ -866,14 +977,22 @@ void Player::DrawColorArrows() // draw the gray parts for( int j=hs.m_iEndIndex; j>=hs.m_iStartIndex; j-- ) // for each arrow in this freeze { + // check if this hold step is off the the screen + if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j) + continue; // skip this arrow + + float fYOffset = GetColorArrowYOffset( j, m_fSongBeat ); - float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); float fYPos = GetColorArrowYPos( j, m_fSongBeat ); - if( score == HOLD_STEPPED_ON || score == HOLD_SCORE_OK ) - fYPos = max( fYPos, GetGrayArrowYPos() ); + if( score == HoldStepScore::HOLD_STEPPED_ON || score == HoldStepScore::HOLD_SCORE_OK ) + { + if( fYPos < GetGrayArrowYPos() ) + continue; // don't draw + } if( m_PlayerOptions.m_bReverseScroll ) fYPos = SCREEN_HEIGHT - fYPos; m_ColorArrow[iColNum].SetY( fYPos ); + float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); m_ColorArrow[iColNum].SetAlpha( fAlpha ); m_ColorArrow[iColNum].DrawGrayPart(); } @@ -881,17 +1000,24 @@ void Player::DrawColorArrows() // draw the color parts for( j=hs.m_iEndIndex; j>=hs.m_iStartIndex; j-- ) // for each arrow in this freeze { + // check if this hold step is off the the screen + if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j) + continue; // skip this arrow + float fYOffset = GetColorArrowYOffset( j, m_fSongBeat ); - float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); float fYPos = GetColorArrowYPos( j, m_fSongBeat ); m_ColorArrow[iColNum].SetY( fYPos ); - if( score == HOLD_STEPPED_ON || score == HOLD_SCORE_OK ) - fYPos = max( fYPos, GetGrayArrowYPos() ); + if( score == HoldStepScore::HOLD_STEPPED_ON || score == HoldStepScore::HOLD_SCORE_OK ) + { + if( fYPos < GetGrayArrowYPos() ) + continue; // don't draw + } if( m_PlayerOptions.m_bReverseScroll ) fYPos = SCREEN_HEIGHT - fYPos; m_ColorArrow[iColNum].SetY( fYPos ); D3DXCOLOR color( (float)(j-hs.m_iStartIndex)/(float)(hs.m_iEndIndex-hs.m_iStartIndex), 1, 0, 1 ); // color shifts from green to yellow m_ColorArrow[iColNum].SetDiffuseColor( color ); + float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); m_ColorArrow[iColNum].SetAlpha( fAlpha ); m_ColorArrow[iColNum].DrawColorPart(); } @@ -900,15 +1026,15 @@ void Player::DrawColorArrows() j = hs.m_iStartIndex; float fYOffset = GetColorArrowYOffset( j, m_fSongBeat ); - float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); float fYPos = GetColorArrowYPos( j, m_fSongBeat ); - if( score == HOLD_STEPPED_ON || score == HOLD_SCORE_OK ) + if( score == HoldStepScore::HOLD_STEPPED_ON || score == HoldStepScore::HOLD_SCORE_OK ) fYPos = max( fYPos, GetGrayArrowYPos() ); if( m_PlayerOptions.m_bReverseScroll ) fYPos = SCREEN_HEIGHT - fYPos; m_ColorArrow[iColNum].SetY( fYPos ); m_ColorArrow[iColNum].SetIndexAndBeat( i, m_fSongBeat ); D3DXCOLOR color( 0, 1, 0, 1 ); // color shifts from green to yellow m_ColorArrow[iColNum].SetDiffuseColor( color ); + float fAlpha = GetColorArrowAlphaFromYOffset( fYOffset ); m_ColorArrow[iColNum].SetAlpha( fAlpha ); m_ColorArrow[iColNum].Draw(); @@ -988,7 +1114,6 @@ float Player::GetGrayArrowYPos() - void Player::SetJudgementX( int iNewX ) { // the frame will do this for us @@ -1075,20 +1200,20 @@ void Player::SetJudgement( StepScore score ) } } -void Player::SetHoldJudgement( int iCol, HoldStepScore score ) +void Player::SetHoldJudgement( int iCol, HoldStepScore::HoldScore score ) { //RageLog( "Judgement::SetJudgement()" ); switch( score ) { - case HOLD_SCORE_NONE: m_sprHoldJudgement[iCol].SetState( 0 ); break; // freeze! - case HOLD_SCORE_OK: m_sprHoldJudgement[iCol].SetState( 7 ); break; - case HOLD_SCORE_NG: m_sprHoldJudgement[iCol].SetState( 8 ); break; + case HoldStepScore::HOLD_SCORE_NONE: m_sprHoldJudgement[iCol].SetState( 0 ); break; // freeze! + case HoldStepScore::HOLD_SCORE_OK: m_sprHoldJudgement[iCol].SetState( 7 ); break; + case HoldStepScore::HOLD_SCORE_NG: m_sprHoldJudgement[iCol].SetState( 8 ); break; } m_fHoldJudgementDisplayCountdown[iCol] = JUDGEMENT_DISPLAY_TIME; - if( score == HOLD_SCORE_NG ) { // falling down + if( score == HoldStepScore::HOLD_SCORE_NG ) { // falling down float fY = HOLD_JUDGEMENT_Y; if( m_PlayerOptions.m_bReverseScroll ) fY = SCREEN_HEIGHT - fY; m_sprHoldJudgement[iCol].SetY( fY - 10 ); @@ -1133,15 +1258,15 @@ void Player::DrawCombo() } -void Player::SetCombo( int iNewCombo ) +void Player::ContinueCombo() { + m_iCurCombo++; + // new max combo - if( iNewCombo > m_iMaxCombo ) - m_iMaxCombo = iNewCombo; + if( m_iCurCombo > m_iMaxCombo ) + m_iMaxCombo = m_iCurCombo; - m_iCurCombo = iNewCombo; - - if( iNewCombo <= 4 ) + if( m_iCurCombo <= 4 ) { m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible @@ -1151,8 +1276,8 @@ void Player::SetCombo( int iNewCombo ) m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible - m_ComboNumber.SetSequence( ssprintf("%d", iNewCombo) ); - float fNewZoom = 0.5f + iNewCombo/800.0f; + m_ComboNumber.SetSequence( ssprintf("%d", m_iCurCombo) ); + float fNewZoom = 0.5f + m_iCurCombo/800.0f; m_ComboNumber.SetZoom( fNewZoom ); m_ComboNumber.SetX( -40 - (fNewZoom-1)*30 ); m_ComboNumber.SetY( m_PlayerOptions.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET ); @@ -1160,6 +1285,14 @@ void Player::SetCombo( int iNewCombo ) //m_ComboNumber.BeginTweening( COMBO_TWEEN_TIME ); //m_ComboNumber.SetTweenZoom( 1 ); } +} + +void Player::EndCombo() +{ + m_iCurCombo = 0; + + m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible + m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible } diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index 01e428f48c..146fbaf860 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -20,9 +20,11 @@ #include "ColorArrow.h" #include "GrayArrow.h" #include "GhostArrow.h" +#include "GhostArrowBright.h" #include "HoldGhostArrow.h" #include "Player.h" #include "ActorFrame.h" +#include "SoundSet.h" @@ -38,6 +40,7 @@ public: void SetSteps( const Steps& newSteps, bool bLoadOnlyLeftSide = false, bool bLoadOnlyRightSide = false ); void SetX( float fX ); void Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference ); + void CrossedIndex( int iIndex ); void Draw(); @@ -97,6 +100,7 @@ protected: void DrawGhostArrows(); void GhostArrowStep( int iCol, StepScore score ); GhostArrow m_GhostArrow[MAX_NUM_COLUMNS]; + GhostArrowBright m_GhostArrowBright[MAX_NUM_COLUMNS]; HoldGhostArrow m_HoldGhostArrow[MAX_NUM_COLUMNS]; // holder for judgement and combo displays @@ -110,7 +114,7 @@ protected: float m_fJudgementDisplayCountdown; Sprite m_sprJudgement; - void SetHoldJudgement( int iCol, HoldStepScore score ); + void SetHoldJudgement( int iCol, HoldStepScore::HoldScore score ); float m_fHoldJudgementDisplayCountdown[MAX_NUM_COLUMNS]; Sprite m_sprHoldJudgement[MAX_NUM_COLUMNS]; @@ -118,7 +122,8 @@ protected: void SetComboX( int iX ); void UpdateCombo( float fDeltaTime ); void DrawCombo(); - void SetCombo( int iNum ); + void ContinueCombo(); + void EndCombo(); bool m_bComboVisible; Sprite m_sprCombo; SpriteSequence m_ComboNumber; @@ -144,6 +149,9 @@ private: Sprite m_sprScoreFrame; SpriteSequence m_ScoreNumber; + // assist + SoundSet m_soundAssistTick; + }; diff --git a/stepmania/src/RageInput.cpp b/stepmania/src/RageInput.cpp index 869d970529..29d80c1703 100644 --- a/stepmania/src/RageInput.cpp +++ b/stepmania/src/RageInput.cpp @@ -64,6 +64,18 @@ CString DeviceInput::GetDescription() case JOY_10: sReturn += "10"; break; case JOY_11: sReturn += "11"; break; case JOY_12: sReturn += "12"; break; + case JOY_13: sReturn += "13"; break; + case JOY_14: sReturn += "14"; break; + case JOY_15: sReturn += "15"; break; + case JOY_16: sReturn += "16"; break; + case JOY_17: sReturn += "17"; break; + case JOY_18: sReturn += "18"; break; + case JOY_19: sReturn += "19"; break; + case JOY_20: sReturn += "20"; break; + case JOY_21: sReturn += "21"; break; + case JOY_22: sReturn += "22"; break; + case JOY_23: sReturn += "23"; break; + case JOY_24: sReturn += "24"; break; } break; @@ -185,7 +197,10 @@ CString DeviceInput::GetDescription() CString DeviceInput::toString() { - return ssprintf("%d-%d", device, button ); + if( device == DEVICE_NONE ) + return ""; + else + return ssprintf("%d-%d", device, button ); } bool DeviceInput::fromString( CString s ) @@ -592,7 +607,7 @@ HRESULT RageInput::GetDeviceInputs( DeviceInputArray &listDeviceInputs ) listDeviceInputs.Add( DeviceInput(InputDevice(DEVICE_JOYSTICK1+i), JOY_DOWN) ); - for( BYTE b=0; b<10; b++ ) + for( BYTE b=0; b #include "RageUtil.h" - const int NUM_KEYBOARD_BUTTONS = 256; + const int NUM_JOYSTICKS = 4; enum InputDevice { @@ -51,9 +51,23 @@ enum JoystickButton { JOY_10, JOY_11, JOY_12, + JOY_13, + JOY_14, + JOY_15, + JOY_16, + JOY_17, + JOY_18, + JOY_19, + JOY_20, + JOY_21, + JOY_22, + JOY_23, + JOY_24, NUM_JOYSTICK_BUTTONS // leave this at the end }; +const int NUM_DEVICE_BUTTONS = max( NUM_KEYBOARD_BUTTONS, NUM_JOYSTICK_BUTTONS ); + struct DeviceInput diff --git a/stepmania/src/RageMovieTexture.cpp b/stepmania/src/RageMovieTexture.cpp index 30ec2c518c..24b2edf13e 100644 --- a/stepmania/src/RageMovieTexture.cpp +++ b/stepmania/src/RageMovieTexture.cpp @@ -48,7 +48,7 @@ CTextureRenderer::CTextureRenderer( LPUNKNOWN pUnk, HRESULT *phr ) { // Store and ARageef the texture for our use. m_pTexture = NULL; - m_bLocked = FALSE; + m_bLocked[0] = m_bLocked[1] = FALSE; *phr = S_OK; } @@ -170,7 +170,7 @@ HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample ) return E_FAIL; } - m_bLocked = TRUE; + m_bLocked[m_pTexture->m_iIndexActiveTexture] = TRUE; // Get the texture buffer & pitch pTxtBuffer = static_cast(d3dlr.pBits); @@ -222,7 +222,7 @@ HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample ) return E_FAIL; } - m_bLocked = FALSE; + m_bLocked[m_pTexture->m_iIndexActiveTexture] = FALSE; // flip active texture diff --git a/stepmania/src/RageMovieTexture.h b/stepmania/src/RageMovieTexture.h index 88480ed00c..41ec8c8af4 100644 --- a/stepmania/src/RageMovieTexture.h +++ b/stepmania/src/RageMovieTexture.h @@ -53,7 +53,7 @@ public: LONG GetVidWidth() {return m_lVidWidth;}; LONG GetVidHeight(){return m_lVidHeight;}; HRESULT SetRenderTarget( RageMovieTexture* pTexture ); - BOOL IsLocked() { return m_bLocked; }; + BOOL IsLocked(int iIndex) { return m_bLocked[iIndex]; }; protected: LONG m_lVidWidth; // Video width @@ -62,7 +62,7 @@ protected: RageMovieTexture* m_pTexture; // the video surface we will copy new frames to D3DFORMAT m_TextureFormat; // Texture format - BOOL m_bLocked; // Is the texture currently locked while we + BOOL m_bLocked[2]; // Is the texture currently locked while we // copy the movie frame to it? }; diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index 966a355bfe..0a09d3e6d8 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -36,7 +36,7 @@ RageSound::RageSound( HWND hWnd ) The most likely cause of this problem is that you do not have a sound card\n\ installed, or that you have not yet installed a driver for your sound card.\n\ Before running this program again, please verify that your sound card is\n\ -is working in other Windows applications.", "Error - Need updated video driver", MB_ICONSTOP ); +is working in other Windows applications.", "Sound error", MB_ICONSTOP ); RageError( "BASS can't initialize sound device." ); } @@ -59,6 +59,7 @@ HSAMPLE RageSound::LoadSample( const CString sFileName ) if( hSample == NULL ) RageError( ssprintf("RageSound::LoadSound: error loading %s (error code %d)", sFileName, BASS_ErrorGetCode()) ); + return hSample; } @@ -69,8 +70,12 @@ void RageSound::UnloadSample( HSAMPLE hSample ) void RageSound::PlaySample( HSAMPLE hSample ) { - if( FALSE == BASS_SamplePlay( hSample ) ) + HCHANNEL hChannel = BASS_SamplePlay( hSample ); + if( hChannel == NULL ) RageError( "There was an error playing a sound sample. Are you sure this is a valid HSAMPLE?" ); + + DWORD dwPosition = BASS_ChannelGetPosition( hChannel ); + RageLog( "First BASS_ChannelGetPosition: %d", dwPosition ); } void RageSound::StopSample( HSAMPLE hSample ) @@ -87,6 +92,7 @@ float RageSound::GetSampleLength( HSAMPLE hSample ) float RageSound::GetSamplePosition( HSAMPLE hSample ) { DWORD dwPosition = BASS_ChannelGetPosition( hSample ); + RageLog( "BASS_ChannelGetPosition: %d", dwPosition ); float fSeconds = BASS_ChannelBytes2Seconds( hSample, dwPosition ); // fSeconds += 0.05f; // fudge number. Should use a BASS_SYNC to sync the music. return fSeconds; diff --git a/stepmania/src/RageTexture.cpp b/stepmania/src/RageTexture.cpp index bc70868e1f..61d836cbe9 100644 --- a/stepmania/src/RageTexture.cpp +++ b/stepmania/src/RageTexture.cpp @@ -78,6 +78,42 @@ void RageTexture::CreateFrameRects() #include "string.h" void RageTexture::GetFrameDimensionsFromFileName( CString sPath, UINT* puFramesWide, UINT* puFramesHigh ) const { + *puFramesWide = *puFramesHigh = 1; // initialize in case we don't find dimensions in the file name + + sPath.MakeLower(); + if( sPath.Find("max300.png") != -1 ) + int kljds = 3; + + CString sDir, sFName, sExt; + splitrelpath( sPath, sDir, sFName, sExt); + + CStringArray sFileNameBits; + split( sFName, " ", sFileNameBits, false ); + + if( sFileNameBits.GetSize() < 2 ) + return; // there can't be dimensions in the file name if there's no space + + CString sDimensionsPart = sFileNameBits[ sFileNameBits.GetSize()-1 ]; // looks like "10x5" + + CStringArray sDimensionsBits; + split( sDimensionsPart, "x", sDimensionsBits, false ); + + if( sDimensionsBits.GetSize() != 2 ) + { + return; + } + else + { + if( !IsAnInt(sDimensionsBits[0]) || !IsAnInt(sDimensionsBits[1]) ) + return; + + *puFramesWide = atoi(sDimensionsBits[0]); + *puFramesHigh = atoi(sDimensionsBits[1]); + return; + } + + + /* ////////////////////////////////////////////////// // Parse m_sFilePath for the frame dimensions // @@ -94,7 +130,7 @@ void RageTexture::GetFrameDimensionsFromFileName( CString sPath, UINT* puFramesW } sDimensionsString = sDimensionsString.Left(index_of_last_period); - // chop off everything before the last space + // chop off everything before and including the last space int index_of_last_space = sDimensionsString.ReverseFind( ' ' ); if( index_of_last_space == -1 ) // this file name has space, so the dimensions tag cannot be read { @@ -118,4 +154,5 @@ void RageTexture::GetFrameDimensionsFromFileName( CString sPath, UINT* puFramesW if( *puFramesWide == 0 ) *puFramesWide = 1; if( *puFramesHigh == 0 ) *puFramesHigh = 1; + */ } \ No newline at end of file diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index b00d075191..96c339ecba 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -41,12 +41,32 @@ int roundf( double f ) return (int)((f)+0.5); } + + +bool IsAnInt( CString s ) +{ + if( s.GetLength() == 0 ) + return false; + + for( int i=0; i '9' ) + return false; + } + + return true; +} + + + //----------------------------------------------------------------------------- // Name: RageLogStart() // Desc: //----------------------------------------------------------------------------- void RageLogStart() { +#if defined(DEBUG) | defined(_DEBUG) + // delete the old log and create a new one DeleteFile( g_sLogFileName ); FILE *fp = NULL; @@ -61,6 +81,8 @@ void RageLogStart() RageLog( "Log starting %.4d-%.2d-%.2d %.2d:%.2d:%.2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond ); RageLog( "\n" ); + +#endif } @@ -141,7 +163,7 @@ CString join(CString Deliminator, CStringArray& Source) // Name: split() // Desc: //----------------------------------------------------------------------------- -void split( CString Source, CString Deliminator, CStringArray& AddIt ) +void split( CString Source, CString Deliminator, CStringArray& AddIt, bool bIgnoreEmpty ) { CString newCString; CString tmpCString; @@ -156,15 +178,19 @@ void split( CString Source, CString Deliminator, CStringArray& AddIt ) pos = newCString.Find(Deliminator, pos1); if ( pos != -1 ) { CString AddCString = newCString.Left(pos); - if (!AddCString.IsEmpty()) - AddIt.Add(AddCString); + if( newCString.IsEmpty() && bIgnoreEmpty ) + ; // do nothing + else + AddIt.Add(AddCString); tmpCString = newCString.Mid(pos + Deliminator.GetLength()); newCString = tmpCString; } } while ( pos != -1 ); - if (!newCString.IsEmpty()) + if( newCString.IsEmpty() && bIgnoreEmpty ) + ; // do nothing + else AddIt.Add(newCString); } @@ -173,13 +199,14 @@ void split( CString Source, CString Deliminator, CStringArray& AddIt ) // Name: splitpath() // Desc: //----------------------------------------------------------------------------- -void splitpath (BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, CString& FName, CString& Ext) +void splitpath( BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, CString& FName, CString& Ext ) { int nSecond; // Look for a UNC Name! - if (Path.Left(2) == "\\\\") { + if (Path.Left(2) == "\\\\") + { int nFirst = Path.Find("\\",3); nSecond = Path.Find("\\",nFirst + 1); if (nSecond == -1) { @@ -191,10 +218,16 @@ void splitpath (BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, else if (nSecond > nFirst) Drive = Path.Left(nSecond); } - else { // Look for normal Drive Structure + else if (Path.Mid(1,1) == ":" ) // normal Drive Structure + { nSecond = 2; Drive = Path.Left(2); } + else // no UNC or drive letter + { + nSecond = -1; + } + if (UsingDirsOnly) { Dir = Path.Right((Path.GetLength() - nSecond) - 1); @@ -232,6 +265,62 @@ void splitpath (BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, } } +//----------------------------------------------------------------------------- +// Name: splitpath() +// Desc: +//----------------------------------------------------------------------------- +void splitrelpath( CString Path, CString& Dir, CString& FName, CString& Ext ) +{ + // need to split on both forward slashes and back slashes + CStringArray sPathBits; + + CStringArray sBackShashPathBits; + split( Path, "\\", sBackShashPathBits, true ); + + for( int i=0; i 1 ) // file has extension and possibly multiple periods + { + Ext = sFNameAndExtBits[ sFNameAndExtBits.GetSize()-1 ]; + + // subtract the Ext and last period from FNameAndExt + FName = sFNameAndExt.Left( sFNameAndExt.GetLength()-Ext.GetLength()-1 ); + } +} + + void GetDirListing( CString sPath, CStringArray &AddTo, BOOL bOnlyDirs ) { WIN32_FIND_DATA fd; @@ -241,8 +330,13 @@ void GetDirListing( CString sPath, CStringArray &AddTo, BOOL bOnlyDirs ) { do { - if( !bOnlyDirs || fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if( bOnlyDirs && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { + ; // do nothing + } + else + { + // add it CString sDirName( fd.cFileName ); if( sDirName != "." && sDirName != ".." ) AddTo.Add( sDirName ); diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index ce7b7b994f..af22f5ca37 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -41,10 +41,12 @@ //----------------------------------------------------------------------------- // Simple function for generating random numbers -FLOAT randomf( FLOAT low=-1.0f, FLOAT high=1.0f ); +float randomf( float low=-1.0f, float high=1.0f ); int roundf( FLOAT f ); int roundf( double f ); +bool IsAnInt( CString s ); + CString ssprintf( LPCTSTR fmt, ...); CString vssprintf( LPCTSTR fmt, va_list argList ); @@ -63,6 +65,10 @@ CString vssprintf( LPCTSTR fmt, va_list argList ); */ void splitpath(BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, CString& FName, CString& Ext); + +void splitrelpath( CString Path, CString& Dir, CString& FName, CString& Ext ); + + /* @FUNCTION: Splits a CString into an CStringArray according the Deliminator. NOTE: Supports UNC path names. @@ -70,7 +76,7 @@ void splitpath(BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, C @PARAM2: Deliminator. @PARAM3: (Referenced) CStringArray to Add to. */ -void split(CString Source, CString Deliminator, CStringArray& AddIt ); +void split(CString Source, CString Deliminator, CStringArray& AddIt, bool bIgnoreEmpty = true ); /* @FUNCTION: Joins a CStringArray to create a CString according the Deliminator. diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 6c4e400b26..284f44000c 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -20,6 +20,10 @@ #include +const CString TEXTURE_FALLBACK_BANNER = "Textures\\Fallback Banner.png"; +const CString TEXTURE_FALLBACK_BACKGROUND = "Textures\\Fallback Background.png"; + + int CompareBPMSegments(const void *arg1, const void *arg2) { @@ -43,6 +47,28 @@ void SortBPMSegmentsArray( CArray &arrayBPMSegments ) qsort( arrayBPMSegments.GetData(), arrayBPMSegments.GetSize(), sizeof(BPMSegment), CompareBPMSegments ); } +int CompareFreezeSegments(const void *arg1, const void *arg2) +{ + // arg1 and arg2 are of type Step** + FreezeSegment* seg1 = (FreezeSegment*)arg1; + FreezeSegment* seg2 = (FreezeSegment*)arg2; + + float score1 = seg1->m_fStartBeat; + float score2 = seg2->m_fStartBeat; + + if( score1 == score2 ) + return 0; + else if( score1 < score2 ) + return -1; + else + return 1; +} + +void SortFreezeSegmentsArray( CArray &arrayFreezeSegments ) +{ + qsort( arrayFreezeSegments.GetData(), arrayFreezeSegments.GetSize(), sizeof(FreezeSegment), CompareFreezeSegments ); +} + ////////////////////////////// // Song @@ -50,8 +76,9 @@ void SortBPMSegmentsArray( CArray &arrayBPMSegments ) Song::Song() { m_bChangedSinceSave = false; -// m_fBPM = 0; m_fOffsetInSeconds = 0; + m_iMaxCombo = m_iTopScore = m_iNumTimesPlayed = 0; + m_bHasBeenLoadedBefore = false; } @@ -59,24 +86,69 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl { fElapsedTime += m_fOffsetInSeconds; - for( int i=0; i fSecondsInThisSegment ) + { + // this BPMSegement is not the current segment fElapsedTime -= fSecondsInThisSegment; - else { - fBeatOut = fStartBeatThisSegment + fElapsedTime*fBPS; + } + else + { + // this BPMSegment IS the current segment + + float fBeatEstimate = fStartBeatThisSegment + fElapsedTime*fBPS; + + for( int j=0; j 0 ) + if( iNumDWIFiles > 1 ) { - // Load the Song info from the first BMS file. Silly BMS duplicates the song info in every - // file, so this method assumes that the song info is identical for every BMS file in - // the directory. - LoadSongInfoFromBMSFile( sDir + arrayBMSFileNames.GetAt(0) ); - for( int i=0; i 0 ) + { + LoadSongInfoFromBMSDir( sDir ); } - else if( iNumDWIFiles > 0 ) - RageError( ssprintf("Found more than one DWI file in '%s'. Which should I use?", sDir) ); else + { RageError( ssprintf("Couldn't find any BMS or MSD files in '%s'", sDir) ); + } return TRUE; } -bool Song::LoadSongInfoFromBMSFile( CString sPath ) + + +bool Song::LoadSongInfoFromBMSDir( CString sDir ) { - RageLog( "Song::LoadFromBMSFile(%s)", sPath ); + RageLog( "Song::LoadSongInfoFromBMSDir(%s)", sDir ); - if( sPath == "Songs\\saints\\saint_4basic.bms" ) - int kdgjf = 0; + // make sure there is a trailing '\\' at the end of sDir + if( sDir.Right(1) != "\\" ) + sDir += "\\"; - BmsFile bms( sPath ); + // save song dir + m_sSongDir = sDir; + + // get group name + CStringArray sDirectoryParts; + split( m_sSongDir, "\\", sDirectoryParts, true ); + for( int p=0; p dwLargestFileSoFar ) // we have a new leader! { dwLargestFileSoFar = this_size; - sLargestFileNameSoFar = arrayPossibleBackgrounds[i]; + sLargestFileSoFar = m_sSongDir + arrayPossibleBackgrounds[i]; } } - if( sLargestFileNameSoFar != "" ) // we found a match - m_sBackground = sLargestFileNameSoFar; + if( sLargestFileSoFar != "" ) // we found a match + m_sBackgroundPath = sLargestFileSoFar; else - RageError( ssprintf("Background could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) ); + m_sBackgroundPath = ""; + // RageError( ssprintf("Background could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) ); } } -/* - D3DXIMAGE_INFO ddii; - - if( FAILED( hr = D3DXGetImageInfoFromFile(m_sFilePath,&ddii) ) ) { - RageErrorHr( ssprintf("D3DXGetImageInfoFromFile() failed for file '%s'.", m_sFilePath), hr ); - } -*/ void Song::GetStepsThatMatchGameMode( GameMode gm, CArray& arrayAddTo ) @@ -531,4 +661,5 @@ void Song::GetNumFeet( GameMode gm, int& iDiffEasyOut, int& iDiffMediumOut, int& break; } } -} \ No newline at end of file +} + diff --git a/stepmania/src/Sprite.cpp b/stepmania/src/Sprite.cpp index 04ad5ad9b8..6a3b94fccd 100644 --- a/stepmania/src/Sprite.cpp +++ b/stepmania/src/Sprite.cpp @@ -32,22 +32,25 @@ void Sprite::Init() m_uCurState = 0; m_bIsAnimating = TRUE; m_fSecsIntoState = 0.0; - m_bUsingCustomTexCoordRect = FALSE ; + m_bUsingCustomTexCoords = false; m_Effect = no_effect ; - m_fPercentBetweenColors = 0.0f ; - m_bTweeningTowardEndColor = TRUE ; - m_fDeltaPercentPerSecond = 1.0 ; - m_fWagRadians = 0.2f ; - m_fWagPeriod = 2.0f ; - m_fWagTimer = 0.0f ; - m_fSpinSpeed = 2.0f ; - m_fVibrationDistance = 5.0f ; + m_fPercentBetweenColors = 0.0f; + m_bTweeningTowardEndColor = true; + m_fDeltaPercentPerSecond = 1.0f; + m_fWagRadians = 0.2f; + m_fWagPeriod = 2.0f; + m_fWagTimer = 0.0f; + m_fSpinSpeed = 2.0f; + m_fVibrationDistance = 5.0f; m_bVisibleThisFrame = FALSE; if( GAMEINFO ) m_bHasShadow = GAMEINFO->m_GameOptions.m_bShadows; else m_bHasShadow = true; + + + m_bBlendAdd = false; } Sprite::~Sprite() @@ -239,15 +242,6 @@ void Sprite::Draw() if( m_pTexture != NULL ) { - FRECT* pTexCoordRect; // the texture coordinates of the frame we're going to use - if( m_bUsingCustomTexCoordRect ) { - pTexCoordRect = &m_CustomTexCoordRect; - } else { - UINT uFrameNo = m_uFrame[m_uCurState]; - pTexCoordRect = m_pTexture->GetTextureCoordRect( uFrameNo ); - } - - D3DXCOLOR colorDiffuse[4]; for(int i=0; i<4; i++) colorDiffuse[i] = m_colorDiffuse[i]; @@ -302,10 +296,26 @@ void Sprite::Draw() v[2].p = D3DXVECTOR3( fHalfSizeX, fHalfSizeY, 0 ); // bottom right v[3].p = D3DXVECTOR3( fHalfSizeX, -fHalfSizeY, 0 ); // top right - v[0].tu = pTexCoordRect->left; v[0].tv = pTexCoordRect->bottom; // bottom left - v[1].tu = pTexCoordRect->left; v[1].tv = pTexCoordRect->top; // top left - v[2].tu = pTexCoordRect->right; v[2].tv = pTexCoordRect->bottom; // bottom right - v[3].tu = pTexCoordRect->right; v[3].tv = pTexCoordRect->top; // top right + + if( m_bUsingCustomTexCoords ) + { + v[0].tu = m_CustomTexCoords[0]; v[0].tv = m_CustomTexCoords[1]; // bottom left + v[1].tu = m_CustomTexCoords[2]; v[1].tv = m_CustomTexCoords[3]; // top left + v[2].tu = m_CustomTexCoords[4]; v[2].tv = m_CustomTexCoords[5]; // bottom right + v[3].tu = m_CustomTexCoords[6]; v[3].tv = m_CustomTexCoords[7]; // top right + } + else + { + UINT uFrameNo = m_uFrame[m_uCurState]; + FRECT* pTexCoordRect = m_pTexture->GetTextureCoordRect( uFrameNo ); + + v[0].tu = pTexCoordRect->left; v[0].tv = pTexCoordRect->bottom; // bottom left + v[1].tu = pTexCoordRect->left; v[1].tv = pTexCoordRect->top; // top left + v[2].tu = pTexCoordRect->right; v[2].tv = pTexCoordRect->bottom; // bottom right + v[3].tu = pTexCoordRect->right; v[3].tv = pTexCoordRect->top; // top right + } + + pVB->Unlock(); @@ -317,52 +327,52 @@ void Sprite::Draw() pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); //pd3dDevice->SetRenderState( D3DRS_SRCBLEND, bBlendAdd ? D3DBLEND_ONE : D3DBLEND_SRCALPHA ); //pd3dDevice->SetRenderState( D3DRS_DESTBLEND, bBlendAdd ? D3DBLEND_ONE : D3DBLEND_INVSRCALPHA ); - pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); - pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + pd3dDevice->SetRenderState( D3DRS_SRCBLEND, m_bBlendAdd ? D3DBLEND_ONE : D3DBLEND_SRCALPHA ); + pd3dDevice->SetRenderState( D3DRS_DESTBLEND, m_bBlendAdd ? D3DBLEND_ONE : D3DBLEND_INVSRCALPHA ); pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX ); pd3dDevice->SetStreamSource( 0, pVB, sizeof(CUSTOMVERTEX) ); - ////////////////////// - // render the shadow - ////////////////////// - if( m_bHasShadow ) - { - D3DXMATRIX matOriginalWorld, matNewWorld, matTemp; - pd3dDevice->GetTransform( D3DTS_WORLD, &matOriginalWorld ); // save the original world matrix - matNewWorld = matOriginalWorld; - - D3DXMatrixTranslation( &matTemp, 5, 5, 0 ); // shift by 5 units - matNewWorld = matTemp * matNewWorld; - pd3dDevice->SetTransform( D3DTS_WORLD, &matNewWorld ); // transform to local coordinates - - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - v[0].color = v[1].color = v[2].color = v[3].color = D3DXCOLOR(0,0,0,0.5f*colorDiffuse[0].a); // semi-transparent black - - pVB->Unlock(); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); - - pd3dDevice->SetTransform( D3DTS_WORLD, &matOriginalWorld ); // restore the original world matrix - - } - - - ////////////////////// - // render the diffuse pass - ////////////////////// if( colorDiffuse[0].a != 0 ) { + ////////////////////// + // render the shadow + ////////////////////// + if( m_bHasShadow ) + { + D3DXMATRIX matOriginalWorld, matNewWorld, matTemp; + pd3dDevice->GetTransform( D3DTS_WORLD, &matOriginalWorld ); // save the original world matrix + matNewWorld = matOriginalWorld; + + D3DXMatrixTranslation( &matTemp, 5, 5, 0 ); // shift by 5 units + matNewWorld = matTemp * matNewWorld; + pd3dDevice->SetTransform( D3DTS_WORLD, &matNewWorld ); // transform to local coordinates + + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + v[0].color = v[1].color = v[2].color = v[3].color = D3DXCOLOR(0,0,0,0.5f*colorDiffuse[0].a); // semi-transparent black + + pVB->Unlock(); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + + pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); + + pd3dDevice->SetTransform( D3DTS_WORLD, &matOriginalWorld ); // restore the original world matrix + + } + + + ////////////////////// + // render the diffuse pass + ////////////////////// pVB->Lock( 0, 0, (BYTE**)&v, 0 ); v[0].color = colorDiffuse[2]; // bottom left @@ -422,10 +432,20 @@ void Sprite::SetState( UINT uNewState ) m_fSecsIntoState = 0.0; } -void Sprite::SetCustomSrcRect( FRECT new_texcoord_frect ) +void Sprite::SetCustomSrcRect( FRECT new_texcoord_frect ) { - m_bUsingCustomTexCoordRect = true; - m_CustomTexCoordRect = new_texcoord_frect; + m_bUsingCustomTexCoords = true; + m_CustomTexCoords[0] = new_texcoord_frect.left; m_CustomTexCoords[1] = new_texcoord_frect.bottom; // bottom left + m_CustomTexCoords[2] = new_texcoord_frect.left; m_CustomTexCoords[3] = new_texcoord_frect.top; // top left + m_CustomTexCoords[4] = new_texcoord_frect.right; m_CustomTexCoords[5] = new_texcoord_frect.bottom; // bottom right + m_CustomTexCoords[6] = new_texcoord_frect.right; m_CustomTexCoords[7] = new_texcoord_frect.top; // top right + } +void Sprite::SetCustomTexCoords( float fTexCoords[8] ) // order: bottom left, top left, bottom right, top right +{ + m_bUsingCustomTexCoords = true; + for( int i=0; i<8; i++ ) + m_CustomTexCoords[i] = fTexCoords[i]; +} diff --git a/stepmania/src/Sprite.h b/stepmania/src/Sprite.h index 38bb2366f1..bd948c1cee 100644 --- a/stepmania/src/Sprite.h +++ b/stepmania/src/Sprite.h @@ -44,10 +44,13 @@ public: void SetCustomSrcRect( FRECT new_texcoord_frect ); // for cropping + void SetCustomTexCoords( float fTexCoords[8] ); void TurnShadowOn() { m_bHasShadow = true; }; void TurnShadowOff() { m_bHasShadow = false; }; + void SetBlendModeAdd() { m_bBlendAdd = true; }; + void SetBlendModeNormal() { m_bBlendAdd = false; }; protected: void Init(); @@ -65,10 +68,13 @@ protected: bool m_bIsAnimating; float m_fSecsIntoState; // number of seconds that have elapsed since we switched to this frame - bool m_bUsingCustomTexCoordRect; - FRECT m_CustomTexCoordRect; + bool m_bUsingCustomTexCoords; + //FRECT m_CustomTexCoordRect; + float m_CustomTexCoords[8]; // (x,y) * 4 bool m_bHasShadow; + + bool m_bBlendAdd; }; diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 81556c6efb..11a02cb41d 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -25,6 +25,7 @@ #include "WindowSandbox.h" #include "WindowLoading.h" +#include "WindowResults.h" #include "WindowTitleMenu.h" #include @@ -89,7 +90,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) RageError( "StepMania is already running!" ); } - if( !DoesFileExist("Songs") ) + if( !DoesFileExist("Textures") ) { // change dir to path of the execuctable TCHAR szFullAppPath[MAX_PATH]; @@ -174,7 +175,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) Update(); Render(); //if( !g_bFullscreen ) - ::Sleep(16); // give some time for the movie + ::Sleep(11); // give some time for the movie decoding thread } } // end while( WM_QUIT != msg.message ) @@ -311,17 +312,18 @@ HRESULT CreateObjects( HWND hWnd ) WM = new WindowManager; // throw something up on the screen while the game resources are loading + // super hack! Why do we crash unless we have rendered one frame before drawing anything? + Render(); + ShowFrame(); WM->SetNewWindow( new WindowLoading ); Render(); ShowFrame(); - // this stuff takes a long time... SOUND = new RageSound( hWnd ); MUSIC = new RageMusic; INPUT = new RageInput( hWnd ); GAMEINFO= new GameInfo; - GAMEINFO->InitSongArrayFromDisk(); BringWindowToTop( hWnd ); SetForegroundWindow( hWnd ); @@ -422,7 +424,7 @@ HRESULT InvalidateObjects() //----------------------------------------------------------------------------- void Update() { - FLOAT fDeltaTime = DXUtil_Timer( TIMER_GETELAPSEDTIME ); + float fDeltaTime = DXUtil_Timer( TIMER_GETELAPSEDTIME ); // This was a hack to fix timing issues with the old WindowSelectSong // diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 7daf72a24e..fdbfe51adf 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -176,6 +176,14 @@ SOURCE=.\Window.h # End Source File # Begin Source File +SOURCE=.\WindowCaution.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowCaution.h +# End Source File +# Begin Source File + SOURCE=.\WindowConfigurePads.cpp # End Source File # Begin Source File @@ -356,6 +364,14 @@ SOURCE=.\BlurredTitle.h # End Source File # Begin Source File +SOURCE=.\BPMDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\BPMDisplay.h +# End Source File +# Begin Source File + SOURCE=.\ColorArrow.cpp # End Source File # Begin Source File @@ -380,6 +396,14 @@ SOURCE=.\GhostArrow.h # End Source File # Begin Source File +SOURCE=.\GhostArrowBright.cpp +# End Source File +# Begin Source File + +SOURCE=.\GhostArrowBright.h +# End Source File +# Begin Source File + SOURCE=.\GrayArrow.cpp # End Source File # Begin Source File @@ -568,6 +592,14 @@ SOURCE=.\TransitionFadeWipe.h # End Source File # Begin Source File +SOURCE=.\TransitionFadeWipeWithLogo.cpp +# End Source File +# Begin Source File + +SOURCE=.\TransitionFadeWipeWithLogo.h +# End Source File +# Begin Source File + SOURCE=.\TransitionRectWipe.cpp # End Source File # Begin Source File diff --git a/stepmania/src/Transition.h b/stepmania/src/Transition.h index 484a607884..fe7128039f 100644 --- a/stepmania/src/Transition.h +++ b/stepmania/src/Transition.h @@ -20,7 +20,7 @@ #include "WindowManager.h" -#define DEFAULT_TRANSITION_TIME 1.0f +#define DEFAULT_TRANSITION_TIME 0.75f class Transition @@ -45,7 +45,7 @@ public: bool IsClosed() { return m_TransitionState == closed; }; bool IsClosing() { return m_TransitionState == closing_right || m_TransitionState == closing_left; }; - void SetTransitionTime( FLOAT fNewTransitionTime ) { m_fTransitionTime = fNewTransitionTime; }; + void SetTransitionTime( float fNewTransitionTime ) { m_fTransitionTime = fNewTransitionTime; }; void SetColor( D3DXCOLOR new_color ) { m_Color = new_color; }; void SetCloseWipingRightSound( CString sSoundPath ); diff --git a/stepmania/src/TransitionFadeWipe.cpp b/stepmania/src/TransitionFadeWipe.cpp index 46b53084f2..e467e24840 100644 --- a/stepmania/src/TransitionFadeWipe.cpp +++ b/stepmania/src/TransitionFadeWipe.cpp @@ -23,7 +23,8 @@ const float FADE_RECT_WIDTH = SCREEN_WIDTH/2; TransitionFadeWipe::TransitionFadeWipe() { - + m_sprLogo.LoadFromTexture( "Textures\\Logo dots.png" ); + m_sprLogo.SetXY( CENTER_X, CENTER_Y ); } TransitionFadeWipe::~TransitionFadeWipe() @@ -70,6 +71,12 @@ void TransitionFadeWipe::Draw() D3DXCOLOR(0,0,0,1), // down left D3DXCOLOR(0,0,0,0) // down right ); + + bool bIsOpening = m_TransitionState == opening_left || m_TransitionState == opening_right; + float fLogoAlpha = bIsOpening ? (1-fPercentComplete)*3-2 : fPercentComplete*3-2; + m_sprLogo.SetDiffuseColor( D3DXCOLOR(1,1,1,fLogoAlpha) ); + m_sprLogo.Draw(); + } diff --git a/stepmania/src/TransitionFadeWipe.h b/stepmania/src/TransitionFadeWipe.h index a4f8d4436c..c9e71254cc 100644 --- a/stepmania/src/TransitionFadeWipe.h +++ b/stepmania/src/TransitionFadeWipe.h @@ -15,6 +15,7 @@ #include "Transition.h" #include "RageScreen.h" #include "RageSound.h" +#include "Sprite.h" class TransitionFadeWipe : public Transition @@ -24,6 +25,9 @@ public: ~TransitionFadeWipe(); void Draw(); + +protected: + Sprite m_sprLogo; }; diff --git a/stepmania/src/resource.h b/stepmania/src/resource.h index 07b416b66d..f003206b9a 100644 --- a/stepmania/src/resource.h +++ b/stepmania/src/resource.h @@ -14,7 +14,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_RESOURCE_VALUE 110 #define _APS_NEXT_COMMAND_VALUE 40009 #define _APS_NEXT_CONTROL_VALUE 1006 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 20817de944..31b7115147 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -19,9 +19,55 @@ class Steps; // why is this needed? enum GameMode; // why is this needed? -struct BPMSegment{ - BPMSegment() { m_fStartBeat = m_fBPM = m_fFreezeSeconds = 0; }; - float m_fStartBeat, m_fBPM, m_fFreezeSeconds; + +struct Grade +{ + Grade() { m_GradeType = GRADE_NONE; }; + CString ToString() + { + switch( m_GradeType ) + { + case GRADE_AAA: return "AAA"; + case GRADE_AA: return "AA"; + case GRADE_A: return "A"; + case GRADE_B: return "B"; + case GRADE_C: return "C"; + case GRADE_D: return "D"; + case GRADE_E: return "E"; + case GRADE_NONE: return "N"; + default: return "N"; + } + }; + void FromString( CString sGradeString ) + { + sGradeString.MakeUpper(); + if ( sGradeString == "AAA" ) m_GradeType = GRADE_AAA; + else if( sGradeString == "AA" ) m_GradeType = GRADE_AA; + else if( sGradeString == "A" ) m_GradeType = GRADE_A; + else if( sGradeString == "B" ) m_GradeType = GRADE_B; + else if( sGradeString == "C" ) m_GradeType = GRADE_C; + else if( sGradeString == "D" ) m_GradeType = GRADE_D; + else if( sGradeString == "E" ) m_GradeType = GRADE_E; + else if( sGradeString == "N" ) m_GradeType = GRADE_NONE; + else m_GradeType = GRADE_NONE; + } + + enum GradeType { GRADE_NONE=0, GRADE_E, GRADE_D, GRADE_C, GRADE_B, GRADE_A, GRADE_AA, GRADE_AAA }; + GradeType m_GradeType; +}; + +struct BPMSegment +{ + BPMSegment() { m_fStartBeat = m_fBPM = -1; }; + float m_fStartBeat; + float m_fBPM; +}; + +struct FreezeSegment +{ + FreezeSegment() { m_fStartBeat = m_fFreezeSeconds = -1; }; + float m_fStartBeat; + float m_fFreezeSeconds; }; @@ -31,32 +77,27 @@ public: Song(); bool LoadFromSongDir( CString sDir ); - - bool IsUsingMovieBG() - { - CString sBGFile = m_sBackground; - sBGFile.MakeLower(); - return sBGFile.Right(3) == "avi" || - sBGFile.Right(3) == "mpg"; - }; - -private: - bool LoadSongInfoFromBMSFile( CString sPath ); bool LoadSongInfoFromDWIFile( CString sPath ); + bool LoadSongInfoFromBMSDir( CString sDir ); +private: void TidyUpData(); public: - CString GetSongFilePath() {return m_sSongDir + m_sSongFile; }; + CString GetSongFilePath() {return m_sSongFilePath; }; CString GetSongFileDir() {return m_sSongDir; }; - CString GetMusicPath() {return m_sSongDir + m_sMusic; }; - CString GetBannerPath() {return m_sSongDir + m_sBanner; }; - CString GetBackgroundPath() {return m_sSongDir + m_sBackground; }; -// Steps& GetStepsAt( int iIndex ) {return arraySteps[iIndex]; }; + CString GetGroupName() {return m_sGroupName; }; + CString GetMusicPath() {return m_sMusicPath; }; + CString GetBannerPath() {return m_sBannerPath; }; + CString GetBackgroundPath() {return m_sBackgroundPath; }; + bool BackgroundIsAMovie() {return m_sBackgroundPath.Right(3) == "avi" || + m_sBackgroundPath.Right(3) == "mpg" || + m_sBackgroundPath.Right(4) == "mpeg"; }; - bool HasMusic() {return m_sMusic != "" && DoesFileExist(GetMusicPath()); }; - bool HasBanner() {return m_sBanner != "" && DoesFileExist(GetBannerPath()); }; - bool HasBackground() {return m_sBackground != "" && DoesFileExist(GetBackgroundPath()); }; + + bool HasMusic() {return m_sMusicPath != "" && DoesFileExist(GetMusicPath()); }; + bool HasBanner() {return m_sBannerPath != "" && DoesFileExist(GetBannerPath()); }; + bool HasBackground() {return m_sBackgroundPath != "" && DoesFileExist(GetBackgroundPath()); }; CString GetTitle() {return m_sTitle; }; @@ -64,45 +105,33 @@ public: CString GetCreator() {return m_sCreator; }; float GetBeatOffsetInSeconds() {return m_fOffsetInSeconds; }; void SetBeatOffsetInSeconds(float fNewOffset) {m_fOffsetInSeconds = fNewOffset; }; - void GetMinMaxBPM( int &iMinBPM, int &iMaxBPM ) + void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) { - iMaxBPM = 0; - iMinBPM = 100000; // inf - for( int i=0; i iMaxBPM ) - iMaxBPM = (int)m_BPMSegments[i].m_fBPM; - if( m_BPMSegments[i].m_fBPM < iMinBPM ) - iMinBPM = (int)m_BPMSegments[i].m_fBPM; + fMaxBPM = 0; + fMinBPM = 100000; // inf + for( int i=0; i fSongBeat || i==m_BPMSegments.GetSize()-1 ) - break; - } - return m_BPMSegments[i].m_fBPM; - }; - void SetBPM( float fNewBPM, float fSongBeat ) - { - for( int i=0; i fSongBeat || i==m_BPMSegments.GetSize()-1 ) - break; - } - m_BPMSegments[i].m_fBPM = fNewBPM; - }; - void GetStepsThatMatchGameMode( GameMode gm, CArray& arrayAddTo ); void GetNumFeet( GameMode gm, int& iDiffEasy, int& iDiffMedium, int& iDiffHard ); public: + // Song statistics: + int m_iMaxCombo, m_iTopScore, m_iNumTimesPlayed; + bool m_bHasBeenLoadedBefore; + Grade m_TopGrade; private: - CString m_sSongFile; + CString m_sSongFilePath; CString m_sSongDir; + CString m_sGroupName; bool m_bChangedSinceSave; CString m_sTitle; @@ -111,11 +140,12 @@ private: // float m_fBPM; float m_fOffsetInSeconds; - CString m_sMusic; - CString m_sBanner; - CString m_sBackground; + CString m_sMusicPath; + CString m_sBannerPath; + CString m_sBackgroundPath; CArray m_BPMSegments; // this must be sorted before dancing + CArray m_FreezeSegments; // this must be sorted before dancing public: CArray arraySteps;