From 0add9e0bb36e27f47306990cc5dd6ca6019a5cb8 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Wed, 16 Jan 2002 10:01:32 +0000 Subject: [PATCH] checkin of v1.50 --- stepmania/Utils/Bitmap Font Builder.exe | Bin 139264 -> 0 bytes stepmania/src/Actor.cpp | 261 ++++++----- stepmania/src/Actor.h | 136 ++++-- stepmania/src/ActorFrame.cpp | 102 +---- stepmania/src/ActorFrame.h | 65 +-- stepmania/src/BPMDisplay.cpp | 33 +- stepmania/src/BPMDisplay.h | 3 +- stepmania/src/Background.cpp | 71 --- stepmania/src/Background.h | 35 -- stepmania/src/Banner.cpp | 7 +- stepmania/src/BitmapText.cpp | 411 ++++++++++++++--- stepmania/src/BitmapText.h | 12 +- stepmania/src/DifficultyIcon.cpp | 18 + stepmania/src/DifficultyIcon.h | 62 +++ stepmania/src/FootMeter.cpp | 18 + stepmania/src/FootMeter.h | 72 +++ stepmania/src/GhostArrow.cpp | 5 +- stepmania/src/GhostArrowBright.cpp | 4 +- stepmania/src/Grade.cpp | 21 + stepmania/src/Grade.h | 61 +++ stepmania/src/GradeDisplay.cpp | 21 + stepmania/src/GradeDisplay.h | 54 +++ stepmania/src/GrayArrow.cpp | 5 +- stepmania/src/HoldGhostArrow.cpp | 4 +- stepmania/src/MusicSortDisplay.cpp | 58 +++ stepmania/src/MusicSortDisplay.h | 35 ++ stepmania/src/MusicStatusDisplay.cpp | 21 + stepmania/src/MusicStatusDisplay.h | 103 +++++ stepmania/src/MusicWheel.cpp | 574 ++++++++++++++++++++++++ stepmania/src/MusicWheel.h | 170 +++++++ stepmania/src/Player.cpp | 71 ++- stepmania/src/Player.h | 14 +- stepmania/src/RageInput.cpp | 18 +- stepmania/src/RageMovieTexture.cpp | 2 +- stepmania/src/RageSound.cpp | 106 ----- stepmania/src/RageSound.h | 19 +- stepmania/src/RageTexture.cpp | 3 - stepmania/src/RageTexture.h | 10 +- stepmania/src/RageTextureManager.cpp | 19 +- stepmania/src/RageTextureManager.h | 3 +- stepmania/src/RageUtil.cpp | 23 +- stepmania/src/RageUtil.h | 16 +- stepmania/src/ScoreDisplay.cpp | 63 +++ stepmania/src/ScoreDisplay.h | 35 ++ stepmania/src/Song.cpp | 154 ++++++- stepmania/src/Sprite.cpp | 374 +++++++-------- stepmania/src/Sprite.h | 20 +- stepmania/src/StepMania.cpp | 38 +- stepmania/src/StepMania.dsp | 406 ++++++++++------- stepmania/src/TextBanner.cpp | 84 +++- stepmania/src/TextBanner.h | 6 +- stepmania/src/ThemeManager.cpp | 206 +++++++++ stepmania/src/ThemeManager.h | 170 +++++++ stepmania/src/TipDisplay.cpp | 87 ++++ stepmania/src/TipDisplay.h | 41 ++ stepmania/src/Transition.cpp | 59 +-- stepmania/src/Transition.h | 45 +- stepmania/src/TransitionFade.cpp | 36 +- stepmania/src/TransitionFade.h | 7 +- stepmania/src/TransitionFadeWipe.cpp | 34 +- stepmania/src/TransitionFadeWipe.h | 6 +- stepmania/src/TransitionRectWipe.cpp | 6 +- stepmania/src/TransitionRectWipe.h | 2 +- stepmania/src/TransitionStarWipe.cpp | 31 +- stepmania/src/TransitionStarWipe.h | 5 +- stepmania/src/song.h | 77 +--- 66 files changed, 3425 insertions(+), 1313 deletions(-) delete mode 100755 stepmania/Utils/Bitmap Font Builder.exe delete mode 100644 stepmania/src/Background.cpp delete mode 100644 stepmania/src/Background.h create mode 100644 stepmania/src/DifficultyIcon.cpp create mode 100644 stepmania/src/DifficultyIcon.h create mode 100644 stepmania/src/FootMeter.cpp create mode 100644 stepmania/src/FootMeter.h create mode 100644 stepmania/src/Grade.cpp create mode 100644 stepmania/src/Grade.h create mode 100644 stepmania/src/GradeDisplay.cpp create mode 100644 stepmania/src/GradeDisplay.h create mode 100644 stepmania/src/MusicSortDisplay.cpp create mode 100644 stepmania/src/MusicSortDisplay.h create mode 100644 stepmania/src/MusicStatusDisplay.cpp create mode 100644 stepmania/src/MusicStatusDisplay.h create mode 100644 stepmania/src/MusicWheel.cpp create mode 100644 stepmania/src/MusicWheel.h create mode 100644 stepmania/src/ScoreDisplay.cpp create mode 100644 stepmania/src/ScoreDisplay.h create mode 100644 stepmania/src/ThemeManager.cpp create mode 100644 stepmania/src/ThemeManager.h create mode 100644 stepmania/src/TipDisplay.cpp create mode 100644 stepmania/src/TipDisplay.h diff --git a/stepmania/Utils/Bitmap Font Builder.exe b/stepmania/Utils/Bitmap Font Builder.exe deleted file mode 100755 index 0b576742fb120f024b4c4eed757a172bc68f4d03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139264 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%0AaH$U2fqf4uDZ(3sNqd)QjOvmwQ|VH(ew^ewlQ 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 // we're actually going to do some drawing in this function + + + D3DXVECTOR3 pos = m_pos; D3DXVECTOR3 rotation = m_rotation; D3DXVECTOR2 scale = m_scale; @@ -65,28 +59,38 @@ void Actor::Draw() break; case flickering: break; + case bouncing: + float fPercentThroughBounce = m_fTimeIntoBounce / m_fBouncePeriod; + float fPercentOffset = sin( fPercentThroughBounce*D3DX_PI ); + pos += m_vectBounce * fPercentOffset; + break; } - LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice(); + SCREEN->Translate( pos.x+0.5f, pos.y-0.5f, pos.z ); // offset so that pixels are aligned to texels + SCREEN->Scale( scale.x, scale.y, 1 ); - // calculate and apply world transform - D3DXMATRIX matWorld, matTemp; - D3DXMatrixIdentity( &matWorld ); // pass this along to each thing we draw and let it set it's own world matrix - D3DXMatrixScaling( &matTemp, scale.x, scale.y, 1 ); // add in the zoom - matWorld *= matTemp; - D3DXMatrixRotationYawPitchRoll( &matTemp, rotation.y, rotation.x, rotation.z ); // add in the rotation - matWorld *= matTemp; - D3DXMatrixTranslation( &matTemp, pos.x, pos.y, 0 ); // add in the translation - matWorld *= matTemp; - D3DXMatrixTranslation( &matTemp, -0.5f, -0.5f, 0 ); // shift to align texels with pixels - matWorld *= matTemp; - pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); + // super slow! + // D3DXMatrixRotationYawPitchRoll( &matTemp, rotation.y, rotation.x, rotation.z ); // add in the rotation + // matNewWorld = matTemp * matNewWorld; + + // replace with... + if( rotation.z != 0 ) + { + SCREEN->RotateZ( rotation.z ); + } + + + + this->RenderPrimitives(); + + + SCREEN->PopMatrix(); } -void Actor::Update( const float &fDeltaTime ) +void Actor::Update( float fDeltaTime ) { // RageLog( "Actor::Update( %f )", fDeltaTime ); @@ -134,91 +138,118 @@ void Actor::Update( const float &fDeltaTime ) break; case flickering: break; + case bouncing: + m_fTimeIntoBounce += fDeltaTime; + if( m_fTimeIntoBounce >= m_fBouncePeriod ) + m_fTimeIntoBounce -= m_fBouncePeriod; + break; } // update tweening - if( m_TweenType != no_tween ) // we are performing some type of tweening + if( m_QueuedTweens.GetSize() > 0 ) // we are performing some type of tweening { - m_fTimeIntoTween += fDeltaTime; + TweenState &TS = m_QueuedTweens[0]; - if( m_fTimeIntoTween > m_fTweenTime ) // The tweening is over. Stop the tweening + if( TS.m_fTimeLeftInTween == TS.m_fTweenTime ) // we are just beginning this tween { - m_pos = m_end_pos; - m_scale = m_end_scale; - m_rotation = m_end_rotation; - for(int i=0; i<4; i++) m_colorDiffuse[i] = m_end_colorDiffuse[i]; - m_colorAdd = m_end_colorAdd; - m_TweenType = no_tween; + // set the start position + m_start_pos = m_pos; + m_start_rotation = m_rotation; + m_start_scale = m_scale; + for( int i=0; i<4; i++) m_start_colorDiffuse[i] = m_colorDiffuse[i]; + m_start_colorAdd = m_colorAdd; } - else // Tweening. Recalcute the curent position. + + TS.m_fTimeLeftInTween -= fDeltaTime; + + if( TS.m_fTimeLeftInTween <= 0 ) // The tweening is over. Stop the tweening { - float fPercentThroughTween = m_fTimeIntoTween / m_fTweenTime; + m_pos = TS.m_end_pos; + m_scale = TS.m_end_scale; + m_rotation = TS.m_end_rotation; + for(int i=0; i<4; i++) m_colorDiffuse[i] = TS.m_end_colorDiffuse[i]; + m_colorAdd = TS.m_end_colorAdd; + + m_QueuedTweens.RemoveAt( 0 ); + return; + } + else // in the middle of tweening. Recalcute the curent position. + { + float fPercentThroughTween = 1-(TS.m_fTimeLeftInTween / TS.m_fTweenTime); // distort the percentage if appropriate - if( m_TweenType == tween_bias_begin ) + switch( TS.m_TweenType ) + { + case TWEEN_BIAS_BEGIN: fPercentThroughTween = (float) sqrt( fPercentThroughTween ); - else if( m_TweenType == tweening_bias_end ) + break; + case TWEEN_BIAS_END: fPercentThroughTween = fPercentThroughTween * fPercentThroughTween; + break; + } - m_pos = m_start_pos + (m_end_pos - m_start_pos )*fPercentThroughTween; - m_scale = m_start_scale + (m_end_scale - m_start_scale )*fPercentThroughTween; - m_rotation = m_start_rotation+ (m_end_rotation - m_start_rotation)*fPercentThroughTween; - for(int i=0; i<4; i++) m_colorDiffuse[i] = m_start_colorDiffuse[i]*(1.0f-fPercentThroughTween) + m_end_colorDiffuse[i]*(fPercentThroughTween); - m_colorAdd = m_start_colorAdd *(1.0f-fPercentThroughTween) + m_end_colorAdd *(fPercentThroughTween); + m_pos = m_start_pos + (TS.m_end_pos - m_start_pos )*fPercentThroughTween; + m_scale = m_start_scale + (TS.m_end_scale - m_start_scale )*fPercentThroughTween; + m_rotation = m_start_rotation+ (TS.m_end_rotation - m_start_rotation)*fPercentThroughTween; + for(int i=0; i<4; i++) m_colorDiffuse[i] = m_start_colorDiffuse[i]*(1.0f-fPercentThroughTween) + TS.m_end_colorDiffuse[i]*(fPercentThroughTween); + m_colorAdd = m_start_colorAdd *(1.0f-fPercentThroughTween) + TS.m_end_colorAdd *(fPercentThroughTween); } - + + } // end if m_TweenType != no_tween } -void Actor::TweenTo( float time, float x, float y, float zoom, float rot, D3DXCOLOR col, TweenType tt ) -{ - // set our tweeen starting values to the current position - m_start_pos = m_pos; - m_start_scale = m_scale; - m_start_rotation = m_rotation; - for(int i=0; i<4; i++) m_start_colorDiffuse[i] = m_colorDiffuse[i]; - - // set the ending tweening position to what the user asked for - m_end_pos.x = (float)x; - m_end_pos.y = (float)y; - m_end_scale.x = zoom; - m_end_scale.y = zoom; - m_end_rotation.z = rot; - for(i=0; i<4; i++) m_end_colorDiffuse[i] = col; - m_TweenType = tt; - m_fTweenTime = time; - m_fTimeIntoTween = 0; - -} - void Actor::BeginTweening( float time, TweenType tt ) { - // set our tweeen starting and ending values to the current position - m_start_pos = m_end_pos = m_pos; - m_start_scale = m_end_scale = m_scale; - m_start_rotation = m_end_rotation = m_rotation; - for(int i=0; i<4; i++)m_start_colorDiffuse[i] = m_end_colorDiffuse[i] = m_colorDiffuse[i]; - m_start_colorAdd = m_end_colorAdd = m_colorAdd; - - m_TweenType = tt; - m_fTweenTime = time; - m_fTimeIntoTween = 0; + StopTweening(); + BeginTweeningQueued( time, tt ); } -void Actor::SetTweenX( float x ) { m_end_pos.x = x; } -void Actor::SetTweenY( float y ) { m_end_pos.y = y; } -void Actor::SetTweenXY( float x, float y ) { SetTweenX(x); SetTweenY(y); } -void Actor::SetTweenZoom( float zoom ) { m_end_scale.x = zoom; m_end_scale.y = zoom; } -void Actor::SetTweenZoomX( float zoom ) { m_end_scale.x = zoom; } -void Actor::SetTweenZoomY( float zoom ) { m_end_scale.y = zoom; } -void Actor::SetTweenRotationX( float r ) { m_end_rotation.x = r; } -void Actor::SetTweenRotationY( float r ) { m_end_rotation.y = r; } -void Actor::SetTweenRotationZ( float r ) { m_end_rotation.z = r; } +void Actor::BeginTweeningQueued( float time, TweenType tt ) +{ + ASSERT( time > 0 ); + + m_QueuedTweens.Add( TweenState() ); + + TweenState &TS = m_QueuedTweens[m_QueuedTweens.GetSize()-1]; + + // set our tween starting and ending values to the current position + TS.m_end_pos = m_pos; + TS.m_end_scale = m_scale; + TS.m_end_rotation = m_rotation; + for(int i=0; i<4; i++) TS.m_end_colorDiffuse[i] = m_colorDiffuse[i]; + TS.m_end_colorAdd = m_colorAdd; + + TS.m_TweenType = tt; + TS.m_fTweenTime = time; + TS.m_fTimeLeftInTween = time; +} + +void Actor::SetTweenX( float x ) { GetLatestTween().m_end_pos.x = x; } +void Actor::SetTweenY( float y ) { GetLatestTween().m_end_pos.y = y; } +void Actor::SetTweenZ( float z ) { GetLatestTween().m_end_pos.z = z; } +void Actor::SetTweenXY( float x, float y ) { GetLatestTween().m_end_pos.x = x; GetLatestTween().m_end_pos.y = y; } +void Actor::SetTweenZoom( float zoom ) { GetLatestTween().m_end_scale.x = zoom; GetLatestTween().m_end_scale.y = zoom; } +void Actor::SetTweenZoomX( float zoom ) { GetLatestTween().m_end_scale.x = zoom; } +void Actor::SetTweenZoomY( float zoom ) { GetLatestTween().m_end_scale.y = zoom; } +void Actor::SetTweenRotationX( float r ) { GetLatestTween().m_end_rotation.x = r; } +void Actor::SetTweenRotationY( float r ) { GetLatestTween().m_end_rotation.y = r; } +void Actor::SetTweenRotationZ( float r ) { GetLatestTween().m_end_rotation.z = r; } +void Actor::SetTweenDiffuseColor( D3DXCOLOR colorDiffuse ) { for(int i=0; i<4; i++) GetLatestTween().m_end_colorDiffuse[i] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorUpperLeft( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[0] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorUpperRight( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[1] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorLowerLeft( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[2] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorLowerRight( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[3] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorTopEdge( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[0] = GetLatestTween().m_end_colorDiffuse[1] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorRightEdge( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[1] = GetLatestTween().m_end_colorDiffuse[3] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorBottomEdge( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[2] = GetLatestTween().m_end_colorDiffuse[3] = colorDiffuse; }; +void Actor::SetTweenDiffuseColorLeftEdge( D3DXCOLOR colorDiffuse ) { GetLatestTween().m_end_colorDiffuse[0] = GetLatestTween().m_end_colorDiffuse[2] = colorDiffuse; }; +void Actor::SetTweenAddColor( D3DXCOLOR c ) { GetLatestTween().m_end_colorAdd = c; }; void Actor::ScaleTo( LPRECT pRect, StretchType st ) @@ -234,7 +265,7 @@ void Actor::ScaleTo( LPRECT pRect, StretchType st ) float rect_cx = pRect->left + rect_width/2; float rect_cy = pRect->top + rect_height/2; - // zoom factor needed to scale the Actor to fill the rectangle + // zoom fActor needed to scale the Actor to fill the rectangle float fNewZoomX = (float)fabs(rect_width / m_size.x); float fNewZoomY = (float)fabs(rect_height / m_size.y); @@ -260,20 +291,17 @@ void Actor::StretchTo( LPRECT pRect ) int rect_width = RECTWIDTH(*pRect); int rect_height = RECTHEIGHT(*pRect); - if( rect_width < 0 ) SetRotationY( D3DX_PI ); - if( rect_height < 0 ) SetRotationX( D3DX_PI ); - // center of the rectangle int rect_cx = pRect->left + rect_width/2; int rect_cy = pRect->top + rect_height/2; - // zoom factor needed to scale the Actor to fill the rectangle - float fNewZoomX = (float)fabs(rect_width / m_size.x); - float fNewZoomY = (float)fabs(rect_height / m_size.y); + // zoom fActor needed to scale the Actor to fill the rectangle + float fNewZoomX = rect_width / m_size.x; + float fNewZoomY = rect_height / m_size.y; SetXY( (float)rect_cx, (float)rect_cy ); - m_scale.x = fNewZoomX; - m_scale.y = fNewZoomY; + SetZoomX( fNewZoomX ); + SetZoomY( fNewZoomY ); } @@ -290,34 +318,27 @@ void Actor::SetEffectNone() void Actor::SetEffectBlinking( float fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 ) { m_Effect = blinking; - for(int i=0; i<4; i++) { - m_start_colorDiffuse[i] = Color; - m_end_colorDiffuse[i] = Color2; - } - //m_fPercentBetweenColors = 0.0; - //m_bTweeningTowardEndColor = TRUE; + m_effect_colorDiffuse1 = Color; + m_effect_colorDiffuse2 = Color2; + m_fDeltaPercentPerSecond = fDeltaPercentPerSecond; } void Actor::SetEffectCamelion( float fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 ) { m_Effect = camelion; - for(int i=0; i<4; i++) { - m_start_colorDiffuse[i] = Color; - m_end_colorDiffuse[i] = Color2; - } - //m_fPercentBetweenColors = 0.0; - //m_bTweeningTowardEndColor = TRUE; + m_effect_colorDiffuse1 = Color; + m_effect_colorDiffuse2 = Color2; + m_fDeltaPercentPerSecond = fDeltaPercentPerSecond; } void Actor::SetEffectGlowing( float fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 ) { m_Effect = glowing; - m_start_colorAdd = Color; - m_end_colorAdd = Color2; - //m_fPercentBetweenColors = 0.0; - //m_bTweeningTowardEndColor = TRUE; + m_effect_colorAdd1 = Color; + m_effect_colorAdd2 = Color2; + m_fDeltaPercentPerSecond = fDeltaPercentPerSecond; } @@ -343,4 +364,14 @@ void Actor::SetEffectVibrating( float fVibrationDistance ) void Actor::SetEffectFlickering() { m_Effect = flickering; +} + +void Actor::SetEffectBouncing( D3DXVECTOR3 vectBounce, float fPeriod ) +{ + m_Effect = bouncing; + + m_vectBounce = vectBounce; + m_fBouncePeriod = fPeriod; + m_fTimeIntoBounce = 0; + } \ No newline at end of file diff --git a/stepmania/src/Actor.h b/stepmania/src/Actor.h index 37a68fee3e..0d009ad3ba 100644 --- a/stepmania/src/Actor.h +++ b/stepmania/src/Actor.h @@ -9,8 +9,8 @@ */ -#ifndef _ACTOR_H_ -#define _ACTOR_H_ +#ifndef _Actor_H_ +#define _Actor_H_ #include "RageUtil.h" @@ -21,14 +21,20 @@ class Actor { +protected: + + public: Actor(); - enum TweenType { no_tween, tween_linear, tween_bias_begin, tweening_bias_end }; + + + enum TweenType { TWEEN_LINEAR, TWEEN_BIAS_BEGIN, TWEEN_BIAS_END }; enum Effect { no_effect, blinking, camelion, glowing, wagging, spinning, - vibrating, flickering + vibrating, flickering, + bouncing }; // let subclasses override @@ -36,15 +42,20 @@ public: virtual void Invalidate() {}; virtual void Draw(); - virtual void Update( const float &fDeltaTime ); + virtual void RenderPrimitives() = 0; + virtual void Update( float fDeltaTime ); virtual float GetX() { return m_pos.x; }; virtual float GetY() { return m_pos.y; }; + virtual float GetZ() { return m_pos.z; }; virtual void SetX( float x ) { m_pos.x = x; }; - virtual void SetY( float y ) { m_pos.y = y; }; + virtual void SetY( float y ) { m_pos.y = y; }; + virtual void SetZ( float z ) { m_pos.z = z; }; virtual void SetXY( float x, float y ) { m_pos.x = x; m_pos.y = y; }; // height and width vary depending on zoom + virtual float GetUnzoomedWidth() { return m_size.x; } + virtual float GetUnzoomedHeight() { return m_size.y; } virtual float GetZoomedWidth() { return m_size.x * m_scale.x; } virtual float GetZoomedHeight() { return m_size.y * m_scale.y; } virtual void SetWidth( float width ){ m_size.x = width; } @@ -79,17 +90,14 @@ public: virtual void SetAddColor( D3DXCOLOR colorAdd ) { m_colorAdd = colorAdd; }; virtual D3DXCOLOR GetAddColor() { return m_colorAdd; }; - virtual void TweenTo( float time, - float x, float y, - float zoom = 1.0, - float rot = 0.0, - D3DXCOLOR colDiffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ), - TweenType tt = tween_linear ); - virtual void BeginTweening( float time, TweenType tt = tween_linear ); - virtual void StopTweening() { m_TweenType = no_tween; }; + + virtual void BeginTweening( float time, TweenType tt = TWEEN_LINEAR ); + virtual void BeginTweeningQueued( float time, TweenType tt = TWEEN_LINEAR ); + virtual void StopTweening() { m_QueuedTweens.RemoveAll(); }; virtual void SetTweenX( float x ); virtual void SetTweenY( float y ); + virtual void SetTweenZ( float z ); virtual void SetTweenXY( float x, float y ); virtual void SetTweenZoom( float zoom ); virtual void SetTweenZoomX( float zoom ); @@ -97,23 +105,18 @@ public: virtual void SetTweenRotationX( float r ); virtual void SetTweenRotationY( float r ); virtual void SetTweenRotationZ( float r ); - virtual void SetTweenDiffuseColor( D3DXCOLOR colorDiffuse ) { for(int i=0; i<4; i++) m_end_colorDiffuse[i] = colorDiffuse; }; - virtual void SetTweenDiffuseColorUpperLeft( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[0] = colorDiffuse; }; - virtual void SetTweenDiffuseColorUpperRight( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[1] = colorDiffuse; }; - virtual void SetTweenDiffuseColorLowerLeft( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[2] = colorDiffuse; }; - virtual void SetTweenDiffuseColorLowerRight( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[3] = colorDiffuse; }; - virtual void SetTweenDiffuseColorTopEdge( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[0] = m_end_colorDiffuse[1] = colorDiffuse; }; - virtual void SetTweenDiffuseColorRightEdge( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[1] = m_end_colorDiffuse[3] = colorDiffuse; }; - virtual void SetTweenDiffuseColorBottomEdge( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[2] = m_end_colorDiffuse[3] = colorDiffuse; }; - virtual void SetTweenDiffuseColorLeftEdge( D3DXCOLOR colorDiffuse ) { m_end_colorDiffuse[0] = m_end_colorDiffuse[2] = colorDiffuse; }; - virtual void SetTweenAddColor( D3DXCOLOR c ) { m_end_colorAdd = c; } + virtual void SetTweenDiffuseColor( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorUpperLeft( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorUpperRight( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorLowerLeft( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorLowerRight( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorTopEdge( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorRightEdge( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorBottomEdge( D3DXCOLOR colorDiffuse ); + virtual void SetTweenDiffuseColorLeftEdge( D3DXCOLOR colorDiffuse ); + virtual void SetTweenAddColor( D3DXCOLOR c ); - // NOTE: GetEdge functions don't consider rotation - //virtual float GetLeftEdge() { return m_pos.x - GetZoomedWidth()/2.0f; }; - //virtual float GetRightEdge() { return m_pos.x + GetZoomedWidth()/2.0f; }; - //virtual float GetTopEdge() { return m_pos.y - GetZoomedHeight()/2.0f; }; - //virtual float GetBottomEdge() { return m_pos.y + GetZoomedHeight()/2.0f; }; enum StretchType { fit_inside, cover }; @@ -124,6 +127,16 @@ public: void StretchTo( LPRECT rect ); + + + enum HorizAlign { align_left, align_center, align_right }; + void SetHorizAlign( HorizAlign ha ) { m_HorizAlign = ha; }; + + enum VertAlign { align_top, align_middle, align_bottom }; + void SetVertAlign( VertAlign va ) { m_VertAlign = va; }; + + + // effects void SetEffectNone(); void SetEffectBlinking( float fDeltaPercentPerSecond = 2.5, @@ -140,37 +153,70 @@ public: void SetEffectSpinning( float fRadsPerSpeed = 2.0 ); void SetEffectVibrating( float fVibrationDistance = 5.0 ); void SetEffectFlickering(); + void SetEffectBouncing( D3DXVECTOR3 vectBounceDir, float fPeriod ); Effect GetEffect() { return m_Effect; }; protected: - void Init(); - D3DXVECTOR2 m_size; // width, height - D3DXVECTOR2 m_pos; // X-Y coordinate of where the center point will appear on screen + D3DXVECTOR3 m_pos; // X-Y coordinate of where the center point will appear on screen D3DXVECTOR3 m_rotation; // X, Y, and Z m_rotation D3DXVECTOR2 m_scale; // X and Y zooming D3DXCOLOR m_colorDiffuse[4]; // 4 corner colors - left to right, top to bottom D3DXCOLOR m_colorAdd; - // start and end position for tweening - D3DXVECTOR2 m_start_pos, m_end_pos; - D3DXVECTOR3 m_start_rotation, m_end_rotation; - D3DXVECTOR2 m_start_scale, m_end_scale; - D3DXCOLOR m_start_colorDiffuse[4],m_end_colorDiffuse[4]; - D3DXCOLOR m_start_colorAdd, m_end_colorAdd; - // counters for tweening - TweenType m_TweenType; - float m_fTweenTime; // seconds between Start and End positions/zooms - float m_fTimeIntoTween; // how long we have been tweening for + // tweening + D3DXVECTOR3 m_start_pos; + D3DXVECTOR3 m_start_rotation; + D3DXVECTOR2 m_start_scale; + D3DXCOLOR m_start_colorDiffuse[4]; + D3DXCOLOR m_start_colorAdd; + + struct TweenState + { + // start and end position for tweening + D3DXVECTOR3 m_end_pos; + D3DXVECTOR3 m_end_rotation; + D3DXVECTOR2 m_end_scale; + D3DXCOLOR m_end_colorDiffuse[4]; + D3DXCOLOR m_end_colorAdd; + + // counters for tweening + TweenType m_TweenType; + float m_fTimeLeftInTween; // how far into the tween are we? + float m_fTweenTime; // seconds between Start and End positions/zooms + + TweenState() + { + m_end_pos = D3DXVECTOR3( 0, 0, 0 ); + m_end_rotation = D3DXVECTOR3( 0, 0, 0 ); + m_end_scale = D3DXVECTOR2( 1, 1 ); + for(int i=0; i<4; i++) m_end_colorDiffuse[i]= D3DXCOLOR( 1, 1, 1, 1 ); + m_end_colorAdd = D3DXCOLOR( 0, 0, 0, 0 ); + }; + }; + + CArray m_QueuedTweens; + TweenState& GetLatestTween() { return m_QueuedTweens[m_QueuedTweens.GetSize()-1]; }; + + + // alignment + HorizAlign m_HorizAlign; + VertAlign m_VertAlign; + // effect Effect m_Effect; + // Counting variables for sprite effects: // camelion and glowing: + D3DXCOLOR m_effect_colorDiffuse1; + D3DXCOLOR m_effect_colorDiffuse2; + D3DXCOLOR m_effect_colorAdd1; + D3DXCOLOR m_effect_colorAdd2; float m_fPercentBetweenColors; bool m_bTweeningTowardEndColor; // TRUE is fading toward end_color, FALSE if fading toward start_color float m_fDeltaPercentPerSecond; // percentage change in tweening per second @@ -188,6 +234,12 @@ protected: // flickering: bool m_bVisibleThisFrame; + + // bouncing: + D3DXVECTOR3 m_vectBounce; + float m_fBouncePeriod; + float m_fTimeIntoBounce; + }; diff --git a/stepmania/src/ActorFrame.cpp b/stepmania/src/ActorFrame.cpp index 7b9706b636..2d190287ed 100644 --- a/stepmania/src/ActorFrame.cpp +++ b/stepmania/src/ActorFrame.cpp @@ -10,117 +10,35 @@ */ #include "ActorFrame.h" -#include -#include "RageScreen.h" -ActorFrame::ActorFrame() +void ActorFrame::RenderPrimitives() { - m_pos = m_start_pos = m_end_pos = D3DXVECTOR2( 0, 0 ); - m_rotation = m_start_rotation = m_end_rotation = D3DXVECTOR3( 0, 0, 0 ); - m_scale = m_start_scale = m_end_scale = D3DXVECTOR2( 1, 1 ); - - m_TweenType = no_tween; - m_fTweenTime = 0.0f; - m_fTimeIntoTween = 0.0f; -} - - -void ActorFrame::Draw() -{ - D3DXVECTOR2 pos = m_pos; - D3DXVECTOR3 rotation = m_rotation; - D3DXVECTOR2 scale = m_scale; - - - LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice(); - - // calculate and apply world transform - D3DXMATRIX matOriginalWorld, matNewWorld, matTemp; - pd3dDevice->GetTransform( D3DTS_WORLD, &matOriginalWorld ); // save the original world matrix - - matNewWorld = matOriginalWorld; // initialize the matrix we're about to build to transform into this Frame's coord space - - D3DXMatrixTranslation( &matTemp, pos.x, pos.y, 0 ); // add in the translation - matNewWorld = matTemp * matNewWorld; - D3DXMatrixScaling( &matTemp, scale.x, scale.y, 1 ); // add in the zoom - matNewWorld = matTemp * matNewWorld; - D3DXMatrixRotationYawPitchRoll( &matTemp, rotation.y, rotation.x, rotation.z ); // add in the rotation - matNewWorld = matTemp * matNewWorld; - - pd3dDevice->SetTransform( D3DTS_WORLD, &matNewWorld ); // apply the translation so we're in this ActorFrame's local coords - - // draw all sub-actors while we're in the frame's local coordinate space + // draw all sub-ActorFrames while we're in the ActorFrame's local coordinate space for( int i=0; iSetTransform( D3DTS_WORLD, &matNewWorld ); // apply the translation so we're in this ActorFrame's local coords m_SubActors[i]->Draw(); } - - - pd3dDevice->SetTransform( D3DTS_WORLD, &matOriginalWorld ); // restore the original world matrix - } void ActorFrame::Update( float fDeltaTime ) { -// RageLog( "ActorFrame::Update( %f )", fDeltaTime ) +// RageLog( "ActorFrame::Update( %f )", fDeltaTime ); - // update tweening - if( m_TweenType != no_tween ) // we are performing some type of tweening - { - m_fTimeIntoTween += fDeltaTime; - - if( m_fTimeIntoTween > m_fTweenTime ) // The tweening is over. Stop the tweening - { - m_pos = m_end_pos; - m_scale = m_end_scale; - m_rotation = m_end_rotation; - m_TweenType = no_tween; - } - else // Tweening. Recalcute the curent position. - { - float fPercentThroughTween = m_fTimeIntoTween / m_fTweenTime; - - // distort the percentage if appropriate - if( m_TweenType == tween_bias_begin ) - fPercentThroughTween = (float) sqrt( fPercentThroughTween ); - else if( m_TweenType == tweening_bias_end ) - fPercentThroughTween = fPercentThroughTween * fPercentThroughTween; + Actor::Update( fDeltaTime ); - m_pos = m_start_pos + (m_end_pos - m_start_pos )*fPercentThroughTween; - m_scale = m_start_scale + (m_end_scale - m_start_scale )*fPercentThroughTween; - m_rotation = m_start_rotation+ (m_end_rotation - m_start_rotation)*fPercentThroughTween; - } - - } // end if m_TweenType != no_tween - - - // update all sub-actors + // update all sub-Actors for( int i=0; iUpdate(fDeltaTime); } -void ActorFrame::BeginTweening( float time, TweenType tt ) +void ActorFrame::SetDiffuseColor( D3DXCOLOR c ) { - // set our tweeen starting and ending values to the current position - m_start_pos = m_end_pos = m_pos; - m_start_scale = m_end_scale = m_scale; - m_start_rotation = m_end_rotation = m_rotation; + Actor::SetDiffuseColor( c ); - m_TweenType = tt; - m_fTweenTime = time; - m_fTimeIntoTween = 0; + // set all sub-Actors + for( int i=0; iSetDiffuseColor(c ); } - -void ActorFrame::SetTweenX( float x ) { m_end_pos.x = x; } -void ActorFrame::SetTweenY( float y ) { m_end_pos.y = y; } -void ActorFrame::SetTweenXY( float x, float y ) { SetTweenX(x); SetTweenY(y); } -void ActorFrame::SetTweenZoom( float zoom ) { m_end_scale.x = zoom; m_end_scale.y = zoom; } -void ActorFrame::SetTweenRotationX( float r ) { m_end_rotation.x = r; } -void ActorFrame::SetTweenRotationY( float r ) { m_end_rotation.y = r; } -void ActorFrame::SetTweenRotationZ( float r ) { m_end_rotation.z = r; } - - diff --git a/stepmania/src/ActorFrame.h b/stepmania/src/ActorFrame.h index 6a4eb2a718..af41b586d5 100644 --- a/stepmania/src/ActorFrame.h +++ b/stepmania/src/ActorFrame.h @@ -15,77 +15,24 @@ #include "RageUtil.h" #include - #include "Actor.h" -class ActorFrame + +class ActorFrame : public Actor { protected: CArray m_SubActors; public: - ActorFrame(); + void AddActor( Actor* pActor) { m_SubActors.Add(pActor); }; - void AddActor( Actor* pActor ) { m_SubActors.Add(pActor); }; + virtual void Update( float fDeltaTime ); + virtual void RenderPrimitives(); + virtual void SetDiffuseColor( D3DXCOLOR c ); - enum TweenType { no_tween, tween_linear, tween_bias_begin, tweening_bias_end }; - - // let subclasses override - void Restore() { for(int i=0; iRestore(); }; - void Invalidate() { for(int i=0; iInvalidate(); }; - - void Draw(); - void Update( float fDeltaTime ); - - float GetX() { return m_pos.x; }; - float GetY() { return m_pos.y; }; - void SetX( float x ) { m_pos.x = x; m_TweenType = no_tween; }; - void SetY( float y ) { m_pos.y = y; m_TweenType = no_tween; }; - void SetXY( float x, float y ) { m_pos.x = x; m_pos.y = y; m_TweenType = no_tween; }; - - float GetZoom() { return m_scale.x; } - void SetZoom( float zoom ) { m_scale.x = zoom; m_scale.y = zoom; } - - float GetRotation() { return m_rotation.z; } - void SetRotation( float rot ) { m_rotation.z = rot; } - float GetRotationX() { return m_rotation.x; } - void SetRotationX( float rot ) { m_rotation.x = rot; } - float GetRotationY() { return m_rotation.y; } - void SetRotationY( float rot ) { m_rotation.y = rot; } - - void SetDiffuseColor( D3DXCOLOR colorDiffuse ) { for(int i=0; iSetDiffuseColor(colorDiffuse); }; - void SetAddColor( D3DXCOLOR colorAdd ) { for(int i=0; iSetAddColor(colorAdd); }; - - - void BeginTweening( float time, TweenType tt = tween_linear ); - void SetTweenX( float x ); - void SetTweenY( float y ); - void SetTweenXY( float x, float y ); - void SetTweenZoom( float zoom ); - void SetTweenRotationX( float r ); - void SetTweenRotationY( float r ); - void SetTweenRotationZ( float r ); - void SetTweenDiffuseColor( D3DXCOLOR c ); - void SetTweenAddColor( D3DXCOLOR c ); - - -protected: - D3DXVECTOR2 m_pos; // X-Y coordinate of where the center point will appear on screen - D3DXVECTOR3 m_rotation; // X, Y, and Z m_rotation - D3DXVECTOR2 m_scale; // X and Y zooming - - // start and end position for tweening - D3DXVECTOR2 m_start_pos, m_end_pos; - D3DXVECTOR3 m_start_rotation, m_end_rotation; - D3DXVECTOR2 m_start_scale, m_end_scale; - - // counters for tweening - TweenType m_TweenType; - float m_fTweenTime; // seconds between Start and End positions/zooms - float m_fTimeIntoTween; // how long we have been tweening for }; diff --git a/stepmania/src/BPMDisplay.cpp b/stepmania/src/BPMDisplay.cpp index 5de79e2876..e33173649c 100644 --- a/stepmania/src/BPMDisplay.cpp +++ b/stepmania/src/BPMDisplay.cpp @@ -12,6 +12,7 @@ #include "BPMDisplay.h" #include "RageUtil.h" #include "ScreenDimensions.h" +#include "ThemeManager.h" @@ -25,22 +26,22 @@ BPMDisplay::BPMDisplay() 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_textBPM.Load( THEME->GetPathTo(FONT_LCD_NUMBERS) ); + m_textBPM.SetXY( CENTER_X, SCREEN_HEIGHT - 50 ); + //m_textBPM.SetSequence( ssprintf("999") ); + m_textBPM.SetXY( -30, 0 ); + m_textBPM.SetZoom( 0.7f ); + m_textBPM.SetDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_textBPM.SetDiffuseColorBottomEdge( D3DXCOLOR(1,0.5f,0,1) ); // orange - m_textLabel.LoadFromFontName( "Black Wolf" ); + m_textLabel.Load( THEME->GetPathTo(FONT_FUTURISTIC) ); 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_textBPM ); this->AddActor( &m_textLabel ); } @@ -70,7 +71,7 @@ void BPMDisplay::Update( float fDeltaTime ) case holding_up: m_fCurrentBPM = m_fHighBPM; break; case holding_down: m_fCurrentBPM = m_fLowBPM; break; } - m_seqBPM.SetSequence( ssprintf("%03.0f", m_fCurrentBPM) ); + m_textBPM.SetText( ssprintf("%03.0f", m_fCurrentBPM) ); } @@ -86,18 +87,18 @@ void BPMDisplay::SetBPMRange( float fLowBPM, float fHighBPM ) 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_textBPM.BeginTweening(0.5f); + m_textBPM.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,0,0,1) ); // red + m_textBPM.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_textBPM.BeginTweening(0.5f); + m_textBPM.SetTweenDiffuseColorTopEdge( D3DXCOLOR(1,1,0,1) ); // yellow + m_textBPM.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 diff --git a/stepmania/src/BPMDisplay.h b/stepmania/src/BPMDisplay.h index 404b3de9d7..64f8cbf21f 100644 --- a/stepmania/src/BPMDisplay.h +++ b/stepmania/src/BPMDisplay.h @@ -16,7 +16,6 @@ #include "Sprite.h" #include "Song.h" #include "ActorFrame.h" -#include "SpriteSequence.h" #include "BitmapText.h" #include "Rectangle.h" @@ -29,7 +28,7 @@ public: void SetBPMRange( float fLowBPM, float fHighBPM ); protected: - SpriteSequence m_seqBPM; + BitmapText m_textBPM; BitmapText m_textLabel; RectangleActor m_rectFrame; diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp deleted file mode 100644 index 0598c27b0a..0000000000 --- a/stepmania/src/Background.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "stdafx.h" -/* ------------------------------------------------------------------------------ - File: Background.h - - Desc: A graphic displayed in the background during Dancing. - - Copyright (c) 2001 Chris Danford. All rights reserved. ------------------------------------------------------------------------------ -*/ - -#include "Background.h" -#include "RageUtil.h" - - -const CString sVisDir = "Visualizations\\"; - - -void Background::LoadFromSong( Song& song ) -{ - CString sBGTexturePath = song.GetBackgroundPath(); - sBGTexturePath.MakeLower(); - - bool bIsAMovieBackground = ( sBGTexturePath.Right(3) == "avi" || - sBGTexturePath.Right(3) == "mpg" || - sBGTexturePath.Right(3) == "mpeg" ); - - if( bIsAMovieBackground ) - { - Sprite::LoadFromTexture( sBGTexturePath ); - Sprite::StretchTo( CRect(0,480,640,0) ); // flip - Sprite::SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0.8f,1) ); - - // 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) -{ - Sprite::Update( fDeltaTime ); - m_sprVis.Update( fDeltaTime ); -} - -void Background::Draw() -{ - Sprite::Draw(); - m_sprVis.Draw(); -} \ No newline at end of file diff --git a/stepmania/src/Background.h b/stepmania/src/Background.h deleted file mode 100644 index e147841a50..0000000000 --- a/stepmania/src/Background.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------------------------------------------ - File: Background.h - - Desc: A graphic displayed in the background during Dancing. - - Copyright (c) 2001 Chris Danford. All rights reserved. ------------------------------------------------------------------------------ -*/ - - -#ifndef _Background_H_ -#define _Background_H_ - - -#include "Sprite.h" -#include "Song.h" - - -class Background : public Sprite -{ -public: - void LoadFromSong( Song& song ); - - void Update( float fDeltaTime); - void Draw(); - - Sprite m_sprVis; - -}; - - - - -#endif \ No newline at end of file diff --git a/stepmania/src/Banner.cpp b/stepmania/src/Banner.cpp index 26029267c4..edce6f36b6 100644 --- a/stepmania/src/Banner.cpp +++ b/stepmania/src/Banner.cpp @@ -12,19 +12,20 @@ #include "RageUtil.h" #include "Banner.h" +#include "ThemeManager.h" -const CString TEXTURE_FALLBACK_BANNER = "Textures\\Fallback Banner.png"; bool Banner::LoadFromSong( Song &song ) { if( song.HasBanner() ) Sprite::LoadFromTexture( song.GetBannerPath() ); - else if( song.HasBackground() && !song.BackgroundIsAMovie() ) + else if( song.HasBackground() ) Sprite::LoadFromTexture( song.GetBackgroundPath() ); else - Sprite::LoadFromTexture( TEXTURE_FALLBACK_BANNER ); + Sprite::LoadFromTexture( THEME->GetPathTo(GRAPHIC_FALLBACK_BANNER) ); + //Sprite::TurnShadowOff(); int iSourceWidth = m_pTexture->GetSourceWidth(); diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index 6ff7c6d96e..035f97772c 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -12,6 +12,7 @@ #include "BitmapText.h" #include "IniFile.h" #include +#include "RageTextureManager.h" @@ -21,40 +22,127 @@ BitmapText::BitmapText() // m_colorBottom = D3DXCOLOR(1,1,1,1); for( int i=0; i 0 for success. -bool BitmapText::LoadCharWidths( CString sWidthFilePath ) -{ - FILE *file; - file = fopen( sWidthFilePath, "rb" ); - for( int i=0; i<256; i++ ) { - BYTE widthSourcePixels; - if( fread(&widthSourcePixels, 1, 1, file) != 1 ) - return false; - m_fCharWidthsInSourcePixels[i] = widthSourcePixels; + + + // Read .font file + IniFile ini; + ini.SetPath( m_sFontFilePath ); + if( !ini.ReadFile() ) + RageError( ssprintf("Error opening Font file '%s'.", m_sFontFilePath) ); + + + + // load texture + CString sTextureFile = ini.GetValue( "Font", "Texture" ); + if( sTextureFile == "" ) + RageError( ssprintf("Error reading value 'Texture' from %s.", m_sFontFilePath) ); + + + CString sTexturePath = sFontDir + sTextureFile; // save the path of the new texture + + // is this the first time the texture is being loaded? + bool bFirstTimeBeingLoaded = !TM->IsTextureLoaded( sTexturePath ); + + LoadTexture( sTexturePath ); + + // the size of the sprite is the size of the image before it was scaled + SetWidth( (float)m_pTexture->GetSourceFrameWidth() ); + SetHeight( (float)m_pTexture->GetSourceFrameHeight() ); + + + + // find out what characters are in this font + CString sCharacters = ini.GetValue( "Font", "Characters" ); + if( sCharacters != "" ) // the creator supplied characters + { + // sanity check + if( sCharacters.GetLength() != Sprite::GetNumStates() ) + RageError( ssprintf("The characters in '%s' does not match the number of frames in the texture.", m_sFontFilePath) ); + + // set the char to frameno map + for( int i=0; iGetSourceFrameWidth(); + } + } + + + if( bFirstTimeBeingLoaded ) + { + // tweak the textures frame rectangles so we don't draw extra to the left and right of the character + for( int i=0; iGetTextureCoordRect( i ); + + float fPixelsToChopOff = m_fFrameNoToWidth[i] - GetUnzoomedWidth(); + float fTexCoordsToChopOff = fPixelsToChopOff / m_pTexture->GetTextureWidth(); + + pFrect->left -= fTexCoordsToChopOff/2; + pFrect->right += fTexCoordsToChopOff/2; + } + } + return true; } + + // get a rectangle for the text, considering a possible text scaling. // useful to know if some text is visible or not float BitmapText::GetWidestLineWidthInSourcePixels() @@ -75,12 +163,16 @@ float BitmapText::GetWidestLineWidthInSourcePixels() float BitmapText::GetLineWidthInSourcePixels( int iLineNo ) { - CString &sText = m_sTextLines[iLineNo]; + CString &sLine = m_sTextLines[iLineNo]; float fLineWidth = 0; - for( int j=0; jGetVertexBuffer(); + CUSTOMVERTEX* v; + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + + + + int iVNum = 0; // the current vertex number + + float fHeight = GetUnzoomedHeight(); + float fY; + switch( m_VertAlign ) + { + case align_top: fY = 0; break; + case align_middle: fY = (m_sTextLines.GetSize()-1) * fHeight / 2; break; + case align_bottom: fY = (m_sTextLines.GetSize()-1) * fHeight; break; + default: ASSERT( true ); + } + + + for( i=0; i 1-fPercentageOfFrame ) + fPercentExtra = 1-fPercentageOfFrame; + + + // set vertex positions + + v[iVNum++].p = D3DXVECTOR3( fX, fHeight/2, 0 ); // bottom left + v[iVNum++].p = D3DXVECTOR3( fX, -fHeight/2, 0 ); // top left + + fX += fCharWidth; + + float fExtraPixels = fPercentExtra * GetUnzoomedWidth(); + + v[iVNum++].p = D3DXVECTOR3( fX+fExtraPixels, fHeight/2, 0 ); // bottom right + v[iVNum++].p = D3DXVECTOR3( fX+fExtraPixels, -fHeight/2, 0 ); // top right + + + // set texture coordinates + iVNum -= 4; + + FRECT* pTexCoordRect = m_pTexture->GetTextureCoordRect( iFrameNo ); + + float fExtraTexCoords = fPercentExtra * m_pTexture->GetTextureFrameWidth() / m_pTexture->GetTextureWidth(); + + v[iVNum].tu = pTexCoordRect->left; v[iVNum++].tv = pTexCoordRect->bottom; // bottom left + v[iVNum].tu = pTexCoordRect->left; v[iVNum++].tv = pTexCoordRect->top; // top left + v[iVNum].tu = pTexCoordRect->right + fExtraTexCoords; v[iVNum++].tv = pTexCoordRect->bottom; // bottom right + v[iVNum].tu = pTexCoordRect->right + fExtraTexCoords; v[iVNum++].tv = pTexCoordRect->top; // top right + + + } + + fY += fHeight; + } + + + + pVB->Unlock(); + + + + + // Set the stage... + LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice(); + pd3dDevice->SetTexture( 0, m_pTexture->GetD3DTexture() ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); + 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, 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) ); + + + + if( colorDiffuse[0].a != 0 ) + { + ////////////////////// + // render the shadow + ////////////////////// + if( m_bHasShadow ) + { + SCREEN->PushMatrix(); + SCREEN->Translate( 5, 5, 0 ); // shift by 5 units + + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + for( int i=0; iUnlock(); + + 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 ); + + for( i=0; iDrawPrimitive( D3DPT_TRIANGLESTRIP, i, 2 ); + + SCREEN->PopMatrix(); + } + + + ////////////////////// + // render the diffuse pass + ////////////////////// + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + for( int i=0; iUnlock(); + + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); + + + for( i=0; iDrawPrimitive( D3DPT_TRIANGLESTRIP, i, 2 ); + } + + + ////////////////////// + // render the add pass + ////////////////////// + if( colorAdd.a != 0 ) + { + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + for( int i=0; iUnlock(); + + 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 ); + + for( i=0; iDrawPrimitive( D3DPT_TRIANGLESTRIP, i, 2 ); + } } void BitmapText::SetText( CString sText ) { + if( sText.GetLength() > MAX_NUM_VERTICIES ) + sText = sText.Left( MAX_NUM_VERTICIES ); + + // strip out foreign chars + for( int i=0; i NUM_CHARS-1 ) + sText.Delete(i); + + m_sTextLines.RemoveAll(); split( sText, "\n", m_sTextLines, false ); } diff --git a/stepmania/src/BitmapText.h b/stepmania/src/BitmapText.h index 69d06a3860..78ab5935ba 100644 --- a/stepmania/src/BitmapText.h +++ b/stepmania/src/BitmapText.h @@ -26,25 +26,25 @@ protected: public: BitmapText(); - bool LoadFromFontName( CString sFontName ); + virtual void RenderPrimitives(); + + bool Load( CString sFontName ); void SetText( CString sText ); CString GetText(); bool LoadFontWidths( CString sFilePath ); - void Draw(); - float GetWidestLineWidthInSourcePixels(); // in logical, pre-zoomed units float GetLineWidthInSourcePixels( int iLineNo ); protected: bool LoadCharWidths( CString sWidthFilePath ); - CString m_sFontName; - float m_fCharWidthsInSourcePixels[NUM_CHARS]; // in soure coordinate space + CString m_sFontFilePath; + int m_iCharToFrameNo[NUM_CHARS]; + float m_fFrameNoToWidth[NUM_CHARS]; // in soure coordinate space CStringArray m_sTextLines; - //CArray m_fLineWidths; }; diff --git a/stepmania/src/DifficultyIcon.cpp b/stepmania/src/DifficultyIcon.cpp new file mode 100644 index 0000000000..505a51631c --- /dev/null +++ b/stepmania/src/DifficultyIcon.cpp @@ -0,0 +1,18 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: DifficultyIcon.h + + Desc: A graphic displayed in the DifficultyIcon during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "DifficultyIcon.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" + + + diff --git a/stepmania/src/DifficultyIcon.h b/stepmania/src/DifficultyIcon.h new file mode 100644 index 0000000000..0aba21006a --- /dev/null +++ b/stepmania/src/DifficultyIcon.h @@ -0,0 +1,62 @@ +/* +----------------------------------------------------------------------------- + File: DifficultyIcon.h + + Desc: A graphic displayed in the DifficultyIcon during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _DifficultyIcon_H_ +#define _DifficultyIcon_H_ + + +#include "Sprite.h" +#include "Song.h" +#include "BitmapText.h" +#include "ThemeManager.h" + + +class DifficultyIcon : public Sprite +{ +public: + DifficultyIcon() + { + Load( THEME->GetPathTo(GRAPHIC_STEPS_DESCRIPTION) ); + StopAnimating(); + + SetFromDescription( "" ); + }; + + void SetFromSteps( Steps &steps ) + { + SetFromDescription( steps.m_sDescription ); + }; + +private: + + void SetFromDescription( CString sDescription ) + { + sDescription.MakeLower(); + if( sDescription.Find( "basic" ) != -1 ) + SetState( 0 ); + else if( sDescription.Find( "trick" ) != -1 ) + SetState( 1 ); + else if( sDescription.Find( "another" ) != -1 ) + SetState( 2 ); + else if( sDescription.Find( "maniac" ) != -1 ) + SetState( 3 ); + else if( sDescription.Find( "ssr" ) != -1 ) + SetState( 4 ); + else if( sDescription.Find( "battle" ) != -1 ) + SetState( 5 ); + else if( sDescription.Find( "couple" ) != -1 ) + SetState( 6 ); + else + SetState( 7 ); + }; +}; + +#endif \ No newline at end of file diff --git a/stepmania/src/FootMeter.cpp b/stepmania/src/FootMeter.cpp new file mode 100644 index 0000000000..8dded0e049 --- /dev/null +++ b/stepmania/src/FootMeter.cpp @@ -0,0 +1,18 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: FootMeter.h + + Desc: A graphic displayed in the FootMeter during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "FootMeter.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" + + + diff --git a/stepmania/src/FootMeter.h b/stepmania/src/FootMeter.h new file mode 100644 index 0000000000..24718e8f0b --- /dev/null +++ b/stepmania/src/FootMeter.h @@ -0,0 +1,72 @@ +/* +----------------------------------------------------------------------------- + File: FootMeter.h + + Desc: A graphic displayed in the FootMeter during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _FootMeter_H_ +#define _FootMeter_H_ + + +#include "Sprite.h" +#include "Song.h" +#include "BitmapText.h" +#include "ThemeManager.h" + + +class FootMeter : public BitmapText +{ +public: + FootMeter() + { + Load( THEME->GetPathTo(FONT_FEET) ); + + SetNumFeet( 0, "" ); + }; + + void SetFromSteps( Steps &steps ) + { + SetNumFeet( steps.m_iNumFeet, steps.m_sDescription ); + }; + +private: + + void SetNumFeet( int iNumFeet, CString sDescription ) + { + CString sNewText; + for( int f=0; f<=9; f++ ) + sNewText += (fGetPathTo(GRAPHIC_GHOST_ARROW) ); SetState( 1 ); SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); TurnShadowOff(); diff --git a/stepmania/src/GhostArrowBright.cpp b/stepmania/src/GhostArrowBright.cpp index c63daf248a..47d76aafbd 100644 --- a/stepmania/src/GhostArrowBright.cpp +++ b/stepmania/src/GhostArrowBright.cpp @@ -5,9 +5,9 @@ ////////////////////////////////////////////////////////////////////// #include "GhostArrowBright.h" +#include "ThemeManager.h" -const CString GHOST_ARROW_SPRITE = "Sprites\\Ghost Arrow.sprite"; const float GRAY_ARROW_TWEEN_TIME = 0.5f; @@ -17,7 +17,7 @@ const float GRAY_ARROW_TWEEN_TIME = 0.5f; GhostArrowBright::GhostArrowBright() { - LoadFromSpriteFile( GHOST_ARROW_SPRITE ); + Load( THEME->GetPathTo(GRAPHIC_GHOST_ARROW) ); SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); TurnShadowOff(); } diff --git a/stepmania/src/Grade.cpp b/stepmania/src/Grade.cpp new file mode 100644 index 0000000000..f6f547729b --- /dev/null +++ b/stepmania/src/Grade.cpp @@ -0,0 +1,21 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: Grade.cpp + + Desc: A graphic displayed in the Grade during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + + +#include "Grade.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" + + + + diff --git a/stepmania/src/Grade.h b/stepmania/src/Grade.h new file mode 100644 index 0000000000..2ecce7c100 --- /dev/null +++ b/stepmania/src/Grade.h @@ -0,0 +1,61 @@ +/* +----------------------------------------------------------------------------- + File: Grade.h + + Desc: A graphic displayed in the Grade during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _Grade_H_ +#define _Grade_H_ + + +#include "Sprite.h" +#include "ThemeManager.h" + + +struct Grade +{ + Grade() + { + m_GradeType = GRADE_NO_DATA; + }; + + + 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_NO_DATA: return "N"; + default: ASSERT(true); return "N"; + } + }; + void FromString( CString sGrade ) + { + sGrade.MakeUpper(); + if ( sGrade == "AAA" ) m_GradeType = GRADE_AAA; + else if( sGrade == "AA" ) m_GradeType = GRADE_AA; + else if( sGrade == "A" ) m_GradeType = GRADE_A; + else if( sGrade == "B" ) m_GradeType = GRADE_B; + else if( sGrade == "C" ) m_GradeType = GRADE_C; + else if( sGrade == "D" ) m_GradeType = GRADE_D; + else if( sGrade == "E" ) m_GradeType = GRADE_E; + else if( sGrade == "N" ) m_GradeType = GRADE_NO_DATA; + else ASSERT(true); // invalid grade string + }; + + enum GradeType { GRADE_NO_DATA=0, GRADE_E, GRADE_D, GRADE_C, GRADE_B, GRADE_A, GRADE_AA, GRADE_AAA }; + GradeType m_GradeType; +}; + +#endif diff --git a/stepmania/src/GradeDisplay.cpp b/stepmania/src/GradeDisplay.cpp new file mode 100644 index 0000000000..f6f547729b --- /dev/null +++ b/stepmania/src/GradeDisplay.cpp @@ -0,0 +1,21 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: Grade.cpp + + Desc: A graphic displayed in the Grade during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + + +#include "Grade.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" + + + + diff --git a/stepmania/src/GradeDisplay.h b/stepmania/src/GradeDisplay.h new file mode 100644 index 0000000000..10ed8452d0 --- /dev/null +++ b/stepmania/src/GradeDisplay.h @@ -0,0 +1,54 @@ +/* +----------------------------------------------------------------------------- + File: GradeDisplay.h + + Desc: A graphic displayed in the GradeDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _GradeDisplay_H_ +#define _GradeDisplay_H_ + + +#include "Sprite.h" +#include "ThemeManager.h" +#include "Grade.h" + + + +class GradeDisplay : public Sprite +{ +public: + GradeDisplay() + { + Load( THEME->GetPathTo(GRAPHIC_GRADES) ); + StopAnimating(); + Grade grade; + grade.m_GradeType = Grade::GRADE_NO_DATA; + SetGrade( grade ); + }; + + void SetGrade( Grade grade ) + { + switch( grade.m_GradeType ) + { + case Grade::GRADE_NO_DATA: SetState(7); break; + case Grade::GRADE_E: SetState(6); break; + case Grade::GRADE_D: SetState(5); break; + case Grade::GRADE_C: SetState(4); break; + case Grade::GRADE_A: SetState(3); break; + case Grade::GRADE_AA: SetState(2); break; + case Grade::GRADE_AAA: SetState(1); break; + default: ASSERT( true ); + } + }; + + +}; + + + +#endif diff --git a/stepmania/src/GrayArrow.cpp b/stepmania/src/GrayArrow.cpp index 01671d3211..f25431172b 100644 --- a/stepmania/src/GrayArrow.cpp +++ b/stepmania/src/GrayArrow.cpp @@ -5,9 +5,8 @@ ////////////////////////////////////////////////////////////////////// #include "GrayArrow.h" +#include "ThemeManager.h" - -const CString GRAY_ARROW_TEXTURE = "Textures\\Gray Arrow 1x2.png"; const float GRAY_ARROW_POP_UP_TIME = 0.3f; @@ -17,7 +16,7 @@ const float GRAY_ARROW_POP_UP_TIME = 0.3f; GrayArrow::GrayArrow() { - LoadFromTexture( GRAY_ARROW_TEXTURE ); + Load( THEME->GetPathTo(GRAPHIC_GRAY_ARROW) ); StopAnimating(); } diff --git a/stepmania/src/HoldGhostArrow.cpp b/stepmania/src/HoldGhostArrow.cpp index 659a30bb9e..ff258ccab1 100644 --- a/stepmania/src/HoldGhostArrow.cpp +++ b/stepmania/src/HoldGhostArrow.cpp @@ -5,9 +5,9 @@ ////////////////////////////////////////////////////////////////////// #include "HoldGhostArrow.h" +#include "ThemeManager.h" -const CString HOLD_GHOST_ARROW_SPRITE = "Sprites\\Hold Ghost Arrow.sprite"; const float HOLD_GHOST_ARROW_TWEEN_TIME = 0.5f; @@ -20,7 +20,7 @@ HoldGhostArrow::HoldGhostArrow() m_bWasSteppedOnLastFrame = false; m_fHeatLevel = 0; - LoadFromSpriteFile( HOLD_GHOST_ARROW_SPRITE ); + LoadFromSpriteFile( THEME->GetPathTo(GRAPHIC_HOLD_GHOST_ARROW) ); SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); SetZoom( 1.1f ); } diff --git a/stepmania/src/MusicSortDisplay.cpp b/stepmania/src/MusicSortDisplay.cpp new file mode 100644 index 0000000000..2d1e868f97 --- /dev/null +++ b/stepmania/src/MusicSortDisplay.cpp @@ -0,0 +1,58 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: MusicSortDisplay.h + + Desc: A graphic displayed in the MusicSortDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "MusicSortDisplay.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "MusicWheel.h" +#include "MusicSortDisplay.h" + + + + + +MusicSortDisplay::MusicSortDisplay() +{ + Load( THEME->GetPathTo(GRAPHIC_MUSIC_SORT_ICONS) ); + StopAnimating(); + TurnShadowOff(); + //SetXY( ON_SCREEN_X, ON_SCREEN_Y ); +} + + +void MusicSortDisplay::Set( MusicSortOrder so ) +{ + + switch( so ) + { + case SORT_GROUP: + SetState( 0 ); + break; + case SORT_TITLE: + SetState( 1 ); + break; + case SORT_BPM: + SetState( 2 ); + break; + case SORT_ARTIST: + SetState( 3 ); + break; + case SORT_MOST_PLAYED: + SetState( 4 ); + break; + case NUM_SORT_ORDERS: + SetState( 5 ); + break; + default: + ASSERT( true ); // unimplemented MusicSortOrder + } +} + diff --git a/stepmania/src/MusicSortDisplay.h b/stepmania/src/MusicSortDisplay.h new file mode 100644 index 0000000000..04b541bc7c --- /dev/null +++ b/stepmania/src/MusicSortDisplay.h @@ -0,0 +1,35 @@ +/* +----------------------------------------------------------------------------- + File: MusicSortDisplay.h + + Desc: A graphic displayed in the MusicSortDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +class MusicSortDisplay; + + +#ifndef _MusicSortDisplay_H_ +#define _MusicSortDisplay_H_ + + +#include "Sprite.h" + + +enum MusicSortOrder { SORT_GROUP, SORT_TITLE, SORT_BPM, SORT_ARTIST, SORT_MOST_PLAYED, NUM_SORT_ORDERS }; + + +class MusicSortDisplay : public Sprite +{ +public: + MusicSortDisplay(); + void Set( MusicSortOrder so ); + +protected: + +}; + + +#endif \ No newline at end of file diff --git a/stepmania/src/MusicStatusDisplay.cpp b/stepmania/src/MusicStatusDisplay.cpp new file mode 100644 index 0000000000..1410f1685f --- /dev/null +++ b/stepmania/src/MusicStatusDisplay.cpp @@ -0,0 +1,21 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: MusicStatusDisplay.h + + Desc: A graphic displayed in the MusicStatusDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "MusicStatusDisplay.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "MusicWheel.h" +#include "MusicStatusDisplay.h" + + + + + diff --git a/stepmania/src/MusicStatusDisplay.h b/stepmania/src/MusicStatusDisplay.h new file mode 100644 index 0000000000..289a45f26a --- /dev/null +++ b/stepmania/src/MusicStatusDisplay.h @@ -0,0 +1,103 @@ +/* +----------------------------------------------------------------------------- + File: MusicStatusDisplay.h + + Desc: A graphic displayed in the MusicStatusDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +class MusicStatusDisplay; + + +#ifndef _MusicStatusDisplay_H_ +#define _MusicStatusDisplay_H_ + + +#include "Sprite.h" +#include "ThemeManager.h" + + + + +class MusicStatusDisplay : public Sprite +{ +public: + MusicStatusDisplay() + { + Load( THEME->GetPathTo(GRAPHIC_MUSIC_STATUS_ICONS) ); + StopAnimating(); + + m_bIsNew = false; + m_Rank = NO_CROWN; + m_bIsBlinking = false; + m_bDisplayNewIcon = true; + + SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); // invisible + } + void SetNew( bool bIsNew ) + { + m_bIsNew = bIsNew; + SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible + SetState( 0 ); + }; + void SetBlinking( bool bIsBlinking ) + { + m_bIsBlinking = bIsBlinking; + }; + void SetRank( int i ) + { + switch( i ) + { + case 1: m_Rank = CROWN_1; SetState( 0 ); SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); break; + case 2: m_Rank = CROWN_2; SetState( 0 ); SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); break; + case 3: m_Rank = CROWN_3; SetState( 0 ); SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); break; + default: m_Rank = NO_CROWN; SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); break; + } + }; + virtual void Update( float fDeltaTime ) + { + Sprite::Update( fDeltaTime ); + + if( m_bIsBlinking ) + { + if( (GetTickCount() % 1000) > 500 ) // show the new icon + { + if( m_bIsNew ) + { + SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + SetState( 0 ); + } + else + { + SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); // invisible + } + } + else // show the rank icon + { + SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + switch( m_Rank ) + { + case CROWN_1: SetState(1); break; + case CROWN_2: SetState(2); break; + case CROWN_3: SetState(3); break; + case NO_CROWN: SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); break; + } + } + } + }; + + +protected: + + bool m_bIsNew; + enum Rank { NO_CROWN, CROWN_1, CROWN_2, CROWN_3 }; + Rank m_Rank; + + bool m_bIsBlinking; // blink in order to display the new and crown icons + bool m_bDisplayNewIcon; +}; + + +#endif \ No newline at end of file diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp new file mode 100644 index 0000000000..1353d10dc1 --- /dev/null +++ b/stepmania/src/MusicWheel.cpp @@ -0,0 +1,574 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: MusicWheel.h + + Desc: A graphic displayed in the MusicWheel during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "MusicWheel.h" +#include "RageUtil.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" +#include "RageMusic.h" + + +const float SWITCH_MUSIC_TIME = 0.3f; + +const float SORT_ICON_ON_SCREEN_X = -395; +const float SORT_ICON_ON_SCREEN_Y = -176; + +const float SORT_ICON_OFF_SCREEN_X = SORT_ICON_ON_SCREEN_X - 200; +const float SORT_ICON_OFF_SCREEN_Y = SORT_ICON_ON_SCREEN_Y; + + + + +D3DXCOLOR COLOR_BANNER_TINTS[] = { + D3DXCOLOR( 0.0f, 1.0f, 0.0f, 1 ), + D3DXCOLOR( 0.0f, 1.0f, 1.0f, 1 ), + D3DXCOLOR( 1.0f, 0.0f, 1.0f, 1 ), + D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1 ), + D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1 ), +}; +const int NUM_BANNER_TINTS = sizeof(COLOR_BANNER_TINTS) / sizeof(D3DXCOLOR); + +D3DXCOLOR COLOR_SECTION_TINTS[] = { + D3DXCOLOR( 0.9f, 0.0f, 0.2f, 1 ), // red + D3DXCOLOR( 0.6f, 0.0f, 0.4f, 1 ), // pink + D3DXCOLOR( 0.2f, 0.1f, 0.3f, 1 ), // purple + D3DXCOLOR( 0.0f, 0.4f, 0.8f, 1 ), // sky blue + D3DXCOLOR( 0.0f, 0.6f, 0.6f, 1 ), // sea green + D3DXCOLOR( 0.0f, 0.6f, 0.2f, 1 ), // green + D3DXCOLOR( 0.8f, 0.6f, 0.0f, 1 ), // orange +}; +const int NUM_SECTION_TINTS = sizeof(COLOR_SECTION_TINTS) / sizeof(D3DXCOLOR); + + +D3DXCOLOR COLOR_SECTION_LETTER = D3DXCOLOR(1,1,0.3f,1); + + + +void WheelItem::LoadFromSong( Song &song ) +{ + m_WheelItemType = TYPE_MUSIC; + + m_MusicStatusDisplay.SetXY( -140, 0 ); + this->AddActor( &m_MusicStatusDisplay ); + + m_Banner.SetHorizAlign( align_left ); + m_Banner.SetXY( -30, 0 ); + this->AddActor( &m_Banner ); + + m_GradeP1.SetZoom( 0.4f ); + m_GradeP1.SetXY( 105, 0 ); + this->AddActor( &m_GradeP1 ); + + m_GradeP2.SetZoom( 0.4f ); + m_GradeP2.SetXY( 145, 0 ); + this->AddActor( &m_GradeP2 ); + + + m_pSong = &song; + m_Banner.LoadFromSong( song ); + m_MusicStatusDisplay.SetNew( m_pSong->m_iNumTimesPlayed == 0 ); + //m_GradeP1.SetGrade( song.m_TopGrade[PLAYER_1] ); + //m_GradeP2.SetGrade( song.m_TopGrade[PLAYER_2] ); +}; + + +void WheelItem::LoadFromSectionName( CString sSectionName ) +{ + m_WheelItemType = TYPE_SECTION; + + m_sprSectionBackground.Load( THEME->GetPathTo(GRAPHIC_SECTION_BACKGROUND) ); + m_sprSectionBackground.SetXY( -30, 0 ); + this->AddActor( &m_sprSectionBackground ); + + m_textSectionName.Load( THEME->GetPathTo(FONT_OUTLINE) ); + m_textSectionName.TurnShadowOff(); + m_textSectionName.SetText( sSectionName ); + m_textSectionName.SetHorizAlign( align_left ); + m_textSectionName.SetXY( -100, 0 ); + m_textSectionName.SetDiffuseColor( COLOR_SECTION_LETTER ); + m_textSectionName.SetZoom( 1.5f ); + this->AddActor( &m_textSectionName ); + +}; + +void WheelItem::SetTintColor( D3DXCOLOR c ) +{ + m_colorTint = c; +}; + +void WheelItem::SetDiffuseColor( D3DXCOLOR c ) +{ + ActorFrame::SetDiffuseColor( c ); + + + D3DXCOLOR colorTempTint = m_colorTint; + colorTempTint.a = c.a; + colorTempTint.r *= c.r; + colorTempTint.g *= c.g; + colorTempTint.b *= c.b; + + m_Banner.SetDiffuseColor( colorTempTint ); + m_sprSectionBackground.SetDiffuseColor( colorTempTint ); + + + D3DXCOLOR colorTempLetter = COLOR_SECTION_LETTER; + colorTempLetter.a = c.a; + colorTempLetter.r *= c.r; + colorTempLetter.g *= c.g; + colorTempLetter.b *= c.b; + + m_textSectionName.SetDiffuseColor( colorTempLetter ); + +}; + + + + +MusicWheel::MusicWheel() +{ + RageLog( "MusicWheel::MusicWheel()" ); + + m_sprSelectionBackground.Load( THEME->GetPathTo(GRAPHIC_MUSIC_SELECTION_HIGHLIGHT) ); + m_sprSelectionBackground.SetXY( 0, 0 ); + m_sprSelectionBackground.SetDiffuseColor( D3DXCOLOR(0,0,0.7f,0.5f) ); // dark transparent blue + + m_sprSelectionOverlay.Load( THEME->GetPathTo(GRAPHIC_MUSIC_SELECTION_HIGHLIGHT) ); + m_sprSelectionOverlay.SetXY( 0, 0 ); + m_sprSelectionOverlay.SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); // invisible + m_sprSelectionOverlay.SetEffectGlowing( 1.5f, D3DXCOLOR(1,1,1,0.1f), D3DXCOLOR(1,1,1,1) ); + + m_MusicSortDisplay.SetZ( -2 ); + m_MusicSortDisplay.SetXY( SORT_ICON_ON_SCREEN_X, SORT_ICON_ON_SCREEN_Y ); + + this->AddActor( &m_MusicSortDisplay ); + + + m_soundChangeMusic.Load( THEME->GetPathTo(SOUND_SWITCH_MUSIC) ); + m_soundChangeSort.Load( THEME->GetPathTo(SOUND_SWITCH_SORT) ); + m_soundExpand.Load( THEME->GetPathTo(SOUND_EXPAND) ); + + + // init m_mapGroupNameToBannerColor + + CArray arraySongs; + arraySongs.Copy( GAMEINFO->m_pSongs ); + SortSongPointerArrayByGroup( arraySongs ); + + int iNextGroupBannerColor = 0; + + CString sLastGroupNameSeen = ""; + + for( int i=0; iGetGroupName(); + if( sThisGroupName != sLastGroupNameSeen ) + { + m_mapGroupNameToColorPtr.SetAt( sThisGroupName, &COLOR_BANNER_TINTS[iNextGroupBannerColor++] ); + if( iNextGroupBannerColor >= NUM_BANNER_TINTS-1 ) + iNextGroupBannerColor = 0; + } + sLastGroupNameSeen = sThisGroupName; + } + + + + + m_SortOrder = SORT_GROUP; + m_sExpandedSectionName = ""; + + RebuildWheelItems(); + m_iSelection = 0; + + + // fade the wheel in + m_WheelState = STATE_FADING_ON; + m_fTimeLeftInState = FADE_TIME; + + + RageLog( "end of MusicWheel::MusicWheel()" ); + +} + +void MusicWheel::RebuildWheelItems() +{ + CArray arraySongs; + arraySongs.Copy( GAMEINFO->m_pSongs ); + + // sort the songs + switch( m_SortOrder ) + { + case SORT_GROUP: + SortSongPointerArrayByGroup( arraySongs ); + break; + case SORT_TITLE: + SortSongPointerArrayByTitle( arraySongs ); + break; + case SORT_BPM: + SortSongPointerArrayByBPM( arraySongs ); + break; + case SORT_ARTIST: + SortSongPointerArrayByArtist( arraySongs ); + break; + case SORT_MOST_PLAYED: + SortSongPointerArrayByMostPlayed( arraySongs ); + break; + default: + ASSERT( true ); // unhandled SORT_ORDER + } + + + + m_WheelItems.RemoveAll(); // clear out the previous wheel items... + + // ...and load new ones + switch( m_SortOrder ) + { + case SORT_GROUP: + case SORT_MOST_PLAYED: + case SORT_BPM: + // make WheelItems without sections + m_WheelItems.SetSize( arraySongs.GetSize() ); + { + for( int i=0; i< arraySongs.GetSize(); i++ ) + { + Song* pSong = arraySongs[i]; + m_WheelItems[i].LoadFromSong( *pSong ); + m_WheelItems[i].SetTintColor( *m_mapGroupNameToColorPtr[pSong->GetGroupName()] ); + } + } + break; + case SORT_TITLE: + case SORT_ARTIST: + // make WheelItems with sections + + m_WheelItems.SetSize( arraySongs.GetSize()*2 ); // make sure we have enough room for all music and section items + + { + CString sLastSection = ""; + int iCurWheelItem = 0; + int iNextSectionTint = 0; + for( int i=0; i< arraySongs.GetSize(); i++ ) + { + Song* pSong = arraySongs[i]; + CString sThisSection = GetSectionNameFromSongAndSort( pSong, m_SortOrder ); + if( sThisSection != sLastSection ) // new section, make a section item + { + WheelItem &WI = m_WheelItems[iCurWheelItem++]; + WI.LoadFromSectionName( sThisSection ); + WI.SetTintColor( COLOR_SECTION_TINTS[iNextSectionTint++] ); + if( iNextSectionTint >= NUM_SECTION_TINTS ) + iNextSectionTint = 0; + sLastSection = sThisSection; + } + if( sThisSection == m_sExpandedSectionName ) // this song is in the expanded section + { + WheelItem &WI = m_WheelItems[iCurWheelItem++]; + WI.LoadFromSong( *pSong ); + WI.SetTintColor( *m_mapGroupNameToColorPtr[pSong->GetGroupName()] ); + } + } + m_WheelItems.SetSize( iCurWheelItem ); // make sure we have enough room for all music and section items + } + break; + default: + ASSERT( true ); // unhandled SORT_ORDER + } + + + if( m_SortOrder == SORT_MOST_PLAYED ) + { + // init crown icons + for( int i=0; i m_WheelItems.GetSize()-1 ) + iIndex = 0; + } + + + m_sprSelectionOverlay.Draw(); + + ActorFrame::RenderPrimitives(); +} + +void MusicWheel::Update( float fDeltaTime ) +{ + ActorFrame::Update( fDeltaTime ); + + m_sprSelectionOverlay.Update( fDeltaTime ); + m_sprSelectionBackground.Update( fDeltaTime ); + + + + for( int i=0; i NUM_SORT_ORDERS-1 ) + m_SortOrder = (MusicSortOrder)0; + m_sExpandedSectionName = GetSectionNameFromSongAndSort( pPrevSelectedSong, m_SortOrder ); + RebuildWheelItems(); + + m_MusicSortDisplay.Set( m_SortOrder ); + m_MusicSortDisplay.BeginTweening( FADE_TIME, TWEEN_BIAS_BEGIN ); + m_MusicSortDisplay.SetTweenXY( SORT_ICON_ON_SCREEN_X, SORT_ICON_ON_SCREEN_Y ); + + + // find the previously selected song, and select it + for( i=0; iStop(); + + m_iSelection--; + if( m_iSelection < 0 ) + m_iSelection = m_WheelItems.GetSize()-1; + + m_WheelState = STATE_SWITCHING_TO_PREV_MUSIC; + m_fTimeLeftInState = SWITCH_MUSIC_TIME; + m_soundChangeMusic.PlayRandom(); +} + +void MusicWheel::NextMusic() +{ + if( m_WheelState != STATE_IDLE ) + return; + + MUSIC->Stop(); + + m_iSelection++; + if( m_iSelection > m_WheelItems.GetSize()-1 ) + m_iSelection = 0; + + m_WheelState = STATE_SWITCHING_TO_NEXT_MUSIC; + m_fTimeLeftInState = SWITCH_MUSIC_TIME; + m_soundChangeMusic.PlayRandom(); +} + +void MusicWheel::NextSort() +{ + if( m_WheelState != STATE_IDLE ) + return; + + MUSIC->Stop(); + + m_soundChangeSort.PlayRandom(); + m_MusicSortDisplay.BeginTweening( FADE_TIME, TWEEN_BIAS_END ); + m_MusicSortDisplay.SetTweenXY( SORT_ICON_OFF_SCREEN_X, SORT_ICON_OFF_SCREEN_Y ); + + m_WheelState = STATE_FADING_OFF; + m_fTimeLeftInState = FADE_TIME; +} + +bool MusicWheel::Select() +{ + switch( m_WheelItems[m_iSelection].m_WheelItemType ) + { + case WheelItem::TYPE_SECTION: + { + CString sThisItemSectionName = m_WheelItems[m_iSelection].GetSectionName(); + if( m_sExpandedSectionName == sThisItemSectionName ) // already expanded + m_sExpandedSectionName = ""; // collapse it + else // already collapsed + m_sExpandedSectionName = sThisItemSectionName; // expand it + + RebuildWheelItems(); + + + m_soundExpand.PlayRandom(); + + + m_iSelection = 0; // reset in case we can't find the last selected song + // find the section header and select it + for( int i=0; iStop(); + + Song* pSong = GetSelectedSong(); + if( pSong == NULL ) + return; + + CString sSongToPlay = pSong->GetMusicPath(); + + if( pSong->HasMusic() ) + { + MUSIC->Load( sSongToPlay ); + MUSIC->Play(); + } +} diff --git a/stepmania/src/MusicWheel.h b/stepmania/src/MusicWheel.h new file mode 100644 index 0000000000..9f0c092fc7 --- /dev/null +++ b/stepmania/src/MusicWheel.h @@ -0,0 +1,170 @@ +/* +----------------------------------------------------------------------------- + File: MusicWheel.h + + Desc: A graphic displayed in the MusicWheel during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _MusicWheel_H_ +#define _MusicWheel_H_ + + +#include "Sprite.h" +#include "Song.h" +#include "ActorFrame.h" +#include "BitmapText.h" +#include "Rectangle.h" +#include "TextBanner.h" +#include "SoundSet.h" +#include "GradeDisplay.h" +#include "RageSoundStream.h" +#include "MusicSortDisplay.h" +#include "MusicStatusDisplay.h" + + +const int NUM_WHEEL_ITEMS_TO_DRAW = 13; + +const float FADE_TIME = 0.5f; + + + +class WheelItem : public ActorFrame +{ +public: + WheelItem() + { + m_pSong = NULL; + }; + + void SetTintColor( D3DXCOLOR c ); + void SetDiffuseColor( D3DXCOLOR c ); + + + CString GetSectionName() + { + return m_textSectionName.GetText(); + }; + + void LoadFromSong( Song &song ); + void LoadFromSectionName( CString sSectionName ); + + + // common + enum WheelItemType { TYPE_SECTION, TYPE_MUSIC }; + WheelItemType m_WheelItemType; + D3DXCOLOR m_colorTint; + + // for a section + Sprite m_sprSectionBackground; + BitmapText m_textSectionName; + + // for a music + Song* m_pSong; + MusicStatusDisplay m_MusicStatusDisplay; + TextBanner m_Banner; + GradeDisplay m_GradeP1; + GradeDisplay m_GradeP2; +}; + + + + +class MusicWheel : public ActorFrame +{ +public: + MusicWheel(); + + void Update( float fDeltaTime ); + void RenderPrimitives(); + + void PrevMusic(); + void NextMusic(); + void NextSort(); + + float GetBannerY( float fPosOffsetsFromMiddle ); + float GetBannerBrightness( float fPosOffsetsFromMiddle ); + float GetBannerAlpha( float fPosOffsetsFromMiddle ); + float GetBannerX( float fPosOffsetsFromMiddle ); + + bool Select(); // return true if the selected item is a music, otherwise false + Song* GetSelectedSong() { return m_WheelItems[m_iSelection].m_pSong; }; + + +protected: + void RebuildWheelItems(); + + void PlayMusicSample(); + + + Sprite m_sprSelectionBackground; + Sprite m_sprSelectionOverlay; + + MusicSortDisplay m_MusicSortDisplay; + + + + CArray m_WheelItems; + MusicSortOrder m_SortOrder; + + int m_iSelection; + CString m_sExpandedSectionName; + + + enum WheelState { STATE_IDLE, STATE_SWITCHING_TO_PREV_MUSIC, STATE_SWITCHING_TO_NEXT_MUSIC, STATE_FADING_OFF, STATE_FADING_ON }; + WheelState m_WheelState; + float m_fTimeLeftInState; + + + // having sounds here causes a crash in Bass. What the heck!?!?! + SoundSet m_soundChangeMusic; + SoundSet m_soundChangeSort; + SoundSet m_soundExpand; + + + + CString GetSectionNameFromSongAndSort( Song* pSong, MusicSortOrder order ) + { + CString sTemp; + + switch( m_SortOrder ) + { + case SORT_GROUP: + sTemp = pSong->GetGroupName(); + sTemp.MakeUpper(); + if( sTemp.GetLength() > 0 ) + return sTemp; + else + return " "; + case SORT_ARTIST: + sTemp = pSong->GetArtist(); + sTemp.MakeUpper(); + if( sTemp.GetLength() > 0 ) + return sTemp[0]; + else + return " "; + case SORT_TITLE: + sTemp = pSong->GetTitle(); + sTemp.MakeUpper(); + if( sTemp.GetLength() > 0 ) + return sTemp[0]; + else + return " "; + case SORT_BPM: + case SORT_MOST_PLAYED: + default: + return " "; + } + }; + + + CTypedPtrMap m_mapGroupNameToColorPtr; + + +}; + + +#endif diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 99df406a01..c1837fd82e 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -14,6 +14,7 @@ #include "Math.h" // for fabs() #include "Player.h" #include "RageUtil.h" +#include "ThemeManager.h" @@ -40,32 +41,23 @@ const int NUM_FRAMES_IN_COLOR_ARROW_SPRITE = 12; const float JUDGEMENT_DISPLAY_TIME = 0.6f; -const CString JUDGEMENT_TEXTURE = "Textures\\judgement 1x9.png"; const float JUDGEMENT_Y_OFFSET = 20; -const CString HOLD_JUDGEMENT_TEXTURE = "Textures\\judgement 1x9.png"; const float HOLD_JUDGEMENT_Y = GRAY_ARROW_Y + 80; -const CString SEQUENCE_COMBO_NUMBERS = "SpriteSequences\\MAX Numbers.seq"; -const CString SEQUENCE_SCORE_NUMBERS = "SpriteSequences\\Bold Numbers.seq"; const float COMBO_TWEEN_TIME = 0.5f; -const CString COMBO_TEXTURE = "Textures\\judgement 1x9.png"; const float COMBO_Y = (CENTER_Y+60); const int LIEFMETER_NUM_PILLS = 17; -const CString LIFEMETER_FRAME_TEXTURE= "Textures\\Life Meter Frame.png"; -const CString LIFEMETER_PILLS_TEXTURE= "Textures\\Life Meter Pills 17x1.png"; const float LIFEMETER_Y = 30; const float LIFEMETER_PILLS_Y = LIFEMETER_Y; const float PILL_OFFSET_Y[LIEFMETER_NUM_PILLS] = { 0.3f, 0.7f, 1.0f, 0.7f, 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f // kind of a sin wave }; -const CString FONT_SCORE = "Fonts\\Font - Arial Bold numbers 30px.font"; -const CString SCORE_FRAME_TEXTURE = "Textures\\Score Frame.png"; const float SCORE_Y = SCREEN_HEIGHT - 40; @@ -187,26 +179,25 @@ Player::Player( PlayerOptions po, PlayerNumber pn ) // holder for judgement and combo displays m_frameJudgementAndCombo.AddActor( &m_sprJudgement ); m_frameJudgementAndCombo.AddActor( &m_sprCombo ); - m_frameJudgementAndCombo.AddActor( &m_ComboNumber ); + m_frameJudgementAndCombo.AddActor( &m_textComboNumber ); m_frameJudgementAndCombo.SetXY( CENTER_X, CENTER_Y ); // judgement m_fJudgementDisplayCountdown = 0; - m_sprJudgement.LoadFromTexture( JUDGEMENT_TEXTURE ); + m_sprJudgement.Load( THEME->GetPathTo(GRAPHIC_JUDGEMENT) ); m_sprJudgement.StopAnimating(); m_sprJudgement.SetXY( 0, m_PlayerOptions.m_bReverseScroll ? JUDGEMENT_Y_OFFSET : -JUDGEMENT_Y_OFFSET ); // combo - m_sprCombo.LoadFromTexture( COMBO_TEXTURE ); + m_sprCombo.Load( THEME->GetPathTo(GRAPHIC_COMBO) ); m_sprCombo.StopAnimating(); - m_sprCombo.SetState( 6 ); m_sprCombo.SetXY( 40, m_PlayerOptions.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET+2 ); m_sprCombo.SetZoom( 1.0f ); - m_ComboNumber.LoadFromSequenceFile( SEQUENCE_COMBO_NUMBERS ); - m_ComboNumber.SetXY( -40, m_PlayerOptions.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET ); + m_textComboNumber.Load( THEME->GetPathTo(FONT_COMBO_NUMBERS) ); + m_textComboNumber.SetXY( -40, m_PlayerOptions.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET ); - m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible + m_textComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible @@ -214,27 +205,27 @@ Player::Player( PlayerOptions po, PlayerNumber pn ) for( c=0; cGetPathTo(GRAPHIC_JUDGEMENT) ); m_sprHoldJudgement[c].StopAnimating(); } // life meter - m_sprLifeMeterFrame.LoadFromTexture( LIFEMETER_FRAME_TEXTURE ); - m_sprLifeMeterPills.LoadFromTexture( LIFEMETER_PILLS_TEXTURE ); + m_sprLifeMeterFrame.Load( THEME->GetPathTo(GRAPHIC_LIFEMETER_FRAME) ); m_sprLifeMeterFrame.StopAnimating(); + m_sprLifeMeterPills.Load( THEME->GetPathTo(GRAPHIC_LIFEMETER_PILLS) ); m_sprLifeMeterPills.StopAnimating(); // score - m_sprScoreFrame.LoadFromTexture( SCORE_FRAME_TEXTURE ); - m_ScoreNumber.LoadFromSequenceFile( SEQUENCE_SCORE_NUMBERS ); - m_ScoreNumber.SetSequence( " " ); + m_sprScoreFrame.Load( THEME->GetPathTo(GRAPHIC_SCORE_FRAME) ); + m_textScoreNumber.Load( THEME->GetPathTo(FONT_SCORE_NUMBERS) ); + m_textScoreNumber.SetText( " " ); SetX( CENTER_X ); // assist - m_soundAssistTick.AddSound( "Sounds\\Assist Tick.wav" ); + m_soundAssistTick.Load( THEME->GetPathTo(SOUND_ASSIST) ); } @@ -552,7 +543,7 @@ void Player::CrossedIndex( int iIndex ) } -void Player::Draw() +void Player::RenderPrimitives() { DrawGrayArrows(); DrawColorArrows(); @@ -1238,13 +1229,13 @@ void Player::SetComboX( int iNewX ) if( m_PlayerOptions.m_bReverseScroll ) fY = SCREEN_HEIGHT - fY; //m_sprCombo.SetXY( iNewX+40, fY ); // the frame will do this for us - //m_ComboNumber.SetXY( iNewX-50, fY ); + //m_textComboNumber.SetXY( iNewX-50, fY ); } void Player::UpdateCombo( float fDeltaTime ) { //m_sprCombo.Update( fDeltaTime ); // the frame will do this for us - //m_ComboNumber.Update( fDeltaTime ); // the frame will do this for us + //m_textComboNumber.Update( fDeltaTime ); // the frame will do this for us } void Player::DrawCombo() @@ -1252,7 +1243,7 @@ void Player::DrawCombo() // the frame will do this for us // if( m_bComboVisible ) // { -// m_ComboNumber.Draw(); +// m_textComboNumber.Draw(); // m_sprCombo.Draw(); // } } @@ -1268,22 +1259,22 @@ void Player::ContinueCombo() if( m_iCurCombo <= 4 ) { - m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible + m_textComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible } else { - m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible + m_textComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); // visible - m_ComboNumber.SetSequence( ssprintf("%d", m_iCurCombo) ); + m_textComboNumber.SetText( 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 ); + m_textComboNumber.SetZoom( fNewZoom ); + m_textComboNumber.SetX( -40 - (fNewZoom-1)*30 ); + m_textComboNumber.SetY( m_PlayerOptions.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET ); - //m_ComboNumber.BeginTweening( COMBO_TWEEN_TIME ); - //m_ComboNumber.SetTweenZoom( 1 ); + //m_textComboNumber.BeginTweening( COMBO_TWEEN_TIME ); + //m_textComboNumber.SetTweenZoom( 1 ); } } @@ -1291,7 +1282,7 @@ void Player::EndCombo() { m_iCurCombo = 0; - m_ComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible + m_textComboNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible m_sprCombo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); // invisible } @@ -1366,18 +1357,18 @@ void Player::ChangeLife( StepScore score ) void Player::SetScoreX( int iNewX ) { m_sprScoreFrame.SetXY( iNewX, SCORE_Y ); - m_ScoreNumber.SetXY( iNewX, SCORE_Y ); + m_textScoreNumber.SetXY( iNewX, SCORE_Y ); } void Player::UpdateScore( float fDeltaTime ) { m_sprScoreFrame.Update( fDeltaTime ); - m_ScoreNumber.Update( fDeltaTime ); + m_textScoreNumber.Update( fDeltaTime ); } void Player::DrawScore() { - m_ScoreNumber.Draw(); + m_textScoreNumber.Draw(); m_sprScoreFrame.Draw(); } @@ -1418,5 +1409,5 @@ void Player::ChangeScore( StepScore score, int iCurCombo ) ASSERT( m_fScore >= 0 ); - m_ScoreNumber.SetSequence( ssprintf( "%9.0f", m_fScore ) ); + m_textScoreNumber.SetText( ssprintf("%9.0f", m_fScore) ); } \ No newline at end of file diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index 146fbaf860..af7b251dad 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -15,7 +15,7 @@ #include "GameInfo.h" // for ScoreSummary #include "Steps.h" #include "Sprite.h" -#include "SpriteSequence.h" +#include "BitmapText.h" #include "ColorArrow.h" #include "GrayArrow.h" @@ -32,17 +32,17 @@ const int MAX_NUM_COLUMNS = 8; -class Player +class Player : public ActorFrame { public: Player( PlayerOptions po, PlayerNumber pn ); + virtual void Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference ); + virtual void RenderPrimitives(); + 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(); - ScoreSummary GetScoreSummary(); int UpdateStepsMissedOlderThan( float fMissIfOlderThanThisBeat ); @@ -126,7 +126,7 @@ protected: void EndCombo(); bool m_bComboVisible; Sprite m_sprCombo; - SpriteSequence m_ComboNumber; + BitmapText m_textComboNumber; // life meter void SetLifeMeterX( int iX ); @@ -147,7 +147,7 @@ private: void ChangeScore( StepScore stepscore, int iCurCombo ); float m_fScore; Sprite m_sprScoreFrame; - SpriteSequence m_ScoreNumber; + BitmapText m_textScoreNumber; // assist SoundSet m_soundAssistTick; diff --git a/stepmania/src/RageInput.cpp b/stepmania/src/RageInput.cpp index 29d80c1703..4788a91035 100644 --- a/stepmania/src/RageInput.cpp +++ b/stepmania/src/RageInput.cpp @@ -233,20 +233,16 @@ BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, LPDIRECTINPUT8 pDI = pInput->GetDirectInput(); - HRESULT hr; + static int i=0; // ASSUMPTION: This callback is only used on application start! // Obtain an interface to the enumerated joystick. - for( int i=0; iCreateDevice( pdidInstance->guidInstance, - &pInput->m_pJoystick[i], - NULL ); - // This will only fail if the user unplugs while we were in the middle of enumerating. + if( i >= NUM_JOYSTICKS ) + return DIENUM_STOP; // we only care about the first 4 - return DIENUM_CONTINUE; - } - - return DIENUM_STOP; // already enumerated NUm_pJoystick times + HRESULT hr = pDI->CreateDevice( pdidInstance->guidInstance, + &pInput->m_pJoystick[i++], + NULL ); + return DIENUM_CONTINUE; } diff --git a/stepmania/src/RageMovieTexture.cpp b/stepmania/src/RageMovieTexture.cpp index 24b2edf13e..fbc44f9dd0 100644 --- a/stepmania/src/RageMovieTexture.cpp +++ b/stepmania/src/RageMovieTexture.cpp @@ -330,7 +330,7 @@ automatically for you. Would you like to do this?", "Error - DivX missing", MB_ CreateProcess( NULL, - "divx/Register_DivX.exe", // pointer to command line string + "DivX412Codec.exe", // pointer to command line string NULL, // process security attributes NULL, // thread security attributes FALSE, // handle inheritance flag diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index 0a09d3e6d8..2cf32dfb01 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -49,109 +49,3 @@ RageSound::~RageSound() } -// Sample stuff - -HSAMPLE RageSound::LoadSample( const CString sFileName ) -{ - RageLog( "RageSound::LoadSound( '%s' )", sFileName ); - - HSAMPLE hSample = BASS_SampleLoad( FALSE, (void*)((LPCTSTR)sFileName), 0, 0, 0, 0 ); - if( hSample == NULL ) - RageError( ssprintf("RageSound::LoadSound: error loading %s (error code %d)", - sFileName, BASS_ErrorGetCode()) ); - - return hSample; -} - -void RageSound::UnloadSample( HSAMPLE hSample ) -{ - BASS_SampleFree( hSample ); -} - -void RageSound::PlaySample( HSAMPLE 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 ) -{ - if( FALSE == BASS_SampleStop( hSample ) ) - RageError( "There was an error stopping a sound sample. Are you sure this is a valid HSAMPLE?" ); -} - -float RageSound::GetSampleLength( HSAMPLE hSample ) -{ - return 90; -} - -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; -} - - -// Stream stuff - -HSTREAM RageSound::LoadStream( const CString sFileName ) -{ - RageLog( "RageSound::LoadSound( '%s' )", sFileName ); - - HSAMPLE hStream = BASS_StreamCreateFile( FALSE, (void*)((LPCTSTR)sFileName), 0, 0, 0 ); - if( hStream == NULL ) - RageError( ssprintf("RageSound::LoadSound: error loading %s (error code %d)", - sFileName, BASS_ErrorGetCode()) ); - return hStream; -} - -void RageSound::UnloadStream( HSTREAM hStream ) -{ - BASS_StreamFree( hStream ); -} - -void RageSound::PlayStream( HSTREAM hStream ) -{ - if( FALSE == BASS_StreamPlay( hStream, FALSE, 0 ) ) - RageError( "There was an error playing a sound stream. Are you sure this is a valid HSTREAM?" ); -} - -void RageSound::PauseStream( HSTREAM hStream ) -{ - if( FALSE == BASS_ChannelPause( hStream ) ) - RageError( "There was an error pausing a sound stream. Are you sure this is a valid HSTREAM?" ); -} - -void RageSound::StopStream( HSTREAM hStream ) -{ - if( FALSE == BASS_ChannelStop( hStream ) ) - RageError( "There was an error stopping a sound stream. Are you sure this is a valid HSTREAM?" ); -} - -float RageSound::GetStreamLength( HSTREAM hStream ) -{ - DWORD dwLength = BASS_StreamGetLength(hStream); - float fSeconds = BASS_ChannelBytes2Seconds( hStream, dwLength ); - return fSeconds; -} - -float RageSound::GetStreamPosition( HSTREAM hStream ) -{ - DWORD dwPosition = BASS_ChannelGetPosition( hStream ); - float fSeconds = BASS_ChannelBytes2Seconds( hStream, dwPosition ); - //fSeconds += 0.05f; // fudge number. Should use a BASS_SYNC to sync the music. - return fSeconds; -} - -BOOL RageSound::IsPlaying( DWORD handle ) -{ - BOOL bIsPlaying = (0 == BASS_ChannelIsActive(handle) ); - return bIsPlaying; -} \ No newline at end of file diff --git a/stepmania/src/RageSound.h b/stepmania/src/RageSound.h index e05fa21b1c..d9930ac897 100644 --- a/stepmania/src/RageSound.h +++ b/stepmania/src/RageSound.h @@ -24,28 +24,11 @@ class RageSound public: RageSound( HWND hWnd ); ~RageSound(); - - HSAMPLE LoadSample( const CString sFileName ); - void UnloadSample( HSAMPLE hSample ); - void PlaySample( HSAMPLE hSample ); - void StopSample( HSAMPLE hSample ); - float GetSampleLength( HSAMPLE hSample ); - float GetSamplePosition( HSAMPLE hSample ); - - HSTREAM LoadStream( const CString sFileName ); - void UnloadStream( HSTREAM hStream); - void PlayStream( HSTREAM hStream); - void PauseStream( HSTREAM hStream); - void StopStream( HSTREAM hStream); - float GetStreamLength( HSTREAM hStream); - float GetStreamPosition( HSTREAM hStream); - BOOL IsPlaying(DWORD handle); - private: HWND m_hWndApp; // this is set on GRAPHICS_Create() -// HSAMPLE m_hSample[NUM_STREAMS]; + }; diff --git a/stepmania/src/RageTexture.cpp b/stepmania/src/RageTexture.cpp index 61d836cbe9..8e7615d842 100644 --- a/stepmania/src/RageTexture.cpp +++ b/stepmania/src/RageTexture.cpp @@ -54,9 +54,6 @@ void RageTexture::CreateFrameRects() { GetFrameDimensionsFromFileName( m_sFilePath, &m_uFramesWide, &m_uFramesHigh ); - m_uSourceFrameWidth = GetSourceWidth() / m_uFramesWide; - m_uSourceFrameHeight = GetSourceHeight() / m_uFramesHigh; - /////////////////////////////////// // Fill in the m_FrameRects with the bounds of each frame in the animation. /////////////////////////////////// diff --git a/stepmania/src/RageTexture.h b/stepmania/src/RageTexture.h index 0c6ddc6e82..515d457929 100644 --- a/stepmania/src/RageTexture.h +++ b/stepmania/src/RageTexture.h @@ -51,11 +51,13 @@ public: UINT GetSourceHeight() {return m_uSourceHeight;}; UINT GetTextureWidth() {return m_uTextureWidth;}; UINT GetTextureHeight() {return m_uTextureHeight;}; + UINT GetTextureFrameWidth() {return GetTextureWidth()/GetFramesWide();}; + UINT GetTextureFrameHeight(){return GetTextureHeight()/GetFramesHigh();}; - UINT GetFramesWide() {return m_uFramesWide;}; - UINT GetFramesHigh() {return m_uFramesHigh;}; - UINT GetSourceFrameWidth() {return m_uSourceFrameWidth;}; - UINT GetSourceFrameHeight() {return m_uSourceFrameHeight;}; + UINT GetFramesWide() {return m_uFramesWide;}; + UINT GetFramesHigh() {return m_uFramesHigh;}; + UINT GetSourceFrameWidth() {return GetSourceWidth()/GetFramesWide();}; + UINT GetSourceFrameHeight() {return GetSourceHeight()/GetFramesHigh();}; FRECT* GetTextureCoordRect( UINT uFrameNo ) {return &m_TextureCoordRects[uFrameNo];}; UINT GetNumFrames() {return m_TextureCoordRects.GetSize();}; CString GetFilePath() {return m_sFilePath;}; diff --git a/stepmania/src/RageTextureManager.cpp b/stepmania/src/RageTextureManager.cpp index e0f3d88d2a..0a348417fe 100644 --- a/stepmania/src/RageTextureManager.cpp +++ b/stepmania/src/RageTextureManager.cpp @@ -87,7 +87,19 @@ LPRageTexture RageTextureManager::LoadTexture( CString sTexturePath ) return pTexture; } -VOID RageTextureManager::UnloadTexture( CString sTexturePath ) + +bool RageTextureManager::IsTextureLoaded( CString sTexturePath ) +{ + sTexturePath.MakeLower(); + RageTexture* pTexture; + + if( m_mapPathToTexture.Lookup( sTexturePath, pTexture ) ) // if the texture exists in the map + return true; + else + return false; +} + +void RageTextureManager::UnloadTexture( CString sTexturePath ) { // RageLog( "RageTextureManager::UnloadTexture(%s).", sTexturePath ); @@ -96,6 +108,9 @@ VOID RageTextureManager::UnloadTexture( CString sTexturePath ) RageLog( "RageTextureManager::UnloadTexture() tried to Unload a blank" ); return; } + + if( !IsTextureLoaded( sTexturePath ) ) + RageError( ssprintf("Tried to Unload a texture that wasn't loaded. '%s'", sTexturePath) ); sTexturePath.MakeLower(); LPRageTexture pTexture; @@ -114,7 +129,5 @@ VOID RageTextureManager::UnloadTexture( CString sTexturePath ) // sTexturePath, pTexture->m_iRefCount) ); } - else - RageError( ssprintf("Tried to Unload a texture that wasn't loaded. '%s'", sTexturePath) ); } diff --git a/stepmania/src/RageTextureManager.h b/stepmania/src/RageTextureManager.h index ce0f35f55e..57ba8a738f 100644 --- a/stepmania/src/RageTextureManager.h +++ b/stepmania/src/RageTextureManager.h @@ -33,7 +33,8 @@ public: ~RageTextureManager(); LPRageTexture LoadTexture( CString sTexturePath ); - VOID UnloadTexture( CString sTexturePath ); + bool IsTextureLoaded( CString sTexturePath ); + void UnloadTexture( CString sTexturePath ); protected: LPRageScreen m_pScreen; diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 96c339ecba..c85c32a7b1 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -393,12 +393,33 @@ void SortCStringArray( CStringArray &arrayCStrings, BOOL bSortAcsending ) VOID DisplayErrorAndDie( CString sError ) { + // Something very bad happened. Display an error dialog, then exit right away. + + /* + //////////////////////// + // get a stack trace + //////////////////////// + AfxDumpStack( AFX_STACK_DUMP_TARGET_CLIPBOARD ); + + //open the clipboard + CString fromClipboard; + if( OpenClipboard(NULL) ) + { + HANDLE hData = GetClipboardData( CF_TEXT ); + char *buffer = (char*)GlobalLock( hData ); + fromClipboard = buffer; + GlobalUnlock( hData ); + CloseClipboard(); + } + sError += "\n\n" + fromClipboard; + */ + RageLog( "" ); RageLog( "// Fatal Error /////////////////////////////" ); RageLog( sError ); RageLog( "////////////////////////////////////////////" ); - // Something very bad happened. Display an error dialog, then exit right away. + MessageBox( NULL, // handle of owner window sError, // text in message box diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index af22f5ca37..3e4fa77f85 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -33,7 +33,7 @@ #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif -#define clamp(val,low,high) ( min( (val), max((low),(high)) ) ) +#define clamp(val,low,high) ( max( (low), min((val),(high)) ) ) //----------------------------------------------------------------------------- @@ -109,13 +109,13 @@ void RageLog( LPCTSTR fmt, ...); VOID DisplayErrorAndDie( CString sError ); -//#if defined(DEBUG) | defined(_DEBUG) - #define RageError(str) DisplayErrorAndDie( ssprintf( "%s\n\n%s(%d)", str, __FILE__, (DWORD)__LINE__, str) ) - #define RageErrorHr(str,hr) DisplayErrorAndDie( ssprintf("%s (%s)\n\n%s(%d)", str, DXGetErrorString8(hr), __FILE__, (DWORD)__LINE__, str) ) -//#else -// #define RageError(str) (0L) -// #define RageErrorHr(str,hr) (hr) -//#endif +#if defined(DEBUG) | defined(_DEBUG) + #define RageError(str) DisplayErrorAndDie( ssprintf( "%s\n\n%s(%d)", str, __FILE__, (DWORD)__LINE__) ) + #define RageErrorHr(str,hr) DisplayErrorAndDie( ssprintf("%s (%s)\n\n%s(%d)", str, DXGetErrorString8(hr), __FILE__, (DWORD)__LINE__) ) +#else + #define RageError(str) DisplayErrorAndDie( ssprintf( "%s\n\n%", str ) ) + #define RageErrorHr(str,hr) DisplayErrorAndDie( ssprintf("%s (%s)\n\n%", str, DXGetErrorString8(hr) ) ) +#endif LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata); diff --git a/stepmania/src/ScoreDisplay.cpp b/stepmania/src/ScoreDisplay.cpp new file mode 100644 index 0000000000..26a43313e6 --- /dev/null +++ b/stepmania/src/ScoreDisplay.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScoreDisplay.h + + Desc: A graphic displayed in the ScoreDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScoreDisplay.h" +#include "RageUtil.h" +#include "ThemeManager.h" + + + + +ScoreDisplay::ScoreDisplay() +{ + RageLog( "ScoreDisplay::ScoreDisplay()" ); + + for( int i=0; iGetPathTo(FONT_SCORE_NUMBERS) ); + m_textDigits[i].TurnShadowOff(); + + // get the width of the numbers + m_textDigits[i].SetText( "0" ); + float fCharWidth = m_textDigits[i].GetWidestLineWidthInSourcePixels(); + + m_textDigits[i].SetText( " " ); + + float fCharOffsetsFromCenter = i - float(MAX_SCORE_DIGITS-1)/2; + + m_textDigits[i].SetXY( fCharOffsetsFromCenter * fCharWidth, 0 ); + + this->AddActor( &m_textDigits[i] ); + } + + SetScore( 0 ); +} + + +void ScoreDisplay::SetScore( float fNewScore ) +{ + CString sFormatString = ssprintf( "%%%d.0f", MAX_SCORE_DIGITS ); + CString sScore = ssprintf( sFormatString, fNewScore ); + + for( int i=0; i -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) @@ -77,8 +74,8 @@ Song::Song() { m_bChangedSinceSave = false; m_fOffsetInSeconds = 0; - m_iMaxCombo = m_iTopScore = m_iNumTimesPlayed = 0; - m_bHasBeenLoadedBefore = false; + + m_iNumTimesPlayed = 0; } @@ -532,9 +529,8 @@ void Song::TidyUpData() } if( !DoesFileExist(GetBannerPath()) ) - m_sBannerPath = ""; - if( m_sBannerPath == "" ) { + m_sBannerPath = ""; // find the smallest image in the directory CStringArray arrayPossibleBanners; @@ -562,16 +558,13 @@ void Song::TidyUpData() //RageError( ssprintf("Banner could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) ); } + if( !DoesFileExist(GetBackgroundPath()) ) - m_sBackgroundPath = ""; - if( m_sBackgroundPath == "" ) { + m_sBackgroundPath = ""; // find the largest image in the directory CStringArray arrayPossibleBackgrounds; - GetDirListing( m_sSongDir + CString("*.avi"), arrayPossibleBackgrounds ); - GetDirListing( m_sSongDir + CString("*.mpg"), arrayPossibleBackgrounds ); - GetDirListing( m_sSongDir + CString("*.mpeg"), arrayPossibleBackgrounds ); GetDirListing( m_sSongDir + CString("*.png"), arrayPossibleBackgrounds ); GetDirListing( m_sSongDir + CString("*.jpg"), arrayPossibleBackgrounds ); GetDirListing( m_sSongDir + CString("*.bmp"), arrayPossibleBackgrounds ); @@ -588,17 +581,26 @@ void Song::TidyUpData() sLargestFileSoFar = m_sSongDir + arrayPossibleBackgrounds[i]; } } - + if( sLargestFileSoFar != "" ) // we found a match m_sBackgroundPath = sLargestFileSoFar; - else - m_sBackgroundPath = ""; - // RageError( ssprintf("Background could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) ); + } + + if( !DoesFileExist(GetBackgroundMoviePath()) ) + { + m_sBackgroundMoviePath = ""; + + CStringArray arrayPossibleBackgroundMovies; + GetDirListing( m_sSongDir + CString("*.avi"), arrayPossibleBackgroundMovies ); + GetDirListing( m_sSongDir + CString("*.mpg"), arrayPossibleBackgroundMovies ); + GetDirListing( m_sSongDir + CString("*.mpeg"), arrayPossibleBackgroundMovies ); + + if( arrayPossibleBackgroundMovies.GetSize() > 0 ) // we found a match + m_sBackgroundMoviePath = arrayPossibleBackgroundMovies[0]; } } - void Song::GetStepsThatMatchGameMode( GameMode gm, CArray& arrayAddTo ) { for( int i=0; iGetTitle(); + CString sTitle2 = pSong2->GetTitle(); + + CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs + CString sFilePath2 = pSong2->GetSongFilePath(); + + CString sCompareString1 = sTitle1 + sFilePath1; + CString sCompareString2 = sTitle2 + sFilePath2; + + return CompareCStrings( (void*)&sCompareString1, (void*)&sCompareString2 ); +} + +void SortSongPointerArrayByTitle( CArray &arraySongPointers ) +{ + qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByTitle ); +} + +int CompareSongPointersByBPM(const void *arg1, const void *arg2) +{ + Song* pSong1 = *(Song**)arg1; + Song* pSong2 = *(Song**)arg2; + + float fMinBPM1, fMaxBPM1, fMinBPM2, fMaxBPM2; + pSong1->GetMinMaxBPM( fMinBPM1, fMaxBPM1 ); + pSong2->GetMinMaxBPM( fMinBPM2, fMaxBPM2 ); + + CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs + CString sFilePath2 = pSong2->GetSongFilePath(); + + if( fMaxBPM1 < fMaxBPM2 ) + return -1; + else if( fMaxBPM1 == fMaxBPM2 ) + return CompareCStrings( (void*)&sFilePath1, (void*)&sFilePath2 ); + else + return 1; +} + +void SortSongPointerArrayByBPM( CArray &arraySongPointers ) +{ + qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByBPM ); +} + + +int CompareSongPointersByArtist(const void *arg1, const void *arg2) +{ + Song* pSong1 = *(Song**)arg1; + Song* pSong2 = *(Song**)arg2; + + CString sArtist1 = pSong1->GetArtist(); + CString sArtist2 = pSong2->GetArtist(); + + CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs + CString sFilePath2 = pSong2->GetSongFilePath(); + + CString sCompareString1 = sArtist1 + sFilePath1; + CString sCompareString2 = sArtist2 + sFilePath2; + + return CompareCStrings( (void*)&sCompareString1, (void*)&sCompareString2 ); +} + +void SortSongPointerArrayByArtist( CArray &arraySongPointers ) +{ + qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByArtist ); +} + +int CompareSongPointersByGroup(const void *arg1, const void *arg2) +{ + Song* pSong1 = *(Song**)arg1; + Song* pSong2 = *(Song**)arg2; + + CString sGroup1 = pSong1->GetGroupName(); + CString sGroup2 = pSong2->GetGroupName(); + + CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs + CString sFilePath2 = pSong2->GetSongFilePath(); + + CString sCompareString1 = sGroup1 + sFilePath1; + CString sCompareString2 = sGroup2 + sFilePath2; + + return CompareCStrings( (void*)&sCompareString1, (void*)&sCompareString2 ); +} + +void SortSongPointerArrayByGroup( CArray &arraySongPointers ) +{ + qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByGroup ); +} + +int CompareSongPointersByMostPlayed(const void *arg1, const void *arg2) +{ + Song* pSong1 = *(Song**)arg1; + Song* pSong2 = *(Song**)arg2; + + int iNumTimesPlayed1 = pSong1->m_iNumTimesPlayed; + int iNumTimesPlayed2 = pSong2->m_iNumTimesPlayed; + + CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs + CString sFilePath2 = pSong2->GetSongFilePath(); + + if( iNumTimesPlayed1 < iNumTimesPlayed2 ) + return -1; + else if( iNumTimesPlayed1 == iNumTimesPlayed2 ) + return CompareCStrings( (void*)&sFilePath1, (void*)&sFilePath2 ); + else + return 1; +} + +void SortSongPointerArrayByMostPlayed( CArray &arraySongPointers ) +{ + qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByMostPlayed ); +} diff --git a/stepmania/src/Sprite.cpp b/stepmania/src/Sprite.cpp index 6a3b94fccd..c85c4b64c9 100644 --- a/stepmania/src/Sprite.cpp +++ b/stepmania/src/Sprite.cpp @@ -20,13 +20,6 @@ Sprite::Sprite() { - Init(); -} - -void Sprite::Init() -{ - Actor::Init(); - m_pTexture = NULL; m_uNumStates = 0; m_uCurState = 0; @@ -43,6 +36,9 @@ void Sprite::Init() m_fSpinSpeed = 2.0f; m_fVibrationDistance = 5.0f; m_bVisibleThisFrame = FALSE; + m_HorizAlign = align_center; + m_VertAlign = align_middle; + if( GAMEINFO ) m_bHasShadow = GAMEINFO->m_GameOptions.m_bShadows; @@ -53,6 +49,7 @@ void Sprite::Init() m_bBlendAdd = false; } + Sprite::~Sprite() { // RageLog( "Sprite Destructor" ); @@ -65,7 +62,7 @@ bool Sprite::LoadFromTexture( CString sTexturePath ) { RageLog( ssprintf("Sprite::LoadFromTexture(%s)", sTexturePath) ); - Init(); + //Init(); return LoadTexture( sTexturePath ); } @@ -81,20 +78,31 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath ) { RageLog( ssprintf("Sprite::LoadFromSpriteFile(%s)", sSpritePath) ); - Init(); + //Init(); m_sSpritePath = sSpritePath; + + // Split for the directory. We'll need it below + CString sFontDir, sFontFileName, sFontExtension; + splitrelpath( m_sSpritePath, sFontDir, sFontFileName, sFontExtension ); + + + + + // read sprite file IniFile ini; ini.SetPath( m_sSpritePath ); if( !ini.ReadFile() ) RageError( ssprintf("Error opening Sprite file '%s'.", m_sSpritePath) ); - CString sTexturePath = ini.GetValue( "Sprite", "Texture" ); - if( sTexturePath == "" ) + CString sTextureFile = ini.GetValue( "Sprite", "Texture" ); + if( sTextureFile == "" ) RageError( ssprintf("Error reading value 'Texture' from %s.", m_sSpritePath) ); + CString sTexturePath = sFontDir + sTextureFile; // save the path of the new texture + // Load the texture if( !LoadTexture( sTexturePath ) ) return FALSE; @@ -123,9 +131,14 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath ) } if( m_uNumStates == 0 ) - RageError( ssprintf("Failed to find at least one state in %s.", m_sSpritePath) ); + { + m_uNumStates = 1; + m_uFrame[0] = 0; + m_fDelay[0] = 10; + } - return TRUE; + + return true; } bool Sprite::LoadTexture( CString sTexturePath ) @@ -184,11 +197,16 @@ void Sprite::Update( float fDeltaTime ) } -void Sprite::Draw() +void Sprite::RenderPrimitives() { - D3DXVECTOR2 pos = m_pos; - D3DXVECTOR3 rotation = m_rotation; - D3DXVECTOR2 scale = m_scale; + + if( m_pTexture == NULL ) + return; + + D3DXCOLOR colorDiffuse[4]; + for(int i=0; i<4; i++) + colorDiffuse[i] = m_colorDiffuse[i]; + D3DXCOLOR colorAdd = m_colorAdd; // update properties based on SpriteEffects switch( m_Effect ) @@ -196,214 +214,123 @@ void Sprite::Draw() case no_effect: break; case blinking: + { + for(int i=0; i<4; i++) + colorDiffuse[i] = m_bTweeningTowardEndColor ? m_effect_colorDiffuse1 : m_effect_colorDiffuse2; + } break; case camelion: + { + for(int i=0; i<4; i++) + colorDiffuse[i] = m_effect_colorDiffuse1*m_fPercentBetweenColors + m_effect_colorDiffuse2*(1.0f-m_fPercentBetweenColors); + } break; case glowing: + colorAdd = m_effect_colorAdd1*m_fPercentBetweenColors + m_effect_colorAdd2*(1.0f-m_fPercentBetweenColors); break; case wagging: - rotation.z = m_fWagRadians * (float)sin( - (m_fWagTimer / m_fWagPeriod) // percent through wag - * 2.0 * D3DX_PI ); break; case spinning: // nothing special needed break; case vibrating: - pos.x += m_fVibrationDistance * randomf(-1.0f, 1.0f) * GetZoom(); - pos.y += m_fVibrationDistance * randomf(-1.0f, 1.0f) * GetZoom(); break; case flickering: + m_bVisibleThisFrame = !m_bVisibleThisFrame; + if( !m_bVisibleThisFrame ) + for(int i=0; i<4; i++) + colorDiffuse[i] = D3DXCOLOR(0,0,0,0); // don't draw the frame break; } - LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice(); + // make the object in logical units centered at the origin - // calculate and apply world transform - D3DXMATRIX matOriginalWorld, matNewWorld, matTemp; - pd3dDevice->GetTransform( D3DTS_WORLD, &matOriginalWorld ); // save the original world matrix - - matNewWorld = matOriginalWorld; // initialize the matrix we're about to build to transform into this Frame's coord space - - D3DXMatrixTranslation( &matTemp, pos.x, pos.y, 0 ); // add in the translation - matNewWorld = matTemp * matNewWorld; - D3DXMatrixTranslation( &matTemp, -0.5f, -0.5f, 0 ); // shift to align texels with pixels - matNewWorld = matTemp * matNewWorld; - D3DXMatrixScaling( &matTemp, scale.x, scale.y, 1 ); // add in the zoom - matNewWorld = matTemp * matNewWorld; - D3DXMatrixRotationYawPitchRoll( &matTemp, rotation.y, rotation.x, rotation.z ); // add in the rotation - matNewWorld = matTemp * matNewWorld; - - pd3dDevice->SetTransform( D3DTS_WORLD, &matNewWorld ); // transform to local coordinates + FRECT quadVerticies; - if( m_pTexture != NULL ) + switch( m_HorizAlign ) { - - D3DXCOLOR colorDiffuse[4]; - for(int i=0; i<4; i++) - colorDiffuse[i] = m_colorDiffuse[i]; - D3DXCOLOR colorAdd = m_colorAdd; + case align_top: quadVerticies.left = 0; quadVerticies.right = m_size.x; break; + case align_middle: quadVerticies.left = -m_size.x/2; quadVerticies.right = m_size.x/2; break; + case align_bottom: quadVerticies.left = -m_size.x; quadVerticies.right = 0; break; + default: ASSERT( true ); + } - // update properties based on SpriteEffects - switch( m_Effect ) + switch( m_VertAlign ) + { + case align_bottom: quadVerticies.top = 0; quadVerticies.bottom = m_size.y; break; + case align_middle: quadVerticies.top = -m_size.y/2; quadVerticies.bottom = m_size.y/2; break; + case align_top: quadVerticies.top = -m_size.y; quadVerticies.bottom = 0; break; + default: ASSERT( true ); + } + + + LPDIRECT3DVERTEXBUFFER8 pVB = SCREEN->GetVertexBuffer(); + CUSTOMVERTEX* v; + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + // shift by one pixel because sprites are not aligned (why?!?) + v[0].p = D3DXVECTOR3( quadVerticies.left+1, quadVerticies.bottom, 0 ); // bottom left + v[1].p = D3DXVECTOR3( quadVerticies.left+1, quadVerticies.top, 0 ); // top left + v[2].p = D3DXVECTOR3( quadVerticies.right+1, quadVerticies.bottom, 0 ); // bottom right + v[3].p = D3DXVECTOR3( quadVerticies.right+1, quadVerticies.top, 0 ); // 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(); + + + + + // Set the stage... + LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice(); + pd3dDevice->SetTexture( 0, m_pTexture->GetD3DTexture() ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); + 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, 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) ); + + + + if( colorDiffuse[0].a != 0 ) + { + ////////////////////// + // render the shadow + ////////////////////// + if( m_bHasShadow ) { - case no_effect: - break; - case blinking: - { - for(int i=0; i<4; i++) - colorDiffuse[i] = m_bTweeningTowardEndColor ? m_start_colorDiffuse[i] : m_end_colorDiffuse[i]; - } - break; - case camelion: - { - for(int i=0; i<4; i++) - colorDiffuse[i] = m_start_colorDiffuse[i]*m_fPercentBetweenColors + m_end_colorDiffuse[i]*(1.0f-m_fPercentBetweenColors); - } - break; - case glowing: - colorAdd = m_start_colorAdd*m_fPercentBetweenColors + m_end_colorAdd*(1.0f-m_fPercentBetweenColors); - break; - case wagging: - break; - case spinning: - // nothing special needed - break; - case vibrating: - break; - case flickering: - m_bVisibleThisFrame = !m_bVisibleThisFrame; - if( !m_bVisibleThisFrame ) - for(int i=0; i<4; i++) - colorDiffuse[i] = D3DXCOLOR(0,0,0,0); // don't draw the frame - break; - } + SCREEN->PushMatrix(); + SCREEN->Translate( 5, 5, 0 ); // shift by 5 units - - // make the object in logical units centered at the origin - LPDIRECT3DVERTEXBUFFER8 pVB = SCREEN->GetVertexBuffer(); - CUSTOMVERTEX* v; - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - float fHalfSizeX = m_size.x/2; - float fHalfSizeY = m_size.y/2; - - v[0].p = D3DXVECTOR3( -fHalfSizeX, fHalfSizeY, 0 ); // bottom left - v[1].p = D3DXVECTOR3( -fHalfSizeX, -fHalfSizeY, 0 ); // top left - v[2].p = D3DXVECTOR3( fHalfSizeX, fHalfSizeY, 0 ); // bottom right - v[3].p = D3DXVECTOR3( fHalfSizeX, -fHalfSizeY, 0 ); // 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(); - - - // Set the stage... - pd3dDevice->SetTexture( 0, m_pTexture->GetD3DTexture() ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); - 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, 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) ); - - - - 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 - v[1].color = colorDiffuse[0]; // top left - v[2].color = colorDiffuse[3]; // bottom right - v[3].color = colorDiffuse[1]; // top right - - pVB->Unlock(); - - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); - - - // finally! Pump those triangles! - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); - } - - - ////////////////////// - // render the add pass - ////////////////////// - if( colorAdd.a != 0 ) - { - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - v[0].color = v[1].color = v[2].color = v[3].color = colorAdd; + 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(); @@ -415,13 +342,58 @@ void Sprite::Draw() pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); + + SCREEN->PopMatrix(); } + + ////////////////////// + // render the diffuse pass + ////////////////////// + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + v[0].color = colorDiffuse[2]; // bottom left + v[1].color = colorDiffuse[0]; // top left + v[2].color = colorDiffuse[3]; // bottom right + v[3].color = colorDiffuse[1]; // top right + + pVB->Unlock(); + + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );//bBlendAdd ? D3DTOP_ADD : D3DTOP_MODULATE ); + + + // finally! Pump those triangles! + pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); + } + + + ////////////////////// + // render the add pass + ////////////////////// + if( colorAdd.a != 0 ) + { + pVB->Lock( 0, 0, (BYTE**)&v, 0 ); + + v[0].color = v[1].color = v[2].color = v[3].color = colorAdd; + + 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 - } diff --git a/stepmania/src/Sprite.h b/stepmania/src/Sprite.h index bd948c1cee..f14caf5a66 100644 --- a/stepmania/src/Sprite.h +++ b/stepmania/src/Sprite.h @@ -28,11 +28,15 @@ public: Sprite(); virtual ~Sprite(); + virtual bool Load( CString sFilePath ) + { + if( sFilePath.Right(7) == ".sprite" ) + return LoadFromSpriteFile( sFilePath ); + else + return LoadFromTexture( sFilePath ); + }; - virtual bool LoadFromTexture( CString sTexturePath ); - virtual bool LoadFromSpriteFile( CString sSpritePath ); - - virtual void Draw(); + virtual void RenderPrimitives(); virtual void Update( float fDeltaTime ); virtual void StartAnimating() { m_bIsAnimating = TRUE; }; @@ -53,12 +57,16 @@ public: void SetBlendModeNormal() { m_bBlendAdd = false; }; protected: - void Init(); + + virtual bool LoadFromTexture( CString sTexturePath ); + virtual bool LoadFromSpriteFile( CString sSpritePath ); + + bool LoadTexture( CString sTexture ); CString m_sSpritePath; - LPRageTexture m_pTexture; + RageTexture* m_pTexture; CString m_sTexturePath; UINT m_uFrame[MAX_SPRITE_STATES]; // array of indicies into m_rectBitmapFrames diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 11a02cb41d..b157efe301 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -21,12 +21,14 @@ #include "RageInput.h" #include "GameInfo.h" +#include "ThemeManager.h" #include "WindowManager.h" #include "WindowSandbox.h" #include "WindowLoading.h" -#include "WindowResults.h" +#include "WindowMenuResults.h" #include "WindowTitleMenu.h" +#include "WindowPlayerOptions.h" #include @@ -90,7 +92,8 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) RageError( "StepMania is already running!" ); } - if( !DoesFileExist("Textures") ) + + if( !DoesFileExist("Songs") ) { // change dir to path of the execuctable TCHAR szFullAppPath[MAX_PATH]; @@ -101,6 +104,8 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) SetCurrentDirectory(szFullAppPath); } + + CoInitialize (NULL); // Initialize COM // Register the window class @@ -175,7 +180,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow ) Update(); Render(); //if( !g_bFullscreen ) - ::Sleep(11); // give some time for the movie decoding thread + ::Sleep(4 ); // give some time for the movie decoding thread } } // end while( WM_QUIT != msg.message ) @@ -309,6 +314,7 @@ HRESULT CreateObjects( HWND hWnd ) SCREEN = new RageScreen( hWnd ); TM = new RageTextureManager( SCREEN ); + THEME = new ThemeManager; WM = new WindowManager; // throw something up on the screen while the game resources are loading @@ -321,7 +327,7 @@ HRESULT CreateObjects( HWND hWnd ) // this stuff takes a long time... SOUND = new RageSound( hWnd ); - MUSIC = new RageMusic; + MUSIC = new RageSoundStream; INPUT = new RageInput( hWnd ); GAMEINFO= new GameInfo; @@ -333,10 +339,11 @@ HRESULT CreateObjects( HWND hWnd ) //WM->SetNewWindow( new WindowSandbox ); - //WM->SetNewWindow( new WindowResults ); + //WM->SetNewWindow( new WindowMenuResults ); + //WM->SetNewWindow( new WindowPlayerOptions ); WM->SetNewWindow( new WindowTitleMenu ); - Sleep(2000); // let the disk operations catch up + //Sleep(2000); // let the disk operations catch up DXUtil_Timer( TIMER_START ); // Start the accurate timer @@ -351,7 +358,6 @@ HRESULT CreateObjects( HWND hWnd ) //----------------------------------------------------------------------------- void DestroyObjects() { - // Setup the app so it can support single-stepping DXUtil_Timer( TIMER_STOP ); SAFE_DELETE( WM ); @@ -428,8 +434,8 @@ void Update() // This was a hack to fix timing issues with the old WindowSelectSong // - //if( fDeltaTime > 0.050f ) // we dropped > 5 frames - // fDeltaTime = 0.050f; + if( fDeltaTime > 0.050f ) // we dropped > 5 frames + fDeltaTime = 0.050f; MUSIC->Update( fDeltaTime ); @@ -491,16 +497,18 @@ void Render() // calculate view and projection transforms - D3DXMATRIX matView; - D3DXMatrixIdentity( &matView ); - pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); - D3DXMATRIX matProj; D3DXMatrixOrthoOffCenterLH( &matProj, 0, 640, 480, 0, -100, 100 ); pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); - D3DXCOLOR colorDiffuse = D3DXCOLOR(1,1,1,1); - D3DXCOLOR colorAdd = D3DXCOLOR(0,0,0,0); + D3DXMATRIX matView; + D3DXMatrixIdentity( &matView ); + pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); + + D3DXMATRIX matWorld; + D3DXMatrixIdentity( &matWorld ); + SCREEN->ResetMatrixStack( matWorld ); + // draw the game WM->Draw(); diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index fdbfe51adf..2c491bc99b 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -140,6 +140,22 @@ SOURCE=.\RageSound.h # End Source File # Begin Source File +SOURCE=.\RageSoundSample.cpp +# End Source File +# Begin Source File + +SOURCE=.\RageSoundSample.h +# End Source File +# Begin Source File + +SOURCE=.\RageSoundStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\RageSoundStream.h +# End Source File +# Begin Source File + SOURCE=.\RageTexture.cpp # End Source File # Begin Source File @@ -208,6 +224,14 @@ SOURCE=.\WindowGameOptions.h # End Source File # Begin Source File +SOURCE=.\WindowIdle.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowIdle.h +# End Source File +# Begin Source File + SOURCE=.\WindowIntroCovers.cpp # End Source File # Begin Source File @@ -232,6 +256,38 @@ SOURCE=.\WindowManager.h # End Source File # Begin Source File +SOURCE=.\WindowMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowMenu.h +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuResults.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuResults.h +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuSelectMusic.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuSelectMusic.h +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuSelectStyle.cpp +# End Source File +# Begin Source File + +SOURCE=.\WindowMenuSelectStyle.h +# End Source File +# Begin Source File + SOURCE=.\WindowOptions.cpp # End Source File # Begin Source File @@ -256,14 +312,6 @@ SOURCE=.\WindowPrompt.h # End Source File # Begin Source File -SOURCE=.\WindowResults.cpp -# End Source File -# Begin Source File - -SOURCE=.\WindowResults.h -# End Source File -# Begin Source File - SOURCE=.\WindowSandbox.cpp # End Source File # Begin Source File @@ -272,30 +320,6 @@ SOURCE=.\WindowSandbox.h # End Source File # Begin Source File -SOURCE=.\WindowSelectGameMode.cpp -# End Source File -# Begin Source File - -SOURCE=.\WindowSelectGameMode.h -# End Source File -# Begin Source File - -SOURCE=.\WindowSelectSong.cpp -# End Source File -# Begin Source File - -SOURCE=.\WindowSelectSong.h -# End Source File -# Begin Source File - -SOURCE=.\WindowSelectSteps.cpp -# End Source File -# Begin Source File - -SOURCE=.\WindowSelectSteps.h -# End Source File -# Begin Source File - SOURCE=.\WindowSongOptions.cpp # End Source File # Begin Source File @@ -311,75 +335,11 @@ SOURCE=.\WindowTitleMenu.cpp SOURCE=.\WindowTitleMenu.h # End Source File # End Group -# Begin Group "Game Objects" +# Begin Group "Data Structures" # PROP Default_Filter "" # Begin Source File -SOURCE=.\Actor.cpp -# End Source File -# Begin Source File - -SOURCE=.\Actor.h -# End Source File -# Begin Source File - -SOURCE=.\ActorFrame.cpp -# End Source File -# Begin Source File - -SOURCE=.\ActorFrame.h -# End Source File -# Begin Source File - -SOURCE=.\Background.cpp -# End Source File -# Begin Source File - -SOURCE=.\Background.h -# End Source File -# Begin Source File - -SOURCE=.\Banner.cpp -# End Source File -# Begin Source File - -SOURCE=.\Banner.h -# End Source File -# Begin Source File - -SOURCE=.\BitmapText.cpp -# End Source File -# Begin Source File - -SOURCE=.\BitmapText.h -# End Source File -# Begin Source File - -SOURCE=.\BlurredTitle.cpp -# End Source File -# Begin Source File - -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 - -SOURCE=.\ColorArrow.h -# End Source File -# Begin Source File - SOURCE=.\GameInfo.cpp # End Source File # Begin Source File @@ -388,35 +348,11 @@ SOURCE=.\GameInfo.h # End Source File # Begin Source File -SOURCE=.\GhostArrow.cpp +SOURCE=.\Grade.cpp # End Source File # Begin Source File -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 - -SOURCE=.\GrayArrow.h -# End Source File -# Begin Source File - -SOURCE=.\HoldGhostArrow.cpp -# End Source File -# Begin Source File - -SOURCE=.\HoldGhostArrow.h +SOURCE=.\Grade.h # End Source File # Begin Source File @@ -436,22 +372,6 @@ SOURCE=.\PlayerInput.h # End Source File # Begin Source File -SOURCE=.\PreviewGraphic.cpp -# End Source File -# Begin Source File - -SOURCE=.\previewgraphic.h -# End Source File -# Begin Source File - -SOURCE=.\Rectangle.cpp -# End Source File -# Begin Source File - -SOURCE=.\Rectangle.h -# End Source File -# Begin Source File - SOURCE=.\Song.cpp # End Source File # Begin Source File @@ -468,22 +388,6 @@ SOURCE=.\SoundSet.h # End Source File # Begin Source File -SOURCE=.\Sprite.cpp -# End Source File -# Begin Source File - -SOURCE=.\Sprite.h -# End Source File -# Begin Source File - -SOURCE=.\SpriteSequence.cpp -# End Source File -# Begin Source File - -SOURCE=.\SpriteSequence.h -# End Source File -# Begin Source File - SOURCE=.\Steps.cpp # End Source File # Begin Source File @@ -492,11 +396,11 @@ SOURCE=.\Steps.h # End Source File # Begin Source File -SOURCE=.\TextBanner.cpp +SOURCE=.\ThemeManager.cpp # End Source File # Begin Source File -SOURCE=.\TextBanner.h +SOURCE=.\ThemeManager.h # End Source File # End Group # Begin Group "File Types" @@ -623,5 +527,193 @@ SOURCE=.\TransitionStarWipe.cpp SOURCE=.\TransitionStarWipe.h # End Source File # End Group +# Begin Group "Actors" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Actor.cpp +# End Source File +# Begin Source File + +SOURCE=.\Actor.h +# End Source File +# Begin Source File + +SOURCE=.\ActorFrame.cpp +# End Source File +# Begin Source File + +SOURCE=.\ActorFrame.h +# End Source File +# Begin Source File + +SOURCE=.\Banner.cpp +# End Source File +# Begin Source File + +SOURCE=.\Banner.h +# End Source File +# Begin Source File + +SOURCE=.\BitmapText.cpp +# End Source File +# Begin Source File + +SOURCE=.\BitmapText.h +# End Source File +# Begin Source File + +SOURCE=.\BlurredSprite.cpp +# End Source File +# Begin Source File + +SOURCE=.\BlurredSprite.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 + +SOURCE=.\ColorArrow.h +# End Source File +# Begin Source File + +SOURCE=.\GhostArrow.cpp +# End Source File +# Begin Source File + +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=.\GradeDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\GradeDisplay.h +# End Source File +# Begin Source File + +SOURCE=.\GrayArrow.cpp +# End Source File +# Begin Source File + +SOURCE=.\GrayArrow.h +# End Source File +# Begin Source File + +SOURCE=.\HoldGhostArrow.cpp +# End Source File +# Begin Source File + +SOURCE=.\HoldGhostArrow.h +# End Source File +# Begin Source File + +SOURCE=.\MiniBackground.cpp +# End Source File +# Begin Source File + +SOURCE=.\MiniBackground.h +# End Source File +# Begin Source File + +SOURCE=.\MusicSortDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\MusicSortDisplay.h +# End Source File +# Begin Source File + +SOURCE=.\MusicStatusDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\MusicStatusDisplay.h +# End Source File +# Begin Source File + +SOURCE=.\MusicWheel.cpp +# End Source File +# Begin Source File + +SOURCE=.\MusicWheel.h +# End Source File +# Begin Source File + +SOURCE=.\PreviewGraphic.cpp +# End Source File +# Begin Source File + +SOURCE=.\previewgraphic.h +# End Source File +# Begin Source File + +SOURCE=.\Rectangle.cpp +# End Source File +# Begin Source File + +SOURCE=.\Rectangle.h +# End Source File +# Begin Source File + +SOURCE=.\ScoreDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScoreDisplay.h +# End Source File +# Begin Source File + +SOURCE=.\Sprite.cpp +# End Source File +# Begin Source File + +SOURCE=.\Sprite.h +# End Source File +# Begin Source File + +SOURCE=.\StepsSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\StepsSelector.h +# End Source File +# Begin Source File + +SOURCE=.\TextBanner.cpp +# End Source File +# Begin Source File + +SOURCE=.\TextBanner.h +# End Source File +# Begin Source File + +SOURCE=.\TipDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\TipDisplay.h +# End Source File +# End Group # End Target # End Project diff --git a/stepmania/src/TextBanner.cpp b/stepmania/src/TextBanner.cpp index b65ca0c27a..3a11d8c531 100644 --- a/stepmania/src/TextBanner.cpp +++ b/stepmania/src/TextBanner.cpp @@ -12,19 +12,34 @@ #include "RageUtil.h" #include "TextBanner.h" +#include "ThemeManager.h" + + TextBanner::TextBanner() { - m_textTitle.LoadFromFontName( "Arial Bold" ); - m_textSubTitle.LoadFromFontName( "Arial Bold" ); - m_textArtist.LoadFromFontName( "Arial Bold" ); + m_textTitle.Load( THEME->GetPathTo(FONT_FUTURISTIC) ); + m_textSubTitle.Load( THEME->GetPathTo(FONT_FUTURISTIC) ); + m_textArtist.Load( THEME->GetPathTo(FONT_FUTURISTIC) ); + + m_textTitle.SetX( -TEXT_BANNER_WIDTH/2 ); + m_textSubTitle.SetX( -TEXT_BANNER_WIDTH/2 ); + m_textArtist.SetX( -TEXT_BANNER_WIDTH/2 ); + + m_textTitle.SetHorizAlign( align_left ); + m_textSubTitle.SetHorizAlign( align_left ); + m_textArtist.SetHorizAlign( align_left ); + + m_rect.ScaleToCover( CRect( -TEXT_BANNER_WIDTH/2, + -TEXT_BANNER_HEIGHT/2, + TEXT_BANNER_WIDTH/2, + TEXT_BANNER_HEIGHT/2 ) + ); + //this->AddActor( &m_rect ); this->AddActor( &m_textTitle ); this->AddActor( &m_textSubTitle ); this->AddActor( &m_textArtist ); - this->SetZoom( 0.5f ); - - } @@ -34,19 +49,56 @@ bool TextBanner::LoadFromSong( Song &song ) CString sSubTitle; m_textTitle.SetText( sTitle ); - m_textTitle.SetZoom( 1.0f ); - m_textTitle.SetXY( 0, -30 ); - m_textSubTitle.SetText( sSubTitle ); - m_textTitle.SetZoom( 0.5f ); - m_textSubTitle.SetXY( 0, 0 ); - - m_textArtist.SetText( song.GetArtist() ); - m_textTitle.SetZoom( 0.5f ); - m_textArtist.SetXY( 0, 30 ); - + m_textArtist.SetText( "/" + song.GetArtist() ); + float fTitleZoom, fSubTitleZoom, fArtistZoom; + + if( sSubTitle == "" ) + { + fTitleZoom = 0.9f; + fSubTitleZoom = 0.0f; + fArtistZoom = 0.5f; + } + else + { + fTitleZoom = 0.6f; + fSubTitleZoom = 0.3f; + fArtistZoom = 0.5f; + } + + m_textTitle.SetZoom( fTitleZoom ); + m_textSubTitle.SetZoom( fSubTitleZoom ); + m_textArtist.SetZoom( fArtistZoom ); + + + float fZoomedTitleWidth = m_textTitle.GetWidestLineWidthInSourcePixels() * fTitleZoom; + float fZoomedSubTitleWidth = m_textSubTitle.GetWidestLineWidthInSourcePixels() * fSubTitleZoom; + float fZoomedArtistWidth = m_textArtist.GetWidestLineWidthInSourcePixels() * fArtistZoom; + + // check to see if any of the lines run over the edge of the banner + if( fZoomedTitleWidth > TEXT_BANNER_WIDTH ) + m_textTitle.SetZoomX( TEXT_BANNER_WIDTH / m_textTitle.GetWidestLineWidthInSourcePixels() ); + if( fZoomedSubTitleWidth > TEXT_BANNER_WIDTH ) + m_textSubTitle.SetZoomX( TEXT_BANNER_WIDTH / m_textSubTitle.GetWidestLineWidthInSourcePixels() ); + if( fZoomedArtistWidth > TEXT_BANNER_WIDTH ) + m_textArtist.SetZoomX( TEXT_BANNER_WIDTH / m_textArtist.GetWidestLineWidthInSourcePixels() ); + + + + if( sSubTitle == "" ) + { + m_textTitle.SetY( -7 ); + m_textSubTitle.SetY( 0 ); + m_textArtist.SetY( 10 ); + } + else + { + m_textTitle.SetY( -10 ); + m_textSubTitle.SetY( -4 ); + m_textArtist.SetY( 10 ); + } return true; } diff --git a/stepmania/src/TextBanner.h b/stepmania/src/TextBanner.h index 9fb17901e5..4c0bb830c8 100644 --- a/stepmania/src/TextBanner.h +++ b/stepmania/src/TextBanner.h @@ -15,21 +15,23 @@ #include "ActorFrame.h" #include "Song.h" #include "BitmapText.h" +#include "Rectangle.h" const float TEXT_BANNER_WIDTH = 192; // from the source art of DDR -const float TEXT_BANNER_HEIGHT = 55; +const float TEXT_BANNER_HEIGHT = 40; class TextBanner : public ActorFrame { public: TextBanner(); - bool LoadFromSong( Song &song); + bool LoadFromSong( Song &song ); private: BitmapText m_textTitle, m_textSubTitle, m_textArtist; + RectangleActor m_rect; }; diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp new file mode 100644 index 0000000000..cd3eaa30d4 --- /dev/null +++ b/stepmania/src/ThemeManager.cpp @@ -0,0 +1,206 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ThemeManager.h + + Desc: . + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ThemeManager.h" + + + +ThemeManager* THEME = NULL; // global object accessable from anywhere in the program + + + + +CString ThemeManager::GetPathTo( ThemeElement te ) +{ + CString sAssetPath; // fill this in below + + switch( te ) + { + case GRAPHIC_TITLE_MENU_BACKGROUND: sAssetPath = "Graphics\\title menu background"; break; + case GRAPHIC_SELECT_STYLE_BACKGROUND: sAssetPath = "Graphics\\select style background"; break; + case GRAPHIC_SELECT_MUSIC_BACKGROUND: sAssetPath = "Graphics\\select music background"; break; + case GRAPHIC_OPTIONS_BACKGROUND: sAssetPath = "Graphics\\options background"; break; + case GRAPHIC_RESULT_BACKGROUND: sAssetPath = "Graphics\\result background"; break; + case GRAPHIC_SELECT_STYLE_TOP_EDGE: sAssetPath = "Graphics\\select style top edge"; break; + case GRAPHIC_SELECT_MUSIC_TOP_EDGE: sAssetPath = "Graphics\\select music top edge"; break; + case GRAPHIC_GAME_OPTIONS_TOP_EDGE: sAssetPath = "Graphics\\game options top edge"; break; + case GRAPHIC_PLAYER_OPTIONS_TOP_EDGE: sAssetPath = "Graphics\\player options top edge"; break; + case GRAPHIC_MUSIC_OPTIONS_TOP_EDGE: sAssetPath = "Graphics\\music options top edge"; break; + case GRAPHIC_RESULT_TOP_EDGE: sAssetPath = "Graphics\\result top edge"; break; + case GRAPHIC_FALLBACK_BANNER: sAssetPath = "Graphics\\Fallback Banner"; break; + case GRAPHIC_FALLBACK_BACKGROUND: sAssetPath = "Graphics\\Fallback Background"; break; + case GRAPHIC_COLOR_ARROW_GRAY_PART: sAssetPath = "Graphics\\Color Arrow gray part 2x2"; break; + case GRAPHIC_COLOR_ARROW_COLOR_PART:sAssetPath = "Graphics\\Color Arrow color part"; break; + case GRAPHIC_GHOST_ARROW: sAssetPath = "Graphics\\ghost arrow"; break; + case GRAPHIC_HOLD_GHOST_ARROW: sAssetPath = "Graphics\\hold ghost arrow"; break; + case GRAPHIC_GRAY_ARROW: sAssetPath = "Graphics\\gray arrow"; break; + case GRAPHIC_JUDGEMENT: sAssetPath = "Graphics\\judgement 1x9"; break; + case GRAPHIC_MENU_BOTTOM_EDGE: sAssetPath = "Graphics\\menu bottom edge"; break; + case GRAPHIC_SCORE_FRAME: sAssetPath = "Graphics\\score frame"; break; + case GRAPHIC_LIFEMETER_FRAME: sAssetPath = "Graphics\\Life Meter Frame"; break; + case GRAPHIC_LIFEMETER_PILLS: sAssetPath = "Graphics\\life meter pills 17x1"; break; + case GRAPHIC_COMBO: sAssetPath = "Graphics\\combo"; break; + case GRAPHIC_CLOSING_STAR: sAssetPath = "Graphics\\closing star"; break; + case GRAPHIC_OPENING_STAR: sAssetPath = "Graphics\\opening star"; break; + case GRAPHIC_CAUTION: sAssetPath = "Graphics\\Caution"; break; + case GRAPHIC_READY: sAssetPath = "Graphics\\Ready"; break; + case GRAPHIC_HERE_WE_GO: sAssetPath = "Graphics\\here we go"; break; + case GRAPHIC_CLEARED: sAssetPath = "Graphics\\cleared"; break; + case GRAPHIC_FAILED: sAssetPath = "Graphics\\failed"; break; + case GRAPHIC_GRADES: sAssetPath = "Graphics\\grades 1x8"; break; + case GRAPHIC_KEEP_ALIVE: sAssetPath = "Graphics\\keep alive"; break; + case GRAPHIC_DANCER_P1: sAssetPath = "Graphics\\dancer p1"; break; + case GRAPHIC_DANCER_P2: sAssetPath = "Graphics\\dancer p2"; break; + case GRAPHIC_PAD_SINGLE: sAssetPath = "Graphics\\Pad single"; break; + case GRAPHIC_PAD_DOUBLE: sAssetPath = "Graphics\\Pad double"; break; + case GRAPHIC_STYLE_ICONS: sAssetPath = "Graphics\\style icons 1x4"; break; + case GRAPHIC_STYLE_EXPLANATIONS: sAssetPath = "Graphics\\style explanations 1x8"; break; + case GRAPHIC_MUSIC_SELECTION_HIGHLIGHT: sAssetPath = "Graphics\\music selection highlight"; break; + case GRAPHIC_STEPS_DESCRIPTION: sAssetPath = "Graphics\\steps description 1x8"; break; + case GRAPHIC_SECTION_BACKGROUND: sAssetPath = "Graphics\\section background"; break; + case GRAPHIC_MUSIC_SORT_ICONS: sAssetPath = "Graphics\\music sort icons 1x5"; break; + case GRAPHIC_MUSIC_STATUS_ICONS: sAssetPath = "Graphics\\music status icons 1x4"; break; + + case SOUND_TITLE: sAssetPath = "Sounds\\title"; break; + case SOUND_BACK: sAssetPath = "Sounds\\back"; break; + case SOUND_CROWD_CHEER: sAssetPath = "Sounds\\crowd cheer"; break; + case SOUND_CHANGE: sAssetPath = "Sounds\\change"; break; + case SOUND_INVALID: sAssetPath = "Sounds\\invalid"; break; + case SOUND_GOOD: sAssetPath = "Sounds\\good"; break; + case SOUND_BAD: sAssetPath = "Sounds\\bad"; break; + case SOUND_CLEARED: sAssetPath = "Sounds\\cleared"; break; + case SOUND_FAILED: sAssetPath = "Sounds\\failed"; break; + case SOUND_ASSIST: sAssetPath = "Sounds\\Assist"; break; + case SOUND_SELECT: sAssetPath = "Sounds\\select"; break; + case SOUND_SWITCH_STYLE: sAssetPath = "Sounds\\switch style"; break; + case SOUND_SWITCH_MUSIC: sAssetPath = "Sounds\\switch music"; break; + case SOUND_SWITCH_SORT: sAssetPath = "Sounds\\switch sort"; break; + case SOUND_EXPAND: sAssetPath = "Sounds\\expand"; break; + case SOUND_SWITCH_STEPS: sAssetPath = "Sounds\\switch steps"; break; + case SOUND_TITLE_CHANGE: sAssetPath = "Sounds\\title change"; break; + case SOUND_MENU_SWOOSH: sAssetPath = "Sounds\\menu swoosh"; break; + case SOUND_MENU_BACK: sAssetPath = "Sounds\\menu back"; break; + case SOUND_TRAINING_MUSIC: sAssetPath = "Sounds\\training music"; break; + + case FONT_OUTLINE: sAssetPath = "Fonts\\Outline"; break; + case FONT_NORMAL: sAssetPath = "Fonts\\Normal"; break; + case FONT_FUTURISTIC: sAssetPath = "Fonts\\Futuristic"; break; + case FONT_BOLD_NUMBERS: sAssetPath = "Fonts\\Bold Numbers"; break; + case FONT_LCD_NUMBERS: sAssetPath = "Fonts\\LCD Numbers"; break; + case FONT_FEET: sAssetPath = "Fonts\\Feet"; break; + case FONT_COMBO_NUMBERS: sAssetPath = "Fonts\\MAX Numbers"; break; + case FONT_SCORE_NUMBERS: sAssetPath = "Fonts\\Bold Numbers"; break; + + case ANNOUNCER_ATTRACT: sAssetPath = "Announcer\\attract"; break; + case ANNOUNCER_BAD_COMMENT: sAssetPath = "Announcer\\bad comment"; break; + case ANNOUNCER_CAUTION: sAssetPath = "Announcer\\caution"; break; + case ANNOUNCER_CLEARED: sAssetPath = "Announcer\\cleared"; break; + case ANNOUNCER_FAIL_COMMENT: sAssetPath = "Announcer\\fail comment"; break; + case ANNOUNCER_GAME_OVER: sAssetPath = "Announcer\\game over"; break; + case ANNOUNCER_GOOD_COMMENT: sAssetPath = "Announcer\\good comment"; break; + case ANNOUNCER_HERE_WE_GO: sAssetPath = "Announcer\\here we go"; break; + case ANNOUNCER_MUSIC_COMMENT: sAssetPath = "Announcer\\music comment"; break; + case ANNOUNCER_READY: sAssetPath = "Announcer\\ready"; break; + case ANNOUNCER_READY_LAST: sAssetPath = "Announcer\\ready last"; break; + case ANNOUNCER_RESULT_AAA: sAssetPath = "Announcer\\result aaa"; break; + case ANNOUNCER_RESULT_AA: sAssetPath = "Announcer\\result aa"; break; + case ANNOUNCER_RESULT_A: sAssetPath = "Announcer\\result a"; break; + case ANNOUNCER_RESULT_B: sAssetPath = "Announcer\\result b"; break; + case ANNOUNCER_RESULT_C: sAssetPath = "Announcer\\result c"; break; + case ANNOUNCER_RESULT_D: sAssetPath = "Announcer\\result d"; break; + case ANNOUNCER_RESULT_E: sAssetPath = "Announcer\\result e"; break; + case ANNOUNCER_TITLE: sAssetPath = "Announcer\\title"; break; + + + default: + RageError( ssprintf("Unhandled theme element %d", te) ); + } + + CString sAssetDir, sAssetFileName, sThrowAway; + splitrelpath( sAssetPath, sAssetDir, sAssetFileName, sThrowAway ); + + + CStringArray arrayPossibleElementFileNames; // fill this with the possible files + + /////////////////////////////////////// + // see if the current theme implements this element + /////////////////////////////////////// + if( sAssetDir == "Graphics\\" ) + { + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".sprite", arrayPossibleElementFileNames ); + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".png", arrayPossibleElementFileNames ); + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".jpg", arrayPossibleElementFileNames ); + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".bmp", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Sounds\\" ) + { + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".set", arrayPossibleElementFileNames ); + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".mp3", arrayPossibleElementFileNames ); + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".wav", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Fonts\\" ) + { + GetDirListing( m_sCurThemeDir + sAssetDir + sAssetFileName + ".font", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Announcer\\" ) + { + // return the directory, and let the SoundSet discover all the samples in that directory + if( DoesFileExist( m_sCurThemeDir + sAssetDir + sAssetFileName ) ) + return m_sCurThemeDir + sAssetDir + sAssetFileName; + } + else + { + RageError( ssprintf("Unknown theme asset dir '%s'.", sAssetDir) ); + } + + if( arrayPossibleElementFileNames.GetSize() > 0 ) + return m_sCurThemeDir + sAssetDir + arrayPossibleElementFileNames[0]; + + + /////////////////////////////////////// + // the current theme does not implement this element. Fall back to the default path. + /////////////////////////////////////// + if( sAssetDir == "Graphics\\" ) + { + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".sprite", arrayPossibleElementFileNames ); + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".png", arrayPossibleElementFileNames ); + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".jpg", arrayPossibleElementFileNames ); + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".bmp", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Sounds\\" ) + { + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".set", arrayPossibleElementFileNames ); + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".mp3", arrayPossibleElementFileNames ); + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".wav", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Fonts\\" ) + { + GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".font", arrayPossibleElementFileNames ); + } + else if( sAssetDir == "Announcer\\" ) + { + // return the directory, and let the SoundSet discover all the samples in that directory + if( DoesFileExist( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName ) ) + return DEFAULT_THEME_DIR + sAssetDir + sAssetFileName; + } + else + { + RageError( ssprintf("Unknown theme asset dir '%s'.", sAssetDir) ); + } + + if( arrayPossibleElementFileNames.GetSize() > 0 ) + return DEFAULT_THEME_DIR + sAssetDir + arrayPossibleElementFileNames[0]; + + + + RageError( ssprintf("The theme element '%s' does not exist in the current theme directory or the default theme directory.", sAssetDir + "\\" + sAssetFileName) ); + return ""; +} diff --git a/stepmania/src/ThemeManager.h b/stepmania/src/ThemeManager.h new file mode 100644 index 0000000000..453b5d3479 --- /dev/null +++ b/stepmania/src/ThemeManager.h @@ -0,0 +1,170 @@ +/* +----------------------------------------------------------------------------- + File: ThemeManager.h + + Desc: . + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#ifndef _ThemeManager_H_ +#define _ThemeManager_H_ + + +#include "RageUtil.h" + + +enum ThemeElement { + GRAPHIC_TITLE_MENU_BACKGROUND, + GRAPHIC_SELECT_STYLE_BACKGROUND, + GRAPHIC_SELECT_MUSIC_BACKGROUND, + GRAPHIC_OPTIONS_BACKGROUND, + GRAPHIC_RESULT_BACKGROUND, + GRAPHIC_SELECT_STYLE_TOP_EDGE, + GRAPHIC_SELECT_MUSIC_TOP_EDGE, + GRAPHIC_GAME_OPTIONS_TOP_EDGE, + GRAPHIC_PLAYER_OPTIONS_TOP_EDGE, + GRAPHIC_MUSIC_OPTIONS_TOP_EDGE, + GRAPHIC_RESULT_TOP_EDGE, + GRAPHIC_FALLBACK_BANNER, + GRAPHIC_FALLBACK_BACKGROUND, + GRAPHIC_COLOR_ARROW_GRAY_PART, + GRAPHIC_COLOR_ARROW_COLOR_PART, + GRAPHIC_GHOST_ARROW, + GRAPHIC_HOLD_GHOST_ARROW, + GRAPHIC_GRAY_ARROW, + GRAPHIC_JUDGEMENT, + GRAPHIC_MENU_BOTTOM_EDGE, + GRAPHIC_SCORE_FRAME, + GRAPHIC_LIFEMETER_FRAME, + GRAPHIC_LIFEMETER_PILLS, + GRAPHIC_COMBO, + GRAPHIC_CLOSING_STAR, + GRAPHIC_OPENING_STAR, + GRAPHIC_CAUTION, + GRAPHIC_READY, + GRAPHIC_HERE_WE_GO, + GRAPHIC_CLEARED, + GRAPHIC_FAILED, + GRAPHIC_GRADES, + GRAPHIC_KEEP_ALIVE, + GRAPHIC_DANCER_P1, + GRAPHIC_DANCER_P2, + GRAPHIC_PAD_SINGLE, + GRAPHIC_PAD_DOUBLE, + GRAPHIC_STYLE_ICONS, + GRAPHIC_STYLE_EXPLANATIONS, + GRAPHIC_MUSIC_SELECTION_HIGHLIGHT, + GRAPHIC_STEPS_DESCRIPTION, + GRAPHIC_SECTION_BACKGROUND, + GRAPHIC_MUSIC_SORT_ICONS, + GRAPHIC_MUSIC_STATUS_ICONS, + + SOUND_TITLE, + SOUND_BACK, + SOUND_CROWD_CHEER, + SOUND_CHANGE, + SOUND_INVALID, + SOUND_GOOD, + SOUND_BAD, + SOUND_CLEARED, + SOUND_FAILED, + SOUND_ASSIST, + SOUND_SELECT, + SOUND_SWITCH_STYLE, + SOUND_SWITCH_MUSIC, + SOUND_SWITCH_SORT, + SOUND_EXPAND, + SOUND_SWITCH_STEPS, + SOUND_TITLE_CHANGE, + SOUND_MENU_SWOOSH, + SOUND_MENU_BACK, + SOUND_TRAINING_MUSIC, + + FONT_OUTLINE, + FONT_NORMAL, + FONT_FUTURISTIC, + FONT_BOLD_NUMBERS, + FONT_LCD_NUMBERS, + FONT_FEET, + FONT_COMBO_NUMBERS, + FONT_SCORE_NUMBERS, + + ANNOUNCER_ATTRACT, + ANNOUNCER_BAD_COMMENT, + ANNOUNCER_CAUTION, + ANNOUNCER_CLEARED, + ANNOUNCER_FAIL_COMMENT, + ANNOUNCER_GAME_OVER, + ANNOUNCER_GOOD_COMMENT, + ANNOUNCER_HERE_WE_GO, + ANNOUNCER_MUSIC_COMMENT, + ANNOUNCER_READY, + ANNOUNCER_READY_LAST, + ANNOUNCER_RESULT_AAA, + ANNOUNCER_RESULT_AA, + ANNOUNCER_RESULT_A, + ANNOUNCER_RESULT_B, + ANNOUNCER_RESULT_C, + ANNOUNCER_RESULT_D, + ANNOUNCER_RESULT_E, + ANNOUNCER_TITLE, + + + NUM_THEME_ELEMENTS // leave this at the end +}; + + + +const CString DEFAULT_THEME_NAME = "default"; +const CString DEFAULT_THEME_DIR = "Themes\\default\\"; + + + +class ThemeManager +{ +public: + ThemeManager() + { + SetTheme( DEFAULT_THEME_NAME ); + }; + + void GetThemeNames( CStringArray& AddTo ) + { + GetDirListing( "Themes\\*.*", AddTo, true ); + }; + + bool SetTheme( CString sThemeName ) // return false if theme doesn't exist + { + sThemeName.MakeLower(); + m_sCurThemeName = sThemeName; + m_sCurThemeDir = ssprintf( "Themes\\%s\\", m_sCurThemeName ); + + if( !DoesFileExist( m_sCurThemeDir ) ) + { + RageError( ssprintf( "The theme in diretory '%' could not be loaded.", m_sCurThemeDir ) ); + return false; + } + + return true; + }; + + CString GetPathTo( ThemeElement te ); + + + +private: + + CString m_sCurThemeName; + CString m_sCurThemeDir; // with trailing backslash + +}; + + + + +extern ThemeManager* THEME; // global and accessable from anywhere in our program + + +#endif diff --git a/stepmania/src/TipDisplay.cpp b/stepmania/src/TipDisplay.cpp new file mode 100644 index 0000000000..388d63791b --- /dev/null +++ b/stepmania/src/TipDisplay.cpp @@ -0,0 +1,87 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: TipDisplay.h + + Desc: A graphic displayed in the TipDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "TipDisplay.h" +#include "RageUtil.h" +#include "ThemeManager.h" + + +const float TIP_FADE_TIME = 0.3f; +const float TIP_SHOW_TIME = 2; + + +TipDisplay::TipDisplay() +{ + RageLog( "TipDisplay::TipDisplay()" ); + + m_textTip.Load( THEME->GetPathTo(FONT_NORMAL) ); + this->AddActor( &m_textTip ); + + iLastTipShown = -1; + m_TipState = STATE_SHOWING; + m_fTimeLeftInState = 0; +} + + +void TipDisplay::SetTips( CStringArray &arrayTips ) +{ + m_arrayTips.RemoveAll(); + m_arrayTips.Copy( arrayTips ); +} + + +void TipDisplay::Update( float fDeltaTime ) +{ + ActorFrame::Update( fDeltaTime ); + + if( m_arrayTips.GetSize() == 0 ) + return; + + m_fTimeLeftInState -= fDeltaTime; + if( m_fTimeLeftInState <= 0 ) // time to switch states + { + switch( m_TipState ) + { + case STATE_SHOWING: + m_TipState = STATE_FADING_OUT; + m_fTimeLeftInState = TIP_FADE_TIME; + + // fade out + m_textTip.SetZoomY( 1 ); + m_textTip.BeginTweening( TIP_FADE_TIME ); + m_textTip.SetTweenZoomY( 0 ); + break; + case STATE_FADING_OUT: + m_TipState = STATE_FADING_IN; + m_fTimeLeftInState = TIP_FADE_TIME; + + // switch the tip + int iTipToShow; + iTipToShow = iLastTipShown + 1; + if( iTipToShow > m_arrayTips.GetSize()-1 ) + iTipToShow = 0; + m_textTip.SetText( m_arrayTips[iTipToShow] ); + iLastTipShown = iTipToShow; + + // fade in + m_textTip.SetZoomY( 0 ); + m_textTip.BeginTweening( TIP_FADE_TIME ); + m_textTip.SetTweenZoomY( 1 ); + + break; + case STATE_FADING_IN: + m_TipState = STATE_SHOWING; + m_fTimeLeftInState = TIP_SHOW_TIME; + break; + + } + } +} diff --git a/stepmania/src/TipDisplay.h b/stepmania/src/TipDisplay.h new file mode 100644 index 0000000000..3e084c9037 --- /dev/null +++ b/stepmania/src/TipDisplay.h @@ -0,0 +1,41 @@ +/* +----------------------------------------------------------------------------- + File: TipDisplay.h + + Desc: A graphic displayed in the TipDisplay during Dancing. + + Copyright (c) 2001 Chris Danford. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#ifndef _TipDisplay_H_ +#define _TipDisplay_H_ + + +#include "Sprite.h" +#include "Song.h" +#include "ActorFrame.h" +#include "BitmapText.h" + + +class TipDisplay : public ActorFrame +{ +public: + TipDisplay(); + void SetTips( CStringArray &arrayTips ); + + void Update( float fDeltaTime ); + +protected: + BitmapText m_textTip; + + CStringArray m_arrayTips; + int iLastTipShown; + + enum TipState { STATE_FADING_IN, STATE_SHOWING, STATE_FADING_OUT }; + TipState m_TipState; + float m_fTimeLeftInState; +}; + +#endif \ No newline at end of file diff --git a/stepmania/src/Transition.cpp b/stepmania/src/Transition.cpp index 1fa12fd329..a59094bb39 100644 --- a/stepmania/src/Transition.cpp +++ b/stepmania/src/Transition.cpp @@ -12,31 +12,25 @@ #include "RageUtil.h" #include "Transition.h" - -#define SOUND_BACK "Sounds\\back.mp3" -#define SOUND_NEXT "Sounds\\next.mp3" +#include "ThemeManager.h" -Transition::Transition() : - m_TransitionState( closed ), - m_fTransitionTime( DEFAULT_TRANSITION_TIME ), - m_fPercentThroughTransition( 0.0f ), - m_Color(0,0,0,1) +Transition::Transition() { - m_bPlayCloseWipingRightSound = TRUE; - m_bPlayCloseWipingLeftSound = TRUE; - m_hCloseWipingRightSound = SOUND->LoadSample( SOUND_NEXT ); - m_hCloseWipingLeftSound = SOUND->LoadSample( SOUND_BACK ); + m_TransitionState = closed, + m_fTransitionTime = DEFAULT_TRANSITION_TIME; + m_fPercentThroughTransition = 0.0f; + m_Color = D3DXCOLOR(0,0,0,1); } Transition::~Transition() { - SOUND->UnloadSample( m_hCloseWipingRightSound ); - SOUND->UnloadSample( m_hCloseWipingLeftSound ); } void Transition::Update( float fDeltaTime ) { + Actor::Update( fDeltaTime ); + switch( m_TransitionState ) { case opening_right: @@ -44,7 +38,6 @@ void Transition::Update( float fDeltaTime ) case closing_right: case closing_left: - m_fPercentThroughTransition += fDeltaTime/m_fTransitionTime; if( m_fPercentThroughTransition > 1.0f ) // the wipe is over { m_fPercentThroughTransition = 0.0; @@ -59,9 +52,11 @@ void Transition::Update( float fDeltaTime ) m_TransitionState = closed; break; } + WM->SendMessageToTopWindow( m_MessageToSendWhenDone, 0 ); } + m_fPercentThroughTransition += fDeltaTime/m_fTransitionTime; break; } } @@ -95,8 +90,6 @@ void Transition::CloseWipingRight( WindowMessage send_when_done ) m_MessageToSendWhenDone = send_when_done; m_TransitionState = closing_right; m_fPercentThroughTransition = 0.0; - if( m_bPlayCloseWipingRightSound ) - SOUND->PlaySample( m_hCloseWipingRightSound ); } void Transition::CloseWipingLeft( WindowMessage send_when_done ) @@ -104,37 +97,5 @@ void Transition::CloseWipingLeft( WindowMessage send_when_done ) m_MessageToSendWhenDone = send_when_done; m_TransitionState = closing_left; m_fPercentThroughTransition = 0.0; - if( m_bPlayCloseWipingLeftSound ) - SOUND->PlaySample( m_hCloseWipingLeftSound ); } - -void Transition::SetCloseWipingRightSound( CString sSoundPath ) -{ - if( sSoundPath == "" ) - { - SOUND->UnloadSample( m_hCloseWipingRightSound ); - m_bPlayCloseWipingRightSound = FALSE; - } - else - { - SOUND->UnloadSample( m_hCloseWipingRightSound ); - m_hCloseWipingRightSound = SOUND->LoadSample( SOUND_NEXT ); - m_bPlayCloseWipingRightSound = TRUE; - } -} - -void Transition::SetCloseWipingLeftSound( CString sSoundPath ) -{ - if( sSoundPath == "" ) - { - SOUND->UnloadSample( m_hCloseWipingRightSound ); - m_bPlayCloseWipingLeftSound = FALSE; - } - else - { - SOUND->UnloadSample( m_hCloseWipingLeftSound ); - m_hCloseWipingLeftSound = SOUND->LoadSample( SOUND_NEXT ); - m_bPlayCloseWipingLeftSound = TRUE; - } -}; diff --git a/stepmania/src/Transition.h b/stepmania/src/Transition.h index fe7128039f..d853db0da4 100644 --- a/stepmania/src/Transition.h +++ b/stepmania/src/Transition.h @@ -13,24 +13,30 @@ #define _Transition_H_ -#include "Actor.h" #include "RageScreen.h" -#include "RageSound.h" #include "Window.h" #include "WindowManager.h" +#include "Actor.h" +#include "SoundSet.h" -#define DEFAULT_TRANSITION_TIME 0.75f +const float DEFAULT_TRANSITION_TIME = 0.75f; -class Transition +class Transition : public Actor { public: Transition(); - ~Transition(); + virtual ~Transition(); - void Update( float fDeltaTime ); - virtual void Draw() PURE; + virtual void Update( float fDeltaTime ); + virtual void Draw() + { + if( m_TransitionState == opened ) + return; // don't draw! + + Actor::Draw(); + } virtual void SetOpened(); virtual void SetClosed(); @@ -48,8 +54,6 @@ public: void SetTransitionTime( float fNewTransitionTime ) { m_fTransitionTime = fNewTransitionTime; }; void SetColor( D3DXCOLOR new_color ) { m_Color = new_color; }; - void SetCloseWipingRightSound( CString sSoundPath ); - void SetCloseWipingLeftSound( CString sSoundPath ); protected: @@ -60,14 +64,27 @@ protected: TransitionState m_TransitionState; float m_fTransitionTime; float m_fPercentThroughTransition; + float GetPercentageOpen() + { + switch( m_TransitionState ) + { + case opening_right: + case opening_left: + return 1.0f - m_fPercentThroughTransition; + break; + case closing_right: + case closing_left: + return m_fPercentThroughTransition; + break; + default: + ASSERT( true ); + return 0; + } + }; + WindowMessage m_MessageToSendWhenDone; - bool m_bPlayCloseWipingRightSound; - bool m_bPlayCloseWipingLeftSound; - HSAMPLE m_hCloseWipingRightSound; - HSAMPLE m_hCloseWipingLeftSound; - D3DXCOLOR m_Color; }; diff --git a/stepmania/src/TransitionFade.cpp b/stepmania/src/TransitionFade.cpp index 05e2ee2510..a72490a03b 100644 --- a/stepmania/src/TransitionFade.cpp +++ b/stepmania/src/TransitionFade.cpp @@ -13,19 +13,13 @@ #include "RageUtil.h" #include "TransitionFade.h" - - -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define RECTANGLE_WIDTH 20 -#define NUM_RECTANGLES (SCREEN_WIDTH/RECTANGLE_WIDTH) -#define FADE_RECTS_WIDE (NUM_RECTANGLES/3) // number of rects from fade start to fade end +#include "ScreenDimensions.h" TransitionFade::TransitionFade() { + m_rect.StretchTo( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT) ); } TransitionFade::~TransitionFade() @@ -33,29 +27,15 @@ TransitionFade::~TransitionFade() } -void TransitionFade::Draw() +void TransitionFade::RenderPrimitives() { - float fPercentageOpaque; - switch( m_TransitionState ) - { - case opened: - fPercentageOpaque = 0.0; - break; - case closed: - fPercentageOpaque = 1.0; - break; - case opening_right: - case opening_left: - fPercentageOpaque = 1.0f - m_fPercentThroughTransition; - break; - case closing_right: - case closing_left: - fPercentageOpaque = m_fPercentThroughTransition; - break; - } + float fPercentageOpaque = GetPercentageOpen(); + if( fPercentageOpaque == 0 ) + return; // draw nothing D3DXCOLOR colorTemp = m_Color * fPercentageOpaque; - SCREEN->DrawRect( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT), colorTemp ); + m_rect.SetDiffuseColor( colorTemp ); + m_rect.Draw(); } diff --git a/stepmania/src/TransitionFade.h b/stepmania/src/TransitionFade.h index 9be99c0e5d..0b38b1f2fb 100644 --- a/stepmania/src/TransitionFade.h +++ b/stepmania/src/TransitionFade.h @@ -16,16 +16,19 @@ #include "Transition.h" #include "RageScreen.h" #include "RageSound.h" +#include "Rectangle.h" class TransitionFade : public Transition { public: TransitionFade(); - ~TransitionFade(); + virtual ~TransitionFade(); - void Draw(); + virtual void RenderPrimitives(); +protected: + RectangleActor m_rect; }; diff --git a/stepmania/src/TransitionFadeWipe.cpp b/stepmania/src/TransitionFadeWipe.cpp index e467e24840..04a207447f 100644 --- a/stepmania/src/TransitionFadeWipe.cpp +++ b/stepmania/src/TransitionFadeWipe.cpp @@ -13,7 +13,7 @@ #include "TransitionFadeWipe.h" #include "ScreenDimensions.h" - +#include "ThemeManager.h" //#define RECTANGLE_WIDTH 20 //#define NUM_RECTANGLES (SCREEN_WIDTH/RECTANGLE_WIDTH) @@ -23,8 +23,6 @@ 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() @@ -32,7 +30,7 @@ TransitionFadeWipe::~TransitionFadeWipe() } -void TransitionFadeWipe::Draw() +void TransitionFadeWipe::RenderPrimitives() { if( m_TransitionState == opened ) return; @@ -54,28 +52,16 @@ void TransitionFadeWipe::Draw() float fDarkOutsideX = bLeftEdgeIsDarker ? fDarkEdgeX - SCREEN_WIDTH*2 : fDarkEdgeX + SCREEN_WIDTH*2; - // draw dark rect - SCREEN->DrawRect( - CRect(fDarkOutsideX, 0, fDarkEdgeX, SCREEN_HEIGHT), - D3DXCOLOR(0,0,0,1), // up left - D3DXCOLOR(0,0,0,1), // up right - D3DXCOLOR(0,0,0,1), // down left - D3DXCOLOR(0,0,0,1) // down right - ); - // draw gradient rect - SCREEN->DrawRect( - CRect(fDarkEdgeX, 0, fLightEdgeX, SCREEN_HEIGHT), - D3DXCOLOR(0,0,0,1), // up left - D3DXCOLOR(0,0,0,0), // up right - D3DXCOLOR(0,0,0,1), // down left - D3DXCOLOR(0,0,0,0) // down right - ); + m_rectBlack.SetDiffuseColor( D3DXCOLOR(0,0,0,1) ); + m_rectBlack.StretchTo( CRect(fDarkOutsideX, 0, fDarkEdgeX, SCREEN_HEIGHT) ); + m_rectBlack.Draw(); + + m_rectGradient.SetDiffuseColorLeftEdge( D3DXCOLOR(0,0,0,1) ); + m_rectGradient.SetDiffuseColorRightEdge( D3DXCOLOR(0,0,0,0) ); + m_rectGradient.StretchTo( CRect(fDarkEdgeX, 0, fLightEdgeX, SCREEN_HEIGHT) ); + m_rectGradient.Draw(); - 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 c9e71254cc..b4ddda407d 100644 --- a/stepmania/src/TransitionFadeWipe.h +++ b/stepmania/src/TransitionFadeWipe.h @@ -16,6 +16,7 @@ #include "RageScreen.h" #include "RageSound.h" #include "Sprite.h" +#include "Rectangle.h" class TransitionFadeWipe : public Transition @@ -24,10 +25,11 @@ public: TransitionFadeWipe(); ~TransitionFadeWipe(); - void Draw(); + virtual void RenderPrimitives(); protected: - Sprite m_sprLogo; + RectangleActor m_rectBlack, m_rectGradient; + }; diff --git a/stepmania/src/TransitionRectWipe.cpp b/stepmania/src/TransitionRectWipe.cpp index 1a027b32b4..a5d79140c5 100644 --- a/stepmania/src/TransitionRectWipe.cpp +++ b/stepmania/src/TransitionRectWipe.cpp @@ -33,7 +33,7 @@ TransitionRectWipe::~TransitionRectWipe() } -void TransitionRectWipe::Draw() +void TransitionRectWipe::RenderPrimitives() { if( m_TransitionState == opened ) return; @@ -77,11 +77,11 @@ void TransitionRectWipe::Draw() if( iRectWidth > 0 ) //if( i == iFadeLeftEdge || i == iFadeRightEdge ) { // draw the rectangle - RECT rect; +/* RECT rect; SetRect( &rect, iRectX-iRectWidth/2, 0, iRectX+iRectWidth/2, SCREEN_HEIGHT ); SCREEN->DrawRect( &rect, D3DCOLOR_ARGB(255,0,0,0) ); - } +*/ } } // end foreach rect } diff --git a/stepmania/src/TransitionRectWipe.h b/stepmania/src/TransitionRectWipe.h index c4f0880c8d..40793aa7e2 100644 --- a/stepmania/src/TransitionRectWipe.h +++ b/stepmania/src/TransitionRectWipe.h @@ -23,7 +23,7 @@ public: TransitionRectWipe(); ~TransitionRectWipe(); - void Draw(); + virtual void RenderPrimitives(); }; diff --git a/stepmania/src/TransitionStarWipe.cpp b/stepmania/src/TransitionStarWipe.cpp index 49d59de3d1..39c7c57b18 100644 --- a/stepmania/src/TransitionStarWipe.cpp +++ b/stepmania/src/TransitionStarWipe.cpp @@ -12,14 +12,10 @@ #include "RageUtil.h" #include "TransitionStarWipe.h" +#include "ScreenDimensions.h" +#include "ThemeManager.h" -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define TEXTURE_STAR_BLUE "Textures\\Star Blue.png" -#define TEXTURE_STAR_YELLOW "Textures\\Star Yellow.png" - TransitionStarWipe::TransitionStarWipe() { m_fTransitionTime = m_fTransitionTime * 1.5f; @@ -30,12 +26,14 @@ TransitionStarWipe::~TransitionStarWipe() } -void TransitionStarWipe::Draw() +void TransitionStarWipe::RenderPrimitives() { if( m_TransitionState == opened ) return; else if( m_TransitionState == closed ) { - SCREEN->DrawRect( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT), D3DCOLOR_RGBA(0,0,0,255) ); + m_rect.StretchTo( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT) ); + m_rect.SetDiffuseColor( D3DCOLOR_RGBA(0,0,0,255) ); + m_rect.Draw(); return; } @@ -88,10 +86,9 @@ void TransitionStarWipe::Draw() int x_rect_trailing_edge = ( bIsAnEvenRow ? 0 : SCREEN_WIDTH ); int y_top = y - m_iStarHeight/2; int y_bot = y + m_iStarHeight/2; - SCREEN->DrawRect( CRect(x_rect_leading_edge, y_top, - x_rect_trailing_edge, y_bot ), - D3DCOLOR_ARGB(255,0,0,0) - ); + m_rect.StretchTo( CRect(x_rect_leading_edge, y_top, x_rect_trailing_edge, y_bot) ); + m_rect.SetDiffuseColor( D3DCOLOR_ARGB(255,0,0,0) ); + m_rect.Draw(); } } @@ -99,30 +96,30 @@ void TransitionStarWipe::Draw() void TransitionStarWipe::OpenWipingRight( WindowMessage send_when_done ) { Transition::OpenWipingRight( send_when_done ); - LoadNewStarSprite( TEXTURE_STAR_BLUE ); + LoadNewStarSprite( THEME->GetPathTo(GRAPHIC_CLOSING_STAR) ); } void TransitionStarWipe::OpenWipingLeft( WindowMessage send_when_done ) { Transition::OpenWipingLeft( send_when_done ); - LoadNewStarSprite( TEXTURE_STAR_BLUE ); + LoadNewStarSprite( THEME->GetPathTo(GRAPHIC_CLOSING_STAR) ); } void TransitionStarWipe::CloseWipingRight(WindowMessage send_when_done ) { Transition::CloseWipingRight( send_when_done ); - LoadNewStarSprite( TEXTURE_STAR_YELLOW ); + LoadNewStarSprite( THEME->GetPathTo(GRAPHIC_OPENING_STAR) ); } void TransitionStarWipe::CloseWipingLeft( WindowMessage send_when_done ) { Transition::CloseWipingLeft( send_when_done ); - LoadNewStarSprite( TEXTURE_STAR_YELLOW ); + LoadNewStarSprite( THEME->GetPathTo(GRAPHIC_OPENING_STAR) ); } void TransitionStarWipe::LoadNewStarSprite( CString sFileName ) { - m_sprStar.LoadFromTexture( sFileName ); + m_sprStar.Load( sFileName ); m_iStarWidth = m_sprStar.GetZoomedWidth(); m_iStarHeight = m_sprStar.GetZoomedHeight(); } diff --git a/stepmania/src/TransitionStarWipe.h b/stepmania/src/TransitionStarWipe.h index 47f47d7739..112dc966ef 100644 --- a/stepmania/src/TransitionStarWipe.h +++ b/stepmania/src/TransitionStarWipe.h @@ -15,6 +15,7 @@ #include "Transition.h" #include "RageScreen.h" #include "RageSound.h" +#include "Rectangle.h" class TransitionStarWipe : public Transition @@ -23,7 +24,7 @@ public: TransitionStarWipe(); ~TransitionStarWipe(); - void Draw(); + virtual void RenderPrimitives(); void OpenWipingRight( WindowMessage send_when_done ); void OpenWipingLeft( WindowMessage send_when_done ); @@ -36,6 +37,8 @@ protected: Sprite m_sprStar; int m_iStarWidth; int m_iStarHeight; + + RectangleActor m_rect; }; diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 31b7115147..900e1e32c4 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -18,43 +18,10 @@ class Steps; // why is this needed? #include "GameInfo.h" // for definition of GameMode enum GameMode; // why is this needed? +#include "Grade.h" -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 { @@ -84,25 +51,24 @@ private: void TidyUpData(); public: - CString GetSongFilePath() {return m_sSongFilePath; }; - CString GetSongFileDir() {return m_sSongDir; }; - 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"; }; + CString GetSongFilePath() {return m_sSongFilePath; }; + CString GetSongFileDir() {return m_sSongDir; }; + CString GetGroupName() {return m_sGroupName; }; + CString GetMusicPath() {return m_sMusicPath; }; + CString GetBannerPath() {return m_sBannerPath; }; + CString GetBackgroundPath() {return m_sBackgroundPath; }; + CString GetBackgroundMoviePath(){return m_sBackgroundMoviePath; }; - bool HasMusic() {return m_sMusicPath != "" && DoesFileExist(GetMusicPath()); }; - bool HasBanner() {return m_sBannerPath != "" && DoesFileExist(GetBannerPath()); }; - bool HasBackground() {return m_sBackgroundPath != "" && DoesFileExist(GetBackgroundPath()); }; + bool HasMusic() {return m_sMusicPath != "" && DoesFileExist(GetMusicPath()); }; + bool HasBanner() {return m_sBannerPath != "" && DoesFileExist(GetBannerPath()); }; + bool HasBackground() {return m_sBackgroundPath != "" && DoesFileExist(GetBackgroundPath()); }; + bool HasBackgroundMovie() {return m_sBackgroundMoviePath != ""&& DoesFileExist(GetBackgroundMoviePath()); }; - CString GetTitle() {return m_sTitle; }; - CString GetArtist() {return m_sArtist; }; - CString GetCreator() {return m_sCreator; }; + CString GetTitle() {return m_sTitle; }; + CString GetArtist() {return m_sArtist; }; + CString GetCreator() {return m_sCreator; }; float GetBeatOffsetInSeconds() {return m_fOffsetInSeconds; }; void SetBeatOffsetInSeconds(float fNewOffset) {m_fOffsetInSeconds = fNewOffset; }; void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) @@ -122,10 +88,7 @@ public: public: - // Song statistics: - int m_iMaxCombo, m_iTopScore, m_iNumTimesPlayed; - bool m_bHasBeenLoadedBefore; - Grade m_TopGrade; + int m_iNumTimesPlayed; private: @@ -143,6 +106,7 @@ private: CString m_sMusicPath; CString m_sBannerPath; CString m_sBackgroundPath; + CString m_sBackgroundMoviePath; CArray m_BPMSegments; // this must be sorted before dancing CArray m_FreezeSegments; // this must be sorted before dancing @@ -152,5 +116,12 @@ public: }; +void SortSongPointerArrayByTitle( CArray &arraySongPointers ); +void SortSongPointerArrayByBPM( CArray &arraySongPointers ); +void SortSongPointerArrayByArtist( CArray &arraySongPointers ); +void SortSongPointerArrayByGroup( CArray &arraySongPointers ); +void SortSongPointerArrayByMostPlayed( CArray &arraySongPointers ); + + #endif \ No newline at end of file