示例#1
0
void EditMetricsDlg::RefreshTree()
{
	m_tree.DeleteAllItems();

	iniBase.Reset();
	iniBase.SetPath( "Themes\\default\\metrics.ini" );
	iniBase.ReadFile();

	iniTheme.Reset();
	iniTheme.SetPath( "Themes\\"+m_sTheme+"\\metrics.ini" );
	iniTheme.ReadFile();

	IniFile iniCombined;
	iniCombined.SetPath( "Themes\\default\\metrics.ini" );
	iniCombined.ReadFile();
	iniCombined.SetPath( "Themes\\"+m_sTheme+"\\metrics.ini" );
	iniCombined.ReadFile();

	CStringArray asKeys;
	IniFile::const_iterator it;
	for( it = iniCombined.begin(); it != iniCombined.end(); ++it )
		asKeys.push_back( it->first );
	SortCStringArray( asKeys );

	for( unsigned i=0; i<asKeys.size(); i++ )
	{
		CString sKey = asKeys[i];
		bool bInBase = iniBase.GetKey(sKey) != NULL;
		bool bInTheme = iniTheme.GetKey(sKey) != NULL;

		HTREEITEM item1 = m_tree.InsertItem( sKey );
		SET_ITEM_STYLE( item1, bInBase, bInTheme );

		const IniFile::key* pKey = iniCombined.GetKey( sKey );
		CStringArray asNames;
		for( IniFile::key::const_iterator val = pKey->begin(); val != pKey->end(); ++val )
		{
			CString sName = val->first, sValue = val->second;
			asNames.push_back( sName );
		}
	
		SortCStringArray( asNames );

		for( unsigned j=0; j<asNames.size(); j++ )
		{
			CString sName = asNames[j];
			CString sValue;
			iniCombined.GetValue( sKey, sName, sValue );

			CString sThrowAway;
			bool bInBase = !!iniBase.GetValue( sKey, sName, sThrowAway );
			bool bInTheme = !!iniTheme.GetValue( sKey, sName, sThrowAway );

			HTREEITEM item2 = m_tree.InsertItem( sName, item1 );
			SET_ITEM_STYLE( item2, bInBase, bInTheme );
		}
	}
}
static void SetDefaultModifiers( const PlayerOptions &po, const SongOptions &so )
{
	CStringArray as;
	if( po.GetString() != "" )
		as.push_back( po.GetString() );
	if( so.GetString() != "" )
		as.push_back( so.GetString() );

	PREFSMAN->m_sDefaultModifiers.Set( join(", ",as) );
}
示例#3
0
CString ParsedCommand::GetOriginalCommandString() const
{
	CStringArray asTokens;
	for( unsigned i=0; i<vTokens.size(); i++ )
		asTokens.push_back( vTokens[i].s );
	return join( ",", asTokens );
}
示例#4
0
void ScreenUserPacks::Init()
{
	ScreenWithMenuElements::Init();

	if ( USER_PACK_WAIT_TEXT.GetValue().empty() )
		USER_PACK_WAIT_TEXT.SetValue("Please Wait...");

	if ( USER_PACK_CANCEL_TEXT.GetValue().empty() )
	{
		USER_PACK_CANCEL_TEXT.SetValue(ssprintf( "Pressing %s will cancel this selection.",
			DiagnosticsUtil::GetInputType() == "ITGIO" ? "&MENULEFT;+&MENURIGHT;" : "&SELECT;" ));
	}

	m_SoundDelete.Load( THEME->GetPathS( m_sName, "delete" ) );
	m_SoundTransferDone.Load( THEME->GetPathS( m_sName, "transfer done" ) );

	m_AddedZips.SetName( "LinkedOptionsMenuAddedZips" );
	m_USBZips.SetName( "LinkedOptionsMenuUSBZips" );
	m_Exit.SetName( "LinkedOptionsMenuSASExit" );

	m_USBZips.Load( NULL, &m_AddedZips );
	m_AddedZips.Load( &m_USBZips, &m_Exit );
	m_Exit.Load( &m_AddedZips, NULL );

	m_USBZips.SetMenuChangeScreenMessage( SM_LinkedMenuChange );
	m_AddedZips.SetMenuChangeScreenMessage( SM_LinkedMenuChange );
	m_Exit.SetMenuChangeScreenMessage( SM_LinkedMenuChange ); // why not..

	this->AddChild( &m_AddedZips );
	this->AddChild( &m_USBZips );
	this->AddChild( &m_Exit );

	SET_XY_AND_ON_COMMAND( m_AddedZips );
	SET_XY_AND_ON_COMMAND( m_USBZips );
	SET_XY_AND_ON_COMMAND( m_Exit );

	m_Disclaimer.SetName( "Disclaimer" );
	m_Disclaimer.LoadFromFont( THEME->GetPathF( m_sName, "text" ) );
	m_Disclaimer.SetText( THEME->GetMetric(m_sName, "DisclaimerText") );
	SET_XY_AND_ON_COMMAND( m_Disclaimer );
	this->AddChild( &m_Disclaimer );

	this->SortByDrawOrder();

	{
		CStringArray asExit;
		asExit.push_back( "Exit" );
		m_Exit.SetChoices( asExit );
	}

	m_Exit.Focus();
	m_pCurLOM = &m_Exit;
	
	m_bStopThread = false;
	m_PlayerSongLoadThread.SetName( "Song Add Thread" );
	m_PlayerSongLoadThread.Create( InitSASSongThread, this );

	ReloadZips();
}
示例#5
0
void ScreenSelectMode::UpdateSelectableChoices()
{
	CStringArray GraphicPaths;
	m_iNumChoices = 0;
	unsigned i=0;
	unsigned j=0;
	for( i=0; i<m_aModeChoices.size(); i++ )
	{
		const ModeChoice& mc = m_aModeChoices[i];
		CString modename = mc.m_sName;
		modename.MakeUpper();


		// FIXME for new premium prefs
		const int SidesJoinedToPlay = 
			(mc.m_pStyle == NULL) ?
			1 :
			1;
			if( PREFSMAN->GetPremium()!=PrefsManager::JOINT_PREMIUM ||
			(
				(PREFSMAN->GetPremium()==PrefsManager::JOINT_PREMIUM) && 
				( 
					(INCLUDE_DOUBLE_IN_JP == 1 && (GAMESTATE->GetNumSidesJoined() == SidesJoinedToPlay)) || 
					(
						INCLUDE_DOUBLE_IN_JP == 0 && 
						(
							GAMESTATE->GetNumSidesJoined() == SidesJoinedToPlay || 
							(modename.substr(0, 6) == "DOUBLE" || modename.substr(0, 13) == "ARCADE-DOUBLE" ||
							modename.substr(0, 10) == "HALFDOUBLE" || modename.substr(0, 17) == "ARCADE-HALFDOUBLE") &&
							GAMESTATE->GetNumSidesJoined() != 2
						)
					)
				) 
			)			
			
		)
		{
			m_iNumChoices++;
			if(j<=MAX_ELEMS)
			{
				m_iSelectableChoices[j] = i;
				j++;
			}
			else
			{
				ASSERT(0); // too many choices, can't track them all. Quick Fix: If You Get This Just Increase MAX_ELEMS
			}
			GraphicPaths.push_back(arrayLocations[i]);
		}
	}
	m_ScrollingList.SetSelection(0);
	m_ScrollingList.Unload();
	m_ScrollingList.Load(GraphicPaths);
	if(USE_MODE_SPECIFIC_BGS == 1)
	{
		// TODO: Finish implementing this! (Got exams no time to finish...)
	}
}
static void GameChoices( CStringArray &out )
{
	vector<const Game*> aGames;
	GAMEMAN->GetEnabledGames( aGames );
	FOREACH( const Game*, aGames, g )
	{
		CString sGameName = (*g)->m_szName;
		sGameName.MakeUpper();
		out.push_back( sGameName );
	}
示例#7
0
void ScreenTestInput::Update( float fDeltaTime )
{
	Screen::Update( fDeltaTime );

	CStringArray asInputs;

	DeviceInput di;

	// XXX: is this needed?
	MESSAGEMAN->Broadcast( "ResetButtons" );

	FOREACH_InputDevice( d )
	{
		for( int b=0; b<GetNumDeviceButtons(d); b++ )
		{
			di.device = d;
			di.button = b;

			if( !INPUTFILTER->IsBeingPressed(di) )
				continue;

			CString sTemp;
			sTemp += di.toString();
			
			GameInput gi;
			if( INPUTMAPPER->DeviceToGame(di,gi) )
			{
				CString sName = GAMESTATE->GetCurrentGame()->m_szButtonNames[gi.button];
				sTemp += ssprintf(" - Controller %d %s", gi.controller+1, sName.c_str() );

				// broadcast a theme notice - "P1Left", etc.
				MESSAGEMAN->Broadcast( ssprintf("P%d%s", gi.controller+1, sName.c_str()) );

				if( !PREFSMAN->m_bOnlyDedicatedMenuButtons )
				{
					CString sSecondary = GAMEMAN->GetMenuButtonSecondaryFunction( GAMESTATE->GetCurrentGame(), gi.button );
					if( !sSecondary.empty() )
						sTemp += ssprintf(" - (%s secondary)", sSecondary.c_str() );
				}
			}
			else
			{
				sTemp += " - not mapped";
			}

			CString sComment = INPUTFILTER->GetButtonComment( di );
			if( sComment != "" )
				sTemp += " - " + sComment;

			asInputs.push_back( sTemp );
		}
	}

	m_textInputs.SetText( join( "\n", asInputs ) );
}
示例#8
0
//-------------------------------------------------------------------------
// ySplitStringVector: spit string "str" and build vector of strings
//-------------------------------------------------------------------------
CStringArray ySplitStringVector(std::string str, std::string delimiter) {
	std::string left, right, rest;
	bool found;
	CStringArray split;
	rest = str;
	do {
		found = ySplitString(rest, delimiter, left, right);
		split.push_back(left);
		rest = right;
	} while (found);
	return split;
}
示例#9
0
/* iMaxValues is only used for writing compatibility fields in non-cache
 * SM files; they're never actually read. */
CString RadarValues::ToString( int iMaxValues ) const
{
	if( iMaxValues == -1 )
		iMaxValues = NUM_RADAR_CATEGORIES;
	iMaxValues = min( iMaxValues, (int)NUM_RADAR_CATEGORIES );

	CStringArray asRadarValues;
	for( int r=0; r < iMaxValues; r++ )
		asRadarValues.push_back( ssprintf("%.3f", m_Values.f[r]) );

	return join( ",",asRadarValues );
}
void LoadingWindow_Win32::SetText(CString str)
{
	CStringArray asMessageLines;
	split( str, "\n", asMessageLines, false );
	while( asMessageLines.size() < 3 )
		asMessageLines.push_back( "" );
	
	const int msgs[] = { IDC_STATIC_MESSAGE1, IDC_STATIC_MESSAGE2, IDC_STATIC_MESSAGE3 };
	for( unsigned i = 0; i < 3; ++i )
	{
		if( text[i] == asMessageLines[i] )
			continue;
		text[i] = asMessageLines[i];

		SendDlgItemMessage( hwnd, msgs[i], WM_SETTEXT, 0, 
			(LPARAM)asMessageLines[i].c_str());
	}
}
示例#11
0
void NotesWriterSM::WriteSMNotesTag( const Steps &in, RageFile &f, bool bSavingCache )
{
	f.PutLine( "" );
	f.PutLine( ssprintf( "//---------------%s - %s----------------",
		GameManager::StepsTypeToString(in.m_StepsType).c_str(), in.GetDescription().c_str() ) );
	f.PutLine( "#NOTES:" );
	f.PutLine( ssprintf( "     %s:", GameManager::StepsTypeToString(in.m_StepsType).c_str() ) );
	f.PutLine( ssprintf( "     %s:", in.GetDescription().c_str() ) );
	f.PutLine( ssprintf( "     %s:", DifficultyToString(in.GetDifficulty()).c_str() ) );
	f.PutLine( ssprintf( "     %d:", in.GetMeter() ) );
	
	int MaxRadar = bSavingCache? NUM_RADAR_CATEGORIES:5;
	CStringArray asRadarValues;
	for( int r=0; r < MaxRadar; r++ )
		asRadarValues.push_back( ssprintf("%.3f", in.GetRadarValues()[r]) );
	/* Don't append a newline here; it's added in NoteDataUtil::GetSMNoteDataString.
	 * If we add it here, then every time we write unmodified data we'll add an extra
	 * newline and they'll accumulate. */
	f.Write( ssprintf( "     %s:", join(",",asRadarValues).c_str() ) );

	CString sNoteData;
	CString sAttackData;
	in.GetSMNoteData( sNoteData, sAttackData );

	vector<CString> lines;

	split( sNoteData, "\n", lines, false );
	WriteLineList( f, lines, true, true );

	if( sAttackData.empty() )
		f.PutLine( ";" );
	else
	{
		f.PutLine( ":" );

		lines.clear();
		split( sAttackData, "\n", lines, false );
		WriteLineList( f, lines, true, true );

		f.PutLine( ";" );
	}
}
示例#12
0
void ScreenTestInput::Update( float fDeltaTime )
{
	Screen::Update( fDeltaTime );

	CStringArray asInputs;

	DeviceInput di;

	for( int d=0; d<NUM_INPUT_DEVICES; d++ )
	{
		for( int b=0; b<NUM_DEVICE_BUTTONS[d]; b++ )
		{
			di.device = (InputDevice)d;
			di.button = b;

			if( INPUTFILTER->IsBeingPressed(di) )
			{
				CString sTemp;
				sTemp += di.GetDescription();
				
				GameInput gi;
				if( INPUTMAPPER->DeviceToGame(di,gi) )
				{
					CString sName = GAMESTATE->GetCurrentGame()->m_szButtonNames[gi.button];
					CString sSecondary = GAMESTATE->GetCurrentGame()->m_szSecondaryFunction[gi.button];
					
					sTemp += ssprintf("  (Controller %d %s)  %s", gi.controller+1, sName.c_str(), sSecondary.c_str() );
				}
				else
				{
					sTemp += "  (not mapped)";
				}

				asInputs.push_back( sTemp );
			}
		}
	}

	m_textInputs.SetText( join( "\n ", asInputs ) );
}
示例#13
0
文件: Font.cpp 项目: Braunson/openitg
/* Given a file in a font, find all of the files for the font.
 * 
 * Possibilities:
 *
 * Normal 16x16.png
 * Normal [other] 16x16.png
 * Normal [more] 8x8.png
 * Normal 16x16.ini
 * Normal.ini
 *
 * Any of the above should find all of the above.  Allow the
 * extension to be omitted. */
void Font::GetFontPaths( const CString &sFontOrTextureFilePath,
							   CStringArray &asTexturePathsOut, CString &sIniPath )
{
	CString sDir, sFName, sExt;
	splitpath( sFontOrTextureFilePath, sDir, sFName, sExt );

	/* Don't give us a redir; resolve those before sending them here. */
	ASSERT( sExt.CompareNoCase("redir") );

	/* sFName can't be empty, or we don't know what to search for. */
	ASSERT( !sFName.empty() );

	CString sFontName = GetFontName( sFName );

	CStringArray asFiles;
	GetDirListing( sDir+sFontName + "*", asFiles, false, false );

	for( unsigned i = 0; i < asFiles.size(); ++i )
	{
		/* We now have a list of possibilities, but it may include false positives,
		 * such as "Normal2" when the font name is "Normal".  Weed them. */
		if( GetFontName(asFiles[i]).CompareNoCase(sFontName) )
			continue;

		/* If it's an INI, and we don't already have an INI, use it. */
		if( !asFiles[i].Right(4).CompareNoCase(".ini"))  
		{
			if( !sIniPath.empty() )
				RageException::Throw( "More than one INI found\n%s\n%s", sIniPath.c_str(), asFiles[i].c_str() );
			
			sIniPath = sDir+asFiles[i];
			continue;
		}

		asTexturePathsOut.push_back( sDir+asFiles[i] );
	}
}
示例#14
0
/****************************
void MusicBannerWheel::LoadSongData()

Loads the Song Data, based upon
its relative position. It's fairly
slow, so should only get used once
and once only.
*****************************/
void MusicBannerWheel::LoadSongData()
{
	Song* pSong = NULL;
	CStringArray asGraphicPaths;

	if(MAXSONGSINBUFFER >= arraySongs.size() && SingleLoad != 1)  // less than the MAXSONGSINBUFFER means we can get away with loading the lot in one go
	{
		SingleLoad=2;
		int difference=0;
		// find out just how short of a full buffer we are =)
		difference = MAXSONGSINBUFFER - arraySongs.size();
		for(int i=0; i<=difference; i++)
		{
			for(unsigned c=0; c<arraySongs.size(); c++)
			{
				pSong = arraySongs[c];

				if( pSong == NULL ) 
					asGraphicPaths.push_back(THEME->GetPathG("Common","fallback banner"));
				else if (pSong->HasBanner()) 
					asGraphicPaths.push_back(pSong->GetBannerPath());
				else 
					asGraphicPaths.push_back(THEME->GetPathG("Common","fallback banner"));	
			}
		}
	}
	
	if(SingleLoad==0)
	{
		for(int count=0; count<MAXSONGSINBUFFER; count++)
		{
			/* In essence, this element is the central one so we want the scrolling list
			to load in the song as specified by currentPos */
			if(count == scrlistPos)
			{	
				pSong = arraySongs[currentPos];
			}
			/* if it's the next element
			*/
			else if(count == scrlistPos+2 || (scrlistPos == MAXSONGSINBUFFER-2 && count == 0))
			{
				if((unsigned)currentPos+2 <= arraySongs.size()-1)
					pSong = arraySongs[currentPos+2];
				else
					pSong = arraySongs[0+2];
			}
			else if(count == scrlistPos-2 || (scrlistPos == 0 && count == MAXSONGSINBUFFER-2))
			{
				if(currentPos-2 >= 0)
					pSong = arraySongs[currentPos-2];
				else
					pSong = arraySongs[arraySongs.size()-2];			
			}
			else if(count == scrlistPos+1 || (scrlistPos == MAXSONGSINBUFFER-1 && count == 0))
			{
				if((unsigned)currentPos+1 <= arraySongs.size()-1)
					pSong = arraySongs[currentPos+1];
				else
					pSong = arraySongs[0];
			}
			/* if it's the previous element OR if we're at element 0..the 5th element (which will wrap to before element 0)
			will actually appear as 5 songs along and not the one immediately before it,, so pull a sneaky and make the 
			final element actually be the song before... */
			else if(count == scrlistPos-1 || (scrlistPos == 0 && count == MAXSONGSINBUFFER-1))
			{
				if(currentPos-1 >= 0)
					pSong = arraySongs[currentPos-1];
				else
					pSong = arraySongs[arraySongs.size()-1];
			}

			if( pSong == NULL ) 
				asGraphicPaths.push_back(THEME->GetPathG("Common","fallback banner"));
			else if (pSong->HasBanner()) 
				asGraphicPaths.push_back(pSong->GetBannerPath());
			else 
				asGraphicPaths.push_back(THEME->GetPathG("Common","fallback banner"));
		}
	}
	if(SingleLoad != 1)
		m_ScrollingList.Load( asGraphicPaths );
	if(SingleLoad == 2)
		SingleLoad = 1;
	if((PREVIEWMUSICMODE == 0 || PREVIEWMUSICMODE == 3) && !bScanning)
		PlayMusicSample();
}
示例#15
0
int main (int argc, char *argv[])
{
  string			FileName;
  CStringArray			InputFiles;
  CProduct			*Product	= NULL;
  bool				Error		= false;
  bool				Help		= false;

  if (argc != 2)
    Error	= true;
  else if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0))
    Help	= true;
  else
  {
    FileName.assign(argv[1]);

    if (! CTools::FileExists(FileName))
    {
      cerr << "ERROR: Data file '" << FileName << "' not found" << endl << endl;
      Error	= true;
    }
    InputFiles.push_back(FileName);
  }

  if (Error || Help)
  {
    cerr << "Usage : " << argv[0] << " [ -h | --help] FileName" << endl;
    cerr << "Where FileName is the name of a file to show" << endl;
  }

  if (Help)
    cerr << endl << "Displays the fields available for a product file" << endl;

  if (Error || Help)
    return 2;

  if (getenv(BRATHL_ENVVAR) == NULL)
  {
    CTools::SetDataDirForExecutable(argv[0]);
  }

  try
  {
//    auto_ptr<CTrace>pTrace(CTrace::GetInstance());

    // construct the product
    Product = CProduct::Construct(InputFiles);
    Product->Open(FileName);

    CTreeField	*Tree	= Product->GetTreeField();
    if (Tree->GetRoot() != NULL)
    {
      Tree->SetWalkDownRootPivot();    
      do
      {
	CField *field  = dynamic_cast<CField*>(Tree->GetWalkCurrent()->GetData()); 
	if (field == NULL)
	{
	  throw CException("ERROR at least one of the tree object is not a CField object",
			   BRATHL_INCONSISTENCY_ERROR);
	}

	if (typeid(*field) == typeid(CFieldRecord))
	  continue;
	if ((typeid(*field) == typeid(CFieldArray))  &&
	    (! field->IsFixedSize()))
	  continue;
	string Unit	= field->GetUnit();
	cout << CTools::Format("%-20s", field->GetRecordName().c_str())
	     << field->GetFullName();
 	if (Unit != "")
	  cout << " (" << Unit << ")";
	cout << endl;
      }
      while (Tree->SubTreeWalkDown());
    }

    delete Product;
    return 0;
  }
  catch (CException &e)
  {
    cerr << "BRAT ERROR: " << e.what() << endl;
    return 1;
  }
  catch (exception &e)
  {
    cerr << "BRAT RUNTIME ERROR: " << e.what() << endl;
    return 254;
  }
  catch (...)
  {
    cerr << "BRAT FATAL ERROR: Unexpected error" << endl;
    return 255;
  }
}
void ScreenMapControllers::Init()
{
	ScreenWithMenuElements::Init();

#ifdef _XBOX
	CStringArray strArray;
	CString text("Use joypad to navigate, START to assign, A, B, X or Y to clear, BACK when done.");
	strArray.push_back(text);
	m_textHelp->SetTips(strArray);
#endif

	for( int b=0; b<GAMESTATE->GetCurrentGame()->m_iButtonsPerController; b++ )
	{
		CString sName = GAMESTATE->GetCurrentGame()->m_szButtonNames[b];
		CString sSecondary = GAMEMAN->GetMenuButtonSecondaryFunction( GAMESTATE->GetCurrentGame(), b );

		m_textName[b].LoadFromFont( THEME->GetPathF("Common","title") );
		m_textName[b].SetXY( SCREEN_CENTER_X, -6 );
		m_textName[b].SetText( sName );
		m_textName[b].SetZoom( 0.7f );
		m_textName[b].SetShadowLength( 2 );
		m_Line[b].AddChild( &m_textName[b] );

		m_textName2[b].LoadFromFont( THEME->GetPathF("Common","title") );
		m_textName2[b].SetXY( SCREEN_CENTER_X, +6 );
		m_textName2[b].SetText( sSecondary );
		m_textName2[b].SetZoom( 0.5f );
		m_textName2[b].SetShadowLength( 2 );
		m_Line[b].AddChild( &m_textName2[b] );

		for( int p=0; p<MAX_GAME_CONTROLLERS; p++ ) 
		{			
			for( int s=0; s<NUM_SHOWN_GAME_TO_DEVICE_SLOTS; s++ ) 
			{
				m_textMappedTo[p][b][s].LoadFromFont( THEME->GetPathF("ScreenMapControllers","entry") );
				m_textMappedTo[p][b][s].SetXY( BUTTON_COLUMN_X[p*NUM_SHOWN_GAME_TO_DEVICE_SLOTS+s], 0 );
				m_textMappedTo[p][b][s].SetZoom( 0.5f );
				m_textMappedTo[p][b][s].SetShadowLength( 0 );
				m_Line[b].AddChild( &m_textMappedTo[p][b][s] );
			}
		}
		m_Line[b].SetY( LINE_START_Y + b*LINE_GAP_Y );
		this->AddChild( &m_Line[b] );

		m_Line[b].RunCommands( (b%2)? ODD_LINE_IN : EVEN_LINE_IN );
	}	

	m_textError.LoadFromFont( THEME->GetPathF("Common","normal") );
	m_textError.SetText( "" );
	m_textError.SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y );
	m_textError.SetDiffuse( RageColor(0,1,0,0) );
	m_textError.SetZoom( 0.8f );
	this->AddChild( &m_textError );


	m_iCurController = 0;
	m_iCurButton = 0;
	m_iCurSlot = 0;

	m_iWaitingForPress = 0;

	SOUND->PlayMusic( THEME->GetPathS("ScreenMapControllers","music") );

	Refresh();
}
示例#17
0
void ScreenArcadePatch::PatchMain()
{
	m_State = PATCH_CHECKING;

        /* NOTE: we used to look for OpenITG prefixed updates also, but the
         * original ITG binary does not, so if we want people to be able to
         * upgrade directly from ITG to OITG, we have to continue to use the
         * "ITG 2 " prefix.  Sad times. */

	/* set up patterns to match */
	CStringArray vsPatterns;
	vsPatterns.push_back( "ITG 2 *.itg" );

	/* check to see if either player has patches */
	PlayerNumber pn = PLAYER_INVALID;

	/* HasPatch() will early abort for us, due to the size() check,
	 * if P1 and P2 both have patches. We just want the first one. */
	FOREACH_PlayerNumber( p )
		if( this->HasPatch(p, vsPatterns) )
			pn = p;

	/* no matches on either card. */
	if( pn == PLAYER_INVALID )
	{
		m_State = PATCH_NONE;
		return;
	}

	/* set the help text to the patch name, blank the patch text */
	m_textHelp->SetText( m_vsPatches[0] );
	PATCH_TEXT( "" );

	/* set up the key paths we want to verify against */
	CStringArray vsRSAPaths;
	vsRSAPaths.push_back( "Data/Patch-OpenITG.rsa" );
	vsRSAPaths.push_back( "Data/Patch.rsa" );

	/* create the path for the patch file */
	CString sPatchFile = m_sProfileDir + m_vsPatches[0];

	// copy the patch file into memory
	// TODO: see if we can FILEMAN->GetFileDriver( "/@mem/" ).
	m_MemDriver = new RageFileDriverMem;

	int iError = 0;
	m_PatchFile = m_MemDriver->Open( ITG_TEMP_FILE, RageFile::WRITE, iError );
	
	if( iError != 0 )
	{
		STATE_TEXT( ssprintf("Failed to open temporary file:\n%s", strerror(iError)) );
		m_State = PATCH_ERROR;
	}

	/* give up to an hour for the data to copy */
	MEMCARDMAN->MountCard( pn, 3600 );

	RageFile patch;
	if( !patch.Open(sPatchFile) )
	{
		STATE_TEXT( ssprintf("Failed to open patch file (%s):\n%s",
			sPatchFile.c_str(), patch.GetError().c_str()) );

		m_State = PATCH_ERROR;
	}

	if( m_State == PATCH_ERROR )
	{
		MEMCARDMAN->UnmountCard(pn);
		return;
	}

	CString sError;
	if( FileCopy( patch, *m_PatchFile, sError, &UpdateProgress) )
	{
		STATE_TEXT( "Patch copied! Checking..." );
		PATCH_TEXT( "" );
	}
	else
	{
		STATE_TEXT( ssprintf("Patch copying failed:\n" "%s", sError.c_str()) );
		m_State = PATCH_ERROR;
	}

	MEMCARDMAN->UnmountCard( pn );

	if( m_State == PATCH_ERROR )
		return;

	/* re-open the patch file read-open. this should not fail. */
	m_PatchFile = m_MemDriver->Open( ITG_TEMP_FILE, RageFile::READ, iError );

	if( !this->VerifyPatch(m_PatchFile, vsRSAPaths) )
	{
		PATCH_TEXT( "" );
		m_State = PATCH_ERROR;
		return;
	}

	/* reset the error checker */
	iError = 0;

	/* check the XML data */
	CString sGame, sSuccessMessage;
	int iPatchRevision;

	/* open our new copy and read from it */
	RageFileDriverZip *fZip = new RageFileDriverZip( m_PatchFile );

	// we'll catch this in a bit, after we've freed our memory
	if( !this->GetXMLData(fZip, sGame, sSuccessMessage, iPatchRevision) )
		m_State = PATCH_ERROR;

	SAFE_DELETE( fZip );

	// if the XML get earlier failed, return now.
	if( m_State == PATCH_ERROR )
		return;

	// accept patches for oITG or ITG2
	if( sGame != "OpenITG" && sGame != "In The Groove 2" )
	{
		sError = ssprintf( "revision is for another game\n" "(\"%s\")", sGame.c_str() );
		STATE_TEXT( ssprintf("Cannot proceed: %s", sError.c_str()) );
		m_State = PATCH_ERROR;
		return;
	}

	int iCurrentRevision = DiagnosticsUtil::GetRevision();

	// HACK: allow any patch at all if it's revision 1.
	if( iCurrentRevision != 1 && iCurrentRevision == iPatchRevision )
	{
		sError = ssprintf( "patch revision (%d) matches the machine revision.", iPatchRevision );
		STATE_TEXT( ssprintf("Cannot proceed: %s", sError.c_str()) );
		m_State = PATCH_ERROR;
		return;
	}

	/* wipe any unsucessful or unused patch data */
	DeleteRecursive( TEMP_PATCH_DIR );
	DeleteRecursive( FINAL_PATCH_DIR );

	FILEMAN->CreateDir( TEMP_PATCH_DIR );

	/* re-open the ZIP file now */
	fZip = new RageFileDriverZip;
	if( !fZip->Load(m_PatchFile) )
	{
		PATCH_TEXT( "Failed to re-open ZIP file!" );
		m_State = PATCH_ERROR;
		return;
	}

	CStringArray vsDirs, vsFiles;
	vsDirs.push_back( "/" );

	/* find all the files we're going to write with a recursive check */
	while( vsDirs.size() )
	{
		CString sDir = vsDirs.back();
		vsDirs.pop_back();

		fZip->GetDirListing( sDir + "/*", vsFiles, false, true );
		fZip->GetDirListing( sDir + "/*", vsDirs, true, true );
	}

	PATCH_TEXT( "Extracting files..." );

	/* write them now */
	for( unsigned i = 0; i < vsFiles.size(); i++ )
	{
		const CString &sPath = vsFiles[i];
		CString sCleanPath = sPath;
		TrimLeft( sCleanPath, "/" );

		if( fZip->GetFileType(sPath) != RageFileManager::TYPE_FILE )
			continue;

		LOG->Trace( "ScreenArcadePatch: copying file \"%s\"", sCleanPath.c_str() );
		PATCH_TEXT( ssprintf("Extracting files...\n" "%s", sCleanPath.c_str()) );

		RageFileBasic *fCopyFrom = fZip->Open( sPath, RageFile::READ, iError );

		RageFile fCopyTo;
		fCopyTo.Open( TEMP_PATCH_DIR + sCleanPath, RageFile::WRITE );

		if( !FileCopy(*fCopyFrom, fCopyTo) )
		{
			PATCH_TEXT( ssprintf("Could not copy \"%s\":\n" "%s", sCleanPath.c_str(),sError.c_str()) );

			m_State = PATCH_ERROR;
			SAFE_DELETE( fCopyFrom );
			SAFE_DELETE( fZip );
			return;
		}

		SAFE_DELETE( fCopyFrom );
		fCopyTo.Close();

/* set CHMOD info */
#ifdef LINUX
		/* get the actual path to the files */
		CString sRealPath = ResolveTempFilePath( sCleanPath );

		const RageFileDriverZip::FileInfo *fi = fZip->GetFileInfo( sPath );
		int ret = chmod( sRealPath.c_str(), fi->m_iFilePermissions );

		LOG->Trace( "chmod( %s, %#o ) returned %i", sRealPath.c_str(), fi->m_iFilePermissions, ret );
#endif // LINUX
	}

	SAFE_DELETE( fZip );

	/* clear the previous copying text */
	STATE_TEXT( "Finalizing patch data..." );
	PATCH_TEXT( "" );

#ifdef LINUX
	sync(); sleep(5);
#endif

	/* we've successfully copied everything. now, move the directory and we're done. */
	if( FILEMAN->Move(TEMP_PATCH_DIR, FINAL_PATCH_DIR) )
	{
		STATE_TEXT( sSuccessMessage );
		m_State = PATCH_INSTALLED;
	}
	else
	{
		STATE_TEXT( "Failed to finalize patch data!\nCheck your system permissions" );
		m_State = PATCH_ERROR;
	}
}
示例#18
0
void EditCoursesMenu::OnRowValueChanged( Row row )
{
	LOG->Trace( "EditCoursesMenu::OnRowValueChanged(%i)", row );

	const bool bCanGoLeft = CanGoLeft(), bCanGoRight = CanGoRight();
	m_sprArrows[0].SetDiffuse( bCanGoLeft?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[1].SetDiffuse( bCanGoRight?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[0].EnableAnimation( bCanGoLeft );
	m_sprArrows[1].EnableAnimation( bCanGoRight );

	Course* pCourse = GetSelectedCourse();
	CourseEntry* pEntry = GetSelectedEntry();

	switch( row )
	{
	case ROW_COURSE:
		CHECKPOINT;
		m_textValue[ROW_COURSE].SetText( pCourse->GetFullDisplayTitle() );
		m_CourseBanner.LoadFromCourse( pCourse );
		m_CourseBanner.ScaleToClipped( COURSE_BANNER_WIDTH, COURSE_BANNER_HEIGHT );
		m_iSelection[ROW_ENTRY] = 0;
		pEntry = GetSelectedEntry();
		if( pEntry == NULL )
		{
			CourseEntry ce;
			const vector<Song*> &apSongs = SONGMAN->GetAllSongs();
			ASSERT( !apSongs.empty() );
			ce.pSong = apSongs[0];
			pCourse->m_entries.push_back( ce );
			pEntry = GetSelectedEntry();
		}
		// fall through
	case ROW_COURSE_OPTIONS:
		CHECKPOINT;
		m_textValue[ROW_COURSE_OPTIONS].SetText( 
			ssprintf(
				"(START)  %s, %s, ",
				pCourse->m_bRepeat ? "repeat" : "no repeat",
				pCourse->m_bRandomize ? "randomize" : "no randomize" ) + 
			ssprintf(
				(pCourse->m_iLives==-1) ? "use bar life" : "%d lives",
				pCourse->m_iLives ) );
		// fall through
	case ROW_ACTION:
		CHECKPOINT;
		m_textValue[ROW_ACTION].SetText( "(START) " + ActionToString(GetSelectedAction()) );
		// fall through
	case ROW_ENTRY:
		CHECKPOINT;
		m_textValue[ROW_ENTRY].SetText( ssprintf("%d of %d",m_iSelection[ROW_ENTRY]+1, (int)GetSelectedCourse()->m_entries.size()) );
		m_iSelection[ROW_ENTRY_TYPE] = pEntry->type;
		// fall through
	case ROW_ENTRY_TYPE:
		CHECKPOINT;
		m_textValue[ROW_ENTRY_TYPE].SetText( pEntry ? CourseEntryTypeToString(pEntry->type) : CString("(none)") );
		// fall through
	case ROW_ENTRY_OPTIONS:
		CHECKPOINT;
		{
			CStringArray as;
			const bool *bShow = g_bRowEnabledForType[GetSelectedEntry()->type];

			if( bShow[song] )
				as.push_back( pEntry->pSong ? pEntry->pSong->GetFullTranslitTitle() : CString("(missing song)") );
			if( bShow[group] )
				as.push_back( pEntry->group_name.empty() ? CString("(no group)") : pEntry->group_name );
			if( bShow[difficulty] )
				if( pEntry->difficulty != DIFFICULTY_INVALID )
					as.push_back( DifficultyToString(pEntry->difficulty) );
			if( bShow[low_meter] )
				if( pEntry->low_meter > 0 )
					as.push_back( ssprintf("low meter %d", pEntry->low_meter) );
			if( bShow[high_meter] )
				if( pEntry->high_meter > 0 )
					as.push_back( ssprintf("high meter %d", pEntry->high_meter) );
			if( bShow[best_worst_value] )
				if( pEntry->players_index != -1 )
					as.push_back( ssprintf("rank %d", pEntry->players_index+1) );

			m_textValue[ROW_ENTRY_OPTIONS].SetText( "(START) " + join(", ",as) );
		}
		// fall through
	case ROW_ENTRY_PLAYER_OPTIONS:
		CHECKPOINT;
		{
			CString s = "(START) ";
		
			PlayerOptions po;
			po.FromString( pEntry->modifiers );
			if( po.GetString().empty() )
				s += "(none)";
			else
				s += po.GetString();
		
			m_textValue[ROW_ENTRY_PLAYER_OPTIONS].SetText( s );
		}
		// fall through
	case ROW_ENTRY_SONG_OPTIONS:
		CHECKPOINT;
		{
			CString s = "(START) ";

			SongOptions so;
			so.FromString( pEntry->modifiers );
			if( so.GetString().empty() )
				s += "(none)";
			else
				s += so.GetString();

			m_textValue[ROW_ENTRY_SONG_OPTIONS].SetText( s );
		}
		break;
	default:
		ASSERT(0);	// invalid row
	}
}