Files
itgmania212121/stepmania/src/Actor.h
T

436 lines
16 KiB
C++
Raw Normal View History

2004-06-08 00:47:53 +00:00
/* Actor - Base class for all objects that appear on the screen. */
#ifndef ACTOR_H
#define ACTOR_H
2001-11-03 10:52:42 +00:00
#include "RageTypes.h"
2004-12-03 05:19:46 +00:00
#include "Command.h"
#include <deque>
2001-11-03 10:52:42 +00:00
2004-05-02 03:01:27 +00:00
#define DRAW_ORDER_BEFORE_EVERYTHING -100
#define DRAW_ORDER_TRANSITIONS 100
#define DRAW_ORDER_AFTER_EVERYTHING 200
2001-11-03 10:52:42 +00:00
class Actor
{
public:
Actor();
virtual ~Actor() {}
virtual void Reset();
2002-01-16 10:01:32 +00:00
static void SetBGMTime( float fTime, float fBeat ) { g_fCurrentBGMTime = fTime; g_fCurrentBGMBeat = fBeat; }
2004-07-07 21:17:47 +00:00
2002-04-01 02:04:43 +00:00
enum TweenType {
TWEEN_LINEAR,
2003-03-02 01:43:33 +00:00
TWEEN_ACCELERATE,
TWEEN_DECELERATE,
2002-04-01 02:04:43 +00:00
TWEEN_BOUNCE_BEGIN,
TWEEN_BOUNCE_END,
TWEEN_SPRING,
};
2001-11-28 20:26:45 +00:00
enum Effect { no_effect,
2003-03-02 01:43:33 +00:00
diffuse_blink, diffuse_shift,
glow_blink, glow_shift,
2003-03-05 02:52:40 +00:00
rainbow,
wag, bounce, bob, pulse,
spin, vibrate
2001-11-28 20:26:45 +00:00
};
2001-11-03 10:52:42 +00:00
2002-01-16 10:01:32 +00:00
struct TweenState
{
// start and end position for tweening
RageVector3 pos;
RageVector3 rotation;
RageVector4 quat;
RageVector3 scale;
RectF crop; // 0 = no cropping, 1 = fully cropped
2003-11-08 19:23:40 +00:00
RectF fade; // 0 = no fade
RageColor fadecolor;
RageColor diffuse[4];
RageColor glow;
2003-05-04 22:35:42 +00:00
GlowMode glowmode;
2004-12-03 05:19:46 +00:00
Command command; // command to execute when this
2002-01-16 10:01:32 +00:00
2003-04-02 05:41:22 +00:00
void Init();
static void MakeWeightedAverage( TweenState& average_out, const TweenState& ts1, const TweenState& ts2, float fPercentBetween );
};
enum EffectClock { CLOCK_TIMER, CLOCK_BGM_TIME, CLOCK_BGM_BEAT, NUM_CLOCKS };
2003-12-18 10:31:42 +00:00
void Draw(); // calls, NeedsDraw, BeginDraw, DrawPrimitives, EndDraw
virtual bool EarlyAbortDraw() { return false; } // return true to early abort drawing of this Actor
virtual void BeginDraw(); // pushes transform onto world matrix stack
virtual void SetRenderStates(); // Actor should call at beginning of their DrawPrimitives() after setting textures
virtual void DrawPrimitives() {}; // Derivitives should override
virtual void EndDraw(); // pops transform from world matrix stack
2003-03-02 01:43:33 +00:00
bool IsFirstUpdate();
virtual void Update( float fDeltaTime );
void UpdateTweening( float fDeltaTime );
void CopyTweening( const Actor &from );
2003-04-12 06:16:12 +00:00
2003-11-14 23:01:35 +00:00
CString m_sName, m_sID;
2003-04-12 06:16:12 +00:00
2003-11-14 23:01:35 +00:00
/* m_sName is the name actors use to look up internal metrics for themselves, and for
* filenames. m_sID is the name parents use to look up their own metrics for an actor
* (usually via ActorUtil). (This is experimental; see DifficultyMeter.cpp for more
* information.) */
2004-11-06 03:00:10 +00:00
const CString &GetName() const { return m_sName; }
const CString &GetID() const { return m_sID.empty() ? m_sName : m_sID; }
void SetName( const CString &sName, const CString &sID = "" ) { m_sName = sName; m_sID = sID; }
2003-04-12 06:16:12 +00:00
/* Do subclasses really need to override tweening? Tween data should
* probably be private ... - glenn */
2003-04-12 06:16:12 +00:00
/* Things like a "FocusingSprite" might, but probably not. -Chris */
2003-03-07 20:27:28 +00:00
/* Return the current coordinates, not the destination coordinates;
* that's what the old behavior was, at least, and it's what ScreenMusicScroll
* expects. I could see uses for knowing the destination coords, though,
* especially now that setting parameters when tweening and when not tweening
* is somewhat abstracted. Hmmm. -glenn */
2003-04-12 06:16:12 +00:00
/* Things like the cursor on ScreenSelectDifficutly need to know the dest coordinates.
* -Chris */
float GetX() const { return m_current.pos.x; };
float GetY() const { return m_current.pos.y; };
float GetZ() const { return m_current.pos.z; };
float GetDestX() { return DestTweenState().pos.x; };
float GetDestY() { return DestTweenState().pos.y; };
float GetDestZ() { return DestTweenState().pos.z; };
void SetX( float x ) { DestTweenState().pos.x = x; };
void SetY( float y ) { DestTweenState().pos.y = y; };
void SetZ( float z ) { DestTweenState().pos.z = z; };
void SetXY( float x, float y ) { DestTweenState().pos.x = x; DestTweenState().pos.y = y; };
void AddX( float x ) { SetX( GetDestX()+x ); }
void AddY( float y ) { SetY( GetDestY()+y ); }
void AddZ( float z ) { SetZ( GetDestZ()+z ); }
2003-03-02 01:43:33 +00:00
// height and width vary depending on zoom
float GetUnzoomedWidth() { return m_size.x; }
float GetUnzoomedHeight() { return m_size.y; }
float GetZoomedWidth() { return m_size.x * m_baseScale.x * DestTweenState().scale.x; }
float GetZoomedHeight() { return m_size.y * m_baseScale.y * DestTweenState().scale.y; }
void SetWidth( float width ) { m_size.x = width; }
void SetHeight( float height ) { m_size.y = height; }
2003-03-02 01:43:33 +00:00
void SetBaseZoomX( float zoom ) { m_baseScale.x = zoom; }
void SetBaseZoomY( float zoom ) { m_baseScale.y = zoom; }
void SetBaseZoomZ( float zoom ) { m_baseScale.z = zoom; }
2004-10-16 16:59:17 +00:00
void SetBaseZoom( const RageVector3 &zoom ) { m_baseScale = zoom; }
void SetBaseRotationX( float rot ) { m_baseRotation.x = rot; }
void SetBaseRotationY( float rot ) { m_baseRotation.y = rot; }
void SetBaseRotationZ( float rot ) { m_baseRotation.z = rot; }
2004-10-16 16:59:17 +00:00
void SetBaseRotation( const RageVector3 &rot ) { m_baseRotation = rot; }
float GetZoom() { return DestTweenState().scale.x; } // not accurate in some cases
float GetZoomX() { return DestTweenState().scale.x; }
float GetZoomY() { return DestTweenState().scale.y; }
float GetZoomZ() { return DestTweenState().scale.z; }
void SetZoom( float zoom ) { DestTweenState().scale.x = zoom; DestTweenState().scale.y = zoom; }
void SetZoomX( float zoom ) { DestTweenState().scale.x = zoom; }
void SetZoomY( float zoom ) { DestTweenState().scale.y = zoom; }
void SetZoomZ( float zoom ) { DestTweenState().scale.z = zoom; }
void ZoomToWidth( float zoom ) { SetZoomX( zoom / GetUnzoomedWidth() ); }
void ZoomToHeight( float zoom ){ SetZoomY( zoom / GetUnzoomedHeight() ); }
2003-03-02 01:43:33 +00:00
float GetRotationX() { return DestTweenState().rotation.x; }
float GetRotationY() { return DestTweenState().rotation.y; }
float GetRotationZ() { return DestTweenState().rotation.z; }
void SetRotationX( float rot ) { DestTweenState().rotation.x = rot; }
void SetRotationY( float rot ) { DestTweenState().rotation.y = rot; }
void SetRotationZ( float rot ) { DestTweenState().rotation.z = rot; }
void AddRotationH( float rot );
void AddRotationP( float rot );
void AddRotationR( float rot );
2003-03-02 01:43:33 +00:00
float GetCropLeft() { return DestTweenState().crop.left; }
float GetCropTop() { return DestTweenState().crop.top; }
float GetCropRight() { return DestTweenState().crop.right;}
float GetCropBottom() { return DestTweenState().crop.bottom;}
void SetCropLeft( float percent ) { DestTweenState().crop.left = percent; }
void SetCropTop( float percent ) { DestTweenState().crop.top = percent; }
void SetCropRight( float percent ) { DestTweenState().crop.right = percent;}
void SetCropBottom( float percent ){ DestTweenState().crop.bottom = percent;}
void SetFadeLeft( float percent ) { DestTweenState().fade.left = percent; }
void SetFadeTop( float percent ) { DestTweenState().fade.top = percent; }
void SetFadeRight( float percent ) { DestTweenState().fade.right = percent;}
void SetFadeBottom( float percent ){ DestTweenState().fade.bottom = percent;}
void SetFadeDiffuseColor( const RageColor &c ) { DestTweenState().fadecolor = c; }
void SetGlobalDiffuseColor( RageColor c );
void SetGlobalX( float x );
virtual void SetDiffuse( RageColor c ) { for(int i=0; i<4; i++) DestTweenState().diffuse[i] = c; };
virtual void SetDiffuseAlpha( float f ) { for(int i = 0; i < 4; ++i) { RageColor c = GetDiffuses( i ); c.a = f; SetDiffuses( i, c ); } }
void SetDiffuseColor( RageColor c );
void SetDiffuses( int i, RageColor c ) { DestTweenState().diffuse[i] = c; };
void SetDiffuseUpperLeft( RageColor c ) { DestTweenState().diffuse[0] = c; };
void SetDiffuseUpperRight( RageColor c ) { DestTweenState().diffuse[1] = c; };
void SetDiffuseLowerLeft( RageColor c ) { DestTweenState().diffuse[2] = c; };
void SetDiffuseLowerRight( RageColor c ) { DestTweenState().diffuse[3] = c; };
void SetDiffuseTopEdge( RageColor c ) { DestTweenState().diffuse[0] = DestTweenState().diffuse[1] = c; };
void SetDiffuseRightEdge( RageColor c ) { DestTweenState().diffuse[1] = DestTweenState().diffuse[3] = c; };
void SetDiffuseBottomEdge( RageColor c ) { DestTweenState().diffuse[2] = DestTweenState().diffuse[3] = c; };
void SetDiffuseLeftEdge( RageColor c ) { DestTweenState().diffuse[0] = DestTweenState().diffuse[2] = c; };
RageColor GetDiffuse() { return DestTweenState().diffuse[0]; };
RageColor GetDiffuses( int i ) { return DestTweenState().diffuse[i]; };
void SetGlow( RageColor c ) { DestTweenState().glow = c; };
RageColor GetGlow() { return DestTweenState().glow; };
void SetGlowMode( GlowMode m ) { DestTweenState().glowmode = m; };
GlowMode GetGlowMode() { return DestTweenState().glowmode; };
2003-03-02 01:43:33 +00:00
void BeginTweening( float time, TweenType tt = TWEEN_LINEAR );
void StopTweening();
2004-04-24 18:38:18 +00:00
void Sleep( float time );
2004-12-03 05:19:46 +00:00
void QueueCommand( Command command );
virtual void FinishTweening();
virtual void HurryTweening( float factor );
// Let ActorFrame and BGAnimation override
2003-03-02 01:43:33 +00:00
virtual float GetTweenTimeLeft() const; // Amount of time until all tweens have stopped
TweenState& DestTweenState() // where Actor will end when its tween finish
2003-03-02 01:43:33 +00:00
{
if( m_TweenStates.empty() ) // not tweening
return m_current;
else
return LatestTween();
}
void SetLatestTween( TweenState ts ) { LatestTween() = ts; }
2003-03-02 01:43:33 +00:00
enum StretchType { fit_inside, cover };
2004-09-22 02:20:50 +00:00
void ScaleToCover( const RectF &rect ) { ScaleTo( rect, cover ); }
void ScaleToFitInside( const RectF &rect ) { ScaleTo( rect, fit_inside); };
void ScaleTo( const RectF &rect, StretchType st );
2003-03-02 01:43:33 +00:00
void StretchTo( const RectF &rect );
//
// Alignment settings. These need to be virtual for BitmapText
//
2003-03-02 01:43:33 +00:00
enum HorizAlign { align_left, align_center, align_right };
virtual void SetHorizAlign( HorizAlign ha ) { m_HorizAlign = ha; }
2004-11-06 03:00:10 +00:00
virtual void SetHorizAlign( const CString &s );
2003-03-02 01:43:33 +00:00
enum VertAlign { align_top, align_middle, align_bottom };
virtual void SetVertAlign( VertAlign va ) { m_VertAlign = va; }
2004-11-06 03:00:10 +00:00
virtual void SetVertAlign( const CString &s );
2003-03-02 01:43:33 +00:00
//
2003-03-02 01:43:33 +00:00
// effects
//
2003-03-02 01:43:33 +00:00
void SetEffectNone() { m_Effect = no_effect; }
Effect GetEffect() { return m_Effect; }
void SetEffectColor1( RageColor c ) { m_effectColor1 = c; }
void SetEffectColor2( RageColor c ) { m_effectColor2 = c; }
void SetEffectPeriod( float fSecs ) { m_fEffectPeriodSeconds = fSecs; }
2004-01-20 23:25:38 +00:00
void SetEffectDelay( float fTime ) { m_fEffectDelay = fTime; }
void SetEffectOffset( float fPercent ) { m_fEffectOffset = fPercent; }
2003-12-18 10:31:42 +00:00
void SetEffectClock( EffectClock c ) { m_EffectClock = c; }
2004-11-06 03:00:10 +00:00
void SetEffectClock( const CString &s );
2003-12-18 10:31:42 +00:00
2003-03-02 01:43:33 +00:00
void SetEffectMagnitude( RageVector3 vec ) { m_vEffectMagnitude = vec; }
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 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) );
2003-03-05 02:52:40 +00:00
void SetEffectRainbow(
float fEffectPeriodSeconds = 2.0f );
2003-03-02 01:43:33 +00:00
void SetEffectWag(
float fPeriod = 2.f,
2004-01-23 08:26:02 +00:00
RageVector3 vect = RageVector3(0,0,20) );
2003-03-02 01:43:33 +00:00
void SetEffectBounce(
float fPeriod = 2.f,
RageVector3 vect = RageVector3(0,0,20) );
void SetEffectBob(
float fPeriod = 2.f,
RageVector3 vect = RageVector3(0,0,20) );
2003-03-05 02:52:40 +00:00
void SetEffectPulse(
float fPeriod = 2.f,
float fMinZoom = 0.5f,
float fMaxZoom = 1.f );
2003-03-02 01:43:33 +00:00
void SetEffectSpin(
2003-07-05 21:36:47 +00:00
RageVector3 vect = RageVector3(0,0,180) );
2003-03-02 01:43:33 +00:00
void SetEffectVibrate(
RageVector3 vect = RageVector3(10,10,10) );
//
// other properties
//
bool GetHidden() const { return m_bHidden; }
void SetHidden( bool b ) { m_bHidden = b; }
2003-04-02 05:41:22 +00:00
void SetShadowLength( float fLength );
// TODO: Implement hibernate as a tween type?
void SetHibernate( float fSecs ) { m_fHibernateSecondsLeft = fSecs; }
2004-05-02 03:01:27 +00:00
void SetDrawOrder( int iOrder ) { m_iDrawOrder = iOrder; }
int GetDrawOrder() const { return m_iDrawOrder; }
2003-03-02 01:43:33 +00:00
virtual void EnableAnimation( bool b ) { m_bIsAnimating = b; } // Sprite needs to overload this
void StartAnimating() { this->EnableAnimation(true); };
void StopAnimating() { this->EnableAnimation(false); };
2003-03-02 01:43:33 +00:00
//
// render states
//
2004-05-15 18:35:03 +00:00
void SetBlendMode( BlendMode mode ) { m_BlendMode = mode; }
2004-11-06 03:00:10 +00:00
void SetBlendMode( const CString &s );
2004-05-15 18:35:03 +00:00
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); }
2004-05-15 09:26:21 +00:00
virtual void SetZTestMode( ZTestMode mode ) { m_ZTestMode = mode; }
2004-11-06 03:00:10 +00:00
virtual void SetZTestMode( const CString &s );
virtual void SetZWrite( bool b ) { m_bZWrite = b; }
virtual void SetCullMode( CullMode mode ) { m_CullMode = mode; }
2004-11-06 03:00:10 +00:00
virtual void SetCullMode( const CString &s );
2003-03-02 01:43:33 +00:00
//
// Commands
2003-03-02 01:43:33 +00:00
//
2004-12-03 05:19:46 +00:00
void RunCommands( const Commands &vCommands );
virtual void HandleCommand( const Command &command ); // derivable
static float GetCommandsLengthSeconds( const Commands &vCommands );
2003-03-02 01:43:33 +00:00
//
// Animation
//
virtual int GetNumStates() const { return 1; }
virtual void SetState( int iNewState ) {}
virtual float GetAnimationLengthSeconds() const { return 0; }
virtual void SetSecondsIntoAnimation( float fSeconds ) {}
2003-01-16 05:07:54 +00:00
2004-02-01 03:14:37 +00:00
//
// BGAnimation stuff
//
2004-08-22 02:16:31 +00:00
virtual void GainFocus( float fRate, bool bRewindMovie, bool bLoop ) {}
virtual void LoseFocus() {}
2004-02-01 03:14:37 +00:00
virtual void PlayCommand( const CString &sCommandName ) {}
virtual void PlayOffCommand( const CString &sCommandName ) {}
2004-02-01 03:14:37 +00:00
2003-01-16 05:07:54 +00:00
protected:
struct TweenInfo
{
2002-01-16 10:01:32 +00:00
// 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;
RageVector2 m_size;
TweenState m_current;
TweenState m_start;
deque<TweenState> m_TweenStates; // use deque for contant time delete of the head
deque<TweenInfo> m_TweenInfo;
2003-02-25 02:51:04 +00:00
TweenState& LatestTween() { ASSERT(m_TweenStates.size()>0); return m_TweenStates.back(); };
2002-01-16 10:01:32 +00:00
//
// Temporary variables that are filled just before drawing
//
2003-10-07 04:26:14 +00:00
TweenState m_tempState;
TweenState *m_pTempState;
2003-01-16 05:07:54 +00:00
bool m_bFirstUpdate;
//
// Stuff for alignment
//
2002-01-16 10:01:32 +00:00
HorizAlign m_HorizAlign;
VertAlign m_VertAlign;
2001-11-03 10:52:42 +00:00
//
// Stuff for effects
//
2001-11-28 20:26:45 +00:00
Effect m_Effect;
2004-10-18 04:19:20 +00:00
float m_fSecsIntoEffect, m_fEffectDelta;
2003-02-17 12:19:42 +00:00
float m_fEffectPeriodSeconds;
2004-01-20 23:25:38 +00:00
float m_fEffectDelay;
float m_fEffectOffset;
2003-12-18 10:31:42 +00:00
EffectClock m_EffectClock;
2004-10-18 04:19:20 +00:00
/* 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; }
2003-02-17 12:19:42 +00:00
RageColor m_effectColor1;
RageColor m_effectColor2;
2003-03-02 01:43:33 +00:00
RageVector3 m_vEffectMagnitude;
2002-01-16 10:01:32 +00:00
//
// other properties
//
bool m_bHidden;
float m_fHibernateSecondsLeft;
float m_fShadowLength; // 0 == no shadow
2003-03-05 02:52:40 +00:00
bool m_bIsAnimating;
2004-05-02 03:01:27 +00:00
int m_iDrawOrder;
//
// render states
//
2004-05-15 09:26:21 +00:00
bool m_bTextureWrapping;
BlendMode m_BlendMode;
2004-05-15 09:26:21 +00:00
bool m_bClearZBuffer;
ZTestMode m_ZTestMode;
bool m_bZWrite;
2004-02-04 11:05:33 +00:00
CullMode m_CullMode;
2004-10-15 22:10:27 +00:00
//
// global state
//
static float g_fCurrentBGMTime, g_fCurrentBGMBeat;
2001-11-03 10:52:42 +00:00
};
2002-11-16 08:08:46 +00:00
#endif
2004-06-08 00:47:53 +00:00
/*
* (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.
*/