diff --git a/stepmania/Themes/default/Graphics/LifeMeterBar frame (doubleres).png b/stepmania/Themes/default/Graphics/LifeMeterBar frame (doubleres).png index ae9b785edb..62a6faa08e 100644 Binary files a/stepmania/Themes/default/Graphics/LifeMeterBar frame (doubleres).png and b/stepmania/Themes/default/Graphics/LifeMeterBar frame (doubleres).png differ diff --git a/stepmania/Themes/default/Graphics/LifeMeterBar hot.png b/stepmania/Themes/default/Graphics/LifeMeterBar hot.png deleted file mode 100644 index 4b4ddfb240..0000000000 Binary files a/stepmania/Themes/default/Graphics/LifeMeterBar hot.png and /dev/null differ diff --git a/stepmania/Themes/default/Graphics/LifeMeterBar normal.png b/stepmania/Themes/default/Graphics/LifeMeterBar normal.png deleted file mode 100644 index 1e1ae3e028..0000000000 Binary files a/stepmania/Themes/default/Graphics/LifeMeterBar normal.png and /dev/null differ diff --git a/stepmania/Themes/default/Graphics/LifeMeterBar passing.redir b/stepmania/Themes/default/Graphics/LifeMeterBar passing.redir deleted file mode 100644 index 07a229f89b..0000000000 --- a/stepmania/Themes/default/Graphics/LifeMeterBar passing.redir +++ /dev/null @@ -1 +0,0 @@ -LifeMeterBar normal \ No newline at end of file diff --git a/stepmania/Themes/default/Graphics/StreamDisplay hot.png b/stepmania/Themes/default/Graphics/StreamDisplay hot.png new file mode 100644 index 0000000000..269362511e Binary files /dev/null and b/stepmania/Themes/default/Graphics/StreamDisplay hot.png differ diff --git a/stepmania/Themes/default/Graphics/StreamDisplay normal.png b/stepmania/Themes/default/Graphics/StreamDisplay normal.png new file mode 100644 index 0000000000..b037fc9eac Binary files /dev/null and b/stepmania/Themes/default/Graphics/StreamDisplay normal.png differ diff --git a/stepmania/Themes/default/Graphics/StreamDisplay passing.redir b/stepmania/Themes/default/Graphics/StreamDisplay passing.redir new file mode 100644 index 0000000000..2d827fdbcd --- /dev/null +++ b/stepmania/Themes/default/Graphics/StreamDisplay passing.redir @@ -0,0 +1 @@ +StreamDisplay normal \ No newline at end of file diff --git a/stepmania/src/LifeMeterBar.cpp b/stepmania/src/LifeMeterBar.cpp index 3a651b4ba6..b9c4a00415 100644 --- a/stepmania/src/LifeMeterBar.cpp +++ b/stepmania/src/LifeMeterBar.cpp @@ -23,8 +23,6 @@ LifeMeterBar::LifeMeterBar() METER_WIDTH.Load ("LifeMeterBar","MeterWidth"); METER_HEIGHT.Load ("LifeMeterBar","MeterHeight"); DANGER_THRESHOLD.Load ("LifeMeterBar","DangerThreshold"); - NUM_CHAMBERS.Load ("LifeMeterBar","NumChambers"); - NUM_STRIPS.Load ("LifeMeterBar","NumStrips"); INITIAL_VALUE.Load ("LifeMeterBar","InitialValue"); MIN_STAY_ALIVE.Load ("LifeMeterBar","MinStayAlive"); m_fLifePercentChange.Load( "LifeMeterBar", LIFE_PERCENT_CHANGE_NAME, NUM_ScoreEvent ); @@ -76,18 +74,7 @@ LifeMeterBar::LifeMeterBar() m_pStream = new StreamDisplay; bool bExtra = GAMESTATE->IsAnExtraStage(); RString sExtra = bExtra ? "extra " : ""; - m_pStream->Load( - METER_WIDTH, - METER_HEIGHT, - NUM_STRIPS, - NUM_CHAMBERS, - THEME->GetPathG(sType,sExtra+"normal"), - THEME->GetPathG(sType,sExtra+"hot"), - THEME->GetPathG(sType,sExtra+"passing"), - THEME->GetMetricA(sType,"StreamNormalOnCommand"), - THEME->GetMetricA(sType,"StreamHotOnCommand"), - THEME->GetMetricA(sType,"StreamPassingOnCommand") - ); + m_pStream->Load( bExtra ? "StreamDisplayExtra" : "StreamDisplay" ); this->AddChild( m_pStream ); m_sprFrame.Load( THEME->GetPathG(sType,sExtra+"frame") ); diff --git a/stepmania/src/LifeMeterBar.h b/stepmania/src/LifeMeterBar.h index ca9558b046..e632dbe463 100644 --- a/stepmania/src/LifeMeterBar.h +++ b/stepmania/src/LifeMeterBar.h @@ -37,8 +37,6 @@ private: ThemeMetric METER_WIDTH; ThemeMetric METER_HEIGHT; ThemeMetric DANGER_THRESHOLD; - ThemeMetric NUM_CHAMBERS; - ThemeMetric NUM_STRIPS; ThemeMetric INITIAL_VALUE; ThemeMetric MIN_STAY_ALIVE; diff --git a/stepmania/src/LifeMeterTime.cpp b/stepmania/src/LifeMeterTime.cpp index 5803803765..b3fbbcd479 100644 --- a/stepmania/src/LifeMeterTime.cpp +++ b/stepmania/src/LifeMeterTime.cpp @@ -16,8 +16,6 @@ const float FULL_LIFE_SECONDS = 1.5f*60; static ThemeMetric METER_WIDTH ("LifeMeterTime","MeterWidth"); static ThemeMetric METER_HEIGHT ("LifeMeterTime","MeterHeight"); static ThemeMetric DANGER_THRESHOLD ("LifeMeterTime","DangerThreshold"); -static ThemeMetric NUM_CHAMBERS ("LifeMeterTime","NumChambers"); -static ThemeMetric NUM_STRIPS ("LifeMeterTime","NumStrips"); static ThemeMetric INITIAL_VALUE ("LifeMeterTime","InitialValue"); static const float g_fTimeMeterSecondsChangeInit[] = @@ -73,21 +71,10 @@ void LifeMeterTime::Load( const PlayerState *pPlayerState, PlayerStageStats *pPl m_pStream = new StreamDisplay; bool bExtra = GAMESTATE->IsAnExtraStage(); - RString sExtra = bExtra ? "extra " : ""; - m_pStream->Load( - METER_WIDTH, - METER_HEIGHT, - NUM_STRIPS, - NUM_CHAMBERS, - THEME->GetPathG(sType,sExtra+"normal"), - THEME->GetPathG(sType,sExtra+"hot"), - THEME->GetPathG(sType,sExtra+"passing"), - THEME->GetMetricA(sType,"StreamNormalOnCommand"), - THEME->GetMetricA(sType,"StreamHotOnCommand"), - THEME->GetMetricA(sType,"StreamPassingOnCommand") - ); + m_pStream->Load( bExtra ? "StreamDisplayExtra" : "StreamDisplay" ); this->AddChild( m_pStream ); + RString sExtra = bExtra ? "extra " : ""; m_sprFrame.Load( THEME->GetPathG(sType,sExtra+"frame") ); m_sprFrame->SetName( "Frame" ); this->AddChild( m_sprFrame ); @@ -181,7 +168,7 @@ void LifeMeterTime::SendLifeChangedMessage( float fOldLife, TapNoteScore tns, Ho bool LifeMeterTime::IsInDanger() const { - return m_pStream->GetTrailingLifePercent() < DANGER_THRESHOLD; + return m_pStream->GetPercent() < DANGER_THRESHOLD; } bool LifeMeterTime::IsHot() const @@ -203,7 +190,6 @@ void LifeMeterTime::Update( float fDeltaTime ) LifeMeter::Update( fDeltaTime ); - // TODO m_pStream->SetPercent( GetLife() ); m_pStream->SetPassingAlpha( 0 ); m_pStream->SetHotAlpha( 0 ); diff --git a/stepmania/src/StreamDisplay.cpp b/stepmania/src/StreamDisplay.cpp index c0fc2882cd..4dc5e9e9e8 100644 --- a/stepmania/src/StreamDisplay.cpp +++ b/stepmania/src/StreamDisplay.cpp @@ -3,11 +3,18 @@ #include "GameState.h" #include #include "RageDisplay.h" +#include "ThemeManager.h" +#include "EnumHelper.h" + +static const char *StreamTypeNames[] = { + "Normal", + "Passing", + "Hot", +}; +XToString( StreamType ); StreamDisplay::StreamDisplay() { - m_iNumStrips = 1; - m_iNumChambers = 1; m_fPercent = 0; m_fTrailingPercent = 0; m_fVelocity = 0; @@ -15,63 +22,38 @@ StreamDisplay::StreamDisplay() m_fHotAlpha = 0; } -void StreamDisplay::Load( - float fMeterWidth, - float fMeterHeight, - int iNumStrips, - int iNumChambers, - const RString &sNormalPath, - const RString &sHotPath, - const RString &sPassingPath, - const apActorCommands &acNormalOnCommand, - const apActorCommands &acHotOnCommand, - const apActorCommands &acPassingOnCommand - ) +void StreamDisplay::Load( const RString &_sMetricsGroup ) { - m_size.x = fMeterWidth; - m_size.y = fMeterHeight; + // XXX + RString sMetricsGroup = "StreamDisplay"; - m_iNumStrips = iNumStrips; - m_iNumChambers = iNumChambers; + m_transformPill.SetFromReference( THEME->GetMetricR(sMetricsGroup,"PillTransformFunction") ); - m_quadMask.SetBlendMode( BLEND_NO_EFFECT ); - m_quadMask.SetZWrite( true ); - m_quadMask.ZoomToWidth( fMeterWidth ); - m_quadMask.ZoomToHeight( fMeterHeight ); + float fTextureCoordScaleX = THEME->GetMetricF(sMetricsGroup,"TextureCoordScaleX"); + int iNumPills = THEME->GetMetricF(sMetricsGroup,"NumPills"); + FOREACH_ENUM( StreamType, st ) + { + ASSERT( m_vpSprPill[st].empty() ); - RString sGraphicPath; - RageTextureID ID; - ID.bStretch = true; + for( int i=0; iLoad( THEME->GetPathG(sMetricsGroup,StreamTypeToString(st)) ); + m_vpSprPill[st].push_back( pSpr ); + m_transformPill.PositionItem( pSpr, -1, i, iNumPills ); - float fStripWidthInPercent = 1.0f/m_iNumStrips; + float f = 1 / fTextureCoordScaleX; + pSpr->SetCustomTextureRect( RectF(f*i,0,f*(i+1),1) ); - ID.filename = sNormalPath; - m_sprStreamNormal.Load( ID ); - m_sprStreamNormal.SetZTestMode( ZTEST_WRITE_ON_PASS ); - m_sprStreamNormal.SetHorizAlign( align_right ); - m_sprStreamNormal.ZoomToHeight( fMeterHeight ); - m_sprStreamNormal.ZoomToWidth( fMeterWidth*fStripWidthInPercent ); - m_sprStreamNormal.RunCommands( acNormalOnCommand ); - - ID.filename = sHotPath; - m_sprStreamHot.Load( ID ); - m_sprStreamHot.SetZTestMode( ZTEST_WRITE_ON_PASS ); - m_sprStreamHot.SetHorizAlign( align_right ); - m_sprStreamHot.ZoomToHeight( fMeterHeight ); - m_sprStreamHot.ZoomToWidth( fMeterWidth*fStripWidthInPercent ); - m_sprStreamHot.RunCommands( acHotOnCommand ); - - ID.filename = sPassingPath; - m_sprStreamPassing.Load( ID ); - m_sprStreamPassing.SetZTestMode( ZTEST_WRITE_ON_PASS ); - m_sprStreamPassing.SetHorizAlign( align_right ); - m_sprStreamPassing.ZoomToHeight( fMeterHeight ); - m_sprStreamPassing.ZoomToWidth( fMeterWidth*fStripWidthInPercent ); - m_sprStreamPassing.RunCommands( acPassingOnCommand ); + this->AddChild( pSpr ); + } + } } void StreamDisplay::Update( float fDeltaSecs ) { + ActorFrame::Update( fDeltaSecs ); + // HACK: Tweaking these values is very difficulty. Update the // "physics" many times so that the spring motion appears faster for( int i=0; i<10; i++ ) @@ -104,35 +86,39 @@ void StreamDisplay::Update( float fDeltaSecs ) // Don't clamp life percentage a little outside the visible range so // that the clamp doesn't dampen the "jiggle" of the meter. CLAMP( m_fTrailingPercent, -0.1f, 1.1f ); -} -void StreamDisplay::DrawPrimitives() -{ - DrawMask( m_fTrailingPercent ); // this is the "right endcap" to the life - - const float fChamberWidthInPercent = 1.0f/m_iNumChambers; - float fPercentBetweenStrips = 1.0f/m_iNumStrips; - // round down so that the chamber overflows align - if( m_iNumChambers > 10 ) - fPercentBetweenStrips = QuantizeDown( fPercentBetweenStrips, fChamberWidthInPercent ); - - - if( m_iNumChambers > 3 ) - fPercentBetweenStrips -= 2*fChamberWidthInPercent; - - float fPercentOffset = fmodf( GAMESTATE->m_fSongBeat/4+1000, fPercentBetweenStrips ); - ASSERT( fPercentOffset >= 0 && fPercentOffset <= fPercentBetweenStrips ); - - // "+fPercentBetweenStrips" so that the whole area is overdrawn 2x - for( float f=fPercentOffset+1+fPercentBetweenStrips; f>=0; f-=fPercentBetweenStrips ) + // set crop of pills + const float fPillWidthPercent = 1.0f / m_vpSprPill[0].size(); + FOREACH_ENUM( StreamType, st ) { - DrawMask( f ); - DrawStrip( f ); - } + for( int i=0; i<(int)m_vpSprPill[st].size(); i++ ) + { + Sprite *pSpr = m_vpSprPill[st][i]; + float fPercentFilledThisPill = SCALE( m_fTrailingPercent, fPillWidthPercent*i, fPillWidthPercent*(i+1), 0.0f, 1.0f ); + CLAMP( fPercentFilledThisPill, 0.0f, 1.0f ); + pSpr->SetCropRight( 1.0f - fPercentFilledThisPill ); + // XXX scale by current song speed + pSpr->SetTexCoordVelocity(-1,0); - // Don't leave the Zbuffer in a messy state for arrows and dancing characters - DISPLAY->ClearZBuffer(); + // Optimization: Don't draw pills that are covered up + switch( st ) + { + DEFAULT_FAIL( st ); + case StreamType_Normal: + pSpr->SetVisible( m_fPassingAlpha < 1 || m_fHotAlpha < 1 ); + pSpr->SetDiffuseAlpha( 1 ); + break; + case StreamType_Passing: + pSpr->SetDiffuseAlpha( m_fPassingAlpha ); + pSpr->SetVisible( m_fHotAlpha < 1 ); + break; + case StreamType_Hot: + pSpr->SetDiffuseAlpha( m_fHotAlpha ); + break; + } + } + } } void StreamDisplay::SetPercent( float fPercent ) @@ -154,118 +140,6 @@ void StreamDisplay::SetPercent( float fPercent ) m_fPercent = fPercent; } -void StreamDisplay::SetPassingAlpha( float fPassingAlpha ) -{ - m_fPassingAlpha = fPassingAlpha; -} - -void StreamDisplay::SetHotAlpha( float fHotAlpha ) -{ - m_fHotAlpha = fHotAlpha; -} - -void StreamDisplay::GetChamberIndexAndOverflow( float fPercent, int& iChamberOut, float& fChamberOverflowPercentOut ) -{ - iChamberOut = (int)(fPercent*m_iNumChambers); - fChamberOverflowPercentOut = fPercent*m_iNumChambers - iChamberOut; -} - -float StreamDisplay::GetChamberLeftPercent( int iChamber ) -{ - return (iChamber+0) / (float)m_iNumChambers; -} - -float StreamDisplay::GetChamberRightPercent( int iChamber ) -{ - return (iChamber+1) / (float)m_iNumChambers; -} - -float StreamDisplay::GetRightEdgePercent( int iChamber, float fChamberOverflowPercent ) -{ - if( (iChamber%2) == 0 ) - return (iChamber+fChamberOverflowPercent) / (float)m_iNumChambers; - else - return (iChamber+1) / (float)m_iNumChambers; -} - -float StreamDisplay::GetHeightPercent( int iChamber, float fChamberOverflowPercent ) -{ - if( (iChamber%2) == 1 ) - return 1-fChamberOverflowPercent; - else - return 0; -} - -void StreamDisplay::DrawStrip( float fRightEdgePercent ) -{ - float fMeterWidth = this->GetUnzoomedWidth(); - m_sprStreamNormal.SetX( -fMeterWidth/2 + fMeterWidth*fRightEdgePercent ); - m_sprStreamPassing.SetX( -fMeterWidth/2 + fMeterWidth*fRightEdgePercent ); - m_sprStreamHot.SetX( -fMeterWidth/2 + fMeterWidth*fRightEdgePercent ); - - const float fMeterLeftEdgePixels = SCALE( 0.0f, 0.0f, 1.0f, -fMeterWidth/2, +fMeterWidth/2 ); - const float fMeterRightEdgePixels = SCALE( 1.0f, 0.0f, 1.0f, -fMeterWidth/2, +fMeterWidth/2 ); - - const float fStreamRightEdgePixels = SCALE( fRightEdgePercent, 0.0f, 1.0f, -fMeterWidth/2, +fMeterWidth/2 ); - const float fStreamLeftEdgePixels = fStreamRightEdgePixels - m_sprStreamNormal.GetZoomedWidth(); - - const float fLeftOverhangPixels = max( 0, fMeterLeftEdgePixels - fStreamLeftEdgePixels ); - const float fStreamCropLeftPercent = SCALE( fLeftOverhangPixels, 0.0f, m_sprStreamNormal.GetZoomedWidth(), 0.0f, 1.0f ); - - const float fRightOverhangPixels = max( 0, fStreamRightEdgePixels - fMeterRightEdgePixels ); - const float fStreamCropRightPercent = SCALE( fRightOverhangPixels, 0.0f, m_sprStreamNormal.GetZoomedWidth(), 0.0f, 1.0f ); - - m_sprStreamNormal.SetCropLeft( fStreamCropLeftPercent ); - m_sprStreamPassing.SetCropLeft( fStreamCropLeftPercent ); - m_sprStreamHot.SetCropLeft( fStreamCropLeftPercent ); - - m_sprStreamNormal.SetCropRight( fStreamCropRightPercent ); - m_sprStreamPassing.SetCropRight(fStreamCropRightPercent ); - m_sprStreamHot.SetCropRight( fStreamCropRightPercent ); - - - float fOrigPassingAlpha = m_sprStreamPassing.GetDiffuse().a; - float fOrigHotAlpha = m_sprStreamHot.GetDiffuse().a; - - m_sprStreamPassing.SetDiffuseAlpha( m_fPassingAlpha * fOrigPassingAlpha ); - m_sprStreamHot.SetDiffuseAlpha( m_fHotAlpha * fOrigHotAlpha ); - - if( m_fPassingAlpha < 1 && m_fHotAlpha < 1) - m_sprStreamNormal.Draw(); - if( m_fHotAlpha < 1) - m_sprStreamPassing.Draw(); - m_sprStreamHot.Draw(); - - m_sprStreamPassing.SetDiffuseAlpha( fOrigPassingAlpha ); - m_sprStreamHot.SetDiffuseAlpha( fOrigHotAlpha ); -} - -void StreamDisplay::DrawMask( float fPercent ) -{ - int iChamber; - float fChamberOverflowPercent; - GetChamberIndexAndOverflow( fPercent, iChamber, fChamberOverflowPercent ); - - // draw mask for vertical chambers - float fHeightPercent = GetHeightPercent( iChamber, fChamberOverflowPercent ); - float fChamberLeftPercent = GetChamberLeftPercent( iChamber ); - float fChamberRightPercent = GetChamberRightPercent( iChamber ); - m_quadMask.SetCropLeft( fChamberLeftPercent ); - m_quadMask.SetCropRight( 1-fChamberRightPercent ); - m_quadMask.SetCropTop( 0 ); - m_quadMask.SetCropBottom( 1-fHeightPercent ); - m_quadMask.Draw(); - - // draw mask for horizontal chambers - float fRightPercent = GetRightEdgePercent( iChamber, fChamberOverflowPercent ); - m_quadMask.SetCropLeft( fRightPercent ); - m_quadMask.SetCropRight( 0 ); - m_quadMask.SetCropTop( 0 ); - m_quadMask.SetCropBottom( 0 ); - - m_quadMask.Draw(); -} - /* * (c) 2003-2004 Chris Danford diff --git a/stepmania/src/StreamDisplay.h b/stepmania/src/StreamDisplay.h index 2ce8c644f8..c3b5205f26 100644 --- a/stepmania/src/StreamDisplay.h +++ b/stepmania/src/StreamDisplay.h @@ -1,57 +1,47 @@ #ifndef StreamDisplay_H #define StreamDisplay_H +#include "ActorFrame.h" #include "Sprite.h" #include "Quad.h" +#include "LuaExpressionTransform.h" -class StreamDisplay : public Actor +enum StreamType +{ + StreamType_Normal, + StreamType_Passing, + StreamType_Hot, + NUM_StreamType, +}; + + +class StreamDisplay : public ActorFrame { public: StreamDisplay(); virtual void Update( float fDeltaSecs ); - void Load( - float fMeterWidth, - float fMeterHeight, - int iNumStrips, - int iNumChambers, - const RString &sNormalPath, - const RString &sHotPath, - const RString &sPassingPath, - const apActorCommands &acNormalOnCommand, - const apActorCommands &acHotOnCommand, - const apActorCommands &acPassingOnCommand - ); + void Load( const RString &sMetricsGroup ); - void DrawPrimitives(); void SetPercent( float fPercent ); - void SetPassingAlpha( float fPassingAlpha ); - void SetHotAlpha( float fHotAlpha ); + void SetPassingAlpha( float fPassingAlpha ) { m_fPassingAlpha = fPassingAlpha; } + void SetHotAlpha( float fHotAlpha ) { m_fHotAlpha = fHotAlpha; } - float GetTrailingLifePercent() { return m_fTrailingPercent; } + float GetPercent() { return m_fPercent; } private: - Sprite m_sprStreamNormal; - Sprite m_sprStreamHot; - Sprite m_sprStreamPassing; - Quad m_quadMask; + vector m_vpSprPill[NUM_StreamType]; - int m_iNumStrips; - int m_iNumChambers; - float m_fPercent; - float m_fTrailingPercent; // this approaches m_fPercent - float m_fVelocity; // of m_fTrailingPercent + LuaExpressionTransform m_transformPill; // params: self,positionIndex,itemIndex,numItems + + float m_fPercent; // percent filled + float m_fTrailingPercent; // this approaches m_fPercent, use this value to draw + float m_fVelocity; // velocity of m_fTrailingPercent + float m_fPassingAlpha; float m_fHotAlpha; - void GetChamberIndexAndOverflow( float fPercent, int& iChamberOut, float& fChamberOverflowPercentOut ); - float GetChamberLeftPercent( int iChamber ); - float GetChamberRightPercent( int iChamber ); - float GetRightEdgePercent( int iChamber, float fChamberOverflowPercent ); - float GetHeightPercent( int iChamber, float fChamberOverflowPercent ); - void DrawStrip( float fRightEdgePercent ); - void DrawMask( float fPercent ); }; #endif