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:
Kevin Slaughter
2003-03-19 12:43:49 +00:00
parent 28e3565775
commit 9c00b6f674
6 changed files with 111 additions and 77 deletions
+15 -19
View File
@@ -20,6 +20,8 @@ bool LyricsLoader::LoadFromLRCFile( CString sPath, Song &out )
LRCFile lrc; LRCFile lrc;
bool bResult = lrc.ReadFile( sPath ); bool bResult = lrc.ReadFile( sPath );
CString m_sLastFoundColor = "0x00ff00";
if( !bResult ) if( !bResult )
RageException::Throw( "Error opening file '%s' for reading.", sPath.GetString() ); RageException::Throw( "Error opening file '%s' for reading.", sPath.GetString() );
@@ -39,35 +41,29 @@ bool LyricsLoader::LoadFromLRCFile( CString sPath, Song &out )
} }
// handle the data // handle the data
if( 0==stricmp(sValueName,"COLOUR") ) if( 0==stricmp(sValueName,"COLOUR") || 0==stricmp(sValueName,"COLOR") )
{ {
// set color var here // set color var here for this segment
LOG->Trace("\n\n\n Got color tag from lyric file \n\n\n"); m_sLastFoundColor = sValueData;
continue; continue;
} }
else else
{ {
/* If we've gotten this far, and no other statement caught /* If we've gotten this far, and no other statement caught
this value before this does, assume it's a time value. this value before this does, assume it's a time value. */
Add the lyric segment! */
// For the sorting routine, we need a numerical version of the 'time' LyricSegment LYRICSTRING;
CString sTempTime = sValueName.GetBuffer(); LYRICSTRING.m_sColor = m_sLastFoundColor;
sTempTime.Replace( ".", "" ); LYRICSTRING.m_fStartTime = TimeToSeconds(sValueName);
sTempTime.Replace( ":", "." ); LYRICSTRING.m_sLyric = sValueData;
// float m_fStartTime = (float)atof(sTempTime); // hush "variable not referenced" LYRICSTRING.m_sLyric.Replace( "\\", "\\" ); // to avoid possible screw-ups
CString m_sLyric = sValueData; // if someone uses a \ for whatever
CString m_sStartTime = sValueName; // reason in their lyrics -- Miryokuteki
//--
//LyricSegment MOOZ; LYRICSTRING.m_sLyric.Replace( "|","\n" ); // Pipe symbols denote a new line in LRC files
//MOOZ.m_fStartTime = (float)atof((LPCTSTR)sTempTime); out.AddLyricSegment( LYRICSTRING );
//MOOZ.m_sStartTime = sValueName.GetBuffer();
//MOOZ.m_sLyric = sValueData.GetBuffer();
//out.AddLyricSegment( LyricSegment( m_fStartTime, m_sLyric, m_sStartTime ) );
} }
} }
+74 -3
View File
@@ -32,9 +32,13 @@
#include "RageTimer.h" #include "RageTimer.h"
#include "ScoreKeeperMAX2.h" #include "ScoreKeeperMAX2.h"
#include "LyricsLoader.h"
// //
// Defines // Defines
// //
#define LYRICS_X THEME->GetMetricF("ScreenGameplay","LyricsX")
#define LYRICS_Y THEME->GetMetricF("ScreenGameplay","LyricsY")
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen") #define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
#define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MaxComboX") #define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MaxComboX")
#define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MaxComboY") #define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MaxComboY")
@@ -110,9 +114,32 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
// 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.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textLyrics.SetXY( 100,100 ); m_textLyrics.SetXY( LYRICS_X,LYRICS_Y );
m_textLyrics.SetDiffuse( RageColor(1,1,1,1) ); 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 ) 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") ); m_textAutoPlay.LoadFromFont( THEME->GetPathTo("Fonts","header2") );
@@ -818,8 +845,52 @@ void ScreenGameplay::Update( float fDeltaTime )
// //
// Check if we should show lyrics now // Check if we should show lyrics now
// //
if( (m_bHasLyrics) ) // Every song without lyrics would crash here.. bug fix -- Miryokuteki
{
m_fLyricsTime += fDeltaTime; 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 // Update players' alive time
+2
View File
@@ -90,6 +90,8 @@ protected:
float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING
float m_fLyricsTime; float m_fLyricsTime;
int m_iCurLyricNumber;
bool m_bHasLyrics;
Background m_Background; Background m_Background;
-1
View File
@@ -83,7 +83,6 @@ const float TWEEN_TIME = 0.5f;
static const ScreenMessage SM_AllowOptionsMenuRepeat = ScreenMessage(SM_User+1); static const ScreenMessage SM_AllowOptionsMenuRepeat = ScreenMessage(SM_User+1);
ScreenSelectMusic::ScreenSelectMusic() ScreenSelectMusic::ScreenSelectMusic()
{ {
LOG->Trace( "ScreenSelectMusic::ScreenSelectMusic()" ); LOG->Trace( "ScreenSelectMusic::ScreenSelectMusic()" );
+12 -46
View File
@@ -77,16 +77,6 @@ void SortBackgroundChangesArray( vector<BackgroundChange> &arrayBackgroundChange
sort( arrayBackgroundChanges.begin(), arrayBackgroundChanges.end(), CompareBackgroundChanges ); 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 // Song
@@ -137,7 +127,6 @@ void Song::AddBackgroundChange( BackgroundChange seg )
void Song::AddLyricSegment( LyricSegment seg ) void Song::AddLyricSegment( LyricSegment seg )
{ {
m_LyricSegments.push_back( seg ); m_LyricSegments.push_back( seg );
SortLyricSegmentsArray( m_LyricSegments );
} }
@@ -309,36 +298,6 @@ bool Song::LoadWithoutCache( CString sDir )
bool success = ld->LoadFromDir( sDir, *this ); bool success = ld->LoadFromDir( sDir, *this );
delete ld; 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) if(!success)
return false; return false;
@@ -603,8 +562,8 @@ void Song::TidyUpData()
LOG->Trace("Looking for lyrics.."); LOG->Trace("Looking for lyrics..");
//if( HasLyrics() ) if( HasLyrics() )
//{ {
//Check if there is a lyric file in here //Check if there is a lyric file in here
CStringArray arrayLyricFiles; CStringArray arrayLyricFiles;
GetDirListing(m_sSongDir + CString("*.lrc"), arrayLyricFiles ); GetDirListing(m_sSongDir + CString("*.lrc"), arrayLyricFiles );
@@ -614,7 +573,7 @@ void Song::TidyUpData()
LyricsLoader ll; LyricsLoader ll;
ll.LoadFromLRCFile(m_sLyricsFile.GetBuffer(), *GAMESTATE->m_pCurSong); ll.LoadFromLRCFile(m_sLyricsFile.GetBuffer(), *GAMESTATE->m_pCurSong);
} }
//} }
@@ -1260,8 +1219,15 @@ CString Song::GetBannerPath() const
CString Song::GetLyricsPath() const CString Song::GetLyricsPath() const
{ {
LOG->Trace("\n\n\n TRYING TO GET LYRICS FROM:: %s%s", m_sSongDir.GetString(), m_sBannerFile.GetString()); //LOG->Trace("\n\n\n TRYING TO GET LYRICS FROM:: %s%s", m_sSongDir, m_sLyricsFile);
return 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 CString Song::GetCDTitlePath() const
+4 -4
View File
@@ -51,11 +51,11 @@ void SortBackgroundChangesArray( vector<BackgroundChange> &arrayBackgroundChange
struct LyricSegment struct LyricSegment
{ {
LyricSegment() { m_fStartTime = -1; }; float m_fStartTime;
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
CString m_sLyric; 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 */
}; };