static void GetFilterToFileNames( const RString sBaseDir, const Song *pSong, set<RString> &vsPossibleFileNamesOut ) { vsPossibleFileNamesOut.clear(); if( pSong->m_sGenre.empty() ) return; ASSERT( !pSong->m_sGroupName.empty() ); IniFile ini; RString sPath = sBaseDir+pSong->m_sGroupName+"/"+"BackgroundMapping.ini"; ini.ReadFile( sPath ); RString sSection; bool bSuccess = ini.GetValue( "GenreToSection", pSong->m_sGenre, sSection ); if( !bSuccess ) { LOG->Warn( "Genre '%s' isn't mapped", pSong->m_sGenre.c_str() ); return; } XNode *pSection = ini.GetChild( sSection ); if( pSection == NULL ) { ASSERT_M( 0, ssprintf("File '%s' refers to a section '%s' that is missing.", sPath.c_str(), sSection.c_str()) ); return; } FOREACH_CONST_Attr( pSection, p ) vsPossibleFileNamesOut.insert( p->first ); }
void PlayerAI::InitFromDisk() { IniFile ini; ini.ReadFile( AI_PATH ); for( int i=0; i<NUM_SKILL_LEVELS; i++ ) { CString sKey = ssprintf("Skill%d", i); XNode* pNode = ini.GetChild(sKey); if( pNode == NULL ) RageException::Throw( "AI.ini: '%s' doesn't exist.", sKey.c_str() ); TapScoreDistribution& dist = g_Distributions[i]; dist.fPercent[TNS_NONE] = 0; pNode->GetAttrValue( "MissWeight", dist.fPercent[TNS_MISS] ); pNode->GetAttrValue( "BooWeight", dist.fPercent[TNS_BOO] ); pNode->GetAttrValue( "GoodWeight", dist.fPercent[TNS_GOOD] ); pNode->GetAttrValue( "GreatWeight", dist.fPercent[TNS_GREAT] ); pNode->GetAttrValue( "PerfectWeight", dist.fPercent[TNS_PERFECT] ); pNode->GetAttrValue( "MarvelousWeight", dist.fPercent[TNS_MARVELOUS] ); float fSum = 0; for( int j=0; j<NUM_TAP_NOTE_SCORES; j++ ) fSum += dist.fPercent[j]; for( int j=0; j<NUM_TAP_NOTE_SCORES; j++ ) dist.fPercent[j] /= fSum; } }
// Sprite file has the format: // // [Sprite] // Texture=Textures\Logo.bmp // Frame0000=0 // Delay0000=1.0 // Frame0001=3 // Delay0000=2.0 // BaseRotationXDegrees=0 // BaseRotationYDegrees=0 // BaseRotationZDegrees=0 // BaseZoomX=1 // BaseZoomY=1 // BaseZoomZ=1 bool Sprite::LoadFromSpriteFile( RageTextureID ID ) { LOG->Trace( ssprintf("Sprite::LoadFromSpriteFile(%s)", ID.filename.c_str()) ); //Init(); m_sSpritePath = ID.filename; // read sprite file IniFile ini; if( !ini.ReadFile( m_sSpritePath ) ) RageException::Throw( "Error opening Sprite file '%s'.", m_sSpritePath.c_str() ); LoadFromNode( Dirname(m_sSpritePath), ini.GetChild("Sprite") ); return true; }
void InputMapper::ReadMappingsFromDisk() { ASSERT( GAMEMAN != NULL ); ClearAllMappings(); IniFile ini; if( !ini.ReadFile( KEYMAPS_PATH ) ) LOG->Trace( "Couldn't open mapping file \"%s\": %s.", KEYMAPS_PATH, ini.GetError().c_str() ); const Game *pGame = GAMESTATE->GetCurrentGame(); const XNode *Key = ini.GetChild( pGame->m_szName ); if( Key ) { FOREACH_CONST_Attr( Key, i ) { const CString &name = i->m_sName; const CString &value = i->m_sValue; GameInput GameI; GameI.fromString( pGame, name ); CStringArray sDeviceInputStrings; split( value, ",", sDeviceInputStrings, false ); for( unsigned i=0; i<sDeviceInputStrings.size() && i<unsigned(NUM_GAME_TO_DEVICE_SLOTS); i++ ) { DeviceInput DeviceI; DeviceI.fromString( sDeviceInputStrings[i] ); if( DeviceI.IsValid() ) SetInputMap( DeviceI, GameI, i ); } } } AddDefaultMappingsForCurrentGameIfUnmapped(); }
void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &sPageName, RString sChars ) { cfg.m_sTexturePath = sTexturePath; /* If we have any characters to map, add them. */ for( unsigned n=0; n<sChars.size(); n++ ) { char c = sChars[n]; cfg.CharToGlyphNo[c] = n; } int iNumFramesWide, iNumFramesHigh; RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh ); int iNumFrames = iNumFramesWide * iNumFramesHigh; ini.RenameKey("Char Widths", "main"); // LOG->Trace("Loading font page '%s' settings from page name '%s'", // TexturePath.c_str(), sPageName.c_str()); ini.GetValue( sPageName, "DrawExtraPixelsLeft", cfg.m_iDrawExtraPixelsLeft ); ini.GetValue( sPageName, "DrawExtraPixelsRight", cfg.m_iDrawExtraPixelsRight ); ini.GetValue( sPageName, "AddToAllWidths", cfg.m_iAddToAllWidths ); ini.GetValue( sPageName, "ScaleAllWidthsBy", cfg.m_fScaleAllWidthsBy ); ini.GetValue( sPageName, "LineSpacing", cfg.m_iLineSpacing ); ini.GetValue( sPageName, "Top", cfg.m_iTop ); ini.GetValue( sPageName, "Baseline", cfg.m_iBaseline ); ini.GetValue( sPageName, "DefaultWidth", cfg.m_iDefaultWidth ); ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels ); ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints ); /* Iterate over all keys. */ const XNode* pNode = ini.GetChild( sPageName ); if( pNode ) { FOREACH_CONST_Attr( pNode, pAttr ) { RString sName = pAttr->first; const XNodeValue *pValue = pAttr->second; sName.MakeUpper(); /* If val is an integer, it's a width, eg. "10=27". */ if( IsAnInt(sName) ) { cfg.m_mapGlyphWidths[atoi(sName)] = pValue->GetValue<int>(); continue; } /* "map codepoint=frame" maps a char to a frame. */ if( sName.substr(0, 4) == "MAP " ) { /* * map CODEPOINT=frame. CODEPOINT can be * 1. U+hexval * 2. an alias ("oq") * 3. a character in quotes ("X") * * map 1=2 is the same as * range unicode #1-1=2 */ RString sCodepoint = sName.substr(4); /* "CODEPOINT" */ wchar_t c; if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) ) sscanf( sCodepoint.substr(2).c_str(), "%x", &c ); else if( sCodepoint.size() > 0 && utf8_get_char_len(sCodepoint[0]) == int(sCodepoint.size()) ) { c = utf8_get_char( sCodepoint.c_str() ); if(c == wchar_t(-1)) LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); } else if( !FontCharAliases::GetChar(sCodepoint, c) ) { LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); continue; } cfg.CharToGlyphNo[c] = pValue->GetValue<int>(); continue; } if( sName.substr(0, 6) == "RANGE " ) { /* * range CODESET=first_frame or * range CODESET #start-end=first_frame * eg * range CP1252=0 (default for 256-frame fonts) * range ASCII=0 (default for 128-frame fonts) * * (Start and end are in hex.) * * Map two high-bit portions of ISO-8859- to one font: * range ISO-8859-2 #80-FF=0 * range ISO-8859-3 #80-FF=128 * * Map hiragana to 0-84: * range Unicode #3041-3094=0 */ vector<RString> asMatches; static Regex parse("^RANGE ([A-Z0-9\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$"); bool bMatch = parse.Compare( sName, asMatches ); ASSERT( asMatches.size() == 4 ); /* 4 parens */ if( !bMatch || asMatches[0].empty() ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": parse error.", ini.GetPath().c_str(), sName.c_str() ); /* We must have either 1 match (just the codeset) or 4 (the whole thing). */ int iCount = -1; int iFirst = 0; if( !asMatches[2].empty() ) { sscanf( asMatches[2].c_str(), "%x", &iFirst ); int iLast; sscanf( asMatches[3].c_str(), "%x", &iLast ); if( iLast < iFirst ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": %i < %i.", ini.GetPath().c_str(), sName.c_str(), iLast, iFirst ); iCount = iLast - iFirst + 1; } RString sRet = cfg.MapRange( asMatches[0], iFirst, pValue->GetValue<int>(), iCount ); if( !sRet.empty() ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": %s.", ini.GetPath().c_str(), sName.c_str(), sRet.c_str() ); continue; } if( sName.substr(0, 5) == "LINE " ) { /* line ROW=CHAR1CHAR2CHAR3CHAR4 * eg. * line 0=ABCDEFGH * * This lets us assign characters very compactly and readably. */ RString sRowStr = sName.substr(5); TrimLeft( sRowStr ); ASSERT( IsAnInt(sRowStr) ); const int iRow = atoi( sRowStr.c_str() ); const int iFirstFrame = iRow * iNumFramesWide; if( iRow > iNumFramesHigh ) RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high.", ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh ); /* Decode the string. */ const wstring wdata( RStringToWstring(pValue->GetValue<RString>()) ); if( int(wdata.size()) > iNumFramesWide ) RageException::Throw( "The font definition \"%s\" assigns %i characters to row %i (\"%ls\"), but the font is only %i characters wide.", ini.GetPath().c_str(), (int)wdata.size(), iRow, wdata.c_str(), iNumFramesWide ); for( unsigned i = 0; i < wdata.size(); ++i ) cfg.CharToGlyphNo[wdata[i]] = iFirstFrame+i; } } }
// NOTE: This function can return NULL if the actor should not be displayed. // Callers should be aware of this and handle it appropriately. Actor* ActorUtil::MakeActor( const RString &sPath_, Actor *pParentActor ) { RString sPath( sPath_ ); FileType ft = GetFileType( sPath ); switch( ft ) { case FT_Lua: { auto_ptr<XNode> pNode( LoadXNodeFromLuaShowErrors(sPath) ); if( pNode.get() == NULL ) { // XNode will warn about the error return new Actor; } Actor *pRet = ActorUtil::LoadFromNode( pNode.get(), pParentActor ); return pRet; } case FT_Xml: { // Legacy actors; only supported in quirks mode if ( !PREFSMAN->m_bQuirksMode ) return new Actor; XNode xml; if ( !XmlFileUtil::LoadFromFileShowErrors(xml, sPath) ) return new Actor; XmlFileUtil::CompileXNodeTree( &xml, sPath ); XmlFileUtil::AnnotateXNodeTree( &xml, sPath ); return LoadFromNode( &xml, pParentActor ); } case FT_Directory: { if( sPath.Right(1) != "/" ) sPath += '/'; RString sXml = sPath + "default.xml"; if (DoesFileExist(sXml)) return MakeActor(sXml, pParentActor); XNode xml; xml.AppendAttr( "Class", "BGAnimation" ); xml.AppendAttr( "AniDir", sPath ); return ActorUtil::LoadFromNode( &xml, pParentActor ); } case FT_Bitmap: case FT_Movie: { XNode xml; xml.AppendAttr( "Class", "Sprite" ); xml.AppendAttr( "Texture", sPath ); return ActorUtil::LoadFromNode( &xml, pParentActor ); } case FT_Sprite: { // Legacy actor; only supported in quirks mode if( !PREFSMAN->m_bQuirksMode ) return new Actor; IniFile ini; ini.ReadFile( sPath ); XmlFileUtil::AnnotateXNodeTree( &ini, sPath ); return ActorUtil::LoadFromNode( ini.GetChild("Sprite"), pParentActor ); } case FT_Model: { XNode xml; xml.AppendAttr( "Class", "Model" ); xml.AppendAttr( "Meshes", sPath ); xml.AppendAttr( "Materials", sPath ); xml.AppendAttr( "Bones", sPath ); return ActorUtil::LoadFromNode( &xml, pParentActor ); } default: { LOG->Warn( "File \"%s\" has unknown type, \"%s\".", sPath.c_str(), FileTypeToString(ft).c_str() ); XNode xml; xml.AppendAttr( "Class", "Actor" ); return ActorUtil::LoadFromNode( &xml, pParentActor ); } } }