diff --git a/stepmania/NEWS b/stepmania/NEWS index 13f8221882..5c93a2e679 100644 --- a/stepmania/NEWS +++ b/stepmania/NEWS @@ -1,4 +1,5 @@ ------------------------CVS after 3.00 beta 6---------------- +CHANGE: Improved the appearance of hidden/sudden. CHANGE: After changing sort to "BEST", focus will be changed to the the most-played song. CHANGE: Texture Hints have been removed in favor of smarter, automatic diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index c8d9f47ccf..2e7c04620c 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -394,22 +394,30 @@ TimerSeconds=40 HelpText=Use arrow keys to navigate, ENTER to assign, and SPACE to clear. [GhostArrow] -PopUpSeconds=0.25 +ShowSeconds=0.25 ZoomStart=1.0 ZoomEnd=1.5 -ColorPerfect=1.0,1.0,0.3,1 // yellow -ColorGreat=0.0,1.0,0.4,1 // green -ColorGood=0.3,0.8,1.0,1 -ColorBoo=0.8,0.0,0.6,1 +ColorPerfectStart=1.0,1.0,0.3,1 // yellow +ColorPerfectEnd=1.0,1.0,0.3,0 // yellow no alpha +ColorGreatStart=0.0,1.0,0.4,1 // green +ColorGreatEnd=0.0,1.0,0.4,0 // green no alpha +ColorGoodStart=0.3,0.8,1.0,1 // blue +ColorGoodEnd=0.3,0.8,1.0,0 // blue no alpha +ColorBooStart=0.8,0.0,0.6,1 // purple +ColorBooEnd=0.8,0.0,0.6,0 // purple no alpha [GhostArrowBright] -PopUpSeconds=0.25 +ShowSeconds=0.25 ZoomStart=1.0 ZoomEnd=1.5 -ColorPerfect=1.0,1.0,0.3,1 // yellow -ColorGreat=0.0,1.0,0.4,1 // green -ColorGood=0.3,0.8,1.0,1 -ColorBoo=0.8,0.0,0.6,1 +ColorPerfectStart=1.0,1.0,0.3,1 // yellow +ColorPerfectEnd=1.0,1.0,0.3,0 // yellow no alpha +ColorGreatStart=0.0,1.0,0.4,1 // green +ColorGreatEnd=0.0,1.0,0.4,0 // green no alpha +ColorGoodStart=0.3,0.8,1.0,1 // blue +ColorGoodEnd=0.3,0.8,1.0,0 // blue no alpha +ColorBooStart=0.8,0.0,0.6,1 // purple +ColorBooEnd=0.8,0.0,0.6,0 // purple no alpha [BitmapText] RainbowColor1=1.0,0.0,0.4,1 // red @@ -446,6 +454,7 @@ JudgeGoodZoomY=1.1 JudgeBooZoomX=1.0 JudgeBooZoomY=1.0 ComboJudgeTweenSeconds=0.1 +BrightGhostThreshold=100 [GameState] StageColorDemo=0.3,1.0,0.3,1 // green diff --git a/stepmania/src/ArrowEffects.cpp b/stepmania/src/ArrowEffects.cpp index 0483143723..5ccc43bec4 100644 --- a/stepmania/src/ArrowEffects.cpp +++ b/stepmania/src/ArrowEffects.cpp @@ -37,7 +37,7 @@ float ArrowGetYOffset( PlayerNumber pn, float fNoteBeat ) return fYOffset; } -float ArrowGetXPos2( PlayerNumber pn, int iColNum, float fYPos ) +float ArrowGetXPos( PlayerNumber pn, int iColNum, float fYPos ) { float fSongBeat = GAMESTATE->m_fSongBeat; float fPixelOffsetFromCenter = GAMESTATE->GetCurrentStyleDef()->m_ColumnInfo[PLAYER_1][iColNum].fXOffset; @@ -70,76 +70,54 @@ float ArrowGetYPos( PlayerNumber pn, float fYOffset ) return fYOffset * GAMESTATE->m_PlayerOptions[pn].m_fArrowScrollSpeed * (GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? -1 : 1 ); } -float ArrowGetAlpha( PlayerNumber pn, float fYPos ) -{ - float fAlpha; - static float blinktimer=0; - if (blinktimer == 0) - blinktimer = TIMER->GetTimeSinceStart(); - - const bool bReverse = GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll; - static int blinkstate=2; +const float fCenterLine = 160; // from fYPos == 0 +const float fFadeDist = 100; + +// used by ArrowGetAlpha and ArrowGetGlow below +float ArrowGetPercentVisible( PlayerNumber pn, float fYPos ) +{ + const bool bReverse = GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll; + const float fCorrectedYPos = bReverse ? -fYPos : fYPos; + const float fDistFromCenterLine = fCorrectedYPos - fCenterLine; + float fAlpha; + switch( GAMESTATE->m_PlayerOptions[pn].m_AppearanceType ) { case PlayerOptions::APPEARANCE_VISIBLE: fAlpha = 1; break; case PlayerOptions::APPEARANCE_HIDDEN: - fAlpha = ((bReverse?-fYPos:fYPos)-100)/100; + fAlpha = SCALE( fDistFromCenterLine, 0, fFadeDist, 0, 1 ); break; case PlayerOptions::APPEARANCE_SUDDEN: - fAlpha = ((SCREEN_HEIGHT-(bReverse?-fYPos:fYPos))-260)/100; + fAlpha = SCALE( fDistFromCenterLine, 0, -fFadeDist, 0, 1 ); break; case PlayerOptions::APPEARANCE_STEALTH: fAlpha = 0; break; case PlayerOptions::APPEARANCE_BLINK: // this is an Ez2dancer Appearance Mode - if (TIMER->GetTimeSinceStart() > blinktimer + 0.20f) - { - blinktimer = TIMER->GetTimeSinceStart(); - if (blinkstate == 1) - { - blinkstate = 2; - } - else if (blinkstate == 0) - { - blinkstate = 3; - } - else if (blinkstate == 2) - { - blinkstate = 0; - } - else - { - blinkstate = 1; - } - } - - if (blinkstate == 1) - { - fAlpha = 1; - } - else if (blinkstate == 0) - { - fAlpha = 0; - } - else - { - fAlpha = ((fYPos-200)/200) + (((SCREEN_HEIGHT-fYPos)-260)/200); - } - + fAlpha = sinf( TIMER->GetTimeSinceStart() ); + fAlpha = froundf( fAlpha, 0.3333f ); break; default: - ASSERT( false ); - fAlpha = 0; - }; - if( !bReverse && fYPos < 0 ) + ASSERT(0); fAlpha = 1; - else if( bReverse && fYPos > 0 ) + } + + if( fCorrectedYPos < 0 ) // past Gray Arrows fAlpha = 1; return clamp( fAlpha, 0, 1 ); -}; +} +float ArrowGetAlpha( PlayerNumber pn, float fYPos ) +{ + return (ArrowGetPercentVisible(pn,fYPos) > 0.5f) ? 1.0f : 0.0f; +} +float ArrowGetGlow( PlayerNumber pn, float fYPos ) +{ + const float fDistFromHalf = fabsf( ArrowGetPercentVisible(pn,fYPos) - 0.5f ); + return SCALE( fDistFromHalf, 0, 0.5f, 1, 0 ); +} diff --git a/stepmania/src/ArrowEffects.h b/stepmania/src/ArrowEffects.h index 5a0e8751d6..5549d0a2ba 100644 --- a/stepmania/src/ArrowEffects.h +++ b/stepmania/src/ArrowEffects.h @@ -39,10 +39,15 @@ float ArrowGetYPos( PlayerNumber pn, float fYOffset ); // fXPos is a horizontal position in pixels relative to the center of the field. // This depends on the column of the arrow and possibly the Arrow effect and // fYPos (in the case of EFFECT_DRUNK). -float ArrowGetXPos2( PlayerNumber pn, int iCol, float fYPos ); +float ArrowGetXPos( PlayerNumber pn, int iCol, float fYPos ); // fAlpha is the transparency of the arrow. It depends on fYPos and the // ArrowAppearance. float ArrowGetAlpha( PlayerNumber pn, float fYPos ); + +// fAlpha is the transparency of the arrow. It depends on fYPos and the +// ArrowAppearance. +float ArrowGetGlow( PlayerNumber pn, float fYPos ); + diff --git a/stepmania/src/Combo.cpp b/stepmania/src/Combo.cpp index 4bd7049f22..fbd19c1ccd 100644 --- a/stepmania/src/Combo.cpp +++ b/stepmania/src/Combo.cpp @@ -47,7 +47,7 @@ Combo::Combo() void Combo::UpdateScore( TapNoteScore score ) { - if( PREFSMAN->m_bAutoPlay ) // cheaters never prosper + if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstration ) // cheaters never prosper { m_iCurCombo = 0; m_iCurComboOfPerfects = 0; diff --git a/stepmania/src/GhostArrow.cpp b/stepmania/src/GhostArrow.cpp index b12e7912c9..c776340de5 100644 --- a/stepmania/src/GhostArrow.cpp +++ b/stepmania/src/GhostArrow.cpp @@ -15,26 +15,46 @@ #include "PrefsManager.h" -#define POP_UP_SECONDS THEME->GetMetricF("GhostArrow","PopUpSeconds") +#define SHOW_SECONDS THEME->GetMetricF("GhostArrow","ShowSeconds") #define ZOOM_START THEME->GetMetricF("GhostArrow","ZoomStart") #define ZOOM_END THEME->GetMetricF("GhostArrow","ZoomEnd") -#define COLOR_PERFECT THEME->GetMetricC("GhostArrow","ColorPerfect") -#define COLOR_GREAT THEME->GetMetricC("GhostArrow","ColorGreat") -#define COLOR_GOOD THEME->GetMetricC("GhostArrow","ColorGood") -#define COLOR_BOO THEME->GetMetricC("GhostArrow","ColorBoo") +#define COLOR_PERFECT_START THEME->GetMetricC("GhostArrow","ColorPerfectStart") +#define COLOR_PERFECT_END THEME->GetMetricC("GhostArrow","ColorPerfectEnd") +#define COLOR_GREAT_START THEME->GetMetricC("GhostArrow","ColorGreatStart") +#define COLOR_GREAT_END THEME->GetMetricC("GhostArrow","ColorGreatEnd") +#define COLOR_GOOD_START THEME->GetMetricC("GhostArrow","ColorGoodStart") +#define COLOR_GOOD_END THEME->GetMetricC("GhostArrow","ColorGoodEnd") +#define COLOR_BOO_START THEME->GetMetricC("GhostArrow","ColorBooStart") +#define COLOR_BOO_END THEME->GetMetricC("GhostArrow","ColorBooEnd") +float g_fShowSeconds; +float g_fZoomStart, g_fZoomEnd; +D3DXCOLOR + g_colorPerfectStart, g_colorPerfectEnd, + g_colorGreatStart, g_colorGreatEnd, + g_colorGoodStart, g_colorGoodEnd, + g_colorBooStart, g_colorBooEnd; GhostArrow::GhostArrow() { - m_fPopUpSeconds = POP_UP_SECONDS; - m_fZoomStart = ZOOM_START; - m_fZoomEnd = ZOOM_END; - m_colorPerfect = COLOR_PERFECT; - m_colorGreat = COLOR_GREAT; - m_colorGood = COLOR_GOOD; - m_colorBoo = COLOR_BOO; + g_fShowSeconds = SHOW_SECONDS; + g_fZoomStart = ZOOM_START; + g_fZoomEnd = ZOOM_END; + g_colorPerfectStart = COLOR_PERFECT_START; + g_colorPerfectEnd = COLOR_PERFECT_END; + g_colorGreatStart = COLOR_GREAT_START; + g_colorGreatEnd = COLOR_GREAT_END; + g_colorGoodStart = COLOR_GOOD_START; + g_colorGoodEnd = COLOR_GOOD_END; + g_colorBooStart = COLOR_BOO_START; + g_colorBooEnd = COLOR_BOO_END; + + SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); - TurnShadowOff(); + + // set the length of each frame so the animation plays in exactly 1 pop up time + for( int i=0; iGetMetricF("GhostArrowBright","PopUpSeconds") +#define SHOW_SECONDS THEME->GetMetricF("GhostArrowBright","ShowSeconds") #define ZOOM_START THEME->GetMetricF("GhostArrowBright","ZoomStart") #define ZOOM_END THEME->GetMetricF("GhostArrowBright","ZoomEnd") -#define COLOR_PERFECT THEME->GetMetricC("GhostArrowBright","ColorPerfect") -#define COLOR_GREAT THEME->GetMetricC("GhostArrowBright","ColorGreat") -#define COLOR_GOOD THEME->GetMetricC("GhostArrowBright","ColorGood") -#define COLOR_BOO THEME->GetMetricC("GhostArrowBright","ColorBoo") +#define COLOR_PERFECT_START THEME->GetMetricC("GhostArrowBright","ColorPerfectStart") +#define COLOR_PERFECT_END THEME->GetMetricC("GhostArrowBright","ColorPerfectEnd") +#define COLOR_GREAT_START THEME->GetMetricC("GhostArrowBright","ColorGreatStart") +#define COLOR_GREAT_END THEME->GetMetricC("GhostArrowBright","ColorGreatEnd") +#define COLOR_GOOD_START THEME->GetMetricC("GhostArrowBright","ColorGoodStart") +#define COLOR_GOOD_END THEME->GetMetricC("GhostArrowBright","ColorGoodEnd") +#define COLOR_BOO_START THEME->GetMetricC("GhostArrowBright","ColorBooStart") +#define COLOR_BOO_END THEME->GetMetricC("GhostArrowBright","ColorBooEnd") + +// "2" appended so the names won't conflict with the GhostArrow +float g_fShowSeconds2; +float g_fZoomStart2, g_fZoomEnd2; +D3DXCOLOR + g_colorPerfectStart2, g_colorPerfectEnd2, + g_colorGreatStart2, g_colorGreatEnd2, + g_colorGoodStart2, g_colorGoodEnd2, + g_colorBooStart2, g_colorBooEnd2; GhostArrowBright::GhostArrowBright() { - m_fPopUpSeconds = POP_UP_SECONDS; - m_fZoomStart = ZOOM_START; - m_fZoomEnd = ZOOM_END; - m_colorPerfect = COLOR_PERFECT; - m_colorGreat = COLOR_GREAT; - m_colorGood = COLOR_GOOD; - m_colorBoo = COLOR_BOO; + g_fShowSeconds2 = SHOW_SECONDS; + g_fZoomStart2 = ZOOM_START; + g_fZoomEnd2 = ZOOM_END; + g_colorPerfectStart2= COLOR_PERFECT_START; + g_colorPerfectEnd2 = COLOR_PERFECT_END; + g_colorGreatStart2 = COLOR_GREAT_START; + g_colorGreatEnd2 = COLOR_GREAT_END; + g_colorGoodStart2 = COLOR_GOOD_START; + g_colorGoodEnd2 = COLOR_GOOD_END; + g_colorBooStart2 = COLOR_BOO_START; + g_colorBooEnd2 = COLOR_BOO_END; + + SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); - TurnShadowOff(); + + // set the length of each frame so the animation plays in exactly 1 pop up time + for( int i=0; im_CurGame == GAME_EZ2) @@ -168,335 +168,12 @@ void NoteDisplay::GetTapEdgeColors( const float fNoteBeat, D3DXCOLOR &colorLeadi colorTrailingOut = m_colorTapTweens[iTrailingColor1] * (1-fTrailingColorWeightOf2) + m_colorTapTweens[iTrailingColor2] * fTrailingColorWeightOf2; } -/* -D3DXCOLOR NoteDisplay::GetHoldColor( const float fY, const float fYTop, const float fYBottom ) +void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail, bool bDrawGlowOnly ) { - if( fY == fYTop ) - return m_colorHoldTweens[0]; + // bDrawGlowOnly is a little hacky. We need to draw the diffuse part and the glow part one pass at a time to minimize state changes - float fDistFromEnd = fYBottom - fY; - float fArrowSizesFromEnd = fDistFromEnd / (float)ARROW_SIZE; - float fPercentThroughColors = fmodf( fArrowSizesFromEnd, 2 ) / 2.0f; - float fIndex = fPercentThroughColors * (m_colorHoldTweens.GetSize()-1); - float fWeightOf2 = fIndex - int(fIndex); - int iColor1 = int(fIndex); - int iColor2 = (iColor1+1) % m_colorHoldTweens.GetSize(); - return m_colorHoldTweens[iColor1] * (1-fWeightOf2) + m_colorHoldTweens[iColor2] * fWeightOf2; -} -*/ + const bool bReverse = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_bReverseScroll; -float NoteDisplay::GetAddAlpha( float fDiffuseAlpha, float fPercentFadeToFail ) -{ - if( fPercentFadeToFail != -1 ) - return 1-fPercentFadeToFail; - - float fDistFromCenter = fabsf( 0.5f - fDiffuseAlpha ); - return clamp( 1-fDistFromCenter*2, 0, 1 ); -} - - -/* -void NoteDisplay::DrawList( int iCount, NoteDisplayInstance cni[], bool bDrawAddPass ) -{ - int iNumV; - - LPDIRECT3DVERTEXBUFFER8 pVB = DISPLAY->GetVertexBuffer(); - RAGEVERTEX* v; - - LPDIRECT3DDEVICE8 pd3dDevice = DISPLAY->GetDevice(); - - pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); - pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); - - pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX ); - pd3dDevice->SetStreamSource( 0, pVB, sizeof(RAGEVERTEX) ); - - - const float fGrayWidth = m_sprHoldParts.GetUnzoomedWidth(); - const float fGrayHeight = m_sprHoldParts.GetUnzoomedHeight(); - const float fColorWidth = m_sprTapParts.GetUnzoomedWidth(); - const float fColorHeight = m_sprTapParts.GetUnzoomedHeight(); - - RageTexture* pGrayTexture = m_sprHoldParts.GetTexture(); - RageTexture* pColorTexture = m_sprTapParts.GetTexture(); - - // - // Draw gray parts diffuse pass - // - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - pd3dDevice->SetTexture( 0, pGrayTexture->GetD3DTexture() ); - - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - iNumV = 0; - for( int i=0; ifX; - const float fY = pCNI->fY; - const float fRotation = pCNI->fRotation; - D3DXVECTOR3 vecPoints[4]; // top left, bottom left, top right, bottom right - - - // - // Set vertex positions - // - vecPoints[0] = D3DXVECTOR3( -fGrayWidth/2, -fGrayHeight/2, 0 ); // top left - vecPoints[1] = D3DXVECTOR3( -fGrayWidth/2, +fGrayHeight/2, 0 ); // bottom left - vecPoints[2] = D3DXVECTOR3( +fGrayWidth/2, -fGrayHeight/2, 0 ); // top right - vecPoints[3] = D3DXVECTOR3( +fGrayWidth/2, +fGrayHeight/2, 0 ); // bottom right - - if( fRotation != 0 ) - { - D3DXMATRIX matRotation; - D3DXMatrixRotationZ( &matRotation, fRotation ); - - for( int j=0; j<4; j++ ) - D3DXVec3TransformCoord( &vecPoints[j], &vecPoints[j], &matRotation ); - } - for( int j=0; j<4; j++ ) - { - vecPoints[j].x += fX; - vecPoints[j].y += fY; - } - - // first triangle - v[iNumV++].p = vecPoints[0]; // top left - v[iNumV++].p = vecPoints[1]; // bottom left - v[iNumV++].p = vecPoints[2]; // top right - // 2nd triangle - v[iNumV++].p = vecPoints[2]; // top right - v[iNumV++].p = vecPoints[1]; // bottom left - v[iNumV++].p = vecPoints[3]; // bottom right - - // - // set texture coordinates - // - iNumV -= 6; - - FRECT* pTexCoordRect = pGrayTexture->GetTextureCoordRect( pCNI->iGrayPartFrameNo ); - - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->left, pTexCoordRect->top ); // top left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->left, pTexCoordRect->bottom ); // bottom left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->right, pTexCoordRect->top ); // top right - v[iNumV++].t = v[iNumV-1].t; // top right - v[iNumV++].t = v[iNumV-3].t; // bottom left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->right, pTexCoordRect->bottom ); // bottom right - - // - // set vertex colors - // - iNumV -= 6; - - D3DXCOLOR colorGrayPart(1,1,1,pCNI->fAlpha); - - v[iNumV++].color = colorGrayPart; // top left - v[iNumV++].color = colorGrayPart; // bottom left - v[iNumV++].color = colorGrayPart; // top right - v[iNumV++].color = colorGrayPart; // top right - v[iNumV++].color = colorGrayPart; // bottom left - v[iNumV++].color = colorGrayPart; // bottom right - - } - ASSERT( iNumV == iCount*6 ); // two triangles for each note - - pVB->Unlock(); - - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, iNumV/3 ); - - - // - // Draw gray parts add pass - // - if( bDrawAddPass ) - { - 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 ); - - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - - iNumV = 0; - for( int i=0; ifAddAlpha); - - // - // set vertex colors - // - v[iNumV++].color = colorGlow; // top left - v[iNumV++].color = colorGlow; // bottom left - v[iNumV++].color = colorGlow; // top right - v[iNumV++].color = colorGlow; // top right - v[iNumV++].color = colorGlow; // bottom left - v[iNumV++].color = colorGlow; // bottom right - - } - ASSERT( iNumV == iCount*6 ); // two triangles for each note - - pVB->Unlock(); - - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, iNumV/3 ); - } - - - - - - - - - // - // Draw color parts diffuse pass - // - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - pd3dDevice->SetTexture( 0, pColorTexture->GetD3DTexture() ); - - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - iNumV = 0; - for( i=0; ifX; - const float fY = pCNI->fY; - const float fRotation = pCNI->fRotation; - D3DXVECTOR3 vecPoints[4]; // top left, bottom left, top right, bottom right - - // - // Set vertex positions - // - vecPoints[0] = D3DXVECTOR3( -fColorWidth/2, -fColorHeight/2, 0 ); // top left - vecPoints[1] = D3DXVECTOR3( -fColorWidth/2, +fColorHeight/2, 0 ); // bottom left - vecPoints[2] = D3DXVECTOR3( +fColorWidth/2, -fColorHeight/2, 0 ); // top right - vecPoints[3] = D3DXVECTOR3( +fColorWidth/2, +fColorHeight/2, 0 ); // bottom right - - if( fRotation != 0 ) - { - D3DXMATRIX matRotation; - D3DXMatrixRotationZ( &matRotation, fRotation ); - - for( int j=0; j<4; j++ ) - D3DXVec3TransformCoord( &vecPoints[j], &vecPoints[j], &matRotation ); - } - for( int j=0; j<4; j++ ) - { - vecPoints[j].x += fX; - vecPoints[j].y += fY; - } - - // first triangle - v[iNumV++].p = vecPoints[0]; // top left - v[iNumV++].p = vecPoints[1]; // bottom left - v[iNumV++].p = vecPoints[2]; // top right - // 2nd triangle - v[iNumV++].p = vecPoints[2]; // top right - v[iNumV++].p = vecPoints[1]; // bottom left - v[iNumV++].p = vecPoints[3]; // bottom right - - // - // set texture coordinates - // - iNumV -= 6; - - FRECT* pTexCoordRect = pColorTexture->GetTextureCoordRect( pCNI->iColorPartFrameNo ); - - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->left, pTexCoordRect->top ); // top left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->left, pTexCoordRect->bottom ); // bottom left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->right, pTexCoordRect->top ); // top right - v[iNumV++].t = v[iNumV-1].t; // top right - v[iNumV++].t = v[iNumV-3].t; // bottom left - v[iNumV++].t = D3DXVECTOR2( pTexCoordRect->right, pTexCoordRect->bottom ); // bottom right - - // - // set vertex colors - // - iNumV -= 6; - - D3DXCOLOR colorLeadingEdge = D3DXCOLOR(pCNI->colorLeadingEdge); - D3DXCOLOR colorTrailingEdge = D3DXCOLOR(pCNI->colorTrailingEdge); - - colorLeadingEdge.a = pCNI->fAlpha; - colorTrailingEdge.a = pCNI->fAlpha; - - v[iNumV++].color = colorLeadingEdge; // top left - v[iNumV++].color = colorTrailingEdge; // bottom left - v[iNumV++].color = colorLeadingEdge; // top right - v[iNumV++].color = v[iNumV-1].color; // top right - v[iNumV++].color = v[iNumV-3].color; // bottom left - v[iNumV++].color = colorTrailingEdge; // bottom right - - } - ASSERT( iNumV == iCount*6 ); // two triangles for each note - - pVB->Unlock(); - - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, iNumV/3 ); - - - // - // Draw Color parts add pass - // - if( bDrawAddPass ) - { - 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 ); - - pVB->Lock( 0, 0, (BYTE**)&v, 0 ); - - - iNumV = 0; - for( int i=0; ifAddAlpha); - - // - // set vertex colors - // - v[iNumV++].color = colorGlow; // top left - v[iNumV++].color = colorGlow; // bottom left - v[iNumV++].color = colorGlow; // top right - v[iNumV++].color = colorGlow; // top right - v[iNumV++].color = colorGlow; // bottom left - v[iNumV++].color = colorGlow; // bottom right - - } - ASSERT( iNumV == iCount*6 ); // two triangles for each note - - pVB->Unlock(); - - pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, iNumV/3 ); - } -} -*/ - - -void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail ) -{ const int iCol = hn.m_iTrack; const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fStartBeat ); const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset ); @@ -508,8 +185,8 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const float fFrameHeight = m_sprHoldParts.GetUnzoomedHeight(); const float fBodyHeight = fFrameHeight*2; - const float fYHead = min(fStartYPos, fEndYPos); // stop drawing here - const float fYTail = max(fStartYPos, fEndYPos); // the center the tail + const float fYHead = bReverse ? fEndYPos : fStartYPos; // the center of the head + const float fYTail = bReverse ? fStartYPos : fEndYPos; // the center the tail const float fYTailTop = fYTail-fFrameHeight/2; const float fYTailBottom = fYTail+fFrameHeight/2; @@ -520,7 +197,10 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const int fYStep = 8; // draw a segment every 8 pixels // this requires that the texture dimensions be a multiple of 8 DISPLAY->SetBlendModeNormal(); - DISPLAY->SetColorTextureMultDiffuse(); + if( bDrawGlowOnly ) + DISPLAY->SetColorDiffuse(); + else + DISPLAY->SetColorTextureMultDiffuse(); DISPLAY->SetAlphaTextureMultDiffuse(); DISPLAY->SetTexture( m_sprHoldParts.GetTexture() ); @@ -532,8 +212,8 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float { const float fYTop = fY; const float fYBottom = fY+min(fYStep, fYTailBottom-fY); - const float fXTop = ArrowGetXPos2( m_PlayerNumber, iCol, fYTop ); - const float fXBottom = ArrowGetXPos2( m_PlayerNumber, iCol, fYBottom ); + const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYTop ); + const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYBottom ); const float fXTopLeft = fXTop - fFrameWidth/2; const float fXTopRight = fXTop + fFrameWidth/2; const float fXBottomLeft = fXBottom - fFrameWidth/2; @@ -547,21 +227,26 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const float fTexCoordRight = bActive ? 0.50f : 0.25f; const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop ); const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, fYBottom ); - const float fAddAlphaTop = GetAddAlpha( fAlphaTop, fPercentFadeToFail ); - const float fAddAlphaBottom = GetAddAlpha( fAlphaBottom, fPercentFadeToFail ); + const float fGlowTop = ArrowGetGlow( m_PlayerNumber, fYTop ); + const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, fYBottom ); const float fColorScale = SCALE(fLife,0,1,0.5f,1); const D3DXCOLOR colorDiffuseTop = D3DXCOLOR(fColorScale,fColorScale,fColorScale,fAlphaTop); const D3DXCOLOR colorDiffuseBottom = D3DXCOLOR(fColorScale,fColorScale,fColorScale,fAlphaBottom); - const D3DXCOLOR colorGlowTop = D3DXCOLOR(1,1,1,fAddAlphaTop); - const D3DXCOLOR colorGlowBottom = D3DXCOLOR(1,1,1,fAddAlphaBottom); + const D3DXCOLOR colorGlowTop = D3DXCOLOR(1,1,1,fGlowTop); + const D3DXCOLOR colorGlowBottom = D3DXCOLOR(1,1,1,fGlowBottom); // the shift by -0.5 is to align texels to pixels + if( bDrawGlowOnly && colorGlowTop.a==0 && colorGlowBottom.a==0 ) + continue; + if( !bDrawGlowOnly && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 ) + continue; + DISPLAY->AddQuad( - D3DXVECTOR3(fXTopLeft-0.5f, fYTop-0.5f, 0), colorDiffuseTop, D3DXVECTOR2(fTexCoordLeft, fTexCoordTop), // colorGlowTop, // top-left - D3DXVECTOR3(fXTopRight-0.5f, fYTop-0.5f, 0), colorDiffuseTop, D3DXVECTOR2(fTexCoordRight, fTexCoordTop), // colorGlowTop, // top-right - D3DXVECTOR3(fXBottomLeft-0.5f, fYBottom-0.5f,0), colorDiffuseBottom, D3DXVECTOR2(fTexCoordLeft, fTexCoordBottom),// colorGlowBottom, // bottom-left - D3DXVECTOR3(fXBottomRight-0.5f,fYBottom-0.5f,0), colorDiffuseBottom, D3DXVECTOR2(fTexCoordRight, fTexCoordBottom) );//, colorGlowBottom ); // bottom-right + D3DXVECTOR3(fXTopLeft-0.5f, fYTop-0.5f, 0), bDrawGlowOnly ? colorGlowTop : colorDiffuseTop, D3DXVECTOR2(fTexCoordLeft, fTexCoordTop), // colorGlowTop, // top-left + D3DXVECTOR3(fXTopRight-0.5f, fYTop-0.5f, 0), bDrawGlowOnly ? colorGlowTop : colorDiffuseTop, D3DXVECTOR2(fTexCoordRight, fTexCoordTop), // colorGlowTop, // top-right + D3DXVECTOR3(fXBottomLeft-0.5f, fYBottom-0.5f,0), bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom, D3DXVECTOR2(fTexCoordLeft, fTexCoordBottom),// colorGlowBottom, // bottom-left + D3DXVECTOR3(fXBottomRight-0.5f,fYBottom-0.5f,0), bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom, D3DXVECTOR2(fTexCoordRight, fTexCoordBottom) );//, colorGlowBottom ); // bottom-right } // @@ -571,8 +256,8 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float { const float fYTop = fY; const float fYBottom = min( fY+fYStep, fYTailTop+1 ); - const float fXTop = ArrowGetXPos2( m_PlayerNumber, iCol, fYTop ); - const float fXBottom = ArrowGetXPos2( m_PlayerNumber, iCol, fYBottom ); + const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYTop ); + const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYBottom ); const float fXTopLeft = fXTop - fFrameWidth/2; const float fXTopRight = fXTop + fFrameWidth/2; const float fXBottomLeft = fXBottom - fFrameWidth/2; @@ -585,19 +270,24 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const float fTexCoordRight = bActive ? 1.00f : 0.75f; const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop ); const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, fYBottom ); - const float fAddAlphaTop = GetAddAlpha( fAlphaTop, fPercentFadeToFail ); - const float fAddAlphaBottom = GetAddAlpha( fAlphaBottom, fPercentFadeToFail ); + const float fGlowTop = ArrowGetGlow( m_PlayerNumber, fYTop ); + const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, fYBottom ); const float fColorScale = SCALE(fLife,0,1,0.5f,1); const D3DXCOLOR colorDiffuseTop = D3DXCOLOR(fColorScale,fColorScale,fColorScale,fAlphaTop); const D3DXCOLOR colorDiffuseBottom = D3DXCOLOR(fColorScale,fColorScale,fColorScale,fAlphaBottom); - const D3DXCOLOR colorGlowTop = D3DXCOLOR(1,1,1,fAddAlphaTop); - const D3DXCOLOR colorGlowBottom = D3DXCOLOR(1,1,1,fAddAlphaBottom); + const D3DXCOLOR colorGlowTop = D3DXCOLOR(1,1,1,fGlowTop); + const D3DXCOLOR colorGlowBottom = D3DXCOLOR(1,1,1,fGlowBottom); + + if( bDrawGlowOnly && colorGlowTop.a==0 && colorGlowBottom.a==0 ) + continue; + if( !bDrawGlowOnly && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 ) + continue; DISPLAY->AddQuad( - D3DXVECTOR3(fXTopLeft-0.5f, fYTop-0.5f, 0), colorDiffuseTop, D3DXVECTOR2(fTexCoordLeft, fTexCoordTop), //colorGlowTop, // top-left - D3DXVECTOR3(fXTopRight-0.5f, fYTop-0.5f, 0), colorDiffuseTop, D3DXVECTOR2(fTexCoordRight, fTexCoordTop), //colorGlowTop, // top-right - D3DXVECTOR3(fXBottomLeft-0.5f, fYBottom-0.5f,0), colorDiffuseBottom, D3DXVECTOR2(fTexCoordLeft, fTexCoordBottom), //colorGlowBottom, // bottom-left - D3DXVECTOR3(fXBottomRight-0.5f,fYBottom-0.5f,0), colorDiffuseBottom, D3DXVECTOR2(fTexCoordRight, fTexCoordBottom) );//, colorGlowBottom ); // bottom-right + D3DXVECTOR3(fXTopLeft-0.5f, fYTop-0.5f, 0), bDrawGlowOnly ? colorGlowTop : colorDiffuseTop, D3DXVECTOR2(fTexCoordLeft, fTexCoordTop), //colorGlowTop, // top-left + D3DXVECTOR3(fXTopRight-0.5f, fYTop-0.5f, 0), bDrawGlowOnly ? colorGlowTop : colorDiffuseTop, D3DXVECTOR2(fTexCoordRight, fTexCoordTop), //colorGlowTop, // top-right + D3DXVECTOR3(fXBottomLeft-0.5f, fYBottom-0.5f,0), bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom, D3DXVECTOR2(fTexCoordLeft, fTexCoordBottom), //colorGlowBottom, // bottom-left + D3DXVECTOR3(fXBottomRight-0.5f,fYBottom-0.5f,0), bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom, D3DXVECTOR2(fTexCoordRight, fTexCoordBottom) );//, colorGlowBottom ); // bottom-right } DISPLAY->FlushQueue(); @@ -608,19 +298,51 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float // { fY = fYHead; - const float fX = ArrowGetXPos2( m_PlayerNumber, iCol, fY ); + const float fX = ArrowGetXPos( m_PlayerNumber, iCol, fY ); const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fY ); - const float fAddAlpha = GetAddAlpha( fAlpha, fPercentFadeToFail ); + const float fGlow = ArrowGetGlow( m_PlayerNumber, fY ); const float fColorScale = SCALE(fLife,0,1,0.5f,1); const D3DXCOLOR colorDiffuse= D3DXCOLOR(fColorScale,fColorScale,fColorScale,fAlpha); - const D3DXCOLOR colorGlow = D3DXCOLOR(1,1,1,fAddAlpha); + const D3DXCOLOR colorGlow = D3DXCOLOR(1,1,1,fGlow); m_sprHoldParts.SetState( bActive?1:0 ); m_sprHoldParts.SetXY( fX, fY ); - m_sprHoldParts.SetDiffuseColor( colorDiffuse ); - m_sprHoldParts.SetGlowColor( colorGlow ); + if( bDrawGlowOnly ) + { + m_sprHoldParts.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_sprHoldParts.SetGlowColor( colorGlow ); + } + else + { + m_sprHoldParts.SetDiffuseColor( colorDiffuse ); + m_sprHoldParts.SetGlowColor( D3DXCOLOR(0,0,0,0) ); + } m_sprHoldParts.Draw(); } + + // + // We've drawn the diffuse pass, now draw the glow pass if necessary + // + bool bDrawGlow = false; + if( fPercentFadeToFail > 0 ) + bDrawGlow = true; + if( !bDrawGlowOnly ) + { + switch( GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_AppearanceType ) + { + case PlayerOptions::APPEARANCE_VISIBLE: + case PlayerOptions::APPEARANCE_STEALTH: + break; // don't need to draw glow + case PlayerOptions::APPEARANCE_HIDDEN: + case PlayerOptions::APPEARANCE_SUDDEN: + bDrawGlow = true; + break; + default: + ASSERT(0); + } + } + if( bDrawGlow ) + DrawHold( hn, bActive, fLife, fPercentFadeToFail, true ); } void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHoldColor, const float fPercentFadeToFail ) @@ -628,9 +350,9 @@ void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHol const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset ); - const float fXPos = ArrowGetXPos2( m_PlayerNumber, iCol, fYPos ); + const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYPos ); const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos ); - const float fAddAlpha = GetAddAlpha( fAlpha, fPercentFadeToFail ); + const float fGlow = ArrowGetGlow( m_PlayerNumber, fYPos ); const int iGrayPartFrameNo = GetTapGrayFrameNo( fBeat ); const int iColorPartFrameNo = GetTapColorFrameNo( fBeat ); @@ -638,7 +360,7 @@ void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHol D3DXCOLOR colorLeadingEdge; D3DXCOLOR colorTrailingEdge; if( bUseHoldColor ) - colorLeadingEdge = colorTrailingEdge = D3DXCOLOR(0,1,0,1); // HACK: green. + colorLeadingEdge = colorTrailingEdge = D3DXCOLOR(0,1,0,1); // HACK: green. Move this into the note skin else GetTapEdgeColors( fBeat, colorLeadingEdge, colorTrailingEdge ); colorGrayPart.a *= fAlpha; @@ -647,7 +369,7 @@ void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHol m_sprTapParts.SetXY( fXPos, fYPos ); m_sprTapParts.SetRotation( fRotation ); - m_sprTapParts.SetGlowColor( D3DXCOLOR(1,1,1,fAddAlpha) ); + m_sprTapParts.SetGlowColor( D3DXCOLOR(1,1,1,fGlow) ); // // draw gray part diff --git a/stepmania/src/NoteDisplay.h b/stepmania/src/NoteDisplay.h index a07f0cedcd..a7f1175e1a 100644 --- a/stepmania/src/NoteDisplay.h +++ b/stepmania/src/NoteDisplay.h @@ -24,20 +24,17 @@ public: void Load( int iColNum, PlayerNumber pn ); void DrawTap( const int iCol, const float fBeat, const bool bUseHoldColor, const float fPercentFadeToFail ); - void DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail ); + void DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail, bool bDrawGlowOnly = false ); protected: int GetTapGrayFrameNo( const float fNoteBeat ); int GetTapColorFrameNo( const float fNoteBeat ); void GetTapEdgeColors( const float fNoteBeat, D3DXCOLOR &colorLeadingOut, D3DXCOLOR &colorTrailingOut ); -// D3DXCOLOR GetHoldColor( const float fY, const float fYTop, const float fYBottom ); - float GetAddAlpha( float DiffuseAlpha, const float fPercentFadeToFail ); PlayerNumber m_PlayerNumber; // to look up PlayerOptions Sprite m_sprTapParts; // for now, must be an even number of frames - Sprite m_sprHoldParts; // for now, must be 16 frames + Sprite m_sprHoldParts; // for now, must be 8 frames CArray m_colorTapTweens; -// CArray m_colorHoldTweens; }; diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index bc31100b65..d70c2bc06a 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -33,6 +33,7 @@ #define JUDGE_BOO_ZOOM_X THEME->GetMetricF("Player","JudgeBooZoomX") #define JUDGE_BOO_ZOOM_Y THEME->GetMetricF("Player","JudgeBooZoomY") #define COMBO_JUDGE_TWEEN_SECONDS THEME->GetMetricF("Player","ComboJudgeTweenSeconds") +#define BRIGHT_GHOST_THRESHOLD THEME->GetMetricI("Player","BrightGhostThreshold") // cache because reading from theme metrics is slow @@ -45,6 +46,7 @@ float g_fJudgePerfectZoomX, g_fJudgeBooZoomX, g_fJudgeBooZoomY, g_fComboJudgeTweenSeconds; +int g_iBrightGhostThreshold; // these two items are in the const float FRAME_JUDGE_AND_COMBO_Y = CENTER_Y; @@ -71,6 +73,7 @@ Player::Player() g_fJudgeBooZoomX = JUDGE_BOO_ZOOM_X; g_fJudgeBooZoomY = JUDGE_BOO_ZOOM_Y; g_fComboJudgeTweenSeconds = COMBO_JUDGE_TWEEN_SECONDS; + g_iBrightGhostThreshold = BRIGHT_GHOST_THRESHOLD; m_PlayerNumber = PLAYER_INVALID; @@ -438,7 +441,7 @@ void Player::OnRowDestroyed( int col, int iIndexThatWasSteppedOn ) { if( m_TapNotes[c][iIndexThatWasSteppedOn] != '0' ) // if there is a note in this col { - m_GhostArrowRow.TapNote( c, score, m_Combo.GetCurrentCombo()>100 ); // show the ghost arrow for this column + m_GhostArrowRow.TapNote( c, score, m_Combo.GetCurrentCombo()>g_iBrightGhostThreshold ); // show the ghost arrow for this column HandleNoteScore( score ); // update score - called once per note in this row