Merge pull request #574 from kyzentun/stripes2

Attempts to improve performance
This commit is contained in:
Kyzentun
2015-04-30 17:19:30 -06:00
20 changed files with 699 additions and 823 deletions
+81 -108
View File
@@ -17,6 +17,7 @@
#include <typeinfo>
static Preference<bool> g_bShowMasks("ShowMasks", false);
static const float default_effect_period= 1.0f;
/**
* @brief Set up a hidden Actor that won't be drawn.
@@ -107,10 +108,7 @@ void Actor::InitState()
#endif
m_fSecsIntoEffect = 0;
m_fEffectDelta = 0;
m_fEffectRampUp = 0.5f;
m_fEffectHoldAtHalf = 0;
m_fEffectRampDown = 0.5f;
m_fEffectHoldAtZero = 0;
SetEffectPeriod(default_effect_period);
m_fEffectOffset = 0;
m_EffectClock = CLOCK_TIMER;
m_vEffectMagnitude = RageVector3(0,0,10);
@@ -229,6 +227,7 @@ Actor::Actor( const Actor &cpy ):
CPY( m_fEffectHoldAtHalf );
CPY( m_fEffectRampDown );
CPY( m_fEffectHoldAtZero );
CPY(m_effect_period);
CPY( m_fEffectOffset );
CPY( m_EffectClock );
@@ -801,7 +800,9 @@ void Actor::Update( float fDeltaTime )
{
m_fHibernateSecondsLeft -= fDeltaTime;
if( m_fHibernateSecondsLeft > 0 )
{
return;
}
// Grab the leftover time.
fDeltaTime = -m_fHibernateSecondsLeft;
@@ -815,69 +816,65 @@ void Actor::Update( float fDeltaTime )
this->UpdateInternal( fDeltaTime );
}
void Actor::UpdateInternal( float fDeltaTime )
static void generic_global_timer_update(float new_time, float& effect_delta_time, float& time_into_effect)
{
effect_delta_time= new_time - time_into_effect;
time_into_effect= new_time;
}
void Actor::UpdateInternal(float delta_time)
{
if( m_bFirstUpdate )
m_bFirstUpdate = false;
switch( m_EffectClock )
switch(m_EffectClock)
{
case CLOCK_TIMER:
m_fSecsIntoEffect += fDeltaTime;
m_fEffectDelta = fDeltaTime;
/* Wrap the counter, so it doesn't increase indefinitely (causing loss
* of precision if a screen is left to sit for a day). */
if( m_fSecsIntoEffect >= GetEffectPeriod() )
m_fSecsIntoEffect -= GetEffectPeriod();
break;
case CLOCK_TIMER_GLOBAL:
{
float fTime = RageTimer::GetTimeSinceStartFast();
m_fEffectDelta = fTime - m_fSecsIntoEffect;
m_fSecsIntoEffect = fTime;
break;
}
case CLOCK_BGM_BEAT:
m_fEffectDelta = g_fCurrentBGMBeat - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCurrentBGMBeat;
break;
case CLOCK_BGM_BEAT_PLAYER1:
m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_1] - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_1];
break;
case CLOCK_BGM_BEAT_PLAYER2:
m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_2] - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_2];
break;
case CLOCK_BGM_TIME:
m_fEffectDelta = g_fCurrentBGMTime - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCurrentBGMTime;
break;
case CLOCK_BGM_BEAT_NO_OFFSET:
m_fEffectDelta = g_fCurrentBGMBeatNoOffset - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCurrentBGMBeatNoOffset;
break;
case CLOCK_BGM_TIME_NO_OFFSET:
m_fEffectDelta = g_fCurrentBGMTimeNoOffset - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCurrentBGMTimeNoOffset;
break;
default:
if( m_EffectClock >= CLOCK_LIGHT_1 && m_EffectClock <= CLOCK_LIGHT_LAST )
{
int i = m_EffectClock - CLOCK_LIGHT_1;
m_fEffectDelta = g_fCabinetLights[i] - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCabinetLights[i];
}
break;
case CLOCK_TIMER:
m_fSecsIntoEffect+= delta_time;
m_fEffectDelta= delta_time;
// Wrap the counter, so it doesn't increase indefinitely (causing loss
// of precision if a screen is left to sit for a day).
if(m_fSecsIntoEffect > GetEffectPeriod())
{
m_fSecsIntoEffect-= GetEffectPeriod();
}
break;
case CLOCK_TIMER_GLOBAL:
generic_global_timer_update(RageTimer::GetUsecsSinceStart(),
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_BEAT:
generic_global_timer_update(g_fCurrentBGMBeat,
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_BEAT_PLAYER1:
generic_global_timer_update(g_vfCurrentBGMBeatPlayer[PLAYER_1],
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_BEAT_PLAYER2:
generic_global_timer_update(g_vfCurrentBGMBeatPlayer[PLAYER_2],
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_TIME:
generic_global_timer_update(g_fCurrentBGMTime,
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_BEAT_NO_OFFSET:
generic_global_timer_update(g_fCurrentBGMBeatNoOffset,
m_fEffectDelta, m_fSecsIntoEffect);
break;
case CLOCK_BGM_TIME_NO_OFFSET:
generic_global_timer_update(g_fCurrentBGMTimeNoOffset,
m_fEffectDelta, m_fSecsIntoEffect);
break;
default:
if(m_EffectClock >= CLOCK_LIGHT_1 && m_EffectClock <= CLOCK_LIGHT_LAST)
{
generic_global_timer_update(
g_fCabinetLights[m_EffectClock - CLOCK_LIGHT_1],
m_fEffectDelta, m_fSecsIntoEffect);
}
break;
}
// update effect
@@ -893,7 +890,7 @@ void Actor::UpdateInternal( float fDeltaTime )
default: break;
}
this->UpdateTweening( fDeltaTime );
this->UpdateTweening(delta_time);
}
RString Actor::GetLineage() const
@@ -1073,11 +1070,8 @@ void Actor::SetEffectPeriod( float fTime )
m_fEffectHoldAtHalf = 0;
m_fEffectRampDown = fTime/2;
m_fEffectHoldAtZero = 0;
}
float Actor::GetEffectPeriod() const
{
return m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown + m_fEffectHoldAtZero;
m_effect_period= m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown +
m_fEffectHoldAtZero;
}
void Actor::SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, float fAtZero )
@@ -1091,19 +1085,26 @@ void Actor::SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, floa
m_fEffectHoldAtHalf = fAtHalf;
m_fEffectRampDown = fRampDown;
m_fEffectHoldAtZero = fAtZero;
m_effect_period= m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown +
m_fEffectHoldAtZero;
}
// effect "macros"
void Actor::ResetEffectTimeIfDifferent(Effect new_effect)
{
if(m_Effect != new_effect)
{
m_Effect= new_effect;
m_fSecsIntoEffect = 0;
}
}
void Actor::SetEffectDiffuseBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 )
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != diffuse_blink )
{
m_Effect = diffuse_blink;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(diffuse_blink);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1113,11 +1114,7 @@ void Actor::SetEffectDiffuseShift( float fEffectPeriodSeconds, RageColor c1, Rag
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != diffuse_shift )
{
m_Effect = diffuse_shift;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(diffuse_shift);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1127,11 +1124,7 @@ void Actor::SetEffectDiffuseRamp( float fEffectPeriodSeconds, RageColor c1, Rage
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != diffuse_ramp )
{
m_Effect = diffuse_ramp;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(diffuse_ramp);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1141,11 +1134,7 @@ void Actor::SetEffectGlowBlink( float fEffectPeriodSeconds, RageColor c1, RageCo
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != glow_blink )
{
m_Effect = glow_blink;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(glow_blink);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1155,11 +1144,7 @@ void Actor::SetEffectGlowShift( float fEffectPeriodSeconds, RageColor c1, RageCo
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != glow_shift )
{
m_Effect = glow_shift;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(glow_shift);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1169,11 +1154,7 @@ void Actor::SetEffectGlowRamp( float fEffectPeriodSeconds, RageColor c1, RageCol
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != glow_ramp )
{
m_Effect = glow_ramp;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(glow_ramp);
SetEffectPeriod( fEffectPeriodSeconds );
m_effectColor1 = c1;
m_effectColor2 = c2;
@@ -1183,11 +1164,7 @@ void Actor::SetEffectRainbow( float fEffectPeriodSeconds )
{
ASSERT( fEffectPeriodSeconds > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != rainbow )
{
m_Effect = rainbow;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(rainbow);
SetEffectPeriod( fEffectPeriodSeconds );
}
@@ -1195,11 +1172,7 @@ void Actor::SetEffectWag( float fPeriod, RageVector3 vect )
{
ASSERT( fPeriod > 0 );
// todo: account for SSC_FUTURES -aj
if( m_Effect != wag )
{
m_Effect = wag;
m_fSecsIntoEffect = 0;
}
ResetEffectTimeIfDifferent(wag);
SetEffectPeriod( fPeriod );
m_vEffectMagnitude = vect;
}
+6 -1
View File
@@ -527,7 +527,7 @@ public:
void SetEffectColor1( RageColor c ) { m_effectColor1 = c; }
void SetEffectColor2( RageColor c ) { m_effectColor2 = c; }
void SetEffectPeriod( float fTime );
float GetEffectPeriod() const;
float GetEffectPeriod() const { return m_effect_period; }
void SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, float fAtZero );
void SetEffectOffset( float fTime ) { m_fEffectOffset = fTime; }
void SetEffectClock( EffectClock c ) { m_EffectClock = c; }
@@ -536,6 +536,7 @@ public:
void SetEffectMagnitude( RageVector3 vec ) { m_vEffectMagnitude = vec; }
RageVector3 GetEffectMagnitude() const { return m_vEffectMagnitude; }
void ResetEffectTimeIfDifferent(Effect new_effect);
void SetEffectDiffuseBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 );
void SetEffectDiffuseShift( float fEffectPeriodSeconds, RageColor c1, RageColor c2 );
void SetEffectDiffuseRamp( float fEffectPeriodSeconds, RageColor c1, RageColor c2 );
@@ -690,6 +691,10 @@ protected:
float m_fEffectRampDown;
float m_fEffectHoldAtZero;
float m_fEffectOffset;
// Anything changing ramp_up, hold_at_half, ramp_down, or hold_at_zero must
// also update the period so the period is only calculated when changed.
// -Kyz
float m_effect_period;
EffectClock m_EffectClock;
/* This can be used in lieu of the fDeltaTime parameter to Update() to
+145 -90
View File
@@ -60,11 +60,13 @@ static ThemeMetric<float> TINY_PERCENT_BASE( "ArrowEffects", "TinyPercentBase" )
static ThemeMetric<float> TINY_PERCENT_GATE( "ArrowEffects", "TinyPercentGate" );
static ThemeMetric<bool> DIZZY_HOLD_HEADS( "ArrowEffects", "DizzyHoldHeads" );
float ArrowGetPercentVisible( const PlayerState* pPlayerState, float fYPosWithoutReverse );
static const PlayerOptions* curr_options= NULL;
static float GetNoteFieldHeight( const PlayerState* pPlayerState )
float ArrowGetPercentVisible(float fYPosWithoutReverse);
static float GetNoteFieldHeight()
{
return SCREEN_HEIGHT + fabsf(pPlayerState->m_PlayerOptions.GetCurrent().m_fPerspectiveTilt)*200;
return SCREEN_HEIGHT + fabsf(curr_options->m_fPerspectiveTilt)*200;
}
namespace
@@ -74,6 +76,8 @@ namespace
float m_fMinTornadoX[MAX_COLS_PER_PLAYER];
float m_fMaxTornadoX[MAX_COLS_PER_PLAYER];
float m_fInvertDistance[MAX_COLS_PER_PLAYER];
float m_tipsy_result[MAX_COLS_PER_PLAYER];
float m_tipsy_offset_result[MAX_COLS_PER_PLAYER];
float m_fBeatFactor;
float m_fExpandSeconds;
};
@@ -92,6 +96,7 @@ void ArrowEffects::Update()
const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming
? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position;
const float field_zoom= GAMESTATE->m_pPlayerState[pn]->m_NotefieldZoom;
const float* effects= GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetCurrent().m_fEffects;
PerPlayerData &data = g_EffectData[pn];
@@ -176,6 +181,34 @@ void ArrowEffects::Update()
data.m_fInvertDistance[iColNum] = fNewPixelOffset - fOldPixelOffset;
}
// Update Tipsy
if(effects[PlayerOptions::EFFECT_TIPSY] != 0)
{
const float time= RageTimer::GetTimeSinceStartFast();
const float time_times_timer= time * TIPSY_TIMER_FREQUENCY;
const float arrow_times_mag= ARROW_SIZE * TIPSY_ARROW_MAGNITUDE;
const float time_times_offset_timer= time *
TIPSY_OFFSET_TIMER_FREQUENCY;
const float arrow_times_offset_mag= ARROW_SIZE *
TIPSY_OFFSET_ARROW_MAGNITUDE;
for(int col= 0; col < MAX_COLS_PER_PLAYER; ++col)
{
data.m_tipsy_result[col]= RageFastCos(
time_times_timer + (col * TIPSY_COLUMN_FREQUENCY)) *
arrow_times_mag;
data.m_tipsy_offset_result[col]= RageFastCos(
time_times_offset_timer + (col * TIPSY_OFFSET_COLUMN_FREQUENCY)) *
arrow_times_offset_mag;
}
}
else
{
for(int col= 0; col < MAX_COLS_PER_PLAYER; ++col)
{
data.m_tipsy_result[col]= 0;
}
}
// Update Beat
do {
float fAccelTime = 0.2f, fTotalTime = 0.5f;
@@ -212,6 +245,11 @@ void ArrowEffects::Update()
fLastTime = fTime;
}
void ArrowEffects::SetCurrentOptions(const PlayerOptions* options)
{
curr_options= options;
}
static float GetDisplayedBeat( const PlayerState* pPlayerState, float beat )
{
// do a binary search here
@@ -254,7 +292,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
/* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or
* entirely time spacing (respectively). Occasionally, we tween between them. */
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
if( curr_options->m_fTimeSpacing != 1.0f )
{
if( GAMESTATE->m_bInStepEditor ) {
// Use constant spacing in step editor
@@ -265,18 +303,18 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
position.m_fSongBeatVisible,
position.m_fMusicSecondsVisible );
}
fYOffset *= 1 - pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing;
fYOffset *= 1 - curr_options->m_fTimeSpacing;
}
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f )
if( curr_options->m_fTimeSpacing != 0.0f )
{
float fSongSeconds = GAMESTATE->m_Position.m_fMusicSecondsVisible;
float fNoteSeconds = pCurSteps->GetTimingData()->GetElapsedTimeFromBeat(fNoteBeat);
float fSecondsUntilStep = fNoteSeconds - fSongSeconds;
float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM;
float fBPM = curr_options->m_fScrollBPM;
float fBPS = fBPM/60.f / GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
float fYOffsetTimeSpacing = fSecondsUntilStep * fBPS;
fYOffset += fYOffsetTimeSpacing * pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing;
fYOffset += fYOffsetTimeSpacing * curr_options->m_fTimeSpacing;
}
// TODO: If we allow noteskins to have metricable row spacing
@@ -284,25 +322,27 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
fYOffset *= ARROW_SPACING;
// Factor in scroll speed
float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed;
if(pPlayerState->m_PlayerOptions.GetCurrent().m_fMaxScrollBPM != 0)
float fScrollSpeed = curr_options->m_fScrollSpeed;
if(curr_options->m_fMaxScrollBPM != 0)
{
fScrollSpeed= pPlayerState->m_PlayerOptions.GetCurrent().m_fMaxScrollBPM /
fScrollSpeed= curr_options->m_fMaxScrollBPM /
(pPlayerState->m_fReadBPM * GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate);
}
// don't mess with the arrows after they've crossed 0
if( fYOffset < 0 )
{
return fYOffset * fScrollSpeed;
}
const float* fAccels = pPlayerState->m_PlayerOptions.GetCurrent().m_fAccels;
//const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fAccels = curr_options->m_fAccels;
//const float* fEffects = curr_options->m_fEffects;
float fYAdjust = 0; // fill this in depending on PlayerOptions
if( fAccels[PlayerOptions::ACCEL_BOOST] != 0 )
{
float fEffectHeight = GetNoteFieldHeight(pPlayerState);
float fEffectHeight = GetNoteFieldHeight();
float fNewYOffset = fYOffset * 1.5f / ((fYOffset+fEffectHeight/1.2f)/fEffectHeight);
float fAccelYAdjust = fAccels[PlayerOptions::ACCEL_BOOST] * (fNewYOffset - fYOffset);
// TRICKY: Clamp this value, or else BOOST+BOOMERANG will draw a ton of arrows on the screen.
@@ -311,7 +351,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
}
if( fAccels[PlayerOptions::ACCEL_BRAKE] != 0 )
{
float fEffectHeight = GetNoteFieldHeight(pPlayerState);
float fEffectHeight = GetNoteFieldHeight();
float fScale = SCALE( fYOffset, 0.f, fEffectHeight, 0, 1.f );
float fNewYOffset = fYOffset * fScale;
float fBrakeYAdjust = fAccels[PlayerOptions::ACCEL_BRAKE] * (fNewYOffset - fYOffset);
@@ -334,7 +374,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
fYOffset = (-1*fYOffset*fYOffset/SCREEN_HEIGHT) + 1.5f*fYOffset;
}
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed > 0 && !bAbsolute )
if( curr_options->m_fRandomSpeed > 0 && !bAbsolute )
{
// Generate a deterministically "random" speed for each arrow.
unsigned seed = GAMESTATE->m_iStageSeed + ( BeatToNoteRow( fNoteBeat ) << 8 ) + (iCol * 100);
@@ -348,7 +388,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
fScrollSpeed *=
SCALE( fRandom,
0.0f, 1.0f,
1.0f, pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed + 1.0f );
1.0f, curr_options->m_fRandomSpeed + 1.0f );
}
if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 )
@@ -370,43 +410,43 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
return fYOffset;
}
static void ArrowGetReverseShiftAndScale( const PlayerState* pPlayerState, int iCol, float fYReverseOffsetPixels, float &fShiftOut, float &fScaleOut )
static void ArrowGetReverseShiftAndScale(int iCol, float fYReverseOffsetPixels, float &fShiftOut, float &fScaleOut)
{
// XXX: Hack: we need to scale the reverse shift by the zoom.
float fMiniPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_MINI];
float fMiniPercent = curr_options->m_fEffects[PlayerOptions::EFFECT_MINI];
float fZoom = 1 - fMiniPercent*0.5f;
// don't divide by 0
if( fabsf(fZoom) < 0.01 )
fZoom = 0.01f;
float fPercentReverse = pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(iCol);
float fPercentReverse = curr_options->GetReversePercentForColumn(iCol);
fShiftOut = SCALE( fPercentReverse, 0.f, 1.f, -fYReverseOffsetPixels/fZoom/2, fYReverseOffsetPixels/fZoom/2 );
float fPercentCentered = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrolls[PlayerOptions::SCROLL_CENTERED];
float fPercentCentered = curr_options->m_fScrolls[PlayerOptions::SCROLL_CENTERED];
fShiftOut = SCALE( fPercentCentered, 0.f, 1.f, fShiftOut, 0.0f );
fScaleOut = SCALE( fPercentReverse, 0.f, 1.f, 1.f, -1.f );
}
float ArrowEffects::GetYPos( const PlayerState* pPlayerState, int iCol, float fYOffset, float fYReverseOffsetPixels, bool WithReverse )
float ArrowEffects::GetYPos(int iCol, float fYOffset, float fYReverseOffsetPixels, bool WithReverse)
{
float f = fYOffset;
if( WithReverse )
{
float fShift, fScale;
ArrowGetReverseShiftAndScale( pPlayerState, iCol, fYReverseOffsetPixels, fShift, fScale );
ArrowGetReverseShiftAndScale(iCol, fYReverseOffsetPixels, fShift, fScale);
f *= fScale;
f += fShift;
}
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
if( fEffects[PlayerOptions::EFFECT_TIPSY] != 0 )
f += fEffects[PlayerOptions::EFFECT_TIPSY]
* ( RageFastCos( RageTimer::GetTimeSinceStartFast()*TIPSY_TIMER_FREQUENCY
+ iCol*TIPSY_COLUMN_FREQUENCY) * ARROW_SIZE*TIPSY_ARROW_MAGNITUDE );
const float* fEffects = curr_options->m_fEffects;
// Doing the math with a precalculated result of 0 should be faster than
// checking whether tipsy is on. -Kyz
// TODO: Don't index by PlayerNumber.
PerPlayerData& data= g_EffectData[curr_options->m_pn];
f+= fEffects[PlayerOptions::EFFECT_TIPSY] * data.m_tipsy_result[iCol];
// In beware's DDR Extreme-focused fork of StepMania 3.9, this value is
// floored, making arrows show on integer Y coordinates. Supposedly it makes
@@ -415,18 +455,19 @@ float ArrowEffects::GetYPos( const PlayerState* pPlayerState, int iCol, float fY
return QUANTIZE_ARROW_Y ? floor(f) : f;
}
float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels )
float ArrowEffects::GetYOffsetFromYPos(int iCol, float YPos, float fYReverseOffsetPixels)
{
float f = YPos;
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
if( fEffects[PlayerOptions::EFFECT_TIPSY] != 0 )
f -= fEffects[PlayerOptions::EFFECT_TIPSY]
* ( RageFastCos( RageTimer::GetTimeSinceStartFast()*TIPSY_OFFSET_TIMER_FREQUENCY
+ iCol*TIPSY_OFFSET_COLUMN_FREQUENCY) * ARROW_SIZE*TIPSY_OFFSET_ARROW_MAGNITUDE );
const float* fEffects = curr_options->m_fEffects;
// Doing the math with a precalculated result of 0 should be faster than
// checking whether tipsy is on. -Kyz
// TODO: Don't index by PlayerNumber.
PerPlayerData& data= g_EffectData[curr_options->m_pn];
f+= fEffects[PlayerOptions::EFFECT_TIPSY] * data.m_tipsy_offset_result[iCol];
float fShift, fScale;
ArrowGetReverseShiftAndScale( pPlayerState, iCol, fYReverseOffsetPixels, fShift, fScale );
ArrowGetReverseShiftAndScale(iCol, fYReverseOffsetPixels, fShift, fScale);
f -= fShift;
if( fScale )
@@ -440,7 +481,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
float fPixelOffsetFromCenter = 0; // fill this in below
const Style* pStyle = GAMESTATE->GetCurrentStyle(pPlayerState->m_PlayerNumber);
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
// TODO: Don't index by PlayerNumber.
const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pPlayerState->m_PlayerNumber];
@@ -528,9 +569,9 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
return fPixelOffsetFromCenter;
}
float ArrowEffects::GetRotationX( const PlayerState *pPlayerState, float fYOffset )
float ArrowEffects::GetRotationX(float fYOffset)
{
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
float fRotation = 0;
if( fEffects[PlayerOptions::EFFECT_ROLL] != 0 )
{
@@ -539,9 +580,9 @@ float ArrowEffects::GetRotationX( const PlayerState *pPlayerState, float fYOffse
return fRotation;
}
float ArrowEffects::GetRotationY( const PlayerState *pPlayerState, float fYOffset )
float ArrowEffects::GetRotationY(float fYOffset)
{
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
float fRotation = 0;
if( fEffects[PlayerOptions::EFFECT_TWIRL] != 0 )
{
@@ -552,7 +593,7 @@ float ArrowEffects::GetRotationY( const PlayerState *pPlayerState, float fYOffse
float ArrowEffects::GetRotationZ( const PlayerState* pPlayerState, float fNoteBeat, bool bIsHoldHead )
{
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
float fRotation = 0;
if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 )
fRotation += ReceptorGetRotationZ( pPlayerState );
@@ -572,7 +613,7 @@ float ArrowEffects::GetRotationZ( const PlayerState* pPlayerState, float fNoteBe
float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState )
{
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
float fRotation = 0;
if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 )
@@ -589,18 +630,18 @@ float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState )
#define CENTER_LINE_Y 160 // from fYOffset == 0
#define FADE_DIST_Y 40
static float GetCenterLine( const PlayerState* pPlayerState )
static float GetCenterLine()
{
/* Another mini hack: if EFFECT_MINI is on, then our center line is at
* eg. 320, not 160. */
const float fMiniPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_MINI];
const float fMiniPercent = curr_options->m_fEffects[PlayerOptions::EFFECT_MINI];
const float fZoom = 1 - fMiniPercent*0.5f;
return CENTER_LINE_Y / fZoom;
}
static float GetHiddenSudden( const PlayerState* pPlayerState )
static float GetHiddenSudden()
{
const float* fAppearances = pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances;
const float* fAppearances = curr_options->m_fAppearances;
return fAppearances[PlayerOptions::APPEARANCE_HIDDEN] *
fAppearances[PlayerOptions::APPEARANCE_SUDDEN];
}
@@ -617,55 +658,55 @@ static float GetHiddenSudden( const PlayerState* pPlayerState )
// ...invisible...
//
// TRICKY: We fudge hidden and sudden to be farther apart if they're both on.
static float GetHiddenEndLine( const PlayerState* pPlayerState )
static float GetHiddenEndLine()
{
return GetCenterLine( pPlayerState ) +
FADE_DIST_Y * SCALE( GetHiddenSudden(pPlayerState), 0.f, 1.f, -1.0f, -1.25f ) +
GetCenterLine( pPlayerState ) * pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET];
return GetCenterLine() +
FADE_DIST_Y * SCALE( GetHiddenSudden(), 0.f, 1.f, -1.0f, -1.25f ) +
GetCenterLine() * curr_options->m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET];
}
static float GetHiddenStartLine( const PlayerState* pPlayerState )
static float GetHiddenStartLine()
{
return GetCenterLine( pPlayerState ) +
FADE_DIST_Y * SCALE( GetHiddenSudden(pPlayerState), 0.f, 1.f, +0.0f, -0.25f ) +
GetCenterLine( pPlayerState ) * pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET];
return GetCenterLine() +
FADE_DIST_Y * SCALE( GetHiddenSudden(), 0.f, 1.f, +0.0f, -0.25f ) +
GetCenterLine() * curr_options->m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET];
}
static float GetSuddenEndLine( const PlayerState* pPlayerState )
static float GetSuddenEndLine()
{
return GetCenterLine( pPlayerState ) +
FADE_DIST_Y * SCALE( GetHiddenSudden(pPlayerState), 0.f, 1.f, -0.0f, +0.25f ) +
GetCenterLine( pPlayerState ) * pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET];
return GetCenterLine() +
FADE_DIST_Y * SCALE( GetHiddenSudden(), 0.f, 1.f, -0.0f, +0.25f ) +
GetCenterLine() * curr_options->m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET];
}
static float GetSuddenStartLine( const PlayerState* pPlayerState )
static float GetSuddenStartLine()
{
return GetCenterLine( pPlayerState ) +
FADE_DIST_Y * SCALE( GetHiddenSudden(pPlayerState), 0.f, 1.f, +1.0f, +1.25f ) +
GetCenterLine( pPlayerState ) * pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET];
return GetCenterLine() +
FADE_DIST_Y * SCALE( GetHiddenSudden(), 0.f, 1.f, +1.0f, +1.25f ) +
GetCenterLine() * curr_options->m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET];
}
// used by ArrowGetAlpha and ArrowGetGlow below
float ArrowGetPercentVisible( const PlayerState* pPlayerState, float fYPosWithoutReverse )
float ArrowGetPercentVisible(float fYPosWithoutReverse)
{
const float fDistFromCenterLine = fYPosWithoutReverse - GetCenterLine( pPlayerState );
const float fDistFromCenterLine = fYPosWithoutReverse - GetCenterLine();
if( fYPosWithoutReverse < 0 && HIDDEN_SUDDEN_PAST_RECEPTOR) // past Gray Arrows
return 1; // totally visible
const float* fAppearances = pPlayerState->m_PlayerOptions.GetCurrent().m_fAppearances;
const float* fAppearances = curr_options->m_fAppearances;
float fVisibleAdjust = 0;
if( fAppearances[PlayerOptions::APPEARANCE_HIDDEN] != 0 )
{
float fHiddenVisibleAdjust = SCALE( fYPosWithoutReverse, GetHiddenStartLine(pPlayerState), GetHiddenEndLine(pPlayerState), 0, -1 );
float fHiddenVisibleAdjust = SCALE( fYPosWithoutReverse, GetHiddenStartLine(), GetHiddenEndLine(), 0, -1 );
CLAMP( fHiddenVisibleAdjust, -1, 0 );
fVisibleAdjust += fAppearances[PlayerOptions::APPEARANCE_HIDDEN] * fHiddenVisibleAdjust;
}
if( fAppearances[PlayerOptions::APPEARANCE_SUDDEN] != 0 )
{
float fSuddenVisibleAdjust = SCALE( fYPosWithoutReverse, GetSuddenStartLine(pPlayerState), GetSuddenEndLine(pPlayerState), -1, 0 );
float fSuddenVisibleAdjust = SCALE( fYPosWithoutReverse, GetSuddenStartLine(), GetSuddenEndLine(), -1, 0 );
CLAMP( fSuddenVisibleAdjust, -1, 0 );
fVisibleAdjust += fAppearances[PlayerOptions::APPEARANCE_SUDDEN] * fSuddenVisibleAdjust;
}
@@ -688,12 +729,12 @@ float ArrowGetPercentVisible( const PlayerState* pPlayerState, float fYPosWithou
return clamp( 1+fVisibleAdjust, 0, 1 );
}
float ArrowEffects::GetAlpha( const PlayerState* pPlayerState, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar )
float ArrowEffects::GetAlpha(int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar)
{
// Get the YPos without reverse (that is, factor in EFFECT_TIPSY).
float fYPosWithoutReverse = ArrowEffects::GetYPos( pPlayerState, iCol, fYOffset, fYReverseOffsetPixels, false );
float fYPosWithoutReverse = ArrowEffects::GetYPos(iCol, fYOffset, fYReverseOffsetPixels, false );
float fPercentVisible = ArrowGetPercentVisible( pPlayerState, fYPosWithoutReverse );
float fPercentVisible = ArrowGetPercentVisible(fYPosWithoutReverse);
if( fPercentFadeToFail != -1 )
fPercentVisible = 1 - fPercentFadeToFail;
@@ -705,17 +746,15 @@ float ArrowEffects::GetAlpha( const PlayerState* pPlayerState, int iCol, float f
float f = SCALE( fYPosWithoutReverse, fFullAlphaY, fDrawDistanceBeforeTargetsPixels, 1.0f, 0.0f );
return f;
}
return (fPercentVisible>0.5f) ? 1.0f : 0.0f;
}
float ArrowEffects::GetGlow( const PlayerState* pPlayerState, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar )
float ArrowEffects::GetGlow(int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar)
{
// Get the YPos without reverse (that is, factor in EFFECT_TIPSY).
float fYPosWithoutReverse = ArrowEffects::GetYPos( pPlayerState, iCol, fYOffset, fYReverseOffsetPixels, false );
float fYPosWithoutReverse = ArrowEffects::GetYPos(iCol, fYOffset, fYReverseOffsetPixels, false );
float fPercentVisible = ArrowGetPercentVisible( pPlayerState, fYPosWithoutReverse );
float fPercentVisible = ArrowGetPercentVisible(fYPosWithoutReverse );
if( fPercentFadeToFail != -1 )
fPercentVisible = 1 - fPercentFadeToFail;
@@ -738,10 +777,10 @@ float ArrowEffects::GetBrightness( const PlayerState* pPlayerState, float fNoteB
}
float ArrowEffects::GetZPos( const PlayerState* pPlayerState, int iCol, float fYOffset )
float ArrowEffects::GetZPos(int iCol, float fYOffset)
{
float fZPos=0;
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
if( fEffects[PlayerOptions::EFFECT_BUMPY] != 0 )
fZPos += fEffects[PlayerOptions::EFFECT_BUMPY] * 40*RageFastSin( fYOffset/16.0f );
@@ -749,15 +788,16 @@ float ArrowEffects::GetZPos( const PlayerState* pPlayerState, int iCol, float fY
return fZPos;
}
bool ArrowEffects::NeedZBuffer( const PlayerState* pPlayerState )
bool ArrowEffects::NeedZBuffer()
{
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
const float* fEffects = curr_options->m_fEffects;
// We also need to use the Z buffer if twirl is in play, because of
// hold modulation. -vyhd (OpenITG r623)
if( fEffects[PlayerOptions::EFFECT_BUMPY] != 0 ||
fEffects[PlayerOptions::EFFECT_TWIRL] != 0 )
{
return true;
}
return false;
}
@@ -770,7 +810,7 @@ float ArrowEffects::GetZoom( const PlayerState* pPlayerState )
// PlayerState. -Kyz
fZoom*= pPlayerState->m_NotefieldZoom;
float fTinyPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY];
float fTinyPercent = curr_options->m_fEffects[PlayerOptions::EFFECT_TINY];
if( fTinyPercent != 0 )
{
fTinyPercent = powf( 0.5f, fTinyPercent );
@@ -840,6 +880,7 @@ namespace
int GetYOffset( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
float fPeakYOffset;
bool bIsPastPeak;
@@ -854,7 +895,8 @@ namespace
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
float fYReverseOffsetPixels = YReverseOffset( L, 4 );
lua_pushnumber( L, ArrowEffects::GetYPos( ps, IArg(2)-1, FArg(3), fYReverseOffsetPixels ) );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber(L, ArrowEffects::GetYPos(IArg(2)-1, FArg(3), fYReverseOffsetPixels));
return 1;
}
@@ -862,8 +904,9 @@ namespace
int GetYOffsetFromYPos( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
float fYReverseOffsetPixels = YReverseOffset( L, 4 );
lua_pushnumber( L, ArrowEffects::GetYOffsetFromYPos( ps, IArg(2)-1, FArg(3), fYReverseOffsetPixels ) );
lua_pushnumber(L, ArrowEffects::GetYOffsetFromYPos(IArg(2)-1, FArg(3), fYReverseOffsetPixels));
return 1;
}
@@ -871,6 +914,7 @@ namespace
int GetXPos( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber( L, ArrowEffects::GetXPos( ps, IArg(2)-1, FArg(3) ) );
return 1;
}
@@ -879,7 +923,8 @@ namespace
int GetZPos( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
lua_pushnumber( L, ArrowEffects::GetZPos( ps, IArg(2)-1, FArg(3) ) );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber(L, ArrowEffects::GetZPos(IArg(2)-1, FArg(3)));
return 1;
}
@@ -887,7 +932,8 @@ namespace
int GetRotationX( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
lua_pushnumber( L, ArrowEffects::GetRotationX( ps, FArg(2) ) );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber(L, ArrowEffects::GetRotationX(FArg(2)));
return 1;
}
@@ -895,7 +941,8 @@ namespace
int GetRotationY( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
lua_pushnumber( L, ArrowEffects::GetRotationY( ps, FArg(2) ) );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber(L, ArrowEffects::GetRotationY(FArg(2)));
return 1;
}
@@ -903,6 +950,7 @@ namespace
int GetRotationZ( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
// Make bIsHoldHead optional.
bool bIsHoldHead = false;
if( lua_gettop(L) >= 3 && !lua_isnil(L, 3) )
@@ -917,6 +965,7 @@ namespace
int ReceptorGetRotationZ( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber( L, ArrowEffects::ReceptorGetRotationZ( ps ) );
return 1;
}
@@ -925,6 +974,7 @@ namespace
int GetAlpha( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
// Provide reasonable default values.
float fPercentFadeToFail = -1;
float fYReverseOffsetPixels = YReverseOffset( L, 5 );
@@ -942,7 +992,7 @@ namespace
{
fFadeInPercentOfDrawFar = FArg(7);
}
lua_pushnumber( L, ArrowEffects::GetAlpha( ps, IArg(2)-1, FArg(3), fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ) );
lua_pushnumber(L, ArrowEffects::GetAlpha(IArg(2)-1, FArg(3), fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar));
return 1;
}
@@ -951,6 +1001,7 @@ namespace
int GetGlow( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
// Provide reasonable default values.
float fPercentFadeToFail = -1; //
float fYReverseOffsetPixels = YReverseOffset( L, 5 );
@@ -968,7 +1019,7 @@ namespace
{
fFadeInPercentOfDrawFar = FArg(7);
}
lua_pushnumber( L, ArrowEffects::GetGlow( ps, IArg(2)-1, FArg(3), fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ) );
lua_pushnumber( L, ArrowEffects::GetGlow(IArg(2)-1, FArg(3), fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ) );
return 1;
}
@@ -976,6 +1027,7 @@ namespace
int GetBrightness( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber( L, ArrowEffects::GetBrightness( ps, FArg(2) ) );
return 1;
}
@@ -984,7 +1036,8 @@ namespace
int NeedZBuffer( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
lua_pushboolean( L, ArrowEffects::NeedZBuffer( ps ) );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushboolean(L, ArrowEffects::NeedZBuffer());
return 1;
}
@@ -992,6 +1045,7 @@ namespace
int GetZoom( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
lua_pushnumber( L, ArrowEffects::GetZoom( ps ) );
return 1;
}
@@ -1000,6 +1054,7 @@ namespace
int GetFrameWidthScale( lua_State *L )
{
PlayerState *ps = Luna<PlayerState>::check( L, 1 );
ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent());
// Make fOverlappedTime optional.
float fOverlappedTime = 0;
+20 -13
View File
@@ -1,12 +1,20 @@
#ifndef ARROWEFFECTS_H
#define ARROWEFFECTS_H
#include "RageTypes.h"
class PlayerState;
class PlayerOptions;
/** @brief Functions that return properties of arrows based on Style and PlayerOptions. */
class ArrowEffects
{
public:
static void Update();
// SetCurrentOptions and the hidden static variable it set exists so that
// ArrowEffects doesn't have to reach through the PlayerState to check
// every option. Also, it will make it easier to implement per-column
// mods later. -Kyz
static void SetCurrentOptions(const PlayerOptions* options);
// fYOffset is a vertical position in pixels relative to the center
// (positive if has not yet been stepped on, negative if has already passed).
@@ -19,12 +27,11 @@ public:
return GetYOffset( pPlayerState, iCol, fNoteBeat, fThrowAway, bThrowAway, bAbsolute );
}
static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, vector<float>& ret, bool with_reverse= true)
static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, RageVector3& ret, bool with_reverse= true)
{
ASSERT(ret.size() == 3);
ret[0]= GetXPos(player_state, col, y_offset);
ret[1]= GetYPos(player_state, col, y_offset, y_reverse_offset, with_reverse);
ret[2]= GetZPos(player_state, col, y_offset);
ret.x= GetXPos(player_state, col, y_offset);
ret.y= GetYPos(col, y_offset, y_reverse_offset, with_reverse);
ret.z= GetZPos(col, y_offset);
}
/**
@@ -37,10 +44,10 @@ public:
* @param fYReverseOffsetPixels the amount offset due to reverse.
* @param WithReverse a flag to see if the Reverse mod is on.
* @return the actual display position. */
static float GetYPos( const PlayerState* pPlayerState, int iCol, float fYOffset, float fYReverseOffsetPixels, bool WithReverse = true );
static float GetYPos(int iCol, float fYOffset, float fYReverseOffsetPixels, bool WithReverse = true );
// Inverse of ArrowGetYPos (YPos -> fYOffset).
static float GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels );
static float GetYOffsetFromYPos(int iCol, float YPos, float fYReverseOffsetPixels);
// fRotation is Z rotation of an arrow. This will depend on the column of
// the arrow and possibly the Arrow effect and the fYOffset (in the case of
@@ -50,8 +57,8 @@ public:
// Due to the handling logic for holds on Twirl, we need to use an offset instead.
// It's more intuitive for Roll to be based off offset, so use an offset there too.
static float GetRotationX( const PlayerState* pPlayerState, float fYOffset );
static float GetRotationY( const PlayerState* pPlayerState, float fYOffset );
static float GetRotationX(float fYOffset);
static float GetRotationY(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
@@ -66,18 +73,18 @@ public:
* @param iCol the specific arrow column.
* @param fYPos the Y position of the arrow.
* @return the Z position. */
static float GetZPos( const PlayerState* pPlayerState, int iCol, float fYPos );
static float GetZPos(int iCol, float fYPos);
// Enable this if any ZPos effects are enabled.
static bool NeedZBuffer( const PlayerState* pPlayerState );
static bool NeedZBuffer();
// fAlpha is the transparency of the arrow. It depends on fYPos and the
// AppearanceType.
static float GetAlpha( const PlayerState* pPlayerState, int iCol, float fYPos, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar );
static float GetAlpha(int iCol, float fYPos, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar);
// fAlpha is the transparency of the arrow. It depends on fYPos and the
// AppearanceType.
static float GetGlow( const PlayerState* pPlayerState, int iCol, float fYPos, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar );
static float GetGlow(int iCol, float fYPos, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar );
/**
* @brief Retrieve the current brightness.
+14
View File
@@ -666,6 +666,20 @@ CSN_EVAL_SOMETHING(evaluate_third_derivative);
#undef CSN_EVAL_SOMETHING
#define CSN_EVAL_RV_SOMETHING(something) \
void CubicSplineN::something(float t, RageVector3& v) const \
{ \
ASSERT(m_splines.size() == 3); \
v.x= m_splines[0].something(t, m_loop); \
v.y= m_splines[1].something(t, m_loop); \
v.z= m_splines[2].something(t, m_loop); \
}
CSN_EVAL_RV_SOMETHING(evaluate);
CSN_EVAL_RV_SOMETHING(evaluate_derivative);
#undef CSN_EVAL_RV_SOMETHING
void CubicSplineN::set_point(size_t i, const vector<float>& v)
{
ASSERT_M(v.size() == m_splines.size(), "CubicSplineN::set_point requires the passed point to be the same dimension as the spline.");
+3
View File
@@ -3,6 +3,7 @@
#include <vector>
using std::vector;
#include "RageTypes.h"
struct lua_State;
struct CubicSpline
@@ -49,6 +50,8 @@ struct CubicSplineN
void evaluate_derivative(float t, vector<float>& v) const;
void evaluate_second_derivative(float t, vector<float>& v) const;
void evaluate_third_derivative(float t, vector<float>& v) const;
void evaluate(float t, RageVector3& v) const;
void evaluate_derivative(float t, RageVector3& v) const;
void set_point(size_t i, const vector<float>& v);
void set_coefficients(size_t i, const vector<float>& b,
const vector<float>& c, const vector<float>& d);
+11 -5
View File
@@ -49,6 +49,7 @@ void Model::Clear()
m_Materials.clear();
m_mapNameToAnimation.clear();
m_pCurAnimation = NULL;
RecalcAnimationLengthSeconds();
if( m_pTempGeometry )
DISPLAY->DeleteCompiledGeometry( m_pTempGeometry );
@@ -62,6 +63,7 @@ void Model::Load( const RString &sFile )
sExt.MakeLower();
if( sExt=="txt" )
LoadMilkshapeAscii( sFile );
RecalcAnimationLengthSeconds();
}
#define THROW RageException::Throw( "Parse error in \"%s\" at line %d: \"%s\".", sPath.c_str(), iLineNum, sLine.c_str() )
@@ -102,6 +104,7 @@ void Model::LoadPieces( const RString &sMeshesPath, const RString &sMaterialsPat
m_pTempGeometry = DISPLAY->CreateCompiledGeometry();
m_pTempGeometry->Set( m_vTempMeshes, this->MaterialsNeedNormals() );
}
RecalcAnimationLengthSeconds();
}
void Model::LoadFromNode( const XNode* pNode )
@@ -117,6 +120,7 @@ void Model::LoadFromNode( const XNode* pNode )
}
Actor::LoadFromNode( pNode );
RecalcAnimationLengthSeconds();
}
@@ -741,12 +745,14 @@ void Model::SetState( int iNewState )
}
}
float Model::GetAnimationLengthSeconds() const
void Model::RecalcAnimationLengthSeconds()
{
float fSeconds = 0;
FOREACH_CONST( msMaterial, m_Materials, m )
fSeconds = max( fSeconds, m->diffuse.GetAnimationLengthSeconds() );
return fSeconds;
m_animation_length_seconds= 0;
FOREACH_CONST(msMaterial, m_Materials, m)
{
m_animation_length_seconds= max(m_animation_length_seconds,
m->diffuse.GetAnimationLengthSeconds());
}
}
void Model::SetSecondsIntoAnimation( float fSeconds )
+4 -1
View File
@@ -43,7 +43,9 @@ public:
virtual int GetNumStates() const;
virtual void SetState( int iNewState );
virtual float GetAnimationLengthSeconds() const;
virtual float GetAnimationLengthSeconds() const
{ return m_animation_length_seconds; }
virtual void RecalcAnimationLengthSeconds();
virtual void SetSecondsIntoAnimation( float fSeconds );
RString GetDefaultAnimation() const { return m_sDefaultAnimation; };
@@ -57,6 +59,7 @@ public:
private:
RageModelGeometry *m_pGeometry;
float m_animation_length_seconds;
vector<msMaterial> m_Materials;
map<RString,msAnimation> m_mapNameToAnimation;
const msAnimation* m_pCurAnimation;
+198 -203
View File
@@ -303,19 +303,19 @@ float NCSplineHandler::BeatToTValue(float song_beat, float note_beat) const
return relative_beat / m_beats_per_t;
}
void NCSplineHandler::EvalForBeat(float song_beat, float note_beat, vector<float>& ret) const
void NCSplineHandler::EvalForBeat(float song_beat, float note_beat, RageVector3& ret) const
{
float t_value= BeatToTValue(song_beat, note_beat);
m_spline.evaluate(t_value, ret);
}
void NCSplineHandler::EvalDerivForBeat(float song_beat, float note_beat, vector<float>& ret) const
void NCSplineHandler::EvalDerivForBeat(float song_beat, float note_beat, RageVector3& ret) const
{
float t_value= BeatToTValue(song_beat, note_beat);
m_spline.evaluate_derivative(t_value, ret);
}
void NCSplineHandler::EvalForReceptor(float song_beat, vector<float>& ret) const
void NCSplineHandler::EvalForReceptor(float song_beat, RageVector3& ret) const
{
float t_value= m_receptor_t;
if(!m_subtract_song_beat_from_curr)
@@ -344,22 +344,17 @@ void NCSplineHandler::MakeWeightedAverage(NCSplineHandler& out,
between);
}
void NoteColumnRenderArgs::spae_pos_for_beat(const PlayerState* state,
void NoteColumnRenderArgs::spae_pos_for_beat(const PlayerState* player_state,
float beat, float y_offset, float y_reverse_offset,
vector<float>& sp_pos, vector<float>& ae_pos) const
RageVector3& sp_pos, RageVector3& ae_pos) const
{
switch(pos_handler->m_spline_mode)
{
case NCSM_Disabled:
ArrowEffects::GetXYZPos(state, column, y_offset, y_reverse_offset, ae_pos);
sp_pos.resize(3);
// Sure, resize is supposed to call the default constructor, and for
// numbers the default constructor is supposed to set it to zero, but
// I got bit for relying on that once. -Kyz
sp_pos[0]= sp_pos[1]= sp_pos[2]= 0.0f;
ArrowEffects::GetXYZPos(player_state, column, y_offset, y_reverse_offset, ae_pos);
break;
case NCSM_Offset:
ArrowEffects::GetXYZPos(state, column, y_offset, y_reverse_offset, ae_pos);
ArrowEffects::GetXYZPos(player_state, column, y_offset, y_reverse_offset, ae_pos);
pos_handler->EvalForBeat(song_beat, beat, sp_pos);
break;
case NCSM_Position:
@@ -368,17 +363,15 @@ void NoteColumnRenderArgs::spae_pos_for_beat(const PlayerState* state,
}
}
void NoteColumnRenderArgs::spae_zoom_for_beat(const PlayerState* state, float beat,
vector<float>& sp_zoom, vector<float>& ae_zoom) const
RageVector3& sp_zoom, RageVector3& ae_zoom) const
{
switch(zoom_handler->m_spline_mode)
{
case NCSM_Disabled:
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(state);
sp_zoom.resize(3);
sp_zoom[0]= sp_zoom[1]= sp_zoom[2]= 0.0f;
ae_zoom.x= ae_zoom.y= ae_zoom.z= ArrowEffects::GetZoom(state);
break;
case NCSM_Offset:
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(state);
ae_zoom.x= ae_zoom.y= ae_zoom.z= ArrowEffects::GetZoom(state);
zoom_handler->EvalForBeat(song_beat, beat, sp_zoom);
break;
case NCSM_Position:
@@ -387,19 +380,19 @@ void NoteColumnRenderArgs::spae_zoom_for_beat(const PlayerState* state, float be
}
}
void NoteColumnRenderArgs::SetPRZForActor(Actor* actor,
const vector<float>& sp_pos, const vector<float>& ae_pos,
const vector<float>& sp_rot, const vector<float>& ae_rot,
const vector<float>& sp_zoom, const vector<float>& ae_zoom) const
const RageVector3& sp_pos, const RageVector3& ae_pos,
const RageVector3& sp_rot, const RageVector3& ae_rot,
const RageVector3& sp_zoom, const RageVector3& ae_zoom) const
{
actor->SetX(sp_pos[0] + ae_pos[0]);
actor->SetY(sp_pos[1] + ae_pos[1]);
actor->SetZ(sp_pos[2] + ae_pos[2]);
actor->SetRotationX(sp_rot[0] * PI_180R + ae_rot[0]);
actor->SetRotationY(sp_rot[1] * PI_180R + ae_rot[1]);
actor->SetRotationZ(sp_rot[2] * PI_180R + ae_rot[2]);
actor->SetZoomX(sp_zoom[0] + ae_zoom[0]);
actor->SetZoomY(sp_zoom[1] + ae_zoom[1]);
actor->SetZoomZ(sp_zoom[2] + ae_zoom[2]);
actor->SetX(sp_pos.x + ae_pos.x);
actor->SetY(sp_pos.y + ae_pos.y);
actor->SetZ(sp_pos.z + ae_pos.z);
actor->SetRotationX(sp_rot.x * PI_180R + ae_rot.x);
actor->SetRotationY(sp_rot.y * PI_180R + ae_rot.y);
actor->SetRotationZ(sp_rot.z * PI_180R + ae_rot.z);
actor->SetZoomX(sp_zoom.x + ae_zoom.x);
actor->SetZoomY(sp_zoom.y + ae_zoom.y);
actor->SetZoomZ(sp_zoom.z + ae_zoom.z);
}
@@ -704,9 +697,9 @@ Sprite *NoteDisplay::GetHoldSprite( NoteColorSprite ncs[NUM_HoldType][NUM_Active
static float ArrowGetAlphaOrGlow( bool bGlow, const PlayerState* pPlayerState, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar )
{
if( bGlow )
return ArrowEffects::GetGlow( pPlayerState, iCol, fYOffset, fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
return ArrowEffects::GetGlow(iCol, fYOffset, fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar);
else
return ArrowEffects::GetAlpha( pPlayerState, iCol, fYOffset, fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
return ArrowEffects::GetAlpha(iCol, fYOffset, fPercentFadeToFail, fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar);
}
struct StripBuffer
@@ -738,53 +731,49 @@ struct StripBuffer
void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, int fYStep,
float fPercentFadeToFail, float fColorScale, bool bGlow,
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
float fYEndPos, bool bWrapping, bool bAnchorToTop,
bool bFlipTextureVertically, float top_beat, float bottom_beat)
const NoteColumnRenderArgs& column_args,
const draw_hold_part_args& part_args, bool glow)
{
ASSERT( !vpSpr.empty() );
ASSERT(!vpSpr.empty());
float ae_zoom= ArrowEffects::GetZoom(m_pPlayerState);
Sprite *pSprite = vpSpr.front();
// draw manually in small segments
RectF rect = *pSprite->GetCurrentTextureCoordRect();
if( bFlipTextureVertically )
swap( rect.top, rect.bottom );
if(part_args.flip_texture_vertically)
swap(rect.top, rect.bottom);
const float fFrameWidth = pSprite->GetUnzoomedWidth();
const float fFrameHeight = pSprite->GetUnzoomedHeight() * ae_zoom;
/* Only draw the section that's within the range specified. If a hold note is
* very long, don't process or draw the part outside of the range. Don't change
* fYTop or fYBottom; they need to be left alone to calculate texture coordinates. */
fYStartPos = max( fYTop, fYStartPos );
fYEndPos = min( fYBottom, fYEndPos );
if( bGlow )
fColorScale = 1;
* part_args.y_top or part_args.y_bottom; they need to be left alone to calculate texture coordinates. */
const float y_start_pos = max(part_args.y_top, part_args.y_start_pos);
const float y_end_pos = min(part_args.y_bottom, part_args.y_end_pos);
const float color_scale= glow ? 1 : part_args.color_scale;
// top to bottom
bool bAllAreTransparent = true;
bool bLast = false;
float fAddToTexCoord = 0;
if( !bAnchorToTop )
if(!part_args.anchor_to_top)
{
float fTexCoordBottom = SCALE( fYBottom - fYTop, 0, fFrameHeight, rect.top, rect.bottom );
float fWantTexCoordBottom = ceilf( fTexCoordBottom - 0.0001f );
fAddToTexCoord = fWantTexCoordBottom - fTexCoordBottom;
float tex_coord_bottom= SCALE(part_args.y_bottom - part_args.y_top,
0, fFrameHeight, rect.top, rect.bottom);
float want_tex_coord_bottom = ceilf(tex_coord_bottom - 0.0001f);
fAddToTexCoord = want_tex_coord_bottom - tex_coord_bottom;
}
if( bWrapping )
if(part_args.wrapping)
{
/* For very large hold notes, shift the texture coordinates to be near 0, so we
* don't send very large values to the renderer. */
const float fDistFromTop = fYStartPos - fYTop;
float fTexCoordTop = SCALE( fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom );
const float fDistFromTop = y_start_pos - part_args.y_top;
float fTexCoordTop = SCALE(fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom);
fTexCoordTop += fAddToTexCoord;
fAddToTexCoord -= floorf( fTexCoordTop );
fAddToTexCoord -= floorf(fTexCoordTop);
}
DISPLAY->ClearAllTextures();
@@ -798,20 +787,20 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
static const RageVector3 pos_y_vec(0.0f, 1.0f, 0.0f);
StripBuffer queue;
for( float fY = fYStartPos; !bLast; fY += fYStep )
for(float fY = y_start_pos; !bLast; fY += part_args.y_step)
{
if( fY >= fYEndPos )
if(fY >= y_end_pos)
{
fY = fYEndPos;
fY = y_end_pos;
bLast = true;
}
const float fYOffset = ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, column_args.column, fY, m_fYReverseOffsetPixels );
const float fYOffset= ArrowEffects::GetYOffsetFromYPos(column_args.column, fY, m_fYReverseOffsetPixels);
float cur_beat= top_beat;
if(top_beat != bottom_beat)
float cur_beat= part_args.top_beat;
if(part_args.top_beat != part_args.bottom_beat)
{
cur_beat= SCALE(fY, fYTop, fYBottom, top_beat, bottom_beat);
cur_beat= SCALE(fY, part_args.y_top, part_args.y_bottom, part_args.top_beat, part_args.bottom_beat);
}
// Fun times ahead with vector math. If the notes are being moved by the
@@ -834,12 +823,12 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
// TODO: Figure out whether it's worth the time investment to figure out
// a way to skip the complex vector handling if the spline is disabled.
vector<float> sp_pos;
vector<float> sp_pos_forward;
vector<float> sp_rot;
vector<float> sp_zoom;
vector<float> ae_pos(3, 0.0f);
vector<float> ae_rot(3, 0.0f);
RageVector3 sp_pos;
RageVector3 sp_pos_forward;
RageVector3 sp_rot;
RageVector3 sp_zoom;
RageVector3 ae_pos;
RageVector3 ae_rot;
// (step 1 of vector handling, part 1)
// ArrowEffects only contributes to the Y component of the vector to
@@ -848,32 +837,30 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
RageVector3 render_forward(0.0f, 1.0f, 0.0f);
column_args.spae_pos_for_beat(m_pPlayerState, cur_beat,
fYOffset, m_fYReverseOffsetPixels, sp_pos, ae_pos);
// fX and fZ are sp_pos[0] + ae_pos[0] and sp_pos[2] + ae_pos[2]. -Kyz
// fX and fZ are sp_pos.x + ae_pos.x and sp_pos.z + ae_pos.z. -Kyz
// fY is the actual y position that should be used, not whatever spae
// fetched from ArrowEffects. -Kyz
switch(column_args.pos_handler->m_spline_mode)
{
case NCSM_Disabled:
ae_pos[1]= fY;
sp_pos_forward.resize(3);
sp_pos_forward[0]= sp_pos_forward[1]= sp_pos_forward[2]= 0.0f;
ae_pos.y= fY;
break;
case NCSM_Offset:
ae_pos[1]= fY;
ae_pos.y= fY;
column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward);
VectorFloatNormalize(sp_pos_forward);
RageVec3Normalize(&sp_pos_forward, &sp_pos_forward);
break;
case NCSM_Position:
ae_pos[1]= 0.0f;
ae_pos.y= 0.0f;
render_forward.y= 0.0f;
column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward);
VectorFloatNormalize(sp_pos_forward);
RageVec3Normalize(&sp_pos_forward, &sp_pos_forward);
break;
}
render_forward.x+= sp_pos_forward[0];
render_forward.y+= sp_pos_forward[1];
render_forward.z+= sp_pos_forward[2];
render_forward.x+= sp_pos_forward.x;
render_forward.y+= sp_pos_forward.y;
render_forward.z+= sp_pos_forward.z;
// Normalize the vector so it'll be easy to test when determining whether
// to use pos_z_vec or pos_y_vec for the cross product in step 2.
RageVec3Normalize(&render_forward, &render_forward);
@@ -888,15 +875,15 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
break;
case NCSM_Offset:
column_args.zoom_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_zoom);
render_width= fFrameWidth * (ae_zoom + sp_zoom[0]);
render_width= fFrameWidth * (ae_zoom + sp_zoom.x);
break;
case NCSM_Position:
column_args.zoom_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_zoom);
render_width= fFrameWidth * sp_zoom[0];
render_width= fFrameWidth * sp_zoom.x;
break;
}
const float fFrameWidthScale = ArrowEffects::GetFrameWidthScale( m_pPlayerState, fYOffset, fOverlappedTime );
const float fFrameWidthScale = ArrowEffects::GetFrameWidthScale(m_pPlayerState, fYOffset, part_args.overlapped_time);
const float fScaledFrameWidth = render_width * fFrameWidthScale;
// Can't use the same code as for taps because hold bodies can only rotate
@@ -905,12 +892,10 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
{
case NCSM_Disabled:
// XXX: Actor rotations use degrees, Math uses radians. Convert here.
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180;
sp_rot.resize(3);
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
ae_rot.y= ArrowEffects::GetRotationY(fYOffset) * PI_180;
break;
case NCSM_Offset:
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180;
ae_rot.y= ArrowEffects::GetRotationY(fYOffset) * PI_180;
column_args.rot_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_rot);
break;
case NCSM_Position:
@@ -918,18 +903,18 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
break;
}
RageVector3 center_vert(sp_pos[0] + ae_pos[0],
sp_pos[1] + ae_pos[1], sp_pos[2] + ae_pos[2]);
RageVector3 center_vert(sp_pos.x + ae_pos.x,
sp_pos.y + ae_pos.y, sp_pos.z + ae_pos.z);
// Special case for hold caps, which have the same top and bottom beat.
if(top_beat == bottom_beat && fY != fYStartPos)
if(part_args.top_beat == part_args.bottom_beat && fY != y_start_pos)
{
center_vert.x+= render_forward.x;
center_vert.y+= render_forward.y;
center_vert.z+= render_forward.z;
}
const float render_roty= (sp_rot[1] + ae_rot[1]);
const float render_roty= (sp_rot.y + ae_rot.y);
// (step 2 of vector handling)
RageVector3 render_left;
@@ -952,21 +937,18 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
const RageVector3 right_vert(center_vert.x - render_left.x,
center_vert.y - render_left.y, center_vert.z - render_left.z);
const float fDistFromTop = fY - fYTop;
float fTexCoordTop = SCALE( fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom );
const float fDistFromTop = fY - part_args.y_top;
float fTexCoordTop = SCALE(fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom);
fTexCoordTop += fAddToTexCoord;
const float fAlpha = ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
const float fAlpha = ArrowGetAlphaOrGlow(glow, m_pPlayerState, column_args.column, fYOffset, part_args.percent_fade_to_fail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets);
const RageColor color= RageColor(
column_args.diffuse.r * fColorScale,
column_args.diffuse.g * fColorScale,
column_args.diffuse.b * fColorScale,
column_args.diffuse.r * color_scale,
column_args.diffuse.g * color_scale,
column_args.diffuse.b * color_scale,
column_args.diffuse.a * fAlpha);
// Holds don't get a glow pass because rendering them is already
// painfully slow. -Kyz
if( fAlpha > 0 )
if(fAlpha > 0)
bAllAreTransparent = false;
queue.v[0].p = left_vert; queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
@@ -974,124 +956,146 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
queue.v[2].p = right_vert; queue.v[2].c = color; queue.v[2].t = RageVector2(fTexCoordRight, fTexCoordTop);
queue.v+=3;
if( queue.Free() < 3 || bLast )
if(queue.Free() < 3 || bLast)
{
/* The queue is full. Render it, clear the buffer, and move back a step to
* start off the strip again. */
if( !bAllAreTransparent )
if(!bAllAreTransparent)
{
FOREACH( Sprite*, vpSpr, spr )
FOREACH(Sprite*, vpSpr, spr)
{
RageTexture* pTexture = (*spr)->GetTexture();
DISPLAY->SetTexture( TextureUnit_1, pTexture->GetTexHandle() );
DISPLAY->SetBlendMode( spr == vpSpr.begin() ? BLEND_NORMAL : BLEND_ADD );
DISPLAY->SetCullMode( CULL_NONE );
DISPLAY->SetTextureWrapping( TextureUnit_1, bWrapping );
DISPLAY->SetTexture(TextureUnit_1, pTexture->GetTexHandle());
DISPLAY->SetBlendMode(spr == vpSpr.begin() ? BLEND_NORMAL : BLEND_ADD);
DISPLAY->SetCullMode(CULL_NONE);
DISPLAY->SetTextureWrapping(TextureUnit_1, part_args.wrapping);
queue.Draw();
}
}
queue.Init();
bAllAreTransparent = true;
fY -= fYStep;
fY -= part_args.y_step;
}
}
}
void NoteDisplay::DrawHoldBodyInternal(vector<Sprite*>& sprite_top,
vector<Sprite*>& sprite_body, vector<Sprite*>& sprite_bottom,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args,
draw_hold_part_args& part_args,
const float head_minus_top, const float tail_plus_bottom,
const float y_head, const float y_tail, const float top_beat,
const float bottom_beat, bool glow)
{
// Draw the top cap
part_args.y_top= head_minus_top;
part_args.y_bottom= y_head;
part_args.top_beat= top_beat;
part_args.bottom_beat= top_beat;
part_args.wrapping= false;
DrawHoldPart(sprite_top, field_args, column_args, part_args, glow);
// Draw the body
part_args.y_top= y_head;
part_args.y_bottom= y_tail;
part_args.bottom_beat= bottom_beat;
part_args.wrapping= true;
DrawHoldPart(sprite_body, field_args, column_args, part_args, glow);
// Draw the bottom cap
part_args.y_top= y_tail;
part_args.y_bottom= tail_plus_bottom;
part_args.top_beat= bottom_beat;
part_args.y_start_pos= max(part_args.y_start_pos, y_head);
DrawHoldPart(sprite_bottom, field_args, column_args, part_args, glow);
}
void NoteDisplay::DrawHoldBody(const TapNote& tn,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, float fBeat,
bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition,
float fPercentFadeToFail, float fColorScale, bool bGlow,
float top_beat, float bottom_beat)
const NoteColumnRenderArgs& column_args, float beat,
bool being_held, float y_head, float y_tail, float percent_fade_to_fail,
float color_scale, float top_beat, float bottom_beat)
{
draw_hold_part_args part_args;
part_args.percent_fade_to_fail= percent_fade_to_fail;
part_args.color_scale= color_scale;
part_args.overlapped_time= tn.HoldResult.fOverlappedTime;
vector<Sprite*> vpSprTop;
Sprite *pSpriteTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, fBeat, tn.subType == TapNoteSubType_Roll, bIsBeingHeld && !cache->m_bHoldActiveIsAddLayer );
Sprite *pSpriteTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, beat, tn.subType == TapNoteSubType_Roll, being_held && !cache->m_bHoldActiveIsAddLayer );
vpSprTop.push_back( pSpriteTop );
vector<Sprite*> vpSprBody;
Sprite *pSpriteBody = GetHoldSprite( m_HoldBody, NotePart_HoldBody, fBeat, tn.subType == TapNoteSubType_Roll, bIsBeingHeld && !cache->m_bHoldActiveIsAddLayer );
Sprite *pSpriteBody = GetHoldSprite( m_HoldBody, NotePart_HoldBody, beat, tn.subType == TapNoteSubType_Roll, being_held && !cache->m_bHoldActiveIsAddLayer );
vpSprBody.push_back( pSpriteBody );
vector<Sprite*> vpSprBottom;
Sprite *pSpriteBottom = GetHoldSprite( m_HoldBottomCap, NotePart_HoldBottomCap, fBeat, tn.subType == TapNoteSubType_Roll, bIsBeingHeld && !cache->m_bHoldActiveIsAddLayer );
Sprite *pSpriteBottom = GetHoldSprite( m_HoldBottomCap, NotePart_HoldBottomCap, beat, tn.subType == TapNoteSubType_Roll, being_held && !cache->m_bHoldActiveIsAddLayer );
vpSprBottom.push_back( pSpriteBottom );
if( bIsBeingHeld && cache->m_bHoldActiveIsAddLayer )
if(being_held && cache->m_bHoldActiveIsAddLayer)
{
Sprite *pSprTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, fBeat, tn.subType == TapNoteSubType_Roll, true );
Sprite *pSprTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, beat, tn.subType == TapNoteSubType_Roll, true );
vpSprTop.push_back( pSprTop );
Sprite *pSprBody = GetHoldSprite( m_HoldBody, NotePart_HoldBody, fBeat, tn.subType == TapNoteSubType_Roll, true );
Sprite *pSprBody = GetHoldSprite( m_HoldBody, NotePart_HoldBody, beat, tn.subType == TapNoteSubType_Roll, true );
vpSprBody.push_back( pSprBody );
Sprite *pSprBottom = GetHoldSprite( m_HoldBottomCap, NotePart_HoldBottomCap, fBeat, tn.subType == TapNoteSubType_Roll, true );
Sprite *pSprBottom = GetHoldSprite( m_HoldBottomCap, NotePart_HoldBottomCap, beat, tn.subType == TapNoteSubType_Roll, true );
vpSprBottom.push_back( pSprBottom );
}
const bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(column_args.column) > 0.5f;
bool bFlipHoldBody = bReverse && cache->m_bFlipHoldBodyWhenReverse;
if( bFlipHoldBody )
const bool reverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(column_args.column) > 0.5f;
part_args.flip_texture_vertically = reverse && cache->m_bFlipHoldBodyWhenReverse;
if(part_args.flip_texture_vertically)
{
swap( vpSprTop, vpSprBottom );
swap( pSpriteTop, pSpriteBottom );
}
if( bGlow )
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
else
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );
const bool bWavyPartsNeedZBuffer = ArrowEffects::NeedZBuffer( m_pPlayerState );
const bool bWavyPartsNeedZBuffer = ArrowEffects::NeedZBuffer();
DISPLAY->SetZTestMode( bWavyPartsNeedZBuffer?ZTEST_WRITE_ON_PASS:ZTEST_OFF );
DISPLAY->SetZWrite( bWavyPartsNeedZBuffer );
// Hack: Z effects need a finer grain step.
const int fYStep = bWavyPartsNeedZBuffer? 4: 16; // use small steps only if wavy
part_args.y_step = bWavyPartsNeedZBuffer? 4: 16; // use small steps only if wavy
if( bFlipHoldBody )
if(part_args.flip_texture_vertically)
{
fYHead -= cache->m_iStopDrawingHoldBodyOffsetFromTail;
fYTail -= cache->m_iStartDrawingHoldBodyOffsetFromHead;
y_head -= cache->m_iStopDrawingHoldBodyOffsetFromTail;
y_tail -= cache->m_iStartDrawingHoldBodyOffsetFromHead;
}
else
{
fYHead += cache->m_iStartDrawingHoldBodyOffsetFromHead;
fYTail += cache->m_iStopDrawingHoldBodyOffsetFromTail;
y_head += cache->m_iStartDrawingHoldBodyOffsetFromHead;
y_tail += cache->m_iStopDrawingHoldBodyOffsetFromTail;
}
const float fFrameHeightTop = pSpriteTop->GetUnzoomedHeight();
const float fFrameHeightBottom = pSpriteBottom->GetUnzoomedHeight();
const float frame_height_top= pSpriteTop->GetUnzoomedHeight();
const float frame_height_bottom= pSpriteBottom->GetUnzoomedHeight();
float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, column_args.column,
field_args.draw_pixels_after_targets, m_fYReverseOffsetPixels );
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, column_args.column,
field_args.draw_pixels_before_targets, m_fYReverseOffsetPixels );
if( bReverse )
swap( fYStartPos, fYEndPos );
part_args.y_start_pos= ArrowEffects::GetYPos(column_args.column,
field_args.draw_pixels_after_targets, m_fYReverseOffsetPixels);
part_args.y_end_pos= ArrowEffects::GetYPos(column_args.column,
field_args.draw_pixels_before_targets, m_fYReverseOffsetPixels);
if(reverse)
{
swap(part_args.y_start_pos, part_args.y_end_pos);
}
// So that part_args.y_start_pos can be changed when drawing the bottom.
const float original_y_start_pos= part_args.y_start_pos;
const float head_minus_top= y_head - frame_height_top;
const float tail_plus_bottom= y_tail + frame_height_bottom;
bool bTopAnchor = bReverse && cache->m_bTopHoldAnchorWhenReverse;
part_args.anchor_to_top= reverse && cache->m_bTopHoldAnchorWhenReverse;
// Draw the top cap
DrawHoldPart(vpSprTop, field_args, column_args, fYStep, fPercentFadeToFail,
fColorScale, bGlow,
tn.HoldResult.fOverlappedTime,
fYHead-fFrameHeightTop, fYHead,
fYStartPos, fYEndPos,
false, bTopAnchor, bFlipHoldBody, top_beat, top_beat);
// Draw the body
DrawHoldPart(vpSprBody, field_args, column_args, fYStep, fPercentFadeToFail,
fColorScale, bGlow,
tn.HoldResult.fOverlappedTime,
fYHead, fYTail,
fYStartPos, fYEndPos,
true, bTopAnchor, bFlipHoldBody, top_beat, bottom_beat);
// Draw the bottom cap
DrawHoldPart(vpSprBottom, field_args, column_args, fYStep, fPercentFadeToFail,
fColorScale, bGlow,
tn.HoldResult.fOverlappedTime,
fYTail, fYTail+fFrameHeightBottom,
max(fYStartPos, fYHead), fYEndPos,
false, bTopAnchor, bFlipHoldBody, bottom_beat, bottom_beat);
DISPLAY->SetTextureMode(TextureUnit_1, TextureMode_Modulate);
DrawHoldBodyInternal(vpSprTop, vpSprBody, vpSprBottom, field_args,
column_args, part_args, head_minus_top,
tail_plus_bottom, y_head, y_tail, top_beat, bottom_beat,
false);
part_args.y_start_pos= original_y_start_pos;
DISPLAY->SetTextureMode(TextureUnit_1, TextureMode_Glow);
DrawHoldBodyInternal(vpSprTop, vpSprBody, vpSprBottom, field_args,
column_args, part_args, head_minus_top,
tail_plus_bottom, y_head, y_tail, top_beat, bottom_beat,
true);
}
void NoteDisplay::DrawHold(const TapNote& tn,
@@ -1136,8 +1140,8 @@ void NoteDisplay::DrawHold(const TapNote& tn,
if( bReverse )
swap( fStartYOffset, fEndYOffset );
const float fYHead = ArrowEffects::GetYPos( m_pPlayerState, column_args.column, fStartYOffset, m_fYReverseOffsetPixels );
const float fYTail = ArrowEffects::GetYPos( m_pPlayerState, column_args.column, fEndYOffset, m_fYReverseOffsetPixels );
const float fYHead= ArrowEffects::GetYPos(column_args.column, fStartYOffset, m_fYReverseOffsetPixels);
const float fYTail= ArrowEffects::GetYPos(column_args.column, fEndYOffset, m_fYReverseOffsetPixels);
const float fColorScale = SCALE( tn.HoldResult.fLife, 0.0f, 1.0f, cache->m_fHoldLetGoGrayPercent, 1.0f );
@@ -1162,8 +1166,7 @@ void NoteDisplay::DrawHold(const TapNote& tn,
}
*/
DrawHoldBody(tn, field_args, column_args, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, top_beat, bottom_beat);
DrawHoldBody(tn, field_args, column_args, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, top_beat, bottom_beat);
DrawHoldBody(tn, field_args, column_args, fBeat, bIsBeingHeld, fYHead, fYTail, fPercentFadeToFail, fColorScale, top_beat, bottom_beat);
/* These set the texture mode themselves. */
// this part was modified in pumpmania, where it flips the draw order
@@ -1188,12 +1191,14 @@ void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
if (tn.type == TapNoteType_AutoKeysound && !GAMESTATE->m_bInStepEditor) return;
if(fYOffset < field_args.draw_pixels_after_targets ||
fYOffset > field_args.draw_pixels_before_targets)
{
return;
}
float spline_beat= fBeat;
if(is_being_held) { spline_beat= column_args.song_beat; }
const float fAlpha = ArrowEffects::GetAlpha( m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
const float fGlow = ArrowEffects::GetGlow( m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
const float fAlpha= ArrowEffects::GetAlpha(column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets);
const float fGlow= ArrowEffects::GetGlow(column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets);
const RageColor diffuse = RageColor(
column_args.diffuse.r * fColorScale,
column_args.diffuse.g * fColorScale,
@@ -1213,12 +1218,12 @@ void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
// same logical structure as in UpdateReceptorGhostStuff, I just haven't
// figured out a good way to combine them. -Kyz
vector<float> sp_pos;
vector<float> sp_rot;
vector<float> sp_zoom;
vector<float> ae_pos(3, 0.0f);
vector<float> ae_rot(3, 0.0f);
vector<float> ae_zoom(3, 0.0f);
RageVector3 sp_pos;
RageVector3 sp_rot;
RageVector3 sp_zoom;
RageVector3 ae_pos;
RageVector3 ae_rot;
RageVector3 ae_zoom;
column_args.spae_pos_for_beat(m_pPlayerState, spline_beat,
fYOffset, m_fYReverseOffsetPixels, sp_pos, ae_pos);
@@ -1227,20 +1232,18 @@ void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
case NCSM_Disabled:
if(!bIsHoldCap)
{
ae_rot[0]= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset);
ae_rot.x= ArrowEffects::GetRotationX(fYOffset);
}
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset);
ae_rot[2]= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
sp_rot.resize(3);
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
ae_rot.y= ArrowEffects::GetRotationY(fYOffset);
ae_rot.z= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
break;
case NCSM_Offset:
if(!bIsHoldCap)
{
ae_rot[0]= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset);
ae_rot.x= ArrowEffects::GetRotationX(fYOffset);
}
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset);
ae_rot[2]= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
ae_rot.y= ArrowEffects::GetRotationY(fYOffset);
ae_rot.z= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
column_args.rot_handler->EvalForBeat(column_args.song_beat, spline_beat, sp_rot);
break;
case NCSM_Position:
@@ -1375,21 +1378,16 @@ void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const
// sp_* will be zeroes in NCSM_Disabled, and ae_* will be zeroes in
// NCSM_Position, so the setting step won't have to check the mode. -Kyz
// sp_* are sized by the spline evaluate function.
vector<float> sp_pos;
vector<float> sp_rot;
vector<float> sp_zoom;
vector<float> ae_pos(3, 0.0f);
vector<float> ae_rot(3, 0.0f);
vector<float> ae_zoom(3, 0.0f);
RageVector3 sp_pos;
RageVector3 sp_rot;
RageVector3 sp_zoom;
RageVector3 ae_pos;
RageVector3 ae_rot;
RageVector3 ae_zoom;
switch(NCR_current.m_pos_handler.m_spline_mode)
{
case NCSM_Disabled:
ArrowEffects::GetXYZPos(player_state, m_column, 0, m_field_render_args->reverse_offset_pixels, ae_pos);
sp_pos.resize(3);
// Sure, resize is supposed to call the default constructor, and for
// numbers the default constructor is supposed to set it to zero, but
// I got bit for relying on that once. -Kyz
sp_pos[0]= sp_pos[1]= sp_pos[2]= 0.0f;
break;
case NCSM_Offset:
ArrowEffects::GetXYZPos(player_state, m_column, 0, m_field_render_args->reverse_offset_pixels, ae_pos);
@@ -1402,12 +1400,10 @@ void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const
switch(NCR_current.m_rot_handler.m_spline_mode)
{
case NCSM_Disabled:
ae_rot[2]= ArrowEffects::ReceptorGetRotationZ(player_state);
sp_rot.resize(3);
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
ae_rot.z= ArrowEffects::ReceptorGetRotationZ(player_state);
break;
case NCSM_Offset:
ae_rot[2]= ArrowEffects::ReceptorGetRotationZ(player_state);
ae_rot.z= ArrowEffects::ReceptorGetRotationZ(player_state);
NCR_current.m_rot_handler.EvalForReceptor(song_beat, sp_rot);
break;
case NCSM_Position:
@@ -1417,12 +1413,10 @@ void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const
switch(NCR_current.m_zoom_handler.m_spline_mode)
{
case NCSM_Disabled:
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(player_state);
sp_zoom.resize(3);
sp_zoom[0]= sp_zoom[1]= sp_zoom[2]= 0.0f;
ae_zoom.x= ae_zoom.y= ae_zoom.z= ArrowEffects::GetZoom(player_state);
break;
case NCSM_Offset:
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(player_state);
ae_zoom.x= ae_zoom.y= ae_zoom.z= ArrowEffects::GetZoom(player_state);
NCR_current.m_zoom_handler.EvalForReceptor(song_beat, sp_zoom);
break;
case NCSM_Position:
@@ -1436,6 +1430,7 @@ void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const
void NoteColumnRenderer::DrawPrimitives()
{
ArrowEffects::SetCurrentOptions(&m_field_render_args->player_state->m_PlayerOptions.GetCurrent());
m_column_render_args.song_beat= m_field_render_args->player_state->GetDisplayedPosition().m_fSongBeatVisible;
m_column_render_args.pos_handler= &NCR_current.m_pos_handler;
m_column_render_args.rot_handler= &NCR_current.m_rot_handler;
+40 -19
View File
@@ -136,9 +136,9 @@ struct NCSplineHandler
m_subtract_song_beat_from_curr= true;
}
float BeatToTValue(float song_beat, float note_beat) const;
void EvalForBeat(float song_beat, float note_beat, vector<float>& ret) const;
void EvalDerivForBeat(float song_beat, float note_beat, vector<float>& ret) const;
void EvalForReceptor(float song_beat, vector<float>& ret) const;
void EvalForBeat(float song_beat, float note_beat, RageVector3& ret) const;
void EvalDerivForBeat(float song_beat, float note_beat, RageVector3& ret) const;
void EvalForReceptor(float song_beat, RageVector3& ret) const;
static void MakeWeightedAverage(NCSplineHandler& out,
const NCSplineHandler& from, const NCSplineHandler& to, float between);
@@ -153,15 +153,15 @@ struct NCSplineHandler
struct NoteColumnRenderArgs
{
void spae_pos_for_beat(const PlayerState* state,
void spae_pos_for_beat(const PlayerState* player_state,
float beat, float y_offset, float y_reverse_offset,
vector<float>& sp_pos, vector<float>& ae_pos) const;
RageVector3& sp_pos, RageVector3& ae_pos) const;
void spae_zoom_for_beat(const PlayerState* state, float beat,
vector<float>& sp_zoom, vector<float>& ae_zoom) const;
RageVector3& sp_zoom, RageVector3& ae_zoom) const;
void SetPRZForActor(Actor* actor,
const vector<float>& sp_pos, const vector<float>& ae_pos,
const vector<float>& sp_rot, const vector<float>& ae_rot,
const vector<float>& sp_zoom, const vector<float>& ae_zoom) const;
const RageVector3& sp_pos, const RageVector3& ae_pos,
const RageVector3& sp_rot, const RageVector3& ae_rot,
const RageVector3& sp_zoom, const RageVector3& ae_zoom) const;
const NCSplineHandler* pos_handler;
const NCSplineHandler* rot_handler;
const NCSplineHandler* zoom_handler;
@@ -221,23 +221,44 @@ private:
Actor *GetHoldActor( NoteColorActor nca[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
Sprite *GetHoldSprite( NoteColorSprite ncs[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
struct draw_hold_part_args
{
int y_step;
float percent_fade_to_fail;
float color_scale;
float overlapped_time;
float y_top;
float y_bottom;
float y_start_pos;
float y_end_pos;
float top_beat;
float bottom_beat;
bool wrapping;
bool anchor_to_top;
bool flip_texture_vertically;
};
void DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, float fYOffset, float fBeat,
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
bool is_being_held);
void DrawHoldBody(const TapNote& tn, const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, float fBeat, bool bIsBeingHeld,
float fYHead, float fYTail,
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
bool bGlow, float top_beat, float bottom_beat);
void DrawHoldPart(vector<Sprite*> &vpSpr,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, int fYStep,
float fPercentFadeToFail, float fColorScale, bool bGlow,
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
float fYEndPos, bool bWrapping, bool bAnchorToTop,
bool bFlipTextureVertically, float top_beat, float bottom_beat);
const NoteColumnRenderArgs& column_args,
const draw_hold_part_args& part_args, bool glow);
void DrawHoldBodyInternal(vector<Sprite*>& sprite_top,
vector<Sprite*>& sprite_body, vector<Sprite*>& sprite_bottom,
const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args,
draw_hold_part_args& part_args,
const float head_minus_top, const float tail_plus_bottom,
const float y_head, const float y_tail, const float top_beat,
const float bottom_beat, bool glow);
void DrawHoldBody(const TapNote& tn, const NoteFieldRenderArgs& field_args,
const NoteColumnRenderArgs& column_args, float beat, bool being_held,
float y_head, float y_tail, float percent_fade_to_fail,
float color_scale, float top_beat, float bottom_beat);
const PlayerState *m_pPlayerState; // to look up PlayerOptions
NoteMetricCache_t *cache;
+87 -351
View File
@@ -299,6 +299,7 @@ void NoteField::Update( float fDeltaTime )
}
ActorFrame::Update( fDeltaTime );
ArrowEffects::SetCurrentOptions(&m_pPlayerState->m_PlayerOptions.GetCurrent());
for(size_t c= 0; c < m_ColumnRenderers.size(); ++c)
{
@@ -310,8 +311,8 @@ void NoteField::Update( float fDeltaTime )
bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK
if( !bTweeningOn && m_fCurrentBeatLastUpdate != -1 )
{
const float fYOffsetLast = ArrowEffects::GetYOffset( m_pPlayerState, 0, m_fCurrentBeatLastUpdate );
const float fYPosLast = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffsetLast, m_fYReverseOffsetPixels );
const float fYOffsetLast = ArrowEffects::GetYOffset(m_pPlayerState, 0, m_fCurrentBeatLastUpdate);
const float fYPosLast= ArrowEffects::GetYPos(0, fYOffsetLast, m_fYReverseOffsetPixels);
const float fPixelDifference = fYPosLast - m_fYPosCurrentBeatLastUpdate;
//LOG->Trace( "speed = %f, %f, %f, %f, %f, %f", fSpeed, fYOffsetAtCurrent, fYOffsetAtNext, fSecondsAtCurrent, fSecondsAtNext, fPixelDifference, fSecondsDifference );
@@ -321,7 +322,7 @@ void NoteField::Update( float fDeltaTime )
}
m_fCurrentBeatLastUpdate = fCurrentBeat;
const float fYOffsetCurrent = ArrowEffects::GetYOffset( m_pPlayerState, 0, m_fCurrentBeatLastUpdate );
m_fYPosCurrentBeatLastUpdate = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffsetCurrent, m_fYReverseOffsetPixels );
m_fYPosCurrentBeatLastUpdate= ArrowEffects::GetYPos(0, fYOffsetCurrent, m_fYReverseOffsetPixels);
m_rectMarkerBar.Update( fDeltaTime );
@@ -362,7 +363,7 @@ void NoteField::DrawBeatBar( const float fBeat, BeatBarType type, int iMeasureIn
bool bIsMeasure = type == measure;
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fYPos= ArrowEffects::GetYPos(0, fYOffset, m_fYReverseOffsetPixels);
float fAlpha;
int iState;
@@ -434,7 +435,7 @@ void NoteField::DrawBoard( int iDrawDistanceAfterTargetsPixels, int iDrawDistanc
{
// Draw the board centered on fYPosAt0 so that the board doesn't slide as
// the draw distance changes with modifiers.
const float fYPosAt0 = ArrowEffects::GetYPos( m_pPlayerState, 0, 0, m_fYReverseOffsetPixels );
const float fYPosAt0= ArrowEffects::GetYPos(0, 0, m_fYReverseOffsetPixels);
RectF rect = *pSprite->GetCurrentTextureCoordRect();
const float fBoardGraphicHeightPixels = pSprite->GetUnzoomedHeight();
@@ -461,7 +462,7 @@ void NoteField::DrawMarkerBar( int iBeat )
{
float fBeat = NoteRowToBeat( iBeat );
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fYPos = ArrowEffects::GetYPos(0, fYOffset, m_fYReverseOffsetPixels);
m_rectMarkerBar.StretchTo( RectF(-GetWidth()/2, fYPos-ARROW_SIZE/2, GetWidth()/2, fYPos+ARROW_SIZE/2) );
m_rectMarkerBar.Draw();
@@ -473,9 +474,9 @@ void NoteField::DrawAreaHighlight( int iStartBeat, int iEndBeat )
float fStartBeat = NoteRowToBeat( iStartBeat );
float fEndBeat = NoteRowToBeat( iEndBeat );
float fDrawDistanceAfterTargetsPixels = ArrowEffects::GetYOffset( m_pPlayerState, 0, fStartBeat );
float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fDrawDistanceAfterTargetsPixels, m_fYReverseOffsetPixels );
float fYStartPos = ArrowEffects::GetYPos(0, fDrawDistanceAfterTargetsPixels, m_fYReverseOffsetPixels);
float fDrawDistanceBeforeTargetsPixels = ArrowEffects::GetYOffset( m_pPlayerState, 0, fEndBeat );
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fDrawDistanceBeforeTargetsPixels, m_fYReverseOffsetPixels );
float fYEndPos= ArrowEffects::GetYPos(0, fDrawDistanceBeforeTargetsPixels, m_fYReverseOffsetPixels);
// The caller should have clamped these to reasonable values
ASSERT( fYStartPos > -1000 );
@@ -492,7 +493,7 @@ static ThemeMetric<RageColor> BPM_COLOR ( "NoteField", "BPMColor" );
static ThemeMetric<RageColor> STOP_COLOR ( "NoteField", "StopColor" );
static ThemeMetric<RageColor> DELAY_COLOR ( "NoteField", "DelayColor" );
static ThemeMetric<RageColor> WARP_COLOR ( "NoteField", "WarpColor" );
static ThemeMetric<RageColor> TIME_SIGNATURE_COLOR ( "NoteField", "TimeSignatureColor" );
static ThemeMetric<RageColor> TIME_SIG_COLOR ( "NoteField", "TimeSignatureColor" );
static ThemeMetric<RageColor> TICKCOUNT_COLOR ( "NoteField", "TickcountColor" );
static ThemeMetric<RageColor> COMBO_COLOR ( "NoteField", "ComboColor" );
static ThemeMetric<RageColor> LABEL_COLOR ( "NoteField", "LabelColor" );
@@ -503,7 +504,7 @@ static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
static ThemeMetric<bool> DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" );
static ThemeMetric<bool> WARP_IS_LEFT_SIDE ( "NoteField", "WarpIsLeftSide" );
static ThemeMetric<bool> TIME_SIGNATURE_IS_LEFT_SIDE ( "NoteField", "TimeSignatureIsLeftSide" );
static ThemeMetric<bool> TIME_SIG_IS_LEFT_SIDE ( "NoteField", "TimeSignatureIsLeftSide" );
static ThemeMetric<bool> TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftSide" );
static ThemeMetric<bool> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
static ThemeMetric<bool> LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" );
@@ -514,7 +515,7 @@ static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
static ThemeMetric<float> DELAY_OFFSETX ( "NoteField", "DelayOffsetX" );
static ThemeMetric<float> WARP_OFFSETX ( "NoteField", "WarpOffsetX" );
static ThemeMetric<float> TIME_SIGNATURE_OFFSETX ( "NoteField", "TimeSignatureOffsetX" );
static ThemeMetric<float> TIME_SIG_OFFSETX ( "NoteField", "TimeSignatureOffsetX" );
static ThemeMetric<float> TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" );
static ThemeMetric<float> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
static ThemeMetric<float> LABEL_OFFSETX ( "NoteField", "LabelOffsetX" );
@@ -522,220 +523,48 @@ static ThemeMetric<float> SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" );
static ThemeMetric<float> SCROLL_OFFSETX ( "NoteField", "ScrollOffsetX" );
static ThemeMetric<float> FAKE_OFFSETX ( "NoteField", "FakeOffsetX" );
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
void NoteField::set_text_measure_number_for_draw(
const float beat, const float side_sign, float x_offset,
const float horiz_align, const RageColor& color, const RageColor& glow)
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = BPM_OFFSETX * fZoom;
const float y_offset= ArrowEffects::GetYOffset(m_pPlayerState, 0, beat);
const float y_pos= ArrowEffects::GetYPos(0, y_offset, m_fYReverseOffsetPixels);
const float zoom= ArrowEffects::GetZoom(m_pPlayerState);
const float x_base= GetWidth() * .5f;
x_offset*= zoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( BPM_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( BPM_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fBPM) );
m_textMeasureNumber.SetXY( (BPM_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.SetZoom(zoom);
m_textMeasureNumber.SetHorizAlign(horiz_align);
m_textMeasureNumber.SetDiffuse(color);
m_textMeasureNumber.SetGlow(glow);
m_textMeasureNumber.SetXY((x_offset + x_base) * side_sign, y_pos);
}
void NoteField::draw_timing_segment_text(const RString& text,
const float beat, const float side_sign, float x_offset,
const float horiz_align, const RageColor& color, const RageColor& glow)
{
set_text_measure_number_for_draw(beat, side_sign, x_offset, horiz_align,
color, glow);
m_textMeasureNumber.SetText(text);
m_textMeasureNumber.Draw();
}
void NoteField::DrawFreezeText( const float fBeat, const float fSecs )
void NoteField::DrawAttackText(const float beat, const Attack &attack,
const RageColor& glow)
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = STOP_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( STOP_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( STOP_COLOR );
m_textMeasureNumber.SetXY( (STOP_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fSecs) );
m_textMeasureNumber.Draw();
}
void NoteField::DrawDelayText( const float fBeat, const float fSecs )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = DELAY_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( DELAY_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( DELAY_COLOR );
m_textMeasureNumber.SetXY( (DELAY_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fSecs) );
m_textMeasureNumber.Draw();
}
void NoteField::DrawWarpText( const float fBeat, const float fNewBeat )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = WARP_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( WARP_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( WARP_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fNewBeat) );
m_textMeasureNumber.SetXY( (WARP_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = TIME_SIGNATURE_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( TIME_SIGNATURE_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( TIME_SIGNATURE_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( ssprintf("%d\n--\n%d", iNumerator, iDenominator) );
m_textMeasureNumber.SetXY( (TIME_SIGNATURE_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawTickcountText( const float fBeat, int iTicks )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = TICKCOUNT_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( TICKCOUNT_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( TICKCOUNT_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( ssprintf("%d", iTicks) );
m_textMeasureNumber.SetXY( (TICKCOUNT_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawComboText( const float fBeat, int iCombo, int iMiss )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = COMBO_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( COMBO_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( COMBO_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( ssprintf("%d/%d", iCombo, iMiss) );
m_textMeasureNumber.SetXY( (COMBO_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawLabelText( const float fBeat, RString sLabel )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = LABEL_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( LABEL_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( LABEL_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( sLabel.c_str() );
m_textMeasureNumber.SetXY( (LABEL_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait, int iMode )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = SPEED_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( SPEED_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( SPEED_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( ssprintf("%s\n%s\n%s", FloatToString(fPercent).c_str(), (iMode == 1 ? "S" : "B"), FloatToString(fWait).c_str()) );
m_textMeasureNumber.SetXY( (SPEED_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawScrollText( const float fBeat, float fPercent )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = SCROLL_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( SCROLL_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( SCROLL_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fPercent) );
m_textMeasureNumber.SetXY( (SCROLL_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawFakeText( const float fBeat, const float fNewBeat )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = FAKE_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( FAKE_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( FAKE_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( FloatToString(fNewBeat) );
m_textMeasureNumber.SetXY( (FAKE_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawAttackText( const float fBeat, const Attack &attack )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( align_left );
m_textMeasureNumber.SetDiffuse( RageColor(0,0.8f,0.8f,1) );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
set_text_measure_number_for_draw(beat, 1, 10, align_left,
RageColor(0,0.8f,0.8f,1), glow);
m_textMeasureNumber.SetText( attack.GetTextDescription() );
m_textMeasureNumber.SetXY( +GetWidth()/2.f + 10*fZoom, fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawBGChangeText( const float fBeat, const RString sNewBGName )
void NoteField::DrawBGChangeText(const float beat, const RString new_bg_name,
const RageColor& glow)
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( align_left );
m_textMeasureNumber.SetDiffuse( RageColor(0,1,0,1) );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( sNewBGName );
m_textMeasureNumber.SetXY( +GetWidth()/2.f, fYPos );
set_text_measure_number_for_draw(beat, 1, 0, align_left, RageColor(0,1,0,1),
glow);
m_textMeasureNumber.SetText(new_bg_name);
m_textMeasureNumber.Draw();
}
@@ -993,139 +822,42 @@ void NoteField::DrawPrimitives()
ASSERT(GAMESTATE->m_pCurSong != NULL);
const TimingData &timing = *pTiming;
const RageColor text_glow= RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f);
// Scroll text
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
{
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawScrollText( fBeat, seg->GetRatio() );
}
float horiz_align= align_right;
float side_sign= 1;
#define draw_all_segments(str_exp, name, caps_name) \
horiz_align= caps_name##_IS_LEFT_SIDE ? align_right : align_left; \
side_sign= caps_name##_IS_LEFT_SIDE ? -1 : 1; \
for(unsigned int i= 0; i < segs[SEGMENT_##caps_name]->size(); ++i) \
{ \
const name##Segment* seg= To##name((*segs[SEGMENT_##caps_name])[i]); \
if(seg->GetRow() >= m_FieldRenderArgs.first_row && \
seg->GetRow() <= m_FieldRenderArgs.last_row && \
IS_ON_SCREEN(seg->GetBeat())) \
{ \
draw_timing_segment_text(str_exp, beat, side_sign, \
caps_name##_OFFSETX, horiz_align, caps_name##_COLOR, text_glow); \
} \
}
// BPM text
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
{
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawBPMText( fBeat, seg->GetBPM() );
}
}
// Freeze text
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
{
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawFreezeText( fBeat, seg->GetPause() );
}
}
// Delay text
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
{
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawDelayText( fBeat, seg->GetPause() );
}
}
// Warp text
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
{
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawWarpText( fBeat, seg->GetLength() );
}
}
// Time Signature text
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
{
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawTimeSignatureText( fBeat, seg->GetNum(), seg->GetDen() );
}
}
// Tickcount text
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
{
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawTickcountText( fBeat, seg->GetTicks() );
}
}
// Combo text
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
{
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawComboText( fBeat, seg->GetCombo(), seg->GetMissCombo() );
}
}
// Label text
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
{
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawLabelText( fBeat, seg->GetLabel() );
}
}
// Speed text
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
{
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawSpeedText(fBeat, seg->GetRatio(),
seg->GetDelay(), seg->GetUnit() );
}
}
// Fake text
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
{
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
{
float fBeat = seg->GetBeat();
if( IS_ON_SCREEN(fBeat) )
DrawFakeText( fBeat, seg->GetLength() );
}
}
draw_all_segments(FloatToString(seg->GetRatio()), Scroll, SCROLL);
draw_all_segments(FloatToString(seg->GetBPM()), BPM, BPM);
draw_all_segments(FloatToString(seg->GetPause()), Stop, STOP);
draw_all_segments(FloatToString(seg->GetPause()), Delay, DELAY);
draw_all_segments(FloatToString(seg->GetLength()), Warp, WARP);
draw_all_segments(ssprintf("%d\n--\n%d", seg->GetNum(), seg->GetDen()),
TimeSignature, TIME_SIG);
draw_all_segments(ssprintf("%d", seg->GetTicks()), Tickcount, TICKCOUNT);
draw_all_segments(
ssprintf("%d/%d", seg->GetCombo(), seg->GetMissCombo()), Combo, COMBO);
draw_all_segments(seg->GetLabel(), Label, LABEL);
draw_all_segments(ssprintf("%s\n%s\n%s",
FloatToString(seg->GetRatio()).c_str(),
(seg->GetUnit() == 1 ? "S" : "B"),
FloatToString(seg->GetDelay()).c_str()), Speed, SPEED);
draw_all_segments(FloatToString(seg->GetLength()), Fake, FAKE);
#undef draw_all_segments
// Course mods text
const Course *pCourse = GAMESTATE->m_pCurCourse;
@@ -1140,10 +872,10 @@ void NoteField::DrawPrimitives()
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
if( BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row &&
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row)
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row &&
IS_ON_SCREEN(fBeat))
{
if( IS_ON_SCREEN(fBeat) )
DrawAttackText( fBeat, *a );
DrawAttackText(fBeat, *a, text_glow);
}
}
}
@@ -1162,7 +894,7 @@ void NoteField::DrawPrimitives()
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row &&
IS_ON_SCREEN(fBeat))
{
this->DrawAttackText(fBeat, *a);
this->DrawAttackText(fBeat, *a, text_glow);
}
}
}
@@ -1226,7 +958,7 @@ void NoteField::DrawPrimitives()
s = ssprintf("%d: ",*bl) + s;
vsBGChanges.push_back( s );
}
DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) );
DrawBGChangeText(fLowestBeat, join("\n",vsBGChanges), text_glow);
}
FOREACH_CONST( BackgroundLayer, viLowestIndex, bl )
iter[*bl]++;
@@ -1270,8 +1002,12 @@ void NoteField::DrawPrimitives()
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
GAMESTATE->GetCurrentStyle(m_pPlayerState->m_PlayerNumber)->m_iColsPerPlayer));
m_FieldRenderArgs.selection_glow= SCALE(
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
if(*m_FieldRenderArgs.selection_begin_marker != -1 &&
*m_FieldRenderArgs.selection_end_marker != -1)
{
m_FieldRenderArgs.selection_glow= SCALE(
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
}
m_FieldRenderArgs.fade_before_targets= FADE_BEFORE_TARGETS_PERCENT;
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
+8 -13
View File
@@ -75,19 +75,14 @@ protected:
void DrawBeatBar( const float fBeat, BeatBarType type, int iMeasureIndex );
void DrawMarkerBar( int fBeat );
void DrawAreaHighlight( int iStartBeat, int iEndBeat );
void DrawBPMText( const float fBeat, const float fBPM );
void DrawFreezeText( const float fBeat, const float fLength );
void DrawDelayText( const float fBeat, const float fLength );
void DrawWarpText( const float fBeat, const float fNewBeat );
void DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator );
void DrawTickcountText( const float fBeat, int iTicks );
void DrawComboText( const float fBeat, int iCombo, int iMiss );
void DrawLabelText( const float fBeat, RString sLabel );
void DrawSpeedText( const float fBeat, float fPercent, float fWait, int iMode );
void DrawScrollText( const float fBeat, float fPercent );
void DrawFakeText( const float fBeat, const float fNewBeat );
void DrawAttackText( const float fBeat, const Attack &attack );
void DrawBGChangeText( const float fBeat, const RString sNewBGName );
void set_text_measure_number_for_draw(
const float beat, const float side_sign, float x_offset,
const float horiz_align, const RageColor& color, const RageColor& glow);
void draw_timing_segment_text(const RString& text,
const float beat, const float side_sign, float x_offset,
const float horiz_align, const RageColor& color, const RageColor& glow);
void DrawAttackText(const float beat, const Attack &attack, const RageColor& glow);
void DrawBGChangeText(const float beat, const RString new_bg_name, const RageColor& glow);
float GetWidth() const;
const NoteData *m_pNoteData;
+3 -1
View File
@@ -819,6 +819,8 @@ void Player::Update( float fDeltaTime )
const float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat;
const int iSongRow = BeatToNoteRow( fSongBeat );
ArrowEffects::SetCurrentOptions(&m_pPlayerState->m_PlayerOptions.GetCurrent());
// Optimization: Don't spend time processing the things below that won't show
// if the Player doesn't show anything on the screen.
if( HasVisibleParts() )
@@ -869,7 +871,7 @@ void Player::Update( float fDeltaTime )
//float fGrayYPos = SCALE( fPercentReverse, 0.f, 1.f, GRAY_ARROWS_Y_STANDARD, GRAY_ARROWS_Y_REVERSE );
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
const float fZ = ArrowEffects::GetZPos(c, 0);
fX *= ( 1 - fMiniPercent * 0.5f );
m_vpHoldJudgment[c]->SetX( fX );
+47 -6
View File
@@ -35,6 +35,8 @@ RageTextureManager* TEXTUREMAN = NULL; // global and accessible from anywhere
namespace
{
map<RageTextureID, RageTexture*> m_mapPathToTexture;
map<RageTextureID, RageTexture*> m_textures_to_update;
map<RageTexture*, RageTextureID> m_texture_ids_by_pointer;
};
RageTextureManager::RageTextureManager():
@@ -50,11 +52,13 @@ RageTextureManager::~RageTextureManager()
LOG->Trace( "TEXTUREMAN LEAK: '%s', RefCount = %d.", i->first.filename.c_str(), pTexture->m_iRefCount );
SAFE_DELETE( pTexture );
}
m_textures_to_update.clear();
m_texture_ids_by_pointer.clear();
}
void RageTextureManager::Update( float fDeltaTime )
{
FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i )
FOREACHM(RageTextureID, RageTexture*, m_textures_to_update, i)
{
RageTexture* pTexture = i->second;
pTexture->Update( fDeltaTime );
@@ -93,6 +97,12 @@ void RageTextureManager::RegisterTexture( RageTextureID ID, RageTexture *pTextur
}
m_mapPathToTexture[ID] = pTexture;
m_texture_ids_by_pointer[pTexture]= ID;
}
void RageTextureManager::RegisterTextureForUpdating(RageTextureID id, RageTexture* tex)
{
m_textures_to_update[id]= tex;
}
static const RString g_sDefaultTextureName = "__blank__";
@@ -164,6 +174,7 @@ RageTexture* RageTextureManager::LoadTextureInternal( RageTextureID ID )
}
m_mapPathToTexture[ID] = pTexture;
m_texture_ids_by_pointer[pTexture]= ID;
return pTexture;
}
@@ -224,13 +235,43 @@ void RageTextureManager::DeleteTexture( RageTexture *t )
ASSERT( t->m_iRefCount == 0 );
LOG->Trace( "RageTextureManager: deleting '%s'.", t->GetID().filename.c_str() );
FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i )
map<RageTexture*, RageTextureID>::iterator id_entry=
m_texture_ids_by_pointer.find(t);
if(id_entry != m_texture_ids_by_pointer.end())
{
if( i->second == t )
map<RageTextureID, RageTexture*>::iterator tex_entry=
m_mapPathToTexture.find(id_entry->second);
if(tex_entry != m_mapPathToTexture.end())
{
m_mapPathToTexture.erase( i ); // remove map entry
SAFE_DELETE( t ); // free the texture
return;
m_mapPathToTexture.erase(tex_entry);
SAFE_DELETE(t);
}
map<RageTextureID, RageTexture*>::iterator tex_update_entry=
m_textures_to_update.find(id_entry->second);
if(tex_update_entry != m_textures_to_update.end())
{
m_textures_to_update.erase(tex_update_entry);
}
m_texture_ids_by_pointer.erase(id_entry);
return;
}
else
{
FAIL_M("Tried to delete a texture that wasn't in the ids by pointer list.");
FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i )
{
if( i->second == t )
{
m_mapPathToTexture.erase( i ); // remove map entry
SAFE_DELETE( t ); // free the texture
map<RageTextureID, RageTexture*>::iterator tex_update_entry=
m_textures_to_update.find(i->first);
if(tex_update_entry != m_textures_to_update.end())
{
m_textures_to_update.erase(tex_update_entry);
}
return;
}
}
}
+2
View File
@@ -60,6 +60,8 @@ public:
void UnloadTexture( RageTexture *t );
void ReloadAll();
void RegisterTextureForUpdating(RageTextureID id, RageTexture* tex);
bool SetPrefs( RageTextureManagerPrefs prefs );
RageTextureManagerPrefs GetPrefs() { return m_Prefs; };
+5 -1
View File
@@ -57,13 +57,17 @@ extern const RageTimer RageZeroTimer;
#define START_TIME_CALL_COUNT(name) START_TIME(name); ++name##_call_count;
#define END_TIME(name) uint64_t name##_end_time= RageTimer::GetUsecsSinceStart(); LOG->Time(#name " time: %zu to %zu = %zu", name##_start_time, name##_end_time, name##_end_time - name##_start_time);
#define END_TIME_ADD_TO(name) uint64_t name##_end_time= RageTimer::GetUsecsSinceStart(); name##_total += name##_end_time - name##_start_time;
#define END_TIME_CALL_COUNT(name) END_TIME_ADD_TO(name); ++name##_end_count;
#define DECL_TOTAL_TIME(name) extern uint64_t name##_total;
#define DEF_TOTAL_TIME(name) uint64_t name##_total= 0;
#define PRINT_TOTAL_TIME(name) LOG->Time(#name " total time: %zu", name##_total);
#define DECL_TOT_CALL_PAIR(name) extern uint64_t name##_total; extern uint64_t name##_call_count;
#define DEF_TOT_CALL_PAIR(name) uint64_t name##_total= 0; uint64_t name##_call_count= 0;
#define PRINT_TOT_CALL_PAIR(name) LOG->Time(#name " calls: %zu, time: %zu", name##_call_count, name##_total);
#define PRINT_TOT_CALL_PAIR(name) LOG->Time(#name " calls: %zu, time: %zu, per: %f", name##_call_count, name##_total, static_cast<float>(name##_total) / name##_call_count);
#define DECL_TOT_CALL_END(name) DECL_TOT_CALL_PAIR(name); extern uint64_t name##_end_count;
#define DEF_TOT_CALL_END(name) DEF_TOT_CALL_PAIR(name); uint64_t name##_end_count= 0;
#define PRINT_TOT_CALL_END(name) LOG->Time(#name " calls: %zu, time: %zu, early end: %zu, per: %f", name##_call_count, name##_total, name##_end_count, static_cast<float>(name##_total) / (name##_call_count - name##_end_count));
#endif
+8 -1
View File
@@ -50,7 +50,14 @@ ReceptorArrowRow::~ReceptorArrowRow()
void ReceptorArrowRow::Update( float fDeltaTime )
{
ActorFrame::Update( fDeltaTime );
ArrowEffects::Update();
// If we're on gameplay, then the notefield will take care of updating
// ArrowEffects. But if we're on ScreenNameEntry, there is no notefield,
// Checking whether m_renderers is null is a proxy for checking whether
// there is a notefield. -Kyz
if(m_renderers == NULL)
{
ArrowEffects::Update();
}
for( unsigned c=0; c<m_ReceptorArrow.size(); c++ )
{
-3
View File
@@ -1994,9 +1994,7 @@ void ScreenGameplay::Update( float fDeltaTime )
}
PlayTicks();
UpdateLights();
SendCrossedMessages();
if( !m_bForceNoNetwork && NSMAN->useSMserver )
@@ -2010,7 +2008,6 @@ void ScreenGameplay::Update( float fDeltaTime )
if( m_bShowScoreboard && NSMAN->ChangedScoreboard(cn) && GAMESTATE->GetFirstDisabledPlayer() != PLAYER_INVALID )
m_Scoreboard[cn].SetText( NSMAN->m_Scoreboard[cn] );
}
// ArrowEffects::Update call moved because having it happen once per
// NoteField (which means twice in two player) seemed wasteful. -Kyz
ArrowEffects::Update();
+12 -5
View File
@@ -8,6 +8,7 @@
#include "RageLog.h"
#include "RageDisplay.h"
#include "RageTexture.h"
#include "RageTimer.h"
#include "RageUtil.h"
#include "ActorUtil.h"
#include "Foreach.h"
@@ -23,6 +24,7 @@ Sprite::Sprite()
m_pTexture = NULL;
m_iCurState = 0;
m_fSecsIntoState = 0.0f;
m_animation_length_seconds= 0.0f;
m_bUsingCustomTexCoords = false;
m_bUsingCustomPosCoords = false;
m_bSkipNextUpdate = true;
@@ -58,6 +60,7 @@ Sprite::Sprite( const Sprite &cpy ):
{
#define CPY(a) a = cpy.a
CPY( m_States );
CPY(m_animation_length_seconds);
CPY( m_iCurState );
CPY( m_fSecsIntoState );
CPY( m_bUsingCustomTexCoords );
@@ -93,6 +96,7 @@ void Sprite::SetAllStateDelays(float fDelay)
{
m_States[i].fDelay = fDelay;
}
RecalcAnimationLengthSeconds();
}
RageTextureID Sprite::SongBGTexture( RageTextureID ID )
@@ -248,6 +252,7 @@ void Sprite::LoadFromNode( const XNode* pNode )
}
Actor::LoadFromNode( pNode );
RecalcAnimationLengthSeconds();
}
void Sprite::UnloadTexture()
@@ -351,6 +356,7 @@ void Sprite::LoadStatesFromTexture()
newState.rect = *m_pTexture->GetTextureCoordRect( i );
m_States.push_back( newState );
}
RecalcAnimationLengthSeconds();
}
void Sprite::UpdateAnimationState()
@@ -774,12 +780,13 @@ void Sprite::SetState( int iNewState )
m_fSecsIntoState = 0.0f;
}
float Sprite::GetAnimationLengthSeconds() const
void Sprite::RecalcAnimationLengthSeconds()
{
float fTotal = 0;
FOREACH_CONST( State, m_States, s )
fTotal += s->fDelay;
return fTotal;
float m_animation_length_seconds = 0;
FOREACH_CONST(State, m_States, s)
{
m_animation_length_seconds += s->fDelay;
}
}
void Sprite::SetSecondsIntoAnimation( float fSeconds )
+5 -2
View File
@@ -54,10 +54,12 @@ public:
virtual int GetNumStates() const;
virtual void SetState( int iNewState );
int GetState() { return m_iCurState; }
virtual float GetAnimationLengthSeconds() const;
virtual float GetAnimationLengthSeconds() const
{ return m_animation_length_seconds; }
virtual void RecalcAnimationLengthSeconds();
virtual void SetSecondsIntoAnimation( float fSeconds );
void SetStateProperties(const vector<State>& new_states)
{ m_States= new_states; SetState(0); }
{ m_States= new_states; RecalcAnimationLengthSeconds(); SetState(0); }
RString GetTexturePath() const;
@@ -106,6 +108,7 @@ private:
int m_iCurState;
/** @brief The number of seconds that have elapsed since we switched to this frame. */
float m_fSecsIntoState;
float m_animation_length_seconds;
EffectMode m_EffectMode;
bool m_bUsingCustomTexCoords;