Add support for #DISPLAYBPM in DWI and SM files
This commit is contained in:
@@ -167,3 +167,25 @@ void BPMDisplay::NoBPM()
|
||||
m_textBPM.SetDiffuse( NORMAL_COLOR );
|
||||
m_sprLabel.SetDiffuse( NORMAL_COLOR );
|
||||
}
|
||||
|
||||
void BPMDisplay::SetBPM( const Song* pSong )
|
||||
{
|
||||
ASSERT( pSong );
|
||||
switch( pSong->m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
{
|
||||
float fMinBPM, fMaxBPM;
|
||||
pSong->GetActualBPM( fMinBPM, fMaxBPM );
|
||||
SetBPMRange( fMinBPM, fMaxBPM );
|
||||
}
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
SetBPMRange( pSong->m_fDisplayBPMMin, pSong->m_fDisplayBPMMax );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "ActorFrame.h"
|
||||
#include "BitmapText.h"
|
||||
#include "Quad.h"
|
||||
|
||||
class Song;
|
||||
|
||||
class BPMDisplay : public ActorFrame
|
||||
{
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
BPMDisplay();
|
||||
virtual void Update( float fDeltaTime );
|
||||
void SetBPMRange( float fLowBPM, float fHighBPM );
|
||||
void SetBPM( const Song* pSong );
|
||||
void CycleRandomly();
|
||||
void NoBPM();
|
||||
|
||||
|
||||
@@ -311,6 +311,24 @@ bool DWILoader::LoadFromDWIFile( CString sPath, Song &out )
|
||||
else if( 0==stricmp(sValueName,"BPM") )
|
||||
out.AddBPMSegment( BPMSegment(0, (float)atof(sParams[1])) );
|
||||
|
||||
else if( 0==stricmp(sValueName,"DISPLAYBPM") )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx..xxx]|[xxx]|[*];
|
||||
if( sscanf( sParams[1], "%f..%f", &out.m_fDisplayBPMMin, &out.m_fDisplayBPMMax ) == 2 )
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
}
|
||||
else if( sscanf( sParams[1], "%f", &out.m_fDisplayBPMMin ) != 1 )
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_fDisplayBPMMax = out.m_fDisplayBPMMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
else if( 0==stricmp(sValueName,"GAP") )
|
||||
// the units of GAP is 1/1000 second
|
||||
out.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f;
|
||||
|
||||
@@ -147,6 +147,22 @@ bool SMLoader::LoadFromSMFile( CString sPath, Song &out )
|
||||
else if( 0==stricmp(sValueName,"SAMPLELENGTH") )
|
||||
out.m_fMusicSampleLengthSeconds = TimeToSeconds( sParams[1] );
|
||||
|
||||
else if( 0==stricmp(sValueName,"DISPLAYBPM") )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx,xxx]|[xxx]|[*];
|
||||
if( sParams[1] == "*" )
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_fDisplayBPMMin = (float)atof( sParams[1] );
|
||||
if( sParams[2].empty() )
|
||||
out.m_fDisplayBPMMax = out.m_fDisplayBPMMin;
|
||||
else
|
||||
out.m_fDisplayBPMMax = (float)atof( sParams[2] );
|
||||
}
|
||||
}
|
||||
|
||||
else if( 0==stricmp(sValueName,"OFFSET") )
|
||||
out.m_fBeat0OffsetInSeconds = (float)atof( sParams[1] );
|
||||
|
||||
|
||||
@@ -229,6 +229,21 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out )
|
||||
fprintf( fp, "#SAMPLELENGTH:%.3f;\n", out.m_fMusicSampleLengthSeconds );
|
||||
if( out.m_sCDTitleFile.size() )
|
||||
fprintf( fp, "#CDTITLE:%s;\n", out.m_sCDTitleFile.c_str() );
|
||||
switch( out.m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
// write nothing
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
if( out.m_fDisplayBPMMin == out.m_fDisplayBPMMax )
|
||||
fprintf( fp, "#DISPLAYBPM:%.3f", out.m_fDisplayBPMMin );
|
||||
else
|
||||
fprintf( fp, "#DISPLAYBPM:%.3f..%.3f", out.m_fDisplayBPMMin, out.m_fDisplayBPMMax );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
fprintf( fp, "#DISPLAYBPM:*" );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !out.m_StopSegments.empty() )
|
||||
{
|
||||
|
||||
@@ -25,6 +25,22 @@ void NotesWriterSM::WriteGlobalTags(FILE *fp, const Song &out)
|
||||
fprintf( fp, "#SAMPLESTART:%.3f;\n", out.m_fMusicSampleStartSeconds );
|
||||
fprintf( fp, "#SAMPLELENGTH:%.3f;\n", out.m_fMusicSampleLengthSeconds );
|
||||
fprintf( fp, "#SELECTABLE:" );
|
||||
switch( out.m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
// write nothing
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
if( out.m_fDisplayBPMMin == out.m_fDisplayBPMMax )
|
||||
fprintf( fp, "#DISPLAYBPM:%.3f", out.m_fDisplayBPMMin );
|
||||
else
|
||||
fprintf( fp, "#DISPLAYBPM:%.3f,%.3f", out.m_fDisplayBPMMin, out.m_fDisplayBPMMax );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
fprintf( fp, "#DISPLAYBPM:*" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch(out.m_SelectionDisplay) {
|
||||
default: ASSERT(0); /* fallthrough */
|
||||
|
||||
@@ -675,9 +675,8 @@ void ScreenGameplay::LoadNextSong()
|
||||
m_textSongTitle.SetText( GAMESTATE->m_pCurSong->m_sMainTitle );
|
||||
|
||||
/* XXX: set it to the current BPM, not the range */
|
||||
float fMinBPM, fMaxBPM;
|
||||
GAMESTATE->m_pCurSong->GetMinMaxBPM( fMinBPM, fMaxBPM );
|
||||
m_BPMDisplay.SetBPMRange( fMinBPM, fMaxBPM );
|
||||
/* What does this comment mean? -Chris */
|
||||
m_BPMDisplay.SetBPM( GAMESTATE->m_pCurSong );
|
||||
|
||||
const bool bExtra = GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2();
|
||||
const bool bReverse[NUM_PLAYERS] = {
|
||||
|
||||
@@ -824,9 +824,7 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
}
|
||||
else
|
||||
{
|
||||
float fMinBPM, fMaxBPM;
|
||||
pSong->GetMinMaxBPM( fMinBPM, fMaxBPM );
|
||||
m_BPMDisplay.SetBPMRange( fMinBPM, fMaxBPM );
|
||||
m_BPMDisplay.SetBPM( pSong );
|
||||
}
|
||||
|
||||
const CString CDTitlePath = pSong->HasCDTitle()? pSong->GetCDTitlePath():THEME->GetPathToG("ScreenSelectMusic fallback cdtitle");
|
||||
|
||||
@@ -91,6 +91,9 @@ Song::Song()
|
||||
m_fFirstBeat = -1;
|
||||
m_fLastBeat = -1;
|
||||
m_SelectionDisplay = SHOW_ALWAYS;
|
||||
m_DisplayBPMType = DISPLAY_ACTUAL;
|
||||
m_fDisplayBPMMin = 0;
|
||||
m_fDisplayBPMMax = 0;
|
||||
}
|
||||
|
||||
Song::~Song()
|
||||
@@ -1070,8 +1073,8 @@ void SortSongPointerArrayByDifficulty( vector<Song*> &arraySongPointers )
|
||||
bool CompareSongPointersByBPM(const Song *pSong1, const Song *pSong2)
|
||||
{
|
||||
float fMinBPM1, fMaxBPM1, fMinBPM2, fMaxBPM2;
|
||||
pSong1->GetMinMaxBPM( fMinBPM1, fMaxBPM1 );
|
||||
pSong2->GetMinMaxBPM( fMinBPM2, fMaxBPM2 );
|
||||
pSong1->GetActualBPM( fMinBPM1, fMaxBPM1 );
|
||||
pSong2->GetActualBPM( fMinBPM2, fMaxBPM2 );
|
||||
|
||||
if( fMaxBPM1 < fMaxBPM2 )
|
||||
return true;
|
||||
|
||||
+11
-8
@@ -141,6 +141,9 @@ public:
|
||||
float GetLastBeat() const;
|
||||
float m_fMusicSampleStartSeconds;
|
||||
float m_fMusicSampleLengthSeconds;
|
||||
enum { DISPLAY_ACTUAL, DISPLAY_SPECIFIED, DISPLAY_RANDOM } m_DisplayBPMType;
|
||||
int m_fDisplayBPMMin;
|
||||
int m_fDisplayBPMMax; // if a range, then Min != Max
|
||||
|
||||
float GetMusicStartBeat() const;
|
||||
|
||||
@@ -175,17 +178,17 @@ public:
|
||||
void AddBackgroundChange( BackgroundChange seg );
|
||||
void AddLyricSegment( LyricSegment seg );
|
||||
|
||||
void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) const
|
||||
void GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
|
||||
{
|
||||
fMaxBPM = 0;
|
||||
fMinBPM = 100000; // inf
|
||||
fMaxBPMOut = 0;
|
||||
fMinBPMOut = 100000; // inf
|
||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ )
|
||||
{
|
||||
const BPMSegment &seg = m_BPMSegments[i];
|
||||
fMaxBPM = max( seg.m_fBPM, fMaxBPM );
|
||||
fMinBPM = min( seg.m_fBPM, fMinBPM );
|
||||
fMaxBPMOut = max( seg.m_fBPM, fMaxBPMOut );
|
||||
fMinBPMOut = min( seg.m_fBPM, fMinBPMOut );
|
||||
}
|
||||
};
|
||||
}
|
||||
float GetBPMAtBeat( float fBeat ) const
|
||||
{
|
||||
unsigned i;
|
||||
@@ -193,7 +196,7 @@ public:
|
||||
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
|
||||
break;
|
||||
return m_BPMSegments[i].m_fBPM;
|
||||
};
|
||||
}
|
||||
BPMSegment& GetBPMSegmentAtBeat( float fBeat )
|
||||
{
|
||||
unsigned i;
|
||||
@@ -209,7 +212,7 @@ public:
|
||||
if( m_BackgroundChanges[i+1].m_fStartBeat > fBeat )
|
||||
break;
|
||||
return m_BackgroundChanges[i].m_sBGName;
|
||||
};
|
||||
}
|
||||
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const;
|
||||
float GetBeatFromElapsedTime( float fElapsedTime ) const // shortcut for places that care only about the beat
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user