/* Actor - Base class for all objects that appear on the screen. */ #ifndef ACTOR_H #define ACTOR_H #include "RageTypes.h" #include "RageUtil_AutoPtr.h" #include "ActorCommands.h" #include struct XNode; struct lua_State; class LuaReference; class LuaClass; #include "MessageManager.h" #include "RageUtil.h" // for ARRAYSIZE #define DRAW_ORDER_BEFORE_EVERYTHING -200 #define DRAW_ORDER_UNDERLAY -100 // normal screen elements go here #define DRAW_ORDER_OVERLAY +100 #define DRAW_ORDER_TRANSITIONS +110 #define DRAW_ORDER_AFTER_EVERYTHING +200 class Actor : public IMessageSubscriber { public: Actor(); Actor( const Actor &cpy ); virtual ~Actor(); virtual Actor *Copy() const; void UnsubcribeAndClearCommands(); virtual void Reset(); void LoadFromNode( const CString& sDir, const XNode* pNode ); static void SetBGMTime( float fTime, float fBeat ); static void SetBGMLight( int iLightNumber, float fCabinetLights ); enum TweenType { TWEEN_LINEAR, TWEEN_ACCELERATE, TWEEN_DECELERATE, TWEEN_SMOOTH, TWEEN_BOUNCE_BEGIN, TWEEN_BOUNCE_END, TWEEN_SPRING, }; enum Effect { no_effect, effect_lua, diffuse_blink, diffuse_shift, diffuse_ramp, glow_blink, glow_shift, rainbow, wag, bounce, bob, pulse, spin, vibrate }; struct TweenState { bool 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( crop ); COMPARE( fade ); for( unsigned i=0; istate; } enum StretchType { fit_inside, cover }; void ScaleToCover( const RectF &rect ) { ScaleTo( rect, cover ); } void ScaleToFitInside( const RectF &rect ) { ScaleTo( rect, fit_inside); }; void ScaleTo( const RectF &rect, StretchType st ); void StretchTo( const RectF &rect ); // // Alignment settings. These need to be virtual for BitmapText // enum HorizAlign { align_left, align_center, align_right }; virtual void SetHorizAlign( HorizAlign ha ) { m_HorizAlign = ha; } virtual void SetHorizAlignString( const CString &s ); // convenience enum VertAlign { align_top, align_middle, align_bottom }; virtual void SetVertAlign( VertAlign va ) { m_VertAlign = va; } virtual void SetVertAlignString( const CString &s ); // convenience // // effects // void StopEffect() { m_Effect = no_effect; } Effect GetEffect() const { return m_Effect; } float GetSecsIntoEffect() const { return m_fSecsIntoEffect; } float GetEffectDelta() const { return m_fEffectDelta; } void SetEffectColor1( RageColor c ) { m_effectColor1 = c; } void SetEffectColor2( RageColor c ) { m_effectColor2 = c; } void SetEffectPeriod( float fTime ); float GetEffectPeriod(); void SetEffectTiming( float fRampUp, float fAtHalf, float fRampDown, float fAtZero ); void SetEffectOffset( float fTime ) { m_fEffectOffset = fTime; } void SetEffectClock( EffectClock c ) { m_EffectClock = c; } void SetEffectClockString( const CString &s ); // convenience void SetEffectMagnitude( RageVector3 vec ) { m_vEffectMagnitude = vec; } RageVector3 GetEffectMagnitude() const { return m_vEffectMagnitude; } void SetEffectLua( const CString &sCommand ); void SetEffectDiffuseBlink( float fEffectPeriodSeconds = 1.0f, RageColor c1 = RageColor(0.5f,0.5f,0.5f,1), RageColor c2 = RageColor(1,1,1,1) ); void SetEffectDiffuseShift( float fEffectPeriodSeconds = 1.f, RageColor c1 = RageColor(0,0,0,1), RageColor c2 = RageColor(1,1,1,1) ); void SetEffectDiffuseRamp( float fEffectPeriodSeconds = 1.f, RageColor c1 = RageColor(0,0,0,1), RageColor c2 = RageColor(1,1,1,1) ); void SetEffectGlowBlink( float fEffectPeriodSeconds = 1.f, RageColor c1 = RageColor(1,1,1,0.2f), RageColor c2 = RageColor(1,1,1,0.8f) ); void SetEffectGlowShift( float fEffectPeriodSeconds = 1.0f, RageColor c1 = RageColor(1,1,1,0.2f), RageColor c2 = RageColor(1,1,1,0.8f) ); void SetEffectRainbow( float fEffectPeriodSeconds = 2.0f ); void SetEffectWag( float fPeriod = 2.f, RageVector3 vect = RageVector3(0,0,20) ); void SetEffectBounce( float fPeriod = 2.f, RageVector3 vect = RageVector3(0,20,0) ); void SetEffectBob( float fPeriod = 2.f, RageVector3 vect = RageVector3(0,20,0) ); void SetEffectPulse( float fPeriod = 2.f, float fMinZoom = 0.5f, float fMaxZoom = 1.f ); void SetEffectSpin( RageVector3 vect = RageVector3(0,0,180) ); void SetEffectVibrate( RageVector3 vect = RageVector3(10,10,10) ); // // other properties // bool GetVisible() const { return m_bVisible; } bool GetHidden() const { return !m_bVisible; } void SetVisible( bool b ) { m_bVisible = b; } void SetHidden( bool b ) { m_bVisible = !b; } void SetShadowLength( float fLength ); // TODO: Implement hibernate as a tween type? void SetHibernate( float fSecs ) { m_fHibernateSecondsLeft = fSecs; } void SetDrawOrder( int iOrder ) { m_iDrawOrder = iOrder; } int GetDrawOrder() const { return m_iDrawOrder; } virtual void EnableAnimation( bool b ) { m_bIsAnimating = b; } // Sprite needs to overload this void StartAnimating() { this->EnableAnimation(true); }; void StopAnimating() { this->EnableAnimation(false); }; // // render states // void SetBlendMode( BlendMode mode ) { m_BlendMode = mode; } void SetBlendModeString( const CString &s ); // convenience void SetTextureWrapping( bool b ) { m_bTextureWrapping = b; } void SetClearZBuffer( bool b ) { m_bClearZBuffer = b; } void SetUseZBuffer( bool b ) { SetZTestMode(b?ZTEST_WRITE_ON_PASS:ZTEST_OFF); SetZWrite(b); } virtual void SetZTestMode( ZTestMode mode ) { m_ZTestMode = mode; } void SetZTestModeString( const CString &s ); // convenience virtual void SetZWrite( bool b ) { m_bZWrite = b; } void SetZBias( float f ) { m_fZBias = f; } virtual void SetCullMode( CullMode mode ) { m_CullMode = mode; } void SetCullModeString( const CString &s ); // convenience // // Lua // virtual void PushSelf( lua_State *L ); // // Commands // void AddCommand( const CString &sCmdName, apActorCommands apac ); bool HasCommand( const CString &sCmdName ); const apActorCommands& GetCommand( const CString &sCommandName ) const; virtual void PlayCommand( const CString &sCommandName, Actor *pParent = NULL ); virtual void RunCommands( const LuaReference& cmds, Actor *pParent = NULL ); void RunCommands( const apActorCommands& cmds, Actor *pParent = NULL ) { this->RunCommands( *cmds, pParent ); } // convenience // If we're a leaf, then execute this command. virtual void RunCommandsOnLeaves( const LuaReference& cmds, Actor *pParent = NULL ) { RunCommands(cmds,pParent); } static float GetCommandsLengthSeconds( const LuaReference& cmds ); static float GetCommandsLengthSeconds( const apActorCommands& cmds ) { return GetCommandsLengthSeconds( *cmds ); } // convenience // // Messages // void SubscribeToMessage( Message message ); // will automatically unsubscribe void SubscribeToMessage( const CString &sMessageName ); // will automatically unsubscribe virtual void HandleMessage( const CString& sMessage ); // // Animation // virtual int GetNumStates() const { return 1; } virtual void SetState( int iNewState ) {} virtual float GetAnimationLengthSeconds() const { return 0; } virtual void SetSecondsIntoAnimation( float fSeconds ) {} virtual void SetUpdateRate( float fRate ) {} HiddenPtr m_pLuaInstance; protected: CString m_sName; struct TweenInfo { // counters for tweening TweenType m_TweenType; float m_fTimeLeftInTween; // how far into the tween are we? float m_fTweenTime; // seconds between Start and End positions/zooms }; RageVector3 m_baseRotation; RageVector3 m_baseScale; float m_fBaseAlpha; RageVector2 m_size; TweenState m_current; TweenState m_start; struct TweenStateAndInfo { TweenState state; TweenInfo info; }; vector m_Tweens; // // Temporary variables that are filled just before drawing // TweenState *m_pTempState; bool m_bFirstUpdate; // // Stuff for alignment // HorizAlign m_HorizAlign; VertAlign m_VertAlign; // // Stuff for effects // Effect m_Effect; CString m_sEffectCommand; // effect_lua float m_fSecsIntoEffect, m_fEffectDelta; // units depend on m_EffectClock float m_fEffectRampUp; float m_fEffectHoldAtHalf; float m_fEffectRampDown; float m_fEffectHoldAtZero; float m_fEffectOffset; EffectClock m_EffectClock; /* This can be used in lieu of the fDeltaTime parameter to Update() to * follow the effect clock. Actor::Update must be called first. */ float GetEffectDeltaTime() const { return m_fEffectDelta; } RageColor m_effectColor1; RageColor m_effectColor2; RageVector3 m_vEffectMagnitude; // // other properties // bool m_bVisible; float m_fHibernateSecondsLeft; float m_fShadowLength; // 0 == no shadow bool m_bIsAnimating; int m_iDrawOrder; // // render states // bool m_bTextureWrapping; BlendMode m_BlendMode; bool m_bClearZBuffer; ZTestMode m_ZTestMode; bool m_bZWrite; float m_fZBias; // 0 = no bias; 1 = full bias CullMode m_CullMode; // // global state // static float g_fCurrentBGMTime, g_fCurrentBGMBeat; private: // // commands // map m_mapNameToCommands; vector m_vsSubscribedTo; }; #endif /* * (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. */