2011-09-23 15:39:54 -07:00
# 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 <typeinfo>
static Preference < bool > 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 < float > Actor : : g_vfCurrentBGMBeatPlayer ( NUM_PlayerNumber , 0 ) ;
vector < float > 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 ( )
{
2014-04-14 21:29:19 -05:00
this - > StopTweening ( ) ;
2011-09-23 15:39:54 -07:00
m_pTempState = NULL ;
m_baseRotation = RageVector3 ( 0 , 0 , 0 ) ;
m_baseScale = RageVector3 ( 1 , 1 , 1 ) ;
m_fBaseAlpha = 1 ;
2013-05-28 21:46:15 -04:00
m_internalDiffuse = RageColor ( 1 , 1 , 1 , 1 ) ;
2013-05-28 20:52:01 -04:00
m_internalGlow = RageColor ( 0 , 0 , 0 , 0 ) ;
2011-09-23 15:39:54 -07:00
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 ;
2014-02-20 21:17:10 -06:00
m_texTranslate = RageVector2 ( 0 , 0 ) ;
2011-09-23 15:39:54 -07:00
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 ) ;
2013-05-28 21:46:15 -04:00
CPY ( m_internalDiffuse ) ;
2013-05-28 20:52:01 -04:00
CPY ( m_internalGlow ) ;
2011-09-23 15:39:54 -07:00
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 < RString > ( ) ) ;
else if ( sKeyName = = " BaseRotationX " ) SetBaseRotationX ( pValue - > GetValue < float > ( ) ) ;
else if ( sKeyName = = " BaseRotationY " ) SetBaseRotationY ( pValue - > GetValue < float > ( ) ) ;
else if ( sKeyName = = " BaseRotationZ " ) SetBaseRotationZ ( pValue - > GetValue < float > ( ) ) ;
else if ( sKeyName = = " BaseZoomX " ) SetBaseZoomX ( pValue - > GetValue < float > ( ) ) ;
else if ( sKeyName = = " BaseZoomY " ) SetBaseZoomY ( pValue - > GetValue < float > ( ) ) ;
else if ( sKeyName = = " BaseZoomZ " ) SetBaseZoomZ ( pValue - > GetValue < float > ( ) ) ;
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 ( )
{
2013-12-13 12:10:11 -06:00
if ( ! m_bVisible | |
m_fHibernateSecondsLeft > 0 | |
this - > EarlyAbortDraw ( ) )
return ; // early abort
this - > PreDraw ( ) ;
ASSERT ( m_pTempState ! = NULL ) ;
2014-03-09 00:17:45 -06:00
if ( m_pTempState - > diffuse [ 0 ] . a ! = 0 | | m_pTempState - > diffuse [ 1 ] . a ! = 0 | | m_pTempState - > diffuse [ 2 ] . a ! = 0 | | m_pTempState - > diffuse [ 3 ] . a ! = 0 | | m_pTempState - > glow . a ! = 0 ) // This Actor is not fully transparent
2013-12-20 17:29:49 -06:00
{
// call the most-derived versions
this - > BeginDraw ( ) ;
this - > DrawPrimitives ( ) ; // call the most-derived version of DrawPrimitives();
this - > EndDraw ( ) ;
}
m_pTempState = NULL ;
2011-09-23 15:39:54 -07:00
}
2013-12-13 12:10:11 -06:00
void Actor : : PreDraw ( ) // calculate actor properties
2011-09-23 15:39:54 -07:00
{
// 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 :
2012-12-27 16:59:35 -05:00
FAIL_M ( ssprintf ( " Invalid effect: %i " , m_Effect ) ) ;
2011-09-23 15:39:54 -07:00
}
}
if ( m_fBaseAlpha ! = 1 )
2013-05-28 21:46:15 -04:00
m_internalDiffuse . a * = m_fBaseAlpha ;
if ( m_internalDiffuse ! = RageColor ( 1 , 1 , 1 , 1 ) )
2011-09-23 15:39:54 -07:00
{
if ( m_pTempState ! = & tempState )
{
m_pTempState = & tempState ;
tempState = m_current ;
}
for ( int i = 0 ; i < 4 ; i + + )
2013-05-28 21:46:15 -04:00
{
tempState . diffuse [ i ] * = m_internalDiffuse ;
}
m_internalDiffuse = RageColor ( 1 , 1 , 1 , 1 ) ;
2011-09-23 15:39:54 -07:00
}
2013-05-28 20:52:01 -04:00
if ( m_internalGlow . a > 0 )
{
if ( m_pTempState ! = & tempState )
{
m_pTempState = & tempState ;
tempState = m_current ;
}
// Blend using Screen mode
tempState . glow = tempState . glow + m_internalGlow - m_internalGlow * tempState . glow ;
m_internalGlow . a = 0 ;
}
2013-12-13 12:10:11 -06:00
}
void Actor : : BeginDraw ( ) // set the world matrix
{
DISPLAY - > PushMatrix ( ) ;
2013-05-28 20:52:01 -04:00
2011-09-23 15:39:54 -07:00
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 ) ;
}
2014-02-20 21:17:10 -06:00
if ( m_texTranslate . x ! = 0 | | m_texTranslate . y ! = 0 )
{
DISPLAY - > TexturePushMatrix ( ) ;
DISPLAY - > TextureTranslate ( m_texTranslate . x , m_texTranslate . y ) ;
}
2011-09-23 15:39:54 -07:00
}
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 ( ) ;
2014-02-20 21:17:10 -06:00
if ( m_texTranslate . x ! = 0 | | m_texTranslate . y ! = 0 )
DISPLAY - > TexturePopMatrix ( ) ;
2011-09-23 15:39:54 -07:00
}
void Actor : : UpdateTweening ( float fDeltaTime )
{
2014-04-14 21:29:19 -05:00
while ( ! m_Tweens . empty ( ) // something to do
& & fDeltaTime > 0 ) // something will change
2011-09-23 15:39:54 -07:00
{
// 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
2014-04-14 21:29:19 -05:00
{
2011-09-23 15:39:54 -07:00
m_start = m_current ; // set the start position
2014-04-14 21:29:19 -05:00
SetCurrentTweenStart ( ) ;
}
2011-09-23 15:39:54 -07:00
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 ( ) ) ;
2014-04-14 21:29:19 -05:00
EraseHeadTween ( ) ;
2011-09-23 15:39:54 -07:00
}
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 ) ;
2014-04-14 21:29:19 -05:00
UpdatePercentThroughTween ( fPercentAlongPath ) ;
2011-09-23 15:39:54 -07:00
}
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 ;
}
2014-04-14 21:29:19 -05:00
this - > UpdateTweening ( fDeltaTime ) ;
2011-09-23 15:39:54 -07:00
}
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 ) ;
// 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 ) ;
2014-04-14 21:29:19 -05:00
this - > FinishTweening ( ) ;
2011-09-23 15:39:54 -07:00
}
// 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 )
{
2013-10-20 18:02:13 -04:00
ASSERT ( time > = 0 ) ;
2011-09-23 15:39:54 -07:00
ITween * pTween = ITween : : CreateFromType ( tt ) ;
2014-04-14 21:29:19 -05:00
this - > BeginTweening ( time , pTween ) ;
2011-09-23 15:39:54 -07:00
}
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 ( ) ;
2014-04-14 21:29:19 -05:00
this - > StopTweening ( ) ;
2011-09-23 15:39:54 -07:00
}
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 ) ;
2012-12-27 16:59:35 -05:00
if ( cl = = CabinetLight_Invalid )
FAIL_M ( ssprintf ( " Invalid cabinet light: %s " , s . c_str ( ) ) ) ;
this - > SetEffectClock ( ( EffectClock ) ( cl + CLOCK_LIGHT_1 ) ) ;
2011-09-23 15:39:54 -07:00
}
}
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 )
{
2013-10-20 17:37:45 -04:00
// No negative timings
ASSERT ( fRampUp > = 0 & & fAtHalf > = 0 & & fRampDown > = 0 & & fAtZero > = 0 ) ;
// and at least one positive timing.
ASSERT ( fRampUp > 0 | | fAtHalf > 0 | | fRampDown > 0 | | fAtZero > 0 ) ;
2011-09-23 15:39:54 -07:00
m_fEffectRampUp = fRampUp ;
m_fEffectHoldAtHalf = fAtHalf ;
m_fEffectRampDown = fRampDown ;
m_fEffectHoldAtZero = fAtZero ;
}
// effect "macros"
void Actor : : SetEffectDiffuseBlink ( float fEffectPeriodSeconds , RageColor c1 , RageColor c2 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fEffectPeriodSeconds > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fPeriod > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fPeriod > 0 ) ;
2011-09-23 15:39:54 -07:00
// todo: account for SSC_FUTURES -aj
m_Effect = bounce ;
SetEffectPeriod ( fPeriod ) ;
m_vEffectMagnitude = vect ;
m_fSecsIntoEffect = 0 ;
}
void Actor : : SetEffectBob ( float fPeriod , RageVector3 vect )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fPeriod > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 16:59:24 -04:00
ASSERT ( fPeriod > 0 ) ;
2011-09-23 15:39:54 -07:00
// 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 )
{
2013-10-20 23:05:26 -04:00
if ( ! cmds . IsSet ( ) | | cmds . IsNil ( ) )
{
LOG - > Warn ( " RunCommands: command is unset or nil " ) ;
return ;
}
2011-09-23 15:39:54 -07:00
Lua * L = LUA - > Get ( ) ;
// function
cmds . PushSelf ( L ) ;
2013-10-13 14:35:48 -04:00
if ( lua_isnil ( L , - 1 ) )
{
LOG - > Warn ( " Error compiling commands " ) ;
LUA - > Release ( L ) ;
return ;
}
2011-09-23 15:39:54 -07:00
// 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
2014-07-05 01:34:05 -06:00
RString Error = " Error playing command: " ;
LuaHelpers : : RunScriptOnStack ( L , Error , 2 , 0 , true ) ;
2011-09-23 15:39:54 -07:00
LUA - > Release ( L ) ;
}
float Actor : : GetTweenTimeLeft ( ) const
{
float tot = 0 ;
tot + = m_fHibernateSecondsLeft ;
for ( unsigned i = 0 ; i < m_Tweens . size ( ) ; + + i )
tot + = m_Tweens [ i ] - > info . 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 ; i < ARRAYLEN ( diffuse ) ; i + + )
COMPARE ( diffuse [ i ] ) ;
COMPARE ( glow ) ;
COMPARE ( aux ) ;
# undef COMPARE
return true ;
}
void Actor : : TweenState : : MakeWeightedAverage ( TweenState & average_out , const TweenState & ts1 , const TweenState & ts2 , float fPercentBetween )
{
average_out . pos = lerp ( fPercentBetween , ts1 . pos , ts2 . pos ) ;
average_out . scale = lerp ( fPercentBetween , ts1 . scale , ts2 . scale ) ;
average_out . rotation = lerp ( fPercentBetween , ts1 . rotation , ts2 . rotation ) ;
RageQuatSlerp ( & average_out . quat , ts1 . quat , ts2 . quat , fPercentBetween ) ;
average_out . fSkewX = lerp ( fPercentBetween , ts1 . fSkewX , ts2 . fSkewX ) ;
average_out . fSkewY = lerp ( fPercentBetween , ts1 . fSkewY , ts2 . fSkewY ) ;
average_out . crop . left = lerp ( fPercentBetween , ts1 . crop . left , ts2 . crop . left ) ;
average_out . crop . top = lerp ( fPercentBetween , ts1 . crop . top , ts2 . crop . top ) ;
average_out . crop . right = lerp ( fPercentBetween , ts1 . crop . right , ts2 . crop . right ) ;
average_out . crop . bottom = lerp ( fPercentBetween , ts1 . crop . bottom , ts2 . crop . bottom ) ;
average_out . fade . left = lerp ( fPercentBetween , ts1 . fade . left , ts2 . fade . left ) ;
average_out . fade . top = lerp ( fPercentBetween , ts1 . fade . top , ts2 . fade . top ) ;
average_out . fade . right = lerp ( fPercentBetween , ts1 . fade . right , ts2 . fade . right ) ;
average_out . fade . bottom = lerp ( fPercentBetween , ts1 . fade . bottom , ts2 . fade . bottom ) ;
for ( int i = 0 ; i < 4 ; + + i )
average_out . diffuse [ i ] = lerp ( fPercentBetween , ts1 . diffuse [ i ] , ts2 . diffuse [ i ] ) ;
average_out . glow = lerp ( fPercentBetween , ts1 . glow , ts2 . glow ) ;
average_out . aux = lerp ( fPercentBetween , ts1 . aux , ts2 . aux ) ;
}
void Actor : : Sleep ( float time )
{
2013-10-20 18:02:13 -04:00
ASSERT ( time > = 0 ) ;
2011-09-23 15:39:54 -07:00
BeginTweening ( time , TWEEN_LINEAR ) ;
BeginTweening ( 0 , TWEEN_LINEAR ) ;
}
void Actor : : QueueCommand ( const RString & sCommandName )
{
BeginTweening ( 0 , TWEEN_LINEAR ) ;
TweenInfo & TI = m_Tweens . back ( ) - > info ;
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 < RString , apActorCommands > : : 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 < Actor >
{
public :
static int name ( T * p , lua_State * L ) { p - > SetName ( SArg ( 1 ) ) ; return 0 ; }
2013-10-20 18:02:13 -04:00
static int sleep ( T * p , lua_State * L )
{
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: sleep(%f): time must not be negative " , fTime ) ;
return 0 ;
}
p - > Sleep ( fTime ) ;
return 0 ;
}
static int linear ( T * p , lua_State * L )
{
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: linear(%f): tween time must not be negative " , fTime ) ;
return 0 ;
}
p - > BeginTweening ( fTime , TWEEN_LINEAR ) ;
return 0 ;
}
static int accelerate ( T * p , lua_State * L )
{
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: accelerate(%f): tween time must not be negative " , fTime ) ;
return 0 ;
}
p - > BeginTweening ( fTime , TWEEN_ACCELERATE ) ;
return 0 ;
}
static int decelerate ( T * p , lua_State * L )
{
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: decelerate(%f): tween time must not be negative " , fTime ) ;
return 0 ;
}
p - > BeginTweening ( fTime , TWEEN_DECELERATE ) ;
return 0 ;
}
static int spring ( T * p , lua_State * L )
{
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: spring(%f): tween time must not be negative " , fTime ) ;
return 0 ;
}
p - > BeginTweening ( fTime , TWEEN_SPRING ) ;
return 0 ;
}
2011-09-23 15:39:54 -07:00
static int tween ( T * p , lua_State * L )
{
2013-10-20 18:02:13 -04:00
float fTime = FArg ( 1 ) ;
if ( fTime < 0 )
{
LOG - > Warn ( " Lua: tween(%f): tween time must not be negative " , fTime ) ;
return 0 ;
}
2011-09-23 15:39:54 -07:00
ITween * pTween = ITween : : CreateFromStack ( L , 2 ) ;
2013-10-20 18:02:13 -04:00
p - > BeginTweening ( fTime , pTween ) ;
2011-09-23 15:39:54 -07:00
return 0 ;
}
2012-12-27 11:01:51 -05:00
static int stoptweening ( T * p , lua_State * ) { p - > StopTweening ( ) ; return 0 ; }
static int finishtweening ( T * p , lua_State * ) { p - > FinishTweening ( ) ; return 0 ; }
2011-09-23 15:39:54 -07:00
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 ; }
2012-05-19 00:20:30 -05:00
static int xy ( T * p , lua_State * L ) { p - > SetXY ( FArg ( 1 ) , FArg ( 2 ) ) ; return 0 ; }
2011-09-23 15:39:54 -07:00
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 < HorizAlign > ( L , 1 ) ) ; return 0 ; }
static int vertalign ( T * p , lua_State * L ) { p - > SetVertAlign ( Enum : : Check < VertAlign > ( 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 ; }
2013-10-20 16:34:19 -04:00
static int diffuseblink ( T * p , lua_State * ) { p - > SetEffectDiffuseBlink ( 1.0f , RageColor ( 0.5f , 0.5f , 0.5f , 0.5f ) , RageColor ( 1 , 1 , 1 , 1 ) ) ; return 0 ; }
static int diffuseshift ( T * p , lua_State * ) { p - > SetEffectDiffuseShift ( 1.0f , RageColor ( 0 , 0 , 0 , 1 ) , RageColor ( 1 , 1 , 1 , 1 ) ) ; return 0 ; }
static int diffuseramp ( T * p , lua_State * ) { p - > SetEffectDiffuseRamp ( 1.0f , RageColor ( 0 , 0 , 0 , 1 ) , RageColor ( 1 , 1 , 1 , 1 ) ) ; return 0 ; }
static int glowblink ( T * p , lua_State * ) { p - > SetEffectGlowBlink ( 1.0f , RageColor ( 1 , 1 , 1 , 0.2f ) , RageColor ( 1 , 1 , 1 , 0.8f ) ) ; return 0 ; }
static int glowshift ( T * p , lua_State * ) { p - > SetEffectGlowShift ( 1.0f , RageColor ( 1 , 1 , 1 , 0.2f ) , RageColor ( 1 , 1 , 1 , 0.8f ) ) ; return 0 ; }
static int glowramp ( T * p , lua_State * ) { p - > SetEffectGlowRamp ( 1.0f , RageColor ( 1 , 1 , 1 , 0.2f ) , RageColor ( 1 , 1 , 1 , 0.8f ) ) ; return 0 ; }
static int rainbow ( T * p , lua_State * ) { p - > SetEffectRainbow ( 2.0f ) ; return 0 ; }
static int wag ( T * p , lua_State * ) { p - > SetEffectWag ( 2.0f , RageVector3 ( 0 , 0 , 20 ) ) ; return 0 ; }
static int bounce ( T * p , lua_State * ) { p - > SetEffectBounce ( 2.0f , RageVector3 ( 0 , 20 , 0 ) ) ; return 0 ; }
static int bob ( T * p , lua_State * ) { p - > SetEffectBob ( 2.0f , RageVector3 ( 0 , 20 , 0 ) ) ; return 0 ; }
static int pulse ( T * p , lua_State * ) { p - > SetEffectPulse ( 2.0f , 0.5f , 1.0f ) ; return 0 ; }
static int spin ( T * p , lua_State * ) { p - > SetEffectSpin ( RageVector3 ( 0 , 0 , 180 ) ) ; return 0 ; }
static int vibrate ( T * p , lua_State * ) { p - > SetEffectVibrate ( RageVector3 ( 10 , 10 , 10 ) ) ; return 0 ; }
2012-12-27 11:01:51 -05:00
static int stopeffect ( T * p , lua_State * ) { p - > StopEffect ( ) ; return 0 ; }
2011-09-23 15:39:54 -07:00
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 ; }
2013-10-20 16:59:24 -04:00
static int effectperiod ( T * p , lua_State * L )
{
float fPeriod = FArg ( 1 ) ;
if ( fPeriod < = 0 )
{
LOG - > Warn ( " Effect period (%f) must be positive; ignoring " , fPeriod ) ;
return 0 ;
}
p - > SetEffectPeriod ( FArg ( 1 ) ) ;
return 0 ;
}
2013-10-20 17:37:45 -04:00
static int effecttiming ( T * p , lua_State * L )
{
float f1 = FArg ( 1 ) , f2 = FArg ( 2 ) , f3 = FArg ( 3 ) , f4 = FArg ( 4 ) ;
if ( f1 < 0 | | f2 < 0 | | f3 < 0 | | f4 < 0 )
{
LOG - > Warn ( " Effect timings (%f,%f,%f,%f) must not be negative; ignoring " ,
f1 , f2 , f3 , f4 ) ;
return 0 ;
}
if ( f1 = = 0 & & f2 = = 0 & & f3 = = 0 & & f4 = = 0 )
{
LOG - > Warn ( " Effect timings (0,0,0,0) must not all be zero; ignoring " ) ;
return 0 ;
}
p - > SetEffectTiming ( FArg ( 1 ) , FArg ( 2 ) , FArg ( 3 ) , FArg ( 4 ) ) ;
return 0 ;
}
2011-09-23 15:39:54 -07:00
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 ; }
2012-12-27 11:01:51 -05:00
static int play ( T * p , lua_State * ) { p - > EnableAnimation ( true ) ; return 0 ; }
static int pause ( T * p , lua_State * ) { p - > EnableAnimation ( false ) ; return 0 ; }
2011-09-23 15:39:54 -07:00
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 ; }
2014-02-21 16:41:30 -06:00
static int texturetranslate ( T * p , lua_State * L ) { p - > SetTextureTranslate ( FArg ( 1 ) , FArg ( 2 ) ) ; return 0 ; }
2011-09-23 15:39:54 -07:00
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 < BlendMode > ( 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 < ZTestMode > ( 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 < CullMode > ( 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 ; }
2014-07-04 02:03:05 -06:00
static int GetDestX ( T * p , lua_State * L ) { lua_pushnumber ( L , p - > GetDestX ( ) ) ; return 1 ; }
static int GetDestY ( T * p , lua_State * L ) { lua_pushnumber ( L , p - > GetDestY ( ) ) ; return 1 ; }
static int GetDestZ ( T * p , lua_State * L ) { lua_pushnumber ( L , p - > GetDestZ ( ) ) ; return 1 ; }
2011-09-23 15:39:54 -07:00
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 ) ;
2012-05-19 00:20:30 -05:00
ADD_METHOD ( xy ) ;
2011-09-23 15:39:54 -07:00
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 ) ;
2014-02-20 21:17:10 -06:00
ADD_METHOD ( texturetranslate ) ;
2011-09-23 15:39:54 -07:00
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 ) ;
2014-07-04 02:03:05 -06:00
ADD_METHOD ( GetDestX ) ;
ADD_METHOD ( GetDestY ) ;
ADD_METHOD ( GetDestZ ) ;
2011-09-23 15:39:54 -07:00
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.
*/