diff --git a/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj b/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj index 8cb7d6311a..852f3d2325 100644 --- a/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj +++ b/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj @@ -670,7 +670,6 @@ AA40D2F509A08D650068C0D5 /* RageSurface_Load_XPM.h in Headers */ = {isa = PBXBuildFile; fileRef = AABBF6730659E78D00738526 /* RageSurface_Load_XPM.h */; }; AA40D2F609A08D650068C0D5 /* RageSurface_Load.h in Headers */ = {isa = PBXBuildFile; fileRef = AABBF6750659E78D00738526 /* RageSurface_Load.h */; }; AA40D2F809A08D650068C0D5 /* Difficulty.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD6A713065E0FDF0042165A /* Difficulty.h */; }; - AA40D2F909A08D650068C0D5 /* Foreach.h in Headers */ = {isa = PBXBuildFile; fileRef = AA70E3640663112800DAE1FD /* Foreach.h */; }; AA40D2FA09A08D650068C0D5 /* Trail.h in Headers */ = {isa = PBXBuildFile; fileRef = AA70E3660663112800DAE1FD /* Trail.h */; }; AA40D2FB09A08D650068C0D5 /* TrailUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = AA70E3680663112800DAE1FD /* TrailUtil.h */; }; AA40D2FC09A08D650068C0D5 /* ScreenNetworkOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = AA42F5E7067068D30013509E /* ScreenNetworkOptions.h */; }; @@ -2499,7 +2498,6 @@ AA6EFFC104770FFD005F316C /* Quad.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Quad.h; path = ../src/Quad.h; sourceTree = ""; }; AA6EFFC204770FFD005F316C /* Sprite.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = Sprite.cpp; path = ../src/Sprite.cpp; sourceTree = ""; }; AA6EFFC304770FFD005F316C /* Sprite.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Sprite.h; path = ../src/Sprite.h; sourceTree = ""; }; - AA70E3640663112800DAE1FD /* Foreach.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = Foreach.h; sourceTree = ""; }; AA70E3650663112800DAE1FD /* Trail.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = Trail.cpp; path = ../src/Trail.cpp; sourceTree = ""; }; AA70E3660663112800DAE1FD /* Trail.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Trail.h; path = ../src/Trail.h; sourceTree = ""; }; AA70E3670663112800DAE1FD /* TrailUtil.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = TrailUtil.cpp; path = ../src/TrailUtil.cpp; sourceTree = ""; }; @@ -3471,7 +3469,6 @@ 29B97315FDCFA39411CA2CEA /* Other Source */ = { isa = PBXGroup; children = ( - AA70E3640663112800DAE1FD /* Foreach.h */, 3659B56D0F902143002B6B68 /* CommandLineActions.cpp */, 3659B56E0F902143002B6B68 /* CommandLineActions.h */, ); @@ -5682,7 +5679,6 @@ AA40D2F509A08D650068C0D5 /* RageSurface_Load_XPM.h in Headers */, AA40D2F609A08D650068C0D5 /* RageSurface_Load.h in Headers */, AA40D2F809A08D650068C0D5 /* Difficulty.h in Headers */, - AA40D2F909A08D650068C0D5 /* Foreach.h in Headers */, AA40D2FA09A08D650068C0D5 /* Trail.h in Headers */, AA40D2FB09A08D650068C0D5 /* TrailUtil.h in Headers */, AA40D2FC09A08D650068C0D5 /* ScreenNetworkOptions.h in Headers */, diff --git a/src/Actor.cpp b/src/Actor.cpp index 93115e06d8..8645c02d65 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -1,1745 +1,1745 @@ -#include "global.h" -#include "Actor.h" -#include "RageDisplay.h" -#include "RageUtil.h" -#include "RageMath.h" -#include "RageLog.h" -#include "arch/Dialog/Dialog.h" -#include "Foreach.h" -#include "XmlFile.h" -#include "LuaBinding.h" -#include "ThemeManager.h" -#include "LuaReference.h" -#include "MessageManager.h" -#include "LightsManager.h" // for NUM_CabinetLight -#include "ActorUtil.h" -#include "Preference.h" -#include - -static Preference g_bShowMasks("ShowMasks", false); - -/** - * @brief Set up a hidden Actor that won't be drawn. - * - * It's useful to be able to construct a basic Actor in XML, in - * order to simply delay a Transition, or receive and send broadcasts. - * Since these actors will never draw, set them hidden by default. */ -class HiddenActor: public Actor -{ -public: - HiddenActor() { SetVisible(false); } - virtual HiddenActor *Copy() const; -}; -REGISTER_ACTOR_CLASS_WITH_NAME( HiddenActor, Actor ); - -float Actor::g_fCurrentBGMTime = 0, Actor::g_fCurrentBGMBeat; -float Actor::g_fCurrentBGMTimeNoOffset = 0, Actor::g_fCurrentBGMBeatNoOffset = 0; -vector Actor::g_vfCurrentBGMBeatPlayer(NUM_PlayerNumber, 0); -vector Actor::g_vfCurrentBGMBeatPlayerNoOffset(NUM_PlayerNumber, 0); - - -Actor *Actor::Copy() const { return new Actor(*this); } - -static float g_fCabinetLights[NUM_CabinetLight]; - -static const char *HorizAlignNames[] = { - "Left", - "Center", - "Right" -}; -XToString( HorizAlign ); -LuaXType( HorizAlign ); - -static const char *VertAlignNames[] = { - "Top", - "Middle", - "Bottom" -}; -XToString( VertAlign ); -LuaXType( VertAlign ); - -void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset ) -{ - g_fCurrentBGMTime = fTime; - g_fCurrentBGMBeat = fBeat; - - /* This timer is generally only used for effects tied to the background music - * when GameSoundManager is aligning music beats. Alignment doesn't handle - * g_fVisualDelaySeconds. */ - g_fCurrentBGMTimeNoOffset = fTimeNoOffset; - g_fCurrentBGMBeatNoOffset = fBeatNoOffset; -} - -void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ) -{ - g_vfCurrentBGMBeatPlayer[pn] = fBeat; - g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset; -} - -void Actor::SetBGMLight( int iLightNumber, float fCabinetLights ) -{ - ASSERT( iLightNumber < NUM_CabinetLight ); - g_fCabinetLights[iLightNumber] = fCabinetLights; -} - -void Actor::InitState() -{ - StopTweening(); - - m_pTempState = NULL; - - m_baseRotation = RageVector3( 0, 0, 0 ); - m_baseScale = RageVector3( 1, 1, 1 ); - m_fBaseAlpha = 1; - - m_start.Init(); - m_current.Init(); - - m_fHorizAlign = 0.5f; - m_fVertAlign = 0.5f; -#if defined(SSC_FUTURES) - for( unsigned i = 0; i < m_Effects.size(); ++i ) - m_Effects[i] = no_effect; -#else - m_Effect = no_effect; -#endif - m_fSecsIntoEffect = 0; - m_fEffectDelta = 0; - m_fEffectRampUp = 0.5f; - m_fEffectHoldAtHalf = 0; - m_fEffectRampDown = 0.5f; - m_fEffectHoldAtZero = 0; - m_fEffectOffset = 0; - m_EffectClock = CLOCK_TIMER; - m_vEffectMagnitude = RageVector3(0,0,10); - m_effectColor1 = RageColor(1,1,1,1); - m_effectColor2 = RageColor(1,1,1,1); - - m_bVisible = true; - m_fShadowLengthX = 0; - m_fShadowLengthY = 0; - m_ShadowColor = RageColor(0,0,0,0.5f); - m_bIsAnimating = true; - m_fHibernateSecondsLeft = 0; - m_iDrawOrder = 0; - - m_bTextureWrapping = false; - m_bTextureFiltering = true; - - m_BlendMode = BLEND_NORMAL; - m_fZBias = 0; - m_bClearZBuffer = false; - m_ZTestMode = ZTEST_OFF; - m_bZWrite = false; - m_CullMode = CULL_NONE; -} - -static bool GetMessageNameFromCommandName( const RString &sCommandName, RString &sMessageNameOut ) -{ - if( sCommandName.Right(7) == "Message" ) - { - sMessageNameOut = sCommandName.Left(sCommandName.size()-7); - return true; - } - else - { - return false; - } -} - -Actor::Actor() -{ - m_pLuaInstance = new LuaClass; - Lua *L = LUA->Get(); - m_pLuaInstance->PushSelf( L ); - lua_newtable( L ); - lua_pushvalue( L, -1 ); - lua_setmetatable( L, -2 ); - lua_setfield( L, -2, "ctx" ); - lua_pop( L, 1 ); - LUA->Release( L ); - - m_size = RageVector2( 1, 1 ); - InitState(); - m_pParent = NULL; - m_bFirstUpdate = true; -} - -Actor::~Actor() -{ - StopTweening(); - UnsubscribeAll(); -} - -Actor::Actor( const Actor &cpy ): - MessageSubscriber( cpy ) -{ - /* Don't copy an Actor in the middle of rendering. */ - ASSERT( cpy.m_pTempState == NULL ); - m_pTempState = NULL; - -#define CPY(x) x = cpy.x - CPY( m_sName ); - CPY( m_pParent ); - CPY( m_pLuaInstance ); - - CPY( m_baseRotation ); - CPY( m_baseScale ); - CPY( m_fBaseAlpha ); - - - CPY( m_size ); - CPY( m_current ); - CPY( m_start ); - for( unsigned i = 0; i < cpy.m_Tweens.size(); ++i ) - m_Tweens.push_back( new TweenStateAndInfo(*cpy.m_Tweens[i]) ); - - CPY( m_bFirstUpdate ); - - CPY( m_fHorizAlign ); - CPY( m_fVertAlign ); -#if defined(SSC_FUTURES) - // I'm a bit worried about this -aj - for( unsigned i = 0; i < cpy.m_Effects.size(); ++i ) - m_Effects.push_back( (*cpy.m_Effects[i]) ); -#else - CPY( m_Effect ); -#endif - CPY( m_fSecsIntoEffect ); - CPY( m_fEffectDelta ); - CPY( m_fEffectRampUp ); - CPY( m_fEffectHoldAtHalf ); - CPY( m_fEffectRampDown ); - CPY( m_fEffectHoldAtZero ); - CPY( m_fEffectOffset ); - CPY( m_EffectClock ); - - CPY( m_effectColor1 ); - CPY( m_effectColor2 ); - CPY( m_vEffectMagnitude ); - - CPY( m_bVisible ); - CPY( m_fHibernateSecondsLeft ); - CPY( m_fShadowLengthX ); - CPY( m_fShadowLengthY ); - CPY( m_ShadowColor ); - CPY( m_bIsAnimating ); - CPY( m_iDrawOrder ); - - CPY( m_bTextureWrapping ); - CPY( m_bTextureFiltering ); - CPY( m_BlendMode ); - CPY( m_bClearZBuffer ); - CPY( m_ZTestMode ); - CPY( m_bZWrite ); - CPY( m_fZBias ); - CPY( m_CullMode ); - - CPY( m_mapNameToCommands ); -#undef CPY -} - -/* XXX: This calls InitCommand, which must happen after all other - * initialization (eg. ActorFrame loading children). However, it - * also loads input variables, which should happen first. The - * former is more important. */ -void Actor::LoadFromNode( const XNode* pNode ) -{ - Lua *L = LUA->Get(); - FOREACH_CONST_Attr( pNode, pAttr ) - { - // Load Name, if any. - const RString &sKeyName = pAttr->first; - const XNodeValue *pValue = pAttr->second; - if( sKeyName == "Name" ) SetName( pValue->GetValue() ); - else if( sKeyName == "BaseRotationX" ) SetBaseRotationX( pValue->GetValue() ); - else if( sKeyName == "BaseRotationY" ) SetBaseRotationY( pValue->GetValue() ); - else if( sKeyName == "BaseRotationZ" ) SetBaseRotationZ( pValue->GetValue() ); - else if( sKeyName == "BaseZoomX" ) SetBaseZoomX( pValue->GetValue() ); - else if( sKeyName == "BaseZoomY" ) SetBaseZoomY( pValue->GetValue() ); - else if( sKeyName == "BaseZoomZ" ) SetBaseZoomZ( pValue->GetValue() ); - else if( EndsWith(sKeyName,"Command") ) - { - LuaReference *pRef = new LuaReference; - pValue->PushValue( L ); - pRef->SetFromStack( L ); - RString sCmdName = sKeyName.Left( sKeyName.size()-7 ); - AddCommand( sCmdName, apActorCommands( pRef ) ); - } - } - - LUA->Release( L ); - - // Don't recurse Init. It gets called once for every Actor when the - // Actor is loaded, and we don't want to call it again. - PlayCommandNoRecurse( Message("Init") ); -} - -void Actor::Draw() -{ - if( !m_bVisible ) - return; // early abort - if( m_fHibernateSecondsLeft > 0 ) - return; // early abort - if( this->EarlyAbortDraw() ) - return; - - // call the most-derived versions - this->BeginDraw(); - this->DrawPrimitives(); // call the most-derived version of DrawPrimitives(); - this->EndDraw(); -} - -void Actor::BeginDraw() // set the world matrix and calculate actor properties -{ - DISPLAY->PushMatrix(); // we're actually going to do some drawing in this function - - // Somthing below may set m_pTempState to tempState - m_pTempState = &m_current; - - // set temporary drawing properties based on Effects - static TweenState tempState; - - // todo: account for SSC_FUTURES -aj - if( m_Effect == no_effect ) - { - } - else - { - m_pTempState = &tempState; - tempState = m_current; - - const float fTotalPeriod = GetEffectPeriod(); - ASSERT( fTotalPeriod > 0 ); - const float fTimeIntoEffect = fmodfp( m_fSecsIntoEffect+m_fEffectOffset, fTotalPeriod ); - - float fPercentThroughEffect; - if( fTimeIntoEffect < m_fEffectRampUp ) - { - fPercentThroughEffect = SCALE( - fTimeIntoEffect, - 0, - m_fEffectRampUp, - 0.0f, - 0.5f ); - } - else if( fTimeIntoEffect < m_fEffectRampUp + m_fEffectHoldAtHalf ) - { - fPercentThroughEffect = 0.5f; - } - else if( fTimeIntoEffect < m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown ) - { - fPercentThroughEffect = SCALE( - fTimeIntoEffect, - m_fEffectRampUp + m_fEffectHoldAtHalf, - m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown, - 0.5f, - 1.0f ); - } - else - { - fPercentThroughEffect = 0; - } - ASSERT_M( fPercentThroughEffect >= 0 && fPercentThroughEffect <= 1, - ssprintf("PercentThroughEffect: %f", fPercentThroughEffect) ); - - bool bBlinkOn = fPercentThroughEffect > 0.5f; - float fPercentBetweenColors = RageFastSin( (fPercentThroughEffect + 0.25f) * 2 * PI ) / 2 + 0.5f; - ASSERT_M( fPercentBetweenColors >= 0 && fPercentBetweenColors <= 1, - ssprintf("PercentBetweenColors: %f, PercentThroughEffect: %f", fPercentBetweenColors, fPercentThroughEffect) ); - float fOriginalAlpha = tempState.diffuse[0].a; - - // todo: account for SSC_FUTURES -aj - switch( m_Effect ) - { - case diffuse_blink: - /* XXX: Should diffuse_blink and diffuse_shift multiply the tempState color? - * (That would have the same effect with 1,1,1,1, and allow tweening the diffuse - * while blinking and shifting.) */ - for(int i=0; i<4; i++) - { - tempState.diffuse[i] = bBlinkOn ? m_effectColor1 : m_effectColor2; - tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing - } - break; - case diffuse_shift: - for(int i=0; i<4; i++) - { - tempState.diffuse[i] = m_effectColor1*fPercentBetweenColors + m_effectColor2*(1.0f-fPercentBetweenColors); - tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing - } - break; - case diffuse_ramp: - for(int i=0; i<4; i++) - { - tempState.diffuse[i] = m_effectColor1*fPercentThroughEffect + m_effectColor2*(1.0f-fPercentThroughEffect); - tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing - } - break; - case glow_blink: - tempState.glow = bBlinkOn ? m_effectColor1 : m_effectColor2; - tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! - break; - case glow_shift: - tempState.glow = m_effectColor1*fPercentBetweenColors + m_effectColor2*(1.0f-fPercentBetweenColors); - tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! - break; - case glow_ramp: - tempState.glow = m_effectColor1*fPercentThroughEffect + m_effectColor2*(1.0f-fPercentThroughEffect); - tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! - break; - case rainbow: - tempState.diffuse[0] = RageColor( - RageFastCos( fPercentBetweenColors*2*PI ) * 0.5f + 0.5f, - RageFastCos( fPercentBetweenColors*2*PI + PI * 2.0f / 3.0f ) * 0.5f + 0.5f, - RageFastCos( fPercentBetweenColors*2*PI + PI * 4.0f / 3.0f) * 0.5f + 0.5f, - fOriginalAlpha ); - for( int i=1; i<4; i++ ) - tempState.diffuse[i] = tempState.diffuse[0]; - break; - case wag: - tempState.rotation += m_vEffectMagnitude * RageFastSin( fPercentThroughEffect * 2.0f * PI ); - break; - case spin: - // nothing needs to be here - break; - case vibrate: - tempState.pos.x += m_vEffectMagnitude.x * randomf(-1.0f, 1.0f) * GetZoom(); - tempState.pos.y += m_vEffectMagnitude.y * randomf(-1.0f, 1.0f) * GetZoom(); - tempState.pos.z += m_vEffectMagnitude.z * randomf(-1.0f, 1.0f) * GetZoom(); - break; - case bounce: - { - float fPercentOffset = RageFastSin( fPercentThroughEffect*PI ); - tempState.pos += m_vEffectMagnitude * fPercentOffset; - tempState.pos.x = roundf( tempState.pos.x ); - tempState.pos.y = roundf( tempState.pos.y ); - tempState.pos.z = roundf( tempState.pos.z ); - } - break; - case bob: - { - float fPercentOffset = RageFastSin( fPercentThroughEffect*PI*2 ); - tempState.pos += m_vEffectMagnitude * fPercentOffset; - tempState.pos.x = roundf( tempState.pos.x ); - tempState.pos.y = roundf( tempState.pos.y ); - tempState.pos.z = roundf( tempState.pos.z ); - } - break; - case pulse: - { - float fMinZoom = m_vEffectMagnitude[0]; - float fMaxZoom = m_vEffectMagnitude[1]; - float fPercentOffset = RageFastSin( fPercentThroughEffect*PI ); - float fZoom = SCALE( fPercentOffset, 0.f, 1.f, fMinZoom, fMaxZoom ); - tempState.scale *= fZoom; - - // Use the color as a Vector3 to scale the effect for added control - RageColor c = SCALE( fPercentOffset, 0.f, 1.f, m_effectColor1, m_effectColor2 ); - tempState.scale.x *= c.r; - tempState.scale.y *= c.g; - tempState.scale.z *= c.b; - } - break; - default: - FAIL_M(ssprintf("Invalid effect: %i", m_Effect)); - } - } - - if( m_fBaseAlpha != 1 ) - { - if( m_pTempState != &tempState ) - { - m_pTempState = &tempState; - tempState = m_current; - } - - for( int i=0; i<4; i++ ) - tempState.diffuse[i].a *= m_fBaseAlpha; - } - - if( m_pTempState->pos.x != 0 || m_pTempState->pos.y != 0 || m_pTempState->pos.z != 0 ) - { - RageMatrix m; - RageMatrixTranslate( - &m, - m_pTempState->pos.x, - m_pTempState->pos.y, - m_pTempState->pos.z - ); - DISPLAY->PreMultMatrix( m ); - } - - { - /* The only time rotation and quat should normally be used simultaneously - * is for m_baseRotation. Most objects aren't rotated at all, so optimize - * that case. */ - const float fRotateX = m_pTempState->rotation.x + m_baseRotation.x; - const float fRotateY = m_pTempState->rotation.y + m_baseRotation.y; - const float fRotateZ = m_pTempState->rotation.z + m_baseRotation.z; - - if( fRotateX != 0 || fRotateY != 0 || fRotateZ != 0 ) - { - RageMatrix m; - RageMatrixRotationXYZ( &m, fRotateX, fRotateY, fRotateZ ); - DISPLAY->PreMultMatrix( m ); - } - } - - // handle scaling - { - const float fScaleX = m_pTempState->scale.x * m_baseScale.x; - const float fScaleY = m_pTempState->scale.y * m_baseScale.y; - const float fScaleZ = m_pTempState->scale.z * m_baseScale.z; - - if( fScaleX != 1 || fScaleY != 1 || fScaleZ != 1 ) - { - RageMatrix m; - RageMatrixScale( - &m, - fScaleX, - fScaleY, - fScaleZ ); - DISPLAY->PreMultMatrix( m ); - } - } - - // handle alignment; most actors have default alignment. - if( unlikely(m_fHorizAlign != 0.5f || m_fVertAlign != 0.5f) ) - { - float fX = SCALE( m_fHorizAlign, 0.0f, 1.0f, +m_size.x/2.0f, -m_size.x/2.0f ); - float fY = SCALE( m_fVertAlign, 0.0f, 1.0f, +m_size.y/2.0f, -m_size.y/2.0f ); - RageMatrix m; - RageMatrixTranslate( - &m, - fX, - fY, - 0 - ); - DISPLAY->PreMultMatrix( m ); - } - - if( m_pTempState->quat.x != 0 || m_pTempState->quat.y != 0 || m_pTempState->quat.z != 0 || m_pTempState->quat.w != 1 ) - { - RageMatrix mat; - RageMatrixFromQuat( &mat, m_pTempState->quat ); - - DISPLAY->MultMatrix(mat); - } - - // handle skews - if( m_pTempState->fSkewX != 0 ) - { - DISPLAY->SkewX( m_pTempState->fSkewX ); - } - - if( m_pTempState->fSkewY != 0 ) - { - DISPLAY->SkewY( m_pTempState->fSkewY ); - } - -} - -void Actor::SetGlobalRenderStates() -{ - // set Actor-defined render states - if( !g_bShowMasks.Get() || m_BlendMode != BLEND_NO_EFFECT ) - DISPLAY->SetBlendMode( m_BlendMode ); - DISPLAY->SetZWrite( m_bZWrite ); - DISPLAY->SetZTestMode( m_ZTestMode ); - - // BLEND_NO_EFFECT is used to draw masks to the Z-buffer, which always wants - // Z-bias enabled. - if( m_fZBias == 0 && m_BlendMode == BLEND_NO_EFFECT ) - DISPLAY->SetZBias( 1.0f ); - else - DISPLAY->SetZBias( m_fZBias ); - - if( m_bClearZBuffer ) - DISPLAY->ClearZBuffer(); - DISPLAY->SetCullMode( m_CullMode ); -} - -void Actor::SetTextureRenderStates() -{ - DISPLAY->SetTextureWrapping( TextureUnit_1, m_bTextureWrapping ); - DISPLAY->SetTextureFiltering( TextureUnit_1, m_bTextureFiltering ); -} - -void Actor::EndDraw() -{ - DISPLAY->PopMatrix(); - m_pTempState = NULL; -} - -void Actor::UpdateTweening( float fDeltaTime ) -{ - while( 1 ) - { - if( m_Tweens.empty() ) // nothing to do - return; - - if( fDeltaTime == 0 ) // nothing will change - return; - - // update current tween state - // earliest tween - TweenState &TS = m_Tweens[0]->state; - TweenInfo &TI = m_Tweens[0]->info; - - bool bBeginning = TI.m_fTimeLeftInTween == TI.m_fTweenTime; - - float fSecsToSubtract = min( TI.m_fTimeLeftInTween, fDeltaTime ); - TI.m_fTimeLeftInTween -= fSecsToSubtract; - fDeltaTime -= fSecsToSubtract; - - RString sCommand = TI.m_sCommandName; - if( bBeginning ) // we are just beginning this tween - m_start = m_current; // set the start position - - if( TI.m_fTimeLeftInTween == 0 ) // Current tween is over. Stop. - { - m_current = TS; - - // delete the head tween - delete m_Tweens.front(); - m_Tweens.erase( m_Tweens.begin() ); - } - else // in the middle of tweening. Recalcute the current position. - { - const float fPercentThroughTween = 1-(TI.m_fTimeLeftInTween / TI.m_fTweenTime); - - // distort the percentage if appropriate - float fPercentAlongPath = TI.m_pTween->Tween( fPercentThroughTween ); - TweenState::MakeWeightedAverage( m_current, m_start, TS, fPercentAlongPath ); - } - - if( bBeginning ) - { - // Execute the command in this tween (if any). Do this last, and don't - // access TI or TS after, since this may modify the tweening queue. - if( !sCommand.empty() ) - { - if( sCommand.Left(1) == "!" ) - MESSAGEMAN->Broadcast( sCommand.substr(1) ); - else - this->PlayCommand( sCommand ); - } - } - } -} - -bool Actor::IsFirstUpdate() const -{ - return m_bFirstUpdate; -} - -void Actor::Update( float fDeltaTime ) -{ -// LOG->Trace( "Actor::Update( %f )", fDeltaTime ); - ASSERT_M( fDeltaTime >= 0, ssprintf("DeltaTime: %f",fDeltaTime) ); - - if( m_fHibernateSecondsLeft > 0 ) - { - m_fHibernateSecondsLeft -= fDeltaTime; - if( m_fHibernateSecondsLeft > 0 ) - return; - - // Grab the leftover time. - fDeltaTime = -m_fHibernateSecondsLeft; - m_fHibernateSecondsLeft = 0; - } - - this->UpdateInternal( fDeltaTime ); -} - -void Actor::UpdateInternal( float fDeltaTime ) -{ - if( m_bFirstUpdate ) - m_bFirstUpdate = false; - - 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; - } - - // update effect - // todo: account for SSC_FUTURES -aj - switch( m_Effect ) - { - case spin: - m_current.rotation += m_fEffectDelta*m_vEffectMagnitude; - wrap( m_current.rotation.x, 360 ); - wrap( m_current.rotation.y, 360 ); - wrap( m_current.rotation.z, 360 ); - break; - default: break; - } - - UpdateTweening( fDeltaTime ); -} - -RString Actor::GetLineage() const -{ - RString sPath; - - if( m_pParent ) - sPath = m_pParent->GetLineage() + '/'; - sPath += ssprintf( "<%s> %s", typeid(*this).name(), m_sName.c_str() ); - return sPath; -} - -void Actor::BeginTweening( float time, ITween *pTween ) -{ - ASSERT( time >= 0 ); - - time = max( time, 0 ); - - // If the number of tweens to ever gets this large, there's probably an infinitely - // recursing ActorCommand. - if( m_Tweens.size() > 50 ) - { - RString sError = ssprintf( "Tween overflow: \"%s\"; infinitely recursing ActorCommand?", GetLineage().c_str() ); - - LOG->Warn( "%s", sError.c_str() ); - Dialog::OK( sError ); - FinishTweening(); - } - - // add a new TweenState to the tail, and initialize it - m_Tweens.push_back( new TweenStateAndInfo ); - - // latest - TweenState &TS = m_Tweens.back()->state; - TweenInfo &TI = m_Tweens.back()->info; - - if( m_Tweens.size() >= 2 ) // if there was already a TS on the stack - { - // initialize the new TS from the last TS in the list - TS = m_Tweens[m_Tweens.size()-2]->state; - } - else - { - // This new TS is the only TS. - // Set our tween starting and ending values to the current position. - TS = m_current; - } - - TI.m_pTween = pTween; - TI.m_fTweenTime = time; - TI.m_fTimeLeftInTween = time; -} - -void Actor::BeginTweening( float time, TweenType tt ) -{ - ITween *pTween = ITween::CreateFromType( tt ); - BeginTweening( time, pTween ); -} - -void Actor::StopTweening() -{ - for( unsigned i = 0; i < m_Tweens.size(); ++i ) - delete m_Tweens[i]; - m_Tweens.clear(); -} - -void Actor::FinishTweening() -{ - if( !m_Tweens.empty() ) - m_current = DestTweenState(); - StopTweening(); -} - -void Actor::HurryTweening( float factor ) -{ - for( unsigned i = 0; i < m_Tweens.size(); ++i ) - { - m_Tweens[i]->info.m_fTimeLeftInTween *= factor; - m_Tweens[i]->info.m_fTweenTime *= factor; - } -} - -void Actor::ScaleTo( const RectF &rect, StretchType st ) -{ - // width and height of rectangle - float rect_width = rect.GetWidth(); - float rect_height = rect.GetHeight(); - - if( rect_width < 0 ) SetRotationY( 180 ); - if( rect_height < 0 ) SetRotationX( 180 ); - - // zoom fActor needed to scale the Actor to fill the rectangle - float fNewZoomX = fabsf(rect_width / m_size.x); - float fNewZoomY = fabsf(rect_height / m_size.y); - - float fNewZoom = 0.f; - switch( st ) - { - case cover: - fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomX : fNewZoomY; // use larger zoom - break; - case fit_inside: - fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomY : fNewZoomX; // use smaller zoom - break; - } - - SetX( rect.left + rect_width * m_fHorizAlign ); - SetY( rect.top + rect_height * m_fVertAlign ); - - SetZoom( fNewZoom ); -} - -void Actor::SetEffectClockString( const RString &s ) -{ - if (s.EqualsNoCase("timer")) this->SetEffectClock( CLOCK_TIMER ); - if (s.EqualsNoCase("timerglobal")) this->SetEffectClock( CLOCK_TIMER_GLOBAL ); - else if(s.EqualsNoCase("beat")) this->SetEffectClock( CLOCK_BGM_BEAT ); - else if(s.EqualsNoCase("music")) this->SetEffectClock( CLOCK_BGM_TIME ); - else if(s.EqualsNoCase("bgm")) this->SetEffectClock( CLOCK_BGM_BEAT ); // compat, deprecated - else if(s.EqualsNoCase("musicnooffset"))this->SetEffectClock( CLOCK_BGM_TIME_NO_OFFSET ); - else if(s.EqualsNoCase("beatnooffset")) this->SetEffectClock( CLOCK_BGM_BEAT_NO_OFFSET ); - else - { - CabinetLight cl = StringToCabinetLight( s ); - if( cl == CabinetLight_Invalid ) - FAIL_M(ssprintf("Invalid cabinet light: %s", s.c_str())); - - this->SetEffectClock( (EffectClock) (cl + CLOCK_LIGHT_1) ); - } -} - -void Actor::StretchTo( const RectF &r ) -{ - // width and height of rectangle - float width = r.GetWidth(); - float height = r.GetHeight(); - - // center of the rectangle - float cx = r.left + width/2.0f; - float cy = r.top + height/2.0f; - - // zoom fActor needed to scale the Actor to fill the rectangle - float fNewZoomX = width / m_size.x; - float fNewZoomY = height / m_size.y; - - SetXY( cx, cy ); - SetZoomX( fNewZoomX ); - SetZoomY( fNewZoomY ); -} - - -void Actor::SetEffectPeriod( float fTime ) -{ - ASSERT( fTime > 0 ); - m_fEffectRampUp = fTime/2; - m_fEffectHoldAtHalf = 0; - m_fEffectRampDown = fTime/2; - m_fEffectHoldAtZero = 0; -} - -float Actor::GetEffectPeriod() const -{ - return m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown + m_fEffectHoldAtZero; -} - -void Actor::SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, float fAtZero ) -{ - m_fEffectRampUp = fRampUp; - m_fEffectHoldAtHalf = fAtHalf; - m_fEffectRampDown = fRampDown; - m_fEffectHoldAtZero = fAtZero; - ASSERT( GetEffectPeriod() > 0 ); -} - -// effect "macros" - -void Actor::SetEffectDiffuseBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != diffuse_blink ) - { - m_Effect = diffuse_blink; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectDiffuseShift( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != diffuse_shift ) - { - m_Effect = diffuse_shift; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectDiffuseRamp( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != diffuse_ramp ) - { - m_Effect = diffuse_ramp; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectGlowBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != glow_blink ) - { - m_Effect = glow_blink; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectGlowShift( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != glow_shift ) - { - m_Effect = glow_shift; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectGlowRamp( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != glow_ramp ) - { - m_Effect = glow_ramp; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); - m_effectColor1 = c1; - m_effectColor2 = c2; -} - -void Actor::SetEffectRainbow( float fEffectPeriodSeconds ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != rainbow ) - { - m_Effect = rainbow; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fEffectPeriodSeconds ); -} - -void Actor::SetEffectWag( float fPeriod, RageVector3 vect ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect != wag ) - { - m_Effect = wag; - m_fSecsIntoEffect = 0; - } - SetEffectPeriod( fPeriod ); - m_vEffectMagnitude = vect; -} - -void Actor::SetEffectBounce( float fPeriod, RageVector3 vect ) -{ - // todo: account for SSC_FUTURES -aj - m_Effect = bounce; - SetEffectPeriod( fPeriod ); - m_vEffectMagnitude = vect; - m_fSecsIntoEffect = 0; -} - -void Actor::SetEffectBob( float fPeriod, RageVector3 vect ) -{ - // todo: account for SSC_FUTURES -aj - if( m_Effect!=bob || GetEffectPeriod() != fPeriod ) - { - m_Effect = bob; - SetEffectPeriod( fPeriod ); - m_fSecsIntoEffect = 0; - } - m_vEffectMagnitude = vect; -} - -void Actor::SetEffectSpin( RageVector3 vect ) -{ - // todo: account for SSC_FUTURES -aj - m_Effect = spin; - m_vEffectMagnitude = vect; -} - -void Actor::SetEffectVibrate( RageVector3 vect ) -{ - // todo: account for SSC_FUTURES -aj - m_Effect = vibrate; - m_vEffectMagnitude = vect; -} - -void Actor::SetEffectPulse( float fPeriod, float fMinZoom, float fMaxZoom ) -{ - // todo: account for SSC_FUTURES -aj - m_Effect = pulse; - SetEffectPeriod( fPeriod ); - m_vEffectMagnitude[0] = fMinZoom; - m_vEffectMagnitude[1] = fMaxZoom; -} - - -void Actor::AddRotationH( float rot ) -{ - RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromH(rot) ); -} - -void Actor::AddRotationP( float rot ) -{ - RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromP(rot) ); -} - -void Actor::AddRotationR( float rot ) -{ - RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromR(rot) ); -} - -void Actor::RunCommands( const LuaReference& cmds, const LuaReference *pParamTable ) -{ - Lua *L = LUA->Get(); - - // function - cmds.PushSelf( L ); - ASSERT( !lua_isnil(L, -1) ); - - // 1st parameter - this->PushSelf( L ); - - // 2nd parameter - if( pParamTable == NULL ) - lua_pushnil( L ); - else - pParamTable->PushSelf( L ); - - // call function with 2 arguments and 0 results - RString sError; - if( !LuaHelpers::RunScriptOnStack(L, sError, 2, 0) ) - LOG->Warn( "Error playing command: %s", sError.c_str() ); - - LUA->Release(L); -} - -float Actor::GetTweenTimeLeft() const -{ - float tot = 0; - - tot += m_fHibernateSecondsLeft; - - for( unsigned i=0; iinfo.m_fTimeLeftInTween; - - return tot; -} - -/* This is a hack to change all tween states while leaving existing tweens alone. - * - * Hmm. Most commands actually act on a TweenStateAndInfo, not the Actor itself. - * Conceptually, it wouldn't be hard to give TweenState a presence in Lua, so - * we can simply say eg. "for x in states(Actor) do x.SetDiffuseColor(c) end". - * However, we'd then have to give every TweenState a userdata in Lua while it's - * being manipulated, which would add overhead ... */ -void Actor::SetGlobalDiffuseColor( RageColor c ) -{ - for( int i=0; i<4; i++ ) // color, not alpha - { - for( unsigned ts = 0; ts < m_Tweens.size(); ++ts ) - { - m_Tweens[ts]->state.diffuse[i].r = c.r; - m_Tweens[ts]->state.diffuse[i].g = c.g; - m_Tweens[ts]->state.diffuse[i].b = c.b; - } - m_current.diffuse[i].r = c.r; - m_current.diffuse[i].g = c.g; - m_current.diffuse[i].b = c.b; - m_start.diffuse[i].r = c.r; - m_start.diffuse[i].g = c.g; - m_start.diffuse[i].b = c.b; - } -} - -void Actor::SetDiffuseColor( RageColor c ) -{ - for( int i=0; i<4; i++ ) - { - DestTweenState().diffuse[i].r = c.r; - DestTweenState().diffuse[i].g = c.g; - DestTweenState().diffuse[i].b = c.b; - } -} - - -void Actor::TweenState::Init() -{ - pos = RageVector3( 0, 0, 0 ); - rotation = RageVector3( 0, 0, 0 ); - quat = RageVector4( 0, 0, 0, 1 ); - scale = RageVector3( 1, 1, 1 ); - fSkewX = 0; - fSkewY = 0; - crop = RectF( 0,0,0,0 ); - fade = RectF( 0,0,0,0 ); - for( int i=0; i<4; i++ ) - diffuse[i] = RageColor( 1, 1, 1, 1 ); - glow = RageColor( 1, 1, 1, 0 ); - aux = 0; -} - -bool Actor::TweenState::operator==( const TweenState &other ) const -{ -#define COMPARE( x ) if( x != other.x ) return false; - COMPARE( pos ); - COMPARE( rotation ); - COMPARE( quat ); - COMPARE( scale ); - COMPARE( fSkewX ); - COMPARE( fSkewY ); - COMPARE( crop ); - COMPARE( fade ); - for( unsigned i=0; iinfo; - TI.m_sCommandName = sCommandName; -} - -void Actor::QueueMessage( const RString& sMessageName ) -{ - // Hack: use "!" as a marker to broadcast a command, instead of playing a - // command, so we don't have to add yet another element to every tween - // state for this rarely-used command. - BeginTweening( 0, TWEEN_LINEAR ); - TweenInfo &TI = m_Tweens.back()->info; - TI.m_sCommandName = "!" + sMessageName; -} - -void Actor::AddCommand( const RString &sCmdName, apActorCommands apac ) -{ - if( HasCommand(sCmdName) ) - { - RString sWarning = GetLineage()+"'s command '"+sCmdName+"' defined twice"; - Dialog::OK( sWarning, "COMMAND_DEFINED_TWICE" ); - } - - RString sMessage; - if( GetMessageNameFromCommandName(sCmdName, sMessage) ) - { - SubscribeToMessage( sMessage ); - m_mapNameToCommands[sMessage] = apac; // sCmdName w/o "Message" at the end - } - else - { - m_mapNameToCommands[sCmdName] = apac; - } -} - -bool Actor::HasCommand( const RString &sCmdName ) const -{ - return GetCommand(sCmdName) != NULL; -} - -const apActorCommands *Actor::GetCommand( const RString &sCommandName ) const -{ - map::const_iterator it = m_mapNameToCommands.find( sCommandName ); - if( it == m_mapNameToCommands.end() ) - return NULL; - return &it->second; -} - -void Actor::HandleMessage( const Message &msg ) -{ - PlayCommandNoRecurse( msg ); -} - -void Actor::PlayCommandNoRecurse( const Message &msg ) -{ - const apActorCommands *pCmd = GetCommand( msg.GetName() ); - if( pCmd != NULL ) - RunCommands( *pCmd, &msg.GetParamTable() ); -} - -void Actor::PushContext( lua_State *L ) -{ - // self.ctx should already exist - m_pLuaInstance->PushSelf( L ); - lua_getfield( L, -1, "ctx" ); - lua_remove( L, -2 ); -} - -void Actor::SetParent( Actor *pParent ) -{ - m_pParent = pParent; - - Lua *L = LUA->Get(); - int iTop = lua_gettop( L ); - - this->PushContext( L ); - lua_pushstring( L, "__index" ); - pParent->PushContext( L ); - lua_settable( L, -3 ); - - lua_settop( L, iTop ); - LUA->Release( L ); -} - -Actor::TweenInfo::TweenInfo() -{ - m_pTween = NULL; -} - -Actor::TweenInfo::~TweenInfo() -{ - delete m_pTween; -} - -Actor::TweenInfo::TweenInfo( const TweenInfo &cpy ) -{ - m_pTween = NULL; - *this = cpy; -} - -Actor::TweenInfo &Actor::TweenInfo::operator=( const TweenInfo &rhs ) -{ - delete m_pTween; - m_pTween = (rhs.m_pTween? rhs.m_pTween->Copy():NULL); - m_fTimeLeftInTween = rhs.m_fTimeLeftInTween; - m_fTweenTime = rhs.m_fTweenTime; - m_sCommandName = rhs.m_sCommandName; - return *this; -} - -// lua start -#include "LuaBinding.h" - -/** @brief Allow Lua to have access to the Actor. */ -class LunaActor : public Luna -{ -public: - static int name( T* p, lua_State *L ) { p->SetName(SArg(1)); return 0; } - static int sleep( T* p, lua_State *L ) { p->Sleep(FArg(1)); return 0; } - static int linear( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_LINEAR); return 0; } - static int accelerate( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_ACCELERATE); return 0; } - static int decelerate( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_DECELERATE); return 0; } - static int spring( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_SPRING); return 0; } - static int tween( T* p, lua_State *L ) - { - ITween *pTween = ITween::CreateFromStack( L, 2 ); - p->BeginTweening( FArg(1), pTween ); - return 0; - } - static int stoptweening( T* p, lua_State * ) { p->StopTweening(); return 0; } - static int finishtweening( T* p, lua_State * ) { p->FinishTweening(); return 0; } - static int hurrytweening( T* p, lua_State *L ) { p->HurryTweening(FArg(1)); return 0; } - static int GetTweenTimeLeft( T* p, lua_State *L ) { lua_pushnumber( L, p->GetTweenTimeLeft() ); return 1; } - static int x( T* p, lua_State *L ) { p->SetX(FArg(1)); return 0; } - static int y( T* p, lua_State *L ) { p->SetY(FArg(1)); return 0; } - static int z( T* p, lua_State *L ) { p->SetZ(FArg(1)); return 0; } - static int xy( T* p, lua_State *L ) { p->SetXY(FArg(1),FArg(2)); return 0; } - static int addx( T* p, lua_State *L ) { p->AddX(FArg(1)); return 0; } - static int addy( T* p, lua_State *L ) { p->AddY(FArg(1)); return 0; } - static int addz( T* p, lua_State *L ) { p->AddZ(FArg(1)); return 0; } - static int zoom( T* p, lua_State *L ) { p->SetZoom(FArg(1)); return 0; } - static int zoomx( T* p, lua_State *L ) { p->SetZoomX(FArg(1)); return 0; } - static int zoomy( T* p, lua_State *L ) { p->SetZoomY(FArg(1)); return 0; } - static int zoomz( T* p, lua_State *L ) { p->SetZoomZ(FArg(1)); return 0; } - static int zoomto( T* p, lua_State *L ) { p->ZoomTo(FArg(1), FArg(2)); return 0; } - static int zoomtowidth( T* p, lua_State *L ) { p->ZoomToWidth(FArg(1)); return 0; } - static int zoomtoheight( T* p, lua_State *L ) { p->ZoomToHeight(FArg(1)); return 0; } - static int setsize( T* p, lua_State *L ) { p->SetWidth(FArg(1)); p->SetHeight(FArg(2)); return 0; } - static int SetWidth( T* p, lua_State *L ) { p->SetWidth(FArg(1)); return 0; } - static int SetHeight( T* p, lua_State *L ) { p->SetHeight(FArg(1)); return 0; } - static int basealpha( T* p, lua_State *L ) { p->SetBaseAlpha(FArg(1)); return 0; } - static int basezoom( T* p, lua_State *L ) { p->SetBaseZoom(FArg(1)); return 0; } - static int basezoomx( T* p, lua_State *L ) { p->SetBaseZoomX(FArg(1)); return 0; } - static int basezoomy( T* p, lua_State *L ) { p->SetBaseZoomY(FArg(1)); return 0; } - static int basezoomz( T* p, lua_State *L ) { p->SetBaseZoomZ(FArg(1)); return 0; } - static int stretchto( T* p, lua_State *L ) { p->StretchTo( RectF(FArg(1),FArg(2),FArg(3),FArg(4)) ); return 0; } - static int cropleft( T* p, lua_State *L ) { p->SetCropLeft(FArg(1)); return 0; } - static int croptop( T* p, lua_State *L ) { p->SetCropTop(FArg(1)); return 0; } - static int cropright( T* p, lua_State *L ) { p->SetCropRight(FArg(1)); return 0; } - static int cropbottom( T* p, lua_State *L ) { p->SetCropBottom(FArg(1)); return 0; } - static int fadeleft( T* p, lua_State *L ) { p->SetFadeLeft(FArg(1)); return 0; } - static int fadetop( T* p, lua_State *L ) { p->SetFadeTop(FArg(1)); return 0; } - static int faderight( T* p, lua_State *L ) { p->SetFadeRight(FArg(1)); return 0; } - static int fadebottom( T* p, lua_State *L ) { p->SetFadeBottom(FArg(1)); return 0; } - static int diffuse( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuse( c ); return 0; } - static int diffuseupperleft( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseUpperLeft( c ); return 0; } - static int diffuseupperright( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseUpperRight( c ); return 0; } - static int diffuselowerleft( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLowerLeft( c ); return 0; } - static int diffuselowerright( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLowerRight( c ); return 0; } - static int diffuseleftedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLeftEdge( c ); return 0; } - static int diffuserightedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseRightEdge( c ); return 0; } - static int diffusetopedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseTopEdge( c ); return 0; } - static int diffusebottomedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseBottomEdge( c ); return 0; } - static int diffusealpha( T* p, lua_State *L ) { p->SetDiffuseAlpha(FArg(1)); return 0; } - static int diffusecolor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseColor( c ); return 0; } - static int glow( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetGlow( c ); return 0; } - static int aux( T* p, lua_State *L ) { p->SetAux( FArg(1) ); return 0; } - static int getaux( T* p, lua_State *L ) { lua_pushnumber( L, p->GetAux() ); return 1; } - static int rotationx( T* p, lua_State *L ) { p->SetRotationX(FArg(1)); return 0; } - static int rotationy( T* p, lua_State *L ) { p->SetRotationY(FArg(1)); return 0; } - static int rotationz( T* p, lua_State *L ) { p->SetRotationZ(FArg(1)); return 0; } - static int addrotationx( T* p, lua_State *L ) { p->AddRotationX(FArg(1)); return 0; } - static int addrotationy( T* p, lua_State *L ) { p->AddRotationY(FArg(1)); return 0; } - static int addrotationz( T* p, lua_State *L ) { p->AddRotationZ(FArg(1)); return 0; } - static int getrotation( T* p, lua_State *L ) { lua_pushnumber(L, p->GetRotationX()); lua_pushnumber(L, p->GetRotationY()); lua_pushnumber(L, p->GetRotationZ()); return 3; } - static int baserotationx( T* p, lua_State *L ) { p->SetBaseRotationX(FArg(1)); return 0; } - static int baserotationy( T* p, lua_State *L ) { p->SetBaseRotationY(FArg(1)); return 0; } - static int baserotationz( T* p, lua_State *L ) { p->SetBaseRotationZ(FArg(1)); return 0; } - static int skewx( T* p, lua_State *L ) { p->SetSkewX(FArg(1)); return 0; } - static int skewy( T* p, lua_State *L ) { p->SetSkewY(FArg(1)); return 0; } - static int heading( T* p, lua_State *L ) { p->AddRotationH(FArg(1)); return 0; } - static int pitch( T* p, lua_State *L ) { p->AddRotationP(FArg(1)); return 0; } - static int roll( T* p, lua_State *L ) { p->AddRotationR(FArg(1)); return 0; } - static int shadowlength( T* p, lua_State *L ) { p->SetShadowLength(FArg(1)); return 0; } - static int shadowlengthx( T* p, lua_State *L ) { p->SetShadowLengthX(FArg(1)); return 0; } - static int shadowlengthy( T* p, lua_State *L ) { p->SetShadowLengthY(FArg(1)); return 0; } - static int shadowcolor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetShadowColor( c ); return 0; } - static int horizalign( T* p, lua_State *L ) { p->SetHorizAlign(Enum::Check(L, 1)); return 0; } - static int vertalign( T* p, lua_State *L ) { p->SetVertAlign(Enum::Check(L, 1)); return 0; } - static int halign( T* p, lua_State *L ) { p->SetHorizAlign(FArg(1)); return 0; } - static int valign( T* p, lua_State *L ) { p->SetVertAlign(FArg(1)); return 0; } - static int diffuseblink( T* p, lua_State * ) { p->SetEffectDiffuseBlink(); return 0; } - static int diffuseshift( T* p, lua_State * ) { p->SetEffectDiffuseShift(); return 0; } - static int diffuseramp( T* p, lua_State * ) { p->SetEffectDiffuseRamp(); return 0; } - static int glowblink( T* p, lua_State * ) { p->SetEffectGlowBlink(); return 0; } - static int glowshift( T* p, lua_State * ) { p->SetEffectGlowShift(); return 0; } - static int glowramp( T* p, lua_State * ) { p->SetEffectGlowRamp(); return 0; } - static int rainbow( T* p, lua_State * ) { p->SetEffectRainbow(); return 0; } - static int wag( T* p, lua_State * ) { p->SetEffectWag(); return 0; } - static int bounce( T* p, lua_State * ) { p->SetEffectBounce(); return 0; } - static int bob( T* p, lua_State * ) { p->SetEffectBob(); return 0; } - static int pulse( T* p, lua_State * ) { p->SetEffectPulse(); return 0; } - static int spin( T* p, lua_State * ) { p->SetEffectSpin(); return 0; } - static int vibrate( T* p, lua_State * ) { p->SetEffectVibrate(); return 0; } - static int stopeffect( T* p, lua_State * ) { p->StopEffect(); return 0; } - static int effectcolor1( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetEffectColor1( c ); return 0; } - static int effectcolor2( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetEffectColor2( c ); return 0; } - static int effectperiod( T* p, lua_State *L ) { p->SetEffectPeriod(FArg(1)); return 0; } - static int effecttiming( T* p, lua_State *L ) { p->SetEffectTiming(FArg(1),FArg(2),FArg(3),FArg(4)); return 0; } - static int effectoffset( T* p, lua_State *L ) { p->SetEffectOffset(FArg(1)); return 0; } - static int effectclock( T* p, lua_State *L ) { p->SetEffectClockString(SArg(1)); return 0; } - static int effectmagnitude( T* p, lua_State *L ) { p->SetEffectMagnitude( RageVector3(FArg(1),FArg(2),FArg(3)) ); return 0; } - static int geteffectmagnitude( T* p, lua_State *L ) { RageVector3 v = p->GetEffectMagnitude(); lua_pushnumber(L, v[0]); lua_pushnumber(L, v[1]); lua_pushnumber(L, v[2]); return 3; } - static int scaletocover( T* p, lua_State *L ) { p->ScaleToCover( RectF(FArg(1), FArg(2), FArg(3), FArg(4)) ); return 0; } - static int scaletofit( T* p, lua_State *L ) { p->ScaleToFitInside( RectF(FArg(1), FArg(2), FArg(3), FArg(4)) ); return 0; } - static int animate( T* p, lua_State *L ) { p->EnableAnimation(BIArg(1)); return 0; } - static int play( T* p, lua_State * ) { p->EnableAnimation(true); return 0; } - static int pause( T* p, lua_State * ) { p->EnableAnimation(false); return 0; } - static int setstate( T* p, lua_State *L ) { p->SetState(IArg(1)); return 0; } - static int GetNumStates( T* p, lua_State *L ) { LuaHelpers::Push( L, p->GetNumStates() ); return 1; } - static int texturewrapping( T* p, lua_State *L ) { p->SetTextureWrapping(BIArg(1)); return 0; } - static int SetTextureFiltering( T* p, lua_State *L ) { p->SetTextureFiltering(BArg(1)); return 0; } - static int blend( T* p, lua_State *L ) { p->SetBlendMode( Enum::Check(L, 1) ); return 0; } - static int zbuffer( T* p, lua_State *L ) { p->SetUseZBuffer(BIArg(1)); return 0; } - static int ztest( T* p, lua_State *L ) { p->SetZTestMode((BIArg(1))?ZTEST_WRITE_ON_PASS:ZTEST_OFF); return 0; } - static int ztestmode( T* p, lua_State *L ) { p->SetZTestMode( Enum::Check(L, 1) ); return 0; } - static int zwrite( T* p, lua_State *L ) { p->SetZWrite(BIArg(1)); return 0; } - static int zbias( T* p, lua_State *L ) { p->SetZBias(FArg(1)); return 0; } - static int clearzbuffer( T* p, lua_State *L ) { p->SetClearZBuffer(BIArg(1)); return 0; } - static int backfacecull( T* p, lua_State *L ) { p->SetCullMode((BIArg(1)) ? CULL_BACK : CULL_NONE); return 0; } - static int cullmode( T* p, lua_State *L ) { p->SetCullMode( Enum::Check(L, 1)); return 0; } - static int visible( T* p, lua_State *L ) { p->SetVisible(BIArg(1)); return 0; } - static int hibernate( T* p, lua_State *L ) { p->SetHibernate(FArg(1)); return 0; } - static int draworder( T* p, lua_State *L ) { p->SetDrawOrder(IArg(1)); return 0; } - static int playcommand( T* p, lua_State *L ) - { - if( !lua_istable(L, 2) && !lua_isnoneornil(L, 2) ) - luaL_typerror( L, 2, "table or nil" ); - - LuaReference ParamTable; - lua_pushvalue( L, 2 ); - ParamTable.SetFromStack( L ); - - Message msg( SArg(1), ParamTable ); - p->HandleMessage( msg ); - - return 0; - } - static int queuecommand( T* p, lua_State *L ) { p->QueueCommand(SArg(1)); return 0; } - static int queuemessage( T* p, lua_State *L ) { p->QueueMessage(SArg(1)); return 0; } - static int addcommand( T* p, lua_State *L ) - { - LuaReference *pRef = new LuaReference; - pRef->SetFromStack( L ); - p->AddCommand( SArg(1), apActorCommands(pRef) ); - return 0; - } - static int GetCommand( T* p, lua_State *L ) - { - const apActorCommands *pCommand = p->GetCommand(SArg(1)); - if( pCommand == NULL ) - lua_pushnil( L ); - else - (*pCommand)->PushSelf(L); - - return 1; - } - static int RunCommandsRecursively( T* p, lua_State *L ) - { - luaL_checktype( L, 1, LUA_TFUNCTION ); - if( !lua_istable(L, 2) && !lua_isnoneornil(L, 2) ) - luaL_typerror( L, 2, "table or nil" ); - - LuaReference ref; - lua_pushvalue( L, 1 ); - ref.SetFromStack( L ); - - LuaReference ParamTable; - lua_pushvalue( L, 2 ); - ParamTable.SetFromStack( L ); - - p->RunCommandsRecursively( ref, &ParamTable ); - return 0; - } - - static int GetX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetX() ); return 1; } - static int GetY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetY() ); return 1; } - static int GetZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZ() ); return 1; } - static int GetWidth( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnzoomedWidth() ); return 1; } - static int GetHeight( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnzoomedHeight() ); return 1; } - static int GetZoomedWidth( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomedWidth() ); return 1; } - static int GetZoomedHeight( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomedHeight() ); return 1; } - static int GetZoom( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoom() ); return 1; } - static int GetZoomX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomX() ); return 1; } - static int GetZoomY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomY() ); return 1; } - static int GetZoomZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomZ() ); return 1; } - static int GetBaseZoomX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomX() ); return 1; } - static int GetBaseZoomY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomY() ); return 1; } - static int GetBaseZoomZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomZ() ); return 1; } - static int GetRotationX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationX() ); return 1; } - static int GetRotationY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationY() ); return 1; } - static int GetRotationZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationZ() ); return 1; } - static int GetSecsIntoEffect( T* p, lua_State *L ) { lua_pushnumber( L, p->GetSecsIntoEffect() ); return 1; } - static int GetEffectDelta( T* p, lua_State *L ) { lua_pushnumber( L, p->GetEffectDelta() ); return 1; } - DEFINE_METHOD( GetDiffuse, GetDiffuse() ) - DEFINE_METHOD( GetGlow, GetGlow() ) - static int GetDiffuseAlpha( T* p, lua_State *L ) { lua_pushnumber( L, p->GetDiffuseAlpha() ); return 1; } - static int GetVisible( T* p, lua_State *L ) { lua_pushboolean( L, p->GetVisible() ); return 1; } - static int GetHAlign( T* p, lua_State *L ) { lua_pushnumber( L, p->GetHorizAlign() ); return 1; } - static int GetVAlign( T* p, lua_State *L ) { lua_pushnumber( L, p->GetVertAlign() ); return 1; } - - static int GetName( T* p, lua_State *L ) { lua_pushstring( L, p->GetName() ); return 1; } - static int GetParent( T* p, lua_State *L ) - { - Actor *pParent = p->GetParent(); - if( pParent == NULL ) - lua_pushnil( L ); - else - pParent->PushSelf(L); - return 1; - } - static int Draw( T* p, lua_State *L ) - { - LUA->YieldLua(); - p->Draw(); - LUA->UnyieldLua(); - return 0; - } - - LunaActor() - { - ADD_METHOD( name ); - ADD_METHOD( sleep ); - ADD_METHOD( linear ); - ADD_METHOD( accelerate ); - ADD_METHOD( decelerate ); - ADD_METHOD( spring ); - ADD_METHOD( tween ); - ADD_METHOD( stoptweening ); - ADD_METHOD( finishtweening ); - ADD_METHOD( hurrytweening ); - ADD_METHOD( GetTweenTimeLeft ); - ADD_METHOD( x ); - ADD_METHOD( y ); - ADD_METHOD( z ); - ADD_METHOD( xy ); - ADD_METHOD( addx ); - ADD_METHOD( addy ); - ADD_METHOD( addz ); - ADD_METHOD( zoom ); - ADD_METHOD( zoomx ); - ADD_METHOD( zoomy ); - ADD_METHOD( zoomz ); - ADD_METHOD( zoomto ); - ADD_METHOD( zoomtowidth ); - ADD_METHOD( zoomtoheight ); - ADD_METHOD( setsize ); - ADD_METHOD( SetWidth ); - ADD_METHOD( SetHeight ); - ADD_METHOD( basealpha ); - ADD_METHOD( basezoom ); - ADD_METHOD( basezoomx ); - ADD_METHOD( basezoomy ); - ADD_METHOD( basezoomz ); - ADD_METHOD( stretchto ); - ADD_METHOD( cropleft ); - ADD_METHOD( croptop ); - ADD_METHOD( cropright ); - ADD_METHOD( cropbottom ); - ADD_METHOD( fadeleft ); - ADD_METHOD( fadetop ); - ADD_METHOD( faderight ); - ADD_METHOD( fadebottom ); - ADD_METHOD( diffuse ); - ADD_METHOD( diffuseupperleft ); - ADD_METHOD( diffuseupperright ); - ADD_METHOD( diffuselowerleft ); - ADD_METHOD( diffuselowerright ); - ADD_METHOD( diffuseleftedge ); - ADD_METHOD( diffuserightedge ); - ADD_METHOD( diffusetopedge ); - ADD_METHOD( diffusebottomedge ); - ADD_METHOD( diffusealpha ); - ADD_METHOD( diffusecolor ); - ADD_METHOD( glow ); - ADD_METHOD( aux ); - ADD_METHOD( getaux ); - ADD_METHOD( rotationx ); - ADD_METHOD( rotationy ); - ADD_METHOD( rotationz ); - ADD_METHOD( addrotationx ); - ADD_METHOD( addrotationy ); - ADD_METHOD( addrotationz ); - ADD_METHOD( getrotation ); - ADD_METHOD( baserotationx ); - ADD_METHOD( baserotationy ); - ADD_METHOD( baserotationz ); - ADD_METHOD( skewx ); - ADD_METHOD( skewy ); - ADD_METHOD( heading ); - ADD_METHOD( pitch ); - ADD_METHOD( roll ); - ADD_METHOD( shadowlength ); - ADD_METHOD( shadowlengthx ); - ADD_METHOD( shadowlengthy ); - ADD_METHOD( shadowcolor ); - ADD_METHOD( horizalign ); - ADD_METHOD( vertalign ); - ADD_METHOD( halign ); - ADD_METHOD( valign ); - ADD_METHOD( diffuseblink ); - ADD_METHOD( diffuseshift ); - ADD_METHOD( diffuseramp ); - ADD_METHOD( glowblink ); - ADD_METHOD( glowshift ); - ADD_METHOD( glowramp ); - ADD_METHOD( rainbow ); - ADD_METHOD( wag ); - ADD_METHOD( bounce ); - ADD_METHOD( bob ); - ADD_METHOD( pulse ); - ADD_METHOD( spin ); - ADD_METHOD( vibrate ); - ADD_METHOD( stopeffect ); - ADD_METHOD( effectcolor1 ); - ADD_METHOD( effectcolor2 ); - ADD_METHOD( effectperiod ); - ADD_METHOD( effecttiming ); - ADD_METHOD( effectoffset ); - ADD_METHOD( effectclock ); - ADD_METHOD( effectmagnitude ); - ADD_METHOD( geteffectmagnitude ); - ADD_METHOD( scaletocover ); - ADD_METHOD( scaletofit ); - ADD_METHOD( animate ); - ADD_METHOD( play ); - ADD_METHOD( pause ); - ADD_METHOD( setstate ); - ADD_METHOD( GetNumStates ); - ADD_METHOD( texturewrapping ); - ADD_METHOD( SetTextureFiltering ); - ADD_METHOD( blend ); - ADD_METHOD( zbuffer ); - ADD_METHOD( ztest ); - ADD_METHOD( ztestmode ); - ADD_METHOD( zwrite ); - ADD_METHOD( zbias ); - ADD_METHOD( clearzbuffer ); - ADD_METHOD( backfacecull ); - ADD_METHOD( cullmode ); - ADD_METHOD( visible ); - ADD_METHOD( hibernate ); - ADD_METHOD( draworder ); - ADD_METHOD( playcommand ); - ADD_METHOD( queuecommand ); - ADD_METHOD( queuemessage ); - ADD_METHOD( addcommand ); - ADD_METHOD( GetCommand ); - ADD_METHOD( RunCommandsRecursively ); - - ADD_METHOD( GetX ); - ADD_METHOD( GetY ); - ADD_METHOD( GetZ ); - ADD_METHOD( GetWidth ); - ADD_METHOD( GetHeight ); - ADD_METHOD( GetZoomedWidth ); - ADD_METHOD( GetZoomedHeight ); - ADD_METHOD( GetZoom ); - ADD_METHOD( GetZoomX ); - ADD_METHOD( GetZoomY ); - ADD_METHOD( GetZoomZ ); - ADD_METHOD( GetRotationX ); - ADD_METHOD( GetRotationY ); - ADD_METHOD( GetRotationZ ); - ADD_METHOD( GetBaseZoomX ); - ADD_METHOD( GetBaseZoomY ); - ADD_METHOD( GetBaseZoomZ ); - ADD_METHOD( GetSecsIntoEffect ); - ADD_METHOD( GetEffectDelta ); - ADD_METHOD( GetDiffuse ); - ADD_METHOD( GetDiffuseAlpha ); - ADD_METHOD( GetGlow ); - ADD_METHOD( GetVisible ); - ADD_METHOD( GetHAlign ); - ADD_METHOD( GetVAlign ); - - ADD_METHOD( GetName ); - ADD_METHOD( GetParent ); - - ADD_METHOD( Draw ); - } -}; - -LUA_REGISTER_INSTANCED_BASE_CLASS( Actor ) -// lua end - - -/* - * (c) 2001-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "Actor.h" +#include "RageDisplay.h" +#include "RageUtil.h" +#include "RageMath.h" +#include "RageLog.h" +#include "arch/Dialog/Dialog.h" + +#include "XmlFile.h" +#include "LuaBinding.h" +#include "ThemeManager.h" +#include "LuaReference.h" +#include "MessageManager.h" +#include "LightsManager.h" // for NUM_CabinetLight +#include "ActorUtil.h" +#include "Preference.h" +#include + +static Preference g_bShowMasks("ShowMasks", false); + +/** + * @brief Set up a hidden Actor that won't be drawn. + * + * It's useful to be able to construct a basic Actor in XML, in + * order to simply delay a Transition, or receive and send broadcasts. + * Since these actors will never draw, set them hidden by default. */ +class HiddenActor: public Actor +{ +public: + HiddenActor() { SetVisible(false); } + virtual HiddenActor *Copy() const; +}; +REGISTER_ACTOR_CLASS_WITH_NAME( HiddenActor, Actor ); + +float Actor::g_fCurrentBGMTime = 0, Actor::g_fCurrentBGMBeat; +float Actor::g_fCurrentBGMTimeNoOffset = 0, Actor::g_fCurrentBGMBeatNoOffset = 0; +vector Actor::g_vfCurrentBGMBeatPlayer(NUM_PlayerNumber, 0); +vector Actor::g_vfCurrentBGMBeatPlayerNoOffset(NUM_PlayerNumber, 0); + + +Actor *Actor::Copy() const { return new Actor(*this); } + +static float g_fCabinetLights[NUM_CabinetLight]; + +static const char *HorizAlignNames[] = { + "Left", + "Center", + "Right" +}; +XToString( HorizAlign ); +LuaXType( HorizAlign ); + +static const char *VertAlignNames[] = { + "Top", + "Middle", + "Bottom" +}; +XToString( VertAlign ); +LuaXType( VertAlign ); + +void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset ) +{ + g_fCurrentBGMTime = fTime; + g_fCurrentBGMBeat = fBeat; + + /* This timer is generally only used for effects tied to the background music + * when GameSoundManager is aligning music beats. Alignment doesn't handle + * g_fVisualDelaySeconds. */ + g_fCurrentBGMTimeNoOffset = fTimeNoOffset; + g_fCurrentBGMBeatNoOffset = fBeatNoOffset; +} + +void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ) +{ + g_vfCurrentBGMBeatPlayer[pn] = fBeat; + g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset; +} + +void Actor::SetBGMLight( int iLightNumber, float fCabinetLights ) +{ + ASSERT( iLightNumber < NUM_CabinetLight ); + g_fCabinetLights[iLightNumber] = fCabinetLights; +} + +void Actor::InitState() +{ + StopTweening(); + + m_pTempState = NULL; + + m_baseRotation = RageVector3( 0, 0, 0 ); + m_baseScale = RageVector3( 1, 1, 1 ); + m_fBaseAlpha = 1; + + m_start.Init(); + m_current.Init(); + + m_fHorizAlign = 0.5f; + m_fVertAlign = 0.5f; +#if defined(SSC_FUTURES) + for( unsigned i = 0; i < m_Effects.size(); ++i ) + m_Effects[i] = no_effect; +#else + m_Effect = no_effect; +#endif + m_fSecsIntoEffect = 0; + m_fEffectDelta = 0; + m_fEffectRampUp = 0.5f; + m_fEffectHoldAtHalf = 0; + m_fEffectRampDown = 0.5f; + m_fEffectHoldAtZero = 0; + m_fEffectOffset = 0; + m_EffectClock = CLOCK_TIMER; + m_vEffectMagnitude = RageVector3(0,0,10); + m_effectColor1 = RageColor(1,1,1,1); + m_effectColor2 = RageColor(1,1,1,1); + + m_bVisible = true; + m_fShadowLengthX = 0; + m_fShadowLengthY = 0; + m_ShadowColor = RageColor(0,0,0,0.5f); + m_bIsAnimating = true; + m_fHibernateSecondsLeft = 0; + m_iDrawOrder = 0; + + m_bTextureWrapping = false; + m_bTextureFiltering = true; + + m_BlendMode = BLEND_NORMAL; + m_fZBias = 0; + m_bClearZBuffer = false; + m_ZTestMode = ZTEST_OFF; + m_bZWrite = false; + m_CullMode = CULL_NONE; +} + +static bool GetMessageNameFromCommandName( const RString &sCommandName, RString &sMessageNameOut ) +{ + if( sCommandName.Right(7) == "Message" ) + { + sMessageNameOut = sCommandName.Left(sCommandName.size()-7); + return true; + } + else + { + return false; + } +} + +Actor::Actor() +{ + m_pLuaInstance = new LuaClass; + Lua *L = LUA->Get(); + m_pLuaInstance->PushSelf( L ); + lua_newtable( L ); + lua_pushvalue( L, -1 ); + lua_setmetatable( L, -2 ); + lua_setfield( L, -2, "ctx" ); + lua_pop( L, 1 ); + LUA->Release( L ); + + m_size = RageVector2( 1, 1 ); + InitState(); + m_pParent = NULL; + m_bFirstUpdate = true; +} + +Actor::~Actor() +{ + StopTweening(); + UnsubscribeAll(); +} + +Actor::Actor( const Actor &cpy ): + MessageSubscriber( cpy ) +{ + /* Don't copy an Actor in the middle of rendering. */ + ASSERT( cpy.m_pTempState == NULL ); + m_pTempState = NULL; + +#define CPY(x) x = cpy.x + CPY( m_sName ); + CPY( m_pParent ); + CPY( m_pLuaInstance ); + + CPY( m_baseRotation ); + CPY( m_baseScale ); + CPY( m_fBaseAlpha ); + + + CPY( m_size ); + CPY( m_current ); + CPY( m_start ); + for( unsigned i = 0; i < cpy.m_Tweens.size(); ++i ) + m_Tweens.push_back( new TweenStateAndInfo(*cpy.m_Tweens[i]) ); + + CPY( m_bFirstUpdate ); + + CPY( m_fHorizAlign ); + CPY( m_fVertAlign ); +#if defined(SSC_FUTURES) + // I'm a bit worried about this -aj + for( unsigned i = 0; i < cpy.m_Effects.size(); ++i ) + m_Effects.push_back( (*cpy.m_Effects[i]) ); +#else + CPY( m_Effect ); +#endif + CPY( m_fSecsIntoEffect ); + CPY( m_fEffectDelta ); + CPY( m_fEffectRampUp ); + CPY( m_fEffectHoldAtHalf ); + CPY( m_fEffectRampDown ); + CPY( m_fEffectHoldAtZero ); + CPY( m_fEffectOffset ); + CPY( m_EffectClock ); + + CPY( m_effectColor1 ); + CPY( m_effectColor2 ); + CPY( m_vEffectMagnitude ); + + CPY( m_bVisible ); + CPY( m_fHibernateSecondsLeft ); + CPY( m_fShadowLengthX ); + CPY( m_fShadowLengthY ); + CPY( m_ShadowColor ); + CPY( m_bIsAnimating ); + CPY( m_iDrawOrder ); + + CPY( m_bTextureWrapping ); + CPY( m_bTextureFiltering ); + CPY( m_BlendMode ); + CPY( m_bClearZBuffer ); + CPY( m_ZTestMode ); + CPY( m_bZWrite ); + CPY( m_fZBias ); + CPY( m_CullMode ); + + CPY( m_mapNameToCommands ); +#undef CPY +} + +/* XXX: This calls InitCommand, which must happen after all other + * initialization (eg. ActorFrame loading children). However, it + * also loads input variables, which should happen first. The + * former is more important. */ +void Actor::LoadFromNode( const XNode* pNode ) +{ + Lua *L = LUA->Get(); + FOREACH_CONST_Attr( pNode, pAttr ) + { + // Load Name, if any. + const RString &sKeyName = pAttr->first; + const XNodeValue *pValue = pAttr->second; + if( sKeyName == "Name" ) SetName( pValue->GetValue() ); + else if( sKeyName == "BaseRotationX" ) SetBaseRotationX( pValue->GetValue() ); + else if( sKeyName == "BaseRotationY" ) SetBaseRotationY( pValue->GetValue() ); + else if( sKeyName == "BaseRotationZ" ) SetBaseRotationZ( pValue->GetValue() ); + else if( sKeyName == "BaseZoomX" ) SetBaseZoomX( pValue->GetValue() ); + else if( sKeyName == "BaseZoomY" ) SetBaseZoomY( pValue->GetValue() ); + else if( sKeyName == "BaseZoomZ" ) SetBaseZoomZ( pValue->GetValue() ); + else if( EndsWith(sKeyName,"Command") ) + { + LuaReference *pRef = new LuaReference; + pValue->PushValue( L ); + pRef->SetFromStack( L ); + RString sCmdName = sKeyName.Left( sKeyName.size()-7 ); + AddCommand( sCmdName, apActorCommands( pRef ) ); + } + } + + LUA->Release( L ); + + // Don't recurse Init. It gets called once for every Actor when the + // Actor is loaded, and we don't want to call it again. + PlayCommandNoRecurse( Message("Init") ); +} + +void Actor::Draw() +{ + if( !m_bVisible ) + return; // early abort + if( m_fHibernateSecondsLeft > 0 ) + return; // early abort + if( this->EarlyAbortDraw() ) + return; + + // call the most-derived versions + this->BeginDraw(); + this->DrawPrimitives(); // call the most-derived version of DrawPrimitives(); + this->EndDraw(); +} + +void Actor::BeginDraw() // set the world matrix and calculate actor properties +{ + DISPLAY->PushMatrix(); // we're actually going to do some drawing in this function + + // Somthing below may set m_pTempState to tempState + m_pTempState = &m_current; + + // set temporary drawing properties based on Effects + static TweenState tempState; + + // todo: account for SSC_FUTURES -aj + if( m_Effect == no_effect ) + { + } + else + { + m_pTempState = &tempState; + tempState = m_current; + + const float fTotalPeriod = GetEffectPeriod(); + ASSERT( fTotalPeriod > 0 ); + const float fTimeIntoEffect = fmodfp( m_fSecsIntoEffect+m_fEffectOffset, fTotalPeriod ); + + float fPercentThroughEffect; + if( fTimeIntoEffect < m_fEffectRampUp ) + { + fPercentThroughEffect = SCALE( + fTimeIntoEffect, + 0, + m_fEffectRampUp, + 0.0f, + 0.5f ); + } + else if( fTimeIntoEffect < m_fEffectRampUp + m_fEffectHoldAtHalf ) + { + fPercentThroughEffect = 0.5f; + } + else if( fTimeIntoEffect < m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown ) + { + fPercentThroughEffect = SCALE( + fTimeIntoEffect, + m_fEffectRampUp + m_fEffectHoldAtHalf, + m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown, + 0.5f, + 1.0f ); + } + else + { + fPercentThroughEffect = 0; + } + ASSERT_M( fPercentThroughEffect >= 0 && fPercentThroughEffect <= 1, + ssprintf("PercentThroughEffect: %f", fPercentThroughEffect) ); + + bool bBlinkOn = fPercentThroughEffect > 0.5f; + float fPercentBetweenColors = RageFastSin( (fPercentThroughEffect + 0.25f) * 2 * PI ) / 2 + 0.5f; + ASSERT_M( fPercentBetweenColors >= 0 && fPercentBetweenColors <= 1, + ssprintf("PercentBetweenColors: %f, PercentThroughEffect: %f", fPercentBetweenColors, fPercentThroughEffect) ); + float fOriginalAlpha = tempState.diffuse[0].a; + + // todo: account for SSC_FUTURES -aj + switch( m_Effect ) + { + case diffuse_blink: + /* XXX: Should diffuse_blink and diffuse_shift multiply the tempState color? + * (That would have the same effect with 1,1,1,1, and allow tweening the diffuse + * while blinking and shifting.) */ + for(int i=0; i<4; i++) + { + tempState.diffuse[i] = bBlinkOn ? m_effectColor1 : m_effectColor2; + tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing + } + break; + case diffuse_shift: + for(int i=0; i<4; i++) + { + tempState.diffuse[i] = m_effectColor1*fPercentBetweenColors + m_effectColor2*(1.0f-fPercentBetweenColors); + tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing + } + break; + case diffuse_ramp: + for(int i=0; i<4; i++) + { + tempState.diffuse[i] = m_effectColor1*fPercentThroughEffect + m_effectColor2*(1.0f-fPercentThroughEffect); + tempState.diffuse[i].a *= fOriginalAlpha; // multiply the alphas so we can fade even while an effect is playing + } + break; + case glow_blink: + tempState.glow = bBlinkOn ? m_effectColor1 : m_effectColor2; + tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! + break; + case glow_shift: + tempState.glow = m_effectColor1*fPercentBetweenColors + m_effectColor2*(1.0f-fPercentBetweenColors); + tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! + break; + case glow_ramp: + tempState.glow = m_effectColor1*fPercentThroughEffect + m_effectColor2*(1.0f-fPercentThroughEffect); + tempState.glow.a *= fOriginalAlpha; // don't glow if the Actor is transparent! + break; + case rainbow: + tempState.diffuse[0] = RageColor( + RageFastCos( fPercentBetweenColors*2*PI ) * 0.5f + 0.5f, + RageFastCos( fPercentBetweenColors*2*PI + PI * 2.0f / 3.0f ) * 0.5f + 0.5f, + RageFastCos( fPercentBetweenColors*2*PI + PI * 4.0f / 3.0f) * 0.5f + 0.5f, + fOriginalAlpha ); + for( int i=1; i<4; i++ ) + tempState.diffuse[i] = tempState.diffuse[0]; + break; + case wag: + tempState.rotation += m_vEffectMagnitude * RageFastSin( fPercentThroughEffect * 2.0f * PI ); + break; + case spin: + // nothing needs to be here + break; + case vibrate: + tempState.pos.x += m_vEffectMagnitude.x * randomf(-1.0f, 1.0f) * GetZoom(); + tempState.pos.y += m_vEffectMagnitude.y * randomf(-1.0f, 1.0f) * GetZoom(); + tempState.pos.z += m_vEffectMagnitude.z * randomf(-1.0f, 1.0f) * GetZoom(); + break; + case bounce: + { + float fPercentOffset = RageFastSin( fPercentThroughEffect*PI ); + tempState.pos += m_vEffectMagnitude * fPercentOffset; + tempState.pos.x = roundf( tempState.pos.x ); + tempState.pos.y = roundf( tempState.pos.y ); + tempState.pos.z = roundf( tempState.pos.z ); + } + break; + case bob: + { + float fPercentOffset = RageFastSin( fPercentThroughEffect*PI*2 ); + tempState.pos += m_vEffectMagnitude * fPercentOffset; + tempState.pos.x = roundf( tempState.pos.x ); + tempState.pos.y = roundf( tempState.pos.y ); + tempState.pos.z = roundf( tempState.pos.z ); + } + break; + case pulse: + { + float fMinZoom = m_vEffectMagnitude[0]; + float fMaxZoom = m_vEffectMagnitude[1]; + float fPercentOffset = RageFastSin( fPercentThroughEffect*PI ); + float fZoom = SCALE( fPercentOffset, 0.f, 1.f, fMinZoom, fMaxZoom ); + tempState.scale *= fZoom; + + // Use the color as a Vector3 to scale the effect for added control + RageColor c = SCALE( fPercentOffset, 0.f, 1.f, m_effectColor1, m_effectColor2 ); + tempState.scale.x *= c.r; + tempState.scale.y *= c.g; + tempState.scale.z *= c.b; + } + break; + default: + FAIL_M(ssprintf("Invalid effect: %i", m_Effect)); + } + } + + if( m_fBaseAlpha != 1 ) + { + if( m_pTempState != &tempState ) + { + m_pTempState = &tempState; + tempState = m_current; + } + + for( int i=0; i<4; i++ ) + tempState.diffuse[i].a *= m_fBaseAlpha; + } + + if( m_pTempState->pos.x != 0 || m_pTempState->pos.y != 0 || m_pTempState->pos.z != 0 ) + { + RageMatrix m; + RageMatrixTranslate( + &m, + m_pTempState->pos.x, + m_pTempState->pos.y, + m_pTempState->pos.z + ); + DISPLAY->PreMultMatrix( m ); + } + + { + /* The only time rotation and quat should normally be used simultaneously + * is for m_baseRotation. Most objects aren't rotated at all, so optimize + * that case. */ + const float fRotateX = m_pTempState->rotation.x + m_baseRotation.x; + const float fRotateY = m_pTempState->rotation.y + m_baseRotation.y; + const float fRotateZ = m_pTempState->rotation.z + m_baseRotation.z; + + if( fRotateX != 0 || fRotateY != 0 || fRotateZ != 0 ) + { + RageMatrix m; + RageMatrixRotationXYZ( &m, fRotateX, fRotateY, fRotateZ ); + DISPLAY->PreMultMatrix( m ); + } + } + + // handle scaling + { + const float fScaleX = m_pTempState->scale.x * m_baseScale.x; + const float fScaleY = m_pTempState->scale.y * m_baseScale.y; + const float fScaleZ = m_pTempState->scale.z * m_baseScale.z; + + if( fScaleX != 1 || fScaleY != 1 || fScaleZ != 1 ) + { + RageMatrix m; + RageMatrixScale( + &m, + fScaleX, + fScaleY, + fScaleZ ); + DISPLAY->PreMultMatrix( m ); + } + } + + // handle alignment; most actors have default alignment. + if( unlikely(m_fHorizAlign != 0.5f || m_fVertAlign != 0.5f) ) + { + float fX = SCALE( m_fHorizAlign, 0.0f, 1.0f, +m_size.x/2.0f, -m_size.x/2.0f ); + float fY = SCALE( m_fVertAlign, 0.0f, 1.0f, +m_size.y/2.0f, -m_size.y/2.0f ); + RageMatrix m; + RageMatrixTranslate( + &m, + fX, + fY, + 0 + ); + DISPLAY->PreMultMatrix( m ); + } + + if( m_pTempState->quat.x != 0 || m_pTempState->quat.y != 0 || m_pTempState->quat.z != 0 || m_pTempState->quat.w != 1 ) + { + RageMatrix mat; + RageMatrixFromQuat( &mat, m_pTempState->quat ); + + DISPLAY->MultMatrix(mat); + } + + // handle skews + if( m_pTempState->fSkewX != 0 ) + { + DISPLAY->SkewX( m_pTempState->fSkewX ); + } + + if( m_pTempState->fSkewY != 0 ) + { + DISPLAY->SkewY( m_pTempState->fSkewY ); + } + +} + +void Actor::SetGlobalRenderStates() +{ + // set Actor-defined render states + if( !g_bShowMasks.Get() || m_BlendMode != BLEND_NO_EFFECT ) + DISPLAY->SetBlendMode( m_BlendMode ); + DISPLAY->SetZWrite( m_bZWrite ); + DISPLAY->SetZTestMode( m_ZTestMode ); + + // BLEND_NO_EFFECT is used to draw masks to the Z-buffer, which always wants + // Z-bias enabled. + if( m_fZBias == 0 && m_BlendMode == BLEND_NO_EFFECT ) + DISPLAY->SetZBias( 1.0f ); + else + DISPLAY->SetZBias( m_fZBias ); + + if( m_bClearZBuffer ) + DISPLAY->ClearZBuffer(); + DISPLAY->SetCullMode( m_CullMode ); +} + +void Actor::SetTextureRenderStates() +{ + DISPLAY->SetTextureWrapping( TextureUnit_1, m_bTextureWrapping ); + DISPLAY->SetTextureFiltering( TextureUnit_1, m_bTextureFiltering ); +} + +void Actor::EndDraw() +{ + DISPLAY->PopMatrix(); + m_pTempState = NULL; +} + +void Actor::UpdateTweening( float fDeltaTime ) +{ + while( 1 ) + { + if( m_Tweens.empty() ) // nothing to do + return; + + if( fDeltaTime == 0 ) // nothing will change + return; + + // update current tween state + // earliest tween + TweenState &TS = m_Tweens[0]->state; + TweenInfo &TI = m_Tweens[0]->info; + + bool bBeginning = TI.m_fTimeLeftInTween == TI.m_fTweenTime; + + float fSecsToSubtract = min( TI.m_fTimeLeftInTween, fDeltaTime ); + TI.m_fTimeLeftInTween -= fSecsToSubtract; + fDeltaTime -= fSecsToSubtract; + + RString sCommand = TI.m_sCommandName; + if( bBeginning ) // we are just beginning this tween + m_start = m_current; // set the start position + + if( TI.m_fTimeLeftInTween == 0 ) // Current tween is over. Stop. + { + m_current = TS; + + // delete the head tween + delete m_Tweens.front(); + m_Tweens.erase( m_Tweens.begin() ); + } + else // in the middle of tweening. Recalcute the current position. + { + const float fPercentThroughTween = 1-(TI.m_fTimeLeftInTween / TI.m_fTweenTime); + + // distort the percentage if appropriate + float fPercentAlongPath = TI.m_pTween->Tween( fPercentThroughTween ); + TweenState::MakeWeightedAverage( m_current, m_start, TS, fPercentAlongPath ); + } + + if( bBeginning ) + { + // Execute the command in this tween (if any). Do this last, and don't + // access TI or TS after, since this may modify the tweening queue. + if( !sCommand.empty() ) + { + if( sCommand.Left(1) == "!" ) + MESSAGEMAN->Broadcast( sCommand.substr(1) ); + else + this->PlayCommand( sCommand ); + } + } + } +} + +bool Actor::IsFirstUpdate() const +{ + return m_bFirstUpdate; +} + +void Actor::Update( float fDeltaTime ) +{ +// LOG->Trace( "Actor::Update( %f )", fDeltaTime ); + ASSERT_M( fDeltaTime >= 0, ssprintf("DeltaTime: %f",fDeltaTime) ); + + if( m_fHibernateSecondsLeft > 0 ) + { + m_fHibernateSecondsLeft -= fDeltaTime; + if( m_fHibernateSecondsLeft > 0 ) + return; + + // Grab the leftover time. + fDeltaTime = -m_fHibernateSecondsLeft; + m_fHibernateSecondsLeft = 0; + } + + this->UpdateInternal( fDeltaTime ); +} + +void Actor::UpdateInternal( float fDeltaTime ) +{ + if( m_bFirstUpdate ) + m_bFirstUpdate = false; + + 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; + } + + // update effect + // todo: account for SSC_FUTURES -aj + switch( m_Effect ) + { + case spin: + m_current.rotation += m_fEffectDelta*m_vEffectMagnitude; + wrap( m_current.rotation.x, 360 ); + wrap( m_current.rotation.y, 360 ); + wrap( m_current.rotation.z, 360 ); + break; + default: break; + } + + UpdateTweening( fDeltaTime ); +} + +RString Actor::GetLineage() const +{ + RString sPath; + + if( m_pParent ) + sPath = m_pParent->GetLineage() + '/'; + sPath += ssprintf( "<%s> %s", typeid(*this).name(), m_sName.c_str() ); + return sPath; +} + +void Actor::BeginTweening( float time, ITween *pTween ) +{ + ASSERT( time >= 0 ); + + time = max( time, 0 ); + + // If the number of tweens to ever gets this large, there's probably an infinitely + // recursing ActorCommand. + if( m_Tweens.size() > 50 ) + { + RString sError = ssprintf( "Tween overflow: \"%s\"; infinitely recursing ActorCommand?", GetLineage().c_str() ); + + LOG->Warn( "%s", sError.c_str() ); + Dialog::OK( sError ); + FinishTweening(); + } + + // add a new TweenState to the tail, and initialize it + m_Tweens.push_back( new TweenStateAndInfo ); + + // latest + TweenState &TS = m_Tweens.back()->state; + TweenInfo &TI = m_Tweens.back()->info; + + if( m_Tweens.size() >= 2 ) // if there was already a TS on the stack + { + // initialize the new TS from the last TS in the list + TS = m_Tweens[m_Tweens.size()-2]->state; + } + else + { + // This new TS is the only TS. + // Set our tween starting and ending values to the current position. + TS = m_current; + } + + TI.m_pTween = pTween; + TI.m_fTweenTime = time; + TI.m_fTimeLeftInTween = time; +} + +void Actor::BeginTweening( float time, TweenType tt ) +{ + ITween *pTween = ITween::CreateFromType( tt ); + BeginTweening( time, pTween ); +} + +void Actor::StopTweening() +{ + for( unsigned i = 0; i < m_Tweens.size(); ++i ) + delete m_Tweens[i]; + m_Tweens.clear(); +} + +void Actor::FinishTweening() +{ + if( !m_Tweens.empty() ) + m_current = DestTweenState(); + StopTweening(); +} + +void Actor::HurryTweening( float factor ) +{ + for( unsigned i = 0; i < m_Tweens.size(); ++i ) + { + m_Tweens[i]->info.m_fTimeLeftInTween *= factor; + m_Tweens[i]->info.m_fTweenTime *= factor; + } +} + +void Actor::ScaleTo( const RectF &rect, StretchType st ) +{ + // width and height of rectangle + float rect_width = rect.GetWidth(); + float rect_height = rect.GetHeight(); + + if( rect_width < 0 ) SetRotationY( 180 ); + if( rect_height < 0 ) SetRotationX( 180 ); + + // zoom fActor needed to scale the Actor to fill the rectangle + float fNewZoomX = fabsf(rect_width / m_size.x); + float fNewZoomY = fabsf(rect_height / m_size.y); + + float fNewZoom = 0.f; + switch( st ) + { + case cover: + fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomX : fNewZoomY; // use larger zoom + break; + case fit_inside: + fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomY : fNewZoomX; // use smaller zoom + break; + } + + SetX( rect.left + rect_width * m_fHorizAlign ); + SetY( rect.top + rect_height * m_fVertAlign ); + + SetZoom( fNewZoom ); +} + +void Actor::SetEffectClockString( const RString &s ) +{ + if (s.EqualsNoCase("timer")) this->SetEffectClock( CLOCK_TIMER ); + if (s.EqualsNoCase("timerglobal")) this->SetEffectClock( CLOCK_TIMER_GLOBAL ); + else if(s.EqualsNoCase("beat")) this->SetEffectClock( CLOCK_BGM_BEAT ); + else if(s.EqualsNoCase("music")) this->SetEffectClock( CLOCK_BGM_TIME ); + else if(s.EqualsNoCase("bgm")) this->SetEffectClock( CLOCK_BGM_BEAT ); // compat, deprecated + else if(s.EqualsNoCase("musicnooffset"))this->SetEffectClock( CLOCK_BGM_TIME_NO_OFFSET ); + else if(s.EqualsNoCase("beatnooffset")) this->SetEffectClock( CLOCK_BGM_BEAT_NO_OFFSET ); + else + { + CabinetLight cl = StringToCabinetLight( s ); + if( cl == CabinetLight_Invalid ) + FAIL_M(ssprintf("Invalid cabinet light: %s", s.c_str())); + + this->SetEffectClock( (EffectClock) (cl + CLOCK_LIGHT_1) ); + } +} + +void Actor::StretchTo( const RectF &r ) +{ + // width and height of rectangle + float width = r.GetWidth(); + float height = r.GetHeight(); + + // center of the rectangle + float cx = r.left + width/2.0f; + float cy = r.top + height/2.0f; + + // zoom fActor needed to scale the Actor to fill the rectangle + float fNewZoomX = width / m_size.x; + float fNewZoomY = height / m_size.y; + + SetXY( cx, cy ); + SetZoomX( fNewZoomX ); + SetZoomY( fNewZoomY ); +} + + +void Actor::SetEffectPeriod( float fTime ) +{ + ASSERT( fTime > 0 ); + m_fEffectRampUp = fTime/2; + m_fEffectHoldAtHalf = 0; + m_fEffectRampDown = fTime/2; + m_fEffectHoldAtZero = 0; +} + +float Actor::GetEffectPeriod() const +{ + return m_fEffectRampUp + m_fEffectHoldAtHalf + m_fEffectRampDown + m_fEffectHoldAtZero; +} + +void Actor::SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, float fAtZero ) +{ + m_fEffectRampUp = fRampUp; + m_fEffectHoldAtHalf = fAtHalf; + m_fEffectRampDown = fRampDown; + m_fEffectHoldAtZero = fAtZero; + ASSERT( GetEffectPeriod() > 0 ); +} + +// effect "macros" + +void Actor::SetEffectDiffuseBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != diffuse_blink ) + { + m_Effect = diffuse_blink; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectDiffuseShift( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != diffuse_shift ) + { + m_Effect = diffuse_shift; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectDiffuseRamp( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != diffuse_ramp ) + { + m_Effect = diffuse_ramp; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectGlowBlink( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != glow_blink ) + { + m_Effect = glow_blink; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectGlowShift( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != glow_shift ) + { + m_Effect = glow_shift; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectGlowRamp( float fEffectPeriodSeconds, RageColor c1, RageColor c2 ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != glow_ramp ) + { + m_Effect = glow_ramp; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); + m_effectColor1 = c1; + m_effectColor2 = c2; +} + +void Actor::SetEffectRainbow( float fEffectPeriodSeconds ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != rainbow ) + { + m_Effect = rainbow; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fEffectPeriodSeconds ); +} + +void Actor::SetEffectWag( float fPeriod, RageVector3 vect ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect != wag ) + { + m_Effect = wag; + m_fSecsIntoEffect = 0; + } + SetEffectPeriod( fPeriod ); + m_vEffectMagnitude = vect; +} + +void Actor::SetEffectBounce( float fPeriod, RageVector3 vect ) +{ + // todo: account for SSC_FUTURES -aj + m_Effect = bounce; + SetEffectPeriod( fPeriod ); + m_vEffectMagnitude = vect; + m_fSecsIntoEffect = 0; +} + +void Actor::SetEffectBob( float fPeriod, RageVector3 vect ) +{ + // todo: account for SSC_FUTURES -aj + if( m_Effect!=bob || GetEffectPeriod() != fPeriod ) + { + m_Effect = bob; + SetEffectPeriod( fPeriod ); + m_fSecsIntoEffect = 0; + } + m_vEffectMagnitude = vect; +} + +void Actor::SetEffectSpin( RageVector3 vect ) +{ + // todo: account for SSC_FUTURES -aj + m_Effect = spin; + m_vEffectMagnitude = vect; +} + +void Actor::SetEffectVibrate( RageVector3 vect ) +{ + // todo: account for SSC_FUTURES -aj + m_Effect = vibrate; + m_vEffectMagnitude = vect; +} + +void Actor::SetEffectPulse( float fPeriod, float fMinZoom, float fMaxZoom ) +{ + // todo: account for SSC_FUTURES -aj + m_Effect = pulse; + SetEffectPeriod( fPeriod ); + m_vEffectMagnitude[0] = fMinZoom; + m_vEffectMagnitude[1] = fMaxZoom; +} + + +void Actor::AddRotationH( float rot ) +{ + RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromH(rot) ); +} + +void Actor::AddRotationP( float rot ) +{ + RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromP(rot) ); +} + +void Actor::AddRotationR( float rot ) +{ + RageQuatMultiply( &DestTweenState().quat, DestTweenState().quat, RageQuatFromR(rot) ); +} + +void Actor::RunCommands( const LuaReference& cmds, const LuaReference *pParamTable ) +{ + Lua *L = LUA->Get(); + + // function + cmds.PushSelf( L ); + ASSERT( !lua_isnil(L, -1) ); + + // 1st parameter + this->PushSelf( L ); + + // 2nd parameter + if( pParamTable == NULL ) + lua_pushnil( L ); + else + pParamTable->PushSelf( L ); + + // call function with 2 arguments and 0 results + RString sError; + if( !LuaHelpers::RunScriptOnStack(L, sError, 2, 0) ) + LOG->Warn( "Error playing command: %s", sError.c_str() ); + + LUA->Release(L); +} + +float Actor::GetTweenTimeLeft() const +{ + float tot = 0; + + tot += m_fHibernateSecondsLeft; + + for( unsigned i=0; iinfo.m_fTimeLeftInTween; + + return tot; +} + +/* This is a hack to change all tween states while leaving existing tweens alone. + * + * Hmm. Most commands actually act on a TweenStateAndInfo, not the Actor itself. + * Conceptually, it wouldn't be hard to give TweenState a presence in Lua, so + * we can simply say eg. "for x in states(Actor) do x.SetDiffuseColor(c) end". + * However, we'd then have to give every TweenState a userdata in Lua while it's + * being manipulated, which would add overhead ... */ +void Actor::SetGlobalDiffuseColor( RageColor c ) +{ + for( int i=0; i<4; i++ ) // color, not alpha + { + for( unsigned ts = 0; ts < m_Tweens.size(); ++ts ) + { + m_Tweens[ts]->state.diffuse[i].r = c.r; + m_Tweens[ts]->state.diffuse[i].g = c.g; + m_Tweens[ts]->state.diffuse[i].b = c.b; + } + m_current.diffuse[i].r = c.r; + m_current.diffuse[i].g = c.g; + m_current.diffuse[i].b = c.b; + m_start.diffuse[i].r = c.r; + m_start.diffuse[i].g = c.g; + m_start.diffuse[i].b = c.b; + } +} + +void Actor::SetDiffuseColor( RageColor c ) +{ + for( int i=0; i<4; i++ ) + { + DestTweenState().diffuse[i].r = c.r; + DestTweenState().diffuse[i].g = c.g; + DestTweenState().diffuse[i].b = c.b; + } +} + + +void Actor::TweenState::Init() +{ + pos = RageVector3( 0, 0, 0 ); + rotation = RageVector3( 0, 0, 0 ); + quat = RageVector4( 0, 0, 0, 1 ); + scale = RageVector3( 1, 1, 1 ); + fSkewX = 0; + fSkewY = 0; + crop = RectF( 0,0,0,0 ); + fade = RectF( 0,0,0,0 ); + for( int i=0; i<4; i++ ) + diffuse[i] = RageColor( 1, 1, 1, 1 ); + glow = RageColor( 1, 1, 1, 0 ); + aux = 0; +} + +bool Actor::TweenState::operator==( const TweenState &other ) const +{ +#define COMPARE( x ) if( x != other.x ) return false; + COMPARE( pos ); + COMPARE( rotation ); + COMPARE( quat ); + COMPARE( scale ); + COMPARE( fSkewX ); + COMPARE( fSkewY ); + COMPARE( crop ); + COMPARE( fade ); + for( unsigned i=0; iinfo; + TI.m_sCommandName = sCommandName; +} + +void Actor::QueueMessage( const RString& sMessageName ) +{ + // Hack: use "!" as a marker to broadcast a command, instead of playing a + // command, so we don't have to add yet another element to every tween + // state for this rarely-used command. + BeginTweening( 0, TWEEN_LINEAR ); + TweenInfo &TI = m_Tweens.back()->info; + TI.m_sCommandName = "!" + sMessageName; +} + +void Actor::AddCommand( const RString &sCmdName, apActorCommands apac ) +{ + if( HasCommand(sCmdName) ) + { + RString sWarning = GetLineage()+"'s command '"+sCmdName+"' defined twice"; + Dialog::OK( sWarning, "COMMAND_DEFINED_TWICE" ); + } + + RString sMessage; + if( GetMessageNameFromCommandName(sCmdName, sMessage) ) + { + SubscribeToMessage( sMessage ); + m_mapNameToCommands[sMessage] = apac; // sCmdName w/o "Message" at the end + } + else + { + m_mapNameToCommands[sCmdName] = apac; + } +} + +bool Actor::HasCommand( const RString &sCmdName ) const +{ + return GetCommand(sCmdName) != NULL; +} + +const apActorCommands *Actor::GetCommand( const RString &sCommandName ) const +{ + map::const_iterator it = m_mapNameToCommands.find( sCommandName ); + if( it == m_mapNameToCommands.end() ) + return NULL; + return &it->second; +} + +void Actor::HandleMessage( const Message &msg ) +{ + PlayCommandNoRecurse( msg ); +} + +void Actor::PlayCommandNoRecurse( const Message &msg ) +{ + const apActorCommands *pCmd = GetCommand( msg.GetName() ); + if( pCmd != NULL ) + RunCommands( *pCmd, &msg.GetParamTable() ); +} + +void Actor::PushContext( lua_State *L ) +{ + // self.ctx should already exist + m_pLuaInstance->PushSelf( L ); + lua_getfield( L, -1, "ctx" ); + lua_remove( L, -2 ); +} + +void Actor::SetParent( Actor *pParent ) +{ + m_pParent = pParent; + + Lua *L = LUA->Get(); + int iTop = lua_gettop( L ); + + this->PushContext( L ); + lua_pushstring( L, "__index" ); + pParent->PushContext( L ); + lua_settable( L, -3 ); + + lua_settop( L, iTop ); + LUA->Release( L ); +} + +Actor::TweenInfo::TweenInfo() +{ + m_pTween = NULL; +} + +Actor::TweenInfo::~TweenInfo() +{ + delete m_pTween; +} + +Actor::TweenInfo::TweenInfo( const TweenInfo &cpy ) +{ + m_pTween = NULL; + *this = cpy; +} + +Actor::TweenInfo &Actor::TweenInfo::operator=( const TweenInfo &rhs ) +{ + delete m_pTween; + m_pTween = (rhs.m_pTween? rhs.m_pTween->Copy():NULL); + m_fTimeLeftInTween = rhs.m_fTimeLeftInTween; + m_fTweenTime = rhs.m_fTweenTime; + m_sCommandName = rhs.m_sCommandName; + return *this; +} + +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the Actor. */ +class LunaActor : public Luna +{ +public: + static int name( T* p, lua_State *L ) { p->SetName(SArg(1)); return 0; } + static int sleep( T* p, lua_State *L ) { p->Sleep(FArg(1)); return 0; } + static int linear( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_LINEAR); return 0; } + static int accelerate( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_ACCELERATE); return 0; } + static int decelerate( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_DECELERATE); return 0; } + static int spring( T* p, lua_State *L ) { p->BeginTweening(FArg(1),TWEEN_SPRING); return 0; } + static int tween( T* p, lua_State *L ) + { + ITween *pTween = ITween::CreateFromStack( L, 2 ); + p->BeginTweening( FArg(1), pTween ); + return 0; + } + static int stoptweening( T* p, lua_State * ) { p->StopTweening(); return 0; } + static int finishtweening( T* p, lua_State * ) { p->FinishTweening(); return 0; } + static int hurrytweening( T* p, lua_State *L ) { p->HurryTweening(FArg(1)); return 0; } + static int GetTweenTimeLeft( T* p, lua_State *L ) { lua_pushnumber( L, p->GetTweenTimeLeft() ); return 1; } + static int x( T* p, lua_State *L ) { p->SetX(FArg(1)); return 0; } + static int y( T* p, lua_State *L ) { p->SetY(FArg(1)); return 0; } + static int z( T* p, lua_State *L ) { p->SetZ(FArg(1)); return 0; } + static int xy( T* p, lua_State *L ) { p->SetXY(FArg(1),FArg(2)); return 0; } + static int addx( T* p, lua_State *L ) { p->AddX(FArg(1)); return 0; } + static int addy( T* p, lua_State *L ) { p->AddY(FArg(1)); return 0; } + static int addz( T* p, lua_State *L ) { p->AddZ(FArg(1)); return 0; } + static int zoom( T* p, lua_State *L ) { p->SetZoom(FArg(1)); return 0; } + static int zoomx( T* p, lua_State *L ) { p->SetZoomX(FArg(1)); return 0; } + static int zoomy( T* p, lua_State *L ) { p->SetZoomY(FArg(1)); return 0; } + static int zoomz( T* p, lua_State *L ) { p->SetZoomZ(FArg(1)); return 0; } + static int zoomto( T* p, lua_State *L ) { p->ZoomTo(FArg(1), FArg(2)); return 0; } + static int zoomtowidth( T* p, lua_State *L ) { p->ZoomToWidth(FArg(1)); return 0; } + static int zoomtoheight( T* p, lua_State *L ) { p->ZoomToHeight(FArg(1)); return 0; } + static int setsize( T* p, lua_State *L ) { p->SetWidth(FArg(1)); p->SetHeight(FArg(2)); return 0; } + static int SetWidth( T* p, lua_State *L ) { p->SetWidth(FArg(1)); return 0; } + static int SetHeight( T* p, lua_State *L ) { p->SetHeight(FArg(1)); return 0; } + static int basealpha( T* p, lua_State *L ) { p->SetBaseAlpha(FArg(1)); return 0; } + static int basezoom( T* p, lua_State *L ) { p->SetBaseZoom(FArg(1)); return 0; } + static int basezoomx( T* p, lua_State *L ) { p->SetBaseZoomX(FArg(1)); return 0; } + static int basezoomy( T* p, lua_State *L ) { p->SetBaseZoomY(FArg(1)); return 0; } + static int basezoomz( T* p, lua_State *L ) { p->SetBaseZoomZ(FArg(1)); return 0; } + static int stretchto( T* p, lua_State *L ) { p->StretchTo( RectF(FArg(1),FArg(2),FArg(3),FArg(4)) ); return 0; } + static int cropleft( T* p, lua_State *L ) { p->SetCropLeft(FArg(1)); return 0; } + static int croptop( T* p, lua_State *L ) { p->SetCropTop(FArg(1)); return 0; } + static int cropright( T* p, lua_State *L ) { p->SetCropRight(FArg(1)); return 0; } + static int cropbottom( T* p, lua_State *L ) { p->SetCropBottom(FArg(1)); return 0; } + static int fadeleft( T* p, lua_State *L ) { p->SetFadeLeft(FArg(1)); return 0; } + static int fadetop( T* p, lua_State *L ) { p->SetFadeTop(FArg(1)); return 0; } + static int faderight( T* p, lua_State *L ) { p->SetFadeRight(FArg(1)); return 0; } + static int fadebottom( T* p, lua_State *L ) { p->SetFadeBottom(FArg(1)); return 0; } + static int diffuse( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuse( c ); return 0; } + static int diffuseupperleft( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseUpperLeft( c ); return 0; } + static int diffuseupperright( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseUpperRight( c ); return 0; } + static int diffuselowerleft( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLowerLeft( c ); return 0; } + static int diffuselowerright( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLowerRight( c ); return 0; } + static int diffuseleftedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLeftEdge( c ); return 0; } + static int diffuserightedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseRightEdge( c ); return 0; } + static int diffusetopedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseTopEdge( c ); return 0; } + static int diffusebottomedge( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseBottomEdge( c ); return 0; } + static int diffusealpha( T* p, lua_State *L ) { p->SetDiffuseAlpha(FArg(1)); return 0; } + static int diffusecolor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseColor( c ); return 0; } + static int glow( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetGlow( c ); return 0; } + static int aux( T* p, lua_State *L ) { p->SetAux( FArg(1) ); return 0; } + static int getaux( T* p, lua_State *L ) { lua_pushnumber( L, p->GetAux() ); return 1; } + static int rotationx( T* p, lua_State *L ) { p->SetRotationX(FArg(1)); return 0; } + static int rotationy( T* p, lua_State *L ) { p->SetRotationY(FArg(1)); return 0; } + static int rotationz( T* p, lua_State *L ) { p->SetRotationZ(FArg(1)); return 0; } + static int addrotationx( T* p, lua_State *L ) { p->AddRotationX(FArg(1)); return 0; } + static int addrotationy( T* p, lua_State *L ) { p->AddRotationY(FArg(1)); return 0; } + static int addrotationz( T* p, lua_State *L ) { p->AddRotationZ(FArg(1)); return 0; } + static int getrotation( T* p, lua_State *L ) { lua_pushnumber(L, p->GetRotationX()); lua_pushnumber(L, p->GetRotationY()); lua_pushnumber(L, p->GetRotationZ()); return 3; } + static int baserotationx( T* p, lua_State *L ) { p->SetBaseRotationX(FArg(1)); return 0; } + static int baserotationy( T* p, lua_State *L ) { p->SetBaseRotationY(FArg(1)); return 0; } + static int baserotationz( T* p, lua_State *L ) { p->SetBaseRotationZ(FArg(1)); return 0; } + static int skewx( T* p, lua_State *L ) { p->SetSkewX(FArg(1)); return 0; } + static int skewy( T* p, lua_State *L ) { p->SetSkewY(FArg(1)); return 0; } + static int heading( T* p, lua_State *L ) { p->AddRotationH(FArg(1)); return 0; } + static int pitch( T* p, lua_State *L ) { p->AddRotationP(FArg(1)); return 0; } + static int roll( T* p, lua_State *L ) { p->AddRotationR(FArg(1)); return 0; } + static int shadowlength( T* p, lua_State *L ) { p->SetShadowLength(FArg(1)); return 0; } + static int shadowlengthx( T* p, lua_State *L ) { p->SetShadowLengthX(FArg(1)); return 0; } + static int shadowlengthy( T* p, lua_State *L ) { p->SetShadowLengthY(FArg(1)); return 0; } + static int shadowcolor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetShadowColor( c ); return 0; } + static int horizalign( T* p, lua_State *L ) { p->SetHorizAlign(Enum::Check(L, 1)); return 0; } + static int vertalign( T* p, lua_State *L ) { p->SetVertAlign(Enum::Check(L, 1)); return 0; } + static int halign( T* p, lua_State *L ) { p->SetHorizAlign(FArg(1)); return 0; } + static int valign( T* p, lua_State *L ) { p->SetVertAlign(FArg(1)); return 0; } + static int diffuseblink( T* p, lua_State * ) { p->SetEffectDiffuseBlink(); return 0; } + static int diffuseshift( T* p, lua_State * ) { p->SetEffectDiffuseShift(); return 0; } + static int diffuseramp( T* p, lua_State * ) { p->SetEffectDiffuseRamp(); return 0; } + static int glowblink( T* p, lua_State * ) { p->SetEffectGlowBlink(); return 0; } + static int glowshift( T* p, lua_State * ) { p->SetEffectGlowShift(); return 0; } + static int glowramp( T* p, lua_State * ) { p->SetEffectGlowRamp(); return 0; } + static int rainbow( T* p, lua_State * ) { p->SetEffectRainbow(); return 0; } + static int wag( T* p, lua_State * ) { p->SetEffectWag(); return 0; } + static int bounce( T* p, lua_State * ) { p->SetEffectBounce(); return 0; } + static int bob( T* p, lua_State * ) { p->SetEffectBob(); return 0; } + static int pulse( T* p, lua_State * ) { p->SetEffectPulse(); return 0; } + static int spin( T* p, lua_State * ) { p->SetEffectSpin(); return 0; } + static int vibrate( T* p, lua_State * ) { p->SetEffectVibrate(); return 0; } + static int stopeffect( T* p, lua_State * ) { p->StopEffect(); return 0; } + static int effectcolor1( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetEffectColor1( c ); return 0; } + static int effectcolor2( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetEffectColor2( c ); return 0; } + static int effectperiod( T* p, lua_State *L ) { p->SetEffectPeriod(FArg(1)); return 0; } + static int effecttiming( T* p, lua_State *L ) { p->SetEffectTiming(FArg(1),FArg(2),FArg(3),FArg(4)); return 0; } + static int effectoffset( T* p, lua_State *L ) { p->SetEffectOffset(FArg(1)); return 0; } + static int effectclock( T* p, lua_State *L ) { p->SetEffectClockString(SArg(1)); return 0; } + static int effectmagnitude( T* p, lua_State *L ) { p->SetEffectMagnitude( RageVector3(FArg(1),FArg(2),FArg(3)) ); return 0; } + static int geteffectmagnitude( T* p, lua_State *L ) { RageVector3 v = p->GetEffectMagnitude(); lua_pushnumber(L, v[0]); lua_pushnumber(L, v[1]); lua_pushnumber(L, v[2]); return 3; } + static int scaletocover( T* p, lua_State *L ) { p->ScaleToCover( RectF(FArg(1), FArg(2), FArg(3), FArg(4)) ); return 0; } + static int scaletofit( T* p, lua_State *L ) { p->ScaleToFitInside( RectF(FArg(1), FArg(2), FArg(3), FArg(4)) ); return 0; } + static int animate( T* p, lua_State *L ) { p->EnableAnimation(BIArg(1)); return 0; } + static int play( T* p, lua_State * ) { p->EnableAnimation(true); return 0; } + static int pause( T* p, lua_State * ) { p->EnableAnimation(false); return 0; } + static int setstate( T* p, lua_State *L ) { p->SetState(IArg(1)); return 0; } + static int GetNumStates( T* p, lua_State *L ) { LuaHelpers::Push( L, p->GetNumStates() ); return 1; } + static int texturewrapping( T* p, lua_State *L ) { p->SetTextureWrapping(BIArg(1)); return 0; } + static int SetTextureFiltering( T* p, lua_State *L ) { p->SetTextureFiltering(BArg(1)); return 0; } + static int blend( T* p, lua_State *L ) { p->SetBlendMode( Enum::Check(L, 1) ); return 0; } + static int zbuffer( T* p, lua_State *L ) { p->SetUseZBuffer(BIArg(1)); return 0; } + static int ztest( T* p, lua_State *L ) { p->SetZTestMode((BIArg(1))?ZTEST_WRITE_ON_PASS:ZTEST_OFF); return 0; } + static int ztestmode( T* p, lua_State *L ) { p->SetZTestMode( Enum::Check(L, 1) ); return 0; } + static int zwrite( T* p, lua_State *L ) { p->SetZWrite(BIArg(1)); return 0; } + static int zbias( T* p, lua_State *L ) { p->SetZBias(FArg(1)); return 0; } + static int clearzbuffer( T* p, lua_State *L ) { p->SetClearZBuffer(BIArg(1)); return 0; } + static int backfacecull( T* p, lua_State *L ) { p->SetCullMode((BIArg(1)) ? CULL_BACK : CULL_NONE); return 0; } + static int cullmode( T* p, lua_State *L ) { p->SetCullMode( Enum::Check(L, 1)); return 0; } + static int visible( T* p, lua_State *L ) { p->SetVisible(BIArg(1)); return 0; } + static int hibernate( T* p, lua_State *L ) { p->SetHibernate(FArg(1)); return 0; } + static int draworder( T* p, lua_State *L ) { p->SetDrawOrder(IArg(1)); return 0; } + static int playcommand( T* p, lua_State *L ) + { + if( !lua_istable(L, 2) && !lua_isnoneornil(L, 2) ) + luaL_typerror( L, 2, "table or nil" ); + + LuaReference ParamTable; + lua_pushvalue( L, 2 ); + ParamTable.SetFromStack( L ); + + Message msg( SArg(1), ParamTable ); + p->HandleMessage( msg ); + + return 0; + } + static int queuecommand( T* p, lua_State *L ) { p->QueueCommand(SArg(1)); return 0; } + static int queuemessage( T* p, lua_State *L ) { p->QueueMessage(SArg(1)); return 0; } + static int addcommand( T* p, lua_State *L ) + { + LuaReference *pRef = new LuaReference; + pRef->SetFromStack( L ); + p->AddCommand( SArg(1), apActorCommands(pRef) ); + return 0; + } + static int GetCommand( T* p, lua_State *L ) + { + const apActorCommands *pCommand = p->GetCommand(SArg(1)); + if( pCommand == NULL ) + lua_pushnil( L ); + else + (*pCommand)->PushSelf(L); + + return 1; + } + static int RunCommandsRecursively( T* p, lua_State *L ) + { + luaL_checktype( L, 1, LUA_TFUNCTION ); + if( !lua_istable(L, 2) && !lua_isnoneornil(L, 2) ) + luaL_typerror( L, 2, "table or nil" ); + + LuaReference ref; + lua_pushvalue( L, 1 ); + ref.SetFromStack( L ); + + LuaReference ParamTable; + lua_pushvalue( L, 2 ); + ParamTable.SetFromStack( L ); + + p->RunCommandsRecursively( ref, &ParamTable ); + return 0; + } + + static int GetX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetX() ); return 1; } + static int GetY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetY() ); return 1; } + static int GetZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZ() ); return 1; } + static int GetWidth( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnzoomedWidth() ); return 1; } + static int GetHeight( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnzoomedHeight() ); return 1; } + static int GetZoomedWidth( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomedWidth() ); return 1; } + static int GetZoomedHeight( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomedHeight() ); return 1; } + static int GetZoom( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoom() ); return 1; } + static int GetZoomX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomX() ); return 1; } + static int GetZoomY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomY() ); return 1; } + static int GetZoomZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetZoomZ() ); return 1; } + static int GetBaseZoomX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomX() ); return 1; } + static int GetBaseZoomY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomY() ); return 1; } + static int GetBaseZoomZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetBaseZoomZ() ); return 1; } + static int GetRotationX( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationX() ); return 1; } + static int GetRotationY( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationY() ); return 1; } + static int GetRotationZ( T* p, lua_State *L ) { lua_pushnumber( L, p->GetRotationZ() ); return 1; } + static int GetSecsIntoEffect( T* p, lua_State *L ) { lua_pushnumber( L, p->GetSecsIntoEffect() ); return 1; } + static int GetEffectDelta( T* p, lua_State *L ) { lua_pushnumber( L, p->GetEffectDelta() ); return 1; } + DEFINE_METHOD( GetDiffuse, GetDiffuse() ) + DEFINE_METHOD( GetGlow, GetGlow() ) + static int GetDiffuseAlpha( T* p, lua_State *L ) { lua_pushnumber( L, p->GetDiffuseAlpha() ); return 1; } + static int GetVisible( T* p, lua_State *L ) { lua_pushboolean( L, p->GetVisible() ); return 1; } + static int GetHAlign( T* p, lua_State *L ) { lua_pushnumber( L, p->GetHorizAlign() ); return 1; } + static int GetVAlign( T* p, lua_State *L ) { lua_pushnumber( L, p->GetVertAlign() ); return 1; } + + static int GetName( T* p, lua_State *L ) { lua_pushstring( L, p->GetName() ); return 1; } + static int GetParent( T* p, lua_State *L ) + { + Actor *pParent = p->GetParent(); + if( pParent == NULL ) + lua_pushnil( L ); + else + pParent->PushSelf(L); + return 1; + } + static int Draw( T* p, lua_State *L ) + { + LUA->YieldLua(); + p->Draw(); + LUA->UnyieldLua(); + return 0; + } + + LunaActor() + { + ADD_METHOD( name ); + ADD_METHOD( sleep ); + ADD_METHOD( linear ); + ADD_METHOD( accelerate ); + ADD_METHOD( decelerate ); + ADD_METHOD( spring ); + ADD_METHOD( tween ); + ADD_METHOD( stoptweening ); + ADD_METHOD( finishtweening ); + ADD_METHOD( hurrytweening ); + ADD_METHOD( GetTweenTimeLeft ); + ADD_METHOD( x ); + ADD_METHOD( y ); + ADD_METHOD( z ); + ADD_METHOD( xy ); + ADD_METHOD( addx ); + ADD_METHOD( addy ); + ADD_METHOD( addz ); + ADD_METHOD( zoom ); + ADD_METHOD( zoomx ); + ADD_METHOD( zoomy ); + ADD_METHOD( zoomz ); + ADD_METHOD( zoomto ); + ADD_METHOD( zoomtowidth ); + ADD_METHOD( zoomtoheight ); + ADD_METHOD( setsize ); + ADD_METHOD( SetWidth ); + ADD_METHOD( SetHeight ); + ADD_METHOD( basealpha ); + ADD_METHOD( basezoom ); + ADD_METHOD( basezoomx ); + ADD_METHOD( basezoomy ); + ADD_METHOD( basezoomz ); + ADD_METHOD( stretchto ); + ADD_METHOD( cropleft ); + ADD_METHOD( croptop ); + ADD_METHOD( cropright ); + ADD_METHOD( cropbottom ); + ADD_METHOD( fadeleft ); + ADD_METHOD( fadetop ); + ADD_METHOD( faderight ); + ADD_METHOD( fadebottom ); + ADD_METHOD( diffuse ); + ADD_METHOD( diffuseupperleft ); + ADD_METHOD( diffuseupperright ); + ADD_METHOD( diffuselowerleft ); + ADD_METHOD( diffuselowerright ); + ADD_METHOD( diffuseleftedge ); + ADD_METHOD( diffuserightedge ); + ADD_METHOD( diffusetopedge ); + ADD_METHOD( diffusebottomedge ); + ADD_METHOD( diffusealpha ); + ADD_METHOD( diffusecolor ); + ADD_METHOD( glow ); + ADD_METHOD( aux ); + ADD_METHOD( getaux ); + ADD_METHOD( rotationx ); + ADD_METHOD( rotationy ); + ADD_METHOD( rotationz ); + ADD_METHOD( addrotationx ); + ADD_METHOD( addrotationy ); + ADD_METHOD( addrotationz ); + ADD_METHOD( getrotation ); + ADD_METHOD( baserotationx ); + ADD_METHOD( baserotationy ); + ADD_METHOD( baserotationz ); + ADD_METHOD( skewx ); + ADD_METHOD( skewy ); + ADD_METHOD( heading ); + ADD_METHOD( pitch ); + ADD_METHOD( roll ); + ADD_METHOD( shadowlength ); + ADD_METHOD( shadowlengthx ); + ADD_METHOD( shadowlengthy ); + ADD_METHOD( shadowcolor ); + ADD_METHOD( horizalign ); + ADD_METHOD( vertalign ); + ADD_METHOD( halign ); + ADD_METHOD( valign ); + ADD_METHOD( diffuseblink ); + ADD_METHOD( diffuseshift ); + ADD_METHOD( diffuseramp ); + ADD_METHOD( glowblink ); + ADD_METHOD( glowshift ); + ADD_METHOD( glowramp ); + ADD_METHOD( rainbow ); + ADD_METHOD( wag ); + ADD_METHOD( bounce ); + ADD_METHOD( bob ); + ADD_METHOD( pulse ); + ADD_METHOD( spin ); + ADD_METHOD( vibrate ); + ADD_METHOD( stopeffect ); + ADD_METHOD( effectcolor1 ); + ADD_METHOD( effectcolor2 ); + ADD_METHOD( effectperiod ); + ADD_METHOD( effecttiming ); + ADD_METHOD( effectoffset ); + ADD_METHOD( effectclock ); + ADD_METHOD( effectmagnitude ); + ADD_METHOD( geteffectmagnitude ); + ADD_METHOD( scaletocover ); + ADD_METHOD( scaletofit ); + ADD_METHOD( animate ); + ADD_METHOD( play ); + ADD_METHOD( pause ); + ADD_METHOD( setstate ); + ADD_METHOD( GetNumStates ); + ADD_METHOD( texturewrapping ); + ADD_METHOD( SetTextureFiltering ); + ADD_METHOD( blend ); + ADD_METHOD( zbuffer ); + ADD_METHOD( ztest ); + ADD_METHOD( ztestmode ); + ADD_METHOD( zwrite ); + ADD_METHOD( zbias ); + ADD_METHOD( clearzbuffer ); + ADD_METHOD( backfacecull ); + ADD_METHOD( cullmode ); + ADD_METHOD( visible ); + ADD_METHOD( hibernate ); + ADD_METHOD( draworder ); + ADD_METHOD( playcommand ); + ADD_METHOD( queuecommand ); + ADD_METHOD( queuemessage ); + ADD_METHOD( addcommand ); + ADD_METHOD( GetCommand ); + ADD_METHOD( RunCommandsRecursively ); + + ADD_METHOD( GetX ); + ADD_METHOD( GetY ); + ADD_METHOD( GetZ ); + ADD_METHOD( GetWidth ); + ADD_METHOD( GetHeight ); + ADD_METHOD( GetZoomedWidth ); + ADD_METHOD( GetZoomedHeight ); + ADD_METHOD( GetZoom ); + ADD_METHOD( GetZoomX ); + ADD_METHOD( GetZoomY ); + ADD_METHOD( GetZoomZ ); + ADD_METHOD( GetRotationX ); + ADD_METHOD( GetRotationY ); + ADD_METHOD( GetRotationZ ); + ADD_METHOD( GetBaseZoomX ); + ADD_METHOD( GetBaseZoomY ); + ADD_METHOD( GetBaseZoomZ ); + ADD_METHOD( GetSecsIntoEffect ); + ADD_METHOD( GetEffectDelta ); + ADD_METHOD( GetDiffuse ); + ADD_METHOD( GetDiffuseAlpha ); + ADD_METHOD( GetGlow ); + ADD_METHOD( GetVisible ); + ADD_METHOD( GetHAlign ); + ADD_METHOD( GetVAlign ); + + ADD_METHOD( GetName ); + ADD_METHOD( GetParent ); + + ADD_METHOD( Draw ); + } +}; + +LUA_REGISTER_INSTANCED_BASE_CLASS( Actor ) +// lua end + + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ActorFrame.cpp b/src/ActorFrame.cpp index 6161689e3b..8d7db5a418 100644 --- a/src/ActorFrame.cpp +++ b/src/ActorFrame.cpp @@ -9,7 +9,7 @@ #include "ActorUtil.h" #include "RageDisplay.h" #include "ScreenDimensions.h" -#include "Foreach.h" + /* Tricky: We need ActorFrames created in Lua to auto delete their children. * We don't want classes that derive from ActorFrame to auto delete their diff --git a/src/ActorMultiTexture.cpp b/src/ActorMultiTexture.cpp index 778cd150c3..08d0570325 100644 --- a/src/ActorMultiTexture.cpp +++ b/src/ActorMultiTexture.cpp @@ -9,7 +9,7 @@ #include "RageTexture.h" #include "RageUtil.h" #include "ActorUtil.h" -#include "Foreach.h" + #include "LuaBinding.h" #include "LuaManager.h" diff --git a/src/ActorScroller.cpp b/src/ActorScroller.cpp index b8a1d4f8a8..7b4a51bb5e 100644 --- a/src/ActorScroller.cpp +++ b/src/ActorScroller.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "ActorScroller.h" -#include "Foreach.h" + #include "RageUtil.h" #include "XmlFile.h" #include "arch/Dialog/Dialog.h" diff --git a/src/ActorUtil.cpp b/src/ActorUtil.cpp index bc61401c81..6a38fca7c7 100644 --- a/src/ActorUtil.cpp +++ b/src/ActorUtil.cpp @@ -8,7 +8,7 @@ #include "XmlFile.h" #include "XmlFileUtil.h" #include "LuaManager.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp index 522a7430db..d71078cb95 100644 --- a/src/AdjustSync.cpp +++ b/src/AdjustSync.cpp @@ -41,7 +41,7 @@ #include "LocalizedString.h" #include "PrefsManager.h" #include "ScreenManager.h" -#include "Foreach.h" + vector AdjustSync::s_vpTimingDataOriginal; float AdjustSync::s_fGlobalOffsetSecondsOriginal = 0.0f; diff --git a/src/Attack.cpp b/src/Attack.cpp index 16031a1c0a..ec24461dc8 100644 --- a/src/Attack.cpp +++ b/src/Attack.cpp @@ -3,7 +3,7 @@ #include "GameState.h" #include "RageUtil.h" #include "Song.h" -#include "Foreach.h" + #include "PlayerOptions.h" #include "PlayerState.h" diff --git a/src/AutoKeysounds.cpp b/src/AutoKeysounds.cpp index 58a8c2fb76..3a46ef82a0 100644 --- a/src/AutoKeysounds.cpp +++ b/src/AutoKeysounds.cpp @@ -30,7 +30,7 @@ #include "RageSoundManager.h" #include "RageLog.h" #include "RageSoundReader_FileReader.h" -#include "Foreach.h" + void AutoKeysounds::Load( PlayerNumber pn, const NoteData& ndAutoKeysoundsOnly ) { diff --git a/src/BGAnimation.cpp b/src/BGAnimation.cpp index 94eb8df6e5..157f5129d8 100644 --- a/src/BGAnimation.cpp +++ b/src/BGAnimation.cpp @@ -4,7 +4,7 @@ #include "BGAnimationLayer.h" #include "RageUtil.h" #include "ActorUtil.h" -#include "Foreach.h" + #include "LuaManager.h" #include "PrefsManager.h" diff --git a/src/BackgroundUtil.cpp b/src/BackgroundUtil.cpp index 74d1feec97..09a13ecad0 100644 --- a/src/BackgroundUtil.cpp +++ b/src/BackgroundUtil.cpp @@ -2,7 +2,7 @@ #include "BackgroundUtil.h" #include "RageUtil.h" #include "Song.h" -#include "Foreach.h" + #include "IniFile.h" #include "RageLog.h" #include diff --git a/src/BannerCache.cpp b/src/BannerCache.cpp index 92956a3796..4a6b621168 100644 --- a/src/BannerCache.cpp +++ b/src/BannerCache.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "BannerCache.h" -#include "Foreach.h" + #include "RageDisplay.h" #include "RageUtil.h" #include "RageLog.h" diff --git a/src/BitmapText.cpp b/src/BitmapText.cpp index 0884023c83..f46e1cbe98 100644 --- a/src/BitmapText.cpp +++ b/src/BitmapText.cpp @@ -9,7 +9,7 @@ #include "Font.h" #include "ActorUtil.h" #include "LuaBinding.h" -#include "Foreach.h" + REGISTER_ACTOR_CLASS( BitmapText ); diff --git a/src/CharacterManager.cpp b/src/CharacterManager.cpp index be6e6be977..7bec33d08a 100644 --- a/src/CharacterManager.cpp +++ b/src/CharacterManager.cpp @@ -2,7 +2,7 @@ #include "CharacterManager.h" #include "Character.h" #include "GameState.h" -#include "Foreach.h" + #include "LuaManager.h" #define CHARACTERS_DIR "/Characters/" diff --git a/src/Command.cpp b/src/Command.cpp index 267fcc64f8..6b794833e5 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -3,7 +3,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "arch/Dialog/Dialog.h" -#include "Foreach.h" + #include RString Command::GetName() const diff --git a/src/CommandLineActions.cpp b/src/CommandLineActions.cpp index 553891c420..139b9e67b7 100644 --- a/src/CommandLineActions.cpp +++ b/src/CommandLineActions.cpp @@ -8,7 +8,7 @@ #include "LuaManager.h" #include "ProductInfo.h" #include "DateTime.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" #include "RageFileManager.h" #include "SpecialFiles.h" diff --git a/src/CommonMetrics.cpp b/src/CommonMetrics.cpp index 6cb7b4d7ac..83e241984b 100644 --- a/src/CommonMetrics.cpp +++ b/src/CommonMetrics.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "CommonMetrics.h" #include "RageUtil.h" -#include "Foreach.h" + #include "GameManager.h" #include "RageLog.h" #include "GameState.h" diff --git a/src/Course.cpp b/src/Course.cpp index a4b677a833..1b04e39895 100644 --- a/src/Course.cpp +++ b/src/Course.cpp @@ -2,7 +2,7 @@ #include "global.h" #include "Course.h" #include "CourseLoaderCRS.h" -#include "Foreach.h" + #include "GameManager.h" #include "GameState.h" #include "LocalizedString.h" diff --git a/src/CourseUtil.cpp b/src/CourseUtil.cpp index 09b3d99909..17397ba92c 100644 --- a/src/CourseUtil.cpp +++ b/src/CourseUtil.cpp @@ -8,7 +8,7 @@ #include "XmlFile.h" #include "GameState.h" #include "Style.h" -#include "Foreach.h" + #include "GameState.h" #include "LocalizedString.h" #include "RageLog.h" diff --git a/src/CsvFile.cpp b/src/CsvFile.cpp index e7d3a5d331..27a1c82f04 100644 --- a/src/CsvFile.cpp +++ b/src/CsvFile.cpp @@ -3,7 +3,6 @@ #include "RageUtil.h" #include "RageFile.h" #include "RageLog.h" -#include "Foreach.h" CsvFile::CsvFile() { diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp index 0a341feb87..6f6a3b9c9c 100644 --- a/src/DifficultyList.cpp +++ b/src/DifficultyList.cpp @@ -7,7 +7,7 @@ #include "StepsDisplay.h" #include "StepsUtil.h" #include "CommonMetrics.h" -#include "Foreach.h" + #include "SongUtil.h" #include "XmlFile.h" diff --git a/src/EditMenu.cpp b/src/EditMenu.cpp index a8d5109391..46cca2b847 100644 --- a/src/EditMenu.cpp +++ b/src/EditMenu.cpp @@ -8,7 +8,7 @@ #include "Steps.h" #include "Song.h" #include "StepsUtil.h" -#include "Foreach.h" + #include "CommonMetrics.h" #include "BannerCache.h" #include "UnlockManager.h" diff --git a/src/FileDownload.cpp b/src/FileDownload.cpp index 50a0646d24..75249845d0 100644 --- a/src/FileDownload.cpp +++ b/src/FileDownload.cpp @@ -7,7 +7,7 @@ #include "SpecialFiles.h" #include "RageLog.h" #include "Preference.h" -#include "Foreach.h" + FileTransfer::FileTransfer() { diff --git a/src/Foreach.h b/src/Foreach.h deleted file mode 100644 index 2ddee30499..0000000000 --- a/src/Foreach.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef Foreach_H -#define Foreach_H - -/** @brief General foreach loop iterating over a vector. */ -#define FOREACH( elemType, vect, var ) \ -for( vector::iterator var = (vect).begin(); var != (vect).end(); ++var ) - -#endif - -/** - * @file - * @author Chris Danford (c) 2004-2005 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ diff --git a/src/Foreground.cpp b/src/Foreground.cpp index 1fca23e0fa..a1f882cb87 100644 --- a/src/Foreground.cpp +++ b/src/Foreground.cpp @@ -6,7 +6,7 @@ #include "ActorUtil.h" #include "Song.h" #include "BackgroundUtil.h" -#include "Foreach.h" + Foreground::~Foreground() { diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index 4424102c30..f8342b2e78 100644 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -13,7 +13,7 @@ #include "PrefsManager.h" #include "Game.h" #include "Style.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" #include "GameSoundManager.h" #include "PlayerState.h" diff --git a/src/GameConstantsAndTypes.cpp b/src/GameConstantsAndTypes.cpp index 7f5a84460c..19b559f776 100644 --- a/src/GameConstantsAndTypes.cpp +++ b/src/GameConstantsAndTypes.cpp @@ -4,7 +4,7 @@ #include "RageUtil.h" #include "ThemeMetric.h" #include "EnumHelper.h" -#include "Foreach.h" + #include "LuaManager.h" #include "GameManager.h" #include "LocalizedString.h" diff --git a/src/GameManager.cpp b/src/GameManager.cpp index 340130605a..a796c8500a 100644 --- a/src/GameManager.cpp +++ b/src/GameManager.cpp @@ -10,7 +10,7 @@ #include "LightsManager.h" // for NUM_CabinetLight #include "Game.h" #include "Style.h" -#include "Foreach.h" + GameManager* GAMEMAN = NULL; // global and accessable from anywhere in our program diff --git a/src/GameState.cpp b/src/GameState.cpp index f93e484352..1a247ebd67 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -8,7 +8,7 @@ #include "CommonMetrics.h" #include "Course.h" #include "CryptManager.h" -#include "Foreach.h" + #include "Game.h" #include "GameCommand.h" #include "GameConstantsAndTypes.h" diff --git a/src/GraphDisplay.cpp b/src/GraphDisplay.cpp index 5a8327964a..ec159e7551 100644 --- a/src/GraphDisplay.cpp +++ b/src/GraphDisplay.cpp @@ -8,7 +8,7 @@ #include "RageLog.h" #include "RageMath.h" #include "StageStats.h" -#include "Foreach.h" + #include "Song.h" #include "XmlFile.h" diff --git a/src/HighScore.cpp b/src/HighScore.cpp index f95c501f84..b0ebe8bc80 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -5,7 +5,7 @@ #include "PlayerNumber.h" #include "ThemeManager.h" #include "XmlFile.h" -#include "Foreach.h" + #include "RadarValues.h" ThemeMetric EMPTY_NAME("HighScore","EmptyName"); diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 95a08d63d4..8c4e6f5004 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -9,7 +9,7 @@ http://en.wikipedia.org/wiki/INI_file #include "RageUtil.h" #include "RageLog.h" #include "RageFile.h" -#include "Foreach.h" + IniFile::IniFile(): XNode("IniFile") { diff --git a/src/InputFilter.cpp b/src/InputFilter.cpp index d5246ef260..fdd0a78535 100644 --- a/src/InputFilter.cpp +++ b/src/InputFilter.cpp @@ -5,7 +5,7 @@ #include "RageUtil.h" #include "RageThreads.h" #include "Preference.h" -#include "Foreach.h" + // for mouse stuff: -aj #include "PrefsManager.h" #include "ScreenDimensions.h" diff --git a/src/InputMapper.cpp b/src/InputMapper.cpp index 48edeba0cb..a0debb56ad 100644 --- a/src/InputMapper.cpp +++ b/src/InputMapper.cpp @@ -9,7 +9,7 @@ #include "RageInput.h" #include "SpecialFiles.h" #include "LocalizedString.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" #define AUTOMAPPINGS_DIR "/Data/AutoMappings/" diff --git a/src/InputQueue.cpp b/src/InputQueue.cpp index b692c7f0cc..e43b6574eb 100644 --- a/src/InputQueue.cpp +++ b/src/InputQueue.cpp @@ -3,7 +3,7 @@ #include "RageTimer.h" #include "RageLog.h" #include "InputEventPlus.h" -#include "Foreach.h" + #include "InputMapper.h" InputQueue* INPUTQUEUE = NULL; // global and accessable from anywhere in our program diff --git a/src/LightsManager.cpp b/src/LightsManager.cpp index 7ef32830a1..d1462e4171 100644 --- a/src/LightsManager.cpp +++ b/src/LightsManager.cpp @@ -10,7 +10,7 @@ #include "PrefsManager.h" #include "Actor.h" #include "Preference.h" -#include "Foreach.h" + #include "GameManager.h" #include "CommonMetrics.h" #include "Style.h" diff --git a/src/LocalizedString.cpp b/src/LocalizedString.cpp index 6861c16a71..8c73e52236 100644 --- a/src/LocalizedString.cpp +++ b/src/LocalizedString.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "LocalizedString.h" -#include "Foreach.h" + #include "RageUtil.h" #include "SubscriptionManager.h" diff --git a/src/LuaBinding.cpp b/src/LuaBinding.cpp index df44868641..322b82e221 100644 --- a/src/LuaBinding.cpp +++ b/src/LuaBinding.cpp @@ -2,7 +2,7 @@ #include "LuaBinding.h" #include "LuaReference.h" #include "RageUtil.h" -#include "Foreach.h" + #include "SubscriptionManager.h" static SubscriptionManager m_Subscribers; diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index b889d9bd3e..98ffeaf7c6 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -5,7 +5,7 @@ #include "RageLog.h" #include "RageFile.h" #include "RageThreads.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" #include "XmlFile.h" #include "Command.h" diff --git a/src/Makefile.am b/src/Makefile.am index a810e72f1f..0fe3771857 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -198,7 +198,7 @@ XmlFile.cpp XmlFile.h \ XmlFileUtil.cpp XmlFileUtil.h StepMania = CommandLineActions.h CommandLineActions.cpp \ -StdString.h Foreach.h \ +StdString.h \ StepMania.cpp StepMania.h \ GameLoop.cpp GameLoop.h \ global.cpp global.h \ diff --git a/src/MemoryCardManager.cpp b/src/MemoryCardManager.cpp index 7f7046ede4..b80f163385 100644 --- a/src/MemoryCardManager.cpp +++ b/src/MemoryCardManager.cpp @@ -8,7 +8,7 @@ #include "RageFileDriver.h" #include "RageFileDriverTimeout.h" #include "MessageManager.h" -#include "Foreach.h" + #include "RageUtil_WorkerThread.h" #include "arch/MemoryCard/MemoryCardDriver_Null.h" #include "LuaManager.h" diff --git a/src/MessageManager.cpp b/src/MessageManager.cpp index fc90635cad..7de4eeb563 100644 --- a/src/MessageManager.cpp +++ b/src/MessageManager.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "MessageManager.h" -#include "Foreach.h" + #include "RageUtil.h" #include "RageThreads.h" #include "EnumHelper.h" diff --git a/src/ModIconRow.cpp b/src/ModIconRow.cpp index f7461d7401..306258f59d 100644 --- a/src/ModIconRow.cpp +++ b/src/ModIconRow.cpp @@ -8,7 +8,7 @@ #include "ActorUtil.h" #include "XmlFile.h" #include "LuaManager.h" -#include "Foreach.h" + int OptionToPreferredColumn( RString sOptionText ); diff --git a/src/Model.cpp b/src/Model.cpp index de3e97b1fc..71398bcdfc 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -10,7 +10,7 @@ #include "RageLog.h" #include "ActorUtil.h" #include "ModelManager.h" -#include "Foreach.h" + #include "LuaBinding.h" #include "PrefsManager.h" diff --git a/src/ModelTypes.cpp b/src/ModelTypes.cpp index 5bd55ca4ca..25700ab352 100644 --- a/src/ModelTypes.cpp +++ b/src/ModelTypes.cpp @@ -8,7 +8,7 @@ #include "RageTextureManager.h" #include "RageLog.h" #include "RageDisplay.h" -#include "Foreach.h" + #include #define MS_MAX_NAME 32 diff --git a/src/MusicWheel.cpp b/src/MusicWheel.cpp index 0597cb5150..e1b79ab77b 100644 --- a/src/MusicWheel.cpp +++ b/src/MusicWheel.cpp @@ -16,7 +16,7 @@ #include "ActorUtil.h" #include "SongUtil.h" #include "CourseUtil.h" -#include "Foreach.h" + #include "Style.h" #include "PlayerState.h" #include "CommonMetrics.h" diff --git a/src/NoteData.cpp b/src/NoteData.cpp index fbbd15fb94..33b43908ab 100644 --- a/src/NoteData.cpp +++ b/src/NoteData.cpp @@ -10,7 +10,7 @@ #include "RageLog.h" #include "XmlFile.h" #include "GameState.h" // blame radar calculations. -#include "Foreach.h" + #include "RageUtil_AutoPtr.h" REGISTER_CLASS_TRAITS( NoteData, new NoteData(*pCopy) ) diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index 906c665378..6a19a5eef9 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -8,7 +8,7 @@ #include "Style.h" #include "GameState.h" #include "RadarValues.h" -#include "Foreach.h" + #include // TODO: Remove these constants that aren't time signature-aware diff --git a/src/NoteDisplay.cpp b/src/NoteDisplay.cpp index edc56154a7..9a2d2d7548 100644 --- a/src/NoteDisplay.cpp +++ b/src/NoteDisplay.cpp @@ -11,7 +11,7 @@ #include "Sprite.h" #include "NoteTypes.h" #include "LuaBinding.h" -#include "Foreach.h" + #include "RageMath.h" const RString& NoteNotePartToString( NotePart i ); diff --git a/src/NoteSkinManager.cpp b/src/NoteSkinManager.cpp index 600adf444d..5ab86677a5 100644 --- a/src/NoteSkinManager.cpp +++ b/src/NoteSkinManager.cpp @@ -10,7 +10,7 @@ #include "RageDisplay.h" #include "arch/Dialog/Dialog.h" #include "PrefsManager.h" -#include "Foreach.h" + #include "ActorUtil.h" #include "XmlFileUtil.h" #include "Sprite.h" diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index 282903e5ca..5f0a404263 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -3,7 +3,7 @@ #include #include "NotesWriterSM.h" #include "BackgroundUtil.h" -#include "Foreach.h" + #include "GameManager.h" #include "LocalizedString.h" #include "NoteTypes.h" diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 42f9ad149a..c3d35ed581 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -3,7 +3,7 @@ #include #include "NotesWriterSSC.h" #include "BackgroundUtil.h" -#include "Foreach.h" + #include "GameManager.h" #include "LocalizedString.h" #include "NoteTypes.h" diff --git a/src/OptionRow.cpp b/src/OptionRow.cpp index 752bafc916..e1997060e9 100644 --- a/src/OptionRow.cpp +++ b/src/OptionRow.cpp @@ -2,7 +2,7 @@ #include "OptionRow.h" #include "RageUtil.h" #include "RageLog.h" -#include "Foreach.h" + #include "OptionRowHandler.h" #include "CommonMetrics.h" #include "GameState.h" diff --git a/src/OptionRowHandler.cpp b/src/OptionRowHandler.cpp index 9eee1400b6..a904b10f84 100644 --- a/src/OptionRowHandler.cpp +++ b/src/OptionRowHandler.cpp @@ -16,7 +16,7 @@ #include "SongUtil.h" #include "StepsUtil.h" #include "GameManager.h" -#include "Foreach.h" + #include "GameSoundManager.h" #include "CommonMetrics.h" #include "CharacterManager.h" diff --git a/src/PaneDisplay.cpp b/src/PaneDisplay.cpp index 7b91953552..a628911afa 100644 --- a/src/PaneDisplay.cpp +++ b/src/PaneDisplay.cpp @@ -1,331 +1,331 @@ -#include "global.h" -#include "PaneDisplay.h" -#include "ThemeManager.h" -#include "GameState.h" -#include "Song.h" -#include "Steps.h" -#include "RageLog.h" -#include "ProfileManager.h" -#include "Profile.h" -#include "Course.h" -#include "Style.h" -#include "ActorUtil.h" -#include "Foreach.h" -#include "LuaManager.h" -#include "XmlFile.h" -#include "PlayerStageStats.h" - -#define SHIFT_X(pc) THEME->GetMetricF(sMetricsGroup, ssprintf("ShiftP%iX", pc+1)) -#define SHIFT_Y(pc) THEME->GetMetricF(sMetricsGroup, ssprintf("ShiftP%iY", pc+1)) - -static const char *PaneCategoryNames[] = { - "NumSteps", - "Jumps", - "Holds", - "Rolls", - "Mines", - "Hands", - "Lifts", - "Fakes", - "MachineHighScore", - "MachineHighName", - "ProfileHighScore", -}; -XToString( PaneCategory ); -LuaXType( PaneCategory ); - - -enum { NEED_NOTES=1, NEED_PROFILE=2 }; -struct Content_t -{ - int req; - RString sFontType; -}; - -static const Content_t g_Contents[NUM_PaneCategory] = -{ - { NEED_NOTES, "count" }, // NumSteps - { NEED_NOTES, "count" }, // Jumps - { NEED_NOTES, "count" }, // Holds - { NEED_NOTES, "count" }, // Rolls - { NEED_NOTES, "count" }, // Mines - { NEED_NOTES, "count" }, // Hands - { NEED_NOTES, "count" }, // Lifts - { NEED_NOTES, "count" }, // Fakes - { NEED_NOTES, "score" }, // MachineHighScore - { NEED_NOTES, "name" }, // MachineHighName - { NEED_NOTES|NEED_PROFILE, "score" }, // ProfileHighScore -}; - -REGISTER_ACTOR_CLASS( PaneDisplay ); - -void PaneDisplay::Load( const RString &sMetricsGroup, PlayerNumber pn ) -{ - m_PlayerNumber = pn; - - EMPTY_MACHINE_HIGH_SCORE_NAME.Load( sMetricsGroup, "EmptyMachineHighScoreName" ); - NOT_AVAILABLE.Load( sMetricsGroup, "NotAvailable" ); - COUNT_FORMAT.Load( sMetricsGroup, "CountFormat" ); - NULL_COUNT_STRING.Load( sMetricsGroup, "NullCountString" ); - - FOREACH_ENUM( PaneCategory, pc ) - { - LuaThreadVariable var( "PaneCategory", LuaReference::Create(pc) ); - - RString sFontType = g_Contents[pc].sFontType; - - m_textContents[pc].LoadFromFont( THEME->GetPathF(sMetricsGroup,sFontType) ); - m_textContents[pc].SetName( PaneCategoryToString(pc) + "Text" ); - ActorUtil::LoadAllCommands( m_textContents[pc], sMetricsGroup ); - ActorUtil::SetXY( m_textContents[pc], sMetricsGroup ); - m_ContentsFrame.AddChild( &m_textContents[pc] ); - - m_Labels[pc].Load( THEME->GetPathG(sMetricsGroup,"label " + PaneCategoryToString(pc)) ); - m_Labels[pc]->SetName( PaneCategoryToString(pc) + "Label" ); - ActorUtil::LoadAllCommands( *m_Labels[pc], sMetricsGroup ); - ActorUtil::SetXY( m_Labels[pc], sMetricsGroup ); - m_ContentsFrame.AddChild( m_Labels[pc] ); - - ActorUtil::LoadAllCommandsFromName( m_textContents[pc], sMetricsGroup, PaneCategoryToString(pc) ); - } - - m_ContentsFrame.SetXY( SHIFT_X(m_PlayerNumber), SHIFT_Y(m_PlayerNumber) ); - this->AddChild( &m_ContentsFrame ); -} - -void PaneDisplay::LoadFromNode( const XNode *pNode ) -{ - bool b; - - RString sMetricsGroup; - b = pNode->GetAttrValue( "MetricsGroup", sMetricsGroup ); - ASSERT( b ); - - Lua *L = LUA->Get(); - b = pNode->PushAttrValue( L, "PlayerNumber" ); - ASSERT( b ); - PlayerNumber pn; - LuaHelpers::Pop( L, pn ); - LUA->Release( L ); - - Load( sMetricsGroup, pn ); - - ActorFrame::LoadFromNode( pNode ); -} - -void PaneDisplay::GetPaneTextAndLevel( PaneCategory c, RString & sTextOut, float & fLevelOut ) -{ - const Song *pSong = GAMESTATE->m_pCurSong; - const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; - const Course *pCourse = GAMESTATE->m_pCurCourse; - const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber]; - const Profile *pProfile = PROFILEMAN->IsPersistentProfile(m_PlayerNumber) ? PROFILEMAN->GetProfile(m_PlayerNumber) : NULL; - bool bIsPlayerEdit = pSteps && pSteps->IsAPlayerEdit(); - - // Defaults, will be filled in later - sTextOut = NULL_COUNT_STRING; - fLevelOut = 0; - - if(GAMESTATE->IsCourseMode() && !pTrail) - { - if( (g_Contents[c].req&NEED_PROFILE) ) - sTextOut = NOT_AVAILABLE; - - { - switch( c ) - { - case PaneCategory_MachineHighName: - sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; - break; - case PaneCategory_MachineHighScore: - case PaneCategory_ProfileHighScore: - sTextOut = NOT_AVAILABLE; - break; - default: break; - } - } - - return; - } - else if(!GAMESTATE->IsCourseMode() && !pSong) - { - if( (g_Contents[c].req&NEED_PROFILE) ) - sTextOut = NOT_AVAILABLE; - - { - switch( c ) - { - case PaneCategory_MachineHighName: - sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; - break; - case PaneCategory_MachineHighScore: - case PaneCategory_ProfileHighScore: - sTextOut = NOT_AVAILABLE; - break; - default: break; - } - } - - return; - } - - if( (g_Contents[c].req&NEED_NOTES) && !pSteps && !pTrail ) - return; - if( (g_Contents[c].req&NEED_PROFILE) && !pProfile ) - { - sTextOut = NOT_AVAILABLE; - return; - } - - { - RadarValues rv; - HighScoreList *pHSL = NULL; - ProfileSlot slot = ProfileSlot_Machine; - switch( c ) - { - case PaneCategory_ProfileHighScore: - slot = (ProfileSlot) m_PlayerNumber; - default: break; - } - - if( pSteps ) - { - rv = pSteps->GetRadarValues( m_PlayerNumber ); - pHSL = &PROFILEMAN->GetProfile(slot)->GetStepsHighScoreList(pSong, pSteps); - } - else if( pTrail ) - { - rv = pTrail->GetRadarValues(); - pHSL = &PROFILEMAN->GetProfile(slot)->GetCourseHighScoreList(pCourse, pTrail); - } - - switch( c ) - { - case PaneCategory_NumSteps: fLevelOut = rv[RadarCategory_TapsAndHolds]; break; - case PaneCategory_Jumps: fLevelOut = rv[RadarCategory_Jumps]; break; - case PaneCategory_Holds: fLevelOut = rv[RadarCategory_Holds]; break; - case PaneCategory_Rolls: fLevelOut = rv[RadarCategory_Rolls]; break; - case PaneCategory_Mines: fLevelOut = rv[RadarCategory_Mines]; break; - case PaneCategory_Hands: fLevelOut = rv[RadarCategory_Hands]; break; - case PaneCategory_Lifts: fLevelOut = rv[RadarCategory_Lifts]; break; - case PaneCategory_Fakes: fLevelOut = rv[RadarCategory_Fakes]; break; - case PaneCategory_ProfileHighScore: - case PaneCategory_MachineHighName: // set fLevelOut for color - case PaneCategory_MachineHighScore: - CHECKPOINT; - fLevelOut = pHSL->GetTopScore().GetPercentDP(); - break; - default: break; - }; - - if( fLevelOut != RADAR_VAL_UNKNOWN ) - { - switch( c ) - { - case PaneCategory_MachineHighName: - if( pHSL->vHighScores.empty() ) - { - sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; - } - else - { - sTextOut = pHSL->GetTopScore().GetName(); - if( sTextOut.empty() ) - sTextOut = "????"; - } - break; - case PaneCategory_MachineHighScore: - case PaneCategory_ProfileHighScore: - // Don't show or save machine high scores for edits loaded from a player profile. - if( bIsPlayerEdit ) - sTextOut = NOT_AVAILABLE; - else - sTextOut = PlayerStageStats::FormatPercentScore( fLevelOut ); - break; - case PaneCategory_NumSteps: - case PaneCategory_Jumps: - case PaneCategory_Holds: - case PaneCategory_Rolls: - case PaneCategory_Mines: - case PaneCategory_Hands: - case PaneCategory_Lifts: - case PaneCategory_Fakes: - sTextOut = ssprintf( COUNT_FORMAT.GetValue(), fLevelOut ); - break; - default: break; - } - } - } -} - -void PaneDisplay::SetContent( PaneCategory c ) -{ - // these get filled in later: - RString str; - float val; - - GetPaneTextAndLevel( c, str, val ); - m_textContents[c].SetText( str ); - - Lua *L = LUA->Get(); - - m_textContents[c].PushSelf( L ); - lua_pushstring( L, "PaneLevel" ); - lua_pushnumber( L, val ); - lua_settable( L, -3 ); - lua_pop( L, 1 ); - - m_textContents[c].PlayCommand( "Level" ); - - LUA->Release(L); -} - -void PaneDisplay::SetFromGameState() -{ - // Don't update text that doesn't apply to the current mode. It's still tweening off. - FOREACH_ENUM( PaneCategory, i ) - SetContent( i ); -} - -// lua start -#include "LuaBinding.h" - -/** @brief Allow Lua to have access to the PaneDisplay. */ -class LunaPaneDisplay: public Luna -{ -public: - static int SetFromGameState( T* pc, lua_State *L ) { pc->SetFromGameState(); return 0; } - - LunaPaneDisplay() - { - ADD_METHOD( SetFromGameState ); - } -}; - -LUA_REGISTER_DERIVED_CLASS( PaneDisplay, ActorFrame ) -// lua end - -/* - * (c) 2003 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "PaneDisplay.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "Song.h" +#include "Steps.h" +#include "RageLog.h" +#include "ProfileManager.h" +#include "Profile.h" +#include "Course.h" +#include "Style.h" +#include "ActorUtil.h" + +#include "LuaManager.h" +#include "XmlFile.h" +#include "PlayerStageStats.h" + +#define SHIFT_X(pc) THEME->GetMetricF(sMetricsGroup, ssprintf("ShiftP%iX", pc+1)) +#define SHIFT_Y(pc) THEME->GetMetricF(sMetricsGroup, ssprintf("ShiftP%iY", pc+1)) + +static const char *PaneCategoryNames[] = { + "NumSteps", + "Jumps", + "Holds", + "Rolls", + "Mines", + "Hands", + "Lifts", + "Fakes", + "MachineHighScore", + "MachineHighName", + "ProfileHighScore", +}; +XToString( PaneCategory ); +LuaXType( PaneCategory ); + + +enum { NEED_NOTES=1, NEED_PROFILE=2 }; +struct Content_t +{ + int req; + RString sFontType; +}; + +static const Content_t g_Contents[NUM_PaneCategory] = +{ + { NEED_NOTES, "count" }, // NumSteps + { NEED_NOTES, "count" }, // Jumps + { NEED_NOTES, "count" }, // Holds + { NEED_NOTES, "count" }, // Rolls + { NEED_NOTES, "count" }, // Mines + { NEED_NOTES, "count" }, // Hands + { NEED_NOTES, "count" }, // Lifts + { NEED_NOTES, "count" }, // Fakes + { NEED_NOTES, "score" }, // MachineHighScore + { NEED_NOTES, "name" }, // MachineHighName + { NEED_NOTES|NEED_PROFILE, "score" }, // ProfileHighScore +}; + +REGISTER_ACTOR_CLASS( PaneDisplay ); + +void PaneDisplay::Load( const RString &sMetricsGroup, PlayerNumber pn ) +{ + m_PlayerNumber = pn; + + EMPTY_MACHINE_HIGH_SCORE_NAME.Load( sMetricsGroup, "EmptyMachineHighScoreName" ); + NOT_AVAILABLE.Load( sMetricsGroup, "NotAvailable" ); + COUNT_FORMAT.Load( sMetricsGroup, "CountFormat" ); + NULL_COUNT_STRING.Load( sMetricsGroup, "NullCountString" ); + + FOREACH_ENUM( PaneCategory, pc ) + { + LuaThreadVariable var( "PaneCategory", LuaReference::Create(pc) ); + + RString sFontType = g_Contents[pc].sFontType; + + m_textContents[pc].LoadFromFont( THEME->GetPathF(sMetricsGroup,sFontType) ); + m_textContents[pc].SetName( PaneCategoryToString(pc) + "Text" ); + ActorUtil::LoadAllCommands( m_textContents[pc], sMetricsGroup ); + ActorUtil::SetXY( m_textContents[pc], sMetricsGroup ); + m_ContentsFrame.AddChild( &m_textContents[pc] ); + + m_Labels[pc].Load( THEME->GetPathG(sMetricsGroup,"label " + PaneCategoryToString(pc)) ); + m_Labels[pc]->SetName( PaneCategoryToString(pc) + "Label" ); + ActorUtil::LoadAllCommands( *m_Labels[pc], sMetricsGroup ); + ActorUtil::SetXY( m_Labels[pc], sMetricsGroup ); + m_ContentsFrame.AddChild( m_Labels[pc] ); + + ActorUtil::LoadAllCommandsFromName( m_textContents[pc], sMetricsGroup, PaneCategoryToString(pc) ); + } + + m_ContentsFrame.SetXY( SHIFT_X(m_PlayerNumber), SHIFT_Y(m_PlayerNumber) ); + this->AddChild( &m_ContentsFrame ); +} + +void PaneDisplay::LoadFromNode( const XNode *pNode ) +{ + bool b; + + RString sMetricsGroup; + b = pNode->GetAttrValue( "MetricsGroup", sMetricsGroup ); + ASSERT( b ); + + Lua *L = LUA->Get(); + b = pNode->PushAttrValue( L, "PlayerNumber" ); + ASSERT( b ); + PlayerNumber pn; + LuaHelpers::Pop( L, pn ); + LUA->Release( L ); + + Load( sMetricsGroup, pn ); + + ActorFrame::LoadFromNode( pNode ); +} + +void PaneDisplay::GetPaneTextAndLevel( PaneCategory c, RString & sTextOut, float & fLevelOut ) +{ + const Song *pSong = GAMESTATE->m_pCurSong; + const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; + const Course *pCourse = GAMESTATE->m_pCurCourse; + const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber]; + const Profile *pProfile = PROFILEMAN->IsPersistentProfile(m_PlayerNumber) ? PROFILEMAN->GetProfile(m_PlayerNumber) : NULL; + bool bIsPlayerEdit = pSteps && pSteps->IsAPlayerEdit(); + + // Defaults, will be filled in later + sTextOut = NULL_COUNT_STRING; + fLevelOut = 0; + + if(GAMESTATE->IsCourseMode() && !pTrail) + { + if( (g_Contents[c].req&NEED_PROFILE) ) + sTextOut = NOT_AVAILABLE; + + { + switch( c ) + { + case PaneCategory_MachineHighName: + sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; + break; + case PaneCategory_MachineHighScore: + case PaneCategory_ProfileHighScore: + sTextOut = NOT_AVAILABLE; + break; + default: break; + } + } + + return; + } + else if(!GAMESTATE->IsCourseMode() && !pSong) + { + if( (g_Contents[c].req&NEED_PROFILE) ) + sTextOut = NOT_AVAILABLE; + + { + switch( c ) + { + case PaneCategory_MachineHighName: + sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; + break; + case PaneCategory_MachineHighScore: + case PaneCategory_ProfileHighScore: + sTextOut = NOT_AVAILABLE; + break; + default: break; + } + } + + return; + } + + if( (g_Contents[c].req&NEED_NOTES) && !pSteps && !pTrail ) + return; + if( (g_Contents[c].req&NEED_PROFILE) && !pProfile ) + { + sTextOut = NOT_AVAILABLE; + return; + } + + { + RadarValues rv; + HighScoreList *pHSL = NULL; + ProfileSlot slot = ProfileSlot_Machine; + switch( c ) + { + case PaneCategory_ProfileHighScore: + slot = (ProfileSlot) m_PlayerNumber; + default: break; + } + + if( pSteps ) + { + rv = pSteps->GetRadarValues( m_PlayerNumber ); + pHSL = &PROFILEMAN->GetProfile(slot)->GetStepsHighScoreList(pSong, pSteps); + } + else if( pTrail ) + { + rv = pTrail->GetRadarValues(); + pHSL = &PROFILEMAN->GetProfile(slot)->GetCourseHighScoreList(pCourse, pTrail); + } + + switch( c ) + { + case PaneCategory_NumSteps: fLevelOut = rv[RadarCategory_TapsAndHolds]; break; + case PaneCategory_Jumps: fLevelOut = rv[RadarCategory_Jumps]; break; + case PaneCategory_Holds: fLevelOut = rv[RadarCategory_Holds]; break; + case PaneCategory_Rolls: fLevelOut = rv[RadarCategory_Rolls]; break; + case PaneCategory_Mines: fLevelOut = rv[RadarCategory_Mines]; break; + case PaneCategory_Hands: fLevelOut = rv[RadarCategory_Hands]; break; + case PaneCategory_Lifts: fLevelOut = rv[RadarCategory_Lifts]; break; + case PaneCategory_Fakes: fLevelOut = rv[RadarCategory_Fakes]; break; + case PaneCategory_ProfileHighScore: + case PaneCategory_MachineHighName: // set fLevelOut for color + case PaneCategory_MachineHighScore: + CHECKPOINT; + fLevelOut = pHSL->GetTopScore().GetPercentDP(); + break; + default: break; + }; + + if( fLevelOut != RADAR_VAL_UNKNOWN ) + { + switch( c ) + { + case PaneCategory_MachineHighName: + if( pHSL->vHighScores.empty() ) + { + sTextOut = EMPTY_MACHINE_HIGH_SCORE_NAME; + } + else + { + sTextOut = pHSL->GetTopScore().GetName(); + if( sTextOut.empty() ) + sTextOut = "????"; + } + break; + case PaneCategory_MachineHighScore: + case PaneCategory_ProfileHighScore: + // Don't show or save machine high scores for edits loaded from a player profile. + if( bIsPlayerEdit ) + sTextOut = NOT_AVAILABLE; + else + sTextOut = PlayerStageStats::FormatPercentScore( fLevelOut ); + break; + case PaneCategory_NumSteps: + case PaneCategory_Jumps: + case PaneCategory_Holds: + case PaneCategory_Rolls: + case PaneCategory_Mines: + case PaneCategory_Hands: + case PaneCategory_Lifts: + case PaneCategory_Fakes: + sTextOut = ssprintf( COUNT_FORMAT.GetValue(), fLevelOut ); + break; + default: break; + } + } + } +} + +void PaneDisplay::SetContent( PaneCategory c ) +{ + // these get filled in later: + RString str; + float val; + + GetPaneTextAndLevel( c, str, val ); + m_textContents[c].SetText( str ); + + Lua *L = LUA->Get(); + + m_textContents[c].PushSelf( L ); + lua_pushstring( L, "PaneLevel" ); + lua_pushnumber( L, val ); + lua_settable( L, -3 ); + lua_pop( L, 1 ); + + m_textContents[c].PlayCommand( "Level" ); + + LUA->Release(L); +} + +void PaneDisplay::SetFromGameState() +{ + // Don't update text that doesn't apply to the current mode. It's still tweening off. + FOREACH_ENUM( PaneCategory, i ) + SetContent( i ); +} + +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the PaneDisplay. */ +class LunaPaneDisplay: public Luna +{ +public: + static int SetFromGameState( T* pc, lua_State *L ) { pc->SetFromGameState(); return 0; } + + LunaPaneDisplay() + { + ADD_METHOD( SetFromGameState ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( PaneDisplay, ActorFrame ) +// lua end + +/* + * (c) 2003 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index c8c66a2e3e..2eaadb93d7 100644 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -7,7 +7,7 @@ #include "Course.h" #include "Steps.h" #include "ThemeManager.h" -#include "Foreach.h" + #include "Style.h" #include "CommonMetrics.h" #include diff --git a/src/PlayerStageStats.cpp b/src/PlayerStageStats.cpp index 88c50d67c2..8b358f1cbf 100644 --- a/src/PlayerStageStats.cpp +++ b/src/PlayerStageStats.cpp @@ -2,7 +2,7 @@ #include "PlayerStageStats.h" #include "RageLog.h" #include "ThemeManager.h" -#include "Foreach.h" + #include "LuaManager.h" #include #include diff --git a/src/PlayerState.cpp b/src/PlayerState.cpp index 7385a9550b..a43fa16387 100644 --- a/src/PlayerState.cpp +++ b/src/PlayerState.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "PlayerState.h" -#include "Foreach.h" + #include "GameState.h" #include "RageLog.h" #include "RadarValues.h" diff --git a/src/Preference.cpp b/src/Preference.cpp index aa42be51ae..c16927cd87 100644 --- a/src/Preference.cpp +++ b/src/Preference.cpp @@ -5,7 +5,7 @@ #include "LuaManager.h" #include "MessageManager.h" #include "SubscriptionManager.h" -#include "Foreach.h" + static SubscriptionManager m_Subscribers; diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index 24c3a43c79..f4a0b54ce6 100644 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "PrefsManager.h" -#include "Foreach.h" + #include "IniFile.h" #include "LuaManager.h" #include "Preference.h" diff --git a/src/Profile.cpp b/src/Profile.cpp index 053aa06d62..e84435f1f8 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -20,7 +20,7 @@ #include "UnlockManager.h" #include "XmlFile.h" #include "XmlFileUtil.h" -#include "Foreach.h" + #include "Game.h" #include "CharacterManager.h" #include "Character.h" diff --git a/src/RageDisplay_OGL.cpp b/src/RageDisplay_OGL.cpp index e3e781af40..4bb96a7595 100644 --- a/src/RageDisplay_OGL.cpp +++ b/src/RageDisplay_OGL.cpp @@ -14,7 +14,7 @@ using namespace RageDisplay_Legacy_Helpers; #include "RageTypes.h" #include "RageUtil.h" #include "EnumHelper.h" -#include "Foreach.h" + #include "DisplayResolutions.h" #include "LocalizedString.h" diff --git a/src/RageFileDriverDirectHelpers.cpp b/src/RageFileDriverDirectHelpers.cpp index 462513ff55..cb95a86d49 100644 --- a/src/RageFileDriverDirectHelpers.cpp +++ b/src/RageFileDriverDirectHelpers.cpp @@ -2,7 +2,7 @@ #include "RageFileDriverDirectHelpers.h" #include "RageUtil.h" #include "RageLog.h" -#include "Foreach.h" + #include #include diff --git a/src/RageFileManager.cpp b/src/RageFileManager.cpp index 8b2d018cd1..4535c13f55 100644 --- a/src/RageFileManager.cpp +++ b/src/RageFileManager.cpp @@ -6,7 +6,7 @@ #include "RageUtil_FileDB.h" #include "RageLog.h" #include "RageThreads.h" -#include "Foreach.h" + #include "arch/ArchHooks/ArchHooks.h" #include "LuaManager.h" diff --git a/src/RageInput.cpp b/src/RageInput.cpp index ef208ea725..bfabb8f275 100644 --- a/src/RageInput.cpp +++ b/src/RageInput.cpp @@ -2,7 +2,7 @@ #include "RageInput.h" #include "RageLog.h" #include "arch/InputHandler/InputHandler.h" -#include "Foreach.h" + #include "Preference.h" #include "LuaManager.h" #include "LocalizedString.h" diff --git a/src/RageInputDevice.cpp b/src/RageInputDevice.cpp index 4adc35258c..acc37c8979 100644 --- a/src/RageInputDevice.cpp +++ b/src/RageInputDevice.cpp @@ -4,7 +4,7 @@ #include "global.h" #include "RageInputDevice.h" #include "RageUtil.h" -#include "Foreach.h" + #include "LocalizedString.h" static const char *InputDeviceStateNames[] = { diff --git a/src/RageLog.cpp b/src/RageLog.cpp index 109dcfba6b..50d6479399 100644 --- a/src/RageLog.cpp +++ b/src/RageLog.cpp @@ -4,7 +4,7 @@ #include "RageTimer.h" #include "RageFile.h" #include "RageThreads.h" -#include "Foreach.h" + #include #if defined(_WINDOWS) diff --git a/src/RageSoundManager.cpp b/src/RageSoundManager.cpp index 8dd322378e..7b64440daa 100644 --- a/src/RageSoundManager.cpp +++ b/src/RageSoundManager.cpp @@ -15,7 +15,7 @@ #include "RageLog.h" #include "RageTimer.h" #include "RageSoundReader_Preload.h" -#include "Foreach.h" + #include "LocalizedString.h" #include "Preference.h" diff --git a/src/RageSoundPosMap.cpp b/src/RageSoundPosMap.cpp index 45208ee438..aca3f0b70b 100644 --- a/src/RageSoundPosMap.cpp +++ b/src/RageSoundPosMap.cpp @@ -3,7 +3,7 @@ #include "RageLog.h" #include "RageUtil.h" #include "RageTimer.h" -#include "Foreach.h" + #include diff --git a/src/RageSoundReader_Chain.cpp b/src/RageSoundReader_Chain.cpp index d1330a7245..6174a8a83a 100644 --- a/src/RageSoundReader_Chain.cpp +++ b/src/RageSoundReader_Chain.cpp @@ -8,7 +8,7 @@ #include "RageUtil.h" #include "RageSoundMixBuffer.h" #include "RageSoundUtil.h" -#include "Foreach.h" + /* * Keyed sounds should pass this object to SoundReader_Preload, to preprocess it. diff --git a/src/RageSoundReader_ChannelSplit.cpp b/src/RageSoundReader_ChannelSplit.cpp index 2500d99418..5bd294a013 100644 --- a/src/RageSoundReader_ChannelSplit.cpp +++ b/src/RageSoundReader_ChannelSplit.cpp @@ -38,7 +38,7 @@ #include "RageUtil.h" #include "RageSoundMixBuffer.h" #include "RageSoundUtil.h" -#include "Foreach.h" + #include class RageSoundReader_Split; diff --git a/src/RageSoundReader_Merge.cpp b/src/RageSoundReader_Merge.cpp index de6e08dc2a..776a23c5d6 100644 --- a/src/RageSoundReader_Merge.cpp +++ b/src/RageSoundReader_Merge.cpp @@ -6,7 +6,7 @@ #include "RageUtil.h" #include "RageSoundMixBuffer.h" #include "RageSoundUtil.h" -#include "Foreach.h" + RageSoundReader_Merge::RageSoundReader_Merge() { diff --git a/src/RageSoundReader_ThreadedBuffer.cpp b/src/RageSoundReader_ThreadedBuffer.cpp index b14de5afb3..a8f464ce65 100644 --- a/src/RageSoundReader_ThreadedBuffer.cpp +++ b/src/RageSoundReader_ThreadedBuffer.cpp @@ -1,377 +1,377 @@ -#include "global.h" -#include "RageSoundReader_ThreadedBuffer.h" -#include "RageUtil.h" -#include "RageTimer.h" -#include "Foreach.h" -#include "RageLog.h" - -#if !defined(_WINDOWS) -#include -#endif - -/* Implement threaded read-ahead buffering. - * - * If a buffer is low on data, keep filling until it has a g_iMinFillFrames. - * Once beyond that, fill at a rate relative to realtime. - * - * This allows a stream to have a large buffer, for higher reliability, without - * causing major CPU bursts when the stream starts or underruns. Filling 32k - * takes more CPU than filling 4k frames, and may cause a skip. */ - -// The amount of data to read at once: -static const unsigned g_iReadBlockSizeFrames = 1024; - -// The maximum number of frames to buffer: -static const int g_iStreamingBufferFrames = 1024*32; - -/* When a sound has fewer than g_iMinFillFrames buffered, buffer at maximum speed. - * Once beyond that, fill at a limited rate. */ -static const int g_iMinFillFrames = 1024*4; - -RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( RageSoundReader *pSource ): - RageSoundReader_Filter( pSource ), - m_Event( "ThreadedBuffer" ) -{ - m_iSampleRate = pSource->GetSampleRate(); - m_iChannels = pSource->GetNumChannels(); - - int iFrameSize = sizeof(float) * this->GetNumChannels(); - m_DataBuffer.reserve( g_iStreamingBufferFrames * iFrameSize, iFrameSize ); - - m_bEOF = false; - m_bShutdownThread = false; - m_bEnabled = false; - m_bFilling = false; - - m_StreamPosition.push_back( Mapping() ); - m_StreamPosition.back().iPositionOfFirstFrame = pSource->GetNextSourceFrame(); - m_StreamPosition.back().fRate = pSource->GetStreamToSourceRatio(); - - m_Thread.SetName( "Streaming sound buffering" ); - m_Thread.Create( StartBufferingThread, this ); -} - -RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( const RageSoundReader_ThreadedBuffer &cpy ): - RageSoundReader_Filter( NULL ), // don't touch m_pSource before DisableBuffering - m_Event( "ThreadedBuffer" ) -{ - bool bWasEnabled = cpy.DisableBuffering(); - - m_pSource = cpy.m_pSource->Copy(); - m_iSampleRate = cpy.m_iSampleRate; - m_iChannels = cpy.m_iChannels; - m_DataBuffer = cpy.m_DataBuffer; - m_bEOF = cpy.m_bEOF; - m_bShutdownThread = cpy.m_bShutdownThread; - m_bEnabled = cpy.m_bEnabled; - m_bFilling = cpy.m_bFilling; - - m_StreamPosition = cpy.m_StreamPosition; - - m_Thread.Create( StartBufferingThread, this ); - - if( bWasEnabled ) - { - cpy.EnableBuffering(); - EnableBuffering(); - } -} - -RageSoundReader_ThreadedBuffer::~RageSoundReader_ThreadedBuffer() -{ - DisableBuffering(); - m_Event.Lock(); - m_bShutdownThread = true; - m_Event.Broadcast(); - m_Event.Unlock(); - - m_Thread.Wait(); -} - -void RageSoundReader_ThreadedBuffer::EnableBuffering() -{ - m_Event.Lock(); - m_bEnabled = true; - m_Event.Broadcast(); - m_Event.Unlock(); -} - -bool RageSoundReader_ThreadedBuffer::DisableBuffering() -{ - m_Event.Lock(); - bool bRet = m_bEnabled; - m_bEnabled = false; - m_Event.Broadcast(); - - while( m_bFilling ) - m_Event.Wait(); - - m_Event.Unlock(); - - return bRet; -} - -void RageSoundReader_ThreadedBuffer::WaitUntilFrames( int iWaitUntilFrames ) -{ - m_Event.Lock(); - ASSERT( m_bEnabled ); - while( GetFilledFrames() < iWaitUntilFrames ) - m_Event.Wait(); - m_Event.Unlock(); -} - -int RageSoundReader_ThreadedBuffer::SetPosition( int iFrame ) -{ - bool bWasEnabled = DisableBuffering(); - - m_DataBuffer.clear(); - - int iRet = RageSoundReader_Filter::SetPosition( iFrame ); - - m_StreamPosition.clear(); - m_StreamPosition.push_back( Mapping() ); - m_StreamPosition.back().iPositionOfFirstFrame = iFrame; - - m_bEOF = iRet == 0; - - if( bWasEnabled ) - EnableBuffering(); - - return iRet; -} - -int RageSoundReader_ThreadedBuffer::GetEmptyFrames() const -{ - int iSamplesPerFrame = this->GetNumChannels(); - if( g_iReadBlockSizeFrames * iSamplesPerFrame > m_DataBuffer.num_writable() ) - return 0; - return m_DataBuffer.num_writable() / iSamplesPerFrame; -} - -int RageSoundReader_ThreadedBuffer::GetFilledFrames() const -{ - int iSamplesPerFrame = this->GetNumChannels(); - return m_DataBuffer.num_readable() / iSamplesPerFrame; -} - -int RageSoundReader_ThreadedBuffer::GetNextSourceFrame() const -{ - m_Event.Lock(); - int iRet = m_StreamPosition.front().iPositionOfFirstFrame; - m_Event.Unlock(); - return iRet; -} - -float RageSoundReader_ThreadedBuffer::GetStreamToSourceRatio() const -{ - m_Event.Lock(); - float fRet = m_StreamPosition.front().fRate; - m_Event.Unlock(); - return fRet; -} - -int RageSoundReader_ThreadedBuffer::GetLength() const -{ - bool bWasEnabled = DisableBuffering(); - int iRet = m_pSource->GetLength(); - if( bWasEnabled ) - EnableBuffering(); - return iRet; -} -int RageSoundReader_ThreadedBuffer::GetLength_Fast() const -{ - bool bWasEnabled = DisableBuffering(); - int iRet = m_pSource->GetLength_Fast(); - if( bWasEnabled ) - EnableBuffering(); - return iRet; -} - -bool RageSoundReader_ThreadedBuffer::SetProperty( const RString &sProperty, float fValue ) -{ - return m_pSource->SetProperty( sProperty, fValue ); -} - -void RageSoundReader_ThreadedBuffer::BufferingThread() -{ - m_Event.Lock(); - while( !m_bShutdownThread ) - { - if( !m_bEnabled ) - { - m_Event.Wait(); - continue; - } - - // Fill some data. - m_bFilling = true; - - int iFramesToFill = g_iReadBlockSizeFrames; - if( GetFilledFrames() < g_iMinFillFrames ) - iFramesToFill = max( iFramesToFill, g_iMinFillFrames - GetFilledFrames() ); - - int iRet = FillFrames( iFramesToFill ); - - // Release m_bFilling, and signal the event to wake anyone waiting for it. - m_bFilling = false; - m_Event.Broadcast(); - - // On error or end of file, stop buffering the sound. - if( iRet < 0 ) - { - m_bEnabled = false; - continue; - } - - /* Sleep proportionately to the amount of data we buffered, so we - * fill at a reasonable pace. */ - float fTimeFilled = float(g_iReadBlockSizeFrames) / m_iSampleRate; - float fTimeToSleep = fTimeFilled / 2; - if( fTimeToSleep == 0 ) - fTimeToSleep = float(g_iReadBlockSizeFrames) / m_iSampleRate; - - if( m_Event.WaitTimeoutSupported() ) - { - RageTimer time; - time.Touch(); - time += fTimeToSleep; - m_Event.Wait( &time ); - } - else - { - m_Event.Unlock(); - usleep( lrintf(fTimeToSleep * 1000000) ); - m_Event.Lock(); - } - } - m_Event.Unlock(); -} - -int RageSoundReader_ThreadedBuffer::FillFrames( int iFrames ) -{ - int iFramesFilled = 0; - while( iFramesFilled < iFrames ) - { - int iRet = FillBlock(); - - if( iRet == 0 ) - break; - // On error or end of file, stop buffering the sound. - if( iRet < 0 ) - return iRet; - - iFramesFilled += iRet; - } - return iFramesFilled; -} - -int RageSoundReader_ThreadedBuffer::FillBlock() -{ - if( GetEmptyFrames() == 0 ) - return 0; - - int iSamplesPerFrame = this->GetNumChannels(); - ASSERT( g_iReadBlockSizeFrames * iSamplesPerFrame <= m_DataBuffer.num_writable() ); - - int iGotFrames; - int iNextSourceFrame = 0; - float fRate = 0; - - m_Event.Unlock(); - - { - // We own m_pSource, even after unlocking, because m_bFilling is true. - unsigned iBufSize; - float *pBuf = m_DataBuffer.get_write_pointer( &iBufSize ); - ASSERT( (iBufSize % iSamplesPerFrame) == 0 ); - iGotFrames = m_pSource->RetriedRead( pBuf, min(g_iReadBlockSizeFrames, iBufSize / iSamplesPerFrame), &iNextSourceFrame, &fRate ); - } - - m_Event.Lock(); - - if( iGotFrames > 0 ) - { - // Add the data to the buffer. - m_DataBuffer.advance_write_pointer( iGotFrames * iSamplesPerFrame ); - if( iNextSourceFrame != m_StreamPosition.back().iPositionOfFirstFrame + m_StreamPosition.back().iFramesBuffered || - fRate != m_StreamPosition.back().fRate ) - { - m_StreamPosition.push_back( Mapping() ); - m_StreamPosition.back().iPositionOfFirstFrame = iNextSourceFrame; - m_StreamPosition.back().fRate = fRate; - } - - m_StreamPosition.back().iFramesBuffered += iGotFrames; - } - - m_bEOF = (iGotFrames == END_OF_FILE); - - return iGotFrames; -} - -int RageSoundReader_ThreadedBuffer::Read( float *pBuffer, int iFrames ) -{ - if( !m_bEOF ) - EnableBuffering(); - - m_Event.Lock(); - - { - /* Delete any empty mappings from the beginning, but don't empty the list, - * so we always have the current position and rate. If we delete an item, - * the rate or position has probably changed, so return. */ - list::iterator it = m_StreamPosition.begin(); - ++it; - if( it != m_StreamPosition.end() && !m_StreamPosition.front().iFramesBuffered ) - { - ++it; - m_StreamPosition.pop_front(); - m_Event.Unlock(); - return 0; - } - } - - int iRet; - if( m_StreamPosition.front().iFramesBuffered ) - { - Mapping &pos = m_StreamPosition.front(); - int iFramesToRead = min( iFrames, pos.iFramesBuffered ); - int iSamplesPerFrame = this->GetNumChannels(); - m_DataBuffer.read( pBuffer, iFramesToRead * iSamplesPerFrame ); - pos.iPositionOfFirstFrame += iFramesToRead; - pos.iFramesBuffered -= iFramesToRead; - iRet = iFramesToRead; - } - else if( m_bEOF ) - iRet = END_OF_FILE; - else - iRet = WOULD_BLOCK; - m_Event.Unlock(); - - return iRet; -} - -/* - * Copyright (c) 2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundReader_ThreadedBuffer.h" +#include "RageUtil.h" +#include "RageTimer.h" + +#include "RageLog.h" + +#if !defined(_WINDOWS) +#include +#endif + +/* Implement threaded read-ahead buffering. + * + * If a buffer is low on data, keep filling until it has a g_iMinFillFrames. + * Once beyond that, fill at a rate relative to realtime. + * + * This allows a stream to have a large buffer, for higher reliability, without + * causing major CPU bursts when the stream starts or underruns. Filling 32k + * takes more CPU than filling 4k frames, and may cause a skip. */ + +// The amount of data to read at once: +static const unsigned g_iReadBlockSizeFrames = 1024; + +// The maximum number of frames to buffer: +static const int g_iStreamingBufferFrames = 1024*32; + +/* When a sound has fewer than g_iMinFillFrames buffered, buffer at maximum speed. + * Once beyond that, fill at a limited rate. */ +static const int g_iMinFillFrames = 1024*4; + +RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( RageSoundReader *pSource ): + RageSoundReader_Filter( pSource ), + m_Event( "ThreadedBuffer" ) +{ + m_iSampleRate = pSource->GetSampleRate(); + m_iChannels = pSource->GetNumChannels(); + + int iFrameSize = sizeof(float) * this->GetNumChannels(); + m_DataBuffer.reserve( g_iStreamingBufferFrames * iFrameSize, iFrameSize ); + + m_bEOF = false; + m_bShutdownThread = false; + m_bEnabled = false; + m_bFilling = false; + + m_StreamPosition.push_back( Mapping() ); + m_StreamPosition.back().iPositionOfFirstFrame = pSource->GetNextSourceFrame(); + m_StreamPosition.back().fRate = pSource->GetStreamToSourceRatio(); + + m_Thread.SetName( "Streaming sound buffering" ); + m_Thread.Create( StartBufferingThread, this ); +} + +RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( const RageSoundReader_ThreadedBuffer &cpy ): + RageSoundReader_Filter( NULL ), // don't touch m_pSource before DisableBuffering + m_Event( "ThreadedBuffer" ) +{ + bool bWasEnabled = cpy.DisableBuffering(); + + m_pSource = cpy.m_pSource->Copy(); + m_iSampleRate = cpy.m_iSampleRate; + m_iChannels = cpy.m_iChannels; + m_DataBuffer = cpy.m_DataBuffer; + m_bEOF = cpy.m_bEOF; + m_bShutdownThread = cpy.m_bShutdownThread; + m_bEnabled = cpy.m_bEnabled; + m_bFilling = cpy.m_bFilling; + + m_StreamPosition = cpy.m_StreamPosition; + + m_Thread.Create( StartBufferingThread, this ); + + if( bWasEnabled ) + { + cpy.EnableBuffering(); + EnableBuffering(); + } +} + +RageSoundReader_ThreadedBuffer::~RageSoundReader_ThreadedBuffer() +{ + DisableBuffering(); + m_Event.Lock(); + m_bShutdownThread = true; + m_Event.Broadcast(); + m_Event.Unlock(); + + m_Thread.Wait(); +} + +void RageSoundReader_ThreadedBuffer::EnableBuffering() +{ + m_Event.Lock(); + m_bEnabled = true; + m_Event.Broadcast(); + m_Event.Unlock(); +} + +bool RageSoundReader_ThreadedBuffer::DisableBuffering() +{ + m_Event.Lock(); + bool bRet = m_bEnabled; + m_bEnabled = false; + m_Event.Broadcast(); + + while( m_bFilling ) + m_Event.Wait(); + + m_Event.Unlock(); + + return bRet; +} + +void RageSoundReader_ThreadedBuffer::WaitUntilFrames( int iWaitUntilFrames ) +{ + m_Event.Lock(); + ASSERT( m_bEnabled ); + while( GetFilledFrames() < iWaitUntilFrames ) + m_Event.Wait(); + m_Event.Unlock(); +} + +int RageSoundReader_ThreadedBuffer::SetPosition( int iFrame ) +{ + bool bWasEnabled = DisableBuffering(); + + m_DataBuffer.clear(); + + int iRet = RageSoundReader_Filter::SetPosition( iFrame ); + + m_StreamPosition.clear(); + m_StreamPosition.push_back( Mapping() ); + m_StreamPosition.back().iPositionOfFirstFrame = iFrame; + + m_bEOF = iRet == 0; + + if( bWasEnabled ) + EnableBuffering(); + + return iRet; +} + +int RageSoundReader_ThreadedBuffer::GetEmptyFrames() const +{ + int iSamplesPerFrame = this->GetNumChannels(); + if( g_iReadBlockSizeFrames * iSamplesPerFrame > m_DataBuffer.num_writable() ) + return 0; + return m_DataBuffer.num_writable() / iSamplesPerFrame; +} + +int RageSoundReader_ThreadedBuffer::GetFilledFrames() const +{ + int iSamplesPerFrame = this->GetNumChannels(); + return m_DataBuffer.num_readable() / iSamplesPerFrame; +} + +int RageSoundReader_ThreadedBuffer::GetNextSourceFrame() const +{ + m_Event.Lock(); + int iRet = m_StreamPosition.front().iPositionOfFirstFrame; + m_Event.Unlock(); + return iRet; +} + +float RageSoundReader_ThreadedBuffer::GetStreamToSourceRatio() const +{ + m_Event.Lock(); + float fRet = m_StreamPosition.front().fRate; + m_Event.Unlock(); + return fRet; +} + +int RageSoundReader_ThreadedBuffer::GetLength() const +{ + bool bWasEnabled = DisableBuffering(); + int iRet = m_pSource->GetLength(); + if( bWasEnabled ) + EnableBuffering(); + return iRet; +} +int RageSoundReader_ThreadedBuffer::GetLength_Fast() const +{ + bool bWasEnabled = DisableBuffering(); + int iRet = m_pSource->GetLength_Fast(); + if( bWasEnabled ) + EnableBuffering(); + return iRet; +} + +bool RageSoundReader_ThreadedBuffer::SetProperty( const RString &sProperty, float fValue ) +{ + return m_pSource->SetProperty( sProperty, fValue ); +} + +void RageSoundReader_ThreadedBuffer::BufferingThread() +{ + m_Event.Lock(); + while( !m_bShutdownThread ) + { + if( !m_bEnabled ) + { + m_Event.Wait(); + continue; + } + + // Fill some data. + m_bFilling = true; + + int iFramesToFill = g_iReadBlockSizeFrames; + if( GetFilledFrames() < g_iMinFillFrames ) + iFramesToFill = max( iFramesToFill, g_iMinFillFrames - GetFilledFrames() ); + + int iRet = FillFrames( iFramesToFill ); + + // Release m_bFilling, and signal the event to wake anyone waiting for it. + m_bFilling = false; + m_Event.Broadcast(); + + // On error or end of file, stop buffering the sound. + if( iRet < 0 ) + { + m_bEnabled = false; + continue; + } + + /* Sleep proportionately to the amount of data we buffered, so we + * fill at a reasonable pace. */ + float fTimeFilled = float(g_iReadBlockSizeFrames) / m_iSampleRate; + float fTimeToSleep = fTimeFilled / 2; + if( fTimeToSleep == 0 ) + fTimeToSleep = float(g_iReadBlockSizeFrames) / m_iSampleRate; + + if( m_Event.WaitTimeoutSupported() ) + { + RageTimer time; + time.Touch(); + time += fTimeToSleep; + m_Event.Wait( &time ); + } + else + { + m_Event.Unlock(); + usleep( lrintf(fTimeToSleep * 1000000) ); + m_Event.Lock(); + } + } + m_Event.Unlock(); +} + +int RageSoundReader_ThreadedBuffer::FillFrames( int iFrames ) +{ + int iFramesFilled = 0; + while( iFramesFilled < iFrames ) + { + int iRet = FillBlock(); + + if( iRet == 0 ) + break; + // On error or end of file, stop buffering the sound. + if( iRet < 0 ) + return iRet; + + iFramesFilled += iRet; + } + return iFramesFilled; +} + +int RageSoundReader_ThreadedBuffer::FillBlock() +{ + if( GetEmptyFrames() == 0 ) + return 0; + + int iSamplesPerFrame = this->GetNumChannels(); + ASSERT( g_iReadBlockSizeFrames * iSamplesPerFrame <= m_DataBuffer.num_writable() ); + + int iGotFrames; + int iNextSourceFrame = 0; + float fRate = 0; + + m_Event.Unlock(); + + { + // We own m_pSource, even after unlocking, because m_bFilling is true. + unsigned iBufSize; + float *pBuf = m_DataBuffer.get_write_pointer( &iBufSize ); + ASSERT( (iBufSize % iSamplesPerFrame) == 0 ); + iGotFrames = m_pSource->RetriedRead( pBuf, min(g_iReadBlockSizeFrames, iBufSize / iSamplesPerFrame), &iNextSourceFrame, &fRate ); + } + + m_Event.Lock(); + + if( iGotFrames > 0 ) + { + // Add the data to the buffer. + m_DataBuffer.advance_write_pointer( iGotFrames * iSamplesPerFrame ); + if( iNextSourceFrame != m_StreamPosition.back().iPositionOfFirstFrame + m_StreamPosition.back().iFramesBuffered || + fRate != m_StreamPosition.back().fRate ) + { + m_StreamPosition.push_back( Mapping() ); + m_StreamPosition.back().iPositionOfFirstFrame = iNextSourceFrame; + m_StreamPosition.back().fRate = fRate; + } + + m_StreamPosition.back().iFramesBuffered += iGotFrames; + } + + m_bEOF = (iGotFrames == END_OF_FILE); + + return iGotFrames; +} + +int RageSoundReader_ThreadedBuffer::Read( float *pBuffer, int iFrames ) +{ + if( !m_bEOF ) + EnableBuffering(); + + m_Event.Lock(); + + { + /* Delete any empty mappings from the beginning, but don't empty the list, + * so we always have the current position and rate. If we delete an item, + * the rate or position has probably changed, so return. */ + list::iterator it = m_StreamPosition.begin(); + ++it; + if( it != m_StreamPosition.end() && !m_StreamPosition.front().iFramesBuffered ) + { + ++it; + m_StreamPosition.pop_front(); + m_Event.Unlock(); + return 0; + } + } + + int iRet; + if( m_StreamPosition.front().iFramesBuffered ) + { + Mapping &pos = m_StreamPosition.front(); + int iFramesToRead = min( iFrames, pos.iFramesBuffered ); + int iSamplesPerFrame = this->GetNumChannels(); + m_DataBuffer.read( pBuffer, iFramesToRead * iSamplesPerFrame ); + pos.iPositionOfFirstFrame += iFramesToRead; + pos.iFramesBuffered -= iFramesToRead; + iRet = iFramesToRead; + } + else if( m_bEOF ) + iRet = END_OF_FILE; + else + iRet = WOULD_BLOCK; + m_Event.Unlock(); + + return iRet; +} + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageTextureManager.cpp b/src/RageTextureManager.cpp index 696d15b06e..caa7c59377 100644 --- a/src/RageTextureManager.cpp +++ b/src/RageTextureManager.cpp @@ -25,7 +25,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "RageDisplay.h" -#include "Foreach.h" + #include diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 95c548a22d..551529c5eb 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -3,7 +3,7 @@ #include "RageMath.h" #include "RageLog.h" #include "RageFile.h" -#include "Foreach.h" + #include "LocalizedString.h" #include "LuaBinding.h" #include "LuaManager.h" diff --git a/src/RoomInfoDisplay.cpp b/src/RoomInfoDisplay.cpp index 847db6846f..86c9c9103c 100644 --- a/src/RoomInfoDisplay.cpp +++ b/src/RoomInfoDisplay.cpp @@ -1,223 +1,223 @@ -#include "global.h" -#if !defined(WITHOUT_NETWORKING) -#include "RoomInfoDisplay.h" -#include "ActorUtil.h" -#include "NetworkSyncManager.h" -#include "LocalizedString.h" - -AutoScreenMessage( SM_RoomInfoRetract ); -AutoScreenMessage( SM_RoomInfoDeploy ); - -static LocalizedString LAST_ROUND_INFO ( "RoomInfoDisplay", "Last Round Info:" ); -static LocalizedString ROOM_NAME ( "RoomInfoDisplay", "Room Name:" ); -static LocalizedString ROOM_DESC ( "RoomInfoDisplay", "Room Description:" ); -static LocalizedString SONG_TITLE( "RoomInfoDisplay", "Song Title:" ); -static LocalizedString SONG_SUB_TITLE( "RoomInfoDisplay", "Song Subtitle:" ); -static LocalizedString SONG_ARTIST( "RoomInfoDisplay", "Song Artist:" ); -static LocalizedString PLAYERS( "RoomInfoDisplay", "Players" ); - -RoomInfoDisplay::RoomInfoDisplay() : - m_state( OPEN ) -{ - //No code -} - -RoomInfoDisplay::~RoomInfoDisplay() -{ - for (size_t i = 0; i < m_playerList.size(); i++) - { - this->RemoveChild(m_playerList[i]); - SAFE_DELETE(m_playerList[i]); - } -} - -void RoomInfoDisplay::DeployInfoBox() -{ - if (m_state == CLOSED) - { - ON_COMMAND( this ); - m_state = OPEN; - } -} - -void RoomInfoDisplay::RetractInfoBox() -{ - if (m_state == OPEN) - OFF_COMMAND( this ); - - m_state = LOCKED; -} - -void RoomInfoDisplay::Load( RString sType ) -{ - DEPLOY_DELAY.Load( sType, "DeployDelay" ); - RETRACT_DELAY.Load( sType, "RetractDelay" ); - PLAYERLISTX.Load( sType, "PlayerListElementX" ); - PLAYERLISTY.Load( sType, "PlayerListElementY" ); - PLAYERLISTOFFSETX.Load( sType, "PlayerListElementOffsetX" ); - PLAYERLISTOFFSETY.Load( sType, "PlayerListElementOffsetY" ); - - m_bg.Load( THEME->GetPathG(m_sName,"Background") ); - m_bg->SetName( "Background" ); - this->AddChild( m_bg ); - - m_Title.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_Title.SetName( "RoomTitle" ); - m_Title.SetShadowLength( 0 ); - m_Title.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_Title ); - ON_COMMAND( m_Title ); - this->AddChild( &m_Title ); - - m_Desc.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_Desc.SetName( "RoomDesc" ); - m_Desc.SetShadowLength( 0 ); - m_Desc.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_Desc ); - ON_COMMAND( m_Desc ); - this->AddChild( &m_Desc ); - - m_lastRound.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_lastRound.SetName( "LastRound" ); - m_lastRound.SetText( LAST_ROUND_INFO.GetValue() ); - m_lastRound.SetShadowLength( 0 ); - m_lastRound.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_lastRound ); - ON_COMMAND( m_lastRound ); - this->AddChild( &m_lastRound ); - - m_songTitle.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songTitle.SetName( "SongTitle" ); - m_songTitle.SetShadowLength( 0 ); - m_songTitle.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songTitle ); - ON_COMMAND( m_songTitle ); - this->AddChild( &m_songTitle ); - - m_songSub.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songSub.SetName( "SongSubTitle" ); - m_songSub.SetShadowLength( 0 ); - m_songSub.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songSub ); - ON_COMMAND( m_songSub ); - this->AddChild( &m_songSub ); - - m_songArtist.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songArtist.SetName( "SongArtist" ); - m_songArtist.SetShadowLength( 0 ); - m_songArtist.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songArtist ); - ON_COMMAND( m_songArtist ); - this->AddChild( &m_songArtist ); - - m_players.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_players.SetName( "Players" ); - m_players.SetShadowLength( 0 ); - m_players.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_players ); - ON_COMMAND( m_players ); - this->AddChild( &m_players ); - - LOAD_ALL_COMMANDS( this ); - - this->PlayCommand("Off"); - FinishTweening(); - - m_state = LOCKED; -} - -void RoomInfoDisplay::SetRoom( const RoomWheelItemData* roomData ) -{ - RequestRoomInfo(roomData->m_sText); - - m_Title.SetText( ROOM_NAME.GetValue() + roomData->m_sText ); - m_Desc.SetText( ROOM_DESC.GetValue() + roomData->m_sDesc ); -} - -void RoomInfoDisplay::Update( float fDeltaTime ) -{ - if ((m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY) && (m_deployDelay.PeekDeltaTime() < (DEPLOY_DELAY + RETRACT_DELAY))) - DeployInfoBox(); - else if (m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY + RETRACT_DELAY) - RetractInfoBox(); - - ActorFrame::Update(fDeltaTime); -} - -void RoomInfoDisplay::RequestRoomInfo(const RString& name) -{ - NSMAN->m_SMOnlinePacket.ClearPacket(); - NSMAN->m_SMOnlinePacket.Write1((uint8_t)3); //Request Room Info - NSMAN->m_SMOnlinePacket.WriteNT(name); - NSMAN->SendSMOnline( ); -} - -void RoomInfoDisplay::SetRoomInfo( const RoomInfo& info) -{ - m_songTitle.SetText( SONG_TITLE.GetValue() + info.songTitle ); - m_songSub.SetText( SONG_SUB_TITLE.GetValue() + info.songSubTitle ); - m_songArtist.SetText( SONG_ARTIST.GetValue() + info.songArtist ); - m_players.SetText(ssprintf("%s (%d/%d):", PLAYERS.GetValue().c_str(), info.numPlayers, info.maxPlayers)); - - if (m_playerList.size() > info.players.size()) - { - for (size_t i = info.players.size(); i < m_playerList.size(); i++) - { - //if our old list is larger remove some elements - this->RemoveChild(m_playerList[i]); - SAFE_DELETE(m_playerList[i]); - } - m_playerList.resize(info.players.size()); - } - else if (m_playerList.size() < info.players.size()) - { - //add elements if our old list is smaller - int oldsize = m_playerList.size(); - m_playerList.resize(info.players.size()); - for (size_t i = oldsize; i < m_playerList.size(); i++) - { - m_playerList[i] = new BitmapText; - m_playerList[i]->LoadFromFont( THEME->GetPathF(GetName(),"text") ); - m_playerList[i]->SetName("PlayerListElement"); - m_playerList[i]->SetHorizAlign( align_left ); - m_playerList[i]->SetX(PLAYERLISTX + (i * PLAYERLISTOFFSETX)); - m_playerList[i]->SetY(PLAYERLISTY + (i * PLAYERLISTOFFSETY)); - LOAD_ALL_COMMANDS(m_playerList[i]); - ON_COMMAND(m_playerList[i]); - this->AddChild(m_playerList[i]); - } - - } - - for (size_t i = 0; i < m_playerList.size(); i++) - m_playerList[i]->SetText(info.players[i]); - - m_state = CLOSED; - m_deployDelay.Touch(); -} -#endif - -/* - * (c) 2006 Josh Allen - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#if !defined(WITHOUT_NETWORKING) +#include "RoomInfoDisplay.h" +#include "ActorUtil.h" +#include "NetworkSyncManager.h" +#include "LocalizedString.h" + +AutoScreenMessage( SM_RoomInfoRetract ); +AutoScreenMessage( SM_RoomInfoDeploy ); + +static LocalizedString LAST_ROUND_INFO ( "RoomInfoDisplay", "Last Round Info:" ); +static LocalizedString ROOM_NAME ( "RoomInfoDisplay", "Room Name:" ); +static LocalizedString ROOM_DESC ( "RoomInfoDisplay", "Room Description:" ); +static LocalizedString SONG_TITLE( "RoomInfoDisplay", "Song Title:" ); +static LocalizedString SONG_SUB_TITLE( "RoomInfoDisplay", "Song Subtitle:" ); +static LocalizedString SONG_ARTIST( "RoomInfoDisplay", "Song Artist:" ); +static LocalizedString PLAYERS( "RoomInfoDisplay", "Players" ); + +RoomInfoDisplay::RoomInfoDisplay() : + m_state( OPEN ) +{ + //No code +} + +RoomInfoDisplay::~RoomInfoDisplay() +{ + for (size_t i = 0; i < m_playerList.size(); i++) + { + this->RemoveChild(m_playerList[i]); + SAFE_DELETE(m_playerList[i]); + } +} + +void RoomInfoDisplay::DeployInfoBox() +{ + if (m_state == CLOSED) + { + ON_COMMAND( this ); + m_state = OPEN; + } +} + +void RoomInfoDisplay::RetractInfoBox() +{ + if (m_state == OPEN) + OFF_COMMAND( this ); + + m_state = LOCKED; +} + +void RoomInfoDisplay::Load( RString sType ) +{ + DEPLOY_DELAY.Load( sType, "DeployDelay" ); + RETRACT_DELAY.Load( sType, "RetractDelay" ); + PLAYERLISTX.Load( sType, "PlayerListElementX" ); + PLAYERLISTY.Load( sType, "PlayerListElementY" ); + PLAYERLISTOFFSETX.Load( sType, "PlayerListElementOffsetX" ); + PLAYERLISTOFFSETY.Load( sType, "PlayerListElementOffsetY" ); + + m_bg.Load( THEME->GetPathG(m_sName,"Background") ); + m_bg->SetName( "Background" ); + this->AddChild( m_bg ); + + m_Title.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_Title.SetName( "RoomTitle" ); + m_Title.SetShadowLength( 0 ); + m_Title.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_Title ); + ON_COMMAND( m_Title ); + this->AddChild( &m_Title ); + + m_Desc.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_Desc.SetName( "RoomDesc" ); + m_Desc.SetShadowLength( 0 ); + m_Desc.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_Desc ); + ON_COMMAND( m_Desc ); + this->AddChild( &m_Desc ); + + m_lastRound.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_lastRound.SetName( "LastRound" ); + m_lastRound.SetText( LAST_ROUND_INFO.GetValue() ); + m_lastRound.SetShadowLength( 0 ); + m_lastRound.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_lastRound ); + ON_COMMAND( m_lastRound ); + this->AddChild( &m_lastRound ); + + m_songTitle.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songTitle.SetName( "SongTitle" ); + m_songTitle.SetShadowLength( 0 ); + m_songTitle.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songTitle ); + ON_COMMAND( m_songTitle ); + this->AddChild( &m_songTitle ); + + m_songSub.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songSub.SetName( "SongSubTitle" ); + m_songSub.SetShadowLength( 0 ); + m_songSub.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songSub ); + ON_COMMAND( m_songSub ); + this->AddChild( &m_songSub ); + + m_songArtist.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songArtist.SetName( "SongArtist" ); + m_songArtist.SetShadowLength( 0 ); + m_songArtist.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songArtist ); + ON_COMMAND( m_songArtist ); + this->AddChild( &m_songArtist ); + + m_players.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_players.SetName( "Players" ); + m_players.SetShadowLength( 0 ); + m_players.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_players ); + ON_COMMAND( m_players ); + this->AddChild( &m_players ); + + LOAD_ALL_COMMANDS( this ); + + this->PlayCommand("Off"); + FinishTweening(); + + m_state = LOCKED; +} + +void RoomInfoDisplay::SetRoom( const RoomWheelItemData* roomData ) +{ + RequestRoomInfo(roomData->m_sText); + + m_Title.SetText( ROOM_NAME.GetValue() + roomData->m_sText ); + m_Desc.SetText( ROOM_DESC.GetValue() + roomData->m_sDesc ); +} + +void RoomInfoDisplay::Update( float fDeltaTime ) +{ + if ((m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY) && (m_deployDelay.PeekDeltaTime() < (DEPLOY_DELAY + RETRACT_DELAY))) + DeployInfoBox(); + else if (m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY + RETRACT_DELAY) + RetractInfoBox(); + + ActorFrame::Update(fDeltaTime); +} + +void RoomInfoDisplay::RequestRoomInfo(const RString& name) +{ + NSMAN->m_SMOnlinePacket.ClearPacket(); + NSMAN->m_SMOnlinePacket.Write1((uint8_t)3); //Request Room Info + NSMAN->m_SMOnlinePacket.WriteNT(name); + NSMAN->SendSMOnline( ); +} + +void RoomInfoDisplay::SetRoomInfo( const RoomInfo& info) +{ + m_songTitle.SetText( SONG_TITLE.GetValue() + info.songTitle ); + m_songSub.SetText( SONG_SUB_TITLE.GetValue() + info.songSubTitle ); + m_songArtist.SetText( SONG_ARTIST.GetValue() + info.songArtist ); + m_players.SetText(ssprintf("%s (%d/%d):", PLAYERS.GetValue().c_str(), info.numPlayers, info.maxPlayers)); + + if (m_playerList.size() > info.players.size()) + { + for (size_t i = info.players.size(); i < m_playerList.size(); i++) + { + //if our old list is larger remove some elements + this->RemoveChild(m_playerList[i]); + SAFE_DELETE(m_playerList[i]); + } + m_playerList.resize(info.players.size()); + } + else if (m_playerList.size() < info.players.size()) + { + //add elements if our old list is smaller + int oldsize = m_playerList.size(); + m_playerList.resize(info.players.size()); + for (size_t i = oldsize; i < m_playerList.size(); i++) + { + m_playerList[i] = new BitmapText; + m_playerList[i]->LoadFromFont( THEME->GetPathF(GetName(),"text") ); + m_playerList[i]->SetName("PlayerListElement"); + m_playerList[i]->SetHorizAlign( align_left ); + m_playerList[i]->SetX(PLAYERLISTX + (i * PLAYERLISTOFFSETX)); + m_playerList[i]->SetY(PLAYERLISTY + (i * PLAYERLISTOFFSETY)); + LOAD_ALL_COMMANDS(m_playerList[i]); + ON_COMMAND(m_playerList[i]); + this->AddChild(m_playerList[i]); + } + + } + + for (size_t i = 0; i < m_playerList.size(); i++) + m_playerList[i]->SetText(info.players[i]); + + m_state = CLOSED; + m_deployDelay.Touch(); +} +#endif + +/* + * (c) 2006 Josh Allen + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/SampleHistory.cpp b/src/SampleHistory.cpp index d60392996e..2578e416cc 100644 --- a/src/SampleHistory.cpp +++ b/src/SampleHistory.cpp @@ -2,7 +2,7 @@ #include "SampleHistory.h" #include "RageLog.h" #include "RageUtil.h" -#include "Foreach.h" + SampleHistory::SampleHistory() { diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index d96a816e2a..b06a38006a 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -6,7 +6,7 @@ #include "AdjustSync.h" #include "BackgroundUtil.h" #include "CommonMetrics.h" -#include "Foreach.h" + #include "GameManager.h" #include "GamePreferences.h" #include "GameSoundManager.h" diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 0cf3679673..6a45af059e 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -37,7 +37,7 @@ #include "StatsManager.h" #include "PlayerAI.h" // for NUM_SKILL_LEVELS #include "NetworkSyncManager.h" -#include "Foreach.h" + #include "DancingCharacters.h" #include "ScreenDimensions.h" #include "ThemeMetric.h" diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index 44a169e9f9..084c673bc2 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -70,7 +70,7 @@ #include "FontManager.h" #include "Screen.h" #include "ScreenDimensions.h" -#include "Foreach.h" + #include "ActorUtil.h" ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program diff --git a/src/ScreenMapControllers2.cpp b/src/ScreenMapControllers2.cpp index cadad48a33..583f1b8d85 100644 --- a/src/ScreenMapControllers2.cpp +++ b/src/ScreenMapControllers2.cpp @@ -9,7 +9,6 @@ #include "ScreenDimensions.h" #include "InputEventPlus.h" #include "LocalizedString.h" -#include "Foreach.h" #include "LuaBinding.h" static const float g_fSecondsToWaitForInput = 0.05f; diff --git a/src/ScreenMessage.cpp b/src/ScreenMessage.cpp index ecdf7609f5..be6ed9e4a1 100644 --- a/src/ScreenMessage.cpp +++ b/src/ScreenMessage.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "ScreenMessage.h" #include "RageLog.h" -#include "Foreach.h" + #include const ScreenMessage SM_Invalid = ""; diff --git a/src/ScreenMiniMenu.cpp b/src/ScreenMiniMenu.cpp index 83be2dd4f0..56bbc23327 100644 --- a/src/ScreenMiniMenu.cpp +++ b/src/ScreenMiniMenu.cpp @@ -3,7 +3,7 @@ #include "ScreenManager.h" #include "GameConstantsAndTypes.h" #include "ThemeManager.h" -#include "Foreach.h" + #include "ScreenDimensions.h" #include "GameState.h" #include "FontCharAliases.h" diff --git a/src/ScreenOptionsMaster.cpp b/src/ScreenOptionsMaster.cpp index ef485cc8f6..8213496445 100644 --- a/src/ScreenOptionsMaster.cpp +++ b/src/ScreenOptionsMaster.cpp @@ -10,7 +10,7 @@ #include "PrefsManager.h" #include "StepMania.h" #include "RageSoundManager.h" -#include "Foreach.h" + #include "OptionRowHandler.h" #include "ScreenOptionsMasterPrefs.h" #include "CommonMetrics.h" diff --git a/src/ScreenOptionsMasterPrefs.cpp b/src/ScreenOptionsMasterPrefs.cpp index e992b3e25d..c02f73769c 100644 --- a/src/ScreenOptionsMasterPrefs.cpp +++ b/src/ScreenOptionsMasterPrefs.cpp @@ -12,7 +12,7 @@ #include "GameState.h" #include "StepMania.h" #include "Game.h" -#include "Foreach.h" + #include "GameConstantsAndTypes.h" #include "DisplayResolutions.h" #include "LocalizedString.h" diff --git a/src/ScreenPlayerOptions.cpp b/src/ScreenPlayerOptions.cpp index 458da965a1..5a1c8efb83 100644 --- a/src/ScreenPlayerOptions.cpp +++ b/src/ScreenPlayerOptions.cpp @@ -11,7 +11,7 @@ #include "CodeDetector.h" #include "ScreenDimensions.h" #include "PlayerState.h" -#include "Foreach.h" + #include "InputEventPlus.h" REGISTER_SCREEN_CLASS( ScreenPlayerOptions ); diff --git a/src/ScreenSelectMaster.cpp b/src/ScreenSelectMaster.cpp index bf52cbe1f6..f576c3a60c 100644 --- a/src/ScreenSelectMaster.cpp +++ b/src/ScreenSelectMaster.cpp @@ -10,7 +10,7 @@ #include "ActorUtil.h" #include "RageLog.h" #include -#include "Foreach.h" + #include "InputEventPlus.h" static const char *MenuDirNames[] = { diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index 9d9c9fa3cc..bd83bc2875 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -20,7 +20,7 @@ #include "MenuTimer.h" #include "StatsManager.h" #include "StepsUtil.h" -#include "Foreach.h" + #include "Style.h" #include "PlayerState.h" #include "CommonMetrics.h" diff --git a/src/Song.cpp b/src/Song.cpp index 5ec2f7b788..b1d50c43d8 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -20,7 +20,7 @@ #include "NoteDataUtil.h" #include "SongUtil.h" #include "StepsUtil.h" -#include "Foreach.h" + #include "BackgroundUtil.h" #include "SpecialFiles.h" #include "NotesLoader.h" diff --git a/src/SongManager.cpp b/src/SongManager.cpp index 255f775d8e..242a97d504 100644 --- a/src/SongManager.cpp +++ b/src/SongManager.cpp @@ -8,7 +8,7 @@ #include "Course.h" #include "CourseLoaderCRS.h" #include "CourseUtil.h" -#include "Foreach.h" + #include "GameManager.h" #include "GameState.h" #include "LocalizedString.h" diff --git a/src/SongUtil.cpp b/src/SongUtil.cpp index 75baa4d0a7..3b7ce6584a 100644 --- a/src/SongUtil.cpp +++ b/src/SongUtil.cpp @@ -9,7 +9,7 @@ #include "PrefsManager.h" #include "SongManager.h" #include "XmlFile.h" -#include "Foreach.h" + #include "UnlockManager.h" #include "ThemeMetric.h" #include "LocalizedString.h" diff --git a/src/Sprite.cpp b/src/Sprite.cpp index a7b6f1d18b..c02f4f5daa 100644 --- a/src/Sprite.cpp +++ b/src/Sprite.cpp @@ -10,7 +10,7 @@ #include "RageUtil.h" #include "ActorUtil.h" #include "arch/Dialog/Dialog.h" -#include "Foreach.h" + #include "LuaBinding.h" #include "LuaManager.h" #include diff --git a/src/StageStats.cpp b/src/StageStats.cpp index 2a9b3c0360..7e70457e6c 100644 --- a/src/StageStats.cpp +++ b/src/StageStats.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "StageStats.h" #include "GameState.h" -#include "Foreach.h" + #include "Steps.h" #include "Song.h" #include "RageLog.h" diff --git a/src/StatsManager.cpp b/src/StatsManager.cpp index 53d07c1660..4d81758b47 100644 --- a/src/StatsManager.cpp +++ b/src/StatsManager.cpp @@ -2,7 +2,7 @@ #include "StatsManager.h" #include "RageFileManager.h" #include "GameState.h" -#include "Foreach.h" + #include "ProfileManager.h" #include "Profile.h" #include "PrefsManager.h" diff --git a/src/StepMania-net2011.vcxproj b/src/StepMania-net2011.vcxproj index bf4bf7ab64..ebbabb954f 100644 --- a/src/StepMania-net2011.vcxproj +++ b/src/StepMania-net2011.vcxproj @@ -1783,7 +1783,6 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)" - diff --git a/src/StepMania-net2011.vcxproj.filters b/src/StepMania-net2011.vcxproj.filters index f7da9a3879..d949714bd0 100644 --- a/src/StepMania-net2011.vcxproj.filters +++ b/src/StepMania-net2011.vcxproj.filters @@ -1883,9 +1883,6 @@ Data Structures - - Data Structures - Data Structures diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index 261ca2fe19..ea254128ad 100644 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -14,7 +14,7 @@ #include "ScreenManager.h" #include "ActorUtil.h" #endif -#include "Foreach.h" + #include "ThemeMetric.h" #include "SubscriptionManager.h" #include "LuaManager.h" diff --git a/src/ThemeMetric.h b/src/ThemeMetric.h index d953128453..ff5decaaf5 100644 --- a/src/ThemeMetric.h +++ b/src/ThemeMetric.h @@ -5,7 +5,7 @@ #include "ThemeManager.h" #include -#include "Foreach.h" + #include "LuaManager.h" #include "RageUtil.h" diff --git a/src/TimingData.cpp b/src/TimingData.cpp index f1843de7bc..762b97aa92 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -4,7 +4,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "NoteTypes.h" -#include "Foreach.h" + #include TimingSegment* GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ); diff --git a/src/TitleSubstitution.cpp b/src/TitleSubstitution.cpp index 6d7e8a3501..b762d23193 100644 --- a/src/TitleSubstitution.cpp +++ b/src/TitleSubstitution.cpp @@ -5,7 +5,7 @@ #include "RageLog.h" #include "FontCharAliases.h" #include "RageFile.h" -#include "Foreach.h" + #include "XmlFile.h" #include "XmlFileUtil.h" diff --git a/src/Trail.cpp b/src/Trail.cpp index 9ccfcfcdb8..58ace184ff 100644 --- a/src/Trail.cpp +++ b/src/Trail.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "Trail.h" -#include "Foreach.h" + #include "GameState.h" #include "Steps.h" #include "Song.h" diff --git a/src/UnlockManager.cpp b/src/UnlockManager.cpp index 6e0a856801..4c8de1078a 100644 --- a/src/UnlockManager.cpp +++ b/src/UnlockManager.cpp @@ -11,7 +11,7 @@ #include "ProfileManager.h" #include "Profile.h" #include "ThemeManager.h" -#include "Foreach.h" + #include "Steps.h" #include #include "CommonMetrics.h" diff --git a/src/WheelBase.cpp b/src/WheelBase.cpp index cad9aa1818..ea10d59c6f 100644 --- a/src/WheelBase.cpp +++ b/src/WheelBase.cpp @@ -11,7 +11,7 @@ #include "ThemeManager.h" #include "RageTextureManager.h" #include "ActorUtil.h" -#include "Foreach.h" + #include "Style.h" #include "ThemeMetric.h" #include "ScreenDimensions.h" diff --git a/src/WorkoutGraph.cpp b/src/WorkoutGraph.cpp index 3e0f27ba6b..dbefbe879d 100644 --- a/src/WorkoutGraph.cpp +++ b/src/WorkoutGraph.cpp @@ -8,7 +8,7 @@ #include "GameState.h" #include "ThemeManager.h" #include "StatsManager.h" -#include "Foreach.h" + #include "Course.h" #include "Style.h" diff --git a/src/XmlFile.cpp b/src/XmlFile.cpp index 1cb67627d8..e219cb81f8 100644 --- a/src/XmlFile.cpp +++ b/src/XmlFile.cpp @@ -1,196 +1,196 @@ -// Adapted from http://www.codeproject.com/cpp/xmlite.asp. -// On 2004-02-09 Cho, Kyung-Min gave us permission to use and modify this -// library. -// -// XmlFile : XML Lite Parser Library -// by Cho, Kyung Min: bro@shinbiro.com 2002-10-30 - -#include "global.h" -#include "XmlFile.h" -#include "RageFile.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "DateTime.h" -#include "Foreach.h" -#include "LuaManager.h" - -const RString XNode::TEXT_ATTRIBUTE = "__TEXT__"; - -XNode::XNode() -{ -} - -XNode::XNode( const RString &sName ) -{ - m_sName = sName; -} - -XNode::XNode( const XNode &cpy ): - m_sName( cpy.m_sName ) -{ - FOREACH_CONST_Attr( &cpy, pAttr ) - this->AppendAttrFrom( pAttr->first, pAttr->second->Copy() ); - FOREACH_CONST_Child( &cpy, c ) - this->AppendChild( new XNode(*c) ); -} - -void XNode::Clear() -{ - Free(); -} - -void XNode::Free() -{ - FOREACH_Child( this, p ) - delete p; - FOREACH_Attr( this, pAttr ) - delete pAttr->second; - m_childs.clear(); - m_attrs.clear(); -} - -void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; } -void XNodeStringValue::GetValue( int &out ) const { out = StringToInt(m_sValue); } -void XNodeStringValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); } -void XNodeStringValue::GetValue( bool &out ) const { out = StringToInt(m_sValue) != 0; } -void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); } -void XNodeStringValue::PushValue( lua_State *L ) const -{ - LuaHelpers::Push( L, m_sValue ); -} - -void XNodeStringValue::SetValue( const RString &v ) { m_sValue = v; } -void XNodeStringValue::SetValue( int v ) { m_sValue = ssprintf("%d",v); } -void XNodeStringValue::SetValue( float v ) { m_sValue = ssprintf("%f",v); } -void XNodeStringValue::SetValue( unsigned v ) { m_sValue = ssprintf("%u",v); } -void XNodeStringValue::SetValueFromStack( lua_State *L ) -{ - LuaHelpers::Pop( L, m_sValue ); -} - -const XNodeValue *XNode::GetAttr( const RString &attrname ) const -{ - XAttrs::const_iterator it = m_attrs.find( attrname ); - if( it != m_attrs.end() ) - return it->second; - return NULL; -} - -bool XNode::PushAttrValue( lua_State *L, const RString &sName ) const -{ - const XNodeValue *pAttr = GetAttr(sName); - if( pAttr == NULL ) - { - lua_pushnil( L ); - return false; - } - pAttr->PushValue( L ); - return true; -} - -XNodeValue *XNode::GetAttr( const RString &attrname ) -{ - XAttrs::iterator it = m_attrs.find( attrname ); - if( it != m_attrs.end() ) - return it->second; - return NULL; -} - -XNode *XNode::GetChild( const RString &sName ) -{ - FOREACH_Child( this, it ) - { - if( it->GetName() == sName ) - return it; - } - return NULL; -} - -bool XNode::PushChildValue( lua_State *L, const RString &sName ) const -{ - const XNode *pChild = GetChild(sName); - if( pChild == NULL ) - { - lua_pushnil( L ); - return false; - } - pChild->GetAttr(XNode::TEXT_ATTRIBUTE)->PushValue( L ); - return true; -} - -const XNode *XNode::GetChild( const RString &sName ) const -{ - FOREACH_CONST_Child( this, it ) - { - if( it->GetName() == sName ) - return it; - } - return NULL; -} - -XNode *XNode::AppendChild( XNode *node ) -{ - DEBUG_ASSERT( node->m_sName.size() ); - - m_childs.push_back( node ); - return node; -} - -// detach node and delete object -bool XNode::RemoveChild( XNode *node, bool /* bDelete */ ) -{ - XNodes::iterator it = find( m_childs.begin(), m_childs.end(), node ); - if( it == m_childs.end() ) - return false; - - delete node; - m_childs.erase( it ); - return true; -} - - -// detach attribute -bool XNode::RemoveAttr( const RString &sName ) -{ - XAttrs::iterator it = m_attrs.find( sName ); - if( it == m_attrs.end() ) - return false; - - delete it->second; - m_attrs.erase( it ); - return true; -} - -/* If bOverwrite is true and a node already exists with that name, the old value will be deleted. - * If bOverwrite is false and a node already exists with that name, the new value will be deleted. */ -XNodeValue *XNode::AppendAttrFrom( const RString &sName, XNodeValue *pValue, bool bOverwrite ) -{ - DEBUG_ASSERT( sName.size() ); - pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); - if( !ret.second ) // already existed - { - if( bOverwrite ) - { - delete ret.first->second; - } - else - { - delete pValue; - pValue = ret.first->second; - } - } - - ret.first->second = pValue; - - return ret.first->second; -}; - -XNodeValue *XNode::AppendAttr( const RString &sName ) -{ - DEBUG_ASSERT( sName.size() ); - pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); - if( ret.second ) - ret.first->second = new XNodeStringValue; - return ret.first->second; // already existed -} - +// Adapted from http://www.codeproject.com/cpp/xmlite.asp. +// On 2004-02-09 Cho, Kyung-Min gave us permission to use and modify this +// library. +// +// XmlFile : XML Lite Parser Library +// by Cho, Kyung Min: bro@shinbiro.com 2002-10-30 + +#include "global.h" +#include "XmlFile.h" +#include "RageFile.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "DateTime.h" + +#include "LuaManager.h" + +const RString XNode::TEXT_ATTRIBUTE = "__TEXT__"; + +XNode::XNode() +{ +} + +XNode::XNode( const RString &sName ) +{ + m_sName = sName; +} + +XNode::XNode( const XNode &cpy ): + m_sName( cpy.m_sName ) +{ + FOREACH_CONST_Attr( &cpy, pAttr ) + this->AppendAttrFrom( pAttr->first, pAttr->second->Copy() ); + FOREACH_CONST_Child( &cpy, c ) + this->AppendChild( new XNode(*c) ); +} + +void XNode::Clear() +{ + Free(); +} + +void XNode::Free() +{ + FOREACH_Child( this, p ) + delete p; + FOREACH_Attr( this, pAttr ) + delete pAttr->second; + m_childs.clear(); + m_attrs.clear(); +} + +void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; } +void XNodeStringValue::GetValue( int &out ) const { out = StringToInt(m_sValue); } +void XNodeStringValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); } +void XNodeStringValue::GetValue( bool &out ) const { out = StringToInt(m_sValue) != 0; } +void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); } +void XNodeStringValue::PushValue( lua_State *L ) const +{ + LuaHelpers::Push( L, m_sValue ); +} + +void XNodeStringValue::SetValue( const RString &v ) { m_sValue = v; } +void XNodeStringValue::SetValue( int v ) { m_sValue = ssprintf("%d",v); } +void XNodeStringValue::SetValue( float v ) { m_sValue = ssprintf("%f",v); } +void XNodeStringValue::SetValue( unsigned v ) { m_sValue = ssprintf("%u",v); } +void XNodeStringValue::SetValueFromStack( lua_State *L ) +{ + LuaHelpers::Pop( L, m_sValue ); +} + +const XNodeValue *XNode::GetAttr( const RString &attrname ) const +{ + XAttrs::const_iterator it = m_attrs.find( attrname ); + if( it != m_attrs.end() ) + return it->second; + return NULL; +} + +bool XNode::PushAttrValue( lua_State *L, const RString &sName ) const +{ + const XNodeValue *pAttr = GetAttr(sName); + if( pAttr == NULL ) + { + lua_pushnil( L ); + return false; + } + pAttr->PushValue( L ); + return true; +} + +XNodeValue *XNode::GetAttr( const RString &attrname ) +{ + XAttrs::iterator it = m_attrs.find( attrname ); + if( it != m_attrs.end() ) + return it->second; + return NULL; +} + +XNode *XNode::GetChild( const RString &sName ) +{ + FOREACH_Child( this, it ) + { + if( it->GetName() == sName ) + return it; + } + return NULL; +} + +bool XNode::PushChildValue( lua_State *L, const RString &sName ) const +{ + const XNode *pChild = GetChild(sName); + if( pChild == NULL ) + { + lua_pushnil( L ); + return false; + } + pChild->GetAttr(XNode::TEXT_ATTRIBUTE)->PushValue( L ); + return true; +} + +const XNode *XNode::GetChild( const RString &sName ) const +{ + FOREACH_CONST_Child( this, it ) + { + if( it->GetName() == sName ) + return it; + } + return NULL; +} + +XNode *XNode::AppendChild( XNode *node ) +{ + DEBUG_ASSERT( node->m_sName.size() ); + + m_childs.push_back( node ); + return node; +} + +// detach node and delete object +bool XNode::RemoveChild( XNode *node, bool /* bDelete */ ) +{ + XNodes::iterator it = find( m_childs.begin(), m_childs.end(), node ); + if( it == m_childs.end() ) + return false; + + delete node; + m_childs.erase( it ); + return true; +} + + +// detach attribute +bool XNode::RemoveAttr( const RString &sName ) +{ + XAttrs::iterator it = m_attrs.find( sName ); + if( it == m_attrs.end() ) + return false; + + delete it->second; + m_attrs.erase( it ); + return true; +} + +/* If bOverwrite is true and a node already exists with that name, the old value will be deleted. + * If bOverwrite is false and a node already exists with that name, the new value will be deleted. */ +XNodeValue *XNode::AppendAttrFrom( const RString &sName, XNodeValue *pValue, bool bOverwrite ) +{ + DEBUG_ASSERT( sName.size() ); + pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); + if( !ret.second ) // already existed + { + if( bOverwrite ) + { + delete ret.first->second; + } + else + { + delete pValue; + pValue = ret.first->second; + } + } + + ret.first->second = pValue; + + return ret.first->second; +}; + +XNodeValue *XNode::AppendAttr( const RString &sName ) +{ + DEBUG_ASSERT( sName.size() ); + pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); + if( ret.second ) + ret.first->second = new XNodeStringValue; + return ret.first->second; // already existed +} + diff --git a/src/XmlFileUtil.cpp b/src/XmlFileUtil.cpp index 0704bfe350..8ca45a7475 100644 --- a/src/XmlFileUtil.cpp +++ b/src/XmlFileUtil.cpp @@ -1,818 +1,818 @@ -#include "global.h" -#include "XmlFileUtil.h" -#include "XmlFile.h" -#include "RageFile.h" -#include "RageFileDriverMemory.h" -#include "RageUtil.h" -#include "RageLog.h" -#include "arch/Dialog/Dialog.h" -#include "Foreach.h" - -bool XmlFileUtil::LoadFromFileShowErrors( XNode &xml, RageFileBasic &f ) -{ - RString sError; - RString s; - if( f.Read( s ) == -1 ) - sError = f.GetError(); - else - Load( &xml, s, sError ); - if( sError.empty() ) - return true; - - RString sWarning = ssprintf( "XML: LoadFromFile failed: %s", sError.c_str() ); - LOG->Warn( "%s", sWarning.c_str() ); - Dialog::OK( sWarning, "XML_PARSE_ERROR" ); - return false; -} - -bool XmlFileUtil::LoadFromFileShowErrors( XNode &xml, const RString &sFile ) -{ - RageFile f; - if( !f.Open(sFile, RageFile::READ) ) - { - LOG->Warn("Couldn't open %s for reading: %s", sFile.c_str(), f.GetError().c_str() ); - return false; - } - - bool bSuccess = LoadFromFileShowErrors( xml, f ); - if( !bSuccess ) - { - RString sWarning = ssprintf( "XML: LoadFromFile failed for file: %s", sFile.c_str() ); - LOG->Warn( "%s", sWarning.c_str() ); - Dialog::OK( sWarning, "XML_PARSE_ERROR" ); - } - return bSuccess; -} - -static const char chXMLTagOpen = '<'; -static const char chXMLTagClose = '>'; -static const char chXMLQuestion = '?'; // used in checking for meta tags: "" -static const char chXMLTagPre = '/'; -static const char chXMLExclamation = '!'; -static const char chXMLDash = '-'; - -static map g_mapEntitiesToChars; -static map g_mapCharsToEntities; - -static void InitEntities() -{ - if( !g_mapEntitiesToChars.empty() ) - return; - - static struct Entity - { - char c; - const char *pEntity; - } - const EntityTable[] = - { - { '&', "amp", }, - { '\"', "quot", }, - { '\'', "apos", }, - { '<', "lt", }, - { '>', "gt", } - }; - - for( unsigned i = 0; i < ARRAYLEN(EntityTable); ++i ) - { - const Entity &ent = EntityTable[i]; - g_mapEntitiesToChars[ent.pEntity] = RString(1, ent.c); - g_mapCharsToEntities[ent.c] = ent.pEntity; - } -} - -// skip spaces -static void tcsskip( const RString &s, RString::size_type &i ) -{ - i = s.find_first_not_of( " \t\r\n", i ); -} - -// put string of (psz~end) on ps string -static void SetString( const RString &s, int iStart, int iEnd, RString* ps, bool trim = false ) -{ - if( trim ) - { - while( iStart < iEnd && s[iStart] > 0 && isspace(s[iStart]) ) - iStart++; - while( iEnd-1 >= iStart && s[iEnd-1] > 0 && isspace(s[iEnd-1]) ) - iEnd--; - } - - int len = iEnd - iStart; - if( len <= 0 ) - return; - - ps->assign( s, iStart, len ); -} - -// attr1="value1" attr2='value2' attr3=value3 /> -// ^- return pointer -// Desc : loading attribute plain xml text -// Param : pszAttrs - xml of attributes -// pi = parser information -// Return : advanced string pointer. (error return npos) -namespace -{ -RString::size_type LoadAttributes( XNode *pNode, const RString &xml, RString &sErrorOut, RString::size_type iOffset ) -{ - while( iOffset < xml.size() ) - { - tcsskip( xml, iOffset ); - if( iOffset >= xml.size() ) - continue; - - // close tag - if( iOffset < xml.size() && - (xml[iOffset] == chXMLTagClose || xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) ) - return iOffset; // well-formed tag - - // XML Attr Name - RString::size_type iEnd = xml.find_first_of( " =", iOffset ); - if( iEnd == xml.npos ) - { - // error - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "<%s> attribute has error ", pNode->GetName().c_str() ); - return string::npos; - } - - // XML Attr Name - RString sName; - SetString( xml, iOffset, iEnd, &sName ); - - // add new attribute - DEBUG_ASSERT( sName.size() ); - XNodeValue *pAttr = pNode->AppendAttr( sName ); - iOffset = iEnd; - - // XML Attr Value - tcsskip( xml, iOffset ); - - if( iOffset < xml.size() && xml[iOffset] == '=' ) - { - ++iOffset; - - tcsskip( xml, iOffset ); - if( iOffset >= xml.size() ) - continue; - - // if " or ' - // or none quote - char quote = xml[iOffset]; - if( quote == '"' || quote == '\'' ) - { - ++iOffset; - iEnd = xml.find( quote, iOffset ); - } - else - { - // XXX: This is invalid XML, should we be accepting it? -- Steve - //attr= value> - // none quote mode - iEnd = xml.find_first_of( " >", iOffset ); - } - - if( iEnd == xml.npos ) - { - // error - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "<%s> attribute text: couldn't find matching quote", sName.c_str() ); - return string::npos; - } - - RString sValue; - SetString( xml, iOffset, iEnd, &sValue, true ); - ReplaceEntityText( sValue, g_mapEntitiesToChars ); - pAttr->SetValue( sValue ); - iOffset = iEnd; - - if( quote == '"' || quote == '\'' ) - ++iOffset; - } - } - - // not well-formed tag - return string::npos; -} - -// -// -// or -// -// ^- return pointer -// Desc : load xml plain text -// Param : pszXml - plain xml text -// pi = parser information -// Return : advanced string pointer (error return npos) -RString::size_type LoadInternal( XNode *pNode, const RString &xml, RString &sErrorOut, RString::size_type iOffset ) -{ - pNode->Clear(); - - // < - iOffset = xml.find( chXMLTagOpen, iOffset ); - if( iOffset == string::npos ) - return string::npos; - - // ", iOffset ); - if( iEnd == string::npos ) - { - if( sErrorOut.empty() ) - sErrorOut = "Unterminated comment"; - - return string::npos; - } - - // Skip -->. - iOffset = iEnd + 3; - - return LoadInternal( pNode, xml, sErrorOut, iOffset ); - } - - // XML Node Tag Name Open - iOffset++; - RString::size_type iTagEnd = xml.find_first_of( " \t\r\n/>", iOffset ); - RString sName; - SetString( xml, iOffset, iTagEnd, &sName ); - pNode->SetName( sName ); - iOffset = iTagEnd; - - // Generate XML Attribute List - iOffset = LoadAttributes( pNode, xml, sErrorOut, iOffset ); - if( iOffset == string::npos ) - return string::npos; - - // alone tag or or - // current pointer: ^ ^ ^ - - if( iOffset < xml.size() && (xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) ) - { - iOffset++; - - // skip over 2nd dash - if( iOffset < xml.size() && xml[iOffset] == chXMLDash ) - iOffset++; - - if( iOffset == xml.size() || xml[iOffset] != chXMLTagClose ) - { - // error: - if( sErrorOut.empty() ) - sErrorOut = "Element must be closed."; - - // ill-formed tag - return string::npos; - } - - // well-formed tag - ++iOffset; - - // UGLY: We want to ignore all XML meta tags. So, since the Node we - // just loaded is a meta tag, then Load ourself again using the rest - // of the file until we reach a non-meta tag. - if( !pNode->GetName().empty() && (pNode->GetName()[0] == chXMLQuestion || pNode->GetName()[0] == chXMLExclamation) ) - iOffset = LoadInternal( pNode, xml, sErrorOut, iOffset ); - - return iOffset; - } - - // open/close tag ... - // ^- current pointer - if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) - { - // Text Value - ++iOffset; - RString::size_type iEnd = xml.find( chXMLTagOpen, iOffset ); - if( iEnd == string::npos ) - { - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "%s must be closed with ", pNode->GetName().c_str(), pNode->GetName().c_str() ); - // error cos not exist CloseTag - return string::npos; - } - - RString sValue; - SetString( xml, iOffset, iEnd, &sValue, true ); - - iOffset = iEnd; - ReplaceEntityText( sValue, g_mapEntitiesToChars ); - - pNode->AppendAttr(XNode::TEXT_ATTRIBUTE, sValue ); - } - - // generate child nodes - while( iOffset < xml.size() ) - { - XNode *node = new XNode; - - iOffset = LoadInternal( node, xml, sErrorOut, iOffset ); - if( iOffset == string::npos ) - { - delete node; - return iOffset; - } - - if( !node->GetName().empty() ) - { - DEBUG_ASSERT( node->GetName().size() ); - pNode->m_childs.push_back( node ); - } - else - { - delete node; - } - - // open/close tag ... - // ^- current pointer - // CloseTag case - if( iOffset+1 < xml.size() && xml[iOffset] == chXMLTagOpen && xml[iOffset+1] == chXMLTagPre ) - { - // - iOffset += 2; // C - - tcsskip( xml, iOffset ); - if( iOffset >= xml.size() ) - continue; - - RString::size_type iEnd = xml.find_first_of( " >", iOffset ); - if( iEnd == string::npos ) - { - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "it must be closed with ", pNode->GetName().c_str() ); - // error - return string::npos; - } - - RString closename; - SetString( xml, iOffset, iEnd, &closename ); - iOffset = iEnd+1; - if( closename == pNode->GetName() ) - { - // wel-formed open/close - // return '>' or ' ' after pointer - return iOffset; - } - else - { - // not welformed open/close - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "'<%s> ... ' is not well-formed.", pNode->GetName().c_str(), closename.c_str() ); - return string::npos; - } - } - else // Alone child Tag Loaded - { - if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen ) - { - // Text Value - RString::size_type iEnd = xml.find( chXMLTagOpen, iOffset ); - if( iEnd == string::npos ) - { - // error cos not exist CloseTag - if( sErrorOut.empty() ) - sErrorOut = ssprintf( "it must be closed with ", pNode->GetName().c_str() ); - return string::npos; - } - - RString sValue; - SetString( xml, iOffset, iEnd, &sValue, true ); - - iOffset = iEnd; - ReplaceEntityText( sValue, g_mapEntitiesToChars ); - pNode->AppendAttr(XNode::TEXT_ATTRIBUTE, sValue ); - } - } - } - - return iOffset; -} - -bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int &iTabBase ) -{ -#define WRITE(x) if( f.Write(x) == -1 ) return false - // tab - WRITE( "\r\n" ); - if( bWriteTabs ) - for( int i = 0 ; i < iTabBase ; i++) - WRITE( "\t" ); - - // GetName() ); - - // first == XNode::TEXT_ATTRIBUTE ) - continue; - RString attr( p->second->GetValue() ); - ReplaceEntityText( attr, g_mapCharsToEntities ); - WRITE( " " ); - WRITE( p->first ); - WRITE( "='" ); - WRITE( attr ); - WRITE( "'" ); - } - - if( pNode->m_childs.empty() && pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) - { - // alone tag - WRITE( "/>" ); - } - else - { - // and get child - WRITE( ">" ); - - if( !pNode->m_childs.empty() ) - iTabBase++; - - FOREACH_CONST_Child( pNode, p ) - if( !GetXMLInternal( p, f, bWriteTabs, iTabBase ) ) - return false; - - // Text Value - const XNodeValue *pText = pNode->GetAttr( XNode::TEXT_ATTRIBUTE ); - if( pText != NULL ) - { - if( !pNode->m_childs.empty() ) - { - WRITE( "\r\n" ); - if( bWriteTabs ) - for( int i = 0 ; i < iTabBase ; i++) - WRITE( "\t" ); - } - RString s; - pText->GetValue( s ); - ReplaceEntityText( s, g_mapCharsToEntities ); - WRITE( s ); - } - - // CloseTag - if( !pNode->m_childs.empty() ) - { - WRITE( "\r\n" ); - if( bWriteTabs ) - for( int i = 0 ; i < iTabBase-1 ; i++) - WRITE( "\t" ); - } - WRITE( "GetName() ); - WRITE( ">" ); - - if( !pNode->m_childs.empty() ) - iTabBase--; - } - return true; -#undef WRITE -} -} - -void XmlFileUtil::Load( XNode *pNode, const RString &sXml, RString &sErrorOut ) -{ - InitEntities(); - LoadInternal( pNode, sXml, sErrorOut, 0 ); -} - -bool XmlFileUtil::GetXML( const XNode *pNode, RageFileBasic &f, bool bWriteTabs ) -{ - int iTabBase = 0; - InitEntities(); - return GetXMLInternal( pNode, f, bWriteTabs, iTabBase ); -} - -RString XmlFileUtil::GetXML( const XNode *pNode ) -{ - RageFileObjMem f; - int iTabBase = 0; - InitEntities(); - GetXMLInternal( pNode, f, true, iTabBase ); - return f.GetString(); -} - -bool XmlFileUtil::SaveToFile( const XNode *pNode, RageFileBasic &f, const RString &sStylesheet, bool bWriteTabs ) -{ - f.PutLine( "" ); - if( !sStylesheet.empty() ) - f.PutLine( "" ); - int iTabBase = 0; - InitEntities(); - if( !GetXMLInternal(pNode, f, bWriteTabs, iTabBase) ) - return false; - f.PutLine( "" ); - if( f.Flush() == -1 ) - return false; - return true; -} - -bool XmlFileUtil::SaveToFile( const XNode *pNode, const RString &sFile, const RString &sStylesheet, bool bWriteTabs ) -{ - RageFile f; - if( !f.Open(sFile, RageFile::WRITE) ) - { - LOG->Warn( "Couldn't open %s for writing: %s", sFile.c_str(), f.GetError().c_str() ); - return false; - } - - return SaveToFile( pNode, f, sStylesheet, bWriteTabs ); -} - -#include "LuaManager.h" -#include "LuaReference.h" -class XNodeLuaValue: public XNodeValue -{ -public: - LuaReference m_Value; - XNodeValue *Copy() const { return new XNodeLuaValue( *this ); } - - template - T GetValue() const { T val; GetValue(val); return val; } - - void GetValue( RString &out ) const; - void GetValue( int &out ) const; - void GetValue( float &out ) const; - void GetValue( bool &out ) const; - void GetValue( unsigned &out ) const; - void PushValue( lua_State *L ) const; - - void SetValue( const RString &v ); - void SetValue( int v ); - void SetValue( float v ); - void SetValue( unsigned v ); - void SetValueFromStack( lua_State *L ); -}; - -void XNodeLuaValue::PushValue( lua_State *L ) const -{ - m_Value.PushSelf( L ); -} - -void XNodeLuaValue::GetValue( RString &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } -void XNodeLuaValue::GetValue( int &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } -void XNodeLuaValue::GetValue( float &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } -void XNodeLuaValue::GetValue( bool &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } -void XNodeLuaValue::GetValue( unsigned &out ) const { Lua *L = LUA->Get(); PushValue( L ); float fVal; LuaHelpers::Pop( L, fVal ); out = unsigned(fVal); LUA->Release( L ); } - -void XNodeLuaValue::SetValueFromStack( lua_State *L ) -{ - m_Value.SetFromStack( L ); -} - -void XNodeLuaValue::SetValue( const RString &v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } -void XNodeLuaValue::SetValue( int v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } -void XNodeLuaValue::SetValue( float v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } -void XNodeLuaValue::SetValue( unsigned v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, (float) v ); SetValueFromStack( L ); LUA->Release( L ); } - -namespace -{ - XNodeValue *CompileXMLNodeValue( Lua *L, const RString &sName, const XNodeValue *pValue, const RString &sFile ) - { - RString sExpression; - pValue->GetValue( sExpression ); - - if( EndsWith(sName, "Command") ) - { - LuaHelpers::ParseCommandList( L, sExpression, sFile ); - } - else if( sExpression.size() > 0 && sExpression[0] == '@' ) - { - // This is a raw string. - sExpression.erase( 0, 1 ); - LuaHelpers::Push( L, sExpression ); - } - else - { - LuaHelpers::RunExpression( L, sExpression, sFile ); - } - - XNodeLuaValue *pRet = new XNodeLuaValue; - pRet->SetValueFromStack( L ); - return pRet; - } -} - -void XmlFileUtil::CompileXNodeTree( XNode *pNode, const RString &sFile ) -{ - vector aToCompile; - aToCompile.push_back( pNode ); - - Lua *L = LUA->Get(); - while( aToCompile.size() ) - { - pNode = aToCompile.back(); - aToCompile.pop_back(); - FOREACH_Child( pNode, pChild ) - aToCompile.push_back( pChild ); - - FOREACH_Attr( pNode, pAttr ) - { - XNodeValue *pValue = CompileXMLNodeValue( L, pAttr->first, pAttr->second, sFile ); - delete pAttr->second; - pAttr->second = pValue; - } - } - - LUA->Release( L ); -} - -namespace -{ - XNode *XNodeFromTableRecursive( lua_State *L, const RString &sName, LuaReference &ProcessedTables ) - { - XNode *pNode = new XNode( sName ); - - // Set the value of the node to the table. - { - XNodeLuaValue *pValue = new XNodeLuaValue; - lua_pushvalue( L, -1 ); - pValue->SetValueFromStack( L ); - pNode->AppendAttrFrom( XNode::TEXT_ATTRIBUTE, pValue ); - } - - // Iterate over the table, pulling out attributes and tables to process. - vector NodeNamesToAdd; - vector NodesToAdd; - - /* Add array elements first, in array order, so iterating over the XNode - * keeps the array in order. */ - FOREACH_LUATABLEI( L, -1, i ) - { - if( !lua_istable(L, -1) ) - continue; - NodeNamesToAdd.push_back( ssprintf("%i", i) ); - NodesToAdd.push_back( LuaReference() ); - NodesToAdd.back().SetFromStack( L ); - } - - int iLen = NodeNamesToAdd.size(); - FOREACH_LUATABLE( L, -1 ) - { - // If this entry is a table, add it recursively. - if( lua_istable(L, -2) ) - { - if( lua_isnumber(L, -1) ) - { - /* If this number is an integer, and between [1,iLen], then - * we added this one already above. */ - lua_Number f = lua_tonumber( L, -1 ); - int i; - lua_number2int(i, f); - if( i >= 1 && i <= iLen && float(i) == f ) - continue; - } - - RString nName; - LuaHelpers::Pop( L, nName ); - NodeNamesToAdd.push_back( nName ); - NodesToAdd.push_back( LuaReference() ); - NodesToAdd.back().SetFromStack( L ); - continue; - } - - RString nName; - LuaHelpers::Pop( L, nName ); - - // Otherwise, add an attribute. - XNodeLuaValue *pValue = new XNodeLuaValue; - pValue->SetValueFromStack( L ); - pNode->AppendAttrFrom( nName, pValue ); - } - lua_pop( L, 1 ); - - // Recursively process tables. - for( size_t i = 0; i < NodesToAdd.size(); ++i ) - { - const RString &sNodeName = NodeNamesToAdd[i]; - LuaReference &NodeToAdd = NodesToAdd[i]; - - // Check if the table is on the stack. - ProcessedTables.PushSelf( L ); - NodeToAdd.PushSelf( L ); // push table - lua_gettable( L, -2 ); - - bool bSawThisTableAlready = !lua_isnil(L, -1); - lua_pop( L, 2 ); // pop lua_gettable result, ProcessedTables - if( bSawThisTableAlready ) - continue; - - // Add the table to the stack. - ProcessedTables.PushSelf( L ); - NodeToAdd.PushSelf( L ); - lua_pushboolean( L, true ); - lua_settable( L, -3 ); - lua_pop( L, 1 ); // pop ProcessedTables - - NodeToAdd.PushSelf( L ); - XNode *pNewNode = XNodeFromTableRecursive( L, sNodeName, ProcessedTables ); - if( pNewNode ) - pNode->AppendChild( pNewNode ); - - // Remove the table from the stack. - ProcessedTables.PushSelf( L ); - NodeToAdd.PushSelf( L ); - lua_pushnil( L ); - lua_settable( L, -3 ); - lua_pop( L, 1 ); // pop ProcessedTables - } - - return pNode; - } - -} - -/* Pop a table off of the stack, and return an XNode tree referring recursively - * to entries in the table. - * - * The table may not contain table cycles; if a cycle is detected, only the first - * table seen will have a corresponding XNode. - * - * Users of the resulting XNode may access the original table via PushValue. */ -XNode *XmlFileUtil::XNodeFromTable( lua_State *L ) -{ - /* Maintain a set of references that we've created. Tables may loop; XNode - * trees may not. If we encounter a cycle, skip creating an XNode for - * that node. */ - LuaReference ProcessedTables; - lua_newtable( L ); - ProcessedTables.SetFromStack( L ); - - return XNodeFromTableRecursive( L, "Layer", ProcessedTables ); -} - -/* Move nodes from pFrom into pTo which don't already exist in pTo. For - * efficiency, nodes will be moved, not copied, so pFrom will be modified. - * On return, the contents of pFrom will be undefined and should be deleted. */ -void XmlFileUtil::MergeIniUnder( XNode *pFrom, XNode *pTo ) -{ - /* Batch up nodes to move, and do them all at once, to deal sanely - * with the possibility of duplicate child names. */ - vector aToMove; - - // Iterate over each section in pFrom. - XNodes::iterator it = pFrom->m_childs.begin(); - while( it != pFrom->m_childs.end() ) - { - XNodes::iterator next = it; - ++next; - - // If this node doesn't exist in pTo, just move the whole node. - XNode *pSectionNode = *it; - XNode *pChildNode = pTo->GetChild( pSectionNode->GetName() ); - if( pChildNode == NULL ) - { - aToMove.push_back( it ); - } - else - { - FOREACH_Attr( pSectionNode, it2 ) - { - // Don't overwrite existing nodes. - pChildNode->AppendAttrFrom( it2->first, it2->second->Copy(), false ); - } - } - - it = next; - } - - /* Iterate in reverse, since erasing iterators will invalidate the - * iterators after it. */ - for( int i = aToMove.size()-1; i >= 0; --i ) - { - XNode *pNode = *aToMove[i]; - pFrom->m_childs.erase( aToMove[i] ); - pTo->AppendChild( pNode ); - } -} - -/* - * (c) 2001-2006 Chris Danford, Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "XmlFileUtil.h" +#include "XmlFile.h" +#include "RageFile.h" +#include "RageFileDriverMemory.h" +#include "RageUtil.h" +#include "RageLog.h" +#include "arch/Dialog/Dialog.h" + + +bool XmlFileUtil::LoadFromFileShowErrors( XNode &xml, RageFileBasic &f ) +{ + RString sError; + RString s; + if( f.Read( s ) == -1 ) + sError = f.GetError(); + else + Load( &xml, s, sError ); + if( sError.empty() ) + return true; + + RString sWarning = ssprintf( "XML: LoadFromFile failed: %s", sError.c_str() ); + LOG->Warn( "%s", sWarning.c_str() ); + Dialog::OK( sWarning, "XML_PARSE_ERROR" ); + return false; +} + +bool XmlFileUtil::LoadFromFileShowErrors( XNode &xml, const RString &sFile ) +{ + RageFile f; + if( !f.Open(sFile, RageFile::READ) ) + { + LOG->Warn("Couldn't open %s for reading: %s", sFile.c_str(), f.GetError().c_str() ); + return false; + } + + bool bSuccess = LoadFromFileShowErrors( xml, f ); + if( !bSuccess ) + { + RString sWarning = ssprintf( "XML: LoadFromFile failed for file: %s", sFile.c_str() ); + LOG->Warn( "%s", sWarning.c_str() ); + Dialog::OK( sWarning, "XML_PARSE_ERROR" ); + } + return bSuccess; +} + +static const char chXMLTagOpen = '<'; +static const char chXMLTagClose = '>'; +static const char chXMLQuestion = '?'; // used in checking for meta tags: "" +static const char chXMLTagPre = '/'; +static const char chXMLExclamation = '!'; +static const char chXMLDash = '-'; + +static map g_mapEntitiesToChars; +static map g_mapCharsToEntities; + +static void InitEntities() +{ + if( !g_mapEntitiesToChars.empty() ) + return; + + static struct Entity + { + char c; + const char *pEntity; + } + const EntityTable[] = + { + { '&', "amp", }, + { '\"', "quot", }, + { '\'', "apos", }, + { '<', "lt", }, + { '>', "gt", } + }; + + for( unsigned i = 0; i < ARRAYLEN(EntityTable); ++i ) + { + const Entity &ent = EntityTable[i]; + g_mapEntitiesToChars[ent.pEntity] = RString(1, ent.c); + g_mapCharsToEntities[ent.c] = ent.pEntity; + } +} + +// skip spaces +static void tcsskip( const RString &s, RString::size_type &i ) +{ + i = s.find_first_not_of( " \t\r\n", i ); +} + +// put string of (psz~end) on ps string +static void SetString( const RString &s, int iStart, int iEnd, RString* ps, bool trim = false ) +{ + if( trim ) + { + while( iStart < iEnd && s[iStart] > 0 && isspace(s[iStart]) ) + iStart++; + while( iEnd-1 >= iStart && s[iEnd-1] > 0 && isspace(s[iEnd-1]) ) + iEnd--; + } + + int len = iEnd - iStart; + if( len <= 0 ) + return; + + ps->assign( s, iStart, len ); +} + +// attr1="value1" attr2='value2' attr3=value3 /> +// ^- return pointer +// Desc : loading attribute plain xml text +// Param : pszAttrs - xml of attributes +// pi = parser information +// Return : advanced string pointer. (error return npos) +namespace +{ +RString::size_type LoadAttributes( XNode *pNode, const RString &xml, RString &sErrorOut, RString::size_type iOffset ) +{ + while( iOffset < xml.size() ) + { + tcsskip( xml, iOffset ); + if( iOffset >= xml.size() ) + continue; + + // close tag + if( iOffset < xml.size() && + (xml[iOffset] == chXMLTagClose || xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) ) + return iOffset; // well-formed tag + + // XML Attr Name + RString::size_type iEnd = xml.find_first_of( " =", iOffset ); + if( iEnd == xml.npos ) + { + // error + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "<%s> attribute has error ", pNode->GetName().c_str() ); + return string::npos; + } + + // XML Attr Name + RString sName; + SetString( xml, iOffset, iEnd, &sName ); + + // add new attribute + DEBUG_ASSERT( sName.size() ); + XNodeValue *pAttr = pNode->AppendAttr( sName ); + iOffset = iEnd; + + // XML Attr Value + tcsskip( xml, iOffset ); + + if( iOffset < xml.size() && xml[iOffset] == '=' ) + { + ++iOffset; + + tcsskip( xml, iOffset ); + if( iOffset >= xml.size() ) + continue; + + // if " or ' + // or none quote + char quote = xml[iOffset]; + if( quote == '"' || quote == '\'' ) + { + ++iOffset; + iEnd = xml.find( quote, iOffset ); + } + else + { + // XXX: This is invalid XML, should we be accepting it? -- Steve + //attr= value> + // none quote mode + iEnd = xml.find_first_of( " >", iOffset ); + } + + if( iEnd == xml.npos ) + { + // error + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "<%s> attribute text: couldn't find matching quote", sName.c_str() ); + return string::npos; + } + + RString sValue; + SetString( xml, iOffset, iEnd, &sValue, true ); + ReplaceEntityText( sValue, g_mapEntitiesToChars ); + pAttr->SetValue( sValue ); + iOffset = iEnd; + + if( quote == '"' || quote == '\'' ) + ++iOffset; + } + } + + // not well-formed tag + return string::npos; +} + +// +// +// or +// +// ^- return pointer +// Desc : load xml plain text +// Param : pszXml - plain xml text +// pi = parser information +// Return : advanced string pointer (error return npos) +RString::size_type LoadInternal( XNode *pNode, const RString &xml, RString &sErrorOut, RString::size_type iOffset ) +{ + pNode->Clear(); + + // < + iOffset = xml.find( chXMLTagOpen, iOffset ); + if( iOffset == string::npos ) + return string::npos; + + // ", iOffset ); + if( iEnd == string::npos ) + { + if( sErrorOut.empty() ) + sErrorOut = "Unterminated comment"; + + return string::npos; + } + + // Skip -->. + iOffset = iEnd + 3; + + return LoadInternal( pNode, xml, sErrorOut, iOffset ); + } + + // XML Node Tag Name Open + iOffset++; + RString::size_type iTagEnd = xml.find_first_of( " \t\r\n/>", iOffset ); + RString sName; + SetString( xml, iOffset, iTagEnd, &sName ); + pNode->SetName( sName ); + iOffset = iTagEnd; + + // Generate XML Attribute List + iOffset = LoadAttributes( pNode, xml, sErrorOut, iOffset ); + if( iOffset == string::npos ) + return string::npos; + + // alone tag or or + // current pointer: ^ ^ ^ + + if( iOffset < xml.size() && (xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) ) + { + iOffset++; + + // skip over 2nd dash + if( iOffset < xml.size() && xml[iOffset] == chXMLDash ) + iOffset++; + + if( iOffset == xml.size() || xml[iOffset] != chXMLTagClose ) + { + // error: + if( sErrorOut.empty() ) + sErrorOut = "Element must be closed."; + + // ill-formed tag + return string::npos; + } + + // well-formed tag + ++iOffset; + + // UGLY: We want to ignore all XML meta tags. So, since the Node we + // just loaded is a meta tag, then Load ourself again using the rest + // of the file until we reach a non-meta tag. + if( !pNode->GetName().empty() && (pNode->GetName()[0] == chXMLQuestion || pNode->GetName()[0] == chXMLExclamation) ) + iOffset = LoadInternal( pNode, xml, sErrorOut, iOffset ); + + return iOffset; + } + + // open/close tag ... + // ^- current pointer + if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) + { + // Text Value + ++iOffset; + RString::size_type iEnd = xml.find( chXMLTagOpen, iOffset ); + if( iEnd == string::npos ) + { + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "%s must be closed with ", pNode->GetName().c_str(), pNode->GetName().c_str() ); + // error cos not exist CloseTag + return string::npos; + } + + RString sValue; + SetString( xml, iOffset, iEnd, &sValue, true ); + + iOffset = iEnd; + ReplaceEntityText( sValue, g_mapEntitiesToChars ); + + pNode->AppendAttr(XNode::TEXT_ATTRIBUTE, sValue ); + } + + // generate child nodes + while( iOffset < xml.size() ) + { + XNode *node = new XNode; + + iOffset = LoadInternal( node, xml, sErrorOut, iOffset ); + if( iOffset == string::npos ) + { + delete node; + return iOffset; + } + + if( !node->GetName().empty() ) + { + DEBUG_ASSERT( node->GetName().size() ); + pNode->m_childs.push_back( node ); + } + else + { + delete node; + } + + // open/close tag ... + // ^- current pointer + // CloseTag case + if( iOffset+1 < xml.size() && xml[iOffset] == chXMLTagOpen && xml[iOffset+1] == chXMLTagPre ) + { + // + iOffset += 2; // C + + tcsskip( xml, iOffset ); + if( iOffset >= xml.size() ) + continue; + + RString::size_type iEnd = xml.find_first_of( " >", iOffset ); + if( iEnd == string::npos ) + { + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "it must be closed with ", pNode->GetName().c_str() ); + // error + return string::npos; + } + + RString closename; + SetString( xml, iOffset, iEnd, &closename ); + iOffset = iEnd+1; + if( closename == pNode->GetName() ) + { + // wel-formed open/close + // return '>' or ' ' after pointer + return iOffset; + } + else + { + // not welformed open/close + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "'<%s> ... ' is not well-formed.", pNode->GetName().c_str(), closename.c_str() ); + return string::npos; + } + } + else // Alone child Tag Loaded + { + if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen ) + { + // Text Value + RString::size_type iEnd = xml.find( chXMLTagOpen, iOffset ); + if( iEnd == string::npos ) + { + // error cos not exist CloseTag + if( sErrorOut.empty() ) + sErrorOut = ssprintf( "it must be closed with ", pNode->GetName().c_str() ); + return string::npos; + } + + RString sValue; + SetString( xml, iOffset, iEnd, &sValue, true ); + + iOffset = iEnd; + ReplaceEntityText( sValue, g_mapEntitiesToChars ); + pNode->AppendAttr(XNode::TEXT_ATTRIBUTE, sValue ); + } + } + } + + return iOffset; +} + +bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int &iTabBase ) +{ +#define WRITE(x) if( f.Write(x) == -1 ) return false + // tab + WRITE( "\r\n" ); + if( bWriteTabs ) + for( int i = 0 ; i < iTabBase ; i++) + WRITE( "\t" ); + + // GetName() ); + + // first == XNode::TEXT_ATTRIBUTE ) + continue; + RString attr( p->second->GetValue() ); + ReplaceEntityText( attr, g_mapCharsToEntities ); + WRITE( " " ); + WRITE( p->first ); + WRITE( "='" ); + WRITE( attr ); + WRITE( "'" ); + } + + if( pNode->m_childs.empty() && pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) + { + // alone tag + WRITE( "/>" ); + } + else + { + // and get child + WRITE( ">" ); + + if( !pNode->m_childs.empty() ) + iTabBase++; + + FOREACH_CONST_Child( pNode, p ) + if( !GetXMLInternal( p, f, bWriteTabs, iTabBase ) ) + return false; + + // Text Value + const XNodeValue *pText = pNode->GetAttr( XNode::TEXT_ATTRIBUTE ); + if( pText != NULL ) + { + if( !pNode->m_childs.empty() ) + { + WRITE( "\r\n" ); + if( bWriteTabs ) + for( int i = 0 ; i < iTabBase ; i++) + WRITE( "\t" ); + } + RString s; + pText->GetValue( s ); + ReplaceEntityText( s, g_mapCharsToEntities ); + WRITE( s ); + } + + // CloseTag + if( !pNode->m_childs.empty() ) + { + WRITE( "\r\n" ); + if( bWriteTabs ) + for( int i = 0 ; i < iTabBase-1 ; i++) + WRITE( "\t" ); + } + WRITE( "GetName() ); + WRITE( ">" ); + + if( !pNode->m_childs.empty() ) + iTabBase--; + } + return true; +#undef WRITE +} +} + +void XmlFileUtil::Load( XNode *pNode, const RString &sXml, RString &sErrorOut ) +{ + InitEntities(); + LoadInternal( pNode, sXml, sErrorOut, 0 ); +} + +bool XmlFileUtil::GetXML( const XNode *pNode, RageFileBasic &f, bool bWriteTabs ) +{ + int iTabBase = 0; + InitEntities(); + return GetXMLInternal( pNode, f, bWriteTabs, iTabBase ); +} + +RString XmlFileUtil::GetXML( const XNode *pNode ) +{ + RageFileObjMem f; + int iTabBase = 0; + InitEntities(); + GetXMLInternal( pNode, f, true, iTabBase ); + return f.GetString(); +} + +bool XmlFileUtil::SaveToFile( const XNode *pNode, RageFileBasic &f, const RString &sStylesheet, bool bWriteTabs ) +{ + f.PutLine( "" ); + if( !sStylesheet.empty() ) + f.PutLine( "" ); + int iTabBase = 0; + InitEntities(); + if( !GetXMLInternal(pNode, f, bWriteTabs, iTabBase) ) + return false; + f.PutLine( "" ); + if( f.Flush() == -1 ) + return false; + return true; +} + +bool XmlFileUtil::SaveToFile( const XNode *pNode, const RString &sFile, const RString &sStylesheet, bool bWriteTabs ) +{ + RageFile f; + if( !f.Open(sFile, RageFile::WRITE) ) + { + LOG->Warn( "Couldn't open %s for writing: %s", sFile.c_str(), f.GetError().c_str() ); + return false; + } + + return SaveToFile( pNode, f, sStylesheet, bWriteTabs ); +} + +#include "LuaManager.h" +#include "LuaReference.h" +class XNodeLuaValue: public XNodeValue +{ +public: + LuaReference m_Value; + XNodeValue *Copy() const { return new XNodeLuaValue( *this ); } + + template + T GetValue() const { T val; GetValue(val); return val; } + + void GetValue( RString &out ) const; + void GetValue( int &out ) const; + void GetValue( float &out ) const; + void GetValue( bool &out ) const; + void GetValue( unsigned &out ) const; + void PushValue( lua_State *L ) const; + + void SetValue( const RString &v ); + void SetValue( int v ); + void SetValue( float v ); + void SetValue( unsigned v ); + void SetValueFromStack( lua_State *L ); +}; + +void XNodeLuaValue::PushValue( lua_State *L ) const +{ + m_Value.PushSelf( L ); +} + +void XNodeLuaValue::GetValue( RString &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } +void XNodeLuaValue::GetValue( int &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } +void XNodeLuaValue::GetValue( float &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } +void XNodeLuaValue::GetValue( bool &out ) const { Lua *L = LUA->Get(); PushValue( L ); LuaHelpers::Pop( L, out ); LUA->Release( L ); } +void XNodeLuaValue::GetValue( unsigned &out ) const { Lua *L = LUA->Get(); PushValue( L ); float fVal; LuaHelpers::Pop( L, fVal ); out = unsigned(fVal); LUA->Release( L ); } + +void XNodeLuaValue::SetValueFromStack( lua_State *L ) +{ + m_Value.SetFromStack( L ); +} + +void XNodeLuaValue::SetValue( const RString &v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } +void XNodeLuaValue::SetValue( int v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } +void XNodeLuaValue::SetValue( float v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, v ); SetValueFromStack( L ); LUA->Release( L ); } +void XNodeLuaValue::SetValue( unsigned v ) { Lua *L = LUA->Get(); LuaHelpers::Push( L, (float) v ); SetValueFromStack( L ); LUA->Release( L ); } + +namespace +{ + XNodeValue *CompileXMLNodeValue( Lua *L, const RString &sName, const XNodeValue *pValue, const RString &sFile ) + { + RString sExpression; + pValue->GetValue( sExpression ); + + if( EndsWith(sName, "Command") ) + { + LuaHelpers::ParseCommandList( L, sExpression, sFile ); + } + else if( sExpression.size() > 0 && sExpression[0] == '@' ) + { + // This is a raw string. + sExpression.erase( 0, 1 ); + LuaHelpers::Push( L, sExpression ); + } + else + { + LuaHelpers::RunExpression( L, sExpression, sFile ); + } + + XNodeLuaValue *pRet = new XNodeLuaValue; + pRet->SetValueFromStack( L ); + return pRet; + } +} + +void XmlFileUtil::CompileXNodeTree( XNode *pNode, const RString &sFile ) +{ + vector aToCompile; + aToCompile.push_back( pNode ); + + Lua *L = LUA->Get(); + while( aToCompile.size() ) + { + pNode = aToCompile.back(); + aToCompile.pop_back(); + FOREACH_Child( pNode, pChild ) + aToCompile.push_back( pChild ); + + FOREACH_Attr( pNode, pAttr ) + { + XNodeValue *pValue = CompileXMLNodeValue( L, pAttr->first, pAttr->second, sFile ); + delete pAttr->second; + pAttr->second = pValue; + } + } + + LUA->Release( L ); +} + +namespace +{ + XNode *XNodeFromTableRecursive( lua_State *L, const RString &sName, LuaReference &ProcessedTables ) + { + XNode *pNode = new XNode( sName ); + + // Set the value of the node to the table. + { + XNodeLuaValue *pValue = new XNodeLuaValue; + lua_pushvalue( L, -1 ); + pValue->SetValueFromStack( L ); + pNode->AppendAttrFrom( XNode::TEXT_ATTRIBUTE, pValue ); + } + + // Iterate over the table, pulling out attributes and tables to process. + vector NodeNamesToAdd; + vector NodesToAdd; + + /* Add array elements first, in array order, so iterating over the XNode + * keeps the array in order. */ + FOREACH_LUATABLEI( L, -1, i ) + { + if( !lua_istable(L, -1) ) + continue; + NodeNamesToAdd.push_back( ssprintf("%i", i) ); + NodesToAdd.push_back( LuaReference() ); + NodesToAdd.back().SetFromStack( L ); + } + + int iLen = NodeNamesToAdd.size(); + FOREACH_LUATABLE( L, -1 ) + { + // If this entry is a table, add it recursively. + if( lua_istable(L, -2) ) + { + if( lua_isnumber(L, -1) ) + { + /* If this number is an integer, and between [1,iLen], then + * we added this one already above. */ + lua_Number f = lua_tonumber( L, -1 ); + int i; + lua_number2int(i, f); + if( i >= 1 && i <= iLen && float(i) == f ) + continue; + } + + RString nName; + LuaHelpers::Pop( L, nName ); + NodeNamesToAdd.push_back( nName ); + NodesToAdd.push_back( LuaReference() ); + NodesToAdd.back().SetFromStack( L ); + continue; + } + + RString nName; + LuaHelpers::Pop( L, nName ); + + // Otherwise, add an attribute. + XNodeLuaValue *pValue = new XNodeLuaValue; + pValue->SetValueFromStack( L ); + pNode->AppendAttrFrom( nName, pValue ); + } + lua_pop( L, 1 ); + + // Recursively process tables. + for( size_t i = 0; i < NodesToAdd.size(); ++i ) + { + const RString &sNodeName = NodeNamesToAdd[i]; + LuaReference &NodeToAdd = NodesToAdd[i]; + + // Check if the table is on the stack. + ProcessedTables.PushSelf( L ); + NodeToAdd.PushSelf( L ); // push table + lua_gettable( L, -2 ); + + bool bSawThisTableAlready = !lua_isnil(L, -1); + lua_pop( L, 2 ); // pop lua_gettable result, ProcessedTables + if( bSawThisTableAlready ) + continue; + + // Add the table to the stack. + ProcessedTables.PushSelf( L ); + NodeToAdd.PushSelf( L ); + lua_pushboolean( L, true ); + lua_settable( L, -3 ); + lua_pop( L, 1 ); // pop ProcessedTables + + NodeToAdd.PushSelf( L ); + XNode *pNewNode = XNodeFromTableRecursive( L, sNodeName, ProcessedTables ); + if( pNewNode ) + pNode->AppendChild( pNewNode ); + + // Remove the table from the stack. + ProcessedTables.PushSelf( L ); + NodeToAdd.PushSelf( L ); + lua_pushnil( L ); + lua_settable( L, -3 ); + lua_pop( L, 1 ); // pop ProcessedTables + } + + return pNode; + } + +} + +/* Pop a table off of the stack, and return an XNode tree referring recursively + * to entries in the table. + * + * The table may not contain table cycles; if a cycle is detected, only the first + * table seen will have a corresponding XNode. + * + * Users of the resulting XNode may access the original table via PushValue. */ +XNode *XmlFileUtil::XNodeFromTable( lua_State *L ) +{ + /* Maintain a set of references that we've created. Tables may loop; XNode + * trees may not. If we encounter a cycle, skip creating an XNode for + * that node. */ + LuaReference ProcessedTables; + lua_newtable( L ); + ProcessedTables.SetFromStack( L ); + + return XNodeFromTableRecursive( L, "Layer", ProcessedTables ); +} + +/* Move nodes from pFrom into pTo which don't already exist in pTo. For + * efficiency, nodes will be moved, not copied, so pFrom will be modified. + * On return, the contents of pFrom will be undefined and should be deleted. */ +void XmlFileUtil::MergeIniUnder( XNode *pFrom, XNode *pTo ) +{ + /* Batch up nodes to move, and do them all at once, to deal sanely + * with the possibility of duplicate child names. */ + vector aToMove; + + // Iterate over each section in pFrom. + XNodes::iterator it = pFrom->m_childs.begin(); + while( it != pFrom->m_childs.end() ) + { + XNodes::iterator next = it; + ++next; + + // If this node doesn't exist in pTo, just move the whole node. + XNode *pSectionNode = *it; + XNode *pChildNode = pTo->GetChild( pSectionNode->GetName() ); + if( pChildNode == NULL ) + { + aToMove.push_back( it ); + } + else + { + FOREACH_Attr( pSectionNode, it2 ) + { + // Don't overwrite existing nodes. + pChildNode->AppendAttrFrom( it2->first, it2->second->Copy(), false ); + } + } + + it = next; + } + + /* Iterate in reverse, since erasing iterators will invalidate the + * iterators after it. */ + for( int i = aToMove.size()-1; i >= 0; --i ) + { + XNode *pNode = *aToMove[i]; + pFrom->m_childs.erase( aToMove[i] ); + pTo->AppendChild( pNode ); + } +} + +/* + * (c) 2001-2006 Chris Danford, Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/Dialog/DialogDriver.cpp b/src/arch/Dialog/DialogDriver.cpp index 7fefe8987b..e13e5de9d0 100644 --- a/src/arch/Dialog/DialogDriver.cpp +++ b/src/arch/Dialog/DialogDriver.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "DialogDriver.h" -#include "Foreach.h" + #include "RageLog.h" map *RegisterDialogDriver::g_pRegistrees; diff --git a/src/arch/InputHandler/InputHandler.cpp b/src/arch/InputHandler/InputHandler.cpp index b4839c9205..893225a4d6 100644 --- a/src/arch/InputHandler/InputHandler.cpp +++ b/src/arch/InputHandler/InputHandler.cpp @@ -6,7 +6,7 @@ #include "LocalizedString.h" #include "arch/arch_default.h" #include "InputHandler_MonkeyKeyboard.h" -#include "Foreach.h" + void InputHandler::UpdateTimer() { diff --git a/src/arch/InputHandler/InputHandler_DirectInput.cpp b/src/arch/InputHandler/InputHandler_DirectInput.cpp index add401ed43..edfe9a0ce3 100644 --- a/src/arch/InputHandler/InputHandler_DirectInput.cpp +++ b/src/arch/InputHandler/InputHandler_DirectInput.cpp @@ -10,7 +10,7 @@ #include "archutils/Win32/RegistryAccess.h" #include "InputFilter.h" #include "PrefsManager.h" -#include "Foreach.h" + #include "InputHandler_DirectInputHelper.h" diff --git a/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp b/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp index 04e501f83f..04371c993c 100644 --- a/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp +++ b/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "RageLog.h" #include "InputHandler_MacOSX_HID.h" -#include "Foreach.h" #include "PrefsManager.h" #include "InputFilter.h" #include "archutils/Darwin/DarwinThreadHelpers.h" diff --git a/src/arch/Lights/LightsDriver.cpp b/src/arch/Lights/LightsDriver.cpp index 0c19ed725b..e1562a9049 100644 --- a/src/arch/Lights/LightsDriver.cpp +++ b/src/arch/Lights/LightsDriver.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "LightsDriver.h" #include "RageLog.h" -#include "Foreach.h" + #include "arch/arch_default.h" DriverList LightsDriver::m_pDriverList; diff --git a/src/arch/MemoryCard/MemoryCardDriver.cpp b/src/arch/MemoryCard/MemoryCardDriver.cpp index 11fb617317..fddb59cb5a 100644 --- a/src/arch/MemoryCard/MemoryCardDriver.cpp +++ b/src/arch/MemoryCard/MemoryCardDriver.cpp @@ -2,7 +2,7 @@ #include "MemoryCardDriver.h" #include "RageFileManager.h" #include "RageLog.h" -#include "Foreach.h" + #include "ProfileManager.h" static const RString TEMP_MOUNT_POINT = "/@mctemptimeout/"; diff --git a/src/arch/MemoryCard/MemoryCardDriverThreaded_MacOSX.cpp b/src/arch/MemoryCard/MemoryCardDriverThreaded_MacOSX.cpp index d2479a543d..13b5385238 100644 --- a/src/arch/MemoryCard/MemoryCardDriverThreaded_MacOSX.cpp +++ b/src/arch/MemoryCard/MemoryCardDriverThreaded_MacOSX.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "MemoryCardDriverThreaded_MacOSX.h" -#include "Foreach.h" #include "RageUtil.h" #include "RageLog.h" diff --git a/src/arch/MovieTexture/MovieTexture.cpp b/src/arch/MovieTexture/MovieTexture.cpp index 206ef0718b..f517bacb5b 100644 --- a/src/arch/MovieTexture/MovieTexture.cpp +++ b/src/arch/MovieTexture/MovieTexture.cpp @@ -6,7 +6,7 @@ #include "PrefsManager.h" #include "RageFile.h" #include "LocalizedString.h" -#include "Foreach.h" + #include "arch/arch_default.h" void ForceToAscii( RString &str ) diff --git a/src/arch/Sound/RageSoundDriver.cpp b/src/arch/Sound/RageSoundDriver.cpp index 7b369c87f3..9b0d68cab6 100644 --- a/src/arch/Sound/RageSoundDriver.cpp +++ b/src/arch/Sound/RageSoundDriver.cpp @@ -2,7 +2,7 @@ #include "RageSoundDriver.h" #include "RageLog.h" #include "RageUtil.h" -#include "Foreach.h" + #include "arch/arch_default.h" DriverList RageSoundDriver::m_pDriverList; diff --git a/src/arch/Sound/RageSoundDriver_WDMKS.cpp b/src/arch/Sound/RageSoundDriver_WDMKS.cpp index 61271c1b5c..d2315d1ceb 100644 --- a/src/arch/Sound/RageSoundDriver_WDMKS.cpp +++ b/src/arch/Sound/RageSoundDriver_WDMKS.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "RageSoundDriver_WDMKS.h" -#include "Foreach.h" + #include "RageLog.h" #include "RageUtil.h" #include "PrefsManager.h" diff --git a/src/arch/arch.cpp b/src/arch/arch.cpp index 69e5d189da..7295006738 100644 --- a/src/arch/arch.cpp +++ b/src/arch/arch.cpp @@ -8,7 +8,6 @@ #include "PrefsManager.h" #include "arch.h" #include "arch_platform.h" -#include "Foreach.h" #include "LocalizedString.h" #include "arch/arch_default.h" diff --git a/src/archutils/Darwin/JoystickDevice.cpp b/src/archutils/Darwin/JoystickDevice.cpp index eddb1b28ec..72a0c7b982 100644 --- a/src/archutils/Darwin/JoystickDevice.cpp +++ b/src/archutils/Darwin/JoystickDevice.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "JoystickDevice.h" #include "RageLog.h" -#include "Foreach.h" using __gnu_cxx::hash_map; diff --git a/src/archutils/Win32/CrashHandlerNetworking.cpp b/src/archutils/Win32/CrashHandlerNetworking.cpp index c00e846b11..6167522dd9 100644 --- a/src/archutils/Win32/CrashHandlerNetworking.cpp +++ b/src/archutils/Win32/CrashHandlerNetworking.cpp @@ -5,7 +5,7 @@ #include "RageThreads.h" #include "RageTimer.h" #include "RageUtil.h" -#include "Foreach.h" + #if defined(WINDOWS) #include diff --git a/src/smpackage/CreateLanguageDlg.cpp b/src/smpackage/CreateLanguageDlg.cpp index 6391934a2d..94f5e692b1 100644 --- a/src/smpackage/CreateLanguageDlg.cpp +++ b/src/smpackage/CreateLanguageDlg.cpp @@ -5,7 +5,6 @@ #include "stdafx.h" #include "smpackage.h" #include "CreateLanguageDlg.h" -#include "Foreach.h" #include "RageUtil.h" #include "SMPackageUtil.h" #include ".\createlanguagedlg.h" diff --git a/src/smpackage/LanguagesDlg.cpp b/src/smpackage/LanguagesDlg.cpp index 23cc3e6c88..e0a3cd9491 100644 --- a/src/smpackage/LanguagesDlg.cpp +++ b/src/smpackage/LanguagesDlg.cpp @@ -4,7 +4,6 @@ #include "global.h" #include "stdafx.h" #include "smpackage.h" -#include "Foreach.h" #include "LanguagesDlg.h" #include "SpecialFiles.h" #include "RageUtil.h"