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
+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;
}