Implement RADAR_NUM_HANDS result.
Change hold note contents to rows (from beats). This makes it consistent with tap note data. Row numbers are also generally more precise, since they're integers, not floats.
This commit is contained in:
+80
-62
@@ -224,7 +224,7 @@ int NoteData::GetFirstTrackWithTapOrHoldHead( int index ) const
|
||||
|
||||
void NoteData::AddHoldNote( HoldNote add )
|
||||
{
|
||||
ASSERT( add.fStartBeat>=0 && add.fEndBeat>=0 );
|
||||
ASSERT( add.iStartRow>=0 && add.iEndRow>=0 );
|
||||
|
||||
int i;
|
||||
|
||||
@@ -235,17 +235,10 @@ void NoteData::AddHoldNote( HoldNote add )
|
||||
{
|
||||
HoldNote &other = GetHoldNote(i);
|
||||
if( add.iTrack == other.iTrack && // the tracks correspond
|
||||
// they overlap
|
||||
(
|
||||
( other.fStartBeat <= add.fStartBeat && other.fEndBeat >= add.fEndBeat ) || // other consumes add
|
||||
( other.fStartBeat >= add.fStartBeat && other.fEndBeat <= add.fEndBeat ) || // other inside add
|
||||
( add.fStartBeat <= other.fStartBeat && other.fStartBeat <= add.fEndBeat ) || // other overlaps add
|
||||
( add.fStartBeat <= other.fEndBeat && other.fEndBeat <= add.fEndBeat ) // other overlaps add
|
||||
)
|
||||
)
|
||||
add.RangeOverlaps(other) ) // they overlap
|
||||
{
|
||||
add.fStartBeat = min(add.fStartBeat, other.fStartBeat);
|
||||
add.fEndBeat = max(add.fEndBeat, other.fEndBeat);
|
||||
add.iStartRow = min(add.iStartRow, other.iStartRow);
|
||||
add.iEndRow = max(add.iEndRow, other.iEndRow);
|
||||
|
||||
// delete this HoldNote
|
||||
RemoveHoldNote( i );
|
||||
@@ -253,8 +246,8 @@ void NoteData::AddHoldNote( HoldNote add )
|
||||
}
|
||||
}
|
||||
|
||||
int iAddStartIndex = BeatToNoteRow(add.fStartBeat);
|
||||
int iAddEndIndex = BeatToNoteRow(add.fEndBeat);
|
||||
int iAddStartIndex = add.iStartRow;
|
||||
int iAddEndIndex = add.iEndRow;
|
||||
|
||||
// delete TapNotes under this HoldNote
|
||||
for( i=iAddStartIndex+1; i<=iAddEndIndex; i++ )
|
||||
@@ -272,7 +265,7 @@ void NoteData::RemoveHoldNote( int iHoldIndex )
|
||||
|
||||
HoldNote& hn = GetHoldNote(iHoldIndex);
|
||||
|
||||
int iHoldStartIndex = BeatToNoteRow(hn.fStartBeat);
|
||||
const int iHoldStartIndex = hn.iStartRow;
|
||||
|
||||
// delete a tap note at the start of this hold
|
||||
SetTapNote(hn.iTrack, iHoldStartIndex, TAP_EMPTY);
|
||||
@@ -344,45 +337,40 @@ const Attack& NoteData::GetAttackAt( int track, int row )
|
||||
|
||||
int NoteData::GetFirstRow() const
|
||||
{
|
||||
return BeatToNoteRow( GetFirstBeat() );
|
||||
}
|
||||
|
||||
float NoteData::GetFirstBeat() const
|
||||
{
|
||||
float fEarliestBeatFoundSoFar = -1;
|
||||
int iEarliestRowFoundSoFar = -1;
|
||||
|
||||
int i;
|
||||
|
||||
for( i=0; i <= int(m_TapNotes[0].size()); i++ )
|
||||
for( i=0; i < int(m_TapNotes[0].size()); i++ )
|
||||
{
|
||||
if( !IsRowEmpty(i) )
|
||||
{
|
||||
fEarliestBeatFoundSoFar = NoteRowToBeat(i);
|
||||
iEarliestRowFoundSoFar = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
if( fEarliestBeatFoundSoFar == -1 ||
|
||||
GetHoldNote(i).fStartBeat < fEarliestBeatFoundSoFar )
|
||||
fEarliestBeatFoundSoFar = GetHoldNote(i).fStartBeat;
|
||||
if( iEarliestRowFoundSoFar == -1 ||
|
||||
GetHoldNote(i).iStartRow < iEarliestRowFoundSoFar )
|
||||
iEarliestRowFoundSoFar = GetHoldNote(i).iStartRow;
|
||||
}
|
||||
|
||||
if( fEarliestBeatFoundSoFar == -1 ) // there are no notes
|
||||
if( iEarliestRowFoundSoFar == -1 ) // there are no notes
|
||||
return 0;
|
||||
|
||||
return fEarliestBeatFoundSoFar;
|
||||
return iEarliestRowFoundSoFar;
|
||||
}
|
||||
|
||||
float NoteData::GetFirstBeat() const
|
||||
{
|
||||
return NoteRowToBeat( GetFirstRow() );
|
||||
}
|
||||
|
||||
int NoteData::GetLastRow() const
|
||||
{
|
||||
return BeatToNoteRow( GetLastBeat() );
|
||||
}
|
||||
|
||||
float NoteData::GetLastBeat() const
|
||||
{
|
||||
float fOldestBeatFoundSoFar = 0;
|
||||
int iOldestRowFoundSoFar = 0;
|
||||
|
||||
int i;
|
||||
|
||||
@@ -390,18 +378,23 @@ float NoteData::GetLastBeat() const
|
||||
{
|
||||
if( !IsRowEmpty(i) )
|
||||
{
|
||||
fOldestBeatFoundSoFar = NoteRowToBeat(i);
|
||||
iOldestRowFoundSoFar = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
if( GetHoldNote(i).fEndBeat > fOldestBeatFoundSoFar )
|
||||
fOldestBeatFoundSoFar = GetHoldNote(i).fEndBeat;
|
||||
if( GetHoldNote(i).iEndRow > iOldestRowFoundSoFar )
|
||||
iOldestRowFoundSoFar = GetHoldNote(i).iEndRow;
|
||||
}
|
||||
|
||||
return fOldestBeatFoundSoFar;
|
||||
return iOldestRowFoundSoFar;
|
||||
}
|
||||
|
||||
float NoteData::GetLastBeat() const
|
||||
{
|
||||
return NoteRowToBeat( GetLastRow() );
|
||||
}
|
||||
|
||||
int NoteData::GetNumTapNotes( float fStartBeat, float fEndBeat ) const
|
||||
@@ -487,13 +480,13 @@ int NoteData::GetNumRowsWithTapOrHoldHead( float fStartBeat, float fEndBeat ) co
|
||||
|
||||
int NoteData::GetNumHands( float fStartBeat, float fEndBeat ) const
|
||||
{
|
||||
/* We want to count both three taps at the same time, a tap while two
|
||||
* hold notes are being held, etc. */
|
||||
NoteData temp;
|
||||
temp.To4s( *this );
|
||||
|
||||
/* Count the number of times you have to use your hands. This includes
|
||||
* three taps at the same time, a tap while two hold notes are being held,
|
||||
* etc. Only count rows that have at least one tap note (hold heads count).
|
||||
* Otherwise, every row of hold notes counts, so three simultaneous hold
|
||||
* notes will count as hundreds of "hands". */
|
||||
if( fEndBeat == -1 )
|
||||
fEndBeat = temp.GetMaxBeat();
|
||||
fEndBeat = GetMaxBeat();
|
||||
|
||||
int iStartIndex = BeatToNoteRow( fStartBeat );
|
||||
int iEndIndex = BeatToNoteRow( fEndBeat );
|
||||
@@ -502,20 +495,46 @@ int NoteData::GetNumHands( float fStartBeat, float fEndBeat ) const
|
||||
iStartIndex = max( iStartIndex, 0 );
|
||||
iEndIndex = min( iEndIndex, GetMaxRow()-1 );
|
||||
|
||||
// vector<int> HoldsAtRow;
|
||||
// HoldsAtRow.insert( HoldsAtRow.begin(), iEndIndex-iStartIndex+1, 0 );
|
||||
int i;
|
||||
// for( i=0; i<GetNumHoldNotes(); i++ )
|
||||
// {
|
||||
// /* Skip the first row of each hold, since there's also a TAP_HOLD_HEAD there. */
|
||||
// const HoldNote &hn = GetHoldNote(i);
|
||||
// for( int row = hn.iStartRow+1; row < hn.iEndRow; ++row )
|
||||
// ++HoldsAtRow[row-iStartIndex];
|
||||
// }
|
||||
|
||||
int iNum = 0;
|
||||
for( int i=iStartIndex; i<=iEndIndex; i++ )
|
||||
for( i=iStartIndex; i<=iEndIndex; i++ )
|
||||
{
|
||||
int iNumNotesThisIndex = 0;
|
||||
for( int t=0; t<m_iNumTracks; t++ )
|
||||
{
|
||||
TapNote tn = temp.GetTapNoteX(t, i);
|
||||
TapNote tn = GetTapNoteX(t, i);
|
||||
if( tn != TAP_MINE && tn != TAP_EMPTY ) // mines don't count
|
||||
iNumNotesThisIndex++;
|
||||
}
|
||||
/* We must have at least one non-hold-body at this row to count it. */
|
||||
if( !iNumNotesThisIndex )
|
||||
continue;
|
||||
if( iNumNotesThisIndex < 3 )
|
||||
{
|
||||
/* We have at least one, but not enough. Count holds. */
|
||||
for( int j=0; j<GetNumHoldNotes(); j++ )
|
||||
{
|
||||
const HoldNote &hn = GetHoldNote(j);
|
||||
if( hn.iStartRow+1 <= j && j <= hn.iEndRow )
|
||||
iNumNotesThisIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// iNumNotesThisIndex += HoldsAtRow[i-iStartIndex];
|
||||
if( iNumNotesThisIndex >= 3 )
|
||||
iNum++;
|
||||
}
|
||||
|
||||
LOG->Trace("xxxxxx %i", iNum);
|
||||
return iNum;
|
||||
}
|
||||
|
||||
@@ -550,13 +569,16 @@ int NoteData::GetNumN( int MinTaps, float fStartBeat, float fEndBeat ) const
|
||||
|
||||
int NoteData::GetNumHoldNotes( float fStartBeat, float fEndBeat ) const
|
||||
{
|
||||
int iNumHolds = 0;
|
||||
if( fEndBeat == -1 )
|
||||
fEndBeat = GetMaxBeat();
|
||||
int iStartIndex = BeatToNoteRow( fStartBeat );
|
||||
int iEndIndex = BeatToNoteRow( fEndBeat );
|
||||
|
||||
if(fEndBeat == -1) fEndBeat = GetMaxBeat();
|
||||
int iNumHolds = 0;
|
||||
for( int i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
const HoldNote &hn = GetHoldNote(i);
|
||||
if( fStartBeat <= hn.fStartBeat && hn.fEndBeat <= fEndBeat )
|
||||
if( iStartIndex <= hn.iStartRow && hn.iEndRow <= iEndIndex )
|
||||
iNumHolds++;
|
||||
}
|
||||
return iNumHolds;
|
||||
@@ -584,7 +606,7 @@ void NoteData::Convert2sAnd3sToHoldNotes()
|
||||
|
||||
SetTapNote(col, j, TAP_EMPTY);
|
||||
|
||||
AddHoldNote( HoldNote(col, NoteRowToBeat(i), NoteRowToBeat(j)) );
|
||||
AddHoldNote( HoldNote(col, i, j) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -600,13 +622,12 @@ void NoteData::ConvertHoldNotesTo2sAnd3s()
|
||||
for( int i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
const HoldNote &hn = GetHoldNote(i);
|
||||
int iHoldStartIndex = max(BeatToNoteRow(hn.fStartBeat), 0);
|
||||
int iHoldEndIndex = max(BeatToNoteRow(hn.fEndBeat), 0);
|
||||
|
||||
/* If they're the same, then they got clamped together, so just ignore it. */
|
||||
if(iHoldStartIndex != iHoldEndIndex) {
|
||||
SetTapNote(hn.iTrack, iHoldStartIndex, TAP_HOLD_HEAD);
|
||||
SetTapNote(hn.iTrack, iHoldEndIndex, TAP_HOLD_TAIL);
|
||||
if( hn.iStartRow != hn.iEndRow )
|
||||
{
|
||||
SetTapNote( hn.iTrack, hn.iStartRow, TAP_HOLD_HEAD );
|
||||
SetTapNote( hn.iTrack, hn.iEndRow, TAP_HOLD_TAIL );
|
||||
}
|
||||
}
|
||||
m_HoldNotes.clear();
|
||||
@@ -653,7 +674,7 @@ void NoteData::Convert4sToHoldNotes()
|
||||
if( GetTapNote(col, i) != TAP_HOLD ) // this is a HoldNote body
|
||||
continue;
|
||||
|
||||
HoldNote hn( col, NoteRowToBeat(i), 0 );
|
||||
HoldNote hn( col, i, 0 );
|
||||
// search for end of HoldNote
|
||||
do {
|
||||
SetTapNote(col, i, TAP_EMPTY);
|
||||
@@ -661,7 +682,7 @@ void NoteData::Convert4sToHoldNotes()
|
||||
} while( GetTapNote(col, i) == TAP_HOLD);
|
||||
SetTapNote(col, i, TAP_EMPTY);
|
||||
|
||||
hn.fEndBeat = NoteRowToBeat(i);
|
||||
hn.iEndRow = i;
|
||||
AddHoldNote( hn );
|
||||
}
|
||||
}
|
||||
@@ -673,10 +694,8 @@ void NoteData::ConvertHoldNotesTo4s()
|
||||
for( int i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
const HoldNote &hn = GetHoldNote(i);
|
||||
int iHoldStartIndex = max(BeatToNoteRow(hn.fStartBeat), 0);
|
||||
int iHoldEndIndex = max(BeatToNoteRow(hn.fEndBeat), 0);
|
||||
|
||||
for( int j = iHoldStartIndex; j < iHoldEndIndex; ++j)
|
||||
for( int j = hn.iStartRow; j < hn.iEndRow; ++j)
|
||||
SetTapNote(hn.iTrack, j, TAP_HOLD);
|
||||
}
|
||||
m_HoldNotes.clear();
|
||||
@@ -896,12 +915,11 @@ void NoteData::EliminateAllButOneTap(int row)
|
||||
|
||||
void NoteData::GetTracksHeldAtRow( int row, vector<int>& viTracksOut )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(row);
|
||||
for( unsigned i=0; i<m_HoldNotes.size(); i++ )
|
||||
{
|
||||
const HoldNote& hn = m_HoldNotes[i];
|
||||
|
||||
if( fBeat >= hn.fStartBeat && fBeat <= hn.fEndBeat )
|
||||
if( hn.RowIsInRange(row) )
|
||||
viTracksOut.push_back( hn.iTrack );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,22 +353,21 @@ float NoteDataUtil::GetChaosRadarValue( const NoteData &in, float fSongSeconds )
|
||||
|
||||
void NoteDataUtil::RemoveHoldNotes(NoteData &in, float fStartBeat, float fEndBeat)
|
||||
{
|
||||
int iStartIndex = BeatToNoteRow( fStartBeat );
|
||||
int iEndIndex = BeatToNoteRow( fEndBeat );
|
||||
|
||||
// turn all the HoldNotes into TapNotes
|
||||
for( int i=in.GetNumHoldNotes()-1; i>=0; i-- ) // iterate backwards so we can delete
|
||||
{
|
||||
const HoldNote hn = in.GetHoldNote(i);
|
||||
|
||||
bool bHoldInRange =
|
||||
(hn.fStartBeat <= fStartBeat && hn.fEndBeat >= fEndBeat) ||
|
||||
(hn.fStartBeat >= fStartBeat && hn.fStartBeat <= fEndBeat) ||
|
||||
(hn.fEndBeat >= fStartBeat && hn.fEndBeat <= fEndBeat);
|
||||
|
||||
if( !bHoldInRange )
|
||||
const HoldNote &hn = in.GetHoldNote(i);
|
||||
if( !hn.RangeInside( iStartIndex, iEndIndex ) )
|
||||
continue; // skip
|
||||
|
||||
const int iStartRow = hn.iStartRow;
|
||||
|
||||
in.RemoveHoldNote( i );
|
||||
|
||||
in.SetTapNote(hn.iTrack, BeatToNoteRow(hn.fStartBeat), TAP_TAP);
|
||||
in.SetTapNote(hn.iTrack, iStartRow, TAP_TAP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +598,7 @@ void NoteDataUtil::Little(NoteData &in, float fStartBeat, float fEndBeat)
|
||||
in.SetTapNote(c, i, TAP_EMPTY);
|
||||
|
||||
for( i=in.GetNumHoldNotes()-1; i>=0; i-- )
|
||||
if( fmodf(in.GetHoldNote(i).fStartBeat,1) != 0 ) // doesn't start on a beat
|
||||
if( fmodf(in.GetHoldNote(i).GetStartBeat(),1) != 0 ) // doesn't start on a beat
|
||||
in.RemoveHoldNote( i );
|
||||
}
|
||||
|
||||
@@ -775,7 +774,7 @@ void NoteDataUtil::AddMines( NoteData &in, float fStartBeat, float fEndBeat )
|
||||
for( int i=0; i<in.GetNumHoldNotes(); i++ )
|
||||
{
|
||||
HoldNote &hn = in.GetHoldNote(i);
|
||||
float fHoldEndBeat = hn.fEndBeat;
|
||||
float fHoldEndBeat = hn.GetEndBeat();
|
||||
int iMineRow = BeatToNoteRow( fHoldEndBeat+0.5f );
|
||||
if( iMineRow < first_row || iMineRow > last_row )
|
||||
continue;
|
||||
@@ -887,7 +886,7 @@ void NoteDataUtil::ConvertTapsToHolds( NoteData &in, int iSimultaneousHolds, flo
|
||||
// to a hold that lasts for at least one beat.
|
||||
if( r2==r+1 )
|
||||
fEndBeat = fStartBeat+1;
|
||||
in.AddHoldNote( HoldNote(t,fStartBeat,fEndBeat) );
|
||||
in.AddHoldNote( HoldNote(t,BeatToNoteRow(fStartBeat),BeatToNoteRow(fEndBeat)) );
|
||||
}
|
||||
dont_add_hold:
|
||||
;
|
||||
|
||||
@@ -92,12 +92,15 @@ int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const floa
|
||||
int iNumSuccessfulHolds = 0;
|
||||
|
||||
if(fEndBeat == -1)
|
||||
fEndBeat = GetMaxBeat()+1;
|
||||
fEndBeat = GetMaxBeat();
|
||||
|
||||
int iStartIndex = BeatToNoteRow( fStartBeat );
|
||||
int iEndIndex = BeatToNoteRow( fEndBeat );
|
||||
|
||||
for( int i=0; i<GetNumHoldNotes(); i++ )
|
||||
{
|
||||
const HoldNote &hn = GetHoldNote(i);
|
||||
if( fStartBeat <= hn.fStartBeat && hn.fEndBeat <= fEndBeat && m_HoldNoteScores[i] == hns )
|
||||
if( iStartIndex <= hn.iStartRow && hn.iEndRow <= iEndIndex && m_HoldNoteScores[i] == hns )
|
||||
iNumSuccessfulHolds++;
|
||||
}
|
||||
return iNumSuccessfulHolds;
|
||||
@@ -127,6 +130,13 @@ int NoteDataWithScoring::GetSuccessfulMines( float fStartBeat, float fEndBeat )
|
||||
return iNumSuccessfulMinesNotes;
|
||||
}
|
||||
|
||||
/* See NoteData::GetNumHands for the maximum calculation. We need to line up to that.
|
||||
* A "hands" */
|
||||
int NoteDataWithScoring::GetSuccessfulHands( const float fStartBeat, const float fEndBeat ) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the minimum tap score of a row. If the row isn't complete (not all
|
||||
* taps have been hit), return TNS_NONE or TNS_MISS. */
|
||||
TapNoteScore NoteDataWithScoring::MinTapNoteScore(unsigned row) const
|
||||
@@ -211,8 +221,7 @@ float NoteDataWithScoring::GetActualRadarValue( RadarCategory rv, PlayerNumber p
|
||||
case RADAR_NUM_JUMPS: return (float) GetNumNWithScore( TNS_GOOD, 2 );
|
||||
case RADAR_NUM_HOLDS: return (float) GetNumHoldNotesWithScore( HNS_OK );
|
||||
case RADAR_NUM_MINES: return (float) GetSuccessfulMines();
|
||||
/* XXX: TODO */
|
||||
case RADAR_NUM_HANDS: return 0;
|
||||
case RADAR_NUM_HANDS: return (float) GetSuccessfulHands();
|
||||
default: ASSERT(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int GetNumNWithScore( TapNoteScore tns, int MinTaps, const float fStartBeat = 0, const float fEndBeat = -1 ) const;
|
||||
int GetNumHoldNotesWithScore( HoldNoteScore hns, const float fStartBeat = 0, const float fEndBeat = -1 ) const;
|
||||
int GetSuccessfulMines( const float fStartBeat = 0, const float fEndBeat = -1 ) const;
|
||||
|
||||
int GetSuccessfulHands( const float fStartBeat = 0, const float fEndBeat = -1 ) const;
|
||||
TapNoteScore GetTapNoteScore(unsigned track, unsigned row) const;
|
||||
void SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns);
|
||||
float GetTapNoteOffset(unsigned track, unsigned row) const;
|
||||
|
||||
@@ -453,7 +453,7 @@ void NoteDisplay::DrawHoldTopCap( const HoldNote& hn, const bool bActive, float
|
||||
//
|
||||
const int size = 4096;
|
||||
static RageSpriteVertex queue[size];
|
||||
Sprite* pSprTopCap = GetHoldTopCapSprite( hn.fStartBeat, bActive );
|
||||
Sprite* pSprTopCap = GetHoldTopCapSprite( hn.GetStartBeat(), bActive );
|
||||
|
||||
// draw manually in small segments
|
||||
RageSpriteVertex *v = &queue[0];
|
||||
@@ -524,7 +524,7 @@ void NoteDisplay::DrawHoldBody( const HoldNote& hn, const bool bActive, float fY
|
||||
const int size = 4096;
|
||||
static RageSpriteVertex queue[size];
|
||||
|
||||
Sprite* pSprBody = GetHoldBodySprite( hn.fStartBeat, bActive );
|
||||
Sprite* pSprBody = GetHoldBodySprite( hn.GetStartBeat(), bActive );
|
||||
|
||||
// draw manually in small segments
|
||||
RageSpriteVertex *v = &queue[0];
|
||||
@@ -609,7 +609,7 @@ void NoteDisplay::DrawHoldBottomCap( const HoldNote& hn, const bool bActive, flo
|
||||
const int size = 4096;
|
||||
static RageSpriteVertex queue[size];
|
||||
|
||||
Sprite* pBottomCap = GetHoldBottomCapSprite( hn.fStartBeat, bActive );
|
||||
Sprite* pBottomCap = GetHoldBottomCapSprite( hn.GetStartBeat(), bActive );
|
||||
|
||||
// draw manually in small segments
|
||||
RageSpriteVertex *v = &queue[0];
|
||||
@@ -678,7 +678,7 @@ void NoteDisplay::DrawHoldTail( const HoldNote& hn, bool bActive, float fYTail,
|
||||
//
|
||||
// Draw the tail
|
||||
//
|
||||
Actor* pSprTail = GetHoldTailActor( hn.fStartBeat, bActive );
|
||||
Actor* pSprTail = GetHoldTailActor( hn.GetStartBeat(), bActive );
|
||||
|
||||
const float fY = fYTail;
|
||||
const float fYOffset = ArrowGetYOffsetFromYPos( m_PlayerNumber, iCol, fY, m_fYReverseOffsetPixels );
|
||||
@@ -728,7 +728,7 @@ void NoteDisplay::DrawHoldHead( const HoldNote& hn, bool bActive, float fYHead,
|
||||
//
|
||||
// Draw the head
|
||||
//
|
||||
Actor* pActor = GetHoldHeadActor( hn.fStartBeat, bActive );
|
||||
Actor* pActor = GetHoldHeadActor( hn.GetStartBeat(), bActive );
|
||||
|
||||
// draw with normal Sprite
|
||||
const float fY = fYHead;
|
||||
@@ -780,9 +780,9 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float
|
||||
|
||||
const int iCol = hn.iTrack;
|
||||
const bool bReverse = GAMESTATE->m_CurrentPlayerOptions[m_PlayerNumber].GetReversePercentForColumn(iCol) > 0.5;
|
||||
const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.fStartBeat );
|
||||
const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.GetStartBeat() );
|
||||
const float fStartYPos = ArrowGetYPos( m_PlayerNumber, iCol, fStartYOffset, fReverseOffsetPixels );
|
||||
const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.fEndBeat );
|
||||
const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, hn.GetEndBeat() );
|
||||
const float fEndYPos = ArrowGetYPos( m_PlayerNumber, iCol, fEndYOffset, fReverseOffsetPixels );
|
||||
|
||||
const float fYHead = bReverse ? fEndYPos : fStartYPos; // the center of the head
|
||||
|
||||
@@ -529,18 +529,22 @@ void NoteField::DrawPrimitives()
|
||||
continue;
|
||||
|
||||
// If no part of this HoldNote is on the screen, skip it
|
||||
if( !( fFirstBeatToDraw <= hn.fEndBeat && hn.fEndBeat <= fLastBeatToDraw ||
|
||||
fFirstBeatToDraw <= hn.fStartBeat && hn.fStartBeat <= fLastBeatToDraw ||
|
||||
hn.fStartBeat < fFirstBeatToDraw && hn.fEndBeat > fLastBeatToDraw ) )
|
||||
if( !( iFirstIndexToDraw <= hn.iEndRow && hn.iEndRow <= iLastIndexToDraw ||
|
||||
iFirstIndexToDraw <= hn.iStartRow && hn.iStartRow <= iLastIndexToDraw ||
|
||||
hn.iStartRow < iFirstIndexToDraw && hn.iEndRow > iLastIndexToDraw ) )
|
||||
{
|
||||
continue; // skip
|
||||
}
|
||||
|
||||
SearchForBeat( CurDisplay, NextDisplay, hn.fStartBeat );
|
||||
SearchForBeat( CurDisplay, NextDisplay, NoteRowToBeat(hn.iStartRow) );
|
||||
|
||||
bool bIsInSelectionRange = false;
|
||||
if( m_fBeginMarker!=-1 && m_fEndMarker!=-1 )
|
||||
bIsInSelectionRange = m_fBeginMarker<=hn.fStartBeat && hn.fStartBeat<=m_fEndMarker && m_fBeginMarker<=hn.fEndBeat && hn.fEndBeat<=m_fEndMarker;
|
||||
bIsInSelectionRange =
|
||||
m_fBeginMarker <= hn.GetStartBeat() &&
|
||||
hn.GetStartBeat() <= m_fEndMarker &&
|
||||
m_fBeginMarker <= hn.GetEndBeat() &&
|
||||
hn.GetEndBeat() <= m_fEndMarker;
|
||||
|
||||
NoteDisplayCols *nd = CurDisplay->second;
|
||||
|
||||
|
||||
+25
-11
@@ -132,17 +132,6 @@ NoteType BeatToNoteType( float fBeat );
|
||||
bool IsNoteOfType( int iNoteIndex, NoteType t );
|
||||
CString NoteTypeToString( NoteType nt );
|
||||
|
||||
|
||||
|
||||
struct HoldNote
|
||||
{
|
||||
HoldNote( int t, float s, float e ) { iTrack=t; fStartBeat=s; fEndBeat=e; }
|
||||
int iTrack;
|
||||
float fStartBeat;
|
||||
float fEndBeat;
|
||||
};
|
||||
|
||||
|
||||
inline int BeatToNoteRow( float fBeatNum ) { return int( fBeatNum * ROWS_PER_BEAT + 0.5f); }; // round
|
||||
inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ROWS_PER_BEAT ); };
|
||||
inline float NoteRowToBeat( float fNoteIndex ) { return fNoteIndex / (float)ROWS_PER_BEAT; };
|
||||
@@ -150,5 +139,30 @@ inline float NoteRowToBeat( int iNoteIndex ) { return NoteRowToBeat( (float)iN
|
||||
|
||||
|
||||
|
||||
struct HoldNote
|
||||
{
|
||||
HoldNote( int t, int s, int e ) { iTrack=t; iStartRow=s; iEndRow=e; }
|
||||
bool RowIsInRange( int row ) const { return iStartRow <= row && row <= iEndRow; }
|
||||
bool RangeOverlaps( int start, int end ) const
|
||||
{
|
||||
return
|
||||
( iStartRow >= start && end >= iEndRow ) || // other consumes us
|
||||
( iStartRow <= start && end <= iEndRow ) || // other inside us
|
||||
( iStartRow <= start && start <= iEndRow ) || // other overlaps us
|
||||
( iStartRow <= end && end <= iEndRow ); // other overlaps us
|
||||
}
|
||||
bool RangeOverlaps( const HoldNote &hn ) const { return RangeOverlaps(hn.iStartRow, hn.iEndRow); }
|
||||
bool RangeInside( int start, int end ) const { return iStartRow <= start && end <= iEndRow; }
|
||||
|
||||
float GetStartBeat() const { return NoteRowToBeat( iStartRow ); }
|
||||
float GetEndBeat() const { return NoteRowToBeat( iEndRow ); }
|
||||
int iTrack;
|
||||
int iStartRow;
|
||||
int iEndRow;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -184,8 +184,8 @@ bool KSFLoader::LoadFromKSFFile( const CString &sPath, Steps &out, const Song &s
|
||||
{
|
||||
HoldNote hn (
|
||||
t, /* button */
|
||||
iHoldStartRow[t]/(float)iTickCount, /* start */
|
||||
(r-1)/(float)iTickCount /* end */
|
||||
BeatToNoteRow(iHoldStartRow[t]/(float)iTickCount), /* start */
|
||||
BeatToNoteRow((r-1)/(float)iTickCount) /* end */
|
||||
);
|
||||
notedata.AddHoldNote( hn );
|
||||
iHoldStartRow[t] = -1;
|
||||
|
||||
@@ -238,6 +238,7 @@ void PlayerMinus::Update( float fDeltaTime )
|
||||
|
||||
|
||||
const float fSongBeat = GAMESTATE->m_fSongBeat;
|
||||
const int iSongRow = BeatToNoteRow( fSongBeat );
|
||||
|
||||
m_pNoteField->Update( fDeltaTime );
|
||||
|
||||
@@ -282,7 +283,7 @@ void PlayerMinus::Update( float fDeltaTime )
|
||||
const HoldNote &hn = GetHoldNote(i);
|
||||
HoldNoteScore hns = GetHoldNoteScore(i);
|
||||
float fLife = GetHoldNoteLife(i);
|
||||
int iHoldStartIndex = BeatToNoteRow(hn.fStartBeat);
|
||||
int iHoldStartIndex = hn.iStartRow;
|
||||
|
||||
m_pNoteField->m_bIsHoldingHoldNote[i] = false; // set host flag so NoteField can do intelligent drawing
|
||||
|
||||
@@ -297,7 +298,7 @@ void PlayerMinus::Update( float fDeltaTime )
|
||||
const bool bSteppedOnTapNote = tns != TNS_NONE && tns != TNS_MISS; // did they step on the start of this hold?
|
||||
|
||||
// If the song beat is in the range of this hold:
|
||||
if( hn.fStartBeat <= fSongBeat && fSongBeat <= hn.fEndBeat )
|
||||
if( hn.iStartRow <= iSongRow && iSongRow <= hn.iEndRow )
|
||||
{
|
||||
bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI );
|
||||
|
||||
@@ -316,7 +317,7 @@ void PlayerMinus::Update( float fDeltaTime )
|
||||
// its HoldNote::fEndBeat. Otherwise, when HoldNotes are converted to the
|
||||
// 4s representation, it disappears, which causes problems for the way we
|
||||
// store HoldNote life (by index of the hold).
|
||||
m_pNoteField->GetHoldNote(i).fStartBeat = min( fSongBeat, m_pNoteField->GetHoldNote(i).fEndBeat -NoteRowToBeat(1) );
|
||||
m_pNoteField->GetHoldNote(i).iStartRow = min( iSongRow, m_pNoteField->GetHoldNote(i).iEndRow-1 );
|
||||
}
|
||||
|
||||
if( bSteppedOnTapNote && bIsHoldingButton )
|
||||
@@ -347,7 +348,7 @@ void PlayerMinus::Update( float fDeltaTime )
|
||||
hns = HNS_NG;
|
||||
|
||||
// check for OK
|
||||
if( fSongBeat >= hn.fEndBeat && bSteppedOnTapNote && fLife > 0 ) // if this HoldNote is in the past
|
||||
if( iSongRow >= hn.iEndRow && bSteppedOnTapNote && fLife > 0 ) // if this HoldNote is in the past
|
||||
{
|
||||
fLife = 1;
|
||||
hns = HNS_OK;
|
||||
|
||||
@@ -416,7 +416,7 @@ void ScreenEdit::Update( float fDeltaTime )
|
||||
fEndBeat = froundf( fEndBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) );
|
||||
|
||||
// create a new hold note
|
||||
HoldNote newHN( t, fStartBeat, fEndBeat );
|
||||
HoldNote newHN( t, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat) );
|
||||
m_NoteFieldRecord.AddHoldNote( newHN );
|
||||
}
|
||||
}
|
||||
@@ -656,7 +656,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
{
|
||||
const HoldNote &hn = m_NoteFieldEdit.GetHoldNote(i);
|
||||
if( iCol == hn.iTrack && // the notes correspond
|
||||
fSongBeat >= hn.fStartBeat && fSongBeat <= hn.fEndBeat ) // the cursor lies within this HoldNote
|
||||
hn.RowIsInRange(iSongIndex) ) // the cursor lies within this HoldNote
|
||||
{
|
||||
m_NoteFieldEdit.RemoveHoldNote( i );
|
||||
return;
|
||||
@@ -764,10 +764,10 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
continue;
|
||||
|
||||
// create a new hold note
|
||||
HoldNote newHN( iCol, min(fStartBeat, fEndBeat), max(fStartBeat, fEndBeat) );
|
||||
HoldNote newHN( iCol, BeatToNoteRow(min(fStartBeat, fEndBeat)), BeatToNoteRow(max(fStartBeat, fEndBeat)) );
|
||||
|
||||
newHN.fStartBeat = max(newHN.fStartBeat, 0);
|
||||
newHN.fEndBeat = max(newHN.fEndBeat, 0);
|
||||
newHN.iStartRow = max(newHN.iStartRow, 0);
|
||||
newHN.iEndRow = max(newHN.iEndRow, 0);
|
||||
|
||||
m_NoteFieldEdit.AddHoldNote( newHN );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user