diff --git a/stepmania/Utils/Bitmap Font Builder.exe b/stepmania/Utils/Bitmap Font Builder.exe deleted file mode 100755 index 0b576742fb..0000000000 Binary files a/stepmania/Utils/Bitmap Font Builder.exe and /dev/null differ diff --git a/stepmania/src/Actor.cpp b/stepmania/src/Actor.cpp index d4d0c8c2b7..9ad87f5584 100644 --- a/stepmania/src/Actor.cpp +++ b/stepmania/src/Actor.cpp @@ -16,27 +16,21 @@ Actor::Actor() { - Init(); -} - -void Actor::Init() -{ - m_size = m_start_pos = m_end_pos = D3DXVECTOR2( 0, 0 ); - 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 ); - for(int i=0; i<4; i++) m_colorDiffuse[i] = m_start_colorDiffuse[i] = m_end_colorDiffuse[i]= D3DXCOLOR( 1, 1, 1, 1 ); - m_colorAdd = m_start_colorAdd = m_end_colorAdd = D3DXCOLOR( 0, 0, 0, 0 ); - - m_TweenType = no_tween; - m_fTweenTime = 0.0f; - m_fTimeIntoTween = 0.0f; + m_size = D3DXVECTOR2( 1, 1 ); + m_pos = m_start_pos = D3DXVECTOR3( 0, 0, 0 ); + m_rotation = m_start_rotation = D3DXVECTOR3( 0, 0, 0 ); + m_scale = m_start_scale = D3DXVECTOR2( 1, 1 ); + for(int i=0; i<4; i++) m_colorDiffuse[i] = m_start_colorDiffuse[i] = D3DXCOLOR( 1, 1, 1, 1 ); + m_colorAdd = m_start_colorAdd = D3DXCOLOR( 0, 0, 0, 0 ); } -void Actor::Draw() +void Actor::Draw() // set the world matrix and calculate actor properties, the call RenderPrimitives { - D3DXVECTOR2 pos = m_pos; + SCREEN->PushMatrix(); // 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