Maybe editing the changelog should only be done after merging a pull, to avoid conflicts.
This commit is contained in:
+64
-2
@@ -164,6 +164,7 @@ Actor::Actor()
|
||||
m_size = RageVector2( 1, 1 );
|
||||
InitState();
|
||||
m_pParent = NULL;
|
||||
m_FakeParent= NULL;
|
||||
m_bFirstUpdate = true;
|
||||
}
|
||||
|
||||
@@ -183,6 +184,7 @@ Actor::Actor( const Actor &cpy ):
|
||||
#define CPY(x) x = cpy.x
|
||||
CPY( m_sName );
|
||||
CPY( m_pParent );
|
||||
CPY( m_FakeParent );
|
||||
CPY( m_pLuaInstance );
|
||||
|
||||
CPY( m_baseRotation );
|
||||
@@ -279,24 +281,56 @@ void Actor::LoadFromNode( const XNode* pNode )
|
||||
PlayCommandNoRecurse( Message("Init") );
|
||||
}
|
||||
|
||||
bool Actor::PartiallyOpaque()
|
||||
{
|
||||
return 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;
|
||||
}
|
||||
|
||||
void Actor::Draw()
|
||||
{
|
||||
if( !m_bVisible ||
|
||||
m_fHibernateSecondsLeft > 0 ||
|
||||
this->EarlyAbortDraw() )
|
||||
{
|
||||
return; // early abort
|
||||
}
|
||||
bool fake_parent_partially_opaque= true;
|
||||
if(m_FakeParent)
|
||||
{
|
||||
if(!m_FakeParent->m_bVisible || m_FakeParent->m_fHibernateSecondsLeft > 0
|
||||
|| m_FakeParent->EarlyAbortDraw())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_FakeParent->PreDraw();
|
||||
fake_parent_partially_opaque= m_FakeParent->PartiallyOpaque();
|
||||
}
|
||||
|
||||
this->PreDraw();
|
||||
ASSERT( m_pTempState != NULL );
|
||||
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
|
||||
{
|
||||
if(PartiallyOpaque() && fake_parent_partially_opaque)
|
||||
{
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->BeginDraw();
|
||||
}
|
||||
// call the most-derived versions
|
||||
this->BeginDraw();
|
||||
this->DrawPrimitives(); // call the most-derived version of DrawPrimitives();
|
||||
this->EndDraw();
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->EndDraw();
|
||||
}
|
||||
}
|
||||
|
||||
this->PostDraw();
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->PostDraw();
|
||||
}
|
||||
m_pTempState = NULL;
|
||||
}
|
||||
|
||||
@@ -1705,6 +1739,32 @@ public:
|
||||
pParent->PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
static int GetFakeParent(T* p, lua_State *L)
|
||||
{
|
||||
Actor* fake= p->GetFakeParent();
|
||||
if(fake == NULL)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
fake->PushSelf(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int SetFakeParent(T* p, lua_State* L)
|
||||
{
|
||||
if(lua_isnoneornil(L, 1))
|
||||
{
|
||||
p->SetFakeParent(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Actor* fake= Luna<Actor>::check(L, 1);
|
||||
p->SetFakeParent(fake);
|
||||
}
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int Draw( T* p, lua_State *L )
|
||||
{
|
||||
LUA->YieldLua();
|
||||
@@ -1876,6 +1936,8 @@ public:
|
||||
|
||||
ADD_METHOD( GetName );
|
||||
ADD_METHOD( GetParent );
|
||||
ADD_METHOD( GetFakeParent );
|
||||
ADD_METHOD( SetFakeParent );
|
||||
|
||||
ADD_METHOD( Draw );
|
||||
}
|
||||
|
||||
@@ -232,6 +232,8 @@ public:
|
||||
float aux;
|
||||
};
|
||||
|
||||
// PartiallyOpaque broken out of Draw for reuse and clarity.
|
||||
bool PartiallyOpaque();
|
||||
/**
|
||||
* @brief Calls multiple functions for drawing the Actors.
|
||||
*
|
||||
@@ -305,6 +307,9 @@ public:
|
||||
* @return the Actor's lineage. */
|
||||
RString GetLineage() const;
|
||||
|
||||
void SetFakeParent(Actor* mailman) { m_FakeParent= mailman; }
|
||||
Actor* GetFakeParent() { return m_FakeParent; }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Actor's x position.
|
||||
* @return the Actor's x position. */
|
||||
@@ -607,6 +612,10 @@ protected:
|
||||
RString m_sName;
|
||||
/** @brief the current parent of this Actor if it exists. */
|
||||
Actor *m_pParent;
|
||||
// m_FakeParent exists to provide a way to render the actor inside another's
|
||||
// state without making that actor the parent. It's like having multiple
|
||||
// parents. -Kyz
|
||||
Actor* m_FakeParent;
|
||||
|
||||
/** @brief Some general information about the Tween. */
|
||||
struct TweenInfo
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageLog.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageTexture.h"
|
||||
#include "RageTimer.h"
|
||||
#include "RageUtil.h"
|
||||
#include "ActorUtil.h"
|
||||
#include "Foreach.h"
|
||||
@@ -62,6 +63,12 @@ ActorMultiVertex::ActorMultiVertex()
|
||||
|
||||
_EffectMode = EffectMode_Normal;
|
||||
_TextureMode = TextureMode_Modulate;
|
||||
_splines.resize(num_vert_splines);
|
||||
for(size_t i= 0; i < num_vert_splines; ++i)
|
||||
{
|
||||
_splines[i].redimension(3);
|
||||
_splines[i].m_owned_by_actor= true;
|
||||
}
|
||||
}
|
||||
|
||||
ActorMultiVertex::~ActorMultiVertex()
|
||||
@@ -78,6 +85,7 @@ ActorMultiVertex::ActorMultiVertex( const ActorMultiVertex &cpy ):
|
||||
CPY( AMV_start );
|
||||
CPY( _EffectMode );
|
||||
CPY( _TextureMode );
|
||||
CPY( _splines );
|
||||
#undef CPY
|
||||
|
||||
if( cpy._Texture != NULL )
|
||||
@@ -309,6 +317,61 @@ bool ActorMultiVertex::EarlyAbortDraw() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SetVertsFromSplinesInternal(size_t num_splines, size_t offset)
|
||||
{
|
||||
vector<RageSpriteVertex>& verts= AMV_DestTweenState().vertices;
|
||||
size_t first= AMV_DestTweenState().FirstToDraw + offset;
|
||||
size_t num_verts= AMV_DestTweenState().GetSafeNumToDraw(AMV_DestTweenState()._DrawMode, AMV_DestTweenState().NumToDraw) - offset;
|
||||
vector<float> tper(num_splines, 0.0f);
|
||||
float num_parts= static_cast<float>(num_verts) /
|
||||
static_cast<float>(num_splines);
|
||||
for(size_t i= 0; i < num_splines; ++i)
|
||||
{
|
||||
tper[i]= _splines[i].get_max_t() / num_parts;
|
||||
}
|
||||
for(size_t v= 0; v < num_verts; ++v)
|
||||
{
|
||||
vector<float> pos;
|
||||
const int spi= v%num_splines;
|
||||
_splines[spi].evaluate(static_cast<float>(v) * tper[spi], pos);
|
||||
verts[v+first].p.x= pos[0];
|
||||
verts[v+first].p.y= pos[1];
|
||||
verts[v+first].p.z= pos[2];
|
||||
}
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SetVertsFromSplines()
|
||||
{
|
||||
if(AMV_DestTweenState().vertices.empty()) { return; }
|
||||
switch(AMV_DestTweenState()._DrawMode)
|
||||
{
|
||||
case DrawMode_Quads:
|
||||
SetVertsFromSplinesInternal(4, 0);
|
||||
break;
|
||||
case DrawMode_QuadStrip:
|
||||
case DrawMode_Strip:
|
||||
SetVertsFromSplinesInternal(2, 0);
|
||||
break;
|
||||
case DrawMode_Fan:
|
||||
// Skip the first vert because it is the center of the fan. -Kyz
|
||||
SetVertsFromSplinesInternal(1, 1);
|
||||
break;
|
||||
case DrawMode_Triangles:
|
||||
case DrawMode_SymmetricQuadStrip:
|
||||
SetVertsFromSplinesInternal(3, 0);
|
||||
break;
|
||||
case DrawMode_LineStrip:
|
||||
SetVertsFromSplinesInternal(1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CubicSplineN* ActorMultiVertex::GetSpline(size_t i)
|
||||
{
|
||||
ASSERT(i < num_vert_splines);
|
||||
return &(_splines[i]);
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SetCurrentTweenStart()
|
||||
{
|
||||
AMV_start= AMV_current;
|
||||
@@ -638,6 +701,23 @@ public:
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
|
||||
static int GetSpline(T* p, lua_State* L)
|
||||
{
|
||||
size_t i= static_cast<size_t>(IArg(1)-1);
|
||||
if(i >= ActorMultiVertex::num_vert_splines)
|
||||
{
|
||||
luaL_error(L, "Spline index must be greater than 0 and less than or equal to %zu.", ActorMultiVertex::num_vert_splines);
|
||||
}
|
||||
p->GetSpline(i)->PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetVertsFromSplines(T* p, lua_State* L)
|
||||
{
|
||||
p->SetVertsFromSplines();
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
|
||||
static int SetTexture( T* p, lua_State *L )
|
||||
{
|
||||
RageTexture *Texture = Luna<RageTexture>::check(L, 1);
|
||||
@@ -679,6 +759,9 @@ public:
|
||||
ADD_METHOD( GetCurrFirstToDraw );
|
||||
ADD_METHOD( GetCurrNumToDraw );
|
||||
|
||||
ADD_METHOD( GetSpline );
|
||||
ADD_METHOD( SetVertsFromSplines );
|
||||
|
||||
// Copy from RageTexture
|
||||
ADD_METHOD( SetTexture );
|
||||
ADD_METHOD( GetTexture );
|
||||
|
||||
+14
-1
@@ -1,7 +1,9 @@
|
||||
/** @brief ActorMultiVertex - A texture created from multiple textures. */
|
||||
|
||||
#include "Actor.h"
|
||||
#include "CubicSpline.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageMath.h"
|
||||
#include "RageTextureID.h"
|
||||
|
||||
enum DrawMode
|
||||
@@ -26,6 +28,7 @@ class RageTexture;
|
||||
class ActorMultiVertex: public Actor
|
||||
{
|
||||
public:
|
||||
static const size_t num_vert_splines= 4;
|
||||
ActorMultiVertex();
|
||||
ActorMultiVertex( const ActorMultiVertex &cpy );
|
||||
virtual ~ActorMultiVertex();
|
||||
@@ -35,7 +38,9 @@ public:
|
||||
|
||||
struct AMV_TweenState
|
||||
{
|
||||
AMV_TweenState(): _DrawMode(DrawMode_Invalid), FirstToDraw(0), NumToDraw(-1), line_width(1.0f) {}
|
||||
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);
|
||||
bool operator==(const AMV_TweenState& other) const;
|
||||
bool operator!=(const AMV_TweenState& other) const { return !operator==(other); }
|
||||
@@ -102,6 +107,10 @@ public:
|
||||
void SetVertexColor( int index , RageColor c );
|
||||
void SetVertexCoords( int index , float TexCoordX , float TexCoordY );
|
||||
|
||||
inline void SetVertsFromSplinesInternal(size_t num_splines, size_t start_vert);
|
||||
void SetVertsFromSplines();
|
||||
CubicSplineN* GetSpline(size_t i);
|
||||
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
@@ -117,6 +126,10 @@ private:
|
||||
|
||||
EffectMode _EffectMode;
|
||||
TextureMode _TextureMode;
|
||||
|
||||
// Four splines for controlling vert positions, because quads drawmode
|
||||
// requires four. -Kyz
|
||||
vector<CubicSplineN> _splines;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,14 @@ public:
|
||||
return GetYOffset( pPlayerState, iCol, fNoteBeat, fThrowAway, bThrowAway, bAbsolute );
|
||||
}
|
||||
|
||||
static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, vector<float>& ret, bool with_reverse= true)
|
||||
{
|
||||
ASSERT(ret.size() == 3);
|
||||
ret[0]= GetXPos(player_state, col, y_offset);
|
||||
ret[1]= GetYPos(player_state, col, y_offset, y_reverse_offset, with_reverse);
|
||||
ret[2]= GetZPos(player_state, col, y_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the actual display position.
|
||||
*
|
||||
|
||||
+1037
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
||||
#ifndef CUBIC_SPLINE_H
|
||||
#define CUBIC_SPLINE_H
|
||||
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
struct lua_State;
|
||||
|
||||
struct CubicSpline
|
||||
{
|
||||
CubicSpline() :m_spatial_extent(0.0f) {}
|
||||
void solve_looped();
|
||||
void solve_straight();
|
||||
void solve_polygonal();
|
||||
void p_and_tfrac_from_t(float t, bool loop, size_t& p, float& tfrac) const;
|
||||
float evaluate(float t, bool loop) const;
|
||||
float evaluate_derivative(float t, bool loop) const;
|
||||
float evaluate_second_derivative(float t, bool loop) const;
|
||||
float evaluate_third_derivative(float t, bool loop) const;
|
||||
void set_point(size_t i, float v);
|
||||
void set_coefficients(size_t i, float b, float c, float d);
|
||||
void get_coefficients(size_t i, float& b, float& c, float& d) const;
|
||||
void set_point_and_coefficients(size_t i, float a, float b, float c, float d);
|
||||
void get_point_and_coefficients(size_t i, float& a, float& b, float& c, float& d) const;
|
||||
void resize(size_t s);
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
float m_spatial_extent;
|
||||
private:
|
||||
bool check_minimum_size();
|
||||
void prep_inner(size_t last, vector<float>& results);
|
||||
void set_results(size_t last, vector<float>& diagonals, vector<float>& results);
|
||||
|
||||
struct SplinePoint
|
||||
{
|
||||
float a, b, c, d;
|
||||
};
|
||||
vector<SplinePoint> m_points;
|
||||
};
|
||||
|
||||
struct CubicSplineN
|
||||
{
|
||||
CubicSplineN()
|
||||
:m_owned_by_actor(false), m_loop(false), m_polygonal(false), m_dirty(true)
|
||||
{}
|
||||
static void weighted_average(CubicSplineN& out, const CubicSplineN& from,
|
||||
const CubicSplineN& to, float between);
|
||||
void solve();
|
||||
void evaluate(float t, vector<float>& v) const;
|
||||
void evaluate_derivative(float t, vector<float>& v) const;
|
||||
void evaluate_second_derivative(float t, vector<float>& v) const;
|
||||
void evaluate_third_derivative(float t, vector<float>& v) const;
|
||||
void set_point(size_t i, const vector<float>& v);
|
||||
void set_coefficients(size_t i, const vector<float>& b,
|
||||
const vector<float>& c, const vector<float>& d);
|
||||
void get_coefficients(size_t i, vector<float>& b,
|
||||
vector<float>& c, vector<float>& d);
|
||||
void set_spatial_extent(size_t i, float extent);
|
||||
float get_spatial_extent(size_t i);
|
||||
void resize(size_t s);
|
||||
size_t size() const;
|
||||
void redimension(size_t d);
|
||||
size_t dimension() const;
|
||||
bool empty() const;
|
||||
float get_max_t() const {
|
||||
if(m_loop) { return static_cast<float>(size()); }
|
||||
else { return static_cast<float>(size()-1); }
|
||||
}
|
||||
typedef vector<CubicSpline> spline_cont_t;
|
||||
void set_loop(bool l);
|
||||
bool get_loop() const;
|
||||
void set_polygonal(bool p);
|
||||
bool get_polygonal() const;
|
||||
void set_dirty(bool d);
|
||||
bool get_dirty() const;
|
||||
bool m_owned_by_actor;
|
||||
|
||||
void PushSelf(lua_State* L);
|
||||
private:
|
||||
bool m_loop;
|
||||
bool m_polygonal;
|
||||
bool m_dirty;
|
||||
spline_cont_t m_splines;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Side note: Actually written between 2014/12/26 and 2014/12/28
|
||||
/*
|
||||
* Copyright (c) 2014-2015 Eric Reese
|
||||
* 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.
|
||||
*/
|
||||
+11
-14
@@ -35,6 +35,16 @@ void GhostArrowRow::Load( const PlayerState* pPlayerState, float fYReverseOffset
|
||||
}
|
||||
}
|
||||
|
||||
void GhostArrowRow::SetColumnRenderers(vector<NoteColumnRenderer>& renderers)
|
||||
{
|
||||
ASSERT_M(renderers.size() == m_Ghost.size(), "Notefield has different number of columns than ghost row.");
|
||||
for(size_t c= 0; c < m_Ghost.size(); ++c)
|
||||
{
|
||||
m_Ghost[c]->SetFakeParent(&(renderers[c]));
|
||||
}
|
||||
m_renderers= &renderers;
|
||||
}
|
||||
|
||||
GhostArrowRow::~GhostArrowRow()
|
||||
{
|
||||
for( unsigned i = 0; i < m_Ghost.size(); ++i )
|
||||
@@ -47,20 +57,7 @@ void GhostArrowRow::Update( float fDeltaTime )
|
||||
for( unsigned c=0; c<m_Ghost.size(); c++ )
|
||||
{
|
||||
m_Ghost[c]->Update( fDeltaTime );
|
||||
|
||||
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
|
||||
float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
|
||||
float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
|
||||
|
||||
m_Ghost[c]->SetX( fX );
|
||||
m_Ghost[c]->SetY( fY );
|
||||
m_Ghost[c]->SetZ( fZ );
|
||||
|
||||
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
|
||||
m_Ghost[c]->SetRotationZ( fRotation );
|
||||
|
||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
||||
m_Ghost[c]->SetZoom( fZoom );
|
||||
(*m_renderers)[c].UpdateReceptorGhostStuff(m_Ghost[c]);
|
||||
}
|
||||
|
||||
for( unsigned i = 0; i < m_bHoldShowing.size(); ++i )
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ActorFrame.h"
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "NoteTypes.h"
|
||||
#include "NoteDisplay.h"
|
||||
|
||||
class PlayerState;
|
||||
/** @brief Row of GhostArrow Actors. */
|
||||
@@ -15,6 +16,7 @@ public:
|
||||
virtual void DrawPrimitives();
|
||||
|
||||
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
||||
void SetColumnRenderers(vector<NoteColumnRenderer>& renderers);
|
||||
|
||||
void DidTapNote( int iCol, TapNoteScore tns, bool bBright );
|
||||
void DidHoldNote( int iCol, HoldNoteScore hns, bool bBright );
|
||||
@@ -24,6 +26,7 @@ protected:
|
||||
float m_fYReverseOffsetPixels;
|
||||
const PlayerState* m_pPlayerState;
|
||||
|
||||
vector<NoteColumnRenderer> const* m_renderers;
|
||||
vector<Actor *> m_Ghost;
|
||||
vector<TapNoteSubType> m_bHoldShowing;
|
||||
vector<TapNoteSubType> m_bLastHoldShowing;
|
||||
|
||||
@@ -516,6 +516,7 @@ RageFileDriverSlice.cpp RageFileDriverSlice.h \
|
||||
RageFileDriverTimeout.cpp RageFileDriverTimeout.h
|
||||
|
||||
Rage = $(PCRE) $(Lua) $(jsoncpp) $(RageFile) $(RageSoundFileReaders) \
|
||||
CubicSpline.cpp CubicSpline.h \
|
||||
RageBitmapTexture.cpp RageBitmapTexture.h \
|
||||
RageDisplay.cpp RageDisplay.h \
|
||||
RageDisplay_OGL.cpp RageDisplay_OGL.h \
|
||||
|
||||
+838
-96
File diff suppressed because it is too large
Load Diff
+184
-21
@@ -1,13 +1,17 @@
|
||||
#ifndef NOTE_DISPLAY_H
|
||||
#define NOTE_DISPLAY_H
|
||||
|
||||
#include "ActorFrame.h"
|
||||
#include "CubicSpline.h"
|
||||
#include "NoteData.h"
|
||||
#include "PlayerNumber.h"
|
||||
#include "GameInput.h"
|
||||
|
||||
class Actor;
|
||||
class Sprite;
|
||||
class Model;
|
||||
class PlayerState;
|
||||
class GhostArrowRow;
|
||||
class ReceptorArrowRow;
|
||||
struct TapNote;
|
||||
struct HoldNoteResult;
|
||||
struct NoteMetricCache_t;
|
||||
@@ -83,6 +87,88 @@ enum ActiveType
|
||||
#define FOREACH_ActiveType( i ) FOREACH_ENUM( ActiveType, i )
|
||||
const RString &ActiveTypeToString( ActiveType at );
|
||||
|
||||
enum NoteColumnSplineMode
|
||||
{
|
||||
NCSM_Disabled,
|
||||
NCSM_Offset,
|
||||
NCSM_Position,
|
||||
NUM_NoteColumnSplineMode,
|
||||
NoteColumnSplineMode_Invalid
|
||||
};
|
||||
|
||||
const RString& NoteColumnSplineModeToString(NoteColumnSplineMode ncsm);
|
||||
LuaDeclareType(NoteColumnSplineMode);
|
||||
|
||||
// A little pod struct to carry the data the NoteField needs to pass to the
|
||||
// NoteDisplay during rendering.
|
||||
struct NoteFieldRenderArgs
|
||||
{
|
||||
const PlayerState* player_state; // to look up PlayerOptions
|
||||
float reverse_offset_pixels;
|
||||
ReceptorArrowRow* receptor_row;
|
||||
GhostArrowRow* ghost_row;
|
||||
const NoteData* note_data;
|
||||
float first_beat;
|
||||
float last_beat;
|
||||
int first_row;
|
||||
int last_row;
|
||||
float draw_pixels_before_targets;
|
||||
float draw_pixels_after_targets;
|
||||
int* selection_begin_marker;
|
||||
int* selection_end_marker;
|
||||
float selection_glow;
|
||||
float fail_fade;
|
||||
float fade_before_targets;
|
||||
};
|
||||
|
||||
// NCSplineHandler exists to allow NoteColumnRenderer to have separate
|
||||
// splines for position, rotation, and zoom, while concisely presenting the
|
||||
// same interface for all three.
|
||||
struct NCSplineHandler
|
||||
{
|
||||
NCSplineHandler()
|
||||
{
|
||||
m_spline.redimension(3);
|
||||
m_spline.m_owned_by_actor= true;
|
||||
m_spline_mode= NCSM_Disabled;
|
||||
m_receptor_t= 0.0f;
|
||||
m_beats_per_t= 1.0f;
|
||||
m_subtract_song_beat_from_curr= true;
|
||||
}
|
||||
float BeatToTValue(float song_beat, float note_beat) const;
|
||||
void EvalForBeat(float song_beat, float note_beat, vector<float>& ret) const;
|
||||
void EvalDerivForBeat(float song_beat, float note_beat, vector<float>& ret) const;
|
||||
void EvalForReceptor(float song_beat, vector<float>& ret) const;
|
||||
static void MakeWeightedAverage(NCSplineHandler& out,
|
||||
const NCSplineHandler& from, const NCSplineHandler& to, float between);
|
||||
|
||||
CubicSplineN m_spline;
|
||||
NoteColumnSplineMode m_spline_mode;
|
||||
float m_receptor_t;
|
||||
float m_beats_per_t;
|
||||
bool m_subtract_song_beat_from_curr;
|
||||
|
||||
void PushSelf(lua_State* L);
|
||||
};
|
||||
|
||||
struct NoteColumnRenderArgs
|
||||
{
|
||||
void spae_pos_for_beat(const PlayerState* state,
|
||||
float beat, float y_offset, float y_reverse_offset,
|
||||
vector<float>& sp_pos, vector<float>& ae_pos) const;
|
||||
void spae_zoom_for_beat(const PlayerState* state, float beat,
|
||||
vector<float>& sp_zoom, vector<float>& ae_zoom) const;
|
||||
void SetPRZForActor(Actor* actor,
|
||||
const vector<float>& sp_pos, const vector<float>& ae_pos,
|
||||
const vector<float>& sp_rot, const vector<float>& ae_rot,
|
||||
const vector<float>& sp_zoom, const vector<float>& ae_zoom) const;
|
||||
const NCSplineHandler* pos_handler;
|
||||
const NCSplineHandler* rot_handler;
|
||||
const NCSplineHandler* zoom_handler;
|
||||
float song_beat;
|
||||
int column;
|
||||
};
|
||||
|
||||
/** @brief Draws TapNotes and HoldNotes. */
|
||||
class NoteDisplay
|
||||
{
|
||||
@@ -94,6 +180,14 @@ public:
|
||||
|
||||
static void Update( float fDeltaTime );
|
||||
|
||||
bool IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const;
|
||||
|
||||
bool DrawHoldsInRange(const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args,
|
||||
const vector<NoteData::TrackMap::const_iterator>& tap_set);
|
||||
bool DrawTapsInRange(const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args,
|
||||
const vector<NoteData::TrackMap::const_iterator>& tap_set);
|
||||
/**
|
||||
* @brief Draw the TapNote onto the NoteField.
|
||||
* @param tn the TapNote in question.
|
||||
@@ -107,19 +201,16 @@ public:
|
||||
* @param fDrawDistanceAfterTargetsPixels how much to draw after the receptors.
|
||||
* @param fDrawDistanceBeforeTargetsPixels how much ot draw before the receptors.
|
||||
* @param fFadeInPercentOfDrawFar when to start fading in. */
|
||||
void DrawTap(const TapNote& tn, int iCol, float fBeat,
|
||||
bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollBeat,
|
||||
bool bIsAddition, float fPercentFadeToFail,
|
||||
float fReverseOffsetPixels,
|
||||
float fDrawDistanceAfterTargetsPixels,
|
||||
float fDrawDistanceBeforeTargetsPixels,
|
||||
float fFadeInPercentOfDrawFar );
|
||||
void DrawHold( const TapNote& tn, int iCol, int iRow, bool bIsBeingHeld, const HoldNoteResult &Result,
|
||||
bool bIsAddition, float fPercentFadeToFail, float fReverseOffsetPixels, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels,
|
||||
float fDrawDistanceBeforeTargetsPixels2, float fFadeInPercentOfDrawFar );
|
||||
|
||||
void DrawTap(const TapNote& tn, const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args, float fBeat,
|
||||
bool bOnSameRowAsHoldStart,
|
||||
bool bOnSameRowAsRollBeat, bool bIsAddition, float fPercentFadeToFail);
|
||||
void DrawHold(const TapNote& tn, const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args, int iRow, bool bIsBeingHeld,
|
||||
const HoldNoteResult &Result,
|
||||
bool bIsAddition, float fPercentFadeToFail);
|
||||
|
||||
bool DrawHoldHeadForTapsOnSameRow() const;
|
||||
|
||||
bool DrawRollHeadForTapsOnSameRow() const;
|
||||
|
||||
private:
|
||||
@@ -128,14 +219,23 @@ private:
|
||||
Actor *GetHoldActor( NoteColorActor nca[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
|
||||
Sprite *GetHoldSprite( NoteColorSprite ncs[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
|
||||
|
||||
void DrawActor( const TapNote& tn, Actor* pActor, NotePart part, int iCol, float fYOffset, float fBeat, bool bIsAddition, float fPercentFadeToFail,
|
||||
float fReverseOffsetPixels, float fColorScale, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar );
|
||||
void DrawHoldBody( const TapNote& tn, int iCol, float fBeat, bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition, float fPercentFadeToFail,
|
||||
float fColorScale,
|
||||
bool bGlow, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar );
|
||||
void DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, float fPercentFadeToFail, float fColorScale, bool bGlow,
|
||||
float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar, float fOverlappedTime,
|
||||
float fYTop, float fYBottom, float fYStartPos, float fYEndPos, bool bWrapping, bool bAnchorToTop, bool bFlipTextureVertically );
|
||||
void DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
||||
const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args, float fYOffset, float fBeat,
|
||||
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
||||
bool is_being_held);
|
||||
void DrawHoldBody(const TapNote& tn, const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args, float fBeat, bool bIsBeingHeld,
|
||||
float fYHead, float fYTail,
|
||||
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
||||
bool bGlow, float top_beat, float bottom_beat);
|
||||
void DrawHoldPart(vector<Sprite*> &vpSpr,
|
||||
const NoteFieldRenderArgs& field_args,
|
||||
const NoteColumnRenderArgs& column_args, int fYStep,
|
||||
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
||||
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
|
||||
float fYEndPos, bool bWrapping, bool bAnchorToTop,
|
||||
bool bFlipTextureVertically, float top_beat, float bottom_beat);
|
||||
|
||||
const PlayerState *m_pPlayerState; // to look up PlayerOptions
|
||||
NoteMetricCache_t *cache;
|
||||
@@ -152,9 +252,72 @@ private:
|
||||
float m_fYReverseOffsetPixels;
|
||||
};
|
||||
|
||||
// So, this is a bit screwy, and it's partly because routine forces rendering
|
||||
// notes from different noteskins in the same column.
|
||||
// NoteColumnRenderer exists to hold all the data needed for rendering a
|
||||
// column and apply any transforms from that column's actor to the
|
||||
// NoteDisplays that render the notes.
|
||||
// NoteColumnRenderer is also used as a fake parent for the receptor and ghost
|
||||
// actors so they can move with the rest of the column. I didn't use
|
||||
// ActorProxy because the receptor/ghost actors need to pull in the parent
|
||||
// state of their rows and the parent state of the column. -Kyz
|
||||
|
||||
struct NoteColumnRenderer : public Actor
|
||||
{
|
||||
NoteDisplay* m_displays[PLAYER_INVALID+1];
|
||||
NoteFieldRenderArgs* m_field_render_args;
|
||||
NoteColumnRenderArgs m_column_render_args;
|
||||
int m_column;
|
||||
|
||||
// UpdateReceptorGhostStuff takes care of the logic for making the ghost
|
||||
// and receptor positions follow the splines. It's called by their row
|
||||
// update functions. -Kyz
|
||||
void UpdateReceptorGhostStuff(Actor* receptor) const;
|
||||
virtual void DrawPrimitives();
|
||||
virtual void PushSelf(lua_State* L);
|
||||
|
||||
struct NCR_TweenState
|
||||
{
|
||||
NCR_TweenState();
|
||||
NCSplineHandler m_pos_handler;
|
||||
NCSplineHandler m_rot_handler;
|
||||
NCSplineHandler m_zoom_handler;
|
||||
static void MakeWeightedAverage(NCR_TweenState& out,
|
||||
const NCR_TweenState& from, const NCR_TweenState& to, float between);
|
||||
bool operator==(const NCR_TweenState& other) const;
|
||||
bool operator!=(const NCR_TweenState& other) const { return !operator==(other); }
|
||||
};
|
||||
|
||||
NCR_TweenState& NCR_DestTweenState()
|
||||
{
|
||||
if(NCR_Tweens.empty())
|
||||
{ return NCR_current; }
|
||||
else
|
||||
{ return NCR_Tweens.back(); }
|
||||
}
|
||||
const NCR_TweenState& NCR_DestTweenState() const { return const_cast<NoteColumnRenderer*>(this)->NCR_DestTweenState(); }
|
||||
|
||||
virtual void SetCurrentTweenStart();
|
||||
virtual void EraseHeadTween();
|
||||
virtual void UpdatePercentThroughTween(float between);
|
||||
virtual void BeginTweening(float time, ITween* interp);
|
||||
virtual void StopTweening();
|
||||
virtual void FinishTweening();
|
||||
|
||||
NCSplineHandler* GetPosHandler() { return &NCR_DestTweenState().m_pos_handler; }
|
||||
NCSplineHandler* GetRotHandler() { return &NCR_DestTweenState().m_rot_handler; }
|
||||
NCSplineHandler* GetZoomHandler() { return &NCR_DestTweenState().m_zoom_handler; }
|
||||
|
||||
private:
|
||||
vector<NCR_TweenState> NCR_Tweens;
|
||||
NCR_TweenState NCR_current;
|
||||
NCR_TweenState NCR_start;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* NoteColumnRenderer and associated spline stuff (c) Eric Reese 2014-2015
|
||||
* @file
|
||||
* @author Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway (c) 2001-2006
|
||||
* @section LICENSE
|
||||
|
||||
+111
-225
@@ -36,11 +36,8 @@ static ThemeMetric<float> FADE_FAIL_TIME( "NoteField", "FadeFailTime" );
|
||||
static RString RoutineNoteSkinName( size_t i ) { return ssprintf("RoutineNoteSkinP%i",int(i+1)); }
|
||||
static ThemeMetric1D<RString> ROUTINE_NOTESKIN( "NoteField", RoutineNoteSkinName, NUM_PLAYERS );
|
||||
|
||||
static bool FAST_NOTE_RENDERING_PREF_CACHED= false;
|
||||
|
||||
NoteField::NoteField()
|
||||
{
|
||||
FAST_NOTE_RENDERING_PREF_CACHED= PREFSMAN->m_FastNoteRendering;
|
||||
m_pNoteData = NULL;
|
||||
m_pCurDisplay = NULL;
|
||||
|
||||
@@ -64,9 +61,13 @@ NoteField::NoteField()
|
||||
m_sprBeatBars.Load( THEME->GetPathG("NoteField","bars") );
|
||||
m_sprBeatBars.StopAnimating();
|
||||
|
||||
// I decided to do it this way because I don't want to dig through
|
||||
// ScreenEdit to change all the places it touches the markers. -Kyz
|
||||
m_FieldRenderArgs.selection_begin_marker= &m_iBeginMarker;
|
||||
m_FieldRenderArgs.selection_end_marker= &m_iEndMarker;
|
||||
m_iBeginMarker = m_iEndMarker = -1;
|
||||
|
||||
m_fPercentFadeToFail = -1;
|
||||
m_FieldRenderArgs.fail_fade = -1;
|
||||
|
||||
m_StepCallback.SetFromNil();
|
||||
m_SetPressedCallback.SetFromNil();
|
||||
@@ -169,6 +170,8 @@ void NoteField::CacheAllUsedNoteSkins()
|
||||
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
||||
m_pDisplays[pn] = it->second;
|
||||
}
|
||||
|
||||
InitColumnRenderers();
|
||||
}
|
||||
|
||||
void NoteField::Init( const PlayerState* pPlayerState, float fYReverseOffsetPixels )
|
||||
@@ -189,7 +192,7 @@ void NoteField::Load(
|
||||
m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels;
|
||||
ASSERT( m_iDrawDistanceBeforeTargetsPixels >= m_iDrawDistanceAfterTargetsPixels );
|
||||
|
||||
m_fPercentFadeToFail = -1;
|
||||
m_FieldRenderArgs.fail_fade = -1;
|
||||
|
||||
//int i1 = m_pNoteData->GetNumTracks();
|
||||
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
|
||||
@@ -240,6 +243,30 @@ void NoteField::Load(
|
||||
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
||||
m_pDisplays[pn] = it->second;
|
||||
}
|
||||
InitColumnRenderers();
|
||||
}
|
||||
|
||||
void NoteField::InitColumnRenderers()
|
||||
{
|
||||
m_FieldRenderArgs.player_state= m_pPlayerState;
|
||||
m_FieldRenderArgs.reverse_offset_pixels= m_fYReverseOffsetPixels;
|
||||
m_FieldRenderArgs.receptor_row= &(m_pCurDisplay->m_ReceptorArrowRow);
|
||||
m_FieldRenderArgs.ghost_row= &(m_pCurDisplay->m_GhostArrowRow);
|
||||
m_FieldRenderArgs.note_data= m_pNoteData;
|
||||
m_ColumnRenderers.resize(GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer);
|
||||
for(size_t ncr= 0; ncr < m_ColumnRenderers.size(); ++ncr)
|
||||
{
|
||||
FOREACH_EnabledPlayer(pn)
|
||||
{
|
||||
m_ColumnRenderers[ncr].m_displays[pn]= &(m_pDisplays[pn]->display[ncr]);
|
||||
}
|
||||
m_ColumnRenderers[ncr].m_displays[PLAYER_INVALID]= &(m_pCurDisplay->display[ncr]);
|
||||
m_ColumnRenderers[ncr].m_column= ncr;
|
||||
m_ColumnRenderers[ncr].m_column_render_args.column= ncr;
|
||||
m_ColumnRenderers[ncr].m_field_render_args= &m_FieldRenderArgs;
|
||||
}
|
||||
m_pCurDisplay->m_ReceptorArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||
m_pCurDisplay->m_GhostArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||
}
|
||||
|
||||
void NoteField::Update( float fDeltaTime )
|
||||
@@ -251,6 +278,11 @@ void NoteField::Update( float fDeltaTime )
|
||||
|
||||
ActorFrame::Update( fDeltaTime );
|
||||
|
||||
for(size_t c= 0; c < m_ColumnRenderers.size(); ++c)
|
||||
{
|
||||
m_ColumnRenderers[c].Update(fDeltaTime);
|
||||
}
|
||||
|
||||
// update m_fBoardOffsetPixels, m_fCurrentBeatLastUpdate, m_fYPosCurrentBeatLastUpdate
|
||||
const float fCurrentBeat = m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||
bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK
|
||||
@@ -276,11 +308,11 @@ void NoteField::Update( float fDeltaTime )
|
||||
cur->m_ReceptorArrowRow.Update( fDeltaTime );
|
||||
cur->m_GhostArrowRow.Update( fDeltaTime );
|
||||
|
||||
if( m_fPercentFadeToFail >= 0 )
|
||||
m_fPercentFadeToFail = min( m_fPercentFadeToFail + fDeltaTime/FADE_FAIL_TIME, 1 );
|
||||
if( m_FieldRenderArgs.fail_fade >= 0 )
|
||||
m_FieldRenderArgs.fail_fade = min( m_FieldRenderArgs.fail_fade + fDeltaTime/FADE_FAIL_TIME, 1 );
|
||||
|
||||
// Update fade to failed
|
||||
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_fPercentFadeToFail );
|
||||
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_FieldRenderArgs.fail_fade );
|
||||
|
||||
NoteDisplay::Update( fDeltaTime );
|
||||
/* Update all NoteDisplays. Hack: We need to call this once per frame, not
|
||||
@@ -801,13 +833,11 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB
|
||||
return fLastBeatToDraw;
|
||||
}
|
||||
|
||||
inline float NoteRowToVisibleBeat( const PlayerState *pPlayerState, int iRow )
|
||||
{
|
||||
return NoteRowToBeat(iRow);
|
||||
}
|
||||
|
||||
bool NoteField::IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const
|
||||
{
|
||||
// IMPORTANT: Do not modify this function without also modifying the
|
||||
// version that is in NoteDisplay.cpp or coming up with a good way to
|
||||
// merge them. -Kyz
|
||||
// TRICKY: If boomerang is on, then ones in the range
|
||||
// [iFirstRowToDraw,iLastRowToDraw] aren't necessarily visible.
|
||||
// Test to see if this beat is visible before drawing.
|
||||
@@ -834,41 +864,41 @@ void NoteField::DrawPrimitives()
|
||||
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
||||
|
||||
// Adjust draw range depending on some effects
|
||||
int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels;
|
||||
m_FieldRenderArgs.draw_pixels_after_targets= m_iDrawDistanceAfterTargetsPixels;
|
||||
// HACK: If boomerang and centered are on, then we want to draw much
|
||||
// earlier so that the notes don't pop on screen.
|
||||
float fCenteredTimesBoomerang =
|
||||
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
|
||||
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
||||
iDrawDistanceAfterTargetsPixels += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
||||
int iDrawDistanceBeforeTargetsPixels = m_iDrawDistanceBeforeTargetsPixels;
|
||||
m_FieldRenderArgs.draw_pixels_after_targets += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
||||
m_FieldRenderArgs.draw_pixels_before_targets = m_iDrawDistanceBeforeTargetsPixels;
|
||||
|
||||
float fDrawScale = 1;
|
||||
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
||||
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_MINI] );
|
||||
|
||||
iDrawDistanceAfterTargetsPixels = (int)(iDrawDistanceAfterTargetsPixels * fDrawScale);
|
||||
iDrawDistanceBeforeTargetsPixels = (int)(iDrawDistanceBeforeTargetsPixels * fDrawScale);
|
||||
m_FieldRenderArgs.draw_pixels_after_targets = (int)(m_FieldRenderArgs.draw_pixels_after_targets * fDrawScale);
|
||||
m_FieldRenderArgs.draw_pixels_before_targets = (int)(m_FieldRenderArgs.draw_pixels_before_targets * fDrawScale);
|
||||
|
||||
|
||||
// Probe for first and last notes on the screen
|
||||
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, iDrawDistanceAfterTargetsPixels );
|
||||
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, iDrawDistanceBeforeTargetsPixels );
|
||||
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, m_FieldRenderArgs.draw_pixels_after_targets );
|
||||
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, m_FieldRenderArgs.draw_pixels_before_targets );
|
||||
|
||||
m_pPlayerState->m_fLastDrawnBeat = fLastBeatToDraw;
|
||||
|
||||
const int iFirstRowToDraw = BeatToNoteRow(fFirstBeatToDraw);
|
||||
const int iLastRowToDraw = BeatToNoteRow(fLastBeatToDraw);
|
||||
m_FieldRenderArgs.first_row = BeatToNoteRow(fFirstBeatToDraw);
|
||||
m_FieldRenderArgs.last_row = BeatToNoteRow(fLastBeatToDraw);
|
||||
|
||||
//LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
|
||||
//LOG->Trace( "Drawing elements %d through %d", iFirstRowToDraw, iLastRowToDraw );
|
||||
//LOG->Trace( "Drawing elements %d through %d", m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||
|
||||
#define IS_ON_SCREEN( fBeat ) ( fFirstBeatToDraw <= (fBeat) && (fBeat) <= fLastBeatToDraw && IsOnScreen( fBeat, 0, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ) )
|
||||
#define IS_ON_SCREEN( fBeat ) ( fFirstBeatToDraw <= (fBeat) && (fBeat) <= fLastBeatToDraw && IsOnScreen( fBeat, 0, m_FieldRenderArgs.draw_pixels_after_targets, m_FieldRenderArgs.draw_pixels_before_targets ) )
|
||||
|
||||
// Draw board
|
||||
if( SHOW_BOARD )
|
||||
{
|
||||
DrawBoard( iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels );
|
||||
DrawBoard( m_FieldRenderArgs.draw_pixels_after_targets, m_FieldRenderArgs.draw_pixels_before_targets );
|
||||
}
|
||||
|
||||
// Draw Receptors
|
||||
@@ -891,7 +921,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < tSigs.size(); i++)
|
||||
{
|
||||
const TimeSignatureSegment *ts = ToTimeSignature(tSigs[i]);
|
||||
int iSegmentEndRow = (i + 1 == tSigs.size()) ? iLastRowToDraw : tSigs[i+1]->GetRow();
|
||||
int iSegmentEndRow = (i + 1 == tSigs.size()) ? m_FieldRenderArgs.last_row : tSigs[i+1]->GetRow();
|
||||
|
||||
// beat bars every 16th note
|
||||
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
|
||||
@@ -934,7 +964,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
||||
{
|
||||
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -946,7 +976,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
||||
{
|
||||
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -958,7 +988,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
||||
{
|
||||
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -970,7 +1000,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
||||
{
|
||||
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -982,7 +1012,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
||||
{
|
||||
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -994,7 +1024,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
||||
{
|
||||
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1006,7 +1036,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
||||
{
|
||||
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1018,7 +1048,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
||||
{
|
||||
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1030,7 +1060,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
||||
{
|
||||
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1042,7 +1072,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
||||
{
|
||||
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1055,7 +1085,7 @@ void NoteField::DrawPrimitives()
|
||||
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
||||
{
|
||||
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
@@ -1075,8 +1105,8 @@ void NoteField::DrawPrimitives()
|
||||
float fSecond = a->fStartSecond;
|
||||
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
||||
|
||||
if( BeatToNoteRow(fBeat) >= iFirstRowToDraw &&
|
||||
BeatToNoteRow(fBeat) <= iLastRowToDraw)
|
||||
if( BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row &&
|
||||
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row)
|
||||
{
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawAttackText( fBeat, *a );
|
||||
@@ -1094,8 +1124,8 @@ void NoteField::DrawPrimitives()
|
||||
FOREACH_CONST(Attack, attacks, a)
|
||||
{
|
||||
float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond);
|
||||
if (BeatToNoteRow(fBeat) >= iFirstRowToDraw &&
|
||||
BeatToNoteRow(fBeat) <= iLastRowToDraw &&
|
||||
if (BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row &&
|
||||
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row &&
|
||||
IS_ON_SCREEN(fBeat))
|
||||
{
|
||||
this->DrawAttackText(fBeat, *a);
|
||||
@@ -1179,20 +1209,20 @@ void NoteField::DrawPrimitives()
|
||||
{
|
||||
int iBegin = m_iBeginMarker;
|
||||
int iEnd = m_iEndMarker;
|
||||
CLAMP( iBegin, iFirstRowToDraw, iLastRowToDraw );
|
||||
CLAMP( iEnd, iFirstRowToDraw, iLastRowToDraw );
|
||||
CLAMP( iBegin, m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||
CLAMP( iEnd, m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||
DrawAreaHighlight( iBegin, iEnd );
|
||||
}
|
||||
else if( m_iBeginMarker != -1 )
|
||||
{
|
||||
if( m_iBeginMarker >= iFirstRowToDraw &&
|
||||
m_iBeginMarker <= iLastRowToDraw )
|
||||
if( m_iBeginMarker >= m_FieldRenderArgs.first_row &&
|
||||
m_iBeginMarker <= m_FieldRenderArgs.last_row )
|
||||
DrawMarkerBar( m_iBeginMarker );
|
||||
}
|
||||
else if( m_iEndMarker != -1 )
|
||||
{
|
||||
if( m_iEndMarker >= iFirstRowToDraw &&
|
||||
m_iEndMarker <= iLastRowToDraw )
|
||||
if( m_iEndMarker >= m_FieldRenderArgs.first_row &&
|
||||
m_iEndMarker <= m_FieldRenderArgs.last_row )
|
||||
DrawMarkerBar( m_iEndMarker );
|
||||
}
|
||||
}
|
||||
@@ -1201,175 +1231,19 @@ void NoteField::DrawPrimitives()
|
||||
// Draw the arrows in order of column. This minimizes texture switches and
|
||||
// lets us draw in big batches.
|
||||
|
||||
float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f );
|
||||
|
||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
||||
ASSERT_M(m_pNoteData->GetNumTracks() == GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer,
|
||||
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
|
||||
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
|
||||
|
||||
m_FieldRenderArgs.selection_glow= SCALE(
|
||||
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
|
||||
m_FieldRenderArgs.fade_before_targets= FADE_BEFORE_TARGETS_PERCENT;
|
||||
|
||||
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
|
||||
{
|
||||
const int c = pStyle->m_iColumnDrawOrder[j];
|
||||
|
||||
bool bAnyUpcomingInThisCol = false;
|
||||
|
||||
// Draw all HoldNotes in this column (so that they appear under the tap notes)
|
||||
{
|
||||
NoteData::TrackMap::const_iterator begin, end;
|
||||
m_pNoteData->GetTapNoteRangeInclusive( c, iFirstRowToDraw, iLastRowToDraw+1, begin, end );
|
||||
|
||||
for( ; begin != end; ++begin )
|
||||
{
|
||||
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, j);
|
||||
if( tn.type != TapNoteType_HoldHead )
|
||||
continue; // skip
|
||||
|
||||
const HoldNoteResult &Result = tn.HoldResult;
|
||||
if( Result.hns == HNS_Held ) // if this HoldNote was completed
|
||||
continue; // don't draw anything
|
||||
|
||||
int iStartRow = begin->first;
|
||||
int iEndRow = iStartRow + tn.iDuration;
|
||||
|
||||
// TRICKY: If boomerang is on, then all notes in the range
|
||||
// [iFirstRowToDraw,iLastRowToDraw] aren't necessarily visible.
|
||||
// Test every note to make sure it's on screen before drawing
|
||||
float fThrowAway;
|
||||
bool bStartIsPastPeak = false;
|
||||
bool bEndIsPastPeak = false;
|
||||
float fStartYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToVisibleBeat(m_pPlayerState, iStartRow), fThrowAway, bStartIsPastPeak );
|
||||
float fEndYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToVisibleBeat(m_pPlayerState, iEndRow), fThrowAway, bEndIsPastPeak );
|
||||
|
||||
bool bTailIsOnVisible = iDrawDistanceAfterTargetsPixels <= fEndYOffset && fEndYOffset <= iDrawDistanceBeforeTargetsPixels;
|
||||
bool bHeadIsVisible = iDrawDistanceAfterTargetsPixels <= fStartYOffset && fStartYOffset <= iDrawDistanceBeforeTargetsPixels;
|
||||
bool bStraddlingVisible = fStartYOffset <= iDrawDistanceAfterTargetsPixels && iDrawDistanceBeforeTargetsPixels <= fEndYOffset;
|
||||
bool bStaddlingPeak = bStartIsPastPeak && !bEndIsPastPeak;
|
||||
if( !(bTailIsOnVisible || bHeadIsVisible || bStraddlingVisible || bStaddlingPeak) )
|
||||
{
|
||||
//LOG->Trace( "skip drawing this hold." );
|
||||
continue; // skip
|
||||
}
|
||||
|
||||
bool bIsAddition = (tn.source == TapNoteSource_Addition);
|
||||
bool bIsHopoPossible = (tn.bHopoPossible);
|
||||
bool bUseAdditionColoring = bIsAddition || bIsHopoPossible;
|
||||
const bool bHoldGhostShowing = tn.HoldResult.bActive && tn.HoldResult.fLife > 0;
|
||||
const bool bIsHoldingNote = tn.HoldResult.bHeld;
|
||||
if( bHoldGhostShowing )
|
||||
m_pCurDisplay->m_GhostArrowRow.SetHoldShowing( c, tn );
|
||||
|
||||
ASSERT_M( NoteRowToBeat(iStartRow) > -2000, ssprintf("%i %i %i", iStartRow, iEndRow, c) );
|
||||
|
||||
bool bIsInSelectionRange = false;
|
||||
if( m_iBeginMarker!=-1 && m_iEndMarker!=-1 )
|
||||
bIsInSelectionRange = (m_iBeginMarker <= iStartRow && iEndRow < m_iEndMarker);
|
||||
|
||||
NoteDisplayCols *displayCols = tn.pn == PLAYER_INVALID ? m_pCurDisplay : m_pDisplays[tn.pn];
|
||||
displayCols->display[c].DrawHold( tn, c, iStartRow, bIsHoldingNote, Result, bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail,
|
||||
m_fYReverseOffsetPixels, (float) iDrawDistanceAfterTargetsPixels, (float) iDrawDistanceBeforeTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT );
|
||||
|
||||
bool bNoteIsUpcoming = NoteRowToBeat(iStartRow) > m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||
bAnyUpcomingInThisCol |= bNoteIsUpcoming;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw all TapNotes in this column
|
||||
|
||||
// draw notes from furthest to closest
|
||||
NoteData::TrackMap::const_iterator begin, end;
|
||||
m_pNoteData->GetTapNoteRange( c, iFirstRowToDraw, iLastRowToDraw+1, begin, end );
|
||||
for( ; begin != end; ++begin )
|
||||
{
|
||||
int q = begin->first;
|
||||
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, q);
|
||||
|
||||
// Switch modified by Wolfman2000, tested by Saturn2888
|
||||
// Fixes hold head overlapping issue, but not the rolls.
|
||||
switch( tn.type )
|
||||
{
|
||||
case TapNoteType_Empty: // no note here
|
||||
{
|
||||
continue;
|
||||
}
|
||||
case TapNoteType_HoldHead:
|
||||
{
|
||||
//if (tn.subType == TapNoteSubType_Roll)
|
||||
continue; // skip
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Don't draw hidden (fully judged) steps.
|
||||
if( tn.result.bHidden )
|
||||
continue;
|
||||
|
||||
// TRICKY: If boomerang is on, then all notes in the range
|
||||
// [iFirstRowToDraw,iLastRowToDraw] aren't necessarily visible.
|
||||
// Test every note to make sure it's on screen before drawing.
|
||||
if( !IsOnScreen( NoteRowToBeat(q), c, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ) )
|
||||
continue; // skip
|
||||
|
||||
ASSERT_M( NoteRowToBeat(q) > -2000, ssprintf("%i %i %i, %f %f", q, iLastRowToDraw,
|
||||
iFirstRowToDraw, m_pPlayerState->GetDisplayedPosition().m_fSongBeat, m_pPlayerState->GetDisplayedPosition().m_fMusicSeconds) );
|
||||
|
||||
// See if there is a hold step that begins on this index.
|
||||
// Only do this if the noteskin cares.
|
||||
bool bHoldNoteBeginsOnThisBeat = false;
|
||||
if( m_pCurDisplay->display[c].DrawHoldHeadForTapsOnSameRow() )
|
||||
{
|
||||
for( int c2=0; c2<m_pNoteData->GetNumTracks(); c2++ )
|
||||
{
|
||||
const TapNote &tmp = m_pNoteData->GetTapNote(c2, q);
|
||||
if(tmp.type == TapNoteType_HoldHead &&
|
||||
tmp.subType == TapNoteSubType_Hold)
|
||||
{
|
||||
bHoldNoteBeginsOnThisBeat = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do the same for a roll.
|
||||
bool bRollNoteBeginsOnThisBeat = false;
|
||||
if (m_pCurDisplay->display[c].DrawRollHeadForTapsOnSameRow() )
|
||||
{
|
||||
for( int c2=0; c2<m_pNoteData->GetNumTracks(); c2++ )
|
||||
{
|
||||
const TapNote &tmp = m_pNoteData->GetTapNote(c2, q);
|
||||
if(tmp.type == TapNoteType_HoldHead &&
|
||||
tmp.subType == TapNoteSubType_Roll)
|
||||
{
|
||||
bRollNoteBeginsOnThisBeat = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bIsInSelectionRange = false;
|
||||
if( m_iBeginMarker!=-1 && m_iEndMarker!=-1 )
|
||||
bIsInSelectionRange = m_iBeginMarker<=q && q<m_iEndMarker;
|
||||
|
||||
bool bIsAddition = (tn.source == TapNoteSource_Addition);
|
||||
bool bIsHopoPossible = (tn.bHopoPossible);
|
||||
bool bUseAdditionColoring = bIsAddition || bIsHopoPossible;
|
||||
NoteDisplayCols *displayCols = tn.pn == PLAYER_INVALID ? m_pCurDisplay : m_pDisplays[tn.pn];
|
||||
displayCols->display[c].DrawTap(tn, c, NoteRowToVisibleBeat(m_pPlayerState, q),
|
||||
bHoldNoteBeginsOnThisBeat, bRollNoteBeginsOnThisBeat,
|
||||
bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail,
|
||||
m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels,
|
||||
FADE_BEFORE_TARGETS_PERCENT );
|
||||
|
||||
bool bNoteIsUpcoming = NoteRowToBeat(q) > m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||
bAnyUpcomingInThisCol |= bNoteIsUpcoming;
|
||||
|
||||
if(!FAST_NOTE_RENDERING_PREF_CACHED)
|
||||
{
|
||||
DISPLAY->ClearZBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
cur->m_ReceptorArrowRow.SetNoteUpcoming( c, bAnyUpcomingInThisCol );
|
||||
m_ColumnRenderers[c].Draw();
|
||||
}
|
||||
|
||||
cur->m_GhostArrowRow.Draw();
|
||||
@@ -1377,7 +1251,7 @@ void NoteField::DrawPrimitives()
|
||||
|
||||
void NoteField::FadeToFail()
|
||||
{
|
||||
m_fPercentFadeToFail = max( 0.0f, m_fPercentFadeToFail ); // this will slowly increase every Update()
|
||||
m_FieldRenderArgs.fail_fade = max( 0.0f, m_FieldRenderArgs.fail_fade ); // this will slowly increase every Update()
|
||||
// don't fade all over again if this is called twice
|
||||
}
|
||||
|
||||
@@ -1523,10 +1397,10 @@ public:
|
||||
} \
|
||||
return 0; \
|
||||
}
|
||||
SET_CALLBACK_GENERIC(SetStepCallback, m_StepCallback);
|
||||
SET_CALLBACK_GENERIC(SetSetPressedCallback, m_SetPressedCallback);
|
||||
SET_CALLBACK_GENERIC(SetDidTapNoteCallback, m_DidTapNoteCallback);
|
||||
SET_CALLBACK_GENERIC(SetDidHoldNoteCallback, m_DidHoldNoteCallback);
|
||||
SET_CALLBACK_GENERIC(set_step_callback, m_StepCallback);
|
||||
SET_CALLBACK_GENERIC(set_set_pressed_callback, m_SetPressedCallback);
|
||||
SET_CALLBACK_GENERIC(set_did_tap_note_callback, m_DidTapNoteCallback);
|
||||
SET_CALLBACK_GENERIC(set_did_hold_note_callback, m_DidHoldNoteCallback);
|
||||
#undef SET_CALLBACK_GENERIC
|
||||
|
||||
static int check_column(lua_State* L, int index)
|
||||
@@ -1542,7 +1416,7 @@ public:
|
||||
return col;
|
||||
}
|
||||
|
||||
static int Step(T* p, lua_State* L)
|
||||
static int step(T* p, lua_State* L)
|
||||
{
|
||||
int col= check_column(L, 1);
|
||||
TapNoteScore tns= Enum::Check<TapNoteScore>(L, 2);
|
||||
@@ -1550,14 +1424,14 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetPressed(T* p, lua_State* L)
|
||||
static int set_pressed(T* p, lua_State* L)
|
||||
{
|
||||
int col= check_column(L, 1);
|
||||
p->SetPressed(col, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DidTapNote(T* p, lua_State* L)
|
||||
static int did_tap_note(T* p, lua_State* L)
|
||||
{
|
||||
int col= check_column(L, 1);
|
||||
TapNoteScore tns= Enum::Check<TapNoteScore>(L, 2);
|
||||
@@ -1566,7 +1440,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DidHoldNote(T* p, lua_State* L)
|
||||
static int did_hold_note(T* p, lua_State* L)
|
||||
{
|
||||
int col= check_column(L, 1);
|
||||
HoldNoteScore hns= Enum::Check<HoldNoteScore>(L, 2);
|
||||
@@ -1575,16 +1449,28 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_column_actors(T* p, lua_State* L)
|
||||
{
|
||||
lua_createtable(L, p->m_ColumnRenderers.size(), 0);
|
||||
for(size_t i= 0; i < p->m_ColumnRenderers.size(); ++i)
|
||||
{
|
||||
p->m_ColumnRenderers[i].PushSelf(L);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
LunaNoteField()
|
||||
{
|
||||
ADD_METHOD(SetStepCallback);
|
||||
ADD_METHOD(SetSetPressedCallback);
|
||||
ADD_METHOD(SetDidTapNoteCallback);
|
||||
ADD_METHOD(SetDidHoldNoteCallback);
|
||||
ADD_METHOD(Step);
|
||||
ADD_METHOD(SetPressed);
|
||||
ADD_METHOD(DidTapNote);
|
||||
ADD_METHOD(DidHoldNote);
|
||||
ADD_METHOD(set_step_callback);
|
||||
ADD_METHOD(set_set_pressed_callback);
|
||||
ADD_METHOD(set_did_tap_note_callback);
|
||||
ADD_METHOD(set_did_hold_note_callback);
|
||||
ADD_METHOD(step);
|
||||
ADD_METHOD(set_pressed);
|
||||
ADD_METHOD(did_tap_note);
|
||||
ADD_METHOD(did_hold_note);
|
||||
ADD_METHOD(get_column_actors);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+8
-2
@@ -29,6 +29,8 @@ public:
|
||||
int iDrawDistanceBeforeTargetsPixels );
|
||||
virtual void Unload();
|
||||
|
||||
void InitColumnRenderers();
|
||||
|
||||
virtual void HandleMessage( const Message &msg );
|
||||
|
||||
// This is done automatically by Init(), but can be re-called explicitly if the
|
||||
@@ -55,6 +57,10 @@ public:
|
||||
|
||||
int m_iBeginMarker, m_iEndMarker; // only used with MODE_EDIT
|
||||
|
||||
// m_ColumnRenderers belongs in the protected section, but it's here in
|
||||
// public so that the Lua API can access it. -Kyz
|
||||
vector<NoteColumnRenderer> m_ColumnRenderers;
|
||||
|
||||
protected:
|
||||
void CacheNoteSkin( const RString &sNoteSkin );
|
||||
void UncacheNoteSkin( const RString &sNoteSkin );
|
||||
@@ -84,8 +90,6 @@ protected:
|
||||
|
||||
const NoteData *m_pNoteData;
|
||||
|
||||
float m_fPercentFadeToFail; // -1 if not fading to fail
|
||||
|
||||
const PlayerState* m_pPlayerState;
|
||||
int m_iDrawDistanceAfterTargetsPixels; // this should be a negative number
|
||||
int m_iDrawDistanceBeforeTargetsPixels; // this should be a positive number
|
||||
@@ -101,6 +105,8 @@ protected:
|
||||
~NoteDisplayCols() { delete [] display; }
|
||||
};
|
||||
|
||||
NoteFieldRenderArgs m_FieldRenderArgs;
|
||||
|
||||
/* All loaded note displays, mapped by their name. */
|
||||
map<RString, NoteDisplayCols *> m_NoteDisplays;
|
||||
NoteDisplayCols *m_pCurDisplay;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "RageLog.h"
|
||||
#include "RageMath.h"
|
||||
#include "RageTypes.h"
|
||||
#include <float.h>
|
||||
@@ -40,6 +41,22 @@ void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV )
|
||||
pOut->z = pV->z * scale;
|
||||
}
|
||||
|
||||
void VectorFloatNormalize(vector<float>& v)
|
||||
{
|
||||
ASSERT_M(v.size() == 3, "Can't normalize a non-3D vector.");
|
||||
float scale = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
v[0]*= scale;
|
||||
v[1]*= scale;
|
||||
v[2]*= scale;
|
||||
}
|
||||
|
||||
void RageVec3Cross(RageVector3* ret, RageVector3 const* a, RageVector3 const* b)
|
||||
{
|
||||
ret->x= (a->y * b->z) - (a->z * b->y);
|
||||
ret->y= ((a->x * b->z) - (a->z * b->x));
|
||||
ret->z= (a->x * b->y) - (a->y * b->x);
|
||||
}
|
||||
|
||||
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM )
|
||||
{
|
||||
RageVector4 temp( pV->x, pV->y, pV->z, 1.0f ); // translate
|
||||
@@ -313,6 +330,21 @@ void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ )
|
||||
pOut->m33 = 1;
|
||||
}
|
||||
|
||||
void RageAARotate(RageVector3* inret, RageVector3 const* axis, float angle)
|
||||
{
|
||||
float ha= angle/2.0f;
|
||||
float ca2= RageFastCos(ha);
|
||||
float sa2= RageFastSin(ha);
|
||||
RageVector4 quat(axis->x * sa2, axis->y * sa2, axis->z * sa2, ca2);
|
||||
RageVector4 quatc(-quat.x, -quat.y, -quat.z, ca2);
|
||||
RageVector4 point(inret->x, inret->y, inret->z, 0.0f);
|
||||
RageQuatMultiply(&point, quat, point);
|
||||
RageQuatMultiply(&point, point, quatc);
|
||||
inret->x= point.x;
|
||||
inret->y= point.y;
|
||||
inret->z= point.z;
|
||||
}
|
||||
|
||||
void RageQuatMultiply( RageVector4* pOut, const RageVector4 &pA, const RageVector4 &pB )
|
||||
{
|
||||
RageVector4 out;
|
||||
|
||||
@@ -18,6 +18,8 @@ void RageVec3AddToBounds( const RageVector3 &p, RageVector3 &mins, RageVector3 &
|
||||
|
||||
void RageVec2Normalize( RageVector2* pOut, const RageVector2* pV );
|
||||
void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV );
|
||||
void VectorFloatNormalize(vector<float>& v);
|
||||
void RageVec3Cross(RageVector3* ret, RageVector3 const* a, RageVector3 const* b);
|
||||
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
||||
void RageVec3TransformNormal( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
||||
void RageVec4TransformCoord( RageVector4* pOut, const RageVector4* pV, const RageMatrix* pM );
|
||||
@@ -34,6 +36,7 @@ void RageMatrixRotationX( RageMatrix* pOut, float fTheta );
|
||||
void RageMatrixRotationY( RageMatrix* pOut, float fTheta );
|
||||
void RageMatrixRotationZ( RageMatrix* pOut, float fTheta );
|
||||
void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ );
|
||||
void RageAARotate(RageVector3* inret, RageVector3 const* axis, float angle);
|
||||
void RageQuatFromHPR(RageVector4* pOut, RageVector3 hpr );
|
||||
void RageQuatFromPRH(RageVector4* pOut, RageVector3 prh );
|
||||
void RageMatrixFromQuat( RageMatrix* pOut, const RageVector4 q );
|
||||
|
||||
@@ -61,6 +61,12 @@ inline bool CLAMP( unsigned &x, unsigned l, unsigned h )
|
||||
else if (x < l) { x = l; return true; }
|
||||
return false;
|
||||
}
|
||||
inline bool CLAMP( size_t &x, size_t l, size_t h )
|
||||
{
|
||||
if (x > h) { x = h; return true; }
|
||||
else if (x < l) { x = l; return true; }
|
||||
return false;
|
||||
}
|
||||
inline bool CLAMP( float &x, float l, float h )
|
||||
{
|
||||
if (x > h) { x = h; return true; }
|
||||
|
||||
+11
-12
@@ -30,6 +30,16 @@ void ReceptorArrowRow::Load( const PlayerState* pPlayerState, float fYReverseOff
|
||||
}
|
||||
}
|
||||
|
||||
void ReceptorArrowRow::SetColumnRenderers(vector<NoteColumnRenderer>& renderers)
|
||||
{
|
||||
ASSERT_M(renderers.size() == m_ReceptorArrow.size(), "Notefield has different number of columns than receptor row.");
|
||||
for(size_t c= 0; c < m_ReceptorArrow.size(); ++c)
|
||||
{
|
||||
m_ReceptorArrow[c]->SetFakeParent(&(renderers[c]));
|
||||
}
|
||||
m_renderers= &renderers;
|
||||
}
|
||||
|
||||
ReceptorArrowRow::~ReceptorArrowRow()
|
||||
{
|
||||
for( unsigned i = 0; i < m_ReceptorArrow.size(); ++i )
|
||||
@@ -53,18 +63,7 @@ void ReceptorArrowRow::Update( float fDeltaTime )
|
||||
m_ReceptorArrow[c]->SetBaseAlpha( fBaseAlpha );
|
||||
|
||||
// set arrow XYZ
|
||||
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
|
||||
const float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
|
||||
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
|
||||
m_ReceptorArrow[c]->SetX( fX );
|
||||
m_ReceptorArrow[c]->SetY( fY );
|
||||
m_ReceptorArrow[c]->SetZ( fZ );
|
||||
|
||||
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
|
||||
m_ReceptorArrow[c]->SetRotationZ( fRotation );
|
||||
|
||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
||||
m_ReceptorArrow[c]->SetZoom( fZoom );
|
||||
(*m_renderers)[c].UpdateReceptorGhostStuff(m_ReceptorArrow[c]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ReceptorArrow.h"
|
||||
#include "ActorFrame.h"
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "NoteDisplay.h"
|
||||
|
||||
class PlayerState;
|
||||
/** @brief A row of ReceptorArrow objects. */
|
||||
@@ -16,6 +17,7 @@ public:
|
||||
virtual void DrawPrimitives();
|
||||
|
||||
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
||||
void SetColumnRenderers(vector<NoteColumnRenderer>& renderers);
|
||||
|
||||
void Step( int iCol, TapNoteScore score );
|
||||
void SetPressed( int iCol );
|
||||
@@ -28,6 +30,7 @@ protected:
|
||||
float m_fYReverseOffsetPixels;
|
||||
float m_fFadeToFailPercent;
|
||||
|
||||
vector<NoteColumnRenderer> const* m_renderers;
|
||||
vector<ReceptorArrow *> m_ReceptorArrow;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user