Пример #1
0
void BatchTestMain( int argc, char* argv[] )
{
	// TODO: Allow other directories and configuration
#ifdef DAEDALUS_PSP
	const char * const romdir = "host1:/";
#else
	const char * const romdir = g_DaedalusConfig.mRomsDir;
#endif

	bool	random_order( false );		// Whether to randomise the order of processing, to help avoid hangs
	bool	update_results( false );	// Whether to update existing results
	s32		run_id( -1 );				// New run by default

	for(int i = 1; i < argc; ++i )
	{
		const char * arg( argv[i] );
		if( *arg == '-' )
		{
			++arg;
			if( strcmp( arg, "rand" ) == 0 || strcmp( arg, "random" ) == 0 )
			{
				random_order = true;
			}
			else if( strcmp( arg, "u" ) == 0 || strcmp( arg, "update" ) == 0 )
			{
				update_results = true;
			}
			else if( strcmp( arg, "r" ) == 0 || strcmp( arg, "run" ) == 0 )
			{
				if( i+1 < argc )
				{
					++i;	// Consume next arg
					run_id = atoi( argv[i] );
				}
			}
		}
	}

	IO::Filename batchdir;
	Dump_GetDumpDirectory( batchdir, "batch" );

	IO::Filename rundir;
	if( run_id < 0 )
	{
		if( !MakeRunDirectory( rundir, batchdir ) )
		{
			printf( "Couldn't start a new run\n" );
			return;
		}
	}
	else
	{
		SprintRunDirectory( rundir, batchdir, run_id );
		if( !IO::Directory::IsDirectory( rundir ) )
		{
			printf( "Couldn't resume run %d\n", run_id );
			return;
		}
	}

	gBatchTestEventHandler = new CBatchTestEventHandler();

	IO::Filename logpath;
	MakeNewLogFilename( logpath, rundir );
	gBatchFH = fopen(logpath, "w");
	if( !gBatchFH )
	{
		printf( "Unable to open '%s' for writing", logpath );
		return;
	}

	std::vector< std::string > roms;
	MakeRomList( romdir, roms );

	u64 time;
	if( NTiming::GetPreciseTime( &time ) )
		srand( (int)time );

	CTimer	timer;

	//	Set up an assert hook to capture all asserts
	SetAssertHook( BatchAssertHook );

	// Hook in our Vbl handler.
	CPU_RegisterVblCallback( &BatchVblHandler, NULL );

	IO::Filename tmpfilepath;
	IO::Path::Combine( tmpfilepath, rundir, "tmp.tmp" );

	while( !roms.empty() )
	{
		gBatchTestEventHandler->Reset();

		u32 idx( 0 );

		// Picking roms in a random order means we can work around roms which crash the emulator a little more easily
		if( random_order )
			idx = rand() % roms.size();

		std::string	r;
		r.swap( roms[idx] );
		roms.erase( roms.begin() + idx );

		// Make a filename of the form: '<rundir>/<romfilename>.txt'
		IO::Filename rom_logpath;
		IO::Path::Combine( rom_logpath, rundir, IO::Path::FindFileName( r.c_str() ) );
		IO::Path::SetExtension( rom_logpath, ".txt" );

		bool	result_exists( IO::File::Exists( rom_logpath ) );

		if( !update_results && result_exists )
		{
			// Already exists, skip
			fprintf( gBatchFH, "\n\n%#.3f: Skipping %s - log already exists\n", timer.GetElapsedSecondsSinceReset(), r.c_str() );
		}
		else
		{
			fprintf( gBatchFH, "\n\n%#.3f: Processing: %s\n", timer.GetElapsedSecondsSinceReset(), r.c_str() );

			gRomLogFH = fopen( tmpfilepath, "w" );
			if( !gRomLogFH )
			{
				fprintf( gBatchFH, "#%.3f: Unable to open temp file\n", timer.GetElapsedSecondsSinceReset() );
			}
			else
			{
				fflush( gBatchFH );

				// TODO: use ROM_GetRomDetailsByFilename and the alternative form of ROM_LoadFile with overridden preferences (allows us to test if roms break by changing prefs)
				System_Open( r.c_str() );

				CPU_Run();

				System_Close();

				const char * reason( CBatchTestEventHandler::GetTerminationReasonString( gBatchTestEventHandler->GetTerminationReason() ) );

				fprintf( gBatchFH, "%#.3f: Finished running: %s - %s\n", timer.GetElapsedSecondsSinceReset(), r.c_str(), reason );

				// Copy temp file over rom_logpath
				gBatchTestEventHandler->PrintSummary( gRomLogFH );
				fclose( gRomLogFH );
				gRomLogFH = NULL;
				if( result_exists )
				{
					IO::File::Delete( rom_logpath );
				}
				if( !IO::File::Move( tmpfilepath, rom_logpath ) )
				{
					fprintf( gBatchFH, "%#.3f: Coping %s -> %s failed\n", timer.GetElapsedSecondsSinceReset(), tmpfilepath, rom_logpath );
				}
			}

		}

	}

	CPU_UnregisterVblCallback( &BatchVblHandler, NULL );
	SetAssertHook( NULL );

	fclose( gBatchFH );
	gBatchFH = NULL;

	delete gBatchTestEventHandler;
	gBatchTestEventHandler = NULL;
}