Ejemplo n.º 1
1
/**
 * Adds an argument to the specified program options object.
 * @param arguments arguments collection to add argument to.
 * @param argument argument to add.
 * @param value value of argument..
 */
template <class T> void add_argument(boost::program_options::variables_map& arguments, std::string argument, T value)
{
    // add the argument to the collection
    arguments.insert(  
        std::pair<std::string, boost::program_options::variable_value>(
            argument, boost::program_options::variable_value( boost::any(value), false )
        )
    );
}
Ejemplo n.º 2
0
Archivo: CMT.cpp Proyecto: yzliang/vcmi
int main(int argc, char** argv)
#endif
{
#ifdef __APPLE__
	// Correct working dir executable folder (not bundle folder) so we can use executable relative pathes
    std::string executablePath = argv[0];
    std::string workDir = executablePath.substr(0, executablePath.rfind('/'));
    chdir(workDir.c_str());
    
    // Check for updates
    OSX_checkForUpdates();

    // Check that game data is prepared. Otherwise run vcmibuilder helper application
    FILE* check = fopen((VCMIDirs::get().localPath() + "/game_data_prepared").c_str(), "r");
    if (check == nullptr) {
        system("open ./vcmibuilder.app");
        return 0;
    }
    fclose(check);
#endif
    std::cout << "Starting... " << std::endl;
	po::options_description opts("Allowed options");
	opts.add_options()
		("help,h", "display help and exit")
		("version,v", "display version information and exit")
		("battle,b", po::value<std::string>(), "runs game in duel mode (battle-only")
		("start", po::value<std::string>(), "starts game from saved StartInfo file")
		("onlyAI", "runs without human player, all players will be default AI")
		("noGUI", "runs without GUI, implies --onlyAI")
		("ai", po::value<std::vector<std::string>>(), "AI to be used for the player, can be specified several times for the consecutive players")
		("oneGoodAI", "puts one default AI and the rest will be EmptyAI")
		("autoSkip", "automatically skip turns in GUI")
		("disable-video", "disable video player")
		("nointro,i", "skips intro movies");

	if(argc > 1)
	{
		try
		{
			po::store(po::parse_command_line(argc, argv, opts), vm);
		}
		catch(std::exception &e) 
		{
            std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
		}
	}

	po::notify(vm);
	if(vm.count("help"))
	{
		prog_help(opts);
		return 0;
	}
	if(vm.count("version"))
	{
		prog_version();
		return 0;
	}
	if(vm.count("noGUI"))
	{
		gNoGUI = true;
		vm.insert(std::pair<std::string, po::variable_value>("onlyAI", po::variable_value()));
	}

	//Set environment vars to make window centered. Sometimes work, sometimes not. :/
	putenv((char*)"SDL_VIDEO_WINDOW_POS");
	putenv((char*)"SDL_VIDEO_CENTERED=1");

	// Have effect on X11 system only (Linux).
	// For whatever reason in fullscreen mode SDL takes "raw" mouse input from DGA X11 extension
	// (DGA = Direct graphics access). Because this is raw input (before any speed\acceleration proceesing)
	// it may result in very small \ very fast mouse when game in fullscreen mode
	putenv((char*)"SDL_VIDEO_X11_DGAMOUSE=0");

    // Init old logging system and new (temporary) logging system
	CStopWatch total, pomtime;
	std::cout.flags(std::ios::unitbuf);
	console = new CConsoleHandler;
	*console->cb = boost::bind(&processCommand, _1);
	console->start();
	atexit(dispose);

	CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Client_log.txt", console);
    logConfig.configureDefault();
	logGlobal->infoStream() <<"Creating console "<<pomtime.getDiff();

    // Init filesystem and settings
	preinitDLL(::console);
    settings.init();

    // Initialize logging based on settings
    logConfig.configure();

	// Some basic data validation to produce better error messages in cases of incorrect install
	auto testFile = [](std::string filename, std::string message) -> bool
	{
		if (CResourceHandler::get()->existsResource(ResourceID(filename)))
			return true;

        logGlobal->errorStream() << "Error: " << message << " was not found!";
		return false;
	};

	if (!testFile("DATA/HELP.TXT", "Heroes III data") &&
	    !testFile("MODS/VCMI/MOD.JSON", "VCMI mod") &&
	    !testFile("DATA/StackQueueBgBig.PCX", "VCMI data"))
		exit(1); // These are unrecoverable errors

	// these two are optional + some installs have them on CD and not in data directory
	testFile("VIDEO/GOOD1A.SMK", "campaign movies");
	testFile("SOUNDS/G1A.WAV", "campaign music"); //technically not a music but voiced intro sounds

	conf.init();
    logGlobal->infoStream() <<"Loading settings: "<<pomtime.getDiff();
    logGlobal->infoStream() << NAME;

	srand ( time(nullptr) );
	

	const JsonNode& video = settings["video"];
	const JsonNode& res = video["screenRes"];

	//something is really wrong...
	if (res["width"].Float() < 100 || res["height"].Float() < 100)
	{
        logGlobal->errorStream() << "Fatal error: failed to load settings!";
        logGlobal->errorStream() << "Possible reasons:";
        logGlobal->errorStream() << "\tCorrupted local configuration file at " << VCMIDirs::get().userConfigPath() << "/settings.json";
        logGlobal->errorStream() << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().userConfigPath() << "/schemas/settings.json";
        logGlobal->errorStream() << "VCMI will now exit...";
		exit(EXIT_FAILURE);
	}

	if(!gNoGUI)
	{
		if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
		{
			logGlobal->errorStream()<<"Something was wrong: "<< SDL_GetError();
			exit(-1);
		}
		atexit(SDL_Quit);
		setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
		logGlobal->infoStream() <<"\tInitializing screen: "<<pomtime.getDiff();
	}


	CCS = new CClientState;
	CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler etc.)
	// Initialize video
#if DISABLE_VIDEO
	CCS->videoh = new CEmptyVideoPlayer;
#else
	if (!gNoGUI && !vm.count("disable-video"))
		CCS->videoh = new CVideoPlayer;
	else
		CCS->videoh = new CEmptyVideoPlayer;
#endif

    logGlobal->infoStream()<<"\tInitializing video: "<<pomtime.getDiff();



	//we can properly play intro only in the main thread, so we have to move loading to the separate thread
	boost::thread loading(init);

	if(!gNoGUI )
	{
		if(!vm.count("battle") && !vm.count("nointro"))
			playIntro();
		SDL_FillRect(screen,nullptr,0);
	}

	CSDL_Ext::update(screen);
	loading.join();
    logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();

	if(!vm.count("battle"))
	{
		Settings session = settings.write["session"];
		session["autoSkip"].Bool()  = vm.count("autoSkip");
		session["oneGoodAI"].Bool() = vm.count("oneGoodAI");

		std::string fileToStartFrom; //none by default
		if(vm.count("start"))
			fileToStartFrom = vm["start"].as<std::string>();

		if(fileToStartFrom.size() && boost::filesystem::exists(fileToStartFrom))
			startGameFromFile(fileToStartFrom); //ommit pregame and start the game using settings from fiel
		else
		{
			if(fileToStartFrom.size())
			{
                logGlobal->warnStream() << "Warning: cannot find given file to start from (" << fileToStartFrom
                    << "). Falling back to main menu.";
			}
			GH.curInt = CGPreGame::create(); //will set CGP pointer to itself
		}
	}
	else
	{
		auto  si = new StartInfo();
		si->mode = StartInfo::DUEL;
		si->mapname = vm["battle"].as<std::string>();
		si->playerInfos[PlayerColor(0)].color = PlayerColor(0);
		si->playerInfos[PlayerColor(1)].color = PlayerColor(1);
		startGame(si);
	}

	if(!gNoGUI)
	{
		mainGUIThread = new boost::thread(&CGuiHandler::run, &GH);
		listenForEvents();
	}
	else
	{
		while(true)
			boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}

	return 0;
}