RageTextureManager now keeps a map of textures by pointer for quicker lookup when deleting.

RageTextureManager now keeps a map of textures that need updating, which is none of them because I couldn't find a class that inherits from RageTexture that doesn't have an empty Update function.
ArrowEffects now requires setting the current PlayerOptions before calling any functions.  This might make moving to per-column mods easier, and reduces the direct usage of PlayerState.
Tipsy calculations for each column are done in ArrowEffects::Update instead of GetYPos and GetYOffset.
DrawHold changed to only call DrawHoldBody once.  DrawHoldBody now does the normal and glow passes together instead of needing to be called twice.
DrawHoldPart changed to take most of its args in a struct.
Giant copy paste mess that NoteField was using to draw timing segment text replaced with a couple functions and a macro.
Selection glow for notefield is only calculated if a section is selected.
Added RageVector3 functions to CubicSplineN for NoteDisplay to use.
Actor effect period is cached now.  Sprites and Models cache their animation length now.
ReceptorArrowRow no longer calls ArrowEffects::Update in gameplay.
This commit is contained in:
Kyzentun
2015-04-24 15:55:54 -06:00
parent ede974ce73
commit 2656123464
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;