We now have lyric support!.. I gotta sleep some, will add an option to turn lyrics on/off when I get home from work
This commit is contained in:
@@ -20,6 +20,8 @@ bool LyricsLoader::LoadFromLRCFile( CString sPath, Song &out )
|
||||
|
||||
LRCFile lrc;
|
||||
bool bResult = lrc.ReadFile( sPath );
|
||||
CString m_sLastFoundColor = "0x00ff00";
|
||||
|
||||
if( !bResult )
|
||||
RageException::Throw( "Error opening file '%s' for reading.", sPath.GetString() );
|
||||
|
||||
@@ -39,35 +41,29 @@ bool LyricsLoader::LoadFromLRCFile( CString sPath, Song &out )
|
||||
}
|
||||
|
||||
// handle the data
|
||||
if( 0==stricmp(sValueName,"COLOUR") )
|
||||
if( 0==stricmp(sValueName,"COLOUR") || 0==stricmp(sValueName,"COLOR") )
|
||||
{
|
||||
// set color var here
|
||||
LOG->Trace("\n\n\n Got color tag from lyric file \n\n\n");
|
||||
// set color var here for this segment
|
||||
m_sLastFoundColor = sValueData;
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* If we've gotten this far, and no other statement caught
|
||||
this value before this does, assume it's a time value.
|
||||
Add the lyric segment! */
|
||||
this value before this does, assume it's a time value. */
|
||||
|
||||
// For the sorting routine, we need a numerical version of the 'time'
|
||||
CString sTempTime = sValueName.GetBuffer();
|
||||
sTempTime.Replace( ".", "" );
|
||||
sTempTime.Replace( ":", "." );
|
||||
|
||||
// float m_fStartTime = (float)atof(sTempTime); // hush "variable not referenced"
|
||||
CString m_sLyric = sValueData;
|
||||
CString m_sStartTime = sValueName;
|
||||
//--
|
||||
LyricSegment LYRICSTRING;
|
||||
LYRICSTRING.m_sColor = m_sLastFoundColor;
|
||||
LYRICSTRING.m_fStartTime = TimeToSeconds(sValueName);
|
||||
LYRICSTRING.m_sLyric = sValueData;
|
||||
|
||||
//LyricSegment MOOZ;
|
||||
//MOOZ.m_fStartTime = (float)atof((LPCTSTR)sTempTime);
|
||||
//MOOZ.m_sStartTime = sValueName.GetBuffer();
|
||||
//MOOZ.m_sLyric = sValueData.GetBuffer();
|
||||
|
||||
//out.AddLyricSegment( LyricSegment( m_fStartTime, m_sLyric, m_sStartTime ) );
|
||||
LYRICSTRING.m_sLyric.Replace( "\\", "\\" ); // to avoid possible screw-ups
|
||||
// if someone uses a \ for whatever
|
||||
// reason in their lyrics -- Miryokuteki
|
||||
|
||||
LYRICSTRING.m_sLyric.Replace( "|","\n" ); // Pipe symbols denote a new line in LRC files
|
||||
out.AddLyricSegment( LYRICSTRING );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,9 +32,13 @@
|
||||
#include "RageTimer.h"
|
||||
#include "ScoreKeeperMAX2.h"
|
||||
|
||||
#include "LyricsLoader.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
#define LYRICS_X THEME->GetMetricF("ScreenGameplay","LyricsX")
|
||||
#define LYRICS_Y THEME->GetMetricF("ScreenGameplay","LyricsY")
|
||||
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
|
||||
#define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MaxComboX")
|
||||
#define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MaxComboY")
|
||||
@@ -109,10 +113,33 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
G_TICK_EARLY_SECONDS.Refresh();
|
||||
|
||||
|
||||
|
||||
m_textLyrics.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
|
||||
m_textLyrics.SetXY( 100,100 );
|
||||
m_textLyrics.SetDiffuse( RageColor(1,1,1,1) );
|
||||
|
||||
|
||||
|
||||
// Lyrics loader
|
||||
|
||||
LyricsLoader LL;
|
||||
if( GAMESTATE->m_pCurSong->GetLyricsPath() != "NULL" )
|
||||
{
|
||||
LL.LoadFromLRCFile(GAMESTATE->m_pCurSong->GetLyricsPath(), *GAMESTATE->m_pCurSong);
|
||||
|
||||
m_textLyrics.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
|
||||
m_textLyrics.SetXY( LYRICS_X,LYRICS_Y );
|
||||
m_textLyrics.SetDiffuse( RageColor(1,1,1,1) );
|
||||
// We need to use the Color Tag that's in m_pCurSong->m_LyricSegments[?].m_sColor
|
||||
// But since the value there is in Hex, need to convert to RageColor I guess.
|
||||
// Until that gets done, this will default to white (&HFFFFFF)
|
||||
|
||||
m_bHasLyrics = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bHasLyrics = false;
|
||||
}
|
||||
|
||||
// ~~
|
||||
|
||||
|
||||
|
||||
|
||||
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL )
|
||||
@@ -404,7 +431,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
}
|
||||
|
||||
|
||||
//this->AddChild( &m_textLyrics ); -- THIS IS NOT DONE YET!! (Miryokuteki)
|
||||
this->AddChild( &m_textLyrics );// -- THIS IS NOT DONE YET!! (Miryokuteki)
|
||||
|
||||
|
||||
m_textAutoPlay.LoadFromFont( THEME->GetPathTo("Fonts","header2") );
|
||||
@@ -818,8 +845,52 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
//
|
||||
// Check if we should show lyrics now
|
||||
//
|
||||
if( (m_bHasLyrics) ) // Every song without lyrics would crash here.. bug fix -- Miryokuteki
|
||||
{
|
||||
m_fLyricsTime += fDeltaTime;
|
||||
m_textLyrics.SetText( SecondsToTime( m_fLyricsTime ) );
|
||||
float fStartTime = (GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime);
|
||||
|
||||
// Make sure we don't go over the array's boundry
|
||||
if( m_iCurLyricNumber <= GAMESTATE->m_pCurSong->m_LyricSegments.size() )
|
||||
{
|
||||
// Check if it's time to animate the old lyrics to off-screen
|
||||
if( (fStartTime - m_fLyricsTime) <= .30 || (fStartTime - m_fLyricsTime) <= -.30f)
|
||||
{
|
||||
m_textLyrics.FadeOff( 0, "foldy", .20f);
|
||||
}
|
||||
|
||||
if( m_fLyricsTime >= fStartTime )
|
||||
{
|
||||
/*I figure for longer lines of text, the Lyric display object should
|
||||
be scaled down, if needed, by the .ScaleTo() function. But somehow
|
||||
it jus ain't working for me at all.. anyone able to do this
|
||||
properly?? We prolly should also add detection of where to put
|
||||
the Lyric object, if the arrows are on reverse? Jus an idea,
|
||||
but it kinda defeats the purpose of the Lyric object X/Y being a
|
||||
theme element :)
|
||||
|
||||
BTW: Once the function is done, this will also be where the color
|
||||
of this lyric block will be set -- Miryokuteki */
|
||||
//m_textLyrics.SetDiffuse(COLOR HERE);
|
||||
|
||||
/*if( GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber].m_sLyric == "" || GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber].m_sLyric == " " )
|
||||
{
|
||||
For some reason, once this fades off, it never comes back when
|
||||
it's called! -- Miryokuteki
|
||||
|
||||
m_textLyrics.FadeOff( 0, "fade", .10f );
|
||||
m_iCurLyricNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
m_textLyrics.FadeOn( 0, "foldy", .20f );
|
||||
m_textLyrics.SetText( GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber].m_sLyric );
|
||||
m_iCurLyricNumber++;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update players' alive time
|
||||
|
||||
@@ -90,6 +90,8 @@ protected:
|
||||
|
||||
float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING
|
||||
float m_fLyricsTime;
|
||||
int m_iCurLyricNumber;
|
||||
bool m_bHasLyrics;
|
||||
|
||||
|
||||
Background m_Background;
|
||||
|
||||
@@ -83,7 +83,6 @@ const float TWEEN_TIME = 0.5f;
|
||||
static const ScreenMessage SM_AllowOptionsMenuRepeat = ScreenMessage(SM_User+1);
|
||||
|
||||
|
||||
|
||||
ScreenSelectMusic::ScreenSelectMusic()
|
||||
{
|
||||
LOG->Trace( "ScreenSelectMusic::ScreenSelectMusic()" );
|
||||
|
||||
+12
-46
@@ -77,16 +77,6 @@ void SortBackgroundChangesArray( vector<BackgroundChange> &arrayBackgroundChange
|
||||
sort( arrayBackgroundChanges.begin(), arrayBackgroundChanges.end(), CompareBackgroundChanges );
|
||||
}
|
||||
|
||||
static int CompareLyricSegments(const LyricSegment &seg1, const LyricSegment &seg2)
|
||||
{
|
||||
return seg1.m_fStartTime < seg2.m_fStartTime;
|
||||
}
|
||||
|
||||
void SortLyricSegmentsArray( vector<LyricSegment> &arrayLyricSegments )
|
||||
{
|
||||
sort( arrayLyricSegments.begin(), arrayLyricSegments.end(), CompareLyricSegments );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Song
|
||||
@@ -137,7 +127,6 @@ void Song::AddBackgroundChange( BackgroundChange seg )
|
||||
void Song::AddLyricSegment( LyricSegment seg )
|
||||
{
|
||||
m_LyricSegments.push_back( seg );
|
||||
SortLyricSegmentsArray( m_LyricSegments );
|
||||
}
|
||||
|
||||
|
||||
@@ -309,36 +298,6 @@ bool Song::LoadWithoutCache( CString sDir )
|
||||
bool success = ld->LoadFromDir( sDir, *this );
|
||||
delete ld;
|
||||
|
||||
LOG->Trace("\n\n\n SONG NAME:: %s", this->GetDisplayMainTitle().GetBuffer() );
|
||||
/*
|
||||
if( this->GetDisplayMainTitle().GetBuffer() == "Future Girls" )
|
||||
* This is incorrect; it's comparing two string pointers, which doesn't
|
||||
* work like you expect. Drop the "GetBuffer".
|
||||
*
|
||||
* I don't believe we should be loading lyrics into Song directly, as part of
|
||||
* the data. Instead, I'd treat it as a separate resource (like images
|
||||
* and movies) and load it on demand; eg. into a LyricsDisplay actor. The
|
||||
* primary reason is that it's more modular: the Song class is already too
|
||||
* monolithic. (Note that lyrics can get substantially more detailed; for
|
||||
* example, we might want to add SSA support.)
|
||||
*
|
||||
* I'm still undecided, personally, as to whether we should ultimately
|
||||
* store lyrics inside the SM or in a separate file, but since we'll want
|
||||
* to support LRC anyway (which is what you're doing) and we don't need to
|
||||
* actually write it to disk at this point, we don't have to decide on this yet.
|
||||
* (I'm leaning to changing my opinion to leaving it in a separate file, but
|
||||
* I need to think on it some more.)
|
||||
*
|
||||
* -glenn */
|
||||
/* if( this->GetDisplayMainTitle() == "Future Girls" ) <- this is what you wanted
|
||||
{
|
||||
LOG->Trace("AAA");
|
||||
} */
|
||||
if( HasLyrics() )
|
||||
{
|
||||
LOG->Trace("\n\n\n LOAD LYRICS HERE!! \n\n\n");
|
||||
}
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
@@ -603,8 +562,8 @@ void Song::TidyUpData()
|
||||
|
||||
|
||||
LOG->Trace("Looking for lyrics..");
|
||||
//if( HasLyrics() )
|
||||
//{
|
||||
if( HasLyrics() )
|
||||
{
|
||||
//Check if there is a lyric file in here
|
||||
CStringArray arrayLyricFiles;
|
||||
GetDirListing(m_sSongDir + CString("*.lrc"), arrayLyricFiles );
|
||||
@@ -614,7 +573,7 @@ void Song::TidyUpData()
|
||||
LyricsLoader ll;
|
||||
ll.LoadFromLRCFile(m_sLyricsFile.GetBuffer(), *GAMESTATE->m_pCurSong);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1260,8 +1219,15 @@ CString Song::GetBannerPath() const
|
||||
|
||||
CString Song::GetLyricsPath() const
|
||||
{
|
||||
LOG->Trace("\n\n\n TRYING TO GET LYRICS FROM:: %s%s", m_sSongDir.GetString(), m_sBannerFile.GetString());
|
||||
return m_sSongDir+m_sLyricsFile;
|
||||
//LOG->Trace("\n\n\n TRYING TO GET LYRICS FROM:: %s%s", m_sSongDir, m_sLyricsFile);
|
||||
CStringArray arrayLyricFiles;
|
||||
GetDirListing(m_sSongDir + CString("*.lrc"), arrayLyricFiles );
|
||||
if( !arrayLyricFiles.empty() )
|
||||
{
|
||||
return m_sSongDir+arrayLyricFiles[0];
|
||||
}
|
||||
|
||||
return CString("NULL");
|
||||
}
|
||||
|
||||
CString Song::GetCDTitlePath() const
|
||||
|
||||
@@ -51,11 +51,11 @@ void SortBackgroundChangesArray( vector<BackgroundChange> &arrayBackgroundChange
|
||||
|
||||
struct LyricSegment
|
||||
{
|
||||
LyricSegment() { m_fStartTime = -1; };
|
||||
LyricSegment( float a, CString m_sLyric, CString m_sStartTime ) { m_fStartTime = a, m_sLyric = m_sLyric, m_sStartTime = m_sStartTime; };
|
||||
float m_fStartTime; // For the sorting routine
|
||||
float m_fStartTime;
|
||||
CString m_sLyric;
|
||||
CString m_sStartTime;
|
||||
CString m_sColor; /* This will eventually be a RAGECOLOR, but until a function
|
||||
is made to convert a hex color to RAGECOLOR, it's a CString.
|
||||
This allows for multiple colors of lyric blocks. -- Miryokuteki */
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user