2003-02-16 04:01:45 +00:00
|
|
|
#include "global.h"
|
2002-04-16 17:31:00 +00:00
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
Class: NoteField
|
|
|
|
|
|
|
|
|
|
Desc: See header.
|
|
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
2002-04-16 17:31:00 +00:00
|
|
|
Chris Danford
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "NoteField.h"
|
|
|
|
|
#include "RageUtil.h"
|
2002-05-01 19:14:55 +00:00
|
|
|
#include "GameConstantsAndTypes.h"
|
2002-07-23 01:41:40 +00:00
|
|
|
#include "PrefsManager.h"
|
2002-04-16 17:31:00 +00:00
|
|
|
#include "ArrowEffects.h"
|
|
|
|
|
#include "PrefsManager.h"
|
|
|
|
|
#include "GameManager.h"
|
2002-07-23 01:41:40 +00:00
|
|
|
#include "GameState.h"
|
2002-07-27 19:29:51 +00:00
|
|
|
#include "RageException.h"
|
|
|
|
|
#include "RageTimer.h"
|
2002-09-10 08:21:55 +00:00
|
|
|
#include "RageLog.h"
|
2002-11-11 04:53:31 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
#include "ThemeManager.h"
|
2002-07-27 19:29:51 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-06-14 22:25:22 +00:00
|
|
|
const float HOLD_NOTE_BITS_PER_BEAT = 6;
|
2002-08-23 20:18:29 +00:00
|
|
|
const float HOLD_NOTE_BITS_PER_ROW = HOLD_NOTE_BITS_PER_BEAT / ROWS_PER_BEAT;
|
2002-06-14 22:25:22 +00:00
|
|
|
const float ROWS_BETWEEN_HOLD_BITS = 1 / HOLD_NOTE_BITS_PER_ROW;
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
NoteField::NoteField()
|
|
|
|
|
{
|
|
|
|
|
m_rectMeasureBar.TurnShadowOff();
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
m_textMeasureNumber.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
|
2002-04-16 17:31:00 +00:00
|
|
|
m_textMeasureNumber.SetZoom( 1.0f );
|
|
|
|
|
|
|
|
|
|
m_rectMarkerBar.TurnShadowOff();
|
2003-02-18 23:15:38 +00:00
|
|
|
m_rectMarkerBar.SetEffectDiffuseShift( 2, RageColor(1,1,1,0.5f), RageColor(0.5f,0.5f,0.5f,0.5f) );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
m_fBeginMarker = m_fEndMarker = -1;
|
2002-06-27 17:49:10 +00:00
|
|
|
|
2002-08-01 21:55:40 +00:00
|
|
|
m_fPercentFadeToFail = -1;
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-01-25 11:05:12 +00:00
|
|
|
void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-28 20:28:37 +00:00
|
|
|
m_PlayerNumber = pn;
|
2003-01-25 11:05:12 +00:00
|
|
|
m_iFirstPixelToDraw = iFirstPixelToDraw;
|
|
|
|
|
m_iLastPixelToDraw = iLastPixelToDraw;
|
2002-07-28 20:28:37 +00:00
|
|
|
|
2002-08-01 21:55:40 +00:00
|
|
|
m_fPercentFadeToFail = -1;
|
|
|
|
|
|
2002-12-18 22:25:24 +00:00
|
|
|
NoteDataWithScoring::Init();
|
2002-08-01 03:15:27 +00:00
|
|
|
|
2002-11-03 21:45:26 +00:00
|
|
|
m_bIsHoldingHoldNote.clear();
|
|
|
|
|
m_bIsHoldingHoldNote.insert(m_bIsHoldingHoldNote.end(), pNoteData->GetNumTapNotes(), false);
|
2002-08-01 03:15:27 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
this->CopyAll( pNoteData );
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
// init note displays
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int c=0; c<GetNumTracks(); c++ )
|
2002-08-13 23:26:46 +00:00
|
|
|
m_NoteDisplay[c].Load( c, pn );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-02-01 05:16:38 +00:00
|
|
|
ASSERT( GetNumTracks() == GAMESTATE->GetCurrentStyleDef()->m_iColsPerPlayer );
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-07-28 20:28:37 +00:00
|
|
|
void NoteField::Update( float fDeltaTime )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
|
|
|
|
m_rectMarkerBar.Update( fDeltaTime );
|
2002-08-01 21:55:40 +00:00
|
|
|
|
|
|
|
|
if( m_fPercentFadeToFail >= 0 )
|
2002-09-05 20:42:49 +00:00
|
|
|
m_fPercentFadeToFail = min( m_fPercentFadeToFail + fDeltaTime/1.5f, 1 ); // take 1.5 seconds to totally fade
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2003-02-18 23:15:38 +00:00
|
|
|
int NoteField::GetWidth()
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2003-02-18 23:15:38 +00:00
|
|
|
return (GetNumTracks()+1) * ARROW_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NoteField::DrawBeatBar( const float fBeat )
|
|
|
|
|
{
|
|
|
|
|
bool bIsMeasure = fmodf( fBeat, (float)BEATS_PER_MEASURE ) == 0;
|
|
|
|
|
int iMeasureIndex = (int)fBeat / BEATS_PER_MEASURE;
|
|
|
|
|
int iMeasureNoDisplay = iMeasureIndex+1;
|
|
|
|
|
|
|
|
|
|
NoteType nt = BeatToNoteType( fBeat );
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2003-01-25 11:05:12 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
|
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
|
2003-02-18 23:15:38 +00:00
|
|
|
int iSegWidth;
|
|
|
|
|
int iSpaceWidth;
|
|
|
|
|
float fBrightness;
|
|
|
|
|
float fScrollSpeed = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fScrollSpeed;
|
|
|
|
|
switch( nt )
|
|
|
|
|
{
|
|
|
|
|
default: ASSERT(0);
|
|
|
|
|
case NOTE_TYPE_4TH: iSegWidth = 16; iSpaceWidth = 0; fBrightness = 1; break;
|
|
|
|
|
case NOTE_TYPE_8TH: iSegWidth = 12; iSpaceWidth = 4; fBrightness = SCALE(fScrollSpeed,1.f,2.f,0.f,1.f); break;
|
|
|
|
|
case NOTE_TYPE_16TH:iSegWidth = 4; iSpaceWidth = 4; fBrightness = SCALE(fScrollSpeed,2.f,4.f,0.f,1.f); break;
|
|
|
|
|
}
|
|
|
|
|
CLAMP( fBrightness, 0, 1 );
|
|
|
|
|
|
|
|
|
|
int iWidth = GetWidth();
|
|
|
|
|
for( int i=-iWidth/2; i<+iWidth/2; )
|
|
|
|
|
{
|
|
|
|
|
m_rectMeasureBar.StretchTo( RectI(i,0,i+iSegWidth,0) );
|
|
|
|
|
m_rectMeasureBar.SetY( fYPos );
|
|
|
|
|
m_rectMeasureBar.SetZoomY( bIsMeasure ? 6.f : 2.f );
|
|
|
|
|
m_rectMeasureBar.SetDiffuse( RageColor(1,1,1,0.5f*fBrightness) );
|
|
|
|
|
m_rectMeasureBar.Draw();
|
|
|
|
|
|
|
|
|
|
i += iSegWidth + iSpaceWidth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( bIsMeasure )
|
|
|
|
|
{
|
|
|
|
|
m_textMeasureNumber.SetDiffuse( RageColor(1,1,1,1) );
|
|
|
|
|
m_textMeasureNumber.SetGlow( RageColor(1,1,1,0) );
|
|
|
|
|
m_textMeasureNumber.SetText( ssprintf("%d", iMeasureNoDisplay) );
|
|
|
|
|
m_textMeasureNumber.SetXY( -iWidth/2.f + 10, fYPos );
|
|
|
|
|
m_textMeasureNumber.Draw();
|
|
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
void NoteField::DrawMarkerBar( const float fBeat )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2003-01-25 11:05:12 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
|
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
m_rectMarkerBar.SetXY( 0, fYPos );
|
2003-02-01 05:16:38 +00:00
|
|
|
m_rectMarkerBar.SetZoomX( (float)(GetNumTracks()+1) * ARROW_SIZE );
|
2003-02-18 23:15:38 +00:00
|
|
|
m_rectMarkerBar.SetZoomY( (float)ARROW_SIZE );
|
2002-04-16 17:31:00 +00:00
|
|
|
m_rectMarkerBar.Draw();
|
|
|
|
|
}
|
|
|
|
|
|
2003-02-18 23:15:38 +00:00
|
|
|
void NoteField::DrawAreaHighlight( const float fStartBeat, const float fEndBeat )
|
|
|
|
|
{
|
|
|
|
|
const float fYStartOffset = ArrowGetYOffset( m_PlayerNumber, fStartBeat );
|
|
|
|
|
const float fYStartPos = ArrowGetYPos( m_PlayerNumber, fYStartOffset );
|
|
|
|
|
const float fYEndOffset = ArrowGetYOffset( m_PlayerNumber, fEndBeat );
|
|
|
|
|
const float fYEndPos = ArrowGetYPos( m_PlayerNumber, fYEndOffset );
|
|
|
|
|
|
|
|
|
|
m_rectAreaHighlight.StretchTo( RectI(0, (int)fYStartPos-ARROW_SIZE/2, 1, (int)fYEndPos+ARROW_SIZE/2) );
|
|
|
|
|
m_rectAreaHighlight.SetZoomX( (float)(GetNumTracks()+1) * ARROW_SIZE );
|
|
|
|
|
m_rectAreaHighlight.SetDiffuse( RageColor(1,0,0,0.3f) );
|
|
|
|
|
m_rectAreaHighlight.Draw();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
|
2002-06-29 11:59:09 +00:00
|
|
|
{
|
2003-01-25 11:05:12 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
|
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-10-28 05:30:45 +00:00
|
|
|
m_textMeasureNumber.SetDiffuse( RageColor(1,0,0,1) );
|
2002-12-19 23:07:20 +00:00
|
|
|
m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) );
|
2002-06-29 11:59:09 +00:00
|
|
|
m_textMeasureNumber.SetText( ssprintf("%.2f", fBPM) );
|
2003-02-18 23:15:38 +00:00
|
|
|
m_textMeasureNumber.SetXY( -GetWidth()/2.f - 60, fYPos );
|
2002-06-29 11:59:09 +00:00
|
|
|
m_textMeasureNumber.Draw();
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
void NoteField::DrawFreezeText( const float fBeat, const float fSecs )
|
2002-06-29 11:59:09 +00:00
|
|
|
{
|
2003-01-25 11:05:12 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
|
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-10-28 05:30:45 +00:00
|
|
|
m_textMeasureNumber.SetDiffuse( RageColor(0.8f,0.8f,0,1) );
|
2002-12-19 23:07:20 +00:00
|
|
|
m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) );
|
2002-06-29 11:59:09 +00:00
|
|
|
m_textMeasureNumber.SetText( ssprintf("%.2f", fSecs) );
|
2003-02-18 23:15:38 +00:00
|
|
|
m_textMeasureNumber.SetXY( -GetWidth()/2.f - 10, fYPos );
|
2002-06-29 11:59:09 +00:00
|
|
|
m_textMeasureNumber.Draw();
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-23 20:18:29 +00:00
|
|
|
void NoteField::DrawBGChangeText( const float fBeat, const CString sNewBGName )
|
|
|
|
|
{
|
2003-01-25 11:05:12 +00:00
|
|
|
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
|
|
|
|
|
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
|
2002-08-23 20:18:29 +00:00
|
|
|
|
2002-10-28 05:30:45 +00:00
|
|
|
m_textMeasureNumber.SetDiffuse( RageColor(0,1,0,1) );
|
2002-12-19 23:07:20 +00:00
|
|
|
m_textMeasureNumber.SetGlow( RageColor(1,1,1,cosf(RageTimer::GetTimeSinceStart()*2)/2+0.5f) );
|
2002-08-23 20:18:29 +00:00
|
|
|
m_textMeasureNumber.SetText( sNewBGName );
|
2003-02-18 23:15:38 +00:00
|
|
|
m_textMeasureNumber.SetXY( +GetWidth()/2.f + 10, fYPos );
|
2002-08-23 20:18:29 +00:00
|
|
|
m_textMeasureNumber.Draw();
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
void NoteField::DrawPrimitives()
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
//LOG->Trace( "NoteField::DrawPrimitives()" );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-09-10 08:21:55 +00:00
|
|
|
const float fSongBeat = GAMESTATE->m_fSongBeat;
|
2003-01-25 11:05:12 +00:00
|
|
|
|
|
|
|
|
// CPU OPTIMIZATION OPPORTUNITY:
|
|
|
|
|
// change this probing to binary search
|
|
|
|
|
|
|
|
|
|
// probe for first note on the screen
|
|
|
|
|
float fFirstBeatToDraw = fSongBeat-2; // Adjust to balance of performance and showing enough notes.
|
|
|
|
|
while( fFirstBeatToDraw<fSongBeat )
|
|
|
|
|
{
|
|
|
|
|
float fYOffset = ArrowGetYOffset(m_PlayerNumber, fFirstBeatToDraw);
|
|
|
|
|
float fYPosWOReverse = ArrowGetYPosWithoutReverse(m_PlayerNumber, fYOffset );
|
|
|
|
|
if( fYPosWOReverse < m_iFirstPixelToDraw ) // off screen
|
|
|
|
|
fFirstBeatToDraw += 0.1f; // move toward fSongBeat
|
|
|
|
|
else // on screen
|
|
|
|
|
break; // stop probing
|
|
|
|
|
}
|
|
|
|
|
fFirstBeatToDraw -= 0.1f; // rewind if we intentionally overshot
|
|
|
|
|
|
|
|
|
|
// probe for last note to draw
|
|
|
|
|
float fLastBeatToDraw = fSongBeat+20; // worst case is 0.25x + boost. Adjust to balance of performance and showing enough notes.
|
|
|
|
|
while( fLastBeatToDraw>fSongBeat )
|
|
|
|
|
{
|
|
|
|
|
float fYOffset = ArrowGetYOffset(m_PlayerNumber, fLastBeatToDraw);
|
|
|
|
|
float fYPosWOReverse = ArrowGetYPosWithoutReverse(m_PlayerNumber, fYOffset );
|
|
|
|
|
if( fYPosWOReverse > m_iLastPixelToDraw ) // off screen
|
|
|
|
|
fLastBeatToDraw -= 0.1f; // move toward fSongBeat
|
|
|
|
|
else // on screen
|
|
|
|
|
break; // stop probing
|
|
|
|
|
}
|
|
|
|
|
fLastBeatToDraw += 0.1f; // fast forward since we intentionally overshot
|
|
|
|
|
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
const int iFirstIndexToDraw = BeatToNoteRow(fFirstBeatToDraw);
|
|
|
|
|
const int iLastIndexToDraw = BeatToNoteRow(fLastBeatToDraw);
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-01-25 11:05:12 +00:00
|
|
|
// LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
|
2002-09-11 04:49:07 +00:00
|
|
|
// LOG->Trace( "Drawing elements %d through %d", iFirstIndexToDraw, iLastIndexToDraw );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-07-28 20:28:37 +00:00
|
|
|
if( GAMESTATE->m_bEditing )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2003-01-31 02:37:23 +00:00
|
|
|
ASSERT(GAMESTATE->m_pCurSong);
|
|
|
|
|
|
2002-10-31 03:16:02 +00:00
|
|
|
unsigned i;
|
2002-08-13 23:26:46 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
//
|
2003-02-18 23:15:38 +00:00
|
|
|
// Draw beat bars
|
2002-06-29 11:59:09 +00:00
|
|
|
//
|
2003-02-18 23:15:38 +00:00
|
|
|
{
|
|
|
|
|
float fStartDrawingMeasureBars = max( 0, froundf(fFirstBeatToDraw-0.25f,0.25f) );
|
|
|
|
|
for( float f=fStartDrawingMeasureBars; f<fLastBeatToDraw; f+=0.25f )
|
|
|
|
|
DrawBeatBar( f );
|
|
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
//
|
|
|
|
|
// BPM text
|
|
|
|
|
//
|
2003-01-03 05:56:28 +00:00
|
|
|
vector<BPMSegment> &aBPMSegments = GAMESTATE->m_pCurSong->m_BPMSegments;
|
2002-10-31 03:16:02 +00:00
|
|
|
for( i=0; i<aBPMSegments.size(); i++ )
|
2003-01-30 20:12:39 +00:00
|
|
|
{
|
|
|
|
|
if(aBPMSegments[i].m_fStartBeat >= fFirstBeatToDraw &&
|
|
|
|
|
aBPMSegments[i].m_fStartBeat <= fLastBeatToDraw)
|
|
|
|
|
DrawBPMText( aBPMSegments[i].m_fStartBeat, aBPMSegments[i].m_fBPM );
|
|
|
|
|
}
|
2002-06-29 11:59:09 +00:00
|
|
|
//
|
|
|
|
|
// Freeze text
|
|
|
|
|
//
|
2003-01-03 05:56:28 +00:00
|
|
|
vector<StopSegment> &aStopSegments = GAMESTATE->m_pCurSong->m_StopSegments;
|
2002-10-31 03:16:02 +00:00
|
|
|
for( i=0; i<aStopSegments.size(); i++ )
|
2003-01-30 20:12:39 +00:00
|
|
|
{
|
|
|
|
|
if(aStopSegments[i].m_fStartBeat >= fFirstBeatToDraw &&
|
|
|
|
|
aStopSegments[i].m_fStartBeat <= fLastBeatToDraw)
|
2002-08-13 23:26:46 +00:00
|
|
|
DrawFreezeText( aStopSegments[i].m_fStartBeat, aStopSegments[i].m_fStopSeconds );
|
2003-01-30 20:12:39 +00:00
|
|
|
}
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-08-23 20:18:29 +00:00
|
|
|
//
|
|
|
|
|
// BGChange text
|
|
|
|
|
//
|
2003-01-03 05:56:28 +00:00
|
|
|
vector<BackgroundChange> &aBackgroundChanges = GAMESTATE->m_pCurSong->m_BackgroundChanges;
|
2002-10-31 03:16:02 +00:00
|
|
|
for( i=0; i<aBackgroundChanges.size(); i++ )
|
2003-01-30 20:12:39 +00:00
|
|
|
{
|
|
|
|
|
if(aBackgroundChanges[i].m_fStartBeat >= fFirstBeatToDraw &&
|
|
|
|
|
aBackgroundChanges[i].m_fStartBeat <= fLastBeatToDraw)
|
|
|
|
|
DrawBGChangeText( aBackgroundChanges[i].m_fStartBeat, aBackgroundChanges[i].m_sBGName );
|
|
|
|
|
}
|
2002-08-23 20:18:29 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
//
|
|
|
|
|
// Draw marker bars
|
|
|
|
|
//
|
2003-02-18 23:15:38 +00:00
|
|
|
if( m_fBeginMarker != -1 && m_fEndMarker != -1 )
|
|
|
|
|
DrawAreaHighlight( m_fBeginMarker, m_fEndMarker );
|
|
|
|
|
else if( m_fBeginMarker != -1 )
|
2002-08-13 23:26:46 +00:00
|
|
|
DrawMarkerBar( m_fBeginMarker );
|
2003-02-18 23:15:38 +00:00
|
|
|
else if( m_fEndMarker != -1 )
|
2002-08-13 23:26:46 +00:00
|
|
|
DrawMarkerBar( m_fEndMarker );
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
//
|
2002-08-23 20:18:29 +00:00
|
|
|
// Optimization is very important here because there are so many arrows to draw.
|
|
|
|
|
// Draw the arrows in order of column. This minimize texture switches and let us
|
|
|
|
|
// draw in big batches.
|
2002-08-13 23:26:46 +00:00
|
|
|
//
|
|
|
|
|
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int c=0; c<GetNumTracks(); c++ ) // for each arrow column
|
2002-04-28 20:42:32 +00:00
|
|
|
{
|
2002-06-14 22:25:22 +00:00
|
|
|
/////////////////////////////////
|
|
|
|
|
// Draw all HoldNotes in this column (so that they appear under the tap notes)
|
|
|
|
|
/////////////////////////////////
|
2002-11-16 09:12:55 +00:00
|
|
|
int i;
|
|
|
|
|
for( i=0; i < GetNumHoldNotes(); i++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-11-02 22:46:15 +00:00
|
|
|
const HoldNote &hn = GetHoldNote(i);
|
2002-12-18 22:25:24 +00:00
|
|
|
const HoldNoteScore hns = GetHoldNoteScore(i);
|
2002-12-17 23:09:10 +00:00
|
|
|
const float fLife = GetHoldNoteLife(i);
|
2003-01-31 03:07:19 +00:00
|
|
|
const bool bIsHoldingNote = (i < int(m_bIsHoldingHoldNote.size()))?
|
2003-01-31 02:37:23 +00:00
|
|
|
m_bIsHoldingHoldNote[i]: false;
|
2002-08-01 03:15:27 +00:00
|
|
|
|
|
|
|
|
if( hns == HNS_OK ) // if this HoldNote was completed
|
|
|
|
|
continue; // don't draw anything
|
|
|
|
|
|
2003-02-16 20:27:53 +00:00
|
|
|
if( hn.iTrack != c ) // this HoldNote doesn't belong to this column
|
2002-04-28 20:42:32 +00:00
|
|
|
continue;
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-04-28 20:42:32 +00:00
|
|
|
// If no part of this HoldNote is on the screen, skip it
|
2003-02-16 20:27:53 +00:00
|
|
|
if( !( fFirstBeatToDraw <= hn.fEndBeat && hn.fEndBeat <= fLastBeatToDraw ||
|
|
|
|
|
fFirstBeatToDraw <= hn.fStartBeat && hn.fStartBeat <= fLastBeatToDraw ||
|
|
|
|
|
hn.fStartBeat < fFirstBeatToDraw && hn.fEndBeat > fLastBeatToDraw ) )
|
2002-04-28 20:42:32 +00:00
|
|
|
{
|
2002-06-14 22:25:22 +00:00
|
|
|
continue; // skip
|
2002-04-28 20:42:32 +00:00
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
m_NoteDisplay[c].DrawHold( hn, bIsHoldingNote, fLife, m_fPercentFadeToFail );
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-06-14 22:25:22 +00:00
|
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
|
// Draw all TapNotes in this column
|
|
|
|
|
///////////////////////////////////
|
2002-08-13 23:26:46 +00:00
|
|
|
for( i=iFirstIndexToDraw; i<=iLastIndexToDraw; i++ ) // for each row
|
2002-06-14 22:25:22 +00:00
|
|
|
{
|
2002-11-02 21:44:52 +00:00
|
|
|
if( GetTapNote(c, i) == TAP_EMPTY ) // no note here
|
2002-08-13 23:26:46 +00:00
|
|
|
continue; // skip
|
2002-06-14 22:25:22 +00:00
|
|
|
|
2002-11-02 21:44:52 +00:00
|
|
|
if( GetTapNote(c, i) == TAP_HOLD_HEAD ) // this is a HoldNote begin marker. Grade it, but don't draw
|
2002-08-13 23:26:46 +00:00
|
|
|
continue; // skip
|
|
|
|
|
|
|
|
|
|
// See if there is a hold step that begins on this index.
|
|
|
|
|
bool bHoldNoteBeginsOnThisBeat = false;
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int c2=0; c2<GetNumTracks(); c2++ )
|
2002-06-14 22:25:22 +00:00
|
|
|
{
|
2002-11-02 21:44:52 +00:00
|
|
|
if( GetTapNote(c2, i) == TAP_HOLD_HEAD )
|
2002-06-14 22:25:22 +00:00
|
|
|
{
|
2002-08-13 23:26:46 +00:00
|
|
|
bHoldNoteBeginsOnThisBeat = true;
|
2002-06-14 22:25:22 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-02-18 23:15:38 +00:00
|
|
|
bool bIsInSelectionRange = false;
|
|
|
|
|
float fGlow = 0;
|
|
|
|
|
if( m_fBeginMarker!=-1 && m_fEndMarker!=-1 )
|
|
|
|
|
{
|
|
|
|
|
float fBeat = NoteRowToBeat(i);
|
|
|
|
|
bIsInSelectionRange = m_fBeginMarker<=fBeat && fBeat<=m_fEndMarker;
|
|
|
|
|
fGlow = SCALE( cosf(RageTimer::GetTimeSinceStart()*2), -1, 1, 0.1f, 0.3f );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_NoteDisplay[c].DrawTap( c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, bIsInSelectionRange ? fGlow : m_fPercentFadeToFail );
|
2002-08-13 23:26:46 +00:00
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
2002-04-28 20:42:32 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void NoteField::RemoveTapNoteRow( int iIndex )
|
|
|
|
|
{
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int c=0; c<GetNumTracks(); c++ )
|
2002-10-25 04:59:12 +00:00
|
|
|
SetTapNote(c, iIndex, TAP_EMPTY);
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-08-01 21:55:40 +00:00
|
|
|
void NoteField::FadeToFail()
|
|
|
|
|
{
|
|
|
|
|
m_fPercentFadeToFail = max( 0.0f, m_fPercentFadeToFail ); // this will slowly increase every Update()
|
|
|
|
|
// don't fade all over again if this is called twice
|
2002-11-16 09:12:55 +00:00
|
|
|
}
|