示例#1
0
static bool ReadBMSFile( const RString &sPath, NameToData_t &mapNameToData )
{
	RageFile file;
	if( !file.Open(sPath) )
	{
		LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", file.GetError().c_str() );
		return false;
	}

	while( !file.AtEOF() )
	{
		RString line;
		if( file.GetLine(line) == -1 )
		{
			LOG->UserLog( "Song file", sPath, "had a read error: %s", file.GetError().c_str() );
			return false;
		}

		StripCrnl( line );

		// BMS value names can be separated by a space or a colon.
		size_t iIndexOfSeparator = line.find_first_of( ": " );
		RString value_name = line.substr( 0, iIndexOfSeparator );
		RString value_data;
		if( iIndexOfSeparator != line.npos )
			value_data = line.substr( iIndexOfSeparator+1 );

		value_name.MakeLower();
		mapNameToData.insert( make_pair(value_name, value_data) );
	}

	return true;
}
示例#2
0
bool IniFile::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;

		int ret = f.GetLine(line);
		if( ret == 0 ) /* eof */
			return true;
		if( ret < 0 )
		{
			m_sError = f.GetError();
			return false;
		}

		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);
			}
		}
	}
}
示例#3
0
bool msAnimation::LoadMilkshapeAsciiBones( CString sAniName, CString sPath )
{
	FixSlashesInPlace(sPath);
	const CString sDir = Dirname( sPath );

	RageFile f;
	if ( !f.Open(sPath) )
		RageException::Throw( "Model:: Could not open \"%s\": %s", sPath.c_str(), f.GetError().c_str() );

	CString sLine;
	int iLineNum = 0;

	msAnimation &Animation = *this;

	bool bLoaded = false;
    while( f.GetLine( sLine ) > 0 )
    {
		iLineNum++;

        if (!strncmp (sLine, "//", 2))
            continue;

        //
        // bones
        //
        int nNumBones = 0;
        if( sscanf (sLine, "Bones: %d", &nNumBones) != 1 )
			continue;

        char szName[MS_MAX_NAME];

        Animation.Bones.resize( nNumBones );

        for( int i = 0; i < nNumBones; i++ )
        {
			msBone& Bone = Animation.Bones[i];

            // name
			if( f.GetLine( sLine ) <= 0 )
				THROW;
            if (sscanf (sLine, "\"%[^\"]\"", szName) != 1)
				THROW;
            strcpy( Bone.szName, szName );

            // parent
			if( f.GetLine( sLine ) <= 0 )
				THROW;
            strcpy (szName, "");
            sscanf (sLine, "\"%[^\"]\"", szName);

            strcpy( Bone.szParentName, szName );

            // flags, position, rotation
            RageVector3 Position, Rotation;
			if( f.GetLine( sLine ) <= 0 )
				THROW;

			int nFlags;
            if (sscanf (sLine, "%d %f %f %f %f %f %f",
                &nFlags,
                &Position[0], &Position[1], &Position[2],
                &Rotation[0], &Rotation[1], &Rotation[2]) != 7)
            {
				THROW;
            }
			Rotation = RadianToDegree(Rotation);

			Bone.nFlags = nFlags;
            memcpy( &Bone.Position, &Position, sizeof(Bone.Position) );
            memcpy( &Bone.Rotation, &Rotation, sizeof(Bone.Rotation) );

            // position key count
			if( f.GetLine( sLine ) <= 0 )
				THROW;
            int nNumPositionKeys = 0;
            if (sscanf (sLine, "%d", &nNumPositionKeys) != 1)
				THROW;

            Bone.PositionKeys.resize( nNumPositionKeys );

            for( int j = 0; j < nNumPositionKeys; ++j )
            {
				if( f.GetLine( sLine ) <= 0 )
					THROW;

				float fTime;
                if (sscanf (sLine, "%f %f %f %f", &fTime, &Position[0], &Position[1], &Position[2]) != 4)
					THROW;

				msPositionKey key;
				key.fTime = fTime;
				key.Position = RageVector3( Position[0], Position[1], Position[2] );
				Bone.PositionKeys[j] = key;
            }

            // rotation key count
			if( f.GetLine( sLine ) <= 0 )
				THROW;
            int nNumRotationKeys = 0;
            if (sscanf (sLine, "%d", &nNumRotationKeys) != 1)
				THROW;

            Bone.RotationKeys.resize( nNumRotationKeys );

            for( int j = 0; j < nNumRotationKeys; ++j )
            {
				if( f.GetLine( sLine ) <= 0 )
					THROW;

				float fTime;
                if (sscanf (sLine, "%f %f %f %f", &fTime, &Rotation[0], &Rotation[1], &Rotation[2]) != 4)
					THROW;
				Rotation = RadianToDegree(Rotation);

				msRotationKey key;
				key.fTime = fTime;
				key.Rotation = RageVector3( Rotation[0], Rotation[1], Rotation[2] );
                Bone.RotationKeys[j] = key;
            }
        }

		// Ignore "Frames:" in file.  Calculate it ourself
		Animation.nTotalFrames = 0;
		for( int i = 0; i < (int)Animation.Bones.size(); i++ )
		{
			msBone& Bone = Animation.Bones[i];
			for( unsigned j = 0; j < Bone.PositionKeys.size(); ++j )
				Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.PositionKeys[j].fTime );
			for( unsigned j = 0; j < Bone.RotationKeys.size(); ++j )
				Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.RotationKeys[j].fTime );
		}
	}

	return bLoaded;
}
示例#4
0
void SanityCheck()
{
	/* Read sanity check. */
	do {
		g_TestFile = "hello";
		g_TestFilename = "file";

		RageFile test;
		if( !test.Open("/test/file", RageFile::READ ) )
			Fail( "Sanity check Open() failed: %s", test.GetError().c_str() );

		RString str;
		int got = test.GetLine( str );
		if( got <= 0 )
			Fail( "Sanity check GetLine(): got %i", got );

		if( str != "hello" )
			Fail( "Sanity check Read(): expected \"hello\", got \"%s\"", str.c_str() );
	} while(false);

	/* Read error sanity check. */
	do {
		g_TestFile = "hello world";
		g_TestFilename = "file";
		g_BytesUntilError = 5;

		RageFile test;
		if( !test.Open("/test/file", RageFile::READ ) )
			Fail( "Sanity check 2 Open() failed: %s", test.GetError().c_str() );

		RString str;
		int got = test.Read( str, 5 );
		if( got != 5 )
			Fail( "Sanity check 2 Read(): got %i", got );

		if( str != "hello" )
			Fail( "Sanity check 2 Read(): expected \"hello\", got \"%s\"", str.c_str() );

		got = test.Read( str, 5 );
		if( got != -1 )
			Fail( "Sanity check 2 GetLine(): expected -1, got %i", got );

		if( test.GetError() != "Fake error" )
			Fail( "Sanity check 2 GetError(): expected \"Fake error\", got \"%s\"", test.GetError().c_str() );
	} while(false);
	
	/* Write error sanity check. */
	do {
		g_TestFilename = "file";
		g_BytesUntilError = 5;

		RageFile test;
		if( !test.Open("/test/file", RageFile::WRITE ) )
			Fail( "Write error check Open() failed: %s", test.GetError().c_str() );

		int wrote = test.Write( "test", 4 );
		if( wrote != 4 )
			Fail( "Write error check Write(): wrote %i", wrote );

		wrote = test.Write( "ing", 3 );
		if( wrote != -1 )
			Fail( "Write error check Write(): expected -1, got %i", wrote );

		if( test.GetError() != "Fake error" )
			Fail( "Write error check GetError(): expected \"Fake error\", got \"%s\"", test.GetError().c_str() );
	} while(false);
}
void MemoryCardDriverThreaded_Linux::GetUSBStorageDevices( vector<UsbStorageDevice>& vDevicesOut )
{
	LOG->Trace( "GetUSBStorageDevices" );
	
	vDevicesOut.clear();

	{
		vector<RString> asDevices;
		RString sBlockDevicePath = "/sys/block/";
		GetFileList( sBlockDevicePath, asDevices );

		for( unsigned i = 0; i < asDevices.size(); ++i )
		{
			const RString &sDevice = asDevices[i];
			if( sDevice == "." || sDevice == ".." )
				continue;

			UsbStorageDevice usbd;

			RString sPath = sBlockDevicePath + sDevice + "/";
			usbd.sSysPath = sPath;

			/* Ignore non-removable devices. */
			RString sBuf;
			if( !ReadFile( sPath + "removable", sBuf ) )
				continue; // already warned
			if( atoi(sBuf) != 1 )
				continue;

			/*
			 * The kernel isn't exposing all of /sys atomically, so we end up missing
			 * the partition due to it not being shown yet.  It won't show up until the
			 * kernel has scanned the partition table, which can take a variable amount
			 * of time, sometimes over a second.  Watch for the "queue" sysfs directory,
			 * which is created after this, to tell when partition directories are created.
			 */
			RageTimer WaitUntil;
			WaitUntil += 5;
			RString sQueueFilePath = usbd.sSysPath + "queue";
			while(1)
			{
				if( WaitUntil.Ago() >= 0 )
				{
					LOG->Warn( "Timed out waiting for %s", sQueueFilePath.c_str() );
					break;
				}

				if( access(usbd.sSysPath, F_OK) == -1 )
				{
					LOG->Warn( "Block directory %s went away while we were waiting for %s",
							usbd.sSysPath.c_str(), sQueueFilePath.c_str() );
					break;
				}

				if( access(sQueueFilePath, F_OK) != -1 )
					break;

				usleep(10000);
			}

			/* Wait for udev to finish handling device node creation */
			ExecuteCommand( "udevadm settle" );

			/* If the first partition device exists, eg. /sys/block/uba/uba1, use it. */
			if( access(usbd.sSysPath + sDevice + "1", F_OK) != -1 )
			{
				LOG->Trace("OK");
				usbd.sDevice = "/dev/" + sDevice + "1";
			}
			else
			{
				LOG->Trace("error %s", strerror(errno));
				usbd.sDevice = "/dev/" + sDevice;
			}

			/*
			 * sPath/device should be a symlink to the actual device.  For USB
			 * devices, it looks like this:
			 *
			 * device -> ../../devices/pci0000:00/0000:00:02.1/usb2/2-1/2-1:1.0
			 *
			 * "2-1" is "bus-port".
			 */
			char szLink[256];
			int iRet = readlink( sPath + "device", szLink, sizeof(szLink) );
			if( iRet == -1 )
			{
				LOG->Warn( "readlink(\"%s\"): %s", (sPath + "device").c_str(), strerror(errno) );
			}
			else
			{
				/*
				 * The full path looks like
				 *
				 *   ../../devices/pci0000:00/0000:00:02.1/usb2/2-2/2-2.1/2-2.1:1.0
				 *
				 * In newer kernels, it looks like:
				 *
				 * ../../../3-2.1:1.0
				 *
				 * Each path element refers to a new hop in the chain.
				 *  "usb2" = second USB host
				 *  2-            second USB host,
				 *   -2           port 1 on the host,
				 *     .1         port 1 on an attached hub
				 *       .2       ... port 2 on the next hub ...
				 * 
				 * We want the bus number and the port of the last hop.  The level is
				 * the number of hops.
				 */
				szLink[iRet] = 0;
				vector<RString> asBits;
				split( szLink, "/", asBits );

				RString sHostPort = asBits[asBits.size()-1];
				if( !sHostPort.empty() )
				{
					/* Strip off the endpoint information after the colon. */
					size_t pos = sHostPort.find(':');
					if( pos != string::npos )
						sHostPort.erase( pos );
					
					/* sHostPort is eg. 2-2.1. */
					sHostPort.Replace( "-", "." );
					asBits.clear();
					split( sHostPort, ".", asBits );
					if( asBits.size() > 1 )
					{
						usbd.iBus = atoi( asBits[0] );
						usbd.iPort = atoi( asBits[asBits.size()-1] );
						usbd.iLevel = asBits.size() - 1;
					}
				}
			}

			if( ReadFile( sPath + "device/../idVendor", sBuf ) )
				sscanf( sBuf, "%x", &usbd.idVendor );

			if( ReadFile( sPath + "device/../idProduct", sBuf ) )
				sscanf( sBuf, "%x", &usbd.idProduct );

			if( ReadFile( sPath + "device/../serial", sBuf ) )
			{
				usbd.sSerial = sBuf;
				TrimRight( usbd.sSerial );
			}
			if( ReadFile( sPath + "device/../product", sBuf ) )
			{
				usbd.sProduct = sBuf;
				TrimRight( usbd.sProduct );
			}
			if( ReadFile( sPath + "device/../manufacturer", sBuf ) )
			{
				usbd.sVendor = sBuf;
				TrimRight( usbd.sVendor );
			}

			vDevicesOut.push_back( usbd );
		}
	}

	{
		// Find where each device is mounted. Output looks like:
		
		// /dev/sda1               /mnt/flash1             auto    noauto,owner 0 0
		// /dev/sdb1               /mnt/flash2             auto    noauto,owner 0 0
		// /dev/sdc1               /mnt/flash3             auto    noauto,owner 0 0
		
		RString fn = "/rootfs/etc/fstab";
		RageFile f;
		if( !f.Open(fn) )
		{
			LOG->Warn( "can't open '%s': %s", fn.c_str(), f.GetError().c_str() );
			return;
		}
		
		RString sLine;
		while( !f.AtEOF() )
		{
			switch( f.GetLine(sLine) )
			{
			case 0: continue; /* eof */
			case -1:
				LOG->Warn( "error reading '%s': %s", fn.c_str(), f.GetError().c_str() );
				return;
			}

			char szScsiDevice[1024];
			char szMountPoint[1024];
			int iRet = sscanf( sLine, "%s %s", szScsiDevice, szMountPoint );
			if( iRet != 2 || szScsiDevice[0] == '#')
				continue;	// don't process this line

			/* Get the real kernel device name, which should match
			 * the name from /sys/block, by following symlinks in
			 * /dev.  This allows us to specify persistent names in
			 * /etc/fstab using things like /dev/device/by-path. */
			char szUnderlyingDevice[PATH_MAX];
			if( realpath(szScsiDevice, szUnderlyingDevice) == NULL )
			{
				// "No such file or directory" is understandable
				if (errno != ENOENT)
					LOG->Warn( "realpath(\"%s\"): %s", szScsiDevice, strerror(errno) );
				continue;
			}

			RString sMountPoint = szMountPoint;
			TrimLeft( sMountPoint );
			TrimRight( sMountPoint );

			// search for the mountpoint corresponding to the device
			for( unsigned i=0; i<vDevicesOut.size(); i++ )
			{
				UsbStorageDevice& usbd = vDevicesOut[i];
				if( usbd.sDevice == szUnderlyingDevice )	// found our match
				{
					// Use the device entry from fstab so the mount command works
					usbd.sDevice = szScsiDevice;
					usbd.sOsMountDir = sMountPoint;
					break;	// stop looking for a match
				}
			}
		}
	}

	for( unsigned i=0; i<vDevicesOut.size(); i++ )
	{
		UsbStorageDevice& usbd = vDevicesOut[i];
		LOG->Trace( "    sDevice: %s, iBus: %d, iLevel: %d, iPort: %d, id: %04X:%04X, Vendor: '%s', Product: '%s', sSerial: \"%s\", sOsMountDir: %s",
				usbd.sDevice.c_str(), usbd.iBus, usbd.iLevel, usbd.iPort, usbd.idVendor, usbd.idProduct, usbd.sVendor.c_str(),
				usbd.sProduct.c_str(), usbd.sSerial.c_str(), usbd.sOsMountDir.c_str() );
	}
	
	/* Remove any devices that we couldn't find a mountpoint for. */
	for( unsigned i=0; i<vDevicesOut.size(); i++ )
	{
		UsbStorageDevice& usbd = vDevicesOut[i];
		if( usbd.sOsMountDir.empty() )
		{
			LOG->Trace( "Ignoring %s (couldn't find in /etc/fstab)", usbd.sDevice.c_str() );
			
			vDevicesOut.erase( vDevicesOut.begin()+i );
			--i;
		}
	}
	
	LOG->Trace( "Done with GetUSBStorageDevices" );
}
示例#6
0
void TitleSubst::Load(const CString &filename, const CString &section)
{
	RageFile f;
	if( !f.Open(filename) )
	{
		LOG->Trace("Error opening %s: %s", filename.c_str(), f.GetError().c_str() );
		return;
	}
	
	CString CurrentSection;
	TitleTrans tr;
	
	while (!f.AtEOF())
	{
		CString line;
		int ret = f.GetLine( line );
		if( ret == 0 )
			break;
		if( ret < 0 )
		{
			LOG->Trace("Error reading %s: %s", filename.c_str(), f.GetError().c_str() );
			break;
		}

		if(line.size() > 0 && utf8_get_char(line.c_str()) == 0xFEFF)
		{
			/* Annoying header that Windows puts on UTF-8 plaintext
			 * files; remove it. */
			line.erase(0, utf8_get_char_len(line[0]));
		}

		TrimLeft(line);
		TrimRight(line);

		if(line.size() == 0) continue; /* blank */
		if(line[0] == '#') continue; /* comment */

		if(!line.CompareNoCase("DontTransliterate"))
		{
			tr.translit = false;
			continue;
		}

		size_t pos = line.find_first_of(':');
		if(pos != string::npos)
		{
			/* x: y */
			CString id = line.substr(0, pos);
			CString txt = line.substr(pos+1);
			TrimLeft(txt);

			/* Surround each regex with ^(...)$, to force all comparisons to default
			 * to being a full-line match.  (Add ".*" manually if this isn't wanted.) */
			if(!id.CompareNoCase("TitleFrom")) tr.TitleFrom = "^(" + txt + ")$";
			else if(!id.CompareNoCase("ArtistFrom")) tr.ArtistFrom = "^(" + txt + ")$";
			else if(!id.CompareNoCase("SubtitleFrom")) tr.SubFrom = "^(" + txt + ")$";
			else if(!id.CompareNoCase("TitleTo")) tr.Dest.Title = txt;
			else if(!id.CompareNoCase("ArtistTo")) tr.Dest.Artist = txt;
			else if(!id.CompareNoCase("SubtitleTo")) tr.Dest.Subtitle = txt;
			else if(!id.CompareNoCase("TitleTransTo")) tr.Dest.TitleTranslit = txt;
			else if(!id.CompareNoCase("ArtistTransTo")) tr.Dest.ArtistTranslit = txt;
			else if(!id.CompareNoCase("SubtitleTransTo")) tr.Dest.SubtitleTranslit = txt;
			else
				LOG->Warn( "Unknown TitleSubst tag: \"%s\"", id.c_str() );
		}

		/* Add the translation if this is a terminator (*) or section
		 * marker ([foo]). */
		if(line[0] == '*' || line[0] == '[')
		{
			if(!CurrentSection.CompareNoCase(section))
				AddTrans(tr);
			
			/* Reset. */
			tr = TitleTrans();
		}

		if(line[0] == '[' && line[line.size()-1] == ']')
		{
			CurrentSection = line.substr(1, line.size()-2);
		}
	}
}
示例#7
0
bool Model::LoadMaterialsFromMilkshapeAscii(const std::string &_sPath,
	std::string& load_fail_reason)
{
#define LOAD_FAIL load_fail_reason= fmt::sprintf("Parse error in \"%s\" at line %d: \"%s\".", sPath.c_str(), iLineNum, sLine.c_str()); return false;
	std::string sPath = _sPath;

	FixSlashesInPlace(sPath);
	const std::string sDir = Rage::dir_name( sPath );

	RageFile f;
	if( !f.Open( sPath ) )
	{
		load_fail_reason= fmt::sprintf("Model::LoadMilkshapeAscii Could not open \"%s\": %s", sPath.c_str(), f.GetError().c_str());
		return false;
	}

	std::string sLine;
	int iLineNum = 0;

	while( f.GetLine( sLine ) > 0 )
	{
		iLineNum++;

		if( !strncmp (sLine.c_str(), "//", 2) )
		{
			continue;
		}
		int nFrame;
		if( sscanf(sLine.c_str(), "Frames: %d", &nFrame) == 1 )
		{
			// ignore
			// m_pModel->nTotalFrames = nFrame;
		}
		if( sscanf(sLine.c_str(), "Frame: %d", &nFrame) == 1 )
		{
			// ignore
			// m_pModel->nFrame = nFrame;
		}

		// materials
		int nNumMaterials = 0;
		if( sscanf(sLine.c_str(), "Materials: %d", &nNumMaterials) == 1 )
		{
			m_Materials.resize( nNumMaterials );

			char szName[256];

			for( int i = 0; i < nNumMaterials; i++ )
			{
				msMaterial& Material = m_Materials[i];

				// name
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				if( sscanf(sLine.c_str(), "\"%255[^\"]\"", szName) != 1 )
				{
					LOAD_FAIL;
				}
				Material.sName = szName;

				// ambient
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				Rage::Vector4 Ambient;
				if( sscanf(sLine.c_str(), "%f %f %f %f", &Ambient.x, &Ambient.y, &Ambient.z, &Ambient.w) != 4 )
				{
					LOAD_FAIL;
				}
				memcpy( &Material.Ambient, &Ambient, sizeof(Material.Ambient) );

				// diffuse
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				Rage::Vector4 Diffuse;
				if( sscanf(sLine.c_str(), "%f %f %f %f", &Diffuse.x, &Diffuse.y, &Diffuse.z, &Diffuse.w) != 4 )
				{
					LOAD_FAIL;
				}
				memcpy( &Material.Diffuse, &Diffuse, sizeof(Material.Diffuse) );

				// specular
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				Rage::Vector4 Specular;
				if( sscanf(sLine.c_str(), "%f %f %f %f", &Specular.x, &Specular.y, &Specular.z, &Specular.w) != 4 )
				{
					LOAD_FAIL;
				}
				memcpy( &Material.Specular, &Specular, sizeof(Material.Specular) );

				// emissive
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				Rage::Vector4 Emissive;
				if( sscanf (sLine.c_str(), "%f %f %f %f", &Emissive.x, &Emissive.y, &Emissive.z, &Emissive.w) != 4 )
				{
					LOAD_FAIL;
				}
				memcpy( &Material.Emissive, &Emissive, sizeof(Material.Emissive) );

				// shininess
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				float fShininess;
				if( !StringConversion::FromString(sLine, fShininess) )
				{
					LOAD_FAIL;
				}
				Material.fShininess = fShininess;

				// transparency
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				float fTransparency;
				if( !StringConversion::FromString(sLine, fTransparency) )
				{
					LOAD_FAIL;
				}
				Material.fTransparency = fTransparency;

				// diffuse texture
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				strcpy( szName, "" );
				sscanf( sLine.c_str(), "\"%255[^\"]\"", szName );
				std::string sDiffuseTexture = szName;

				if( sDiffuseTexture == "" )
				{
					Material.diffuse.LoadBlank();
				}
				else
				{
					std::string sTexturePath = sDir + sDiffuseTexture;
					FixSlashesInPlace( sTexturePath );
					CollapsePath( sTexturePath );
					if( !IsAFile(sTexturePath) )
					{
						load_fail_reason= fmt::sprintf("\"%s\" references a texture \"%s\" that does not exist.", sPath.c_str(), sTexturePath.c_str());
						return false;
					}

					Material.diffuse.Load( sTexturePath );
				}

				// alpha texture
				if( f.GetLine( sLine ) <= 0 )
				{
					LOAD_FAIL;
				}
				strcpy( szName, "" );
				sscanf( sLine.c_str(), "\"%255[^\"]\"", szName );
				std::string sAlphaTexture = szName;

				if( sAlphaTexture == "" )
				{
					Material.alpha.LoadBlank();
				}
				else
				{
					std::string sTexturePath = sDir + sAlphaTexture;
					FixSlashesInPlace( sTexturePath );
					CollapsePath( sTexturePath );
					if( !IsAFile(sTexturePath) )
					{
						load_fail_reason= fmt::sprintf("\"%s\" references a texture \"%s\" that does not exist.", sPath.c_str(), sTexturePath.c_str());
						return false;
					}

					Material.alpha.Load( sTexturePath );
				}
			}
		}
	}
#undef LOAD_FAIL
	return true;
}
示例#8
0
void ConditionalBGA::Load(const CString &szScreenName)
{
	RageFile file;

	CString szConditionalBGAFile = THEME->GetCurThemeDir() + szScreenName + " ConditionalBGA.ini";


//	char filepath[512];
//	strcpy(filepath,""); // empty the path first
//	strcpy(filepath,szConditionalBGAFile.c_str());
	
	LOG->Trace("ConditionalBGA Load:%s",szConditionalBGAFile.c_str());

	bool loaded = file.Open(szConditionalBGAFile,RageFile::READ);
//	FILE* fp = NULL;
//	fp = fopen(filepath,"r");
	if(!loaded)
	{
		LOG->Trace("ConditionalBGA File Not Found");
		return;
	}
	else
	{
		CString currentline;
		int bgano=0;

		while(!file.AtEOF())
		{
			file.GetLine(currentline); // get the current line
	
			// kill any possible comments
			CStringArray asKillComments;
			asKillComments.clear(); // get rid of anything in there
			split(currentline, "#",asKillComments); // A comment starting with #
			if(!asKillComments.empty())
			{
				currentline = asKillComments[0]; // there was some commentstuff here, take the first bit to be the actual data
			}
			asKillComments.clear(); // get rid of anything in there
			split(currentline, "/",asKillComments); // A comment starting with // or /*
			if(!asKillComments.empty())
			{
				currentline = asKillComments[0]; // there was some commentstuff here, take the first bit to be the actual data
			}
			TrimRight(currentline); // nuke trailing whitespace

			// start parsing the data
			if(currentline.c_str()[0] == '[') // we found a new bganimation
			{
				if(!m_bgainfo.empty()) // last one wasnt empty
				{
					CheckBgaRequirements(m_bgainfo[bgano]);
					bgano++;
				}
				BgaCondInfo temp;
				m_bgainfo.push_back(temp);
				ClearINFO(bgano); // wipe out the old info structure.

				CStringArray asSplitLine;
				split(currentline,"[",asSplitLine);
				split(asSplitLine[0],"]",asSplitLine);
				if(!asSplitLine.empty() && asSplitLine.size() >= 1)
					m_bgainfo[bgano].bganame = asSplitLine[asSplitLine.size() - 1];
			}
			else
			{
				CStringArray asSplitLine;
				split(currentline,":",asSplitLine);
				if(asSplitLine.empty()) continue;

				if(!asSplitLine[0].CompareNoCase("clear") && asSplitLine.size() > 1)
				{
					if(!asSplitLine[1].CompareNoCase("true") || !asSplitLine[1].CompareNoCase("cleared") || !asSplitLine[1].CompareNoCase("clear")) // true / clear (any clear condition)
						m_bgainfo[bgano].cleared = CBGA_CSCLEARED;
					else if(!asSplitLine[1].CompareNoCase("false") || !asSplitLine[1].CompareNoCase("failed")) // false / failed 
						m_bgainfo[bgano].cleared = CBGA_CSFAILED;
					else if(!asSplitLine[1].CompareNoCase("maxcombo") || !asSplitLine[1].CompareNoCase("fullcombo")) // passed with maxcombo 
						m_bgainfo[bgano].cleared = CBGA_CSMAXCOMBO;
					else if(!asSplitLine[1].CompareNoCase("brokencombo")) // passed with a broken combo 
						m_bgainfo[bgano].cleared = CBGA_CSBROKECOMBO;	

			//		LOG->Trace("Clear Conditon: %d",info.cleared);
				}
				if(!asSplitLine[0].CompareNoCase("songtitle") && asSplitLine.size() > 1)
				{
					m_bgainfo[bgano].songtitle = asSplitLine[1];
				//	LOG->Trace("SongTitle: %s",info.songtitle.c_str());
				}
				if(!asSplitLine[0].CompareNoCase("songartist") && asSplitLine.size() > 1)
				{
					m_bgainfo[bgano].songartist = asSplitLine[1];
				//	LOG->Trace("SongArtist: %s",info.songartist.c_str());
				}
				if(!asSplitLine[0].CompareNoCase("songday") && asSplitLine.size() > 1)
				{
					CStringArray asDays;
					split( asSplitLine[1], ",", asDays );
					for( unsigned d=0; d<asDays.size(); d++ )
					{
						int dn = atoi(asDays[d].c_str());
						if(!(dn < 1 || dn > 32)) // ignore if date is out of range
						{
							m_bgainfo[bgano].songdays.push_back(dn);
						}
					}
			//		for(d=0; d<info.songdays.size(); d++)
			//		{
			//			LOG->Trace("SongDay: %d",info.songdays[d]);
			//		}
				}
				if(!asSplitLine[0].CompareNoCase("songmonth") && asSplitLine.size() > 1)
				{
					CStringArray asMonths;
					split( asSplitLine[1], ",", asMonths );
					for( unsigned d=0; d<asMonths.size(); d++ )
					{
						int dn = atoi(asMonths[d].c_str());
						if(!(dn < 1 || dn > 12)) // ignore if date is out of range
						{
							m_bgainfo[bgano].songmonths.push_back(dn);
						}
					}
		//			for(d=0; d<info.songmonths.size(); d++)
		//			{
		//				LOG->Trace("SongMonth: %d",info.songmonths[d]);
		//			}
				}

				// foot meter ratings
				if(!asSplitLine[0].CompareNoCase("songdifficulty") && asSplitLine.size() > 1)
				{
					CStringArray asDifficulties;
					split( asSplitLine[1], ",", asDifficulties );
					
					for(unsigned d=0;d<asDifficulties.size();d++)
					{
						// check to see if the last character is a +
						bool bHandled = false;
						if(asDifficulties[d].c_str()[strlen(asDifficulties[d].c_str())-1] == '+')
						{
							bHandled = true;
							CStringArray asVal;
							split(asDifficulties[d],"+",asVal);
							int temp=0;
							temp = 0 - atoi(asVal[0].c_str()); // negative numbers will indicate 'greater than' for this system
							m_bgainfo[bgano].songmeters.push_back(temp);
						}

						if(!bHandled) // didnt find the + (gt) so find a - (range)
						{
							bool isarange=false;
							for(unsigned b=0; b<strlen(asDifficulties[d].c_str());b++)
							{
								if(asDifficulties[d].c_str()[b] == '-')
								{
									bHandled = isarange = true;
									break;
								}
							}
							if(isarange)
							{
								CStringArray asVal;
								split(asDifficulties[d],"-",asVal);
								int imin=0,imax=0,itmp=0;
								imin=atoi(asVal[0].c_str());
								imax=atoi(asVal[1].c_str());
								itmp=imin;
								while(itmp<=imax) // fill in the values between the min and max range inclusive
								{
									m_bgainfo[bgano].songmeters.push_back(itmp);
									itmp++;
								}
							}
						}

						if(!bHandled) // its not a range so must be a value on its own
						{
							int tmp = atoi(asDifficulties[d].c_str());
							m_bgainfo[bgano].songmeters.push_back(tmp);
						}

					}
				}

				// mods that mustn't be present
				if(!asSplitLine[0].CompareNoCase("moddisallow") && asSplitLine.size() > 1)
				{
					m_bgainfo[bgano].dpoused = true;
					m_bgainfo[bgano].disallowedpo.FromString(asSplitLine[1]);

				}
				
				// heavy, light e.t.c.
				if(!asSplitLine[0].CompareNoCase("songrating") && asSplitLine.size() > 1)
				{
					CStringArray asDifficulties;
					split( asSplitLine[1], ",", asDifficulties );
					for( unsigned d=0; d<asDifficulties.size(); d++ )
					{
						m_bgainfo[bgano].difficulties.push_back(StringToDifficulty(asDifficulties[d]));
					}
		//			for(d=0; d<info.difficulties.size(); d++)
		//			{
		//				LOG->Trace("Difficulty: %d",info.difficulties[d]);
		//			}
				}
				if(!asSplitLine[0].CompareNoCase("grade") && asSplitLine.size() > 1)
				{
					CStringArray asGrades;
					split( asSplitLine[1], ",", asGrades );
					for( unsigned d=0; d<asGrades.size(); d++ )
					{
						m_bgainfo[bgano].grades.push_back(StringToGrade(asGrades[d]));
					}

				}
				if(!asSplitLine[0].CompareNoCase("style") && asSplitLine.size() > 1)
				{
					LOG->Info("Comparing Styles");
					CStringArray asStyles;
					split( asSplitLine[1], ",", asStyles );
					for( unsigned d=0; d<asStyles.size(); d++ )
					{
						LOG->Info( "Style:%s", asStyles[d].c_str() );

						m_bgainfo[bgano].styles.push_back(GAMEMAN->GameAndStringToStyle(GAMESTATE->m_pCurGame,asStyles[d]));
					}

				}


			}

		}
		if(bganimtouse.CompareNoCase("")!=0)
		{
			LOG->Info("Best Match BGA Was: %s",bganimtouse.c_str());
			bganim.LoadFromAniDir( THEME->GetPathToB(bganimtouse) );
		}

	}
	file.Close(); 
}
示例#9
0
void RageModelGeometry::LoadMilkshapeAscii( const std::string& _sPath, bool bNeedsNormals )
{
	std::string sPath = _sPath;
	FixSlashesInPlace(sPath);
	const std::string sDir = Rage::dir_name( sPath );

	RageFile f;
	if( !f.Open( sPath ) )
		RageException::Throw( "RageModelGeometry::LoadMilkshapeAscii Could not open \"%s\": %s", sPath.c_str(), f.GetError().c_str() );

	std::string sLine;
	int iLineNum = 0;
	char szName[MS_MAX_NAME];
	int nFlags, nIndex;

	RageVec3ClearBounds( m_vMins, m_vMaxs );

	while( f.GetLine( sLine ) > 0 )
	{
		iLineNum++;

		if( !strncmp(sLine.c_str(), "//", 2) )
			continue;

		int nFrame;
		if( sscanf(sLine.c_str(), "Frames: %d", &nFrame) == 1 )
		{
			// ignore
			// m_pRageModelGeometry->nTotalFrames = nFrame;
		}
		if( sscanf(sLine.c_str(), "Frame: %d", &nFrame) == 1 )
		{
			// ignore
			// m_pRageModelGeometry->nFrame = nFrame;
		}

		int nNumMeshes = 0;
		if( sscanf(sLine.c_str(), "Meshes: %d", &nNumMeshes) == 1 )
		{
			ASSERT( m_Meshes.empty() );
			m_Meshes.resize( nNumMeshes );

			for( int i = 0; i < nNumMeshes; i++ )
			{
				msMesh &mesh = m_Meshes[i];
				vector<Rage::ModelVertex> &Vertices = mesh.Vertices;
				vector<msTriangle> &Triangles = mesh.Triangles;

				if( f.GetLine( sLine ) <= 0 )
					THROW;

				// mesh: name, flags, material index
				if( sscanf (sLine.c_str(), "\"%31[^\"]\" %d %d",szName, &nFlags, &nIndex) != 3 )
					THROW;

				mesh.sName = szName;
				// mesh.nFlags = nFlags;
				mesh.nMaterialIndex = (uint8_t) nIndex;

				mesh.m_iBoneIndex = -1;

				//
				// vertices
				//
				if( f.GetLine( sLine ) <= 0 )
					THROW;

				int nNumVertices = 0;
				if( sscanf (sLine.c_str(), "%d", &nNumVertices) != 1 )
					THROW;

				Vertices.resize( nNumVertices );

				for( int j = 0; j < nNumVertices; j++ )
				{
					Rage::ModelVertex &v = Vertices[j];

					if( f.GetLine( sLine ) <= 0 )
						THROW;

					if( sscanf(sLine.c_str(), "%d %f %f %f %f %f %d",
								&nFlags,
								&v.p.x, &v.p.y, &v.p.z,
								&v.t.x, &v.t.y,
								&nIndex
						   ) != 7 )
					{
						THROW;
					}

					// vertex.nFlags = nFlags;
					if( nFlags & 1 )
						v.TextureMatrixScale.x = 0;
					if( nFlags & 2 )
						v.TextureMatrixScale.y = 0;
					if( nFlags & 4 )
					{
						v.t.x = v.p.x / v.t.x;
						v.t.y = v.p.y / v.t.y;
					}
					v.bone = (uint8_t) nIndex;
					RageVec3AddToBounds( v.p, m_vMins, m_vMaxs );
				}


				//
				// normals
				//
				if( f.GetLine( sLine ) <= 0 )
					THROW;

				int nNumNormals = 0;
				if( sscanf(sLine.c_str(), "%d", &nNumNormals) != 1 )
					THROW;

				vector<Rage::Vector3> Normals;
				Normals.resize( nNumNormals );
				for( int j = 0; j < nNumNormals; j++ )
				{
					if( f.GetLine( sLine ) <= 0 )
						THROW;

					Rage::Vector3 Normal;
					if( sscanf(sLine.c_str(), "%f %f %f", &Normal.x, &Normal.y, &Normal.z) != 3 )
						THROW;

					Normal = Normal.GetNormalized();
					Normals[j] = Normal;
				}

				//
				// triangles
				//
				if( f.GetLine( sLine ) <= 0 )
					THROW;

				int nNumTriangles = 0;
				if( sscanf (sLine.c_str(), "%d", &nNumTriangles) != 1 )
					THROW;

				Triangles.resize( nNumTriangles );

				for( int j = 0; j < nNumTriangles; j++ )
				{
					if( f.GetLine( sLine ) <= 0 )
						THROW;

					uint16_t nIndices[3];
					uint16_t nNormalIndices[3];
					if( sscanf (sLine.c_str(), "%d %hd %hd %hd %hd %hd %hd %d",
								&nFlags,
								&nIndices[0], &nIndices[1], &nIndices[2],
								&nNormalIndices[0], &nNormalIndices[1], &nNormalIndices[2],
								&nIndex
						   ) != 8 )
					{
						THROW;
					}

					// deflate the normals into vertices
					for( int k=0; k<3; k++ )
					{
						ASSERT_M( nIndices[k] < Vertices.size(), fmt::sprintf("mesh \"%s\" tri #%i accesses vertex %i, but we only have %i",
							szName, j, nIndices[k], int(Vertices.size())) );
						ASSERT_M( nNormalIndices[k] < Normals.size(), fmt::sprintf("mesh \"%s\" tri #%i accesses normal %i, but we only have %i",
							szName, j, nNormalIndices[k], int(Normals.size())) );
						Rage::ModelVertex& vertex = Vertices[ nIndices[k] ];
						Rage::Vector3& normal = Normals[ nNormalIndices[k] ];
						vertex.n = normal;
						//mesh.Vertices[nIndices[k]].n = Normals[ nNormalIndices[k] ];
					}

					msTriangle& Triangle = Triangles[j];
					// Triangle.nFlags = nFlags;
					memcpy( &Triangle.nVertexIndices, nIndices, sizeof(Triangle.nVertexIndices) );
					// Triangle.nSmoothingGroup = nIndex;
				}
			}
		}
	}

	OptimizeBones();

	if( DISPLAY->SupportsPerVertexMatrixScale() )
	{
		if( m_Meshes.size() == 2  &&  m_Meshes[0].sName == m_Meshes[1].sName )
		{
			MergeMeshes( 1, 0 );
		}
	}

	// send the finalized vertices to the graphics card
	m_pCompiledGeometry->Set( m_Meshes, bNeedsNormals );
}