diff --git a/stepmania/src/LRCFile.cpp b/stepmania/src/LRCFile.cpp new file mode 100644 index 0000000000..8b30639a2d --- /dev/null +++ b/stepmania/src/LRCFile.cpp @@ -0,0 +1,162 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + Class: LRCFile + + Desc: See header. + + Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved. + Chris Danford + Glenn Maynard + Kevin Slaughter +----------------------------------------------------------------------------- +*/ + +#include "LRCFile.h" +#include "RageLog.h" +#include +#if defined(WIN32) +#include +#endif +#include "RageUtil.h" + +void LRCFile::AddParam( char *buf, int len ) +{ + values.back().params.push_back(CString(buf, len)); +} + +void LRCFile::AddValue() /* (no extra charge) */ +{ + values.push_back(value_t()); +} + +void LRCFile::ReadBuf( char *buf, int len ) +{ + int value_start = -1; + + bool ReadingValue=false; + int i = 0; + while(i < len) + { + if(!strncmp(buf+i, "//", 2)) + { + /* //; erase with spaces until newline */ + do { + buf[i] = ' '; + i++; + } while(i < len && buf[i] != '\n'); + + continue; + } + + if(ReadingValue && buf[i] == '[') { + /* If we get a [ when we thought we were inside a value, start a new + one. Back up and end the value. */ + /* Make sure this [ is the first non-whitespace character on the line. */ + bool FirstChar = true; + int j; + for(j = i-1; j >= 0 && !strchr("\r\n", buf[j]); --j) + { + if(buf[j] == ' ' || buf[j] == '\t') + continue; + + FirstChar = false; + break; + } + + if(!FirstChar) { + /* Oops, we're not; handle this like a regular character. */ + i++; + continue; + } + + AddParam(buf+value_start, j - value_start); + ReadingValue=false; + } + + /* # starts a new value. */ + if(!ReadingValue && buf[i] == '[') { + AddValue(); + ReadingValue=true; + } + + if(!ReadingValue) + { + i++; + continue; /* nothing else is meaningful outside of a value */ + } + + /* ']' ends the current value bracket */ + if(buf[i] == ']') + { + AddParam( buf+value_start, i - value_start ); + i++; + // START TO READ IN LYRICS HERE + value_start = i; + // The next value cannot be a '['.. This WILL cause problems if it is. + // ** NOTE: I will add error-checking here soon. -- Miryokuteki + continue; + } + + + /* [ begins a new param. */ + if(buf[i] == '[' ) + { + i++; /* Start AFTER the bracket */ + value_start = i; + continue; + } + + + /* ; ends the current value/lyric. */ + if(buf[i] == '\n' || buf[i] == '\r\n') + { + // Lyric line ends at a line break. Add the param + AddParam(buf+value_start, i - value_start); + ReadingValue=false; + } + + i++; + } + + /* Add any unterminated value at the very end. */ + if(ReadingValue) + { + AddParam(buf+value_start, i - value_start); + } +} + +// returns true if successful, false otherwise +bool LRCFile::ReadFile( CString sNewPath ) +{ + int fd; + + /* Open a file */ + if( (fd = open(sNewPath, O_RDONLY, 0)) == -1 ) + return false; + + int iBufferSize = GetFileSizeInBytes(sNewPath) + 1000; // +1000 because sometimes the bytes read is > filelength. Why? + + // allocate a string to hold the file + char* szFileString = new char[iBufferSize]; + + int iBytesRead = read( fd, szFileString, iBufferSize ); + close( fd ); + + ASSERT( iBufferSize > iBytesRead ); + szFileString[iBytesRead] = '\0'; + + ReadBuf(szFileString, iBytesRead); + + delete [] szFileString; + + return true; +} + +CString LRCFile::GetParam(unsigned val, unsigned par) const +{ + if(val >= GetNumValues()) return ""; + if(par >= GetNumParams(val)) return ""; + + return values[val].params[par]; +} diff --git a/stepmania/src/LRCFile.h b/stepmania/src/LRCFile.h new file mode 100644 index 0000000000..cc3d79d724 --- /dev/null +++ b/stepmania/src/LRCFile.h @@ -0,0 +1,46 @@ +#ifndef LRCFILE_H +#define LRCFILE_H +/* +----------------------------------------------------------------------------- + Class: LRCFile + + Desc: Wrapper for reading an LRC Lyrics file. + + Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved. + Chris Danford + Glenn Maynard + Kevin Slaughter +----------------------------------------------------------------------------- +*/ + + +class LRCFile +{ +public: + /* #param:param:param:param; <- one whole value */ + struct value_t + { + vector params; + + CString operator[](unsigned i) const { if(i >= params.size()) return ""; return params[i]; } + }; + + virtual ~LRCFile() { } + + //returns true if successful, false otherwise + bool ReadFile( CString sFilePath ); + + unsigned GetNumValues() const { return values.size(); } + unsigned GetNumParams(unsigned val) const { if(val >= GetNumValues()) return 0; return values[val].params.size(); } + const value_t &GetValue(unsigned val) const { ASSERT(val < GetNumValues()); return values[val]; } + CString GetParam(unsigned val, unsigned par) const; + +private: + void ReadBuf( char *buf, int len ); + void AddParam( char *buf, int len ); + void AddValue(); + + vector values; +}; + +#endif diff --git a/stepmania/src/LyricsLoader.cpp b/stepmania/src/LyricsLoader.cpp new file mode 100644 index 0000000000..adca5c2548 --- /dev/null +++ b/stepmania/src/LyricsLoader.cpp @@ -0,0 +1,97 @@ +#include "global.h" +/* + Loader for lyrics files + By: Kevin Slaughter +*/ +#include "RageLog.h" +#include "RageException.h" +#include "RageUtil.h" +#include "LRCFile.h" +#include "LyricsLoader.h" + +#include +using namespace std; + + +bool LyricsLoader::LoadFromLRCFile( CString sPath, Song &out ) +{ + LOG->Trace( "Song::LoadFromLRCFile(%s)", sPath.GetString() ); + + + LRCFile lrc; + bool bResult = lrc.ReadFile( sPath ); + if( !bResult ) + RageException::Throw( "Error opening file '%s' for reading.", sPath.GetString() ); + + unsigned iLineCount = 0; + for( unsigned i=0; iWarn("Got \"%s\" tag with no parameters", sValueName.GetString()); + continue; + } + + // handle the data + if( 0==stricmp(sValueName,"COLOUR") ) + { + // set color var here + LOG->Trace("\n\n\n Got color tag from lyric file \n\n\n"); + 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! */ + + // 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); + CString m_sLyric = sValueData; + CString m_sStartTime = sValueName; + //-- + + //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 ) ); + } + + } + + return true; +} + +void LyricsLoader::GetApplicableFiles( CString sPath, CStringArray &out ) +{ + GetDirListing( sPath + CString("*.dwi"), out ); +} + +bool LyricsLoader::LoadFromDir( CString sPath, Song &out ) +{ + CStringArray aFileNames; + GetApplicableFiles( sPath, aFileNames ); + + if( aFileNames.size() > 1 ) + RageException::Throw( "There is more than one DWI file in '%s'. There should be only one!", sPath.GetString() ); + + /* We should have exactly one; if we had none, we shouldn't have been + * called to begin with. */ + ASSERT( aFileNames.size() == 1 ); + + return LoadFromLRCFile( sPath + aFileNames[0], out ); +} + diff --git a/stepmania/src/LyricsLoader.h b/stepmania/src/LyricsLoader.h new file mode 100644 index 0000000000..690f181d9c --- /dev/null +++ b/stepmania/src/LyricsLoader.h @@ -0,0 +1,23 @@ +#ifndef LYRICS_LOADER_H +#define LYRICS_LOADER_H +/* + Declares for lyrics loader + By: Kevin Slaughter +*/ + +#include "song.h" +//#include "GameInput.h" + +class LyricsLoader { + //bool LoadFromLRCFile( CString sPath, Song &out ); +public: + void GetApplicableFiles( CString sPath, CStringArray &out ); + bool Loadable( CString sPath ); + bool LoadFromDir( CString sPath, Song &out ); + bool LoadFromLRCFile( CString sPath, Song &out ); +private: + LyricSegment LySeg; + float fSecs; +}; + +#endif