Changelogged the unconflict.

This commit is contained in:
Kyzentun
2015-02-04 19:30:05 -07:00
8 changed files with 633 additions and 19 deletions
+9
View File
@@ -6,6 +6,9 @@ ________________________________________________________________________________
2015/02/02
----------
* [ActorMultiVertex] ForceStateUpdate and SetDecodeMovie added. [kyzentun]
* [RageTexture] Get<thing>Width and Height functions added.
(<thing> means Source, Texture, or Image) [kyzentun]
* [Scripts] find_missing_strings_in_theme_translations function added to
_fallback scripts to assist translators in finding what needs to be
translated. If you need/want to run it on your them, write a piece of lua
@@ -15,6 +18,12 @@ ________________________________________________________________________________
The second arg is the name of the language that is fully translated. All
other languages will be compared to it to decide what is missing or unused.
[kyzentun]
* [Song] GetBGChanges added. [kyzentun]
2015/02/01
----------
* [ActorMultiVertex] Animation state system added. AMVs can now have
animated textures controlled by states written in lua. [kyzentun]
2015/01/31
----------
+26
View File
@@ -493,22 +493,41 @@
<Function name='SetTextureMode'/>
</Class>
<Class base='Actor' name='ActorMultiVertex'>
<Function name='AddState'/>
<Function name='AddQuadState'/>
<Function name='ForceStateUpdate'/>
<Function name='GetCurrDrawMode'/>
<Function name='GetCurrFirstToDraw'/>
<Function name='GetCurrNumToDraw'/>
<Function name='GetDestDrawMode'/>
<Function name='GetDestFirstToDraw'/>
<Function name='GetDestNumToDraw'/>
<Function name='GetNumStates'/>
<Function name='GetNumQuadStates'/>
<Function name='GetNumVertices'/>
<Function name='GetQuadState'/>
<Function name='GetSpline'/>
<Function name='GetState'/>
<Function name='GetStateData'/>
<Function name='GetTexture'/>
<Function name='GetUseAnimationState'/>
<Function name='LoadTexture'/>
<Function name='RemoveState'/>
<Function name='RemoveQuadState'/>
<Function name='SetAllStateDelays'/>
<Function name='SetDecodeMovie'/>
<Function name='SetDrawState'/>
<Function name='SetEffectMode'/>
<Function name='SetLineWidth'/>
<Function name='SetNumVertices'/>
<Function name='SetQuadState'/>
<Function name='SetSecondsIntoAnimation'/>
<Function name='SetState'/>
<Function name='SetStateData'/>
<Function name='SetStateProperties'/>
<Function name='SetTexture'/>
<Function name='SetTextureMode'/>
<Function name='SetUseAnimationState'/>
<Function name='SetVertex'/>
<Function name='SetVertices'/>
<Function name='SetVertsFromSplines'/>
@@ -1369,6 +1388,12 @@
<Function name='volume'/>
</Class>
<Class name='RageTexture'>
<Function name='GetSourceWidth'/>
<Function name='GetSourceHeight'/>
<Function name='GetTextureWidth'/>
<Function name='GetTextureHeight'/>
<Function name='GetImageWidth'/>
<Function name='GetImageHeight'/>
<Function name='GetTextureCoordRect'/>
<Function name='loop'/>
<Function name='position'/>
@@ -1492,6 +1517,7 @@
<Function name='GetAllSteps'/>
<Function name='GetBackgroundPath'/>
<Function name='GetBannerPath'/>
<Function name='GetBGChanges'/>
<Function name='GetCDImagePath'/>
<Function name='GetCDTitlePath'/>
<Function name='GetDiscPath'/>
+86
View File
@@ -1531,6 +1531,69 @@ save yourself some time, copy this for undocumented things:
</Function>
</Class>
<Class name='ActorMultiVertex'>
<Function name='AddQuadState' return='' arguments='int offset'>
The list of quad states is used to determine which animation state is used for each quad. The offset is added to the AMV's current state, and the resulting state is used.
</Function>
<Function name='AddState' return='' arguments='table state_data'>
Adds an animation state to the ActorMultiVertex. The state_data table must be like this:<br />
{{left, top, right, bottom}, delay}<br />
left, top, right, and bottom are pixel coordinates, starting at 0. If delay is 0 or negative, the state will last forever.
</Function>
<Function name='ForceStateUpdate' return='' arguments=''>
Forces the AMV to update the texture coordinates on all its quads, even if the current state has not changed.
</Function>
<Function name='GetUseAnimationState' return= 'bool' arguments=''>
Returns whether the AMV uses the animation state.
</Function>
<Function name='SetUseAnimationState' return= '' arguments='bool use'>
Sets whether the AMV uses the animation state.<br />
This works best when using DrawMode_Quads.<br />
AMV's can have animated textures like sprites. Each state tells the AMV what part of the texture to use, and how long the state lasts.<br />
Use AddState to add a state onto the end, or SetStateProperties to set all the states at once, or SetState to set a single state.<br />
Each quad has its own offset that is added to the current state. Use AddQuadState to add to the list of quad states, or SetQuadState to set an existing quad state.
</Function>
<Function name='GetNumStates' return= 'int' arguments=''>
Returns the number of states the AMV has.
</Function>
<Function name='GetNumQuadStates' return= 'int' arguments=''>
Returns the number of quad states in the destination tween state for the AMV.
</Function>
<Function name='GetState' return= 'int' arguments=''>
Returns the id of the current state.
</Function>
<Function name='SetDecodeMovie' return='' arguments='bool decode'>
Sets whether the AMV should call the decode function for its texture during updates.
</Function>
<Function name='SetState' return= '' arguments='int id'>
Sets the current state.
</Function>
<Function name='GetQuadState' return= 'int' arguments='int id'>
Returns the offset of the requested quad state.
</Function>
<Function name='SetQuadState' return= '' arguments='int id, int offset'>
Sets the offset of the requested quad state.
</Function>
<Function name='GetStateData' return= 'table' arguments='int id'>
Returns a table containing the data for the requested state.
</Function>
<Function name='SetStateData' return= '' arguments='int id, table state_data'>
Sets the requested state to the data in state_data. Similar to AddState, but SetStateData only works on states that have already been added.
</Function>
<Function name='SetStateProperties' return= '' arguments='table {state_data, ...}'>
Each element of the table must be a state_data table, and is used to construct one state. The table as a whole is the entire list of all states for the AMV.
</Function>
<Function name='RemoveState' return= '' arguments='int id'>
Removes the requested state from the state list.
</Function>
<Function name='RemoveQuadState' return= '' arguments='int id'>
Removes the requested quad state from the quad state list.
</Function>
<Function name='SetAllStateDelays' return= '' arguments='float delay'>
Sets the delay for every state to delay.
</Function>
<Function name='SetSecondsIntoAnimation' return= '' arguments='float seconds'>
Sets how far into its animation the AMV is.
</Function>
<Function name='SetVertex' return='void' arguments='int index, table { table pos, table color, table textcoords }'>
Sets vertex number <code>index</code> with the properties provided. The tables of properties are each optional and can be provided in any order.
</Function>
@@ -4001,6 +4064,24 @@ save yourself some time, copy this for undocumented things:
</Function>
</Class>
<Class name='RageTexture'>
<Function name='GetSourceWidth' return='float' arguments=''>
Returns the source width.
</Function>
<Function name='GetSourceHeight' return='float' arguments=''>
Returns the source height.
</Function>
<Function name='GetTextureWidth' return='float' arguments=''>
Returns the texture width.
</Function>
<Function name='GetTextureHeight' return='float' arguments=''>
Returns the texture height.
</Function>
<Function name='GetImageWidth' return='float' arguments=''>
Returns the image width.
</Function>
<Function name='GetImageHeight' return='float' arguments=''>
Returns the image height.
</Function>
<Function name='GetNumFrames' return='int' arguments=''>
Returns the number of frames in this texture.
</Function>
@@ -4309,6 +4390,11 @@ save yourself some time, copy this for undocumented things:
<Function name='GetBannerPath' return='string' arguments=''>
Returns the path to the song's banner.
</Function>
<Function name='GetBGChanges' return='table' arguments=''>
Returns a table with all the data for the song's BGCHANGES line.<br />
Each element of the table is one change like this:<br />
{start_beat= 1.0, rate= 1.0, transition= "example", effect= "example", file1= "example", file2= "example", color1= "#FFFFFFFF", color2= "#FFFFFFFF"}
</Function>
<Function name='GetCDImagePath' return='string' arguments=''>
Returns the path to the song's CD image.
</Function>
+421
View File
@@ -15,6 +15,8 @@
#include "LuaManager.h"
#include "LocalizedString.h"
const float min_state_delay= 0.0001f;
static const char *DrawModeNames[] = {
"Quads",
"QuadStrip",
@@ -69,6 +71,11 @@ ActorMultiVertex::ActorMultiVertex()
_splines[i].redimension(3);
_splines[i].m_owned_by_actor= true;
}
_skip_next_update= true;
_decode_movie= true;
_use_animation_state= false;
_secs_into_state= 0.0f;
_cur_state= 0;
}
ActorMultiVertex::~ActorMultiVertex()
@@ -86,6 +93,11 @@ ActorMultiVertex::ActorMultiVertex( const ActorMultiVertex &cpy ):
CPY( _EffectMode );
CPY( _TextureMode );
CPY( _splines );
CPY(_skip_next_update);
CPY(_use_animation_state);
CPY(_secs_into_state);
CPY(_cur_state);
CPY(_states);
#undef CPY
if( cpy._Texture != NULL )
@@ -373,6 +385,199 @@ CubicSplineN* ActorMultiVertex::GetSpline(size_t i)
return &(_splines[i]);
}
void ActorMultiVertex::SetState(size_t i)
{
ASSERT(i < _states.size());
_cur_state= i;
_secs_into_state= 0.0f;
}
void ActorMultiVertex::SetAllStateDelays(float delay)
{
FOREACH(State, _states, s)
{
s->delay= delay;
}
}
float ActorMultiVertex::GetAnimationLengthSeconds() const
{
float tot= 0.0f;
FOREACH_CONST(State, _states, s)
{
tot+= s->delay;
}
return tot;
}
void ActorMultiVertex::SetSecondsIntoAnimation(float seconds)
{
SetState(0);
if(_Texture)
{
_Texture->SetPosition(seconds);
}
_secs_into_state= seconds;
UpdateAnimationState(true);
}
void ActorMultiVertex::UpdateAnimationState(bool force_update)
{
AMV_TweenState& dest= AMV_DestTweenState();
vector<RageSpriteVertex>& verts= dest.vertices;
vector<size_t>& qs= dest.quad_states;
if(!_use_animation_state || _states.empty() ||
dest._DrawMode == DrawMode_LineStrip || qs.empty())
{ return; }
bool state_changed= force_update;
if(_states.size() > 1)
{
while(_states[_cur_state].delay > min_state_delay &&
_secs_into_state + min_state_delay > _states[_cur_state].delay)
{
_secs_into_state-= _states[_cur_state].delay;
_cur_state= (_cur_state + 1) % _states.size();
state_changed= true;
}
}
if(state_changed)
{
size_t first= dest.FirstToDraw;
size_t last= first+dest.GetSafeNumToDraw(dest._DrawMode, dest.NumToDraw);
#define STATE_ID const size_t state_id= (_cur_state + qs[quad_id % qs.size()]) % _states.size();
switch(AMV_DestTweenState()._DrawMode)
{
case DrawMode_Quads:
for(size_t i= first; i < last; ++i)
{
const size_t quad_id= (i-first)/4;
STATE_ID;
switch((i-first)%4)
{
case 0:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
break;
case 1:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top;
break;
case 2:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.bottom;
break;
case 3:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.bottom;
break;
}
}
break;
case DrawMode_QuadStrip:
for(size_t i= first; i < last; ++i)
{
const size_t quad_id= (i-first)/2;
STATE_ID;
switch((i-first)%2)
{
case 0:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
break;
case 1:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.bottom;
break;
}
}
break;
case DrawMode_Strip:
case DrawMode_Fan:
for(size_t i= first; i < last; ++i)
{
const size_t quad_id= (i-first);
STATE_ID;
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
}
break;
case DrawMode_Triangles:
for(size_t i= first; i < last; ++i)
{
const size_t quad_id= (i-first)/3;
STATE_ID;
switch((i-first)%3)
{
case 0:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
break;
case 1:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top;
break;
case 2:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.bottom;
break;
}
}
break;
case DrawMode_SymmetricQuadStrip:
for(size_t i= first; i < last; ++i)
{
const size_t quad_id= (i-first)/3;
STATE_ID;
switch((i-first)%3)
{
case 0:
case 2:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
break;
case 1:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top;
break;
}
}
break;
}
}
#undef STATE_ID
}
void ActorMultiVertex::EnableAnimation(bool bEnable)
{
bool bWasEnabled = m_bIsAnimating;
Actor::EnableAnimation(bEnable);
if(bEnable && !bWasEnabled)
{
_skip_next_update = true;
}
}
void ActorMultiVertex::Update(float fDelta)
{
Actor::Update(fDelta); // do tweening
const bool skip_this_movie_update= _skip_next_update;
_skip_next_update= false;
if(!m_bIsAnimating) { return; }
if(!_Texture) { return; }
float time_passed = GetEffectDeltaTime();
_secs_into_state += time_passed;
if(_secs_into_state < 0)
{
wrap(_secs_into_state, GetAnimationLengthSeconds());
}
UpdateAnimationState();
if(!skip_this_movie_update && _decode_movie)
{
_Texture->DecodeSeconds(max(0, time_passed));
}
}
void ActorMultiVertex::SetCurrentTweenStart()
{
AMV_start= AMV_current;
@@ -693,11 +898,14 @@ public:
if( lua_isnil(L, 1) )
{
p->UnloadTexture();
p->LoadFromTexture(TEXTUREMAN->GetDefaultTextureID());
}
else
{
RageTextureID ID( SArg(1) );
TEXTUREMAN->DisableOddDimensionWarning();
p->LoadFromTexture( ID );
TEXTUREMAN->EnableOddDimensionWarning();
}
COMMON_RETURN_SELF;
}
@@ -719,6 +927,199 @@ public:
COMMON_RETURN_SELF;
}
DEFINE_METHOD(GetUseAnimationState, _use_animation_state);
static int SetUseAnimationState(T* p, lua_State *L)
{
p->_use_animation_state= BArg(1);
COMMON_RETURN_SELF;
}
static int GetNumStates(T* p, lua_State *L)
{
lua_pushnumber(L, p->GetNumStates());
return 1;
}
static void FillStateFromLua(lua_State *L, ActorMultiVertex::State& state,
RageTexture* tex, int index)
{
if(tex == NULL)
{
luaL_error(L, "The texture must be set before adding states.");
}
// State looks like this:
// {{left, top, right, bottom}, delay}
#define DATA_ERROR(i) \
if(!lua_istable(L, i)) \
{ \
luaL_error(L, "The state data must be in a table like this: {{left, top, right, bottom}, delay}"); \
}
#define SET_SIDE(i, side) \
lua_rawgeti(L, -1, i); \
state.side= FArg(-1); \
lua_pop(L, 1);
DATA_ERROR(index);
lua_rawgeti(L, index, 1);
DATA_ERROR(-1);
SET_SIDE(1, rect.left);
SET_SIDE(2, rect.top);
SET_SIDE(3, rect.right);
SET_SIDE(4, rect.bottom);
lua_pop(L, 1);
SET_SIDE(2, delay);
const float width_ratio= tex->GetImageToTexCoordsRatioX();
const float height_ratio= tex->GetImageToTexCoordsRatioY();
state.rect.left= state.rect.left * width_ratio;
state.rect.top= state.rect.top * height_ratio;
// Pixel centers are at .5, so add an extra pixel to the size to adjust.
state.rect.right= (state.rect.right * width_ratio) + width_ratio;
state.rect.bottom= (state.rect.bottom * height_ratio) + height_ratio;
#undef SET_SIDE
#undef DATA_ERROR
}
static int AddState(T* p, lua_State *L)
{
ActorMultiVertex::State s;
FillStateFromLua(L, s, p->GetTexture(), 1);
p->AddState(s);
COMMON_RETURN_SELF;
}
static size_t ValidStateIndex(T* p, lua_State *L, int pos)
{
int index= IArg(pos)-1;
if(index < 0 || static_cast<size_t>(index) >= p->GetNumStates())
{
luaL_error(L, "Invalid state index %d.", index+1);
}
return static_cast<size_t>(index);
}
static int RemoveState(T* p, lua_State *L)
{
p->RemoveState(ValidStateIndex(p, L, 1));
COMMON_RETURN_SELF;
}
static int GetState(T* p, lua_State *L)
{
lua_pushnumber(L, p->GetState()+1);
return 1;
}
static int SetState(T* p, lua_State *L)
{
p->SetState(ValidStateIndex(p, L, 1));
COMMON_RETURN_SELF;
}
static int GetStateData(T* p, lua_State *L)
{
RageTexture* tex= p->GetTexture();
if(tex == NULL)
{
luaL_error(L, "The texture must be set before adding states.");
}
const float width_pix= tex->GetImageToTexCoordsRatioX();
const float height_pix= tex->GetImageToTexCoordsRatioY();
const float width_ratio= 1.0f / tex->GetImageToTexCoordsRatioX();
const float height_ratio= 1.0f / tex->GetImageToTexCoordsRatioY();
const ActorMultiVertex::State& state=
p->GetStateData(ValidStateIndex(p, L, 1));
lua_createtable(L, 2, 0);
lua_createtable(L, 4, 0);
lua_pushnumber(L, state.rect.left * width_ratio);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, state.rect.top * height_ratio);
lua_rawseti(L, -2, 2);
lua_pushnumber(L, (state.rect.right - width_pix) * width_ratio);
lua_rawseti(L, -2, 3);
lua_pushnumber(L, (state.rect.bottom + height_pix) * height_ratio);
lua_rawseti(L, -2, 4);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, state.delay);
lua_rawseti(L, -2, 2);
return 1;
}
static int SetStateData(T* p, lua_State *L)
{
ActorMultiVertex::State& state= p->GetStateData(ValidStateIndex(p, L, 1));
FillStateFromLua(L, state, p->GetTexture(), 2);
COMMON_RETURN_SELF;
}
static int SetStateProperties(T* p, lua_State *L)
{
if(!lua_istable(L, 1))
{
luaL_error(L, "The states must be inside a table.");
}
RageTexture* tex= p->GetTexture();
if(tex == NULL)
{
luaL_error(L, "The texture must be set before adding states.");
}
vector<ActorMultiVertex::State> new_states;
size_t num_states= lua_objlen(L, 1);
new_states.resize(num_states);
for(size_t i= 0; i < num_states; ++i)
{
lua_rawgeti(L, 1, i+1);
FillStateFromLua(L, new_states[i], tex, -1);
lua_pop(L, 1);
}
p->SetStateProperties(new_states);
COMMON_RETURN_SELF;
}
static int SetAllStateDelays(T* p, lua_State *L)
{
p->SetAllStateDelays(FArg(1));
COMMON_RETURN_SELF;
}
DEFINE_METHOD(GetAnimationLengthSeconds, GetAnimationLengthSeconds());
static int SetSecondsIntoAnimation(T* p, lua_State *L)
{
p->SetSecondsIntoAnimation(FArg(1));
COMMON_RETURN_SELF;
}
static int GetNumQuadStates(T* p, lua_State *L)
{
lua_pushnumber(L, p->GetNumQuadStates());
return 1;
}
static size_t QuadStateIndex(T* p, lua_State *L, int pos)
{
int index= IArg(pos)-1;
if(index < 0 || static_cast<size_t>(index) >= p->GetNumQuadStates())
{
luaL_error(L, "Invalid state index %d.", index+1);
}
return static_cast<size_t>(index);
}
static int AddQuadState(T* p, lua_State *L)
{
p->AddQuadState(IArg(1)-1);
COMMON_RETURN_SELF;
}
static int RemoveQuadState(T* p, lua_State *L)
{
p->RemoveQuadState(QuadStateIndex(p, L, 1));
COMMON_RETURN_SELF;
}
static int GetQuadState(T* p, lua_State *L)
{
lua_pushnumber(L, p->GetQuadState(QuadStateIndex(p, L, 1))+1);
return 1;
}
static int SetQuadState(T* p, lua_State *L)
{
p->SetQuadState(QuadStateIndex(p, L, 1), IArg(2)-1);
COMMON_RETURN_SELF;
}
static int ForceStateUpdate(T* p, lua_State *L)
{
p->UpdateAnimationState(true);
COMMON_RETURN_SELF;
}
static int SetDecodeMovie(T* p, lua_State *L)
{
p->_decode_movie= BArg(1);
COMMON_RETURN_SELF;
}
static int SetTexture( T* p, lua_State *L )
{
RageTexture *Texture = Luna<RageTexture>::check(L, 1);
@@ -763,6 +1164,26 @@ public:
ADD_METHOD( GetSpline );
ADD_METHOD( SetVertsFromSplines );
ADD_METHOD(GetUseAnimationState);
ADD_METHOD(SetUseAnimationState);
ADD_METHOD(GetNumStates);
ADD_METHOD(GetNumQuadStates);
ADD_METHOD(AddState);
ADD_METHOD(RemoveState);
ADD_METHOD(GetState);
ADD_METHOD(SetState);
ADD_METHOD(GetStateData);
ADD_METHOD(SetStateData);
ADD_METHOD(SetStateProperties);
ADD_METHOD(SetAllStateDelays);
ADD_METHOD(SetSecondsIntoAnimation);
ADD_METHOD(AddQuadState);
ADD_METHOD(RemoveQuadState);
ADD_METHOD(GetQuadState);
ADD_METHOD(SetQuadState);
ADD_METHOD(ForceStateUpdate);
ADD_METHOD(SetDecodeMovie);
// Copy from RageTexture
ADD_METHOD( SetTexture );
ADD_METHOD( GetTexture );
+43 -1
View File
@@ -38,7 +38,7 @@ public:
struct AMV_TweenState
{
AMV_TweenState(): _DrawMode(DrawMode_Invalid), FirstToDraw(0),
AMV_TweenState(): _DrawMode(DrawMode_Invalid), FirstToDraw(0),
NumToDraw(-1), line_width(1.0f)
{}
static void MakeWeightedAverage(AMV_TweenState& average_out, const AMV_TweenState& ts1, const AMV_TweenState& ts2, float percent_between);
@@ -49,6 +49,7 @@ public:
int GetSafeNumToDraw( DrawMode dm, int num ) const;
vector<RageSpriteVertex> vertices;
vector<size_t> quad_states;
DrawMode _DrawMode;
int FirstToDraw;
@@ -67,6 +68,8 @@ public:
}
const AMV_TweenState& AMV_DestTweenState() const { return const_cast<ActorMultiVertex*>(this)->AMV_DestTweenState(); }
virtual void EnableAnimation(bool bEnable);
virtual void Update(float fDelta);
virtual bool EarlyAbortDraw() const;
virtual void DrawPrimitives();
virtual void DrawInternal( const AMV_TweenState *TS );
@@ -111,6 +114,40 @@ public:
void SetVertsFromSplines();
CubicSplineN* GetSpline(size_t i);
struct State
{
RectF rect;
float delay;
};
int GetNumStates() const { return _states.size(); }
void AddState(const State& new_state) { _states.push_back(new_state); }
void RemoveState(size_t i)
{ ASSERT(i < _states.size()); _states.erase(_states.begin()+i); }
size_t GetState() { return _cur_state; }
State& GetStateData(size_t i)
{ ASSERT(i < _states.size()); return _states[i]; }
void SetStateData(size_t i, const State& s)
{ ASSERT(i < _states.size()); _states[i]= s; }
void SetStateProperties(const vector<State>& new_states)
{ _states= new_states; SetState(0); }
void SetState(size_t i);
void SetAllStateDelays(float delay);
float GetAnimationLengthSeconds() const;
void SetSecondsIntoAnimation(float seconds);
void UpdateAnimationState(bool force_update= false);
size_t GetNumQuadStates() const
{ return AMV_DestTweenState().quad_states.size(); }
void AddQuadState(size_t s)
{ AMV_DestTweenState().quad_states.push_back(s); }
void RemoveQuadState(size_t i)
{ AMV_DestTweenState().quad_states.erase(AMV_DestTweenState().quad_states.begin()+i); }
size_t GetQuadState(size_t i)
{ return AMV_DestTweenState().quad_states[i]; }
void SetQuadState(size_t i, size_t s)
{ AMV_DestTweenState().quad_states[i]= s; }
bool _use_animation_state;
bool _decode_movie;
virtual void PushSelf( lua_State *L );
private:
@@ -130,6 +167,11 @@ private:
// Four splines for controlling vert positions, because quads drawmode
// requires four. -Kyz
vector<CubicSplineN> _splines;
bool _skip_next_update;
float _secs_into_state;
size_t _cur_state;
vector<State> _states;
};
/**
+12
View File
@@ -108,6 +108,12 @@ public:
p->Reload();
COMMON_RETURN_SELF;
}
DEFINE_METHOD(GetSourceWidth, GetSourceWidth());
DEFINE_METHOD(GetSourceHeight, GetSourceHeight());
DEFINE_METHOD(GetTextureWidth, GetTextureWidth());
DEFINE_METHOD(GetTextureHeight, GetTextureHeight());
DEFINE_METHOD(GetImageWidth, GetImageWidth());
DEFINE_METHOD(GetImageHeight, GetImageHeight());
LunaRageTexture()
{
@@ -117,6 +123,12 @@ public:
ADD_METHOD( GetTextureCoordRect );
ADD_METHOD( GetNumFrames );
ADD_METHOD( Reload );
ADD_METHOD(GetSourceWidth);
ADD_METHOD(GetSourceHeight);
ADD_METHOD(GetTextureWidth);
ADD_METHOD(GetTextureHeight);
ADD_METHOD(GetImageWidth);
ADD_METHOD(GetImageHeight);
}
};
+28
View File
@@ -1916,6 +1916,33 @@ public:
return 1;
}
static int GetTimingData( T* p, lua_State *L ) { p->m_SongTiming.PushSelf(L); return 1; }
static int GetBGChanges(T* p, lua_State* L)
{
const vector<BackgroundChange>& changes= p->GetBackgroundChanges(BACKGROUND_LAYER_1);
lua_createtable(L, changes.size(), 0);
for(size_t c= 0; c < changes.size(); ++c)
{
lua_createtable(L, 0, 8);
lua_pushnumber(L, changes[c].m_fStartBeat);
lua_setfield(L, -2, "start_beat");
lua_pushnumber(L, changes[c].m_fRate);
lua_setfield(L, -2, "rate");
LuaHelpers::Push(L, changes[c].m_sTransition);
lua_setfield(L, -2, "transition");
LuaHelpers::Push(L, changes[c].m_def.m_sEffect);
lua_setfield(L, -2, "effect");
LuaHelpers::Push(L, changes[c].m_def.m_sFile1);
lua_setfield(L, -2, "file1");
LuaHelpers::Push(L, changes[c].m_def.m_sFile2);
lua_setfield(L, -2, "file2");
LuaHelpers::Push(L, changes[c].m_def.m_sColor1);
lua_setfield(L, -2, "color1");
LuaHelpers::Push(L, changes[c].m_def.m_sColor2);
lua_setfield(L, -2, "color2");
lua_rawseti(L, -2, c+1);
}
return 1;
}
// has functions
static int HasMusic( T* p, lua_State *L ) { lua_pushboolean(L, p->HasMusic()); return 1; }
static int HasBanner( T* p, lua_State *L ) { lua_pushboolean(L, p->HasBanner()); return 1; }
@@ -2053,6 +2080,7 @@ public:
ADD_METHOD( HasStepsTypeAndDifficulty );
ADD_METHOD( GetOneSteps );
ADD_METHOD( GetTimingData );
ADD_METHOD(GetBGChanges);
ADD_METHOD( HasMusic );
ADD_METHOD( HasBanner );
ADD_METHOD( HasBackground );
+8 -18
View File
@@ -186,11 +186,6 @@ void Sprite::LoadFromNode( const XNode* pNode )
{
newState.fDelay = 0.1f;
}
if(newState.fDelay <= min_state_delay)
{
LuaHelpers::ReportScriptErrorFmt("%s: State #%i has near-zero delay.", ActorUtil::GetWhere(pNode).c_str(), i+1);
newState.fDelay= 0.1f;
}
pFrame->GetAttrValue( "Frame", iFrameIndex );
if( iFrameIndex >= m_pTexture->GetNumFrames() )
@@ -362,7 +357,12 @@ void Sprite::UpdateAnimationState()
// We already know what's going to show.
if( m_States.size() > 1 )
{
while( m_fSecsIntoState+min_state_delay > m_States[m_iCurState].fDelay ) // it's time to switch frames
// UpdateAnimationState changed to not loop forever on negative state
// delay. This allows a state to last forever when it is reached, so
// the animation has a built-in ending point. -Kyz
while(m_States[m_iCurState].fDelay > min_state_delay &&
m_fSecsIntoState+min_state_delay > m_States[m_iCurState].fDelay)
// it's time to switch frames
{
// increment frame and reset the counter
m_fSecsIntoState -= m_States[m_iCurState].fDelay; // leave the left over time for the next frame
@@ -1047,15 +1047,6 @@ void Sprite::AddImageCoords( float fX, float fY )
class LunaSprite: public Luna<Sprite>
{
public:
static float valid_state_delay(lua_State* L, int i)
{
float delay= FArg(i);
if(delay <= min_state_delay)
{
luaL_error(L, "State delay cannot be less than or equal to zero.");
}
return delay;
}
static int Load( T* p, lua_State *L )
{
if( lua_isnil(L, 1) )
@@ -1151,7 +1142,7 @@ public:
lua_getfield(L, -1, "Delay");
if(lua_isnumber(L, -1))
{
new_state.fDelay= valid_state_delay(L, -1);
new_state.fDelay= FArg(-1);
}
lua_pop(L, 1);
RectF r= new_state.rect;
@@ -1216,8 +1207,7 @@ public:
static int GetNumStates( T* p, lua_State *L ) { lua_pushnumber( L, p->GetNumStates() ); return 1; }
static int SetAllStateDelays( T* p, lua_State *L )
{
float delay= valid_state_delay(L, -1);
p->SetAllStateDelays(delay);
p->SetAllStateDelays(FArg(-1));
COMMON_RETURN_SELF;
}