Files
itgmania212121/stepmania/src/NoteDisplay.cpp
T

918 lines
38 KiB
C++
Raw Normal View History

2003-02-16 04:01:45 +00:00
#include "global.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"
2003-08-03 00:13:55 +00:00
#include "Steps.h"
#include "PrefsManager.h"
#include "GameState.h"
#include "NoteSkinManager.h"
#include "RageException.h"
#include "ArrowEffects.h"
#include "RageLog.h"
#include <math.h>
#include "RageDisplay.h"
#include "NoteTypes.h"
2003-04-17 21:45:37 +00:00
#include "NoteFieldPositioning.h"
#include "ActorUtil.h"
2003-05-09 04:42:04 +00:00
#define DRAW_HOLD_HEAD_FOR_TAPS_ON_SAME_ROW NOTESKIN->GetMetricB(skin,name,"DrawHoldHeadForTapsOnSameRow")
#define TAP_NOTE_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"TapNoteAnimationLengthInBeats")
#define TAP_ADDITION_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"TapAdditionAnimationLengthInBeats")
#define TAP_MINE_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"TapMineAnimationLengthInBeats")
#define HOLD_HEAD_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"HoldHeadAnimationLengthInBeats")
#define HOLD_TOPCAP_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"HoldTopCapAnimationLengthInBeats")
#define HOLD_BODY_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"HoldBodyAnimationLengthInBeats")
#define HOLD_BOTTOMCAP_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"HoldBottomCapAnimationLengthInBeats")
#define HOLD_TAIL_ANIMATION_LENGTH_IN_BEATS NOTESKIN->GetMetricF(skin,name,"HoldTailAnimationLengthInBeats")
#define TAP_NOTE_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"TapNoteAnimationIsVivid")
#define TAP_ADDITION_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"TapAdditionAnimationIsVivid")
#define TAP_MINE_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"TapMineAnimationIsVivid")
#define HOLD_HEAD_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"HoldHeadAnimationIsVivid")
#define HOLD_TOPCAP_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"HoldTopCapAnimationIsVivid")
#define HOLD_BODY_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"HoldBodyAnimationIsVivid")
#define HOLD_BOTTOMCAP_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"HoldBottomCapAnimationIsVivid")
#define HOLD_TAIL_ANIMATION_IS_VIVID NOTESKIN->GetMetricB(skin,name,"HoldTailAnimationIsVivid")
#define TAP_NOTE_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"TapNoteAnimationIsNoteColor")
2003-12-29 03:51:15 +00:00
#define TAP_ADDITION_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"TapAdditionAnimationIsNoteColor")
#define HOLD_HEAD_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"HoldHeadAnimationIsNoteColor")
#define HOLD_TOPCAP_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"HoldTopCapAnimationIsNoteColor")
#define HOLD_BODY_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"HoldBodyAnimationIsNoteColor")
#define HOLD_BOTTOMCAP_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"HoldBottomCapAnimationIsNoteColor")
#define HOLD_TAIL_ANIMATION_IS_NOTE_COLOR NOTESKIN->GetMetricB(skin,name,"HoldTailAnimationIsNoteColor")
#define HOLD_HEAD_IS_ABOVE_WAVY_PARTS NOTESKIN->GetMetricB(skin,name,"HoldHeadIsAboveWavyParts")
#define HOLD_TAIL_IS_ABOVE_WAVY_PARTS NOTESKIN->GetMetricB(skin,name,"HoldTailIsAboveWavyParts")
#define START_DRAWING_HOLD_BODY_OFFSET_FROM_HEAD NOTESKIN->GetMetricI(skin,name,"StartDrawingHoldBodyOffsetFromHead")
#define STOP_DRAWING_HOLD_BODY_OFFSET_FROM_TAIL NOTESKIN->GetMetricI(skin,name,"StopDrawingHoldBodyOffsetFromTail")
#define HOLD_NG_GRAY_PERCENT NOTESKIN->GetMetricF(skin,name,"HoldNGGrayPercent")
#define USE_LIGHTING NOTESKIN->GetMetricB(skin,name,"UseLighting")
#define FLIP_HEAD_AND_TAIL_WHEN_REVERSE NOTESKIN->GetMetricB(skin,name,"FlipHeadAndTailWhenReverse")
2003-01-13 08:31:34 +00:00
// cache
struct NoteMetricCache_t {
bool m_bDrawHoldHeadForTapsOnSameRow;
float m_fTapNoteAnimationLengthInBeats;
float m_fTapAdditionAnimationLengthInBeats;
2003-08-10 10:12:50 +00:00
float m_fTapMineAnimationLengthInBeats;
float m_fHoldHeadAnimationLengthInBeats;
float m_fHoldTopCapAnimationLengthInBeats;
float m_fHoldBodyAnimationLengthInBeats;
float m_fHoldBottomCapAnimationLengthInBeats;
float m_fHoldTailAnimationLengthInBeats;
bool m_bTapNoteAnimationIsVivid;
bool m_bTapAdditionAnimationIsVivid;
2003-08-10 10:12:50 +00:00
bool m_bTapMineAnimationIsVivid;
bool m_bHoldHeadAnimationIsVivid;
bool m_bHoldTopCapAnimationIsVivid;
bool m_bHoldBodyAnimationIsVivid;
bool m_bHoldBottomCapAnimationIsVivid;
bool m_bHoldTailAnimationIsVivid;
bool m_bTapNoteAnimationIsNoteColor;
2003-12-29 03:51:15 +00:00
bool m_bTapAdditionAnimationIsNoteColor;
bool m_bHoldHeadAnimationIsNoteColor;
bool m_bHoldTopCapAnimationIsNoteColor;
bool m_bHoldBodyAnimationIsNoteColor;
bool m_bHoldBottomCapAnimationIsNoteColor;
bool m_bHoldTailAnimationIsNoteColor;
bool m_bHoldHeadIsAboveWavyParts;
bool m_bHoldTailIsAboveWavyParts;
int m_iStartDrawingHoldBodyOffsetFromHead;
int m_iStopDrawingHoldBodyOffsetFromTail;
float m_fHoldNGGrayPercent;
2003-05-13 13:35:32 +00:00
bool m_bUseLighting;
bool m_bFlipHeadAndTailWhenReverse;
void Load(CString skin, const CString &name);
} *NoteMetricCache;
void NoteMetricCache_t::Load(CString skin, const CString &name)
{
m_bDrawHoldHeadForTapsOnSameRow = DRAW_HOLD_HEAD_FOR_TAPS_ON_SAME_ROW;
m_fTapNoteAnimationLengthInBeats = TAP_NOTE_ANIMATION_LENGTH_IN_BEATS;
m_fTapAdditionAnimationLengthInBeats = TAP_ADDITION_ANIMATION_LENGTH_IN_BEATS;
2003-08-10 10:12:50 +00:00
m_fTapMineAnimationLengthInBeats = TAP_MINE_ANIMATION_LENGTH_IN_BEATS;
m_fHoldHeadAnimationLengthInBeats = HOLD_HEAD_ANIMATION_LENGTH_IN_BEATS;
m_fHoldTopCapAnimationLengthInBeats = HOLD_TOPCAP_ANIMATION_LENGTH_IN_BEATS;
m_fHoldBodyAnimationLengthInBeats = HOLD_BODY_ANIMATION_LENGTH_IN_BEATS;
m_fHoldBottomCapAnimationLengthInBeats = HOLD_BOTTOMCAP_ANIMATION_LENGTH_IN_BEATS;
m_fHoldTailAnimationLengthInBeats = HOLD_TAIL_ANIMATION_LENGTH_IN_BEATS;
m_bTapNoteAnimationIsVivid = TAP_NOTE_ANIMATION_IS_VIVID;
m_bTapAdditionAnimationIsVivid = TAP_ADDITION_ANIMATION_IS_VIVID;
2003-08-10 10:12:50 +00:00
m_bTapMineAnimationIsVivid = TAP_MINE_ANIMATION_IS_VIVID;
m_bHoldHeadAnimationIsVivid = HOLD_HEAD_ANIMATION_IS_VIVID;
m_bHoldTopCapAnimationIsVivid = HOLD_TOPCAP_ANIMATION_IS_VIVID;
m_bHoldBodyAnimationIsVivid = HOLD_BODY_ANIMATION_IS_VIVID;
m_bHoldBottomCapAnimationIsVivid = HOLD_BOTTOMCAP_ANIMATION_IS_VIVID;
m_bHoldTailAnimationIsVivid = HOLD_TAIL_ANIMATION_IS_VIVID;
m_bTapNoteAnimationIsNoteColor = TAP_NOTE_ANIMATION_IS_NOTE_COLOR;
2003-12-29 03:51:15 +00:00
m_bTapAdditionAnimationIsNoteColor = TAP_ADDITION_ANIMATION_IS_NOTE_COLOR;
m_bHoldHeadAnimationIsNoteColor = HOLD_HEAD_ANIMATION_IS_NOTE_COLOR;
m_bHoldTopCapAnimationIsNoteColor = HOLD_TOPCAP_ANIMATION_IS_NOTE_COLOR;
m_bHoldBodyAnimationIsNoteColor = HOLD_BODY_ANIMATION_IS_NOTE_COLOR;
m_bHoldBottomCapAnimationIsNoteColor = HOLD_BOTTOMCAP_ANIMATION_IS_NOTE_COLOR;
m_bHoldTailAnimationIsNoteColor = HOLD_TAIL_ANIMATION_IS_NOTE_COLOR;
m_bHoldHeadIsAboveWavyParts = HOLD_HEAD_IS_ABOVE_WAVY_PARTS;
m_bHoldTailIsAboveWavyParts = HOLD_TAIL_IS_ABOVE_WAVY_PARTS;
m_iStartDrawingHoldBodyOffsetFromHead = START_DRAWING_HOLD_BODY_OFFSET_FROM_HEAD;
m_iStopDrawingHoldBodyOffsetFromTail = STOP_DRAWING_HOLD_BODY_OFFSET_FROM_TAIL;
m_fHoldNGGrayPercent = HOLD_NG_GRAY_PERCENT;
2003-05-13 13:35:32 +00:00
m_bUseLighting = USE_LIGHTING;
m_bFlipHeadAndTailWhenReverse = FLIP_HEAD_AND_TAIL_WHEN_REVERSE;
2003-09-12 02:44:14 +00:00
}
NoteDisplay::NoteDisplay()
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_pTapNote[i] = NULL;
2003-12-29 03:51:15 +00:00
m_pTapAddition[i] = NULL;
2003-09-12 02:44:14 +00:00
m_pHoldHeadActive[i] = NULL;
m_pHoldHeadInactive[i] = NULL;
2003-09-23 01:24:20 +00:00
m_pHoldTailActive[i] = NULL;
m_pHoldTailInactive[i] = NULL;
2003-09-12 02:44:14 +00:00
}
m_pTapMine = NULL;
cache = new NoteMetricCache_t;
}
NoteDisplay::~NoteDisplay()
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
delete m_pTapNote[i];
2003-12-29 03:51:15 +00:00
delete m_pTapAddition[i];
2003-09-12 02:44:14 +00:00
delete m_pHoldHeadActive[i];
delete m_pHoldHeadInactive[i];
2003-09-23 01:24:20 +00:00
delete m_pHoldTailActive[i];
delete m_pHoldTailInactive[i];
2003-09-12 02:44:14 +00:00
}
delete m_pTapMine;
delete cache;
}
void NoteDisplay::Load( int iColNum, PlayerNumber pn, CString NoteSkin, float fYReverseOffsetPixels )
2003-09-12 02:44:14 +00:00
{
m_PlayerNumber = pn;
m_fYReverseOffsetPixels = fYReverseOffsetPixels;
/* Normally, this is empty and we use the style table entry via ColToButtonName. */
CString Button = g_NoteFieldMode[m_PlayerNumber].NoteButtonNames[iColNum];
if(Button == "")
Button = NoteSkinManager::ColToButtonName(iColNum);
cache->Load( NoteSkin, Button );
// Look up note names once and store them here.
CString sNoteType[ NOTE_COLOR_IMAGES ];
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
sNoteType[i] = NoteTypeToString( (NoteType)i );
2003-09-12 02:44:14 +00:00
if( cache->m_bTapNoteAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
m_pTapNote[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "tap note "+sNoteType[i]) );
}
else
{
m_pTapNote[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "tap note") );
}
2003-12-29 03:51:15 +00:00
if( cache->m_bTapAdditionAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
m_pTapAddition[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "tap addition "+sNoteType[i]) );
}
else
{
m_pTapAddition[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "tap addition") );
}
m_pTapMine = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "tap mine") );
2003-08-10 10:12:50 +00:00
2003-09-12 02:44:14 +00:00
if( cache->m_bHoldHeadAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_pHoldHeadActive[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold head active "+sNoteType[i]) );
m_pHoldHeadInactive[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold head inactive "+sNoteType[i]) );
}
}
else
{
m_pHoldHeadActive[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold head active") );
m_pHoldHeadInactive[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold head inactive") );
}
2003-09-12 02:44:14 +00:00
if( cache->m_bHoldTopCapAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_sprHoldTopCapActive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold topcap active "+sNoteType[i]) );
m_sprHoldTopCapInactive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold topcap inactive "+sNoteType[i]) );
}
}
else
{
m_sprHoldTopCapActive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold topcap active") );
m_sprHoldTopCapInactive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold topcap inactive") );
}
2003-09-12 02:44:14 +00:00
if( cache->m_bHoldBodyAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_sprHoldBodyActive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold body active "+sNoteType[i]) );
m_sprHoldBodyInactive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold body inactive "+sNoteType[i]) );
}
}
else
{
m_sprHoldBodyActive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold body active") );
m_sprHoldBodyInactive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold body inactive") );
}
2003-09-12 02:44:14 +00:00
if( cache->m_bHoldBottomCapAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_sprHoldBottomCapActive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold bottomcap active "+sNoteType[i]) );
m_sprHoldBottomCapInactive[i].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold bottomcap inactive "+sNoteType[i]) );
}
}
else
{
m_sprHoldBottomCapActive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold bottomcap active") );
m_sprHoldBottomCapInactive[0].Load( NOTESKIN->GetPathTo(NoteSkin, Button, "hold bottomcap inactive") );
}
2003-09-12 02:44:14 +00:00
if( cache->m_bHoldTailAnimationIsNoteColor )
{
for( int i=0; i<NOTE_COLOR_IMAGES; i++ )
{
m_pHoldTailActive[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold tail active "+sNoteType[i]) );
m_pHoldTailInactive[i] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold tail inactive "+sNoteType[i]) );
}
}
else
{
m_pHoldTailActive[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold tail active") );
m_pHoldTailInactive[0] = MakeActor( NOTESKIN->GetPathTo(NoteSkin, Button, "hold tail inactive") );
}
}
2003-05-09 04:42:04 +00:00
void NoteDisplay::SetActiveFrame( float fNoteBeat, Actor &actorToSet, float fAnimationLengthInBeats, bool bVivid, bool bNoteColor )
{
2003-05-09 04:42:04 +00:00
const int iNumFrames = actorToSet.GetNumStates();
if( iNumFrames == 0 ) // Model with no textures
return;
float fSongBeat = GAMESTATE->m_fSongBeat;
float fPrecentIntoAnimation = fmodf(fSongBeat,fAnimationLengthInBeats) / fAnimationLengthInBeats;
float fNoteBeatFraction = fmodf( fNoteBeat, 1.0f );
2003-02-07 01:23:35 +00:00
int iFrameNo = (int)(fPrecentIntoAnimation*iNumFrames);
if( bVivid )
2003-02-07 01:23:35 +00:00
iFrameNo += (int)( froundf(fNoteBeatFraction,1.f/fAnimationLengthInBeats)*iNumFrames );
iFrameNo += iNumFrames;
iFrameNo %= iNumFrames;
ASSERT( iFrameNo>=0 && iFrameNo<iNumFrames );
2003-05-09 04:42:04 +00:00
actorToSet.SetState( iFrameNo );
2003-01-13 08:31:34 +00:00
}
2003-05-09 04:42:04 +00:00
Actor * NoteDisplay::GetTapNoteActor( float fNoteBeat )
{
NoteType nt = NoteType(0);
if( cache->m_bTapNoteAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Actor *pActorOut = m_pTapNote[nt];
SetActiveFrame(
fNoteBeat,
2003-05-09 04:42:04 +00:00
*pActorOut,
cache->m_fTapNoteAnimationLengthInBeats,
cache->m_bTapNoteAnimationIsVivid,
cache->m_bTapNoteAnimationIsNoteColor );
2003-05-09 04:42:04 +00:00
return pActorOut;
}
Actor * NoteDisplay::GetTapAdditionActor( float fNoteBeat )
{
2003-12-29 03:51:15 +00:00
NoteType nt = NoteType(0);
if( cache->m_bTapAdditionAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
Actor *pActorOut = m_pTapAddition[nt];
SetActiveFrame(
fNoteBeat,
2003-12-29 03:51:15 +00:00
*pActorOut,
cache->m_fTapAdditionAnimationLengthInBeats,
cache->m_bTapAdditionAnimationIsVivid,
2003-12-29 03:51:15 +00:00
cache->m_bTapAdditionAnimationIsNoteColor );
2003-12-29 03:51:15 +00:00
return pActorOut;
}
2003-08-10 10:12:50 +00:00
Actor * NoteDisplay::GetTapMineActor( float fNoteBeat )
{
SetActiveFrame(
fNoteBeat,
2003-09-12 02:44:14 +00:00
*m_pTapMine,
2003-08-10 10:12:50 +00:00
cache->m_fTapMineAnimationLengthInBeats,
cache->m_bTapMineAnimationIsVivid,
false );
2003-09-12 02:44:14 +00:00
return m_pTapMine;
2003-08-10 10:12:50 +00:00
}
Sprite * NoteDisplay::GetHoldTopCapSprite( float fNoteBeat, bool bActive )
{
NoteType nt = NoteType(0);
if( cache->m_bHoldTopCapAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Sprite *pSpriteOut = bActive ? &m_sprHoldTopCapActive[nt] : &m_sprHoldTopCapInactive[nt];
SetActiveFrame(
fNoteBeat,
*pSpriteOut,
cache->m_fHoldTopCapAnimationLengthInBeats,
cache->m_bHoldTopCapAnimationIsVivid,
cache->m_bHoldTopCapAnimationIsNoteColor );
return pSpriteOut;
}
Sprite * NoteDisplay::GetHoldBottomCapSprite( float fNoteBeat, bool bActive )
{
NoteType nt = NoteType(0);
if( cache->m_bHoldBottomCapAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Sprite *pSpriteOut = bActive ? &m_sprHoldBottomCapActive[nt] : &m_sprHoldBottomCapInactive[nt];
SetActiveFrame(
fNoteBeat,
*pSpriteOut,
cache->m_fHoldBottomCapAnimationLengthInBeats,
cache->m_bHoldBottomCapAnimationIsVivid,
cache->m_bHoldBottomCapAnimationIsNoteColor );
return pSpriteOut;
}
2003-05-09 04:42:04 +00:00
Actor* NoteDisplay::GetHoldHeadActor( float fNoteBeat, bool bActive )
{
NoteType nt = NoteType(0);
if( cache->m_bHoldHeadAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Actor *pActorOut = bActive ? m_pHoldHeadActive[nt] : m_pHoldHeadInactive[nt];
SetActiveFrame(
fNoteBeat,
2003-05-09 04:42:04 +00:00
*pActorOut,
cache->m_fHoldHeadAnimationLengthInBeats,
cache->m_bHoldHeadAnimationIsVivid,
cache->m_bHoldHeadAnimationIsNoteColor );
2003-05-09 04:42:04 +00:00
return pActorOut;
}
Sprite *NoteDisplay::GetHoldBodySprite( float fNoteBeat, bool bActive )
{
NoteType nt = NoteType(0);
if( cache->m_bHoldBodyAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Sprite *pSpriteOut = bActive ? &m_sprHoldBodyActive[nt] : &m_sprHoldBodyInactive[nt];
SetActiveFrame(
fNoteBeat,
*pSpriteOut,
cache->m_fHoldBodyAnimationLengthInBeats,
cache->m_bHoldBodyAnimationIsVivid,
cache->m_bHoldBodyAnimationIsNoteColor );
return pSpriteOut;
}
2003-07-09 05:57:48 +00:00
Actor* NoteDisplay::GetHoldTailActor( float fNoteBeat, bool bActive )
{
NoteType nt = NoteType(0);
if( cache->m_bHoldTailAnimationIsNoteColor )
nt = BeatToNoteType( fNoteBeat );
// NOTE_TYPE_INVALID is 192nds at this point.
if( nt == NOTE_TYPE_INVALID )
nt = NOTE_TYPE_192ND;
2003-11-06 07:19:46 +00:00
nt = min( nt, (NoteType) (NOTE_COLOR_IMAGES-1) );
2003-09-12 02:44:14 +00:00
Actor *pActorOut = bActive ? m_pHoldTailActive[nt] : m_pHoldTailInactive[nt];
SetActiveFrame(
fNoteBeat,
2003-07-09 05:57:48 +00:00
*pActorOut,
cache->m_fHoldTailAnimationLengthInBeats,
cache->m_bHoldTailAnimationIsVivid,
cache->m_bHoldTailAnimationIsNoteColor );
2003-07-09 05:57:48 +00:00
return pActorOut;
}
void NoteDisplay::DrawHoldTopCap( const HoldNote& hn, const bool bActive, float fYHead, float fYTail, int fYStep, int iCol, float fPercentFadeToFail, float fColorScale, bool bGlow )
{
//
// Draw the top cap (always wavy)
//
2003-06-28 02:15:27 +00:00
const int size = 4096;
static RageSpriteVertex queue[size];
2003-12-16 04:00:39 +00:00
Sprite* pSprTopCap = GetHoldTopCapSprite( hn.GetStartBeat(), bActive );
// draw manually in small segments
RageSpriteVertex *v = &queue[0];
RageTexture* pTexture = pSprTopCap->GetTexture();
const RectF *pRect = pSprTopCap->GetCurrentTextureCoordRect();
DISPLAY->SetTexture( pTexture );
DISPLAY->SetBlendMode( BLEND_NORMAL );
DISPLAY->SetBackfaceCull( false );
DISPLAY->SetTextureWrapping(false);
const float fFrameWidth = pSprTopCap->GetUnzoomedWidth();
const float fFrameHeight = pSprTopCap->GetUnzoomedHeight();
const float fYCapTop = fYHead+cache->m_iStartDrawingHoldBodyOffsetFromHead-fFrameHeight;
const float fYCapBottom = fYHead+cache->m_iStartDrawingHoldBodyOffsetFromHead;
for( float fY=fYCapTop; fY<fYCapBottom; fY+=fYStep )
{
const float fYTop = fY;
2003-09-30 03:14:09 +00:00
const float fYOffsetTop = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYTop, m_fYReverseOffsetPixels );
const float fStepHeight = min( fYStep, fFrameHeight );
const float fYBottom = min( fY+fStepHeight, fYCapBottom );
2003-09-30 03:14:09 +00:00
const float fYOffsetBottom = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYBottom, m_fYReverseOffsetPixels );
const float fZTop = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fZBottom = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetBottom );
const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetBottom );
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 - fYCapTop;
const float fBottomDistFromHeadTop = fYBottom - fYCapTop;
const float fTexCoordTop = SCALE( fTopDistFromHeadTop, 0, fFrameHeight, pRect->top, pRect->bottom );
const float fTexCoordBottom = SCALE( fBottomDistFromHeadTop, 0, fFrameHeight, pRect->top, pRect->bottom );
ASSERT( fTexCoordTop>=-0.0001 && fTexCoordBottom<=1.0001 ); /* allow for rounding error */
const float fTexCoordLeft = pRect->left;
const float fTexCoordRight = pRect->right;
2003-09-30 03:14:09 +00:00
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
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);
if( bGlow && colorGlowTop.a==0 && colorGlowBottom.a==0 )
continue;
if( !bGlow && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 )
continue;
v[0].p = RageVector3(fXTopLeft, fYTop, fZTop); v[0].c = bGlow? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop),
v[1].p = RageVector3(fXTopRight, fYTop, fZTop); v[1].c = bGlow? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
v[2].p = RageVector3(fXBottomRight,fYBottom,fZBottom); v[2].c = bGlow? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
v[3].p = RageVector3(fXBottomLeft, fYBottom,fZBottom); v[3].c = bGlow? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
v+=4;
if( v-queue >= size )
break;
}
DISPLAY->DrawQuads( queue, v-queue );
}
void NoteDisplay::DrawHoldBody( const HoldNote& hn, const bool bActive, float fYHead, float fYTail, int fYStep, int iCol, float fPercentFadeToFail, float fColorScale, bool bGlow )
{
//
// Draw the body (always wavy)
//
const int size = 4096;
static RageSpriteVertex queue[size];
2003-12-16 04:00:39 +00:00
Sprite* pSprBody = GetHoldBodySprite( hn.GetStartBeat(), bActive );
// draw manually in small segments
RageSpriteVertex *v = &queue[0];
RageTexture* pTexture = pSprBody->GetTexture();
const RectF *pRect = pSprBody->GetCurrentTextureCoordRect();
DISPLAY->SetTexture( pTexture );
DISPLAY->SetBlendMode( BLEND_NORMAL );
DISPLAY->SetBackfaceCull( false );
DISPLAY->SetTextureWrapping( true );
const float fFrameWidth = pSprBody->GetUnzoomedWidth();
const float fFrameHeight = pSprBody->GetUnzoomedHeight();
const float fYBodyTop = fYHead + cache->m_iStartDrawingHoldBodyOffsetFromHead;
const float fYBodyBottom = fYTail + cache->m_iStopDrawingHoldBodyOffsetFromTail;
// top to bottom
for( float fY=fYBodyTop; fY<=fYBodyBottom; fY+=fYStep )
{
const float fYTop = fY;
2003-09-30 03:14:09 +00:00
const float fYOffsetTop = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYTop, m_fYReverseOffsetPixels );
const float fYBottom = min( fY+fYStep, fYBodyBottom );
2003-09-30 03:14:09 +00:00
const float fYOffsetBottom = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYBottom, m_fYReverseOffsetPixels );
const float fZTop = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fZBottom = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetBottom );
const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetBottom );
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 fTopDistFromBodyBottom = fYBodyBottom - fYTop;
const float fBottomDistFromBodyBottom = fYBodyBottom - fYBottom;
float fTexCoordTop = SCALE( fTopDistFromBodyBottom, 0, fFrameHeight, pRect->bottom, pRect->top );
float fTexCoordBottom = SCALE( fBottomDistFromBodyBottom, 0, fFrameHeight, pRect->bottom, pRect->top );
if( fTexCoordTop < 0 )
{
int iToSubtract = (int)fTexCoordTop - 1;
fTexCoordTop -= iToSubtract;
fTexCoordBottom -= iToSubtract;
}
else if( fTexCoordBottom > 2 )
{
int iToSubtract = (int)fTexCoordBottom;
fTexCoordTop -= iToSubtract;
fTexCoordBottom -= iToSubtract;
}
ASSERT( fTexCoordTop>=0 && fTexCoordBottom>=0 );
ASSERT( fTexCoordTop<=2 && fTexCoordBottom<=2 );
const float fTexCoordLeft = pRect->left;
const float fTexCoordRight = pRect->right;
2003-09-30 03:14:09 +00:00
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
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);
if( bGlow && colorGlowTop.a==0 && colorGlowBottom.a==0 )
continue;
if( !bGlow && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 )
continue;
v[0].p = RageVector3(fXTopLeft, fYTop, fZTop); v[0].c = bGlow? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
v[1].p = RageVector3(fXTopRight, fYTop, fZTop); v[1].c = bGlow? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
v[2].p = RageVector3(fXBottomRight,fYBottom,fZBottom); v[2].c = bGlow? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
v[3].p = RageVector3(fXBottomLeft, fYBottom,fZBottom); v[3].c = bGlow? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
v+=4;
if( v-queue >= size )
break;
}
DISPLAY->DrawQuads( queue, v-queue );
}
void NoteDisplay::DrawHoldBottomCap( const HoldNote& hn, const bool bActive, float fYHead, float fYTail, int fYStep, int iCol, float fPercentFadeToFail, float fColorScale, bool bGlow )
{
//
// Draw the bottom cap (always wavy)
//
const int size = 4096;
static RageSpriteVertex queue[size];
2003-12-16 04:00:39 +00:00
Sprite* pBottomCap = GetHoldBottomCapSprite( hn.GetStartBeat(), bActive );
// draw manually in small segments
RageSpriteVertex *v = &queue[0];
RageTexture* pTexture = pBottomCap->GetTexture();
const RectF *pRect = pBottomCap->GetCurrentTextureCoordRect();
DISPLAY->SetTexture( pTexture );
DISPLAY->SetBlendMode( BLEND_NORMAL );
DISPLAY->SetBackfaceCull( false );
DISPLAY->SetTextureWrapping(false);
const float fFrameWidth = pBottomCap->GetUnzoomedWidth();
const float fFrameHeight = pBottomCap->GetUnzoomedHeight();
const float fYCapTop = fYTail+cache->m_iStopDrawingHoldBodyOffsetFromTail;
const float fYCapBottom = fYTail+cache->m_iStopDrawingHoldBodyOffsetFromTail+fFrameHeight;
// don't draw any part of the tail that is before the middle of the head
float fY=max( fYCapTop, fYHead );
for( ; fY<fYCapBottom; fY+=fYStep )
{
const float fYTop = fY;
2003-09-30 03:14:09 +00:00
const float fYOffsetTop = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYTop, m_fYReverseOffsetPixels );
const float fStepHeight = min( fYStep, fFrameHeight );
const float fYBottom = min( fY+fStepHeight, fYCapBottom );
2003-09-30 03:14:09 +00:00
const float fYOffsetBottom = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fYBottom, m_fYReverseOffsetPixels );
const float fZTop = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fZBottom = ArrowGetZPos( m_PlayerNumber, iCol, fYOffsetBottom );
const float fXTop = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetTop );
const float fXBottom = ArrowGetXPos( m_PlayerNumber, iCol, fYOffsetBottom );
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 - fYCapTop;
const float fBottomDistFromTailTop = fYBottom - fYCapTop;
const float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fFrameHeight, pRect->top, pRect->bottom );
const float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fFrameHeight, pRect->top, pRect->bottom );
const float fTexCoordLeft = pRect->left;
const float fTexCoordRight = pRect->right;
2003-09-30 03:14:09 +00:00
const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fAlphaBottom = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowTop = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetTop, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlowBottom = ArrowGetGlow( m_PlayerNumber, iCol, fYOffsetBottom, fPercentFadeToFail, m_fYReverseOffsetPixels );
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);
if( bGlow && colorGlowTop.a==0 && colorGlowBottom.a==0 )
continue;
if( !bGlow && colorDiffuseTop.a==0 && colorDiffuseBottom.a==0 )
continue;
v[0].p = RageVector3(fXTopLeft, fYTop, fZTop); v[0].c = bGlow ? colorGlowTop : colorDiffuseTop; v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop),
v[1].p = RageVector3(fXTopRight, fYTop, fZTop); v[1].c = bGlow ? colorGlowTop : colorDiffuseTop; v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
v[2].p = RageVector3(fXBottomRight,fYBottom,fZBottom); v[2].c = bGlow ? colorGlowBottom : colorDiffuseBottom; v[2].t = RageVector2(fTexCoordRight, fTexCoordBottom);
v[3].p = RageVector3(fXBottomLeft, fYBottom,fZBottom); v[3].c = bGlow ? colorGlowBottom : colorDiffuseBottom; v[3].t = RageVector2(fTexCoordLeft, fTexCoordBottom);
v+=4;
if( v-queue >= size )
break;
}
DISPLAY->DrawQuads( queue, v-queue );
}
void NoteDisplay::DrawHoldTail( const HoldNote& hn, bool bActive, float fYTail, int iCol, float fPercentFadeToFail, float fColorScale, bool bGlow )
{
//
// Draw the tail
//
2003-12-16 04:00:39 +00:00
Actor* pSprTail = GetHoldTailActor( hn.GetStartBeat(), bActive );
const float fY = fYTail;
2003-09-30 03:14:09 +00:00
const float fYOffset = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fY, m_fYReverseOffsetPixels );
const float fX = ArrowGetXPos( m_PlayerNumber, iCol, fYOffset );
const float fZ = ArrowGetZPos( m_PlayerNumber, iCol, fYOffset );
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlow = ArrowGetGlow( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const RageColor colorDiffuse= RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
const RageColor colorGlow = RageColor(1,1,1,fGlow);
pSprTail->SetXY( fX, fY );
pSprTail->SetZ( fZ );
if( bGlow )
{
pSprTail->SetDiffuse( RageColor(1,1,1,0) );
pSprTail->SetGlow( colorGlow );
}
else
{
pSprTail->SetDiffuse( colorDiffuse );
pSprTail->SetGlow( RageColor(0,0,0,0) );
}
2003-07-17 06:11:32 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLighting( true );
DISPLAY->SetLightDirectional(
0,
RageColor(0.1f,0.1f,0.1f,1),
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageVector3(1, 0, +1) );
}
pSprTail->Draw();
2003-07-17 06:11:32 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLightOff( 0 );
DISPLAY->SetLighting( false );
}
}
void NoteDisplay::DrawHoldHead( const HoldNote& hn, bool bActive, float fYHead, int iCol, float fPercentFadeToFail, float fColorScale, bool bGlow )
{
//
// Draw the head
//
2003-12-16 04:00:39 +00:00
Actor* pActor = GetHoldHeadActor( hn.GetStartBeat(), bActive );
// draw with normal Sprite
const float fY = fYHead;
2003-09-30 03:14:09 +00:00
const float fYOffset = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fY, m_fYReverseOffsetPixels );
const float fX = ArrowGetXPos( m_PlayerNumber, iCol, fYOffset );
const float fZ = ArrowGetZPos( m_PlayerNumber, iCol, fYOffset );
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlow = ArrowGetGlow( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const RageColor colorDiffuse= RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
const RageColor colorGlow = RageColor(1,1,1,fGlow);
pActor->SetXY( fX, fY );
pActor->SetZ( fZ );
2003-07-09 00:49:05 +00:00
if( bGlow )
{
pActor->SetDiffuse( RageColor(1,1,1,0) );
pActor->SetGlow( colorGlow );
}
else
{
pActor->SetDiffuse( colorDiffuse );
pActor->SetGlow( RageColor(0,0,0,0) );
}
2003-07-10 03:38:45 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLighting( true );
DISPLAY->SetLightDirectional(
0,
RageColor(0.1f,0.1f,0.1f,1),
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageVector3(1, 0, +1) );
}
2003-07-10 03:38:45 +00:00
pActor->Draw();
2003-07-10 03:38:45 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLightOff( 0 );
DISPLAY->SetLighting( false );
}
}
void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail, bool bDrawGlowOnly, float fReverseOffsetPixels )
{
// 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
const int iCol = hn.iTrack;
2003-08-17 00:15:54 +00:00
const bool bReverse = GAMESTATE->m_CurrentPlayerOptions[m_PlayerNumber].GetReversePercentForColumn(iCol) > 0.5;
2003-12-16 04:00:39 +00:00
const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.GetStartBeat() );
const float fStartYPos = ArrowGetYPos( m_PlayerNumber, iCol, fStartYOffset, fReverseOffsetPixels );
2003-12-16 04:00:39 +00:00
const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.GetEndBeat() );
const float fEndYPos = ArrowGetYPos( m_PlayerNumber, iCol, fEndYOffset, fReverseOffsetPixels );
const float fYHead = bReverse ? fEndYPos : fStartYPos; // the center of the head
const float fYTail = bReverse ? fStartYPos : fEndYPos; // the center the tail
// const bool bWavy = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fEffects[PlayerOptions::EFFECT_DRUNK] > 0;
const bool WavyPartsNeedZBuffer = ArrowsNeedZBuffer( m_PlayerNumber );
/* Hack: Z effects need a finer grain step. */
const int fYStep = WavyPartsNeedZBuffer? 4: 16; //bWavy ? 16 : 128; // use small steps only if wavy
const float fColorScale = 1*fLife + (1-fLife)*cache->m_fHoldNGGrayPercent;
2003-10-19 07:47:16 +00:00
bool bFlipHeadAndTail = bReverse && cache->m_bFlipHeadAndTailWhenReverse;
/* The body and caps should have no overlap, so their order doesn't matter.
* Draw the head last, so it appears on top. */
if( !cache->m_bHoldHeadIsAboveWavyParts )
2003-10-19 07:47:16 +00:00
DrawHoldHead( hn, bActive, bFlipHeadAndTail ? fYTail : fYHead, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
if( !cache->m_bHoldTailIsAboveWavyParts )
2003-10-19 07:47:16 +00:00
DrawHoldTail( hn, bActive, bFlipHeadAndTail ? fYHead : fYTail, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
if( bDrawGlowOnly )
DISPLAY->SetTextureModeGlow();
else
DISPLAY->SetTextureModeModulate();
DISPLAY->SetZBuffer( WavyPartsNeedZBuffer );
DrawHoldBottomCap( hn, bActive, fYHead, fYTail, fYStep, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
DrawHoldBody( hn, bActive, fYHead, fYTail, fYStep, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
DrawHoldTopCap( hn, bActive, fYHead, fYTail, fYStep, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
/* These set the texture mode themselves. */
if( cache->m_bHoldTailIsAboveWavyParts )
2003-10-19 07:47:16 +00:00
DrawHoldTail( hn, bActive, bFlipHeadAndTail ? fYHead : fYTail, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
if( cache->m_bHoldHeadIsAboveWavyParts )
2003-10-19 07:47:16 +00:00
DrawHoldHead( hn, bActive, bFlipHeadAndTail ? fYTail : fYHead, iCol, fPercentFadeToFail, fColorScale, bDrawGlowOnly );
// now, draw the glow pass
if( !bDrawGlowOnly )
DrawHold( hn, bActive, fLife, fPercentFadeToFail, true, fReverseOffsetPixels );
}
2003-11-15 08:51:47 +00:00
void NoteDisplay::DrawActor( Actor* pActor, int iCol, float fBeat, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels )
{
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, iCol, fYOffset, fReverseOffsetPixels );
2003-02-12 22:05:14 +00:00
const float fRotation = ArrowGetRotation( m_PlayerNumber, fBeat );
2003-09-30 03:14:09 +00:00
const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYOffset );
const float fZPos = ArrowGetZPos( m_PlayerNumber, iCol, fYOffset );
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fGlow = ArrowGetGlow( m_PlayerNumber, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
const float fColorScale = ArrowGetBrightness( m_PlayerNumber, fBeat ) * SCALE(fLife,0,1,0.2f,1);
2003-01-14 05:35:12 +00:00
RageColor diffuse = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
RageColor glow = RageColor(1,1,1,fGlow);
pActor->SetRotationZ( fRotation );
2003-05-09 04:42:04 +00:00
pActor->SetXY( fXPos, fYPos );
2003-07-09 00:49:05 +00:00
pActor->SetZ( fZPos );
2003-05-09 04:42:04 +00:00
pActor->SetDiffuse( diffuse );
pActor->SetGlow( glow );
2003-05-11 07:23:47 +00:00
2003-05-13 13:35:32 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLighting( true );
2003-05-13 13:35:32 +00:00
DISPLAY->SetLightDirectional(
0,
2003-07-10 03:38:45 +00:00
RageColor(0.1f,0.1f,0.1f,1),
2003-05-13 13:35:32 +00:00
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageVector3(1, 0, +1) );
}
2003-05-11 07:23:47 +00:00
2003-05-09 04:42:04 +00:00
pActor->Draw();
2003-05-11 07:23:47 +00:00
2003-05-13 13:35:32 +00:00
if( cache->m_bUseLighting )
{
DISPLAY->SetLightOff( 0 );
DISPLAY->SetLighting( false );
2003-05-13 13:35:32 +00:00
}
2003-01-14 05:35:12 +00:00
}
2003-11-15 08:51:47 +00:00
void NoteDisplay::DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bool bIsAddition, bool bIsMine, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels )
{
Actor* pActor = NULL;
if( bIsMine )
pActor = GetTapMineActor( fBeat );
else if( bIsAddition )
pActor = GetTapAdditionActor( fBeat );
else if( bOnSameRowAsHoldStart && cache->m_bDrawHoldHeadForTapsOnSameRow )
pActor = GetHoldHeadActor( fBeat, false );
else
pActor = GetTapNoteActor( fBeat );
DrawActor( pActor, iCol, fBeat, fPercentFadeToFail, fLife, fReverseOffsetPixels );
}
2003-01-14 05:35:12 +00:00
// if( ct == PlayerOptions::COLOR_NOTE )
// {
// RageColor color = GetNoteColorFromBeat( fNoteBeat );
// 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;
// }