Created NoteColumnRenderer to handle column rendering. Added m_FakeParent to Actor to solve part of the problem.
This commit is contained in:
+35
-1
@@ -164,6 +164,7 @@ Actor::Actor()
|
|||||||
m_size = RageVector2( 1, 1 );
|
m_size = RageVector2( 1, 1 );
|
||||||
InitState();
|
InitState();
|
||||||
m_pParent = NULL;
|
m_pParent = NULL;
|
||||||
|
m_FakeParent= NULL;
|
||||||
m_bFirstUpdate = true;
|
m_bFirstUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +184,7 @@ Actor::Actor( const Actor &cpy ):
|
|||||||
#define CPY(x) x = cpy.x
|
#define CPY(x) x = cpy.x
|
||||||
CPY( m_sName );
|
CPY( m_sName );
|
||||||
CPY( m_pParent );
|
CPY( m_pParent );
|
||||||
|
CPY( m_FakeParent );
|
||||||
CPY( m_pLuaInstance );
|
CPY( m_pLuaInstance );
|
||||||
|
|
||||||
CPY( m_baseRotation );
|
CPY( m_baseRotation );
|
||||||
@@ -279,24 +281,56 @@ void Actor::LoadFromNode( const XNode* pNode )
|
|||||||
PlayCommandNoRecurse( Message("Init") );
|
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()
|
void Actor::Draw()
|
||||||
{
|
{
|
||||||
if( !m_bVisible ||
|
if( !m_bVisible ||
|
||||||
m_fHibernateSecondsLeft > 0 ||
|
m_fHibernateSecondsLeft > 0 ||
|
||||||
this->EarlyAbortDraw() )
|
this->EarlyAbortDraw() )
|
||||||
|
{
|
||||||
return; // early abort
|
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();
|
this->PreDraw();
|
||||||
ASSERT( m_pTempState != NULL );
|
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
|
// call the most-derived versions
|
||||||
this->BeginDraw();
|
this->BeginDraw();
|
||||||
this->DrawPrimitives(); // call the most-derived version of DrawPrimitives();
|
this->DrawPrimitives(); // call the most-derived version of DrawPrimitives();
|
||||||
this->EndDraw();
|
this->EndDraw();
|
||||||
|
if(m_FakeParent)
|
||||||
|
{
|
||||||
|
m_FakeParent->EndDraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->PostDraw();
|
this->PostDraw();
|
||||||
|
if(m_FakeParent)
|
||||||
|
{
|
||||||
|
m_FakeParent->PostDraw();
|
||||||
|
}
|
||||||
m_pTempState = NULL;
|
m_pTempState = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ public:
|
|||||||
float aux;
|
float aux;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PartiallyOpaque broken out of Draw for reuse and clarity.
|
||||||
|
bool PartiallyOpaque();
|
||||||
/**
|
/**
|
||||||
* @brief Calls multiple functions for drawing the Actors.
|
* @brief Calls multiple functions for drawing the Actors.
|
||||||
*
|
*
|
||||||
@@ -305,6 +307,9 @@ public:
|
|||||||
* @return the Actor's lineage. */
|
* @return the Actor's lineage. */
|
||||||
RString GetLineage() const;
|
RString GetLineage() const;
|
||||||
|
|
||||||
|
void SetFakeParent(Actor* mailman) { m_FakeParent= mailman; }
|
||||||
|
Actor* GetFakeParent() { return m_FakeParent; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve the Actor's x position.
|
* @brief Retrieve the Actor's x position.
|
||||||
* @return the Actor's x position. */
|
* @return the Actor's x position. */
|
||||||
@@ -607,6 +612,10 @@ protected:
|
|||||||
RString m_sName;
|
RString m_sName;
|
||||||
/** @brief the current parent of this Actor if it exists. */
|
/** @brief the current parent of this Actor if it exists. */
|
||||||
Actor *m_pParent;
|
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. */
|
/** @brief Some general information about the Tween. */
|
||||||
struct TweenInfo
|
struct TweenInfo
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ 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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GhostArrowRow::~GhostArrowRow()
|
GhostArrowRow::~GhostArrowRow()
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < m_Ghost.size(); ++i )
|
for( unsigned i = 0; i < m_Ghost.size(); ++i )
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "ActorFrame.h"
|
#include "ActorFrame.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "NoteTypes.h"
|
#include "NoteTypes.h"
|
||||||
|
#include "NoteDisplay.h"
|
||||||
|
|
||||||
class PlayerState;
|
class PlayerState;
|
||||||
/** @brief Row of GhostArrow Actors. */
|
/** @brief Row of GhostArrow Actors. */
|
||||||
@@ -15,6 +16,7 @@ public:
|
|||||||
virtual void DrawPrimitives();
|
virtual void DrawPrimitives();
|
||||||
|
|
||||||
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
||||||
|
void SetColumnRenderers(vector<NoteColumnRenderer>& renderers);
|
||||||
|
|
||||||
void DidTapNote( int iCol, TapNoteScore tns, bool bBright );
|
void DidTapNote( int iCol, TapNoteScore tns, bool bBright );
|
||||||
void DidHoldNote( int iCol, HoldNoteScore hns, bool bBright );
|
void DidHoldNote( int iCol, HoldNoteScore hns, bool bBright );
|
||||||
|
|||||||
+80
-21
@@ -7,6 +7,7 @@
|
|||||||
#include "ArrowEffects.h"
|
#include "ArrowEffects.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageDisplay.h"
|
#include "RageDisplay.h"
|
||||||
|
#include "ReceptorArrowRow.h"
|
||||||
#include "ActorUtil.h"
|
#include "ActorUtil.h"
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "PlayerState.h"
|
#include "PlayerState.h"
|
||||||
@@ -341,8 +342,8 @@ bool NoteDisplay::IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTarge
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoteDisplay::DrawHoldsInRange(NoteDisplayRenderArgs const& args,
|
bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
int column, vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
||||||
{
|
{
|
||||||
bool any_upcoming = false;
|
bool any_upcoming = false;
|
||||||
for(vector<NoteData::TrackMap::const_iterator>::const_iterator tapit=
|
for(vector<NoteData::TrackMap::const_iterator>::const_iterator tapit=
|
||||||
@@ -359,10 +360,10 @@ bool NoteDisplay::DrawHoldsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
float throw_away;
|
float throw_away;
|
||||||
bool start_past_peak = false;
|
bool start_past_peak = false;
|
||||||
bool end_past_peak = false;
|
bool end_past_peak = false;
|
||||||
float start_y = ArrowEffects::GetYOffset(m_pPlayerState, args.column,
|
float start_y = ArrowEffects::GetYOffset(m_pPlayerState, column,
|
||||||
NoteRowToVisibleBeat(m_pPlayerState, start_row), throw_away,
|
NoteRowToVisibleBeat(m_pPlayerState, start_row), throw_away,
|
||||||
start_past_peak);
|
start_past_peak);
|
||||||
float end_y = ArrowEffects::GetYOffset(m_pPlayerState, args.column,
|
float end_y = ArrowEffects::GetYOffset(m_pPlayerState, column,
|
||||||
NoteRowToVisibleBeat(m_pPlayerState, end_row), throw_away,
|
NoteRowToVisibleBeat(m_pPlayerState, end_row), throw_away,
|
||||||
end_past_peak);
|
end_past_peak);
|
||||||
bool tail_visible = args.draw_pixels_after_targets <= end_y &&
|
bool tail_visible = args.draw_pixels_after_targets <= end_y &&
|
||||||
@@ -385,19 +386,19 @@ bool NoteDisplay::DrawHoldsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
const bool is_holding = tn.HoldResult.bHeld;
|
const bool is_holding = tn.HoldResult.bHeld;
|
||||||
if(hold_ghost_showing)
|
if(hold_ghost_showing)
|
||||||
{
|
{
|
||||||
args.ghost_row.SetHoldShowing(args.column, tn);
|
args.ghost_row->SetHoldShowing(column, tn);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_M(NoteRowToBeat(start_row) > -2000, ssprintf("%i %i %i", start_row, end_row, args.column));
|
ASSERT_M(NoteRowToBeat(start_row) > -2000, ssprintf("%i %i %i", start_row, end_row, column));
|
||||||
|
|
||||||
bool in_selection_range = false;
|
bool in_selection_range = false;
|
||||||
if(args.selection_begin_marker != -1 && args.selection_end_marker != -1)
|
if(*args.selection_begin_marker != -1 && *args.selection_end_marker != -1)
|
||||||
{
|
{
|
||||||
in_selection_range = (args.selection_begin_marker <= start_row &&
|
in_selection_range = (*args.selection_begin_marker <= start_row &&
|
||||||
end_row < args.selection_end_marker);
|
end_row < *args.selection_end_marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawHold(tn, args.column, start_row, is_holding, result,
|
DrawHold(tn, column, start_row, is_holding, result,
|
||||||
use_addition_coloring,
|
use_addition_coloring,
|
||||||
in_selection_range ? args.selection_glow : args.fail_fade,
|
in_selection_range ? args.selection_glow : args.fail_fade,
|
||||||
m_fYReverseOffsetPixels, (float)args.draw_pixels_after_targets,
|
m_fYReverseOffsetPixels, (float)args.draw_pixels_after_targets,
|
||||||
@@ -411,8 +412,8 @@ bool NoteDisplay::DrawHoldsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
return any_upcoming;
|
return any_upcoming;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoteDisplay::DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
int column, vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
||||||
{
|
{
|
||||||
bool any_upcoming= false;
|
bool any_upcoming= false;
|
||||||
// draw notes from furthest to closest
|
// draw notes from furthest to closest
|
||||||
@@ -425,7 +426,7 @@ bool NoteDisplay::DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
// TRICKY: If boomerang is on, then all notes in the range
|
// TRICKY: If boomerang is on, then all notes in the range
|
||||||
// [first_row,last_row] aren't necessarily visible.
|
// [first_row,last_row] aren't necessarily visible.
|
||||||
// Test every note to make sure it's on screen before drawing.
|
// Test every note to make sure it's on screen before drawing.
|
||||||
if(!IsOnScreen(NoteRowToBeat(tap_row), args.column,
|
if(!IsOnScreen(NoteRowToBeat(tap_row), column,
|
||||||
args.draw_pixels_after_targets, args.draw_pixels_before_targets))
|
args.draw_pixels_after_targets, args.draw_pixels_before_targets))
|
||||||
{
|
{
|
||||||
continue; // skip
|
continue; // skip
|
||||||
@@ -446,9 +447,9 @@ bool NoteDisplay::DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
bool hold_begins_on_this_beat = false;
|
bool hold_begins_on_this_beat = false;
|
||||||
if(DrawHoldHeadForTapsOnSameRow())
|
if(DrawHoldHeadForTapsOnSameRow())
|
||||||
{
|
{
|
||||||
for(int c2= 0; c2 < args.note_data.GetNumTracks(); ++c2)
|
for(int c2= 0; c2 < args.note_data->GetNumTracks(); ++c2)
|
||||||
{
|
{
|
||||||
const TapNote &tmp = args.note_data.GetTapNote(c2, tap_row);
|
const TapNote &tmp = args.note_data->GetTapNote(c2, tap_row);
|
||||||
if(tmp.type == TapNoteType_HoldHead &&
|
if(tmp.type == TapNoteType_HoldHead &&
|
||||||
tmp.subType == TapNoteSubType_Hold)
|
tmp.subType == TapNoteSubType_Hold)
|
||||||
{
|
{
|
||||||
@@ -462,9 +463,9 @@ bool NoteDisplay::DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
bool roll_begins_on_this_beat = false;
|
bool roll_begins_on_this_beat = false;
|
||||||
if(DrawRollHeadForTapsOnSameRow())
|
if(DrawRollHeadForTapsOnSameRow())
|
||||||
{
|
{
|
||||||
for(int c2= 0; c2 < args.note_data.GetNumTracks(); ++c2)
|
for(int c2= 0; c2 < args.note_data->GetNumTracks(); ++c2)
|
||||||
{
|
{
|
||||||
const TapNote &tmp = args.note_data.GetTapNote(c2, tap_row);
|
const TapNote &tmp = args.note_data->GetTapNote(c2, tap_row);
|
||||||
if(tmp.type == TapNoteType_HoldHead &&
|
if(tmp.type == TapNoteType_HoldHead &&
|
||||||
tmp.subType == TapNoteSubType_Roll)
|
tmp.subType == TapNoteSubType_Roll)
|
||||||
{
|
{
|
||||||
@@ -475,16 +476,16 @@ bool NoteDisplay::DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool in_selection_range = false;
|
bool in_selection_range = false;
|
||||||
if(args.selection_begin_marker != -1 && args.selection_end_marker != -1)
|
if(*args.selection_begin_marker != -1 && *args.selection_end_marker != -1)
|
||||||
{
|
{
|
||||||
in_selection_range = args.selection_begin_marker <= tap_row &&
|
in_selection_range = *args.selection_begin_marker <= tap_row &&
|
||||||
tap_row < args.selection_end_marker;
|
tap_row < *args.selection_end_marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_addition = (tn.source == TapNoteSource_Addition);
|
bool is_addition = (tn.source == TapNoteSource_Addition);
|
||||||
bool hopo_possible = (tn.bHopoPossible);
|
bool hopo_possible = (tn.bHopoPossible);
|
||||||
bool use_addition_coloring = is_addition || hopo_possible;
|
bool use_addition_coloring = is_addition || hopo_possible;
|
||||||
DrawTap(tn, args.column, NoteRowToVisibleBeat(m_pPlayerState, tap_row),
|
DrawTap(tn, column, NoteRowToVisibleBeat(m_pPlayerState, tap_row),
|
||||||
hold_begins_on_this_beat, roll_begins_on_this_beat,
|
hold_begins_on_this_beat, roll_begins_on_this_beat,
|
||||||
use_addition_coloring,
|
use_addition_coloring,
|
||||||
in_selection_range ? args.selection_glow : args.fail_fade,
|
in_selection_range ? args.selection_glow : args.fail_fade,
|
||||||
@@ -1064,6 +1065,64 @@ void NoteDisplay::DrawTap(const TapNote& tn, int iCol, float fBeat,
|
|||||||
pActor->PlayCommand( "UnsetAttack" );
|
pActor->PlayCommand( "UnsetAttack" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoteColumnRenderer::DrawPrimitives()
|
||||||
|
{
|
||||||
|
bool any_upcoming= false;
|
||||||
|
// Build lists of holds and taps for each player number, then pass those
|
||||||
|
// lists to the displays to draw.
|
||||||
|
// The vector in the NUM_PlayerNumber slot should stay empty, not worth
|
||||||
|
// optimizing it out. -Kyz
|
||||||
|
vector<vector<NoteData::TrackMap::const_iterator> > holds(PLAYER_INVALID+1);
|
||||||
|
vector<vector<NoteData::TrackMap::const_iterator> > taps(PLAYER_INVALID+1);
|
||||||
|
NoteData::TrackMap::const_iterator begin, end;
|
||||||
|
m_render_args->note_data->GetTapNoteRangeInclusive(m_column,
|
||||||
|
m_render_args->first_row, m_render_args->last_row+1, begin, end);
|
||||||
|
for(; begin != end; ++begin)
|
||||||
|
{
|
||||||
|
TapNote const& tn= begin->second;
|
||||||
|
switch(tn.type)
|
||||||
|
{
|
||||||
|
case TapNoteType_Empty:
|
||||||
|
continue;
|
||||||
|
case TapNoteType_Tap:
|
||||||
|
case TapNoteType_HoldTail:
|
||||||
|
case TapNoteType_Mine:
|
||||||
|
case TapNoteType_Lift:
|
||||||
|
case TapNoteType_Attack:
|
||||||
|
case TapNoteType_AutoKeysound:
|
||||||
|
case TapNoteType_Fake:
|
||||||
|
if(!tn.result.bHidden)
|
||||||
|
{
|
||||||
|
taps[tn.pn].push_back(begin);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TapNoteType_HoldHead:
|
||||||
|
if(tn.HoldResult.hns != HNS_Held)
|
||||||
|
{
|
||||||
|
holds[tn.pn].push_back(begin);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define DTS_INNER(pn, tap_set, draw_func, disp) \
|
||||||
|
if(!tap_set[pn].empty()) \
|
||||||
|
{ \
|
||||||
|
any_upcoming|= disp->draw_func(*m_render_args, m_column, tap_set[pn]); \
|
||||||
|
}
|
||||||
|
#define DRAW_TAP_SET(tap_set, draw_func) \
|
||||||
|
FOREACH_PlayerNumber(pn) \
|
||||||
|
{ \
|
||||||
|
DTS_INNER(pn, tap_set, draw_func, m_displays[pn]); \
|
||||||
|
}
|
||||||
|
DRAW_TAP_SET(holds, DrawHoldsInRange);
|
||||||
|
DTS_INNER(PLAYER_INVALID, holds, DrawHoldsInRange, m_displays[PLAYER_INVALID]);
|
||||||
|
DRAW_TAP_SET(taps, DrawTapsInRange);
|
||||||
|
DTS_INNER(PLAYER_INVALID, taps, DrawTapsInRange, m_displays[PLAYER_INVALID]);
|
||||||
|
#undef DTS_INNER
|
||||||
|
#undef DRAW_TAP_SET
|
||||||
|
m_render_args->receptor_row->SetNoteUpcoming(m_column, any_upcoming);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2006 Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway
|
* (c) 2001-2006 Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|||||||
+31
-17
@@ -1,15 +1,16 @@
|
|||||||
#ifndef NOTE_DISPLAY_H
|
#ifndef NOTE_DISPLAY_H
|
||||||
#define NOTE_DISPLAY_H
|
#define NOTE_DISPLAY_H
|
||||||
|
|
||||||
|
#include "ActorFrame.h"
|
||||||
#include "NoteData.h"
|
#include "NoteData.h"
|
||||||
#include "PlayerNumber.h"
|
#include "PlayerNumber.h"
|
||||||
#include "GameInput.h"
|
#include "GameInput.h"
|
||||||
|
|
||||||
class Actor;
|
|
||||||
class Sprite;
|
class Sprite;
|
||||||
class Model;
|
class Model;
|
||||||
class PlayerState;
|
class PlayerState;
|
||||||
class GhostArrowRow;
|
class GhostArrowRow;
|
||||||
|
class ReceptorArrowRow;
|
||||||
struct TapNote;
|
struct TapNote;
|
||||||
struct HoldNoteResult;
|
struct HoldNoteResult;
|
||||||
struct NoteMetricCache_t;
|
struct NoteMetricCache_t;
|
||||||
@@ -87,28 +88,22 @@ const RString &ActiveTypeToString( ActiveType at );
|
|||||||
|
|
||||||
// A little pod struct to carry the data the NoteField needs to pass to the
|
// A little pod struct to carry the data the NoteField needs to pass to the
|
||||||
// NoteDisplay during rendering.
|
// NoteDisplay during rendering.
|
||||||
struct NoteDisplayRenderArgs
|
struct CommonColumnRenderArgs
|
||||||
{
|
{
|
||||||
NoteData const& note_data;
|
ReceptorArrowRow* receptor_row;
|
||||||
int column;
|
GhostArrowRow* ghost_row;
|
||||||
|
NoteData const* note_data;
|
||||||
|
int first_row;
|
||||||
|
int last_row;
|
||||||
int draw_pixels_before_targets;
|
int draw_pixels_before_targets;
|
||||||
int draw_pixels_after_targets;
|
int draw_pixels_after_targets;
|
||||||
int selection_begin_marker;
|
int* selection_begin_marker;
|
||||||
int selection_end_marker;
|
int* selection_end_marker;
|
||||||
float selection_glow;
|
float selection_glow;
|
||||||
float fail_fade;
|
float fail_fade;
|
||||||
float fade_before_targets;
|
float fade_before_targets;
|
||||||
GhostArrowRow& ghost_row;
|
|
||||||
NoteDisplayRenderArgs(NoteData const& nd, int dpbt, int dpat, int sbm,
|
|
||||||
int sem, float sg, float ff, float fbt, GhostArrowRow& gr)
|
|
||||||
:note_data(nd), column(0),
|
|
||||||
draw_pixels_before_targets(dpbt), draw_pixels_after_targets(dpat),
|
|
||||||
selection_begin_marker(sbm), selection_end_marker(sem),
|
|
||||||
selection_glow(sg), fail_fade(ff), fade_before_targets(fbt), ghost_row(gr)
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** @brief Draws TapNotes and HoldNotes. */
|
/** @brief Draws TapNotes and HoldNotes. */
|
||||||
class NoteDisplay
|
class NoteDisplay
|
||||||
{
|
{
|
||||||
@@ -122,9 +117,9 @@ public:
|
|||||||
|
|
||||||
bool IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const;
|
bool IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const;
|
||||||
|
|
||||||
bool DrawHoldsInRange(NoteDisplayRenderArgs const& args,
|
bool DrawHoldsInRange(CommonColumnRenderArgs const& args, int column,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
||||||
bool DrawTapsInRange(NoteDisplayRenderArgs const& args,
|
bool DrawTapsInRange(CommonColumnRenderArgs const& args, int column,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
||||||
/**
|
/**
|
||||||
* @brief Draw the TapNote onto the NoteField.
|
* @brief Draw the TapNote onto the NoteField.
|
||||||
@@ -184,6 +179,25 @@ private:
|
|||||||
float m_fYReverseOffsetPixels;
|
float m_fYReverseOffsetPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// So, this is a bit screwy, and it's all 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
|
||||||
|
class NoteColumnRenderer : public ActorFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NoteDisplay* m_displays[PLAYER_INVALID+1];
|
||||||
|
CommonColumnRenderArgs* m_render_args;
|
||||||
|
int m_column;
|
||||||
|
|
||||||
|
virtual void DrawPrimitives();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+89
-102
@@ -61,9 +61,13 @@ NoteField::NoteField()
|
|||||||
m_sprBeatBars.Load( THEME->GetPathG("NoteField","bars") );
|
m_sprBeatBars.Load( THEME->GetPathG("NoteField","bars") );
|
||||||
m_sprBeatBars.StopAnimating();
|
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_ColumnRenderArgs.selection_begin_marker= &m_iBeginMarker;
|
||||||
|
m_ColumnRenderArgs.selection_end_marker= &m_iEndMarker;
|
||||||
m_iBeginMarker = m_iEndMarker = -1;
|
m_iBeginMarker = m_iEndMarker = -1;
|
||||||
|
|
||||||
m_fPercentFadeToFail = -1;
|
m_ColumnRenderArgs.fail_fade = -1;
|
||||||
|
|
||||||
m_StepCallback.SetFromNil();
|
m_StepCallback.SetFromNil();
|
||||||
m_SetPressedCallback.SetFromNil();
|
m_SetPressedCallback.SetFromNil();
|
||||||
@@ -166,6 +170,8 @@ void NoteField::CacheAllUsedNoteSkins()
|
|||||||
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
||||||
m_pDisplays[pn] = it->second;
|
m_pDisplays[pn] = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitColumnRenderers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteField::Init( const PlayerState* pPlayerState, float fYReverseOffsetPixels )
|
void NoteField::Init( const PlayerState* pPlayerState, float fYReverseOffsetPixels )
|
||||||
@@ -186,7 +192,7 @@ void NoteField::Load(
|
|||||||
m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels;
|
m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels;
|
||||||
ASSERT( m_iDrawDistanceBeforeTargetsPixels >= m_iDrawDistanceAfterTargetsPixels );
|
ASSERT( m_iDrawDistanceBeforeTargetsPixels >= m_iDrawDistanceAfterTargetsPixels );
|
||||||
|
|
||||||
m_fPercentFadeToFail = -1;
|
m_ColumnRenderArgs.fail_fade = -1;
|
||||||
|
|
||||||
//int i1 = m_pNoteData->GetNumTracks();
|
//int i1 = m_pNoteData->GetNumTracks();
|
||||||
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
|
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
|
||||||
@@ -237,6 +243,27 @@ void NoteField::Load(
|
|||||||
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
|
||||||
m_pDisplays[pn] = it->second;
|
m_pDisplays[pn] = it->second;
|
||||||
}
|
}
|
||||||
|
InitColumnRenderers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NoteField::InitColumnRenderers()
|
||||||
|
{
|
||||||
|
m_ColumnRenderArgs.receptor_row= &(m_pCurDisplay->m_ReceptorArrowRow);
|
||||||
|
m_ColumnRenderArgs.ghost_row= &(m_pCurDisplay->m_GhostArrowRow);
|
||||||
|
m_ColumnRenderArgs.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_render_args= &m_ColumnRenderArgs;
|
||||||
|
}
|
||||||
|
m_pCurDisplay->m_ReceptorArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||||
|
m_pCurDisplay->m_GhostArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteField::Update( float fDeltaTime )
|
void NoteField::Update( float fDeltaTime )
|
||||||
@@ -248,6 +275,11 @@ void NoteField::Update( float fDeltaTime )
|
|||||||
|
|
||||||
ActorFrame::Update( 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
|
// update m_fBoardOffsetPixels, m_fCurrentBeatLastUpdate, m_fYPosCurrentBeatLastUpdate
|
||||||
const float fCurrentBeat = m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
const float fCurrentBeat = m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||||
bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK
|
bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK
|
||||||
@@ -273,11 +305,11 @@ void NoteField::Update( float fDeltaTime )
|
|||||||
cur->m_ReceptorArrowRow.Update( fDeltaTime );
|
cur->m_ReceptorArrowRow.Update( fDeltaTime );
|
||||||
cur->m_GhostArrowRow.Update( fDeltaTime );
|
cur->m_GhostArrowRow.Update( fDeltaTime );
|
||||||
|
|
||||||
if( m_fPercentFadeToFail >= 0 )
|
if( m_ColumnRenderArgs.fail_fade >= 0 )
|
||||||
m_fPercentFadeToFail = min( m_fPercentFadeToFail + fDeltaTime/FADE_FAIL_TIME, 1 );
|
m_ColumnRenderArgs.fail_fade = min( m_ColumnRenderArgs.fail_fade + fDeltaTime/FADE_FAIL_TIME, 1 );
|
||||||
|
|
||||||
// Update fade to failed
|
// Update fade to failed
|
||||||
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_fPercentFadeToFail );
|
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_ColumnRenderArgs.fail_fade );
|
||||||
|
|
||||||
NoteDisplay::Update( fDeltaTime );
|
NoteDisplay::Update( fDeltaTime );
|
||||||
/* Update all NoteDisplays. Hack: We need to call this once per frame, not
|
/* Update all NoteDisplays. Hack: We need to call this once per frame, not
|
||||||
@@ -829,41 +861,41 @@ void NoteField::DrawPrimitives()
|
|||||||
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
||||||
|
|
||||||
// Adjust draw range depending on some effects
|
// Adjust draw range depending on some effects
|
||||||
int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels;
|
m_ColumnRenderArgs.draw_pixels_after_targets= m_iDrawDistanceAfterTargetsPixels;
|
||||||
// HACK: If boomerang and centered are on, then we want to draw much
|
// HACK: If boomerang and centered are on, then we want to draw much
|
||||||
// earlier so that the notes don't pop on screen.
|
// earlier so that the notes don't pop on screen.
|
||||||
float fCenteredTimesBoomerang =
|
float fCenteredTimesBoomerang =
|
||||||
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
|
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
|
||||||
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
||||||
iDrawDistanceAfterTargetsPixels += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
m_ColumnRenderArgs.draw_pixels_after_targets += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
||||||
int iDrawDistanceBeforeTargetsPixels = m_iDrawDistanceBeforeTargetsPixels;
|
m_ColumnRenderArgs.draw_pixels_before_targets = m_iDrawDistanceBeforeTargetsPixels;
|
||||||
|
|
||||||
float fDrawScale = 1;
|
float fDrawScale = 1;
|
||||||
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
||||||
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_MINI] );
|
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_MINI] );
|
||||||
|
|
||||||
iDrawDistanceAfterTargetsPixels = (int)(iDrawDistanceAfterTargetsPixels * fDrawScale);
|
m_ColumnRenderArgs.draw_pixels_after_targets = (int)(m_ColumnRenderArgs.draw_pixels_after_targets * fDrawScale);
|
||||||
iDrawDistanceBeforeTargetsPixels = (int)(iDrawDistanceBeforeTargetsPixels * fDrawScale);
|
m_ColumnRenderArgs.draw_pixels_before_targets = (int)(m_ColumnRenderArgs.draw_pixels_before_targets * fDrawScale);
|
||||||
|
|
||||||
|
|
||||||
// Probe for first and last notes on the screen
|
// Probe for first and last notes on the screen
|
||||||
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, iDrawDistanceAfterTargetsPixels );
|
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, m_ColumnRenderArgs.draw_pixels_after_targets );
|
||||||
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, iDrawDistanceBeforeTargetsPixels );
|
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, m_ColumnRenderArgs.draw_pixels_before_targets );
|
||||||
|
|
||||||
m_pPlayerState->m_fLastDrawnBeat = fLastBeatToDraw;
|
m_pPlayerState->m_fLastDrawnBeat = fLastBeatToDraw;
|
||||||
|
|
||||||
const int iFirstRowToDraw = BeatToNoteRow(fFirstBeatToDraw);
|
m_ColumnRenderArgs.first_row = BeatToNoteRow(fFirstBeatToDraw);
|
||||||
const int iLastRowToDraw = BeatToNoteRow(fLastBeatToDraw);
|
m_ColumnRenderArgs.last_row = BeatToNoteRow(fLastBeatToDraw);
|
||||||
|
|
||||||
//LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
|
//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_ColumnRenderArgs.first_row, m_ColumnRenderArgs.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_ColumnRenderArgs.draw_pixels_after_targets, m_ColumnRenderArgs.draw_pixels_before_targets ) )
|
||||||
|
|
||||||
// Draw board
|
// Draw board
|
||||||
if( SHOW_BOARD )
|
if( SHOW_BOARD )
|
||||||
{
|
{
|
||||||
DrawBoard( iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels );
|
DrawBoard( m_ColumnRenderArgs.draw_pixels_after_targets, m_ColumnRenderArgs.draw_pixels_before_targets );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Receptors
|
// Draw Receptors
|
||||||
@@ -886,7 +918,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < tSigs.size(); i++)
|
for (i = 0; i < tSigs.size(); i++)
|
||||||
{
|
{
|
||||||
const TimeSignatureSegment *ts = ToTimeSignature(tSigs[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_ColumnRenderArgs.last_row : tSigs[i+1]->GetRow();
|
||||||
|
|
||||||
// beat bars every 16th note
|
// beat bars every 16th note
|
||||||
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
|
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
|
||||||
@@ -929,7 +961,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
||||||
{
|
{
|
||||||
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -941,7 +973,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
||||||
{
|
{
|
||||||
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -953,7 +985,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
||||||
{
|
{
|
||||||
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -965,7 +997,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
||||||
{
|
{
|
||||||
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -977,7 +1009,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
||||||
{
|
{
|
||||||
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -989,7 +1021,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
||||||
{
|
{
|
||||||
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1001,7 +1033,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
||||||
{
|
{
|
||||||
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1013,7 +1045,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
||||||
{
|
{
|
||||||
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1025,7 +1057,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
||||||
{
|
{
|
||||||
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1037,7 +1069,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
||||||
{
|
{
|
||||||
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1050,7 +1082,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
||||||
{
|
{
|
||||||
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
||||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1070,8 +1102,8 @@ void NoteField::DrawPrimitives()
|
|||||||
float fSecond = a->fStartSecond;
|
float fSecond = a->fStartSecond;
|
||||||
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
||||||
|
|
||||||
if( BeatToNoteRow(fBeat) >= iFirstRowToDraw &&
|
if( BeatToNoteRow(fBeat) >= m_ColumnRenderArgs.first_row &&
|
||||||
BeatToNoteRow(fBeat) <= iLastRowToDraw)
|
BeatToNoteRow(fBeat) <= m_ColumnRenderArgs.last_row)
|
||||||
{
|
{
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
DrawAttackText( fBeat, *a );
|
DrawAttackText( fBeat, *a );
|
||||||
@@ -1089,8 +1121,8 @@ void NoteField::DrawPrimitives()
|
|||||||
FOREACH_CONST(Attack, attacks, a)
|
FOREACH_CONST(Attack, attacks, a)
|
||||||
{
|
{
|
||||||
float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond);
|
float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond);
|
||||||
if (BeatToNoteRow(fBeat) >= iFirstRowToDraw &&
|
if (BeatToNoteRow(fBeat) >= m_ColumnRenderArgs.first_row &&
|
||||||
BeatToNoteRow(fBeat) <= iLastRowToDraw &&
|
BeatToNoteRow(fBeat) <= m_ColumnRenderArgs.last_row &&
|
||||||
IS_ON_SCREEN(fBeat))
|
IS_ON_SCREEN(fBeat))
|
||||||
{
|
{
|
||||||
this->DrawAttackText(fBeat, *a);
|
this->DrawAttackText(fBeat, *a);
|
||||||
@@ -1174,20 +1206,20 @@ void NoteField::DrawPrimitives()
|
|||||||
{
|
{
|
||||||
int iBegin = m_iBeginMarker;
|
int iBegin = m_iBeginMarker;
|
||||||
int iEnd = m_iEndMarker;
|
int iEnd = m_iEndMarker;
|
||||||
CLAMP( iBegin, iFirstRowToDraw, iLastRowToDraw );
|
CLAMP( iBegin, m_ColumnRenderArgs.first_row, m_ColumnRenderArgs.last_row );
|
||||||
CLAMP( iEnd, iFirstRowToDraw, iLastRowToDraw );
|
CLAMP( iEnd, m_ColumnRenderArgs.first_row, m_ColumnRenderArgs.last_row );
|
||||||
DrawAreaHighlight( iBegin, iEnd );
|
DrawAreaHighlight( iBegin, iEnd );
|
||||||
}
|
}
|
||||||
else if( m_iBeginMarker != -1 )
|
else if( m_iBeginMarker != -1 )
|
||||||
{
|
{
|
||||||
if( m_iBeginMarker >= iFirstRowToDraw &&
|
if( m_iBeginMarker >= m_ColumnRenderArgs.first_row &&
|
||||||
m_iBeginMarker <= iLastRowToDraw )
|
m_iBeginMarker <= m_ColumnRenderArgs.last_row )
|
||||||
DrawMarkerBar( m_iBeginMarker );
|
DrawMarkerBar( m_iBeginMarker );
|
||||||
}
|
}
|
||||||
else if( m_iEndMarker != -1 )
|
else if( m_iEndMarker != -1 )
|
||||||
{
|
{
|
||||||
if( m_iEndMarker >= iFirstRowToDraw &&
|
if( m_iEndMarker >= m_ColumnRenderArgs.first_row &&
|
||||||
m_iEndMarker <= iLastRowToDraw )
|
m_iEndMarker <= m_ColumnRenderArgs.last_row )
|
||||||
DrawMarkerBar( m_iEndMarker );
|
DrawMarkerBar( m_iEndMarker );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1196,76 +1228,19 @@ void NoteField::DrawPrimitives()
|
|||||||
// Draw the arrows in order of column. This minimizes texture switches and
|
// Draw the arrows in order of column. This minimizes texture switches and
|
||||||
// lets us draw in big batches.
|
// lets us draw in big batches.
|
||||||
|
|
||||||
float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f );
|
|
||||||
|
|
||||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
||||||
ASSERT_M(m_pNoteData->GetNumTracks() == GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer,
|
ASSERT_M(m_pNoteData->GetNumTracks() == GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer,
|
||||||
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
|
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
|
||||||
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
|
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
|
||||||
|
|
||||||
NoteDisplayRenderArgs display_args(*m_pNoteData,
|
m_ColumnRenderArgs.selection_glow= SCALE(
|
||||||
iDrawDistanceBeforeTargetsPixels,
|
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
|
||||||
iDrawDistanceAfterTargetsPixels, m_iBeginMarker, m_iEndMarker,
|
m_ColumnRenderArgs.fade_before_targets= FADE_BEFORE_TARGETS_PERCENT;
|
||||||
fSelectedRangeGlow, m_fPercentFadeToFail, FADE_BEFORE_TARGETS_PERCENT,
|
|
||||||
m_pCurDisplay->m_GhostArrowRow);
|
|
||||||
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
|
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
|
||||||
{
|
{
|
||||||
const int c = pStyle->m_iColumnDrawOrder[j];
|
const int c = pStyle->m_iColumnDrawOrder[j];
|
||||||
display_args.column= c;
|
m_ColumnRenderers[c].Draw();
|
||||||
bool any_upcoming= false;
|
|
||||||
// Build lists of holds and taps for each player number, then pass those
|
|
||||||
// lists to the displays to draw.
|
|
||||||
// The vector in the NUM_PlayerNumber slot should stay empty, not worth
|
|
||||||
// optimizing it out. -Kyz
|
|
||||||
vector<vector<NoteData::TrackMap::const_iterator> > holds(PLAYER_INVALID+1);
|
|
||||||
vector<vector<NoteData::TrackMap::const_iterator> > taps(PLAYER_INVALID+1);
|
|
||||||
NoteData::TrackMap::const_iterator begin, end;
|
|
||||||
m_pNoteData->GetTapNoteRangeInclusive(c, iFirstRowToDraw,
|
|
||||||
iLastRowToDraw+1, begin, end);
|
|
||||||
for(; begin != end; ++begin)
|
|
||||||
{
|
|
||||||
TapNote const& tn= begin->second;
|
|
||||||
switch(tn.type)
|
|
||||||
{
|
|
||||||
case TapNoteType_Empty:
|
|
||||||
continue;
|
|
||||||
case TapNoteType_Tap:
|
|
||||||
case TapNoteType_HoldTail:
|
|
||||||
case TapNoteType_Mine:
|
|
||||||
case TapNoteType_Lift:
|
|
||||||
case TapNoteType_Attack:
|
|
||||||
case TapNoteType_AutoKeysound:
|
|
||||||
case TapNoteType_Fake:
|
|
||||||
if(!tn.result.bHidden)
|
|
||||||
{
|
|
||||||
taps[tn.pn].push_back(begin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TapNoteType_HoldHead:
|
|
||||||
if(tn.HoldResult.hns != HNS_Held)
|
|
||||||
{
|
|
||||||
holds[tn.pn].push_back(begin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define DTS_INNER(pn, tap_set, draw_func, disp) \
|
|
||||||
if(!tap_set[pn].empty()) \
|
|
||||||
{ \
|
|
||||||
any_upcoming|= disp->display[c].draw_func(display_args, tap_set[pn]); \
|
|
||||||
}
|
|
||||||
#define DRAW_TAP_SET(tap_set, draw_func) \
|
|
||||||
FOREACH_PlayerNumber(pn) \
|
|
||||||
{ \
|
|
||||||
DTS_INNER(pn, tap_set, draw_func, m_pDisplays[pn]); \
|
|
||||||
}
|
|
||||||
DRAW_TAP_SET(holds, DrawHoldsInRange);
|
|
||||||
DTS_INNER(PLAYER_INVALID, holds, DrawHoldsInRange, m_pCurDisplay);
|
|
||||||
DRAW_TAP_SET(taps, DrawTapsInRange);
|
|
||||||
DTS_INNER(PLAYER_INVALID, taps, DrawTapsInRange, m_pCurDisplay);
|
|
||||||
#undef DTS_INNER
|
|
||||||
#undef DRAW_TAP_SET
|
|
||||||
cur->m_ReceptorArrowRow.SetNoteUpcoming(c, any_upcoming);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->m_GhostArrowRow.Draw();
|
cur->m_GhostArrowRow.Draw();
|
||||||
@@ -1273,7 +1248,7 @@ void NoteField::DrawPrimitives()
|
|||||||
|
|
||||||
void NoteField::FadeToFail()
|
void NoteField::FadeToFail()
|
||||||
{
|
{
|
||||||
m_fPercentFadeToFail = max( 0.0f, m_fPercentFadeToFail ); // this will slowly increase every Update()
|
m_ColumnRenderArgs.fail_fade = max( 0.0f, m_ColumnRenderArgs.fail_fade ); // this will slowly increase every Update()
|
||||||
// don't fade all over again if this is called twice
|
// don't fade all over again if this is called twice
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1471,6 +1446,17 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int GetColumnActors(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()
|
LunaNoteField()
|
||||||
{
|
{
|
||||||
ADD_METHOD(SetStepCallback);
|
ADD_METHOD(SetStepCallback);
|
||||||
@@ -1481,6 +1467,7 @@ public:
|
|||||||
ADD_METHOD(SetPressed);
|
ADD_METHOD(SetPressed);
|
||||||
ADD_METHOD(DidTapNote);
|
ADD_METHOD(DidTapNote);
|
||||||
ADD_METHOD(DidHoldNote);
|
ADD_METHOD(DidHoldNote);
|
||||||
|
ADD_METHOD(GetColumnActors);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -29,6 +29,8 @@ public:
|
|||||||
int iDrawDistanceBeforeTargetsPixels );
|
int iDrawDistanceBeforeTargetsPixels );
|
||||||
virtual void Unload();
|
virtual void Unload();
|
||||||
|
|
||||||
|
void InitColumnRenderers();
|
||||||
|
|
||||||
virtual void HandleMessage( const Message &msg );
|
virtual void HandleMessage( const Message &msg );
|
||||||
|
|
||||||
// This is done automatically by Init(), but can be re-called explicitly if the
|
// 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
|
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:
|
protected:
|
||||||
void CacheNoteSkin( const RString &sNoteSkin );
|
void CacheNoteSkin( const RString &sNoteSkin );
|
||||||
void UncacheNoteSkin( const RString &sNoteSkin );
|
void UncacheNoteSkin( const RString &sNoteSkin );
|
||||||
@@ -84,8 +90,6 @@ protected:
|
|||||||
|
|
||||||
const NoteData *m_pNoteData;
|
const NoteData *m_pNoteData;
|
||||||
|
|
||||||
float m_fPercentFadeToFail; // -1 if not fading to fail
|
|
||||||
|
|
||||||
const PlayerState* m_pPlayerState;
|
const PlayerState* m_pPlayerState;
|
||||||
int m_iDrawDistanceAfterTargetsPixels; // this should be a negative number
|
int m_iDrawDistanceAfterTargetsPixels; // this should be a negative number
|
||||||
int m_iDrawDistanceBeforeTargetsPixels; // this should be a positive number
|
int m_iDrawDistanceBeforeTargetsPixels; // this should be a positive number
|
||||||
@@ -101,6 +105,8 @@ protected:
|
|||||||
~NoteDisplayCols() { delete [] display; }
|
~NoteDisplayCols() { delete [] display; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CommonColumnRenderArgs m_ColumnRenderArgs;
|
||||||
|
|
||||||
/* All loaded note displays, mapped by their name. */
|
/* All loaded note displays, mapped by their name. */
|
||||||
map<RString, NoteDisplayCols *> m_NoteDisplays;
|
map<RString, NoteDisplayCols *> m_NoteDisplays;
|
||||||
NoteDisplayCols *m_pCurDisplay;
|
NoteDisplayCols *m_pCurDisplay;
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ 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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReceptorArrowRow::~ReceptorArrowRow()
|
ReceptorArrowRow::~ReceptorArrowRow()
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < m_ReceptorArrow.size(); ++i )
|
for( unsigned i = 0; i < m_ReceptorArrow.size(); ++i )
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "ReceptorArrow.h"
|
#include "ReceptorArrow.h"
|
||||||
#include "ActorFrame.h"
|
#include "ActorFrame.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
|
#include "NoteDisplay.h"
|
||||||
|
|
||||||
class PlayerState;
|
class PlayerState;
|
||||||
/** @brief A row of ReceptorArrow objects. */
|
/** @brief A row of ReceptorArrow objects. */
|
||||||
@@ -16,6 +17,7 @@ public:
|
|||||||
virtual void DrawPrimitives();
|
virtual void DrawPrimitives();
|
||||||
|
|
||||||
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
void Load( const PlayerState* pPlayerState, float fYReverseOffset );
|
||||||
|
void SetColumnRenderers(vector<NoteColumnRenderer>& renderers);
|
||||||
|
|
||||||
void Step( int iCol, TapNoteScore score );
|
void Step( int iCol, TapNoteScore score );
|
||||||
void SetPressed( int iCol );
|
void SetPressed( int iCol );
|
||||||
|
|||||||
Reference in New Issue
Block a user