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 );
}
Exemple #2
0
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;
	}
}
Exemple #3
0
// 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;
}
Exemple #4
0
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();
}
Exemple #5
0
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;
			}
		}
	}
Exemple #6
0
// 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 );
		}
	}
}