diff --git a/stepmania/src/IniFile.cpp b/stepmania/src/IniFile.cpp index d0bb4eab8a..5a69d5835c 100644 --- a/stepmania/src/IniFile.cpp +++ b/stepmania/src/IniFile.cpp @@ -242,6 +242,152 @@ void IniFile::RenameKey(const CString &from, const CString &to) keys.erase(from); } + + + + + + + + + +bool IniFilePreserveOrder::ReadFile( const CString &sPath ) +{ + m_sPath = sPath; + CHECKPOINT_M( ssprintf("Reading '%s'",m_sPath.c_str()) ); + + RageFile f; + if( !f.Open( m_sPath ) ) + { + LOG->Trace( "Reading '%s' failed: %s", m_sPath.c_str(), f.GetError().c_str() ); + m_sError = f.GetError(); + return 0; + } + + CString keyname; + while( 1 ) + { + CString line; + switch( f.GetLine(line) ) + { + case -1: + m_sError = f.GetError(); + return false; + case 0: + return true; /* eof */ + } + + if( line.size() >= 3 && + line[0] == '\xef' && + line[1] == '\xbb' && + line[2] == '\xbf' + ) + { + /* Obnoxious NT marker for UTF-8. Remove it. */ + line.erase(0, 3); + } + + if( line == "" ) + continue; + + if( line.substr(0, 2) == "//" || line.substr(0) == "#" ) + continue; /* comment */ + + if( line[0] == '[' && line[line.GetLength()-1] == ']' ) + { + /* New section. */ + keyname = line.substr(1, line.size()-2); + } + else //if a value + { + int iEqualIndex = line.Find("="); + if( iEqualIndex != -1 ) + { + CString valuename = line.Left(iEqualIndex); + CString value = line.Right(line.GetLength()-valuename.GetLength()-1); + SetValue(keyname,valuename,value); + } + } + } +} + +bool IniFilePreserveOrder::WriteFile( const CString &sPath ) +{ + RageFile f; + if( !f.Open( sPath, RageFile::WRITE ) ) + { + LOG->Trace( "Writing '%s' failed: %s", sPath.c_str(), f.GetError().c_str() ); + m_sError = f.GetError(); + return false; + } + + for( keymap::const_iterator k = keys.begin(); k != keys.end(); ++k ) + { + if (k->second.empty()) + continue; + + if( f.PutLine( ssprintf("[%s]", k->first.c_str()) ) == -1 ) + { + m_sError = f.GetError(); + return false; + } + + + for( key::const_iterator i = k->second.begin(); i != k->second.end(); ++i ) + f.PutLine( ssprintf("%s=%s", i->first.c_str(), i->second.c_str()) ); + + if( f.PutLine( "" ) == -1 ) + { + m_sError = f.GetError(); + return false; + } + } + return true; +} + +bool IniFilePreserveOrder::SetValue( const CString &keyname, const CString &valuename, const CString &value ) +{ + int iIndexOfKey = -1; + for( unsigned i=0; i key_value; + typedef vector key; + typedef pair keymap_value; + typedef vector keymap; + + typedef keymap::const_iterator const_iterator; + const_iterator begin() const { return keys.begin(); } + const_iterator end() const { return keys.end(); } + + typedef keymap::iterator iterator; + iterator begin() { return keys.begin(); } + iterator end() { return keys.end(); } + +private: + CString m_sPath; + + keymap keys; + + mutable CString m_sError; + +public: + /* Retrieve the filename of the last file loaded. */ + CString GetPath() const { return m_sPath; } + const CString &GetError() const { return m_sError; } + + bool ReadFile( const CString &sPath ); + bool WriteFile( const CString &sPath ); + + bool SetValue( const CString &key, const CString &valuename, const CString &value ); +}; + #endif /* diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp index 4fde5ff465..7106771cb6 100644 --- a/stepmania/src/ThemeManager.cpp +++ b/stepmania/src/ThemeManager.cpp @@ -174,6 +174,39 @@ void ThemeManager::LoadThemeRecursive( deque &theme, const CString &sThem if( !sThemeName.CompareNoCase(BASE_THEME_NAME) ) loaded_base = true; + + // Uncomment to write "metrics.ini.new" that automatically converts absolute + // screen positions to use the SCREEN_* constants. +#if 0 + IniFilePreserveOrder ini; + ini.ReadFile( GetMetricsIniPath(sThemeName) ); + for( IniFilePreserveOrder::iterator k = ini.begin(); k != ini.end(); k++ ) + { + IniFilePreserveOrder::key &k2 = k->second; + for( IniFilePreserveOrder::key::iterator v = k2.begin(); v != k2.end(); v++ ) + { + const CString &sName = v->first; + CString &sValue = v->second; + + if( sValue.empty() ) + continue; + if( !isdigit(sValue[0]) ) + continue; + if( sName.Right(1) == "SpacingX" || sName.Right(1) == "SpacingY" ) + continue; + + int i = atoi( sValue ); + if( sName.Right(1) == "X" ) + sValue = "SCREEN_CENTER_X" + ssprintf("%+d", i-320); + if( sName.Right(1) == "Y" ) + sValue = "SCREEN_CENTER_Y" + ssprintf("%+d", i-240); + } + } + ini.WriteFile( GetMetricsIniPath(sThemeName)+".new" ); +#endif + + + Theme t; t.sThemeName = sThemeName; t.iniMetrics.ReadFile( GetMetricsIniPath(sThemeName) );