2002-08-13 23:26:46 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
Class: NoteDisplay
|
|
|
|
|
|
|
|
|
|
Desc: See header.
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
|
|
|
|
Brian Bugh
|
|
|
|
|
Ben Nordstrom
|
|
|
|
|
Chris Danford
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "NoteDisplay.h"
|
|
|
|
|
#include "Notes.h"
|
|
|
|
|
#include "PrefsManager.h"
|
|
|
|
|
#include "GameState.h"
|
|
|
|
|
#include "GameManager.h"
|
|
|
|
|
#include "RageException.h"
|
|
|
|
|
#include "ArrowEffects.h"
|
|
|
|
|
#include "RageLog.h"
|
2002-11-11 04:53:31 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
#include "RageDisplay.h"
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
bool g_bDrawHoldHeadForTapsOnSameRow, g_bDrawTapOnTopOfHoldHead, g_bDrawTapOnTopOfHoldTail; // cache
|
2002-09-15 23:20:59 +00:00
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
NoteDisplay::NoteDisplay()
|
|
|
|
|
{
|
2002-09-17 23:02:37 +00:00
|
|
|
g_bDrawHoldHeadForTapsOnSameRow = GAMEMAN->GetMetricB( "NoteDisplay", "DrawHoldHeadForTapsOnSameRow" );
|
|
|
|
|
g_bDrawTapOnTopOfHoldHead = GAMEMAN->GetMetricB( "NoteDisplay", "DrawTapOnTopOfHoldHead" );
|
|
|
|
|
g_bDrawTapOnTopOfHoldTail = GAMEMAN->GetMetricB( "NoteDisplay", "DrawTapOnTopOfHoldTail" );
|
2002-09-15 23:20:59 +00:00
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
// the owner of the NoteDisplay must call load on the gray and color parts
|
|
|
|
|
// m_sprHoldParts.Load( THEME->GetPathTo(GRAPHIC_COLOR_ARROW_GRAY_PART) );
|
|
|
|
|
// m_sprTapParts.Load( THEME->GetPathTo(GRAPHIC_COLOR_ARROW_COLOR_PART) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void NoteDisplay::Load( int iColNum, PlayerNumber pn )
|
|
|
|
|
{
|
|
|
|
|
m_PlayerNumber = pn;
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
CString sTapPartsPath = GAMEMAN->GetPathTo(iColNum, "tap parts");
|
|
|
|
|
m_sprTapParts.Load( sTapPartsPath );
|
2002-08-13 23:26:46 +00:00
|
|
|
if( m_sprTapParts.GetNumStates() % 2 != 0 )
|
2002-10-29 07:58:44 +00:00
|
|
|
throw RageException( "Tap Parts '%s' must have an even number of frames.", sTapPartsPath.GetString() );
|
2002-08-13 23:26:46 +00:00
|
|
|
m_sprTapParts.StopAnimating();
|
|
|
|
|
m_sprTapParts.TurnShadowOff();
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
CString sHoldPartsPath = GAMEMAN->GetPathTo(iColNum, "hold parts");
|
|
|
|
|
m_sprHoldParts.Load( sHoldPartsPath );
|
|
|
|
|
if( m_sprHoldParts.GetTexture()->GetFramesWide() != 4 || m_sprHoldParts.GetTexture()->GetFramesHigh() != 2 )
|
2002-10-29 07:58:44 +00:00
|
|
|
throw RageException( "Hold Parts '%s' must have 4x2 frames.", sHoldPartsPath.GetString() );
|
2002-08-13 23:26:46 +00:00
|
|
|
m_sprHoldParts.StopAnimating();
|
|
|
|
|
m_sprHoldParts.TurnShadowOff();
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
|
2002-10-24 20:15:24 +00:00
|
|
|
m_colorTapTweens.clear();
|
2002-09-17 23:02:37 +00:00
|
|
|
const CString sColorsFilePath = GAMEMAN->GetPathTo( iColNum, "Tap.colors" );
|
|
|
|
|
FILE* fp = fopen( sColorsFilePath, "r" );
|
|
|
|
|
if( fp == NULL )
|
2002-10-29 07:58:44 +00:00
|
|
|
throw RageException( "Couldn't open .colors file '%s'", sColorsFilePath.GetString() );
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
bool bSuccess;
|
|
|
|
|
do
|
|
|
|
|
{
|
2002-10-28 05:30:45 +00:00
|
|
|
RageColor color;
|
2002-09-17 23:02:37 +00:00
|
|
|
int retval = fscanf( fp, "%f,%f,%f,%f\n", &color.r, &color.g, &color.b, &color.a );
|
|
|
|
|
bSuccess = (retval == 4);
|
|
|
|
|
if( bSuccess )
|
2002-10-31 04:23:39 +00:00
|
|
|
m_colorTapTweens.push_back( color );
|
2002-09-17 23:02:37 +00:00
|
|
|
} while( bSuccess );
|
|
|
|
|
|
2002-10-31 02:54:49 +00:00
|
|
|
if( m_colorTapTweens.empty() )
|
2002-10-31 04:23:39 +00:00
|
|
|
m_colorTapTweens.push_back( RageColor(1,1,1,1) );
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
fclose( fp );
|
|
|
|
|
return;
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int NoteDisplay::GetTapGrayFrameNo( const float fNoteBeat )
|
|
|
|
|
{
|
|
|
|
|
const int iNumGrayPartFrames = m_sprTapParts.GetNumStates()/2;
|
|
|
|
|
|
|
|
|
|
const float fSongBeat = GAMESTATE->m_fSongBeat;
|
|
|
|
|
const float fPercentIntoBeat = fSongBeat - (int)fSongBeat;
|
|
|
|
|
int iFrameNo = int(fPercentIntoBeat * iNumGrayPartFrames) % iNumGrayPartFrames;
|
|
|
|
|
if( iFrameNo < 0 )
|
|
|
|
|
iFrameNo += iNumGrayPartFrames;
|
|
|
|
|
|
|
|
|
|
return iFrameNo * 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int NoteDisplay::GetTapColorFrameNo( const float fNoteBeat )
|
|
|
|
|
{
|
|
|
|
|
return GetTapGrayFrameNo(fNoteBeat) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-28 05:30:45 +00:00
|
|
|
void NoteDisplay::GetTapEdgeColors( const float fNoteBeat, RageColor &colorLeadingOut, RageColor &colorTrailingOut )
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
2002-08-29 01:38:21 +00:00
|
|
|
// Chris: If EZ2 doesn't use a color part, leave that part of the NoteSkin graphic empty
|
2002-08-13 23:26:46 +00:00
|
|
|
//
|
|
|
|
|
// Andy:
|
|
|
|
|
// if (GAMESTATE->m_CurGame == GAME_EZ2)
|
|
|
|
|
// {
|
|
|
|
|
// return; // Get out of this, as it breaks EZ2, and besides, Ez2 doesn't use COLOR ARROWS
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
// ADDED 2-14-2002 - BrianB
|
|
|
|
|
//
|
|
|
|
|
// This section has been added for the different arrow
|
|
|
|
|
// display types:
|
|
|
|
|
//
|
|
|
|
|
// Note: Each note has a different color, but does not tween
|
|
|
|
|
// Flat: Each note has the same color, and does tween
|
|
|
|
|
// Plain: Each note has the same color, but does not tween
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
const PlayerOptions::ColorType ct = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_ColorType;
|
|
|
|
|
const float fNotePercentIntoBeat = fNoteBeat - (int)fNoteBeat;
|
|
|
|
|
const float fSongBeat = GAMESTATE->m_fSongBeat;
|
|
|
|
|
float fPercentThroughColors = fmodf( fSongBeat, (float)BEATS_PER_MEASURE ) / BEATS_PER_MEASURE;
|
|
|
|
|
|
|
|
|
|
switch( ct )
|
|
|
|
|
{
|
|
|
|
|
case PlayerOptions::COLOR_VIVID:
|
|
|
|
|
case PlayerOptions::COLOR_NOTE:
|
|
|
|
|
fPercentThroughColors += fNotePercentIntoBeat;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( fPercentThroughColors < 0 )
|
|
|
|
|
fPercentThroughColors += 1;
|
|
|
|
|
else
|
|
|
|
|
fPercentThroughColors -= (int)fPercentThroughColors;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-09-07 10:22:21 +00:00
|
|
|
float fPercentThroughColorsLeading=0.f; // fill these in below
|
|
|
|
|
float fPercentThroughColorsTrailing=0.f;
|
2002-08-13 23:26:46 +00:00
|
|
|
switch( ct )
|
|
|
|
|
{
|
|
|
|
|
case PlayerOptions::COLOR_VIVID:
|
|
|
|
|
case PlayerOptions::COLOR_NOTE:
|
|
|
|
|
case PlayerOptions::COLOR_FLAT:
|
|
|
|
|
// use different edge colors so that the arrows look more colorful
|
|
|
|
|
fPercentThroughColorsLeading = fPercentThroughColors;
|
|
|
|
|
fPercentThroughColorsTrailing = fmodf( fPercentThroughColors + 0.20f, 1 );
|
|
|
|
|
break;
|
|
|
|
|
case PlayerOptions::COLOR_PLAIN:
|
|
|
|
|
// use same colors for both edges, making it look "plain"
|
|
|
|
|
fPercentThroughColorsLeading = fPercentThroughColors;
|
|
|
|
|
fPercentThroughColorsTrailing = fPercentThroughColors;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ASSERT(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ct == PlayerOptions::COLOR_NOTE )
|
|
|
|
|
{
|
2002-10-28 05:30:45 +00:00
|
|
|
RageColor color = GetNoteColorFromBeat( fNoteBeat );
|
2002-08-13 23:26:46 +00:00
|
|
|
colorLeadingOut = color;
|
|
|
|
|
colorTrailingOut = color;
|
|
|
|
|
|
|
|
|
|
// add a little bit of white so the note doesn't look so plain
|
|
|
|
|
colorLeadingOut.r += 0.3f * fabsf( fPercentThroughColorsLeading - 0.5f );
|
|
|
|
|
colorLeadingOut.g += 0.3f * fabsf( fPercentThroughColorsLeading - 0.5f );
|
|
|
|
|
colorLeadingOut.b += 0.3f * fabsf( fPercentThroughColorsLeading - 0.5f );
|
|
|
|
|
colorTrailingOut.r += 0.3f * fabsf( fPercentThroughColorsTrailing - 0.5f );
|
|
|
|
|
colorTrailingOut.g += 0.3f * fabsf( fPercentThroughColorsTrailing - 0.5f );
|
|
|
|
|
colorTrailingOut.b += 0.3f * fabsf( fPercentThroughColorsTrailing - 0.5f );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-31 02:54:49 +00:00
|
|
|
float fLeadingColorIndex = fPercentThroughColorsLeading * m_colorTapTweens.size();
|
|
|
|
|
float fTrailingColorIndex = fPercentThroughColorsTrailing* m_colorTapTweens.size();
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
float fLeadingColorWeightOf2 = fLeadingColorIndex - int(fLeadingColorIndex);
|
|
|
|
|
int iLeadingColor1 = int(fLeadingColorIndex);
|
2002-10-31 02:54:49 +00:00
|
|
|
int iLeadingColor2 = (iLeadingColor1 + 1) % m_colorTapTweens.size();
|
2002-08-13 23:26:46 +00:00
|
|
|
colorLeadingOut = m_colorTapTweens[iLeadingColor1] * (1-fLeadingColorWeightOf2) + m_colorTapTweens[iLeadingColor2] * fLeadingColorWeightOf2;
|
|
|
|
|
|
|
|
|
|
float fTrailingColorWeightOf2 = fTrailingColorIndex - int(fTrailingColorIndex);
|
|
|
|
|
int iTrailingColor1 = int(fTrailingColorIndex);
|
2002-10-31 02:54:49 +00:00
|
|
|
int iTrailingColor2 = (iTrailingColor1 + 1) % m_colorTapTweens.size();
|
2002-08-13 23:26:46 +00:00
|
|
|
colorTrailingOut = m_colorTapTweens[iTrailingColor1] * (1-fTrailingColorWeightOf2) + m_colorTapTweens[iTrailingColor2] * fTrailingColorWeightOf2;
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-29 01:38:21 +00:00
|
|
|
void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail, bool bDrawGlowOnly )
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
2002-08-29 01:38:21 +00:00
|
|
|
// 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
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-08-29 01:38:21 +00:00
|
|
|
const bool bReverse = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_bReverseScroll;
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
const int iCol = hn.m_iTrack;
|
2002-08-23 20:18:29 +00:00
|
|
|
const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fStartBeat );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset );
|
2002-08-23 20:18:29 +00:00
|
|
|
const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fEndBeat );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fEndYPos = ArrowGetYPos( m_PlayerNumber, fEndYOffset );
|
|
|
|
|
|
|
|
|
|
// draw from bottom to top
|
|
|
|
|
const float fFrameWidth = m_sprHoldParts.GetUnzoomedWidth();
|
|
|
|
|
const float fFrameHeight = m_sprHoldParts.GetUnzoomedHeight();
|
2002-08-25 06:42:26 +00:00
|
|
|
const float fBodyHeight = fFrameHeight*2;
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-08-29 01:38:21 +00:00
|
|
|
const float fYHead = bReverse ? fEndYPos : fStartYPos; // the center of the head
|
|
|
|
|
const float fYTail = bReverse ? fStartYPos : fEndYPos; // the center the tail
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
const float fYHeadTop = fYHead-fFrameHeight/2;
|
|
|
|
|
const float fYHeadBottom = fYHead+fFrameHeight/2;
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fYTailTop = fYTail-fFrameHeight/2;
|
|
|
|
|
const float fYTailBottom = fYTail+fFrameHeight/2;
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
const float fYBodyTop = g_bDrawTapOnTopOfHoldHead ? fYHeadBottom : fYHead; // middle of head
|
|
|
|
|
const float fYBodyBottom = fYTailTop; // top of tail
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
const int fYStep = 8; // draw a segment every 8 pixels // this requires that the texture dimensions be a multiple of 8
|
|
|
|
|
|
2002-11-12 01:55:25 +00:00
|
|
|
DISPLAY->SetBlendModeNormal();
|
|
|
|
|
if( bDrawGlowOnly )
|
|
|
|
|
DISPLAY->SetTextureModeGlow();
|
|
|
|
|
else
|
|
|
|
|
DISPLAY->SetTextureModeModulate();
|
|
|
|
|
DISPLAY->EnableTextureWrapping();
|
|
|
|
|
DISPLAY->SetTexture( m_sprHoldParts.GetTexture() );
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Draw the tail
|
|
|
|
|
//
|
|
|
|
|
float fY;
|
2002-10-18 19:01:32 +00:00
|
|
|
// HACK: +0.05 below to try and get rid of ugly border at top of tail
|
|
|
|
|
for( fY=max(fYTailTop-0.05f,fYHead); fY<fYTailBottom; fY+=fYStep ) // don't draw the part of the tail that is before the middle of the head
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
|
|
|
|
const float fYTop = fY;
|
2002-08-26 05:53:48 +00:00
|
|
|
const float fYBottom = fY+min(fYStep, fYTailBottom-fY);
|
2002-08-29 01:38:21 +00:00
|
|
|
const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYTop );
|
|
|
|
|
const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYBottom );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fXTopLeft = fXTop - fFrameWidth/2;
|
|
|
|
|
const float fXTopRight = fXTop + fFrameWidth/2;
|
|
|
|
|
const float fXBottomLeft = fXBottom - fFrameWidth/2;
|
|
|
|
|
const float fXBottomRight = fXBottom + fFrameWidth/2;
|
|
|
|
|
const float fTopDistFromTailTop = fYTop - fYTailTop;
|
|
|
|
|
const float fBottomDistFromTailTop = fYBottom - fYTailTop;
|
2002-08-25 06:42:26 +00:00
|
|
|
const float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f );
|
|
|
|
|
const float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f );
|
2002-10-09 06:57:37 +00:00
|
|
|
ASSERT( fBottomDistFromTailTop-0.001 <= fFrameHeight );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fTexCoordLeft = bActive ? 0.25f : 0.00f;
|
|
|
|
|
const float fTexCoordRight = bActive ? 0.50f : 0.25f;
|
2002-09-05 03:45:07 +00:00
|
|
|
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
|
|
|
|
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
2002-09-11 04:49:07 +00:00
|
|
|
const float fColorScale = SCALE(fLife,0,1,0.2f,1);
|
2002-10-28 05:30:45 +00:00
|
|
|
const RageColor colorDiffuseTop = RageColor(fColorScale,fColorScale,fColorScale,fAlphaTop);
|
|
|
|
|
const RageColor colorDiffuseBottom = RageColor(fColorScale,fColorScale,fColorScale,fAlphaBottom);
|
|
|
|
|
const RageColor colorGlowTop = RageColor(1,1,1,fGlowTop);
|
|
|
|
|
const RageColor colorGlowBottom = RageColor(1,1,1,fGlowBottom);
|
2002-08-13 23:26:46 +00:00
|
|
|
|
|
|
|
|
// the shift by -0.5 is to align texels to pixels
|
|
|
|
|
|
2002-08-29 01:38:21 +00:00
|
|
|
if( bDrawGlowOnly && colorGlowTop.a==0 && colorGlowBottom.a==0 )
|
|
|
|
|
continue;
|
|
|
|
|
if( !bDrawGlowOnly && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 )
|
|
|
|
|
continue;
|
|
|
|
|
|
2002-11-11 04:53:31 +00:00
|
|
|
static RageVertex v[4];
|
|
|
|
|
v[0].p = RageVector3(fXTopLeft-0.5f, fYTop-0.5f, 0); v[0].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop),
|
|
|
|
|
v[1].p = RageVector3(fXTopRight-0.5f, fYTop-0.5f, 0); v[1].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
|
2002-11-12 01:55:25 +00:00
|
|
|
v[2].p = RageVector3(fXBottomRight-0.5f,fYBottom-0.5f,0); v[2].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
|
|
|
|
|
v[3].p = RageVector3(fXBottomLeft-0.5f, fYBottom-0.5f,0); v[3].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
|
2002-11-11 04:53:31 +00:00
|
|
|
|
|
|
|
|
DISPLAY->DrawQuad( v );
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Draw the body
|
|
|
|
|
//
|
2002-10-18 19:01:32 +00:00
|
|
|
for( fY=fYBodyTop; fY<=fYBodyBottom+1; fY+=fYStep ) // top to bottom
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
|
|
|
|
const float fYTop = fY;
|
2002-08-25 19:00:12 +00:00
|
|
|
const float fYBottom = min( fY+fYStep, fYTailTop+1 );
|
2002-08-29 01:38:21 +00:00
|
|
|
const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYTop );
|
|
|
|
|
const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYBottom );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fXTopLeft = fXTop - fFrameWidth/2;
|
|
|
|
|
const float fXTopRight = fXTop + fFrameWidth/2;
|
|
|
|
|
const float fXBottomLeft = fXBottom - fFrameWidth/2;
|
|
|
|
|
const float fXBottomRight = fXBottom + fFrameWidth/2;
|
|
|
|
|
const float fTopDistFromTailTop = fYTailTop - fYTop;
|
|
|
|
|
const float fBottomDistFromTailTop = fYTailTop - fYBottom;
|
|
|
|
|
const float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fBodyHeight, 1, 0 );
|
|
|
|
|
const float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fBodyHeight, 1, 0 );
|
|
|
|
|
const float fTexCoordLeft = bActive ? 0.75f : 0.50f;
|
|
|
|
|
const float fTexCoordRight = bActive ? 1.00f : 0.75f;
|
2002-09-05 03:45:07 +00:00
|
|
|
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
|
|
|
|
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
2002-09-11 04:49:07 +00:00
|
|
|
const float fColorScale = SCALE(fLife,0,1,0.2f,1);
|
2002-10-28 05:30:45 +00:00
|
|
|
const RageColor colorDiffuseTop = RageColor(fColorScale,fColorScale,fColorScale,fAlphaTop);
|
|
|
|
|
const RageColor colorDiffuseBottom = RageColor(fColorScale,fColorScale,fColorScale,fAlphaBottom);
|
|
|
|
|
const RageColor colorGlowTop = RageColor(1,1,1,fGlowTop);
|
|
|
|
|
const RageColor colorGlowBottom = RageColor(1,1,1,fGlowBottom);
|
2002-08-29 01:38:21 +00:00
|
|
|
|
|
|
|
|
if( bDrawGlowOnly && colorGlowTop.a==0 && colorGlowBottom.a==0 )
|
|
|
|
|
continue;
|
|
|
|
|
if( !bDrawGlowOnly && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 )
|
|
|
|
|
continue;
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-11-11 04:53:31 +00:00
|
|
|
static RageVertex v[4];
|
2002-11-12 01:55:25 +00:00
|
|
|
v[0].p = RageVector3(fXTopLeft-0.5f, fYTop-0.5f, 0); v[0].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
|
|
|
|
|
v[1].p = RageVector3(fXTopRight-0.5f, fYTop-0.5f, 0); v[1].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
|
|
|
|
|
v[2].p = RageVector3(fXBottomRight-0.5f,fYBottom-0.5f,0); v[2].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
|
|
|
|
|
v[3].p = RageVector3(fXBottomLeft-0.5f, fYBottom-0.5f,0); v[3].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
|
|
|
|
|
DISPLAY->DrawQuad( v );
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
if( g_bDrawTapOnTopOfHoldHead )
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
2002-09-17 23:02:37 +00:00
|
|
|
//
|
|
|
|
|
// Draw the head
|
|
|
|
|
//
|
|
|
|
|
float fY;
|
|
|
|
|
for( fY=fYHeadTop; fY<fYHeadBottom; fY+=fYStep )
|
2002-08-29 01:38:21 +00:00
|
|
|
{
|
2002-09-17 23:02:37 +00:00
|
|
|
const float fYTop = fY;
|
|
|
|
|
const float fYBottom = fY+min(fYStep, fYHeadBottom-fY);
|
|
|
|
|
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;
|
|
|
|
|
const float fXBottomRight = fXBottom + fFrameWidth/2;
|
|
|
|
|
const float fTopDistFromHeadTop = fYTop - fYHeadTop;
|
|
|
|
|
const float fBottomDistFromHeadTop = fYBottom - fYHeadTop;
|
2002-10-18 19:01:32 +00:00
|
|
|
const float fTexCoordTop = SCALE( fTopDistFromHeadTop, 0, fFrameHeight, 0.0f, 0.499f );
|
|
|
|
|
const float fTexCoordBottom = SCALE( fBottomDistFromHeadTop, 0, fFrameHeight, 0.0f, 0.499f );
|
2002-09-17 23:02:37 +00:00
|
|
|
ASSERT( fBottomDistFromHeadTop-0.0001 <= fFrameHeight );
|
|
|
|
|
const float fTexCoordLeft = bActive ? 0.25f : 0.00f;
|
|
|
|
|
const float fTexCoordRight = bActive ? 0.50f : 0.25f;
|
|
|
|
|
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
|
|
|
|
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, fYTop, fPercentFadeToFail );
|
|
|
|
|
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, fYBottom, fPercentFadeToFail );
|
|
|
|
|
const float fColorScale = SCALE(fLife,0,1,0.2f,1);
|
2002-10-28 05:30:45 +00:00
|
|
|
const RageColor colorDiffuseTop = RageColor(fColorScale,fColorScale,fColorScale,fAlphaTop);
|
|
|
|
|
const RageColor colorDiffuseBottom = RageColor(fColorScale,fColorScale,fColorScale,fAlphaBottom);
|
|
|
|
|
const RageColor colorGlowTop = RageColor(1,1,1,fGlowTop);
|
|
|
|
|
const RageColor colorGlowBottom = RageColor(1,1,1,fGlowBottom);
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
2002-11-12 01:55:25 +00:00
|
|
|
static RageVertex v[4];
|
|
|
|
|
v[0].p = RageVector3(fXTopLeft-0.5f, fYTop-0.5f, 0); v[0].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
|
|
|
|
|
v[1].p = RageVector3(fXTopRight-0.5f, fYTop-0.5f, 0); v[1].c = bDrawGlowOnly ? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
|
|
|
|
|
v[2].p = RageVector3(fXBottomRight-0.5f,fYBottom-0.5f,0); v[2].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
|
|
|
|
|
v[3].p = RageVector3(fXBottomLeft-0.5f, fYBottom-0.5f,0); v[3].c = bDrawGlowOnly ? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
|
|
|
|
|
DISPLAY->DrawQuad( v );
|
2002-08-29 01:38:21 +00:00
|
|
|
}
|
2002-09-17 23:02:37 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// Draw head
|
|
|
|
|
//
|
2002-08-29 01:38:21 +00:00
|
|
|
{
|
2002-09-17 23:02:37 +00:00
|
|
|
fY = fYHead;
|
|
|
|
|
const float fX = ArrowGetXPos( m_PlayerNumber, iCol, fY );
|
|
|
|
|
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fY, fPercentFadeToFail );
|
|
|
|
|
const float fGlow = ArrowGetGlow( m_PlayerNumber, fY, fPercentFadeToFail );
|
|
|
|
|
const float fColorScale = SCALE(fLife,0,1,0.2f,1);
|
2002-10-28 05:30:45 +00:00
|
|
|
const RageColor colorDiffuse= RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
|
|
|
|
const RageColor colorGlow = RageColor(1,1,1,fGlow);
|
2002-09-17 23:02:37 +00:00
|
|
|
|
2002-10-18 19:01:32 +00:00
|
|
|
// m_sprHoldParts.SetState( bActive?1:0 );
|
|
|
|
|
// HACK: the border around the edge of on this sprite is super-obvious.
|
2002-10-31 06:00:30 +00:00
|
|
|
m_sprHoldParts.SetCustomTextureRect( bActive ? RectF(0.251f,0.002f,0.499f,0.498f) : RectF(0.001f,0.002f,0.249f,0.498f) );
|
2002-09-17 23:02:37 +00:00
|
|
|
m_sprHoldParts.SetXY( fX, fY );
|
|
|
|
|
if( bDrawGlowOnly )
|
|
|
|
|
{
|
2002-10-28 05:30:45 +00:00
|
|
|
m_sprHoldParts.SetDiffuse( RageColor(1,1,1,0) );
|
2002-09-17 23:02:37 +00:00
|
|
|
m_sprHoldParts.SetGlow( colorGlow );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_sprHoldParts.SetDiffuse( colorDiffuse );
|
2002-10-28 05:30:45 +00:00
|
|
|
m_sprHoldParts.SetGlow( RageColor(0,0,0,0) );
|
2002-09-17 23:02:37 +00:00
|
|
|
}
|
|
|
|
|
m_sprHoldParts.Draw();
|
2002-08-29 01:38:21 +00:00
|
|
|
}
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
2002-08-29 01:38:21 +00:00
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
|
|
|
|
|
if( g_bDrawTapOnTopOfHoldHead )
|
|
|
|
|
DrawTap( hn.m_iTrack, hn.m_fStartBeat, false, fPercentFadeToFail, fLife );
|
|
|
|
|
if( g_bDrawTapOnTopOfHoldTail )
|
|
|
|
|
DrawTap( hn.m_iTrack, hn.m_fEndBeat, false, fPercentFadeToFail, fLife );
|
|
|
|
|
|
|
|
|
|
|
2002-09-02 21:59:58 +00:00
|
|
|
// now, draw the glow pass
|
2002-08-29 01:38:21 +00:00
|
|
|
if( !bDrawGlowOnly )
|
|
|
|
|
DrawHold( hn, bActive, fLife, fPercentFadeToFail, true );
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bOnSameRowAsHoldStart, const float fPercentFadeToFail, const float fLife )
|
2002-08-13 23:26:46 +00:00
|
|
|
{
|
2002-08-23 20:18:29 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
2002-08-13 23:26:46 +00:00
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
|
|
|
|
const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset );
|
2002-08-29 01:38:21 +00:00
|
|
|
const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYPos );
|
2002-09-05 03:45:07 +00:00
|
|
|
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos, fPercentFadeToFail );
|
|
|
|
|
const float fGlow = ArrowGetGlow( m_PlayerNumber, fYPos, fPercentFadeToFail );
|
2002-08-13 23:26:46 +00:00
|
|
|
const int iGrayPartFrameNo = GetTapGrayFrameNo( fBeat );
|
|
|
|
|
const int iColorPartFrameNo = GetTapColorFrameNo( fBeat );
|
2002-09-17 23:02:37 +00:00
|
|
|
const float fColorScale = SCALE(fLife,0,1,0.2f,1);
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-10-28 05:30:45 +00:00
|
|
|
RageColor colorGrayPart = RageColor(fColorScale,fColorScale,fColorScale,1);
|
|
|
|
|
RageColor colorLeadingEdge;
|
|
|
|
|
RageColor colorTrailingEdge;
|
2002-09-05 03:45:07 +00:00
|
|
|
GetTapEdgeColors( fBeat, colorLeadingEdge, colorTrailingEdge );
|
2002-08-13 23:26:46 +00:00
|
|
|
colorGrayPart.a *= fAlpha;
|
|
|
|
|
colorLeadingEdge.a *= fAlpha;
|
|
|
|
|
colorTrailingEdge.a *= fAlpha;
|
|
|
|
|
|
2002-09-17 23:02:37 +00:00
|
|
|
colorLeadingEdge.r *= fColorScale;
|
|
|
|
|
colorLeadingEdge.g *= fColorScale;
|
|
|
|
|
colorLeadingEdge.b *= fColorScale;
|
|
|
|
|
colorTrailingEdge.r *= fColorScale;
|
|
|
|
|
colorTrailingEdge.g *= fColorScale;
|
|
|
|
|
colorTrailingEdge.b *= fColorScale;
|
|
|
|
|
|
|
|
|
|
if( bOnSameRowAsHoldStart && g_bDrawHoldHeadForTapsOnSameRow )
|
2002-09-05 03:45:07 +00:00
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// draw hold head
|
|
|
|
|
//
|
|
|
|
|
m_sprHoldParts.SetXY( fXPos, fYPos );
|
|
|
|
|
m_sprHoldParts.SetDiffuse( colorGrayPart );
|
2002-10-28 05:30:45 +00:00
|
|
|
m_sprHoldParts.SetGlow( RageColor(1,1,1,fGlow) );
|
2002-10-20 05:25:34 +00:00
|
|
|
m_sprHoldParts.StopUsingCustomCoords();
|
2002-09-05 03:45:07 +00:00
|
|
|
m_sprHoldParts.SetState( 0 );
|
|
|
|
|
m_sprHoldParts.Draw();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_sprTapParts.SetXY( fXPos, fYPos );
|
|
|
|
|
m_sprTapParts.SetRotation( fRotation );
|
2002-10-28 05:30:45 +00:00
|
|
|
m_sprTapParts.SetGlow( RageColor(1,1,1,fGlow) );
|
2002-09-05 03:45:07 +00:00
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// draw gray part
|
|
|
|
|
//
|
|
|
|
|
m_sprTapParts.SetState( iGrayPartFrameNo );
|
|
|
|
|
m_sprTapParts.SetDiffuse( colorGrayPart );
|
|
|
|
|
m_sprTapParts.Draw();
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// draw color part
|
|
|
|
|
//
|
|
|
|
|
m_sprTapParts.SetState( iColorPartFrameNo );
|
|
|
|
|
m_sprTapParts.SetDiffuseTopEdge( colorLeadingEdge );
|
|
|
|
|
m_sprTapParts.SetDiffuseBottomEdge( colorTrailingEdge );
|
|
|
|
|
m_sprTapParts.Draw();
|
|
|
|
|
}
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|