예제 #1
0
int
main(int argc, char **argv, char **envp)
{
  char *s;
  int i, exit_code;

#ifndef _MSC_VER
  /* catch SIGUSR1 and dump intermediate stats */
  signal(SIGUSR1, signal_sim_stats);

  /* catch SIGUSR2 and dump final stats and exit */
  signal(SIGUSR2, signal_exit_now);
#endif /* _MSC_VER */

  /* register an error handler */
  fatal_hook(sim_print_stats);

  /* set up a non-local exit point */
  if ((exit_code = setjmp(sim_exit_buf)) != 0)
    {
      /* special handling as longjmp cannot pass 0 */
      exit_now(exit_code-1);
    }

  /* register global options */
  sim_odb = opt_new(orphan_fn);
  opt_reg_flag(sim_odb, "-v", "verbose operation",
	       &verbose, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_int(sim_odb, "-seed",
	      "random number generator seed (0 for timer seed)",
	      &rand_seed, /* default */1, /* print */TRUE, NULL);
  opt_reg_string(sim_odb, "-chkpt", "restore EIO trace execution from <fname>",
		 &sim_chkpt_fname, /* default */NULL, /* !print */FALSE, NULL);

  /* register instruction execution options */
  insn_reg_options(sim_odb);

  /* register all simulator-specific options */
  sim_reg_options(sim_odb);

  /* parse simulator options */
  exec_index = -1;
  opt_process_options(sim_odb, argc, argv);

  /* need at least two argv values to run */
  if (argc < 2)
    {
      banner(stderr, argc, argv);
      usage(stderr, argc, argv);
      exit(1);
    }

  /* opening banner */
  banner(stderr, argc, argv);

  /* seed the random number generator */
  if (rand_seed == 0)
    {
      /* seed with the timer value, true random */
      mysrand(time((time_t *)NULL));
    }
  else
    {
      /* seed with default or user-specified random number generator seed */
      mysrand(rand_seed);
    }

  /* exec_index is set in orphan_fn() */
  if (exec_index == -1)
    {
      /* executable was not found */
      fprintf(stderr, "error: no executable specified\n");
      usage(stderr, argc, argv);
      exit(1);
    }
  /* else, exec_index points to simulated program arguments */

  /* initialize the instruction decoder */
  md_init_decoder();

  /* need options */
  insn_check_options();

  /* check simulator-specific options */
  sim_check_options();

  /* default architected value... */
  sim_num_insn = 0;

#ifdef BFD_LOADER
  /* initialize the bfd library */
  bfd_init();
#endif /* BFD_LOADER */

  /* initialize all simulation modules */
  sim_init();

  /* initialize architected state */
  sim_load_prog(argv[exec_index], argc-exec_index, argv+exec_index, envp);

  /* register all simulator stats */

  /* record start of execution time, used in rate stats */
  sim_start_time = time((time_t *)NULL);

  /* emit the command line for later reuse */
  fprintf(stderr, "sim: command line: ");
  for (i=0; i < argc; i++)
    fprintf(stderr, "%s ", argv[i]);
  fprintf(stderr, "\n");

  /* output simulation conditions */
  s = ctime(&sim_start_time);
  if (s[strlen(s)-1] == '\n')
    s[strlen(s)-1] = '\0';
  fprintf(stderr, "\nsim: simulation started @ %s, options follow:\n", s);
  opt_print_options(sim_odb, stderr, /* short */TRUE, /* notes */TRUE);
  sim_aux_config(stderr);
  fprintf(stderr, "\n");

  /* omit option dump time from rate stats */
  sim_start_time = time((time_t *)NULL);

  running = TRUE;
  sim_main();

  /* simulation finished early */
  exit_now(0);

  return 0;
}
예제 #2
0
static struct dma_program_node *
random_dma_program_structure(unsigned int seed)
{
	// So that test sequences are reproducable.
	mysrand(seed);

	// It is suprisingly difficult to come up with a routine to generate
	// valid DMA programs. Our main constraint is that we don't try to
	// set a loop counter in the body of a loop. I also want to generate
	// various interesting patterns of loops, and ensure that each loop
	// performs some interesting work.
	//
	// So, let's build up a tree. A tree node has up to two children, and
	// can be of four different types. It can be a loop: we can't have a
	// depth greater than 4 of loops. It can be an add, or transfer. It
	// can be a sequence. This whole proces is a bit hacky and ad-hoc. I
	// have a python script modelling the size of the program generated.
	// The parameters here give an average program length of 12, with a
	// maximum of around 23.

	struct dma_program_node *root, *next_space, *last_space, *left, *right;
	root = malloc(sizeof(struct dma_program_node));
	next_space = last_space = root;

	// Not technically a limit, but when the program gets this long, we
	// start definitely filling in gaps.
	const long LENGTH_LIMIT = 12;
	const long SPACE_LIMIT = 10;

	// These are longs so that we can multiply constants by RAND_LIMIT
	// without worrying.
	long spaces = 1;
	long program_length = 0;
	long space_bias, length_bias;

	int p;
	// The idea is we are more likely to add operations when the program
	// gets longer, and more likely to add spaces when there are fewer
	// spaces. The whole thing is unrolled, so we don't have to do divide,
	// which would require float conversion etc.
	while (spaces > 0) {
		p = myrand();
		space_bias = SPACE_LIMIT - spaces;
		length_bias = LENGTH_LIMIT - program_length;
		if ((LENGTH_LIMIT * p) > (RAND_LIMIT * length_bias)) {
			// fill in next space with operation
			next_space->dmapn_type = DMAPNT_OP;

			program_length += 1;
			spaces -= 1;
		}
		else if (LENGTH_LIMIT * SPACE_LIMIT * p >
				(RAND_LIMIT * length_bias * space_bias)) {
			// fill in with loop
			next_space->dmapn_type = DMAPNT_LOOP;
			left = malloc(sizeof(struct dma_program_node));
			next_space->dmapn_left_child = left;
			last_space->dmapn_next_space = left;
			last_space = left;

			program_length += 2;
		}
		else {
			next_space->dmapn_type = DMAPNT_SEQ;
			left = malloc(sizeof(struct dma_program_node));
			right = malloc(sizeof(struct dma_program_node));
			next_space->dmapn_left_child = left;
			next_space->dmapn_right_child = right;
			last_space->dmapn_next_space = left;
			left->dmapn_next_space = right;
			last_space = right;

			spaces += 1;
		}
		next_space = next_space->dmapn_next_space;
	}

	return root;
}
예제 #3
0
int
main(int argc, char **argv, char **envp)
{
  char *s;
  int i, exit_code;

#ifndef _MSC_VER
  /* catch SIGUSR1 and dump intermediate stats */
  signal(SIGUSR1, signal_sim_stats);

  /* catch SIGUSR2 and dump final stats and exit */
  signal(SIGUSR2, signal_exit_now);
#endif /* _MSC_VER */

  /* register an error handler */
  fatal_hook(sim_print_stats);

  /* set up a non-local exit point */
  if ((exit_code = setjmp(sim_exit_buf)) != 0)
    {
      /* special handling as longjmp cannot pass 0 */
      exit_now(exit_code-1);
    }

  /* register global options */
  sim_odb = opt_new(orphan_fn);
  opt_reg_flag(sim_odb, "-h", "print help message",
	       &help_me, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_flag(sim_odb, "-v", "verbose operation",
	       &verbose, /* default */FALSE, /* !print */FALSE, NULL);
#ifdef DEBUG
  opt_reg_flag(sim_odb, "-d", "enable debug message",
	       &debugging, /* default */FALSE, /* !print */FALSE, NULL);
#endif /* DEBUG */
  opt_reg_flag(sim_odb, "-i", "start in Dlite debugger",
	       &dlite_active, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_int(sim_odb, "-seed",
	      "random number generator seed (0 for timer seed)",
	      &rand_seed, /* default */1, /* print */TRUE, NULL);
  opt_reg_flag(sim_odb, "-q", "initialize and terminate immediately",
	       &init_quit, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_string(sim_odb, "-chkpt", "restore EIO trace execution from <fname>",
		 &sim_chkpt_fname, /* default */NULL, /* !print */FALSE, NULL);

  /* stdio redirection options */
  opt_reg_string(sim_odb, "-redir:sim",
		 "redirect simulator output to file (non-interactive only)",
		 &sim_simout,
		 /* default */NULL, /* !print */FALSE, NULL);
  opt_reg_string(sim_odb, "-redir:prog",
		 "redirect simulated program output to file",
		 &sim_progout, /* default */NULL, /* !print */FALSE, NULL);

#ifndef _MSC_VER
  /* scheduling priority option */
  opt_reg_int(sim_odb, "-nice",
	      "simulator scheduling priority", &nice_priority,
	      /* default */NICE_DEFAULT_VALUE, /* print */TRUE, NULL);
#endif

  /* FIXME: add stats intervals and max insts... */

  /* register all simulator-specific options */
  sim_reg_options(sim_odb);

  /* parse simulator options */
  exec_index = -1;
  opt_process_options(sim_odb, argc, argv);

  /* redirect I/O? */
  if (sim_simout != NULL)
    {
      /* send simulator non-interactive output (STDERR) to file SIM_SIMOUT */
      fflush(stderr);
      if (!freopen(sim_simout, "w", stderr))
	fatal("unable to redirect simulator output to file `%s'", sim_simout);
    }

  if (sim_progout != NULL)
    {
      /* redirect simulated program output to file SIM_PROGOUT */
      sim_progfd = fopen(sim_progout, "w");
      if (!sim_progfd)
	fatal("unable to redirect program output to file `%s'", sim_progout);
    }

  /* need at least two argv values to run */
  if (argc < 2)
    {
      banner(stderr, argc, argv);
      usage(stderr, argc, argv);
      exit(1);
    }

  /* opening banner */
  banner(stderr, argc, argv);

  if (help_me)
    {
      /* print help message and exit */
      usage(stderr, argc, argv);
      exit(1);
    }

  /* seed the random number generator */
  if (rand_seed == 0)
    {
      /* seed with the timer value, true random */
      mysrand(time((time_t *)NULL));
    }
  else
    {
      /* seed with default or user-specified random number generator seed */
      mysrand(rand_seed);
    }

  /* exec_index is set in orphan_fn() */
  if (exec_index == -1)
    {
      /* executable was not found */
      fprintf(stderr, "error: no executable specified\n");
      usage(stderr, argc, argv);
      exit(1);
    }
  /* else, exec_index points to simulated program arguments */

  /* check simulator-specific options */
  sim_check_options(sim_odb, argc, argv);

#ifndef _MSC_VER
  /* set simulator scheduling priority */
  if (nice(0) < nice_priority)
    {
      if (nice(nice_priority - nice(0)) < 0)
        fatal("could not renice simulator process");
    }
#endif

  /* default architected value... */
  sim_num_insn = 0;

#ifdef BFD_LOADER
  /* initialize the bfd library */
  bfd_init();
#endif /* BFD_LOADER */

  /* initialize the instruction decoder */
  md_init_decoder();

  /* initialize all simulation modules */
  sim_init();

  /* initialize architected state */
  sim_load_prog(argv[exec_index], argc-exec_index, argv+exec_index, envp);

  /* register all simulator stats */
  sim_sdb = stat_new();
  sim_reg_stats(sim_sdb);
#if 0 /* not portable... :-( */
  stat_reg_uint(sim_sdb, "sim_mem_usage",
		"total simulator (data) memory usage",
		&sim_mem_usage, sim_mem_usage, "%11dk");
#endif

  /* record start of execution time, used in rate stats */
  sim_start_time = time((time_t *)NULL);

  /* emit the command line for later reuse */
  fprintf(stderr, "sim: command line: ");
  for (i=0; i < argc; i++)
    fprintf(stderr, "%s ", argv[i]);
  fprintf(stderr, "\n");

  /* output simulation conditions */
  s = ctime(&sim_start_time);
  if (s[strlen(s)-1] == '\n')
    s[strlen(s)-1] = '\0';
  fprintf(stderr, "\nsim: simulation started @ %s, options follow:\n", s);
  opt_print_options(sim_odb, stderr, /* short */TRUE, /* notes */TRUE);
  sim_aux_config(stderr);
  fprintf(stderr, "\n");

  /* omit option dump time from rate stats */
  sim_start_time = time((time_t *)NULL);

  if (init_quit)
    exit_now(0);

  running = TRUE;
  sim_main();

  /* simulation finished early */
  exit_now(0);

  return 0;
}
예제 #4
0
파일: main.cpp 프로젝트: ChicoTeam/minetest
int main(int argc, char *argv[])
{
	int retval = 0;

	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");

	// This enables internatonal characters input
	if( setlocale(LC_ALL, "") == NULL )
	{
		fprintf( stderr, "%s: warning: could not set default locale\n", argv[0] );
	}

	// Set locale. This is for forcing '.' as the decimal point.
	try {
		std::locale::global(std::locale(std::locale(""), "C", std::locale::numeric));
		setlocale(LC_NUMERIC, "C");
	} catch (const std::exception& ex) {
		errorstream<<"Could not set numeric locale to C"<<std::endl;
	}
	/*
		Parse command line
	*/
	
	// List all allowed options
	core::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG,
			_("Show allowed options")));
	allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
			_("Load configuration from specified file")));
	allowed_options.insert("port", ValueSpec(VALUETYPE_STRING,
			_("Set network port (UDP)")));
	allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Disable unit tests")));
	allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Enable unit tests")));
	allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING,
			_("Same as --world (deprecated)")));
	allowed_options.insert("world", ValueSpec(VALUETYPE_STRING,
			_("Set world path (implies local game) ('list' lists all)")));
	allowed_options.insert("worldname", ValueSpec(VALUETYPE_STRING,
			_("Set world by name (implies local game)")));
	allowed_options.insert("info", ValueSpec(VALUETYPE_FLAG,
			_("Print more information to console")));
	allowed_options.insert("verbose", ValueSpec(VALUETYPE_FLAG,
			_("Print even more information to console")));
	allowed_options.insert("trace", ValueSpec(VALUETYPE_FLAG,
			_("Print enormous amounts of information to log and console")));
	allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING,
			_("Set logfile path ('' = no logging)")));
	allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING,
			_("Set gameid (\"--gameid list\" prints available ones)")));
#ifndef SERVER
	allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
			_("Run speed tests")));
	allowed_options.insert("address", ValueSpec(VALUETYPE_STRING,
			_("Address to connect to. ('' = local game)")));
	allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG,
			_("Enable random user input, for testing")));
	allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
			_("Run dedicated server")));
	allowed_options.insert("name", ValueSpec(VALUETYPE_STRING,
			_("Set player name")));
	allowed_options.insert("password", ValueSpec(VALUETYPE_STRING,
			_("Set password")));
	allowed_options.insert("go", ValueSpec(VALUETYPE_FLAG,
			_("Disable main menu")));
#endif

	Settings cmd_args;
	
	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1"))
	{
		dstream<<_("Allowed options:")<<std::endl;
		for(core::map<std::string, ValueSpec>::Iterator
				i = allowed_options.getIterator();
				i.atEnd() == false; i++)
		{
			std::ostringstream os1(std::ios::binary);
			os1<<"  --"<<i.getNode()->getKey();
			if(i.getNode()->getValue().type == VALUETYPE_FLAG)
				{}
			else
				os1<<_(" <value>");
			dstream<<padStringRight(os1.str(), 24);

			if(i.getNode()->getValue().help != NULL)
				dstream<<i.getNode()->getValue().help;
			dstream<<std::endl;
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}
	
	/*
		Low-level initialization
	*/
	
	// If trace is enabled, enable logging of certain things
	if(cmd_args.getFlag("trace")){
		dstream<<_("Enabling trace level debug output")<<std::endl;
		log_trace_level_enabled = true;
		dout_con_ptr = &verbosestream; // this is somewhat old crap
		socket_enable_debug_output = true; // socket doesn't use log.h
	}
	// In certain cases, output info level on stderr
	if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
			cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
		log_add_output(&main_stderr_log_out, LMT_INFO);
	// In certain cases, output verbose level on stderr
	if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
		log_add_output(&main_stderr_log_out, LMT_VERBOSE);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();
	
	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_user);

	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str());

	infostream<<"path_share = "<<porting::path_share<<std::endl;
	infostream<<"path_user  = "******"gameid") && cmd_args.get("gameid") == "list")
	{
		std::set<std::string> gameids = getAvailableGameIds();
		for(std::set<std::string>::const_iterator i = gameids.begin();
				i != gameids.end(); i++)
			dstream<<(*i)<<std::endl;
		return 0;
	}
	
	// List worlds if requested
	if(cmd_args.exists("world") && cmd_args.get("world") == "list"){
		dstream<<_("Available worlds:")<<std::endl;
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		print_worldspecs(worldspecs, dstream);
		return 0;
	}
	
	// Print startup message
	infostream<<PROJECT_NAME<<
			" "<<_("with")<<" SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
			<<", "<<BUILD_INFO
			<<std::endl;
	
	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);
	
	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);
	
	/*
		Read config file
	*/
	
	// Path of configuration file in use
	std::string configpath = "";
	
	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		configpath = cmd_args.get("config");
	}
	else
	{
		core::array<std::string> filenames;
		filenames.push_back(porting::path_user +
				DIR_DELIM + "minetest.conf");
		// Legacy configuration file location
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#if RUN_IN_PLACE
		// Try also from a lower level (to aid having the same configuration
		// for many RUN_IN_PLACE installs)
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				configpath = filenames[i];
				break;
			}
		}
		
		// If no path found, use the first one (menu creates the file)
		if(configpath == "")
			configpath = filenames[0];
	}
	
	// Initialize debug streams
#define DEBUGFILE "debug.txt"
#if RUN_IN_PLACE
	std::string logfile = DEBUGFILE;
#else
	std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
	if(cmd_args.exists("logfile"))
		logfile = cmd_args.get("logfile");
	
	log_remove_output(&main_dstream_no_stderr_log_out);
	int loglevel = g_settings->getS32("debug_log_level");

	if (loglevel == 0) //no logging
		logfile = "";
	else if (loglevel > 0 && loglevel <= LMT_NUM_VALUES)
		log_add_output_maxlev(&main_dstream_no_stderr_log_out, (LogMessageLevel)(loglevel - 1));

	if(logfile != "")
		debugstreams_init(false, logfile.c_str());
	else
		debugstreams_init(false, NULL);
		
	infostream<<"logfile    = "<<logfile<<std::endl;

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
	
	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;
	
	// World directory
	std::string commanded_world = "";
	if(cmd_args.exists("world"))
		commanded_world = cmd_args.get("world");
	else if(cmd_args.exists("map-dir"))
		commanded_world = cmd_args.get("map-dir");
	else if(cmd_args.exists("nonopt0")) // First nameless argument
		commanded_world = cmd_args.get("nonopt0");
	else if(g_settings->exists("map-dir"))
		commanded_world = g_settings->get("map-dir");
	
	// World name
	std::string commanded_worldname = "";
	if(cmd_args.exists("worldname"))
		commanded_worldname = cmd_args.get("worldname");
	
	// Strip world.mt from commanded_world
	{
		std::string worldmt = "world.mt";
		if(commanded_world.size() > worldmt.size() &&
				commanded_world.substr(commanded_world.size()-worldmt.size())
				== worldmt){
			dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl;
			commanded_world = commanded_world.substr(
					0, commanded_world.size()-worldmt.size());
		}
	}
	
	// If a world name was specified, convert it to a path
	if(commanded_worldname != ""){
		// Get information about available worlds
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		bool found = false;
		for(u32 i=0; i<worldspecs.size(); i++){
			std::string name = worldspecs[i].name;
			if(name == commanded_worldname){
				if(commanded_world != ""){
					dstream<<_("--worldname takes precedence over previously "
							"selected world.")<<std::endl;
				}
				commanded_world = worldspecs[i].path;
				found = true;
				break;
			}
		}
		if(!found){
			dstream<<_("World")<<" '"<<commanded_worldname<<_("' not "
					"available. Available worlds:")<<std::endl;
			print_worldspecs(worldspecs, dstream);
			return 1;
		}
	}

	// Gamespec
	SubgameSpec commanded_gamespec;
	if(cmd_args.exists("gameid")){
		std::string gameid = cmd_args.get("gameid");
		commanded_gamespec = findSubgame(gameid);
		if(!commanded_gamespec.isValid()){
			errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
			return 1;
		}
	}

	/*
		Run dedicated server if asked to or no other option
	*/
#ifdef SERVER
	bool run_dedicated_server = true;
#else
	bool run_dedicated_server = cmd_args.getFlag("server");
#endif
	g_settings->set("server_dedicated", run_dedicated_server ? "true" : "false");
	if(run_dedicated_server)
	{
		DSTACK("Dedicated server branch");
		// Create time getter if built with Irrlicht
#ifndef SERVER
		g_timegetter = new SimpleTimeGetter();
#endif

		// World directory
		std::string world_path;
		verbosestream<<_("Determining world path")<<std::endl;
		bool is_legacy_world = false;
		// If a world was commanded, use it
		if(commanded_world != ""){
			world_path = commanded_world;
			infostream<<"Using commanded world path ["<<world_path<<"]"
					<<std::endl;
		}
		// No world was specified; try to select it automatically
		else
		{
			// Get information about available worlds
			std::vector<WorldSpec> worldspecs = getAvailableWorlds();
			// If a world name was specified, select it
			if(commanded_worldname != ""){
				world_path = "";
				for(u32 i=0; i<worldspecs.size(); i++){
					std::string name = worldspecs[i].name;
					if(name == commanded_worldname){
						world_path = worldspecs[i].path;
						break;
					}
				}
				if(world_path == ""){
					dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not "
							"available. Available worlds:")<<std::endl;
					print_worldspecs(worldspecs, dstream);
					return 1;
				}
			}
			// If there is only a single world, use it
			if(worldspecs.size() == 1){
				world_path = worldspecs[0].path;
				dstream<<_("Automatically selecting world at")<<" ["
						<<world_path<<"]"<<std::endl;
			// If there are multiple worlds, list them
			} else if(worldspecs.size() > 1){
				dstream<<_("Multiple worlds are available.")<<std::endl;
				dstream<<_("Please select one using --worldname <name>"
						" or --world <path>")<<std::endl;
				print_worldspecs(worldspecs, dstream);
				return 1;
			// If there are no worlds, automatically create a new one
			} else {
				// This is the ultimate default world path
				world_path = porting::path_user + DIR_DELIM + "worlds" +
						DIR_DELIM + "world";
				infostream<<"Creating default world at ["
						<<world_path<<"]"<<std::endl;
			}
		}

		if(world_path == ""){
			errorstream<<"No world path specified or found."<<std::endl;
			return 1;
		}
		verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl;

		// We need a gamespec.
		SubgameSpec gamespec;
		verbosestream<<_("Determining gameid/gamespec")<<std::endl;
		// If world doesn't exist
		if(!getWorldExists(world_path))
		{
			// Try to take gamespec from command line
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl;
			}
			// Otherwise we will be using "minetest"
			else{
				gamespec = findSubgame(g_settings->get("default_game"));
				infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		// World exists
		else
		{
			std::string world_gameid = getWorldGameId(world_path, is_legacy_world);
			// If commanded to use a gameid, do so
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				if(commanded_gamespec.id != world_gameid){
					errorstream<<"WARNING: Using commanded gameid ["
							<<gamespec.id<<"]"<<" instead of world gameid ["
							<<world_gameid<<"]"<<std::endl;
				}
			} else{
				// If world contains an embedded game, use it;
				// Otherwise find world from local system.
				gamespec = findWorldSubgame(world_path);
				infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		if(!gamespec.isValid()){
			errorstream<<"Subgame ["<<gamespec.id<<"] could not be found."
					<<std::endl;
			return 1;
		}
		verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;

		// Create server
		Server server(world_path, configpath, gamespec, false);
		server.start(port);
		
		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}

#ifndef SERVER // Exclude from dedicated server build

	/*
		More parameters
	*/
	
	std::string address = g_settings->get("address");
	if(commanded_world != "")
		address = "";
	else if(cmd_args.exists("address"))
		address = cmd_args.get("address");
	
	std::string playername = g_settings->get("name");
	if(cmd_args.exists("name"))
		playername = cmd_args.get("name");
	
	bool skip_main_menu = cmd_args.getFlag("go");

	/*
		Device initialization
	*/

	// Resolution selection
	
	bool fullscreen = g_settings->getBool("fullscreen");
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// bpp, fsaa, vsync

	bool vsync = g_settings->getBool("vsync");
	u16 bits = g_settings->getU16("fullscreen_bpp");
	u16 fsaa = g_settings->getU16("fsaa");

	// Determine driver

	video::E_DRIVER_TYPE driverType;
	
	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		Create device and exit if creation failed
	*/

	MyEventReceiver receiver;

	IrrlichtDevice *device;

	SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
	params.DriverType    = driverType;
	params.WindowSize    = core::dimension2d<u32>(screenW, screenH);
	params.Bits          = bits;
	params.AntiAlias     = fsaa;
	params.Fullscreen    = fullscreen;
	params.Stencilbuffer = false;
	params.Vsync         = vsync;
	params.EventReceiver = &receiver;

	device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.
	
	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	/*
		This changes the minimum allowed number of vertices in a VBO.
		Default is 500.
	*/
	//driver->setMinHardwareBufferVertexCount(50);

	// Create time getter
	g_timegetter = new IrrlichtTimeGetter(device);
	
	// Create game callback for menus
	g_gamecallback = new MainGameCallback(device);
	
	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		return 0;
	}
	
	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input)
		input = new RandomInputHandler();
	else
		input = new RealInputHandler(device, &receiver);
	
	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	#if USE_FREETYPE
	std::string font_path = g_settings->get("font_path");
	u16 font_size = g_settings->getU16("font_size");
	gui::IGUIFont *font = gui::CGUITTFont::createTTFont(guienv, font_path.c_str(), font_size);
	#else
	gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
	#endif
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	assert(font);
	
	u32 text_height = font->getDimension(L"Hello, world!").Height;
	infostream<<"text_height="<<text_height<<std::endl;

	//skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255,70,100,50));
	skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255,255,255,255));

#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
	// Irrlicht 1.8 input colours
	skin->setColor(gui::EGDC_EDITABLE, video::SColor(255,128,128,128));
	skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49));
#endif

	/*
		GUI stuff
	*/

	ChatBackend chat_backend;

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	bool first_loop = true;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{
		// Set the window caption
		device->setWindowCaption((std::wstring(L"Minetest [")+wgettext("Main Menu")+L"]").c_str());

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			guienv->clear();
			
			/*
				We need some kind of a root node to be able to add
				custom gui elements directly on the screen.
				Otherwise they won't be automatically drawn.
			*/
			guiroot = guienv->addStaticText(L"",
					core::rect<s32>(0, 0, 10000, 10000));
			
			SubgameSpec gamespec;
			WorldSpec worldspec;
			bool simple_singleplayer_mode = false;

			// These are set up based on the menu and other things
			std::string current_playername = "inv£lid";
			std::string current_password = "";
			std::string current_address = "does-not-exist";
			int current_port = 0;

			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// If skip_main_menu, only go through here once
				if(skip_main_menu && !first_loop){
					kill = true;
					break;
				}
				first_loop = false;
				
				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();
				
				// Initialize menu data
				MainMenuData menudata;
				if(g_settings->exists("selected_mainmenu_tab"))
					menudata.selected_tab = g_settings->getS32("selected_mainmenu_tab");
				menudata.address = narrow_to_wide(address);
				menudata.name = narrow_to_wide(playername);
				menudata.port = narrow_to_wide(itos(port));
				if(cmd_args.exists("password"))
					menudata.password = narrow_to_wide(cmd_args.get("password"));
				menudata.fancy_trees = g_settings->getBool("new_style_leaves");
				menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
				menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
				menudata.opaque_water = g_settings->getBool("opaque_water");
				menudata.mip_map = g_settings->getBool("mip_map");
				menudata.anisotropic_filter = g_settings->getBool("anisotropic_filter");
				menudata.bilinear_filter = g_settings->getBool("bilinear_filter");
				menudata.trilinear_filter = g_settings->getBool("trilinear_filter");
				menudata.enable_shaders = g_settings->getS32("enable_shaders");
				menudata.preload_item_visuals = g_settings->getBool("preload_item_visuals");
				menudata.enable_particles = g_settings->getBool("enable_particles");
				driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, menudata.mip_map);
				menudata.creative_mode = g_settings->getBool("creative_mode");
				menudata.enable_damage = g_settings->getBool("enable_damage");
				menudata.enable_public = g_settings->getBool("server_announce");
				// Default to selecting nothing
				menudata.selected_world = -1;
				// Get world listing for the menu
				std::vector<WorldSpec> worldspecs = getAvailableWorlds();
				// If there is only one world, select it
				if(worldspecs.size() == 1){
					menudata.selected_world = 0;
				}
				// Otherwise try to select according to selected_world_path
				else if(g_settings->exists("selected_world_path")){
					std::string trypath = g_settings->get("selected_world_path");
					for(u32 i=0; i<worldspecs.size(); i++){
						if(worldspecs[i].path == trypath){
							menudata.selected_world = i;
							break;
						}
					}
				}
				// If a world was commanded, append and select it
				if(commanded_world != ""){
					std::string gameid = getWorldGameId(commanded_world, true);
					std::string name = _("[--world parameter]");
					if(gameid == ""){
						gameid = g_settings->get("default_game");
						name += " [new]";
					}
					WorldSpec spec(commanded_world, name, gameid);
					worldspecs.push_back(spec);
					menudata.selected_world = worldspecs.size()-1;
				}
				// Copy worldspecs to menu
				menudata.worlds = worldspecs;

				if(skip_main_menu == false)
				{
					video::IVideoDriver* driver = device->getVideoDriver();
					
					infostream<<"Waiting for other menus"<<std::endl;
					while(device->run() && kill == false)
					{
						if(noMenuActive())
							break;
						driver->beginScene(true, true,
								video::SColor(255,128,128,128));
						drawMenuBackground(driver);
						guienv->drawAll();
						driver->endScene();
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					infostream<<"Waited for other menus"<<std::endl;

					GUIMainMenu *menu =
							new GUIMainMenu(guienv, guiroot, -1, 
								&g_menumgr, &menudata, g_gamecallback);
					menu->allowFocusRemoval(true);

					if(error_message != L"")
					{
						verbosestream<<"error_message = "
								<<wide_to_narrow(error_message)<<std::endl;

						GUIMessageMenu *menu2 =
								new GUIMessageMenu(guienv, guiroot, -1, 
									&g_menumgr, error_message.c_str());
						menu2->drop();
						error_message = L"";
					}

					infostream<<"Created main menu"<<std::endl;

					while(device->run() && kill == false)
					{
						if(menu->getStatus() == true)
							break;

						//driver->beginScene(true, true, video::SColor(255,0,0,0));
						driver->beginScene(true, true, video::SColor(255,128,128,128));

						drawMenuBackground(driver);

						guienv->drawAll();
						
						driver->endScene();
						
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					
					infostream<<"Dropping main menu"<<std::endl;

					menu->drop();
				}

				playername = wide_to_narrow(menudata.name);
				password = translatePassword(playername, menudata.password);
				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = wide_to_narrow(menudata.address);
				int newport = stoi(wide_to_narrow(menudata.port));
				if(newport != 0)
					port = newport;
				simple_singleplayer_mode = menudata.simple_singleplayer_mode;
				// Save settings
				g_settings->setS32("selected_mainmenu_tab", menudata.selected_tab);
				g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
				g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
				g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
				g_settings->set("opaque_water", itos(menudata.opaque_water));

				g_settings->set("mip_map", itos(menudata.mip_map));
				g_settings->set("anisotropic_filter", itos(menudata.anisotropic_filter));
				g_settings->set("bilinear_filter", itos(menudata.bilinear_filter));
				g_settings->set("trilinear_filter", itos(menudata.trilinear_filter));

				g_settings->setS32("enable_shaders", menudata.enable_shaders);
				g_settings->set("preload_item_visuals", itos(menudata.preload_item_visuals));
				g_settings->set("enable_particles", itos(menudata.enable_particles));

				g_settings->set("creative_mode", itos(menudata.creative_mode));
				g_settings->set("enable_damage", itos(menudata.enable_damage));
				g_settings->set("server_announce", itos(menudata.enable_public));
				g_settings->set("name", playername);
				g_settings->set("address", address);
				g_settings->set("port", itos(port));
				if(menudata.selected_world != -1)
					g_settings->set("selected_world_path",
							worldspecs[menudata.selected_world].path);

				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;
				
				current_playername = playername;
				current_password = password;
				current_address = address;
				current_port = port;

				// If using simple singleplayer mode, override
				if(simple_singleplayer_mode){
					current_playername = "singleplayer";
					current_password = "";
					current_address = "";
					current_port = 30011;
				}
				else if (address != "")
				{
					ServerListSpec server;
					server["name"] = menudata.servername;
					server["address"] = wide_to_narrow(menudata.address);
					server["port"] = wide_to_narrow(menudata.port);
					server["description"] = menudata.serverdescription;
					ServerList::insert(server);
				}
				
				// Set world path to selected one
				if(menudata.selected_world != -1){
					worldspec = worldspecs[menudata.selected_world];
					infostream<<"Selected world: "<<worldspec.name
							<<" ["<<worldspec.path<<"]"<<std::endl;
				}

				// Only refresh if so requested
				if(menudata.only_refresh){
					infostream<<"Refreshing menu"<<std::endl;
					continue;
				}
				
				// Create new world if requested
				if(menudata.create_world_name != L"")
				{
					std::string path = porting::path_user + DIR_DELIM
							"worlds" + DIR_DELIM
							+ wide_to_narrow(menudata.create_world_name);
					// Create world if it doesn't exist
					if(!initializeWorld(path, menudata.create_world_gameid)){
						error_message = wgettext("Failed to initialize world");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					g_settings->set("selected_world_path", path);
					continue;
				}

				// If local game
				if(current_address == "")
				{
					if(menudata.selected_world == -1){
						error_message = wgettext("No world selected and no address "
								"provided. Nothing to do.");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					// Load gamespec for required game
					gamespec = findWorldSubgame(worldspec.path);
					if(!gamespec.isValid() && !commanded_gamespec.isValid()){
						error_message = wgettext("Could not find or load game \"")
								+ narrow_to_wide(worldspec.gameid) + L"\"";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					if(commanded_gamespec.isValid() &&
							commanded_gamespec.id != worldspec.gameid){
						errorstream<<"WARNING: Overriding gamespec from \""
								<<worldspec.gameid<<"\" to \""
								<<commanded_gamespec.id<<"\""<<std::endl;
						gamespec = commanded_gamespec;
					}

					if(!gamespec.isValid()){
						error_message = wgettext("Invalid gamespec.");
						error_message += L" (world_gameid="
								+narrow_to_wide(worldspec.gameid)+L")";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
				}

				// Continue to game
				break;
			}
			
			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true)
				break;

			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				worldspec.path,
				current_playername,
				current_password,
				current_address,
				current_port,
				error_message,
				configpath,
				chat_backend,
				gamespec,
				simple_singleplayer_mode
			);

		} //try
		catch(con::PeerNotFoundException &e)
		{
			error_message = wgettext("Connection error (timed out?)");
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ServerError &e)
		{
			error_message = narrow_to_wide(e.what());
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ModError &e)
		{
			errorstream<<e.what()<<std::endl;
			error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details.");
		}
#ifdef NDEBUG
		catch(std::exception &e)
		{
			std::string narrow_message = "Some exception: \"";
			narrow_message += e.what();
			narrow_message += "\"";
			errorstream<<narrow_message<<std::endl;
			error_message = narrow_to_wide(narrow_message);
		}
#endif

		// If no main menu, show error and exit
		if(skip_main_menu)
		{
			if(error_message != L""){
				verbosestream<<"error_message = "
						<<wide_to_narrow(error_message)<<std::endl;
				retval = 1;
			}
			break;
		}
	} // Menu-game loop
	
	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();

#endif // !SERVER
	
	// Update configuration file
	if(configpath != "")
		g_settings->updateConfigFile(configpath.c_str());
	
	// Print modified quicktune values
	{
		bool header_printed = false;
		std::vector<std::string> names = getQuicktuneNames();
		for(u32 i=0; i<names.size(); i++){
			QuicktuneValue val = getQuicktuneValue(names[i]);
			if(!val.modified)
				continue;
			if(!header_printed){
				dstream<<"Modified quicktune values:"<<std::endl;
				header_printed = true;
			}
			dstream<<names[i]<<" = "<<val.getString()<<std::endl;
		}
	}

	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	
	debugstreams_deinit();
	
	return retval;
}
예제 #5
0
파일: main.cpp 프로젝트: Queatz/minetest
int main(int argc, char *argv[])
{
	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");

	// Set locale. This is for forcing '.' as the decimal point.
	std::locale::global(std::locale("C"));
	// This enables printing all characters in bitmap font
	setlocale(LC_CTYPE, "en_US");

	/*
		Parse command line
	*/
	
	// List all allowed options
	core::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG,
			"Show allowed options"));
	allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
			"Run server directly"));
	allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
			"Load configuration from specified file"));
	allowed_options.insert("port", ValueSpec(VALUETYPE_STRING,
			"Set network port to connect to"));
	allowed_options.insert("address", ValueSpec(VALUETYPE_STRING,
			"Address to connect to"));
	allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG,
			"Enable random user input, for testing"));
	allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			"Disable unit tests"));
	allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			"Enable unit tests"));
	allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING,
			"Map directory (where everything in the world is stored)"));
#ifdef _WIN32
	allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
#endif
	allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
			"Run speed tests"));
	allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG,
			"Print debug information to console"));

	Settings cmd_args;
	
	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help"))
	{
		dstream<<"Allowed options:"<<std::endl;
		for(core::map<std::string, ValueSpec>::Iterator
				i = allowed_options.getIterator();
				i.atEnd() == false; i++)
		{
			dstream<<"  --"<<i.getNode()->getKey();
			if(i.getNode()->getValue().type == VALUETYPE_FLAG)
			{
			}
			else
			{
				dstream<<" <value>";
			}
			dstream<<std::endl;

			if(i.getNode()->getValue().help != NULL)
			{
				dstream<<"      "<<i.getNode()->getValue().help
						<<std::endl;
			}
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}
	
	/*
		Low-level initialization
	*/

	bool disable_stderr = false;
#ifdef _WIN32
	if(cmd_args.getFlag("dstream-on-stderr") == false)
		disable_stderr = true;
#endif
	
	if(cmd_args.getFlag("info-on-stderr"))
		log_add_output(&main_stderr_log_out, LMT_INFO);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();
	
	// Initialize porting::path_data and porting::path_userdata
	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_userdata);

	init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
	
	// Initialize debug streams
#ifdef RUN_IN_PLACE
	std::string debugfile = DEBUGFILE;
#else
	std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
#endif
	debugstreams_init(disable_stderr, debugfile.c_str());
	// Initialize debug stacks
	debug_stacks_init();

	DSTACK(__FUNCTION_NAME);

	// Init material properties table
	//initializeMaterialProperties();

	// Debug handler
	BEGIN_DEBUG_EXCEPTION_HANDLER

	// Print startup message
	actionstream<<PROJECT_NAME<<
			" with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
			<<", "<<BUILD_INFO
			<<std::endl;
	
	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);
	
	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);
	
	/*
		Read config file
	*/
	
	// Path of configuration file in use
	std::string configpath = "";
	
	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		configpath = cmd_args.get("config");
	}
	else
	{
		core::array<std::string> filenames;
		filenames.push_back(porting::path_userdata +
				DIR_DELIM + "minetest.conf");
#ifdef RUN_IN_PLACE
		filenames.push_back(porting::path_userdata +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				configpath = filenames[i];
				break;
			}
		}
		
		// If no path found, use the first one (menu creates the file)
		if(configpath == "")
			configpath = filenames[0];
	}

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
	
	/*for(s16 y=-100; y<100; y++)
	for(s16 x=-100; x<100; x++)
	{
		std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl;
	}
	return 0;*/
	
	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;
	
	// Map directory
	std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
	if(cmd_args.exists("map-dir"))
		map_dir = cmd_args.get("map-dir");
	else if(g_settings->exists("map-dir"))
		map_dir = g_settings->get("map-dir");
	
	// Run dedicated server if asked to
	if(cmd_args.getFlag("server"))
	{
		DSTACK("Dedicated server branch");

		// Create time getter
		g_timegetter = new SimpleTimeGetter();
		
		// Create server
		Server server(map_dir.c_str(), configpath);
		server.start(port);
		
		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}


	/*
		More parameters
	*/
	
	// Address to connect to
	std::string address = "";
	
	if(cmd_args.exists("address"))
	{
		address = cmd_args.get("address");
	}
	else
	{
		address = g_settings->get("address");
	}
	
	std::string playername = g_settings->get("name");

	/*
		Device initialization
	*/

	// Resolution selection
	
	bool fullscreen = false;
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// Determine driver

	video::E_DRIVER_TYPE driverType;
	
	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		Create device and exit if creation failed
	*/

	MyEventReceiver receiver;

	IrrlichtDevice *device;
	device = createDevice(driverType,
			core::dimension2d<u32>(screenW, screenH),
			16, fullscreen, false, false, &receiver);

	if (device == 0)
		return 1; // could not create selected driver.
	
	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	// Disable mipmaps (because some of them look ugly)
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	/*
		This changes the minimum allowed number of vertices in a VBO.
		Default is 500.
	*/
	//driver->setMinHardwareBufferVertexCount(50);

	// Set the window caption
	device->setWindowCaption(L"Minetest [Main Menu]");
	
	// Create time getter
	g_timegetter = new IrrlichtTimeGetter(device);
	
	// Create game callback for menus
	g_gamecallback = new MainGameCallback(device);
	
	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		return 0;
	}
	
	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input)
		input = new RandomInputHandler();
	else
		input = new RealInputHandler(device, &receiver);
	
	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	assert(font);
	
	u32 text_height = font->getDimension(L"Hello, world!").Height;
	infostream<<"text_height="<<text_height<<std::endl;

	//skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
	
	/*
		GUI stuff
	*/

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			guienv->clear();
			
			/*
				We need some kind of a root node to be able to add
				custom gui elements directly on the screen.
				Otherwise they won't be automatically drawn.
			*/
			guiroot = guienv->addStaticText(L"",
					core::rect<s32>(0, 0, 10000, 10000));
			
			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();
				// Reset or hide the debug gui texts
				/*guitext->setText(L"Minetest-c55");
				guitext2->setVisible(false);
				guitext_info->setVisible(false);
				guitext_chat->setVisible(false);*/
				
				// Initialize menu data
				MainMenuData menudata;
				menudata.address = narrow_to_wide(address);
				menudata.name = narrow_to_wide(playername);
				menudata.port = narrow_to_wide(itos(port));
				menudata.fancy_trees = g_settings->getBool("new_style_leaves");
				menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
				menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
				menudata.opaque_water = g_settings->getBool("opaque_water");
				menudata.creative_mode = g_settings->getBool("creative_mode");
				menudata.enable_damage = g_settings->getBool("enable_damage");

				GUIMainMenu *menu =
						new GUIMainMenu(guienv, guiroot, -1, 
							&g_menumgr, &menudata, g_gamecallback);
				menu->allowFocusRemoval(true);

				if(error_message != L"")
				{
					errorstream<<"error_message = "
							<<wide_to_narrow(error_message)<<std::endl;

					GUIMessageMenu *menu2 =
							new GUIMessageMenu(guienv, guiroot, -1, 
								&g_menumgr, error_message.c_str());
					menu2->drop();
					error_message = L"";
				}

				video::IVideoDriver* driver = device->getVideoDriver();
				
				infostream<<"Created main menu"<<std::endl;

				while(device->run() && kill == false)
				{
					if(menu->getStatus() == true)
						break;

					//driver->beginScene(true, true, video::SColor(255,0,0,0));
					driver->beginScene(true, true, video::SColor(255,128,128,128));

					drawMenuBackground(driver);

					guienv->drawAll();
					
					driver->endScene();
					
					// On some computers framerate doesn't seem to be
					// automatically limited
					sleep_ms(25);
				}
				
				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;
				
				infostream<<"Dropping main menu"<<std::endl;

				menu->drop();
				
				// Delete map if requested
				if(menudata.delete_map)
				{
					bool r = fs::RecursiveDeleteContent(map_dir);
					if(r == false)
						error_message = L"Delete failed";
					continue;
				}

				playername = wide_to_narrow(menudata.name);

				password = translatePassword(playername, menudata.password);

				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = wide_to_narrow(menudata.address);
				int newport = stoi(wide_to_narrow(menudata.port));
				if(newport != 0)
					port = newport;
				g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
				g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
				g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
				g_settings->set("opaque_water", itos(menudata.opaque_water));
				g_settings->set("creative_mode", itos(menudata.creative_mode));
				g_settings->set("enable_damage", itos(menudata.enable_damage));
				
				// NOTE: These are now checked server side; no need to do it
				//       here, so let's not do it here.
				/*// Check for valid parameters, restart menu if invalid.
				if(playername == "")
				{
					error_message = L"Name required.";
					continue;
				}
				// Check that name has only valid chars
				if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)
				{
					error_message = L"Characters allowed: "
							+narrow_to_wide(PLAYERNAME_ALLOWED_CHARS);
					continue;
				}*/

				// Save settings
				g_settings->set("name", playername);
				g_settings->set("address", address);
				g_settings->set("port", itos(port));
				// Update configuration file
				if(configpath != "")
					g_settings->updateConfigFile(configpath.c_str());
			
				// Continue to game
				break;
			}
			
			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true)
				break;
			
			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				map_dir,
				playername,
				password,
				address,
				port,
				error_message,
				configpath
			);

		} //try
		catch(con::PeerNotFoundException &e)
		{
			errorstream<<"Connection error (timed out?)"<<std::endl;
			error_message = L"Connection error (timed out?)";
		}
		catch(SocketException &e)
		{
			errorstream<<"Socket error (port already in use?)"<<std::endl;
			error_message = L"Socket error (port already in use?)";
		}
		catch(ModError &e)
		{
			errorstream<<e.what()<<std::endl;
			error_message = narrow_to_wide(e.what()) + L"\nCheck debug.txt for details.";
		}
#ifdef NDEBUG
		catch(std::exception &e)
		{
			std::string narrow_message = "Some exception, what()=\"";
			narrow_message += e.what();
			narrow_message += "\"";
			errorstream<<narrow_message<<std::endl;
			error_message = narrow_to_wide(narrow_message);
		}
#endif

	} // Menu-game loop
	
	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();
	
	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	
	debugstreams_deinit();
	
	return 0;
}
예제 #6
0
파일: jmetis.c 프로젝트: liuxfiu/primogeni
JNIEXPORT jint JNICALL Java_jprime_JMetis_PartitionGraph(
		JNIEnv * env,
		jobject obj,
		jboolean j_force_PartGraphRecursive,
		jboolean j_force_PartGraphKway,
		jint j_num_vertices,
		jintArray j_xadj,
		jintArray j_adjncy,
		jintArray j_vwgt,
		jintArray j_adjwgt,
		jint j_wgtflag,
		jint j_nparts,
		jintArray j_options,
		jintArray j_partioned_nodes) {
	mysrand(7654321L);
	//delcare vars
	jint * xadj=NULL, * adjncy=NULL,* vwgt=NULL, * adjwgt=NULL, * options=NULL, * partioned_nodes=NULL;
	int idx, edges_cut=-1, num_vertices=0, nparts=0, wgtflag=0, numflag=0;
	jsize xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len;

	//copy the jsize vars
	num_vertices=j_num_vertices;
	nparts=j_nparts;
	wgtflag=j_wgtflag;

	//get array lengths
	xadj_len            = (*env)->GetArrayLength(env,j_xadj);
	adjncy_len          = (*env)->GetArrayLength(env,j_adjncy);
	vwgt_len            = (*env)->GetArrayLength(env,j_vwgt);
	adjwgt_len          = (*env)->GetArrayLength(env,j_adjwgt);
	options_len         = (*env)->GetArrayLength(env,j_options);
	partioned_nodes_len = (*env)->GetArrayLength(env,j_partioned_nodes);
	//printf("xadj_len=%i, adjncy_len=%i, vwgt_len=%i, adjwgt_len=%i, options_len=%i, partioned_nodes_len=%i\n",xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len);

	//create/get local copies
	xadj                      = (*env)->GetIntArrayElements(env,j_xadj,0);
	adjncy                    = (*env)->GetIntArrayElements(env,j_adjncy,0);
	if(vwgt_len>0)    vwgt    = (*env)->GetIntArrayElements(env,j_vwgt,0);
	if(adjwgt_len>0)  adjwgt  = (*env)->GetIntArrayElements(env,j_adjwgt,0);
	if(options_len>0) options = (*env)->GetIntArrayElements(env,j_options,0);
	partioned_nodes           = (int*)malloc(sizeof(int)*partioned_nodes_len);
#if 0
	printf("num_vertices=%i,wgtflag=%i, numflag=%i, nparts=%i\n", num_vertices, wgtflag, numflag, nparts);
	printf("xadj=%p, adjncy=%p, vwgt=%p, adjwgt=%p, options=%p, partioned_nodes=%p\n",
		xadj,
		adjncy,
		vwgt,
		adjwgt,
		options,
		partioned_nodes);
	printf("xadj:");
	for(idx=0;idx<xadj_len;idx++) {
		printf("%i ",xadj[idx]);
	}
	printf("\n");

	printf("adjncy:");
	for(idx=0;idx<adjncy_len;idx++) {
		printf("%i ",adjncy[idx]);
	}
	printf("\n");
#endif
	//call func
	if((j_nparts<8 || j_force_PartGraphRecursive) && !j_force_PartGraphKway) {
		METIS_PartGraphRecursive(
				&num_vertices,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				options,
				&edges_cut,
				partioned_nodes);
	}
	else {
		METIS_PartGraphKway(
				&num_vertices,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				options,
				&edges_cut,
				partioned_nodes);
	}

	//pop partioned_nodes
	(*env)->SetIntArrayRegion(env,j_partioned_nodes,0,partioned_nodes_len,partioned_nodes);

	//free local copies
	free(partioned_nodes);
	(*env)->ReleaseIntArrayElements(env, j_xadj, xadj, 0);
	(*env)->ReleaseIntArrayElements(env, j_adjncy, adjncy, 0);
	if(vwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_vwgt, vwgt, 0);
	if(adjwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_adjwgt, adjwgt, 0);
	if(options_len>0) (*env)->ReleaseIntArrayElements(env, j_options, options, 0);
	return edges_cut;
}
예제 #7
0
파일: jmetis.c 프로젝트: liuxfiu/primogeni
JNIEXPORT jint JNICALL Java_jprime_JMetis_mcPartitionGraph(
		JNIEnv * env,
		jobject obj,
		jboolean j_force_PartGraphRecursive,
		jboolean j_force_PartGraphKway,
		jint j_num_vertices,
		jint j_num_constraints,
		jintArray j_xadj,
		jintArray j_adjncy,
		jintArray j_vwgt,
		jintArray j_adjwgt,
		jint j_wgtflag,
		jint j_nparts,
		jintArray j_options,
		jintArray j_partioned_nodes) {
	mysrand(7654321L);
	//delcare vars
	jint * xadj=NULL, * adjncy=NULL,* vwgt=NULL, * adjwgt=NULL, * options=NULL, * partioned_nodes=NULL;
	int idx, edges_cut=-1, num_vertices=0, num_constraints, nparts=0, wgtflag=0, numflag=0;
	float* ubvec=0;
	jsize xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len;

	//copy the jsize vars
	num_vertices=j_num_vertices;
	num_constraints=j_num_constraints;
	nparts=j_nparts;
	wgtflag=j_wgtflag;

	//get array lengths
	xadj_len            = (*env)->GetArrayLength(env,j_xadj);
	adjncy_len          = (*env)->GetArrayLength(env,j_adjncy);
	vwgt_len            = (*env)->GetArrayLength(env,j_vwgt);
	adjwgt_len          = (*env)->GetArrayLength(env,j_adjwgt);
	options_len         = (*env)->GetArrayLength(env,j_options);
	partioned_nodes_len = (*env)->GetArrayLength(env,j_partioned_nodes);

	//create/get local copies
	xadj                      = (*env)->GetIntArrayElements(env,j_xadj,0);
	adjncy                    = (*env)->GetIntArrayElements(env,j_adjncy,0);
	if(vwgt_len>0)    vwgt    = (*env)->GetIntArrayElements(env,j_vwgt,0);
	if(adjwgt_len>0)  adjwgt  = (*env)->GetIntArrayElements(env,j_adjwgt,0);
	if(options_len>0) options = (*env)->GetIntArrayElements(env,j_options,0);
	partioned_nodes           = (int*)malloc(sizeof(int)*partioned_nodes_len);

	//call func
	if((j_nparts<8 || j_force_PartGraphRecursive) && !j_force_PartGraphKway) {
		//printf("[0]nparts=%i, num_vertices=%i, num_constraints=%i, wgtflag=%i, xadj_len=%i, adjncy_len=%i, vwgt_len=%i, adjwgt_len=%i, options_len=%i, partioned_nodes_len=%i\n",
		//		nparts, num_vertices, num_constraints, wgtflag, xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len);
		METIS_mCPartGraphRecursive(
				&num_vertices,
				&num_constraints,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				options,
				&edges_cut,
				partioned_nodes);
	}
	else {
		//printf("[1]nparts=%i, num_vertices=%i, num_constraints=%i, wgtflag=%i, xadj_len=%i, adjncy_len=%i, vwgt_len=%i, adjwgt_len=%i, options_len=%i, partioned_nodes_len=%i\n",
		//		nparts, num_vertices, num_constraints, wgtflag, xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len);
		ubvec = (float*)malloc(sizeof(float)*num_constraints);
		for(idx=0;idx<num_constraints;idx++) {
			ubvec[idx]=1.1; //manual says should be larger than 1.03 so 1.1 seems reasonable
		}
		METIS_mCPartGraphKway(
				&num_vertices, //int *nvtxs,
				&num_constraints,//int *ncon,
				xadj,//idxtype *xadj,
				adjncy,//idxtype *adjncy,
				vwgt,//idxtype *vwgt,
				adjwgt,//idxtype *adjwgt,
				&wgtflag,//int *wgtflag,
				&numflag,//int *numflag,
				&nparts, //int *nparts,
				ubvec,//float *rubvec,
				options,//int *options,
				&edges_cut,//int *edgecut,
				partioned_nodes); //idxtype *part)
		free(ubvec);
	}

	//pop partioned_nodes
	(*env)->SetIntArrayRegion(env,j_partioned_nodes,0,partioned_nodes_len,partioned_nodes);

	//free local copies
	free(partioned_nodes);
	(*env)->ReleaseIntArrayElements(env, j_xadj, xadj, 0);
	(*env)->ReleaseIntArrayElements(env, j_adjncy, adjncy, 0);
	if(vwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_vwgt, vwgt, 0);
	if(adjwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_adjwgt, adjwgt, 0);
	if(options_len>0) (*env)->ReleaseIntArrayElements(env, j_options, options, 0);
	return edges_cut;
}
int
main (int argc, char **argv, char **envp)
{
    char *s ;
    s = NULL ;
    int i, exit_code, j;

#ifndef _MSC_VER
    /* catch SIGUSR1 and dump intermediate stats */
    signal (SIGUSR1, signal_sim_stats);

    /* catch SIGUSR2 and dump final stats and exit */
    signal (SIGUSR2, signal_exit_now);
#endif /* _MSC_VER */

    /* register an error handler */
    fatal_hook (sim_print_stats);

    /* set up a non-local exit point */
    if ((exit_code = setjmp (sim_exit_buf)) != 0)
    {
	/* special handling as longjmp cannot pass 0 */
	exit_now (exit_code - 1);
    }

    /* register global options */
    sim_odb = opt_new (orphan_fn);
    opt_reg_flag (sim_odb, "-h", "print help message", &help_me, /* default */ FALSE, /* !print */ FALSE, NULL);
    opt_reg_flag (sim_odb, "-v", "verbose operation", &verbose, /* default */ FALSE, /* !print */ FALSE, NULL);
#ifdef DEBUG
    opt_reg_flag (sim_odb, "-d", "enable debug message", &debugging, /* default */ FALSE, /* !print */ FALSE, NULL);
#endif /* DEBUG */
    opt_reg_flag (sim_odb, "-i", "start in Dlite debugger", &dlite_active, /* default */ FALSE, /* !print */ FALSE, NULL);
    opt_reg_int (sim_odb, "-seed", "random number generator seed (0 for timer seed)", &rand_seed, /* default */ 1, /* print */ TRUE, NULL);
    opt_reg_flag (sim_odb, "-q", "initialize and terminate immediately", &init_quit, /* default */ FALSE, /* !print */ FALSE, NULL);

#ifdef SMT_SS
    fprintf (stderr, "Note: -chkpt option is disabled for SMT version \n");
#else
    opt_reg_string (sim_odb, "-chkpt", "restore EIO trace execution from <fname>", &sim_chkpt_fname, /* default */ NULL, /* !print */ FALSE, NULL);
#endif

#ifdef REMOVE_MY_CODE
    opt_reg_string (sim_odb, "-chkpt", "restore EIO trace execution from <fname>", &sim_chkpt_fname, /* default */ NULL, /* !print */ FALSE, NULL);
#endif

    /* stdio redirection options */
    opt_reg_string (sim_odb, "-redir:sim", "redirect simulator output to file (non-interactive only)", &sim_simout,
		    /* default */ NULL, /* !print */ FALSE, NULL);
#ifdef SMT_SS
#ifndef PROG_OUT_FROM_SIM_OUT
    fprintf (stderr, "Note: -redir:prog option is controled in *.bnc configuration " "file of each program in SMT version \n");
#else // !PROG_OUT_FROM_SIM_OUT
    fprintf (stderr, "Note: -redir:prog option is controled by combining the *.bnc configuration " "setting with the -redir:sim option. \n");
#endif // !PROG_OUT_FROM_SIM_OUT
#else
    opt_reg_string (sim_odb, "-redir:prog", "redirect simulated program output to file", &sim_progout, /* default */ NULL, /* !print */ FALSE, NULL);
#endif

#ifdef REMOVE_MY_CODE
    opt_reg_string (sim_odb, "-redir:prog", "redirect simulated program output to file", &sim_progout, /* default */ NULL, /* !print */ FALSE, NULL);
#endif

    /* Dump files to load assembly code and dumping stats etc. */
    opt_reg_string (sim_odb, "-redir:dump", "redirect simulated program output to file", &sim_str_dump, /* default */ NULL, /* !print */ FALSE, NULL);

#ifndef _MSC_VER
    /* scheduling priority option */
    opt_reg_int (sim_odb, "-nice", "simulator scheduling priority", &nice_priority,
		 /* default */ NICE_DEFAULT_VALUE, /* print */ TRUE, NULL);
#endif

    /* register all simulator-specific options */
    sim_reg_options (sim_odb);

    /* parse simulator options */
    exec_index = -1;

#ifdef REMOVE_MY_CODE
    fprintf (stderr, "sim_odb %lu \n", (long) sim_odb);
    fprintf (stderr, "sim: command line: ");
    for (i = 0; i < argc; i++)
	fprintf (stderr, "%s ", argv[i]);
    fprintf (stderr, "\n");
    {
	char name[256];

	gethostname (name, 256);
	fprintf (stderr, "Run on %s\n", name);
    }
#endif
    opt_process_options (sim_odb, argc, argv);
    /* redirect I/O? */
    if (sim_simout != NULL)
    {
	/* send simulator non-interactive output (STDERR) to file SIM_SIMOUT */
	if (fflush (stderr))
	    fatal ("unable to flush stderr ");
	else
	{
	   if (!freopen (sim_simout, "w", stderr))
		fatal ("unable to redirect simulator output to file `%s'", sim_simout);
	}

    }

#ifndef SMT_SS
    if (sim_progout != NULL)
    {
	/* redirect simulated program output to file SIM_PROGOUT */
	sim_progfd = fopen (sim_progout, "w");
	if (!sim_progfd)
	    fatal ("unable to redirect program output to file `%s'", sim_progout);
    }
#endif

    /* need at least two argv values to run */
    if (argc < 2)
    {
	banner (stderr, argc, argv);
	usage (stderr, argc, argv);
	fprintf (stderr, "error:exit from main argc < 2\n");
	exit (1);
    }

    /* opening banner */
    banner (stderr, argc, argv);

    if (help_me)
    {
	/* print help message and exit */
	usage (stderr, argc, argv);
	fprintf (stderr, "error:exit from main help_me\n");
	exit (1);
    }

    /* seed the random number generator */
    if (rand_seed == 0)
    {
	/* seed with the timer value, true random */
	mysrand (time ((time_t *) NULL));
    }
    else
    {
	/* seed with default or user-specified random number generator seed */
	mysrand (rand_seed);
    }

    /* exec_index is set in orphan_fn() */
    if (exec_index == -1)
    {
	/* executable was not found */
	fprintf (stderr, "error: no executable specified\n");
	usage (stderr, argc, argv);
	exit (1);
    }
    /* else, exec_index points to simulated program arguments */

    /* check simulator-specific options */
    sim_check_options (sim_odb, argc, argv);

#ifndef _MSC_VER
    /* set simulator scheduling priority */
    if (nice (0) < nice_priority)
    {
	if (nice (nice_priority - nice (0)) < 0)
	    fatal ("could not renice simulator process");
    }
#endif
    /* emit the command line for later reuse */
    /* copied here for easier debugging */
    fprintf (stderr, "sim: command line: ");
    for (i = 0; i < argc; i++)
	fprintf (stderr, "%s ", argv[i]);
    fprintf (stderr, "\n");
    {
	char name[256];

	gethostname (name, 256);
	fprintf (stderr, "Run on %s\n", name);
    }


    /* default architected value... */
    sim_num_insn = 0;

#ifdef BFD_LOADER
    /* initialize the bfd library */
    bfd_init ();
#endif /* BFD_LOADER */

    /* initialize the instruction decoder */
    md_init_decoder ();

#ifndef SMT_SS
    /* initialize all simulation modules */
    sim_init ();
#endif

    /* initialize architected state */
#ifdef SMT_SS
    sim_load_threads (argc - exec_index, argv + exec_index, envp);
#else
    sim_load_prog (argv[exec_index], argc - exec_index, argv + exec_index, envp);
#endif

#ifdef SMT_SS
    /* initialize all simulation modules */
    sim_init ();
#endif

#ifndef PARALLEL_EMUL
    /* register all simulator stats */
    sim_sdb = stat_new ();
    sim_reg_stats (sim_sdb);
#endif
    
    /* record start of execution time, used in rate stats */
    sim_start_time = time ((time_t *) NULL);

    /* emit the command line for later reuse */
    fprintf (stderr, "sim: command line: ");
    for (i = 0; i < argc; i++)
	fprintf (stderr, "%s ", argv[i]);
    fprintf (stderr, "\n");
    {
	char name[256];

	gethostname (name, 256);
	fprintf (stderr, "Run on %s\n", name);
    }

    /* output simulation conditions */
    s = ctime (&sim_start_time);
    if (s[strlen (s) - 1] == '\n')
	s[strlen (s) - 1] = '\0';
#ifdef __VERSION__
#define COMPILEDWITH "gcc version " __VERSION__
#else
#define COMPILEDWITH "unknown compiler"
#endif
    fprintf (stderr, "\nsim: main.c compiled on " __DATE__ " at " __TIME__ " with " COMPILEDWITH);
    fprintf (stderr, "\nsim: simulation started @ %s, options follow:\n", s);
    opt_print_options (sim_odb, stderr, /* short */ TRUE, /* notes */ TRUE);
    sim_aux_config (stderr);
    fprintf (stderr, "\n");

    /* omit option dump time from rate stats */
    sim_start_time = time ((time_t *) NULL);

    if (init_quit)
	exit_now (0);

    running = TRUE;

    for (j = 0; j < 4; j++)
    {
	for (i = 0; i < NUM_COM_REGS; i++)
	{
	    common_regs_s[j][i].regs_lock = 0;
	    common_regs_s[j][i].address = 0;
	}
    }
    //outFile = fopen ("simOutFile.txt", "w");
//    fprintf(outFile,"fanglei\n");           // fprintf test @ fanglei
//    fflush(outFile);                        // flush @ fanglei
    if(!strcmp(argv[9], "ilink1030.BNC"))
	ilink_run = 1;
    else
	ilink_run = 0;
    if(!strcmp(argv[9], "../../BNCfor16/em3d1030.BNC"))
	em3d_run = 1;
    else
	em3d_run = 0;
    sim_main ();

    /* simulation finished early */
    exit_now (0);
#ifdef __GNUC__
    return 0;
#endif
}
예제 #9
0
void gen_disk(int nptcl, int myseed, float *buffer, int verbose)
{
  dotalk = verbose;
	int i, j, k, nobj=10000;
	int seed= -123;
	int icofm=1;
	float q=0.9, rtrunc=5.0;
	float rhoran, massapp;
	float x, y, z, vx, vy, v, v2, R, vmax, vmax2;
	float phi, cph, sph, cth, sth, vR, vp, vz;
	float E, Lz, rad, rad2;
	float f0, frand, fmax, fmax1, vphimax1, psi, fnorm;
	float Fdisk();
	float ran1();
	float invu();
	float dr, rhomax1;
	float t, mass;
	float u1, v1, u1max, v1max;
	float xcm, ycm, zcm, vxcm, vycm, vzcm;
	float zip = 0.0, psi0;
	float rhomax=0.15, rhomin, rhotst;
	float rhoguess, zcon;
	float stream=0.5;
	float con, outdisk, drtrunc;
	float omega, kappa;
	float dv, v0;
	float broadcon=1.0;
	float vfacR, vfacz;
	float f1;
	float gr, gp, gz, g2;
	float vsigmax, vmean, vsig2;
	float gasdev();
	float diskdensf_(), sigr2_(), sigz2_();
	float FindMax(), FindMax1(), Fmax();
	float simpson(), massring();
	float velocityfactors_();
//	FILE *rhoout;
//	FILE *errfile;
	char harmfile[80];

//	errfile = fopen("errmsg.dat","w"); 
  if(verbose)
    fprintf(stderr,"The Disk\n");
	strcpy(harmfile,"dbh.dat");
  nobj = nptcl;
  seed = myseed;
  mysrand(myseed);
  icofm = 1;
  if (nobj <= 0)
  {
    iquery("Enter the number of particles",&nobj);
    iquery("Enter negative integer seed",&seed);
    iquery("Center the simulation (0=no,1=yes)",&icofm);
    cquery("Enter harmonics file",harmfile);
  }
  

	r = (phase *) calloc(nobj,sizeof(phase));

	readdiskdf_(harmfile,&gparam);
	mdisk = gparam.mdisk; rdisk = gparam.rdisk; zdisk = gparam.zdisk;
	outdisk = gparam.outdisk; drtrunc = gparam.drtrunc;
	rd = 1.2*rdisk;
	zd = 1.2*zdisk;
	rtrunc = (outdisk + 2.0*drtrunc);
	diskmass = 4.0*M_PI*simpson(massring,0.0,rtrunc,128);
	mass   = diskmass/nobj;
	dr = rtrunc/100.;
	rhomax = 0.0;
//	rhoout = fopen("rhotst.dat","w");
	for(i=0; i<100; i++) {
	  R = i*dr;
	  z = 0.0;
	  rhoguess = exp(-R/rd);
	  rhotst = diskdensf_(&R,&z);
	  rhotst /= rhoguess;
	  if( rhotst > rhomax ) rhomax = rhotst;
//	  fprintf(rhoout,"%g %g\n",R, rhotst);
	}
	rhomin = 0.0;
	rhomax *=1.2;
#if 0
	{
		FILE *disksig;
		float rad, vsigR, vsigp;;

		disksig = fopen("disksig.dat","w");
		for(rad=0.1; rad<30.0; rad+=0.1) {
			omekap_(&rad,&omega,&kappa);
			vsigR = sqrt(sigr2_(&rad));
			vsigp = kappa/(2.0*omega)*vsigR;
			fprintf(disksig,"%g %g %g %g %g\n",rad,vsigp,vsigR,omega,kappa);
		}
		fclose(disksig);
	}
#endif

/*
	tstFdisk();
*/
  if (verbose)
    fprintf(stderr,"Calculating disk positions and velocities\n");
	vmean = 0;  vsig2 = 0;
	for(i=0, j=0, k=0; i<nobj;) {

	  u1 = -ran1(&seed);
	  v1 = 2.0*(ran1(&seed) - 0.5);
	  R = rd*invu(u1);
	  z = zd*atanh(v1);
	  
	  zcon = cosh(z/zd);
	  rhoguess = exp(-R/rd)/(zcon*zcon);
	  /* Guess at the approximate functional form of the density */
	  
	  rhotst = diskdensf_(&R,&z);
	  rhotst /= rhoguess;
	  
	  k++;
	  if( rhotst < rhomin )
	    continue;
	  
	  rhoran = (rhomax - rhomin)*ran1(&seed);
	  if( rhoran > rhotst )
	    continue;
	  phi = 2.0*M_PI*ran1(&seed);
	  x = R*cos(phi);
	  y = R*sin(phi);
	  omekap_(&R, &omega, &kappa);
	  vphimax = omega*R;	  
	  vsigR = sqrt(sigr2_(&R));
	  vsigp = kappa/(2.0*omega)*vsigR;
	  vsigz = sqrt(sigz2_(&R));
	  vsigmax = vsigR;
	  if( vsigp > vsigmax ) vsigmax = vsigp;
	  if( vsigz > vsigmax ) vsigmax = vsigz;


	  fmax = 1.1*FindMax(R,z,&vphimax);
/*
	  fmax1 = 1.1*FindMax1(R,z,&vphimax1);
	  fprintf(stderr,"fmax %g fmax1 %g vphimax %g vphimax1 %g\n",
			fmax, fmax1, vphimax, vphimax1);
*/
	  f0 = 0.0; frand = 1.0; /* dummy starters */
	  while( frand > f0 ) {
			  /*
		g2 = 999.;
	    while( g2 > 1.0) {
	      gr = 2.*(ran1(&seed) - 0.5);
	      gp = 2.*(ran1(&seed) - 0.5);
	      gz = 2.*(ran1(&seed) - 0.5);
	      g2 = (gr*gr + gp*gp + gz*gz);
	    }
		*/

		gr = 6.0*(ran1(&seed) - 0.5)*vsigR;
	    gp = 6.0*(ran1(&seed) - 0.5)*vsigp;
		gz = 6.0*(ran1(&seed) - 0.5)*vsigz;
/*
	    gp = (vphimax + 3.0*vsigp)*ran1(&seed) - vphimax;
*/
		/*
		gr = 3.0*vsigmax;
		gp = 3.0*vsigmax;
		gz = 3.0*vsigmax;
		*/
	    
	    vR = gr;
	    vp = vphimax + gp;
	    vz = gz;

	    f0 = Fdisk(vR, vp, vz, R, z);
	    frand = fmax*ran1(&seed);
#if 0
	    if( f0 > fmax ) {
	      float vpmax;
	      fprintf(errfile,"f0 > fmax at R=%g z=%g\nvr=%g vp=%g, vz=%g vphimax=%g f0=%g, fmax=%g\n", 
		      R,z, 
		      vR*broadcon/vsigR, 
		      (vp - vphimax)*broadcon/vsigp, 
		      vz*broadcon/vsigz, vphimax, f0, fmax);
	      fflush(errfile);
	    }
#endif
	    j++;
	  }
	  
	  velocityfactors_(&R, &z, &vfacR, &vfacz);
	  vphimax = vp - gp;
	  vphimax *= vfacR;
	  vp = vphimax + gp;
	  vz *= vfacz;
	  /*
	  fprintf(stdout,"%g %g\n",vp,frand);
	  */

	  cph = x/R; sph = y/R;
	  vx = vR*cph - vp*sph;
	  vy = vR*sph + vp*cph;
	  /*  vz stays the same */

    /* sanity check */
    if (isnan(x)) continue;
    if (isnan(y)) continue;
    if (isnan(z)) continue;
    if (isnan(vx)) continue;
    if (isnan(vy)) continue;
    if (isnan(vz)) continue;
    const float RMAX = 200;
    const float VMAX = 10;
    if (abs(x) > RMAX) continue;
    if (abs(y) > RMAX) continue;
    if (abs(z) > RMAX) continue;
    if (abs(vx) > VMAX) continue;
    if (abs(vy) > VMAX) continue;
    if (abs(vz) > VMAX) continue;

	  r[i].x = (float) x;
	  r[i].y = (float) y;
	  r[i].z = (float) z;
	  r[i].vx = (float)vx;
	  r[i].vy = (float)vy;
	  r[i].vz = (float)vz;
	  i++;
    if (verbose)
      if( i % 1000 == 0 ) {
        fprintf(stderr,".");
        fflush(stderr);
      }
  }
  if (verbose)
  {
    fprintf(stderr,"\n");
    fprintf(stderr,"number of density trials %d\n",k);
    fprintf(stderr,"number of velocity trials %d\n",j);
  }

  if( icofm ) {
    xcm = ycm =zcm = vxcm =vycm =vzcm = 0;
    for(i=0; i<nobj; i++) {
      xcm += r[i].x;
      ycm += r[i].y;
      zcm += r[i].z;
      vxcm += r[i].vx;
      vycm += r[i].vy;
      vzcm += r[i].vz;
    }
    xcm /= nobj; ycm /=nobj; zcm /= nobj;
    vxcm /= nobj; vycm /=nobj; vzcm /= nobj;

    for(i=0; i<nobj; i++) {
      r[i].x -= xcm;
      r[i].y -= ycm;
      r[i].z -= zcm;
      r[i].vx -= vxcm;
      r[i].vy -= vycm;
      r[i].vz -= vzcm;
    }
  }


  if (buffer == NULL)
  {
    t = 0.0;
#ifdef ASCII
    fprintf(stdout,"%d\n",nobj);
    for(i=0; i<nobj; i++) {
      fprintf(stdout,"% 15.7e % 15.7e % 15.7e % 15.7e % 15.7e % 15.7e % 15.7e\n", mass, r[i].x, r[i].y, r[i].z, r[i].vx, r[i].vy, r[i].vz);
    }
#else
    for(i=0; i<nobj; i++)  {
      fwrite(&mass,sizeof(float),1,stdout);
      fwrite(r+i,sizeof(phase),1,stdout);
    }
#endif
  }
  else
  {
    const int min_disk = 000000000;
    const int max_disk = 100000000;
    int NEL = 8;
    int i,pc;
    for (i = 0, pc= 0; i < nobj; i++, pc += NEL)
    {
      *((int*)&buffer[pc]) = min_disk + (i%(max_disk-min_disk));
      buffer[pc+1] = mass;
      buffer[pc+2] = r[i].x;
      buffer[pc+3] = r[i].y;
      buffer[pc+4] = r[i].z;
      buffer[pc+5] = r[i].vx;
      buffer[pc+6] = r[i].vy;
      buffer[pc+7] = r[i].vz;
    }
  }
}
예제 #10
0
int init(simoutorder* in_simobj,
         int argc,
         char** argv,
         char **envp
         )
{
in_simobj->sim_odb = opt_new(orphan_fn);
opt_reg_flag(in_simobj->sim_odb, "-h", "print help message",
	       &help_me, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_flag(in_simobj->sim_odb, "-v", "verbose operation",
	       &verbose, /* default */FALSE, /* !print */FALSE, NULL);
#ifdef DEBUG
  opt_reg_flag(in_simobj->sim_odb, "-d", "enable debug message",
	       &debugging, /* default */FALSE, /* !print */FALSE, NULL);
#endif /* DEBUG */
  opt_reg_flag(in_simobj->sim_odb, "-i", "start in Dlite debugger",
	       &dlite_active, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_int(in_simobj->sim_odb, "-seed",
	      "random number generator seed (0 for timer seed)",
	      &rand_seed, /* default */1, /* print */TRUE, NULL);
  opt_reg_flag(in_simobj->sim_odb, "-q", "initialize and terminate immediately",
	       &init_quit, /* default */FALSE, /* !print */FALSE, NULL);
  opt_reg_string(in_simobj->sim_odb, "-chkpt", "restore EIO trace execution from <fname>",
		 &sim_chkpt_fname, /* default */NULL, /* !print */FALSE, NULL);

  /* stdio redirection options */
  opt_reg_string(in_simobj->sim_odb, "-redir:sim",
		 "redirect simulator output to file (non-interactive only)",
		 &sim_simout,
		 /* default */NULL, /* !print */FALSE, NULL);
  opt_reg_string(in_simobj->sim_odb, "-redir:prog",
		 "redirect simulated program output to file",
		 &sim_progout, /* default */NULL, /* !print */FALSE, NULL);
  #ifndef _MSC_VER
  /* scheduling priority option */
  opt_reg_int(in_simobj->sim_odb, "-nice",
	      "simulator scheduling priority", &nice_priority,
	      /* default */NICE_DEFAULT_VALUE, /* print */TRUE, NULL);
#endif
in_simobj->sim_reg_options(in_simobj->sim_odb);

exec_index = -1;
  opt_process_options(in_simobj->sim_odb, argc, argv);

  /* redirect I/O? */
  if (sim_simout != NULL)
    {
      /* send simulator non-interactive output (STDERR) to file SIM_SIMOUT */
      fflush(stderr);
      if (!freopen(sim_simout, "w", stderr))
	fatal("unable to redirect simulator output to file `%s'", sim_simout);
    }

  if (sim_progout != NULL)
    {
      /* redirect simulated program output to file SIM_PROGOUT */
      sim_progfd = fopen(sim_progout, "w");
      if (!sim_progfd)
	fatal("unable to redirect program output to file `%s'", sim_progout);
    }

  /* need at least two argv values to run */
  if (argc < 2)
    {
      banner(stderr, argc, argv);
      usage(stderr, argc, argv, in_simobj->sim_odb);
      exit(1);
    }
  
  if (help_me)
    {
      /* print help message and exit */
      usage(stderr, argc, argv, in_simobj->sim_odb);
      exit(1);
    }

  /* seed the random number generator */
  if (rand_seed == 0)
    {
      /* seed with the timer value, true random */
      mysrand(time((time_t *)NULL));
    }
  else
    {
      /* seed with default or user-specified random number generator seed */
      mysrand(rand_seed);
    }

  /* exec_index is set in orphan_fn() */
  if (exec_index == -1)
    {
      /* executable was not found */
      fprintf(stderr, "error: no executable specified\n");
      usage(stderr, argc, argv, in_simobj->sim_odb);
      exit(1);
    }
  /* else, exec_index points to simulated program arguments */

  /* check simulator-specific options */
  in_simobj->sim_check_options(in_simobj->sim_odb, argc, argv);

#ifndef _MSC_VER
  /* set simulator scheduling priority */
  if (nice(0) < nice_priority)
    {
      if (nice(nice_priority - nice(0)) < 0)
        fatal("could not renice simulator process");
    }
#endif

  /* default architected value... */
  sim_num_insn = 0;

#ifdef BFD_LOADER
  /* initialize the bfd library */
  bfd_init();
#endif /* BFD_LOADER */

 

  /* initialize all simulation modules */
  in_simobj->sim_init();

  /* initialize architected state */
  in_simobj->sim_load_prog(argv[exec_index], argc-exec_index, argv+exec_index, envp);
 
  /* register all simulator stats */
  struct stat_sdb_t *sdb;

  in_simobj->sim_sdb = (struct stat_sdb_t *)calloc(1, sizeof(struct stat_sdb_t));
  if (!in_simobj->sim_sdb)
    fatal("out of virtual memory");

  in_simobj->sim_sdb->stats = NULL;
  in_simobj->sim_sdb->evaluator = eval_new(stat_eval_ident, in_simobj->sim_sdb);

  in_simobj->sim_reg_stats(in_simobj->sim_sdb);
  
  return 1;
  
}