示例#1
0
qboolean RPI_Init (rendererstate_t *info, unsigned char *palette)
{
	static EGL_DISPMANX_WINDOW_T nativewindow;

	DISPMANX_ELEMENT_HANDLE_T dispman_element;
	DISPMANX_DISPLAY_HANDLE_T dispman_display;
	DISPMANX_UPDATE_HANDLE_T dispman_update;
	VC_RECT_T dst_rect;
	VC_RECT_T src_rect;
	int rw, rh;

	if (!EGL_LoadLibrary(info->subrenderer))
	{
		Con_Printf("couldn't load EGL library\n");
		return false;
	}
	bcm_host_init();

	graphics_get_display_size(0 /* LCD */, &rw, &rh);
	Con_Printf("Screen size is actually %i*%i\n", rw, rh);

	if (info->width < 64 || info->height < 64)
	{
		info->width = rw;
		info->height = rh;
	}
	dispman_display = vc_dispmanx_display_open(0 /* LCD */);
	dispman_update = vc_dispmanx_update_start(0);


	dst_rect.x = 0;
	dst_rect.y = 0;
	dst_rect.width = info->width;
	dst_rect.height = info->height;
	  
	src_rect.x = 0;
	src_rect.y = 0;
	src_rect.width = info->width << 16;
	src_rect.height = info->height << 16; 

	vid.pixelwidth = info->width;
	vid.pixelheight = info->height;
	 
	dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
  
	nativewindow.element = dispman_element;
	nativewindow.width = info->width;
	nativewindow.height = info->height;
	vc_dispmanx_update_submit_sync(dispman_update);


	if (!EGL_Init(info, palette, &nativewindow, EGL_DEFAULT_DISPLAY))
	{
		Con_Printf("couldn't initialise EGL context\n");
		return false;
	}
	GL_Init(&EGL_Proc);
	return true;
}
示例#2
0
/**
 * ANSI main entry point
 */
int main(int argc, char* argv[])
{
	unsigned long lvl_id;
	level::size lvl_sz;
	bool lvl_wrap;
	if (parse_cmd_params(argc, argv, lvl_id, lvl_sz, lvl_wrap))
		return 0;	//Help or version was shown

	//Initialization
	if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) != 0) {
		fprintf(stderr, "Critical error\nSDL_Init failed: %s\n", SDL_GetError());
		return 1;
	}
#ifdef USE_OPENGLES
       	if (EGL_Open()){
		fprintf(stderr, "Critical error\nUnable to open egl\n");
		return 1;
	}
#endif
	//Let's get some video information
	const SDL_VideoInfo* vinfo = SDL_GetVideoInfo();
	if (!vinfo) {
		fprintf(stderr, "Critical error\nUnable to get video information: %s\n", SDL_GetError());
		return 1;
	}

	//Save desktop size
	const int desktop_width = vinfo->current_w;
	const int desktop_height = vinfo->current_h;

	//Calculate minimum window sizes
	const int wnd_min_width =  PW_SCREEN_WIDTH  / 3;
	const int wnd_min_height = PW_SCREEN_HEIGHT / 3;

	//Create window
#if USE_OPENGLES
	if (!SDL_SetVideoMode(800, 480, 0, SDL_FULLSCREEN)) {
		fprintf(stderr, "Critical error\nUnable to set video mode: %s\n", SDL_GetError());
		return 1;
	}
	int prevcursorstate=SDL_ShowCursor(SDL_QUERY);
	SDL_ShowCursor(SDL_DISABLE);
	EGL_Init();
#else
	if (!SDL_SetVideoMode(PW_SCREEN_WIDTH, PW_SCREEN_HEIGHT, 0, SDL_OPENGL | SDL_RESIZABLE)) {
		fprintf(stderr, "Critical error\nUnable to set video mode: %s\n", SDL_GetError());
		return 1;
	}
#endif
	SDL_WM_SetCaption(PACKAGE_NAME, PACKAGE_NAME);
	image wnd_icon;
	if (wnd_icon.load_XPM(pipewalker_xpm, sizeof(pipewalker_xpm) / sizeof(pipewalker_xpm[0])))
		SDL_WM_SetIcon(wnd_icon.get_surface(), NULL);

	game& game_instance = game::instance();
	if (!game_instance.initialize(lvl_id, lvl_sz, lvl_wrap))
		return 1;

	//Timer - about 25 fps
	SDL_SetTimer(40, &timer_callback);

#ifdef WIN32
	SDL_SysWMinfo wmi;
	SDL_VERSION(&wmi.version);
	if (SDL_GetWMInfo(&wmi)) {
		//Set own window procedure
		sdl_wnd_proc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(wmi.window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&pw_win32_wnd_proc)));
		//Set normal icon
		static HICON icon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(0));
		if (icon)
			SetClassLongPtr(wmi.window, GCL_HICON, reinterpret_cast<LONG>(icon));
	}
#endif // WIN32

	bool done = false;
	Uint8 last_mouse_state = 0;

	while (!done) {
		SDL_Event event;
		if (SDL_WaitEvent(&event) == 0) {
			fprintf(stderr, "Critical error\nSDL_WaitEvent failed: %s\n", SDL_GetError());
			return 1;
		}
		switch (event.type) {
			case SDL_MOUSEMOTION:
				{
					Sint32 x, y;
					SDL_GetMouseState(&x, &y);
					game_instance.on_mouse_move(x, y);
				}
				break;
			case SDL_MOUSEBUTTONDOWN:
				//We need to save buttons state - in the SDL_MOUSEBUTTONUP event doesn't have this information
				last_mouse_state = SDL_GetMouseState(NULL, NULL);
				break;
			case SDL_MOUSEBUTTONUP:
				if (last_mouse_state) {
					game_instance.on_mouse_click(last_mouse_state);
					last_mouse_state = 0;
				}
				break;
			case SDL_KEYDOWN:
				if (event.key.keysym.sym == SDLK_F4 && (SDL_GetModState() == KMOD_LALT || SDL_GetModState() == KMOD_RALT))
					done = true;	//Alt+F4 pressed
				else
					done = game_instance.on_key_press(event.key.keysym.sym);
				break;
			case SDL_QUIT:
				done = true;
				break;
			case SDL_VIDEOEXPOSE:
				game_instance.draw_scene();
				break;
			case SDL_VIDEORESIZE:
				if (event.resize.w && event.resize.h) {
					int wnd_width = event.resize.w;
					int wnd_height = event.resize.h;

					//Set correct aspect ratio
					if (wnd_width != desktop_width && wnd_height != desktop_height) {
						if (wnd_height != vinfo->current_h)
							wnd_width = static_cast<int>(static_cast<float>(wnd_height) / PW_ASPECT_RATIO);
						else if (wnd_width != vinfo->current_w)
							wnd_height = static_cast<int>(static_cast<float>(wnd_width) * PW_ASPECT_RATIO);
						if (wnd_width < wnd_min_width || wnd_height < wnd_min_height) {
							//Set minimum window size
							wnd_width = wnd_min_width;
							wnd_height = wnd_min_height;
						}
					}

					SDL_SetVideoMode(wnd_width, wnd_height, 0, SDL_OPENGL | SDL_RESIZABLE);
					game_instance.on_window_resize(wnd_width, wnd_height);
					SDL_Event expose_event;
					expose_event.type = SDL_VIDEOEXPOSE;
					SDL_PushEvent(&expose_event);
				}
				break;
		}
	}

	game_instance.finalize();
#if USE_OPENGLES
	EGL_Close();
	SDL_ShowCursor(prevcursorstate);
#endif

	SDL_Quit();
	return 0;
}
示例#3
0
文件: PCMain.cpp 项目: PeterTh/native
int main(int argc, char *argv[]) {
	std::string app_name;
	std::string app_name_nice;

	float zoom = 1.0f;
	bool tablet = false;
	bool aspect43 = false;
	const char *zoomenv = getenv("ZOOM");
	const char *tabletenv = getenv("TABLET");
	const char *ipad = getenv("IPAD");

	if (zoomenv) {
		zoom = atof(zoomenv);
	}
	if (tabletenv) {
		tablet = atoi(tabletenv) ? true : false;
	}
	if (ipad) aspect43 = true;
	
	bool landscape;
	NativeGetAppInfo(&app_name, &app_name_nice, &landscape);
	
	// Change these to temporarily test other resolutions.
	aspect43 = false;
	tablet = false;
	float density = 1.0f;
	//zoom = 1.5f;

	if (landscape) {
		if (tablet) {
			pixel_xres = 1280 * zoom;
			pixel_yres = 800 * zoom;
		} else if (aspect43) {
			pixel_xres = 1024 * zoom;
			pixel_yres = 768 * zoom;
		} else {
			pixel_xres = 800 * zoom;
			pixel_yres = 480 * zoom;
		}
	} else {
		// PC development hack for more space
		//pixel_xres = 1580 * zoom;
		//pixel_yres = 1000 * zoom;
		if (tablet) {
			pixel_xres = 800 * zoom;
			pixel_yres = 1280 * zoom;
		} else if (aspect43) {
			pixel_xres = 768 * zoom;
			pixel_yres = 1024 * zoom;
		} else {
			pixel_xres = 480 * zoom;
			pixel_yres = 800 * zoom;
		}
	}

	net::Init();
#ifdef __APPLE__
	// Make sure to request a somewhat modern GL context at least - the
	// latest supported by MacOSX (really, really sad...)
	// Requires SDL 2.0 (which is even more sad, as that hasn't been released yet)
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
#endif

	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
		return 1;
	}
#ifdef EGL
	if (EGL_Open())
		return 1;
#endif

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

	if (SDL_SetVideoMode(pixel_xres, pixel_yres, 0, 
#ifdef USING_GLES2
		SDL_SWSURFACE | SDL_FULLSCREEN
#else
		SDL_OPENGL
#endif
		) == NULL) {
		fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
		SDL_Quit();
		return(2);
	}
#ifdef EGL
	EGL_Init();
#endif

	SDL_WM_SetCaption(app_name_nice.c_str(), NULL);
#ifdef MAEMO
	SDL_ShowCursor(SDL_DISABLE);
#endif


#ifndef USING_GLES2
	if (GLEW_OK != glewInit()) {
		printf("Failed to initialize glew!\n");
		return 1;
	}

	if (GLEW_VERSION_2_0) {
		printf("OpenGL 2.0 or higher.\n");
	} else {
		printf("Sorry, this program requires OpenGL 2.0.\n");
		return 1;
	}
#endif

#ifdef _MSC_VER
	// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
	TCHAR path[MAX_PATH];
	SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
	PathAppend(path, (app_name + "\\").c_str());
#else
	// Mac / Linux
	char path[512];
	const char *the_path = getenv("HOME");
	if (!the_path) {
		struct passwd* pwd = getpwuid(getuid());
		if (pwd)
			the_path = pwd->pw_dir;
	}
	strcpy(path, the_path);
	if (path[strlen(path)-1] != '/')
		strcat(path, "/");
#endif

#ifdef _WIN32
	NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE");
#else
	NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
#endif

	dp_xres = (float)pixel_xres * density / zoom;
	dp_yres = (float)pixel_yres * density / zoom;
	pixel_in_dps = (float)pixel_xres / dp_xres;

	NativeInitGraphics();
	glstate.viewport.set(0, 0, pixel_xres, pixel_yres);

	float dp_xscale = (float)dp_xres / pixel_xres;
	float dp_yscale = (float)dp_yres / pixel_yres;


	printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
	printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);

	SDL_AudioSpec fmt;
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 1024;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, NULL) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
		return 1;
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#ifdef PANDORA
	// Joysticks init, we the nubs if setup as Joystick
	int numjoys = SDL_NumJoysticks();
	if (numjoys>0)
		for (int i=0; i<numjoys; i++)
		{
			if (strncmp(SDL_JoystickName(i), "nub0", 4) == 0)
				ljoy=SDL_JoystickOpen(i);
			if (strncmp(SDL_JoystickName(i), "nub1", 4) == 0)
				rjoy=SDL_JoystickOpen(i);
		}
#endif

	int framecount = 0;
	bool nextFrameMD = 0;
	float t = 0, lastT = 0;
	while (true) {
		input_state.accelerometer_valid = false;
		input_state.mouse_valid = true;
		int quitRequested = 0;

		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			float mx = event.motion.x * dp_xscale;
			float my = event.motion.y * dp_yscale;

			if (event.type == SDL_QUIT) {
				quitRequested = 1;
			} else if (event.type == SDL_KEYDOWN) {
				if (event.key.keysym.sym == SDLK_ESCAPE) {
					quitRequested = 1;
				}
			} else if (event.type == SDL_MOUSEMOTION) {
				input_state.pointer_x[0] = mx;
				input_state.pointer_y[0] = my;
				NativeTouch(0, mx, my, 0, TOUCH_MOVE);
			} else if (event.type == SDL_MOUSEBUTTONDOWN) {
				if (event.button.button == SDL_BUTTON_LEFT) {
					//input_state.mouse_buttons_down = 1;
					input_state.pointer_down[0] = true;
					nextFrameMD = true;
					NativeTouch(0, mx, my, 0, TOUCH_DOWN);
				}
			} else if (event.type == SDL_MOUSEBUTTONUP) {
				if (event.button.button == SDL_BUTTON_LEFT) {
					input_state.pointer_down[0] = false;
					nextFrameMD = false;
					//input_state.mouse_buttons_up = 1;
					NativeTouch(0, mx, my, 0, TOUCH_UP);
				}
			}
		}

		if (quitRequested)
			break;

		const uint8 *keys = (const uint8 *)SDL_GetKeyState(NULL);
		if (keys[SDLK_ESCAPE])
			break;
		SimulateGamepad(keys, &input_state);
		UpdateInputState(&input_state);
		NativeUpdate(input_state);
		NativeRender();

		EndInputState(&input_state);

		if (framecount % 60 == 0) {
			// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
		}

#ifdef EGL
		eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
		if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
		{
			SDL_GL_SwapBuffers();
			lastT = t;
		}
#endif

		// Simple frame rate limiting
//		while (time_now() < t + 1.0f/60.0f) {
//			sleep_ms(0);
//			time_update();
//		}
		time_update();
		t = time_now();
		framecount++;
	}
	// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
	// The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifdef _WIN32
	exit(0);
#endif
	NativeShutdownGraphics();
	SDL_PauseAudio(1);
	SDL_CloseAudio();
	NativeShutdown();
#ifdef EGL
	EGL_Close();
#endif
	SDL_Quit();
	net::Shutdown();
	exit(0);
	return 0;
}
示例#4
0
extern "C" int main(int argcount, char* argvec[])
#endif
{
#if defined(__native_client__)
	std::cerr << "Running game_main" << std::endl;

	chdir("/frogatto");
	{
		char buf[256];
		const char* const res = getcwd(buf,sizeof(buf));
		std::cerr << "Current working directory: " << res << std::endl;
	}
#endif 

#if defined(__APPLE__) && TARGET_OS_MAC
    chdir([[[NSBundle mainBundle] resourcePath] fileSystemRepresentation]);
#endif

	#ifdef NO_STDERR
	std::freopen("/dev/null", "w", stderr);
	std::cerr.sync_with_stdio(true);
	#endif

	std::cerr << "Frogatto engine version " << preferences::version() << "\n";
	LOG( "After print engine version" );

	#if defined(TARGET_BLACKBERRY)
		chdir("app/native");
		std::cout<< "Changed working directory to: " << getcwd(0, 0) << std::endl;
	#endif

	game_logic::init_callable_definitions();

	std::string level_cfg = "titlescreen.cfg";
	bool unit_tests_only = false, skip_tests = false;
	bool run_benchmarks = false;
	std::vector<std::string> benchmarks_list;
	std::string utility_program;
	std::vector<std::string> util_args;
	std::string server = "wesnoth.org";
#if defined(UTILITY_IN_PROC)
	bool create_utility_in_new_process = false;
	std::string utility_name;
#endif
	bool is_child_utility = false;

	const char* profile_output = NULL;
	std::string profile_output_buf;

#if defined(__ANDROID__)
	//monstartup("libapplication.so");
#endif

	std::string orig_level_cfg = level_cfg;
	std::string override_level_cfg = "";

	int modules_loaded = 0;

	std::vector<std::string> argv;
	for(int n = 1; n < argcount; ++n) {
#if defined(UTILITY_IN_PROC)
		std::string sarg(argvec[n]);
		if(sarg.compare(0, 15, "--utility-proc=") == 0) {
			create_utility_in_new_process = true;
			utility_name = "--utility-child=" + sarg.substr(15);
		} else {
			argv.push_back(argvec[n]);
		}
#else
		argv.push_back(argvec[n]);
#endif
        
        if(argv.size() >= 2 && argv[argv.size()-2] == "-NSDocumentRevisionsDebugMode" && argv.back() == "YES") {
            //XCode passes these arguments by default when debugging -- make sure they are ignored.
            argv.resize(argv.size()-2);
        }
	}

#if defined(UTILITY_IN_PROC)
	if(create_utility_in_new_process) {
		argv.push_back(utility_name);
#if defined(_MSC_VER)
		// app name is ignored for windows, we get windows to tell us.
		is_child_utility = create_utility_process("", argv);
#else 
		is_child_utility = create_utility_process(argvec[0], argv);
#endif
		if(!is_child_utility) {
			argv.pop_back();
		}
#if defined(_MSC_VER)
		atexit(terminate_utility_process);
#endif
	}
#endif

	if(sys::file_exists("./master-config.cfg")) {
		std::cerr << "LOADING CONFIGURATION FROM master-config.cfg" << std::endl;
		variant cfg = json::parse_from_file("./master-config.cfg");
		if(cfg.is_map()) {
			if( cfg["id"].is_null() == false) {
				std::cerr << "SETTING MODULE PATH FROM master-config.cfg: " << cfg["id"].as_string() << std::endl;
				preferences::set_preferences_path_from_module(cfg["id"].as_string());
				//XXX module::set_module_name(cfg["id"].as_string(), cfg["id"].as_string());
			}
			if(cfg["arguments"].is_null() == false) {
				std::vector<std::string> additional_args = cfg["arguments"].as_list_string();
				argv.insert(argv.begin(), additional_args.begin(), additional_args.end());
				std::cerr << "ADDING ARGUMENTS FROM master-config.cfg:";
				for(size_t n = 0; n < cfg["arguments"].num_elements(); ++n) {
					std::cerr << " " << cfg["arguments"][n].as_string();
				}
				std::cerr << std::endl;
			}
		}
	}

	stats::record_program_args(argv);

	for(size_t n = 0; n < argv.size(); ++n) {
		const int argc = argv.size();
		const std::string arg(argv[n]);
		std::string arg_name, arg_value;
		std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '=');
		if(equal != arg.end()) {
			arg_name = std::string(arg.begin(), equal);
			arg_value = std::string(equal+1, arg.end());
		}
		if(arg_name == "--module") {
			if(load_module(arg_value, &argv) != 0) {
				std::cerr << "FAILED TO LOAD MODULE: " << arg_value << "\n";
				return -1;
			}
			++modules_loaded;
		}
	}

	if(modules_loaded == 0) {
		if(load_module(DEFAULT_MODULE, &argv) != 0) {
			std::cerr << "FAILED TO LOAD MODULE: " << DEFAULT_MODULE << "\n";
			return -1;
		}
	}

	preferences::load_preferences();
	LOG( "After load_preferences()" );

	// load difficulty settings after module, before rest of args.
	difficulty::manager();

	for(size_t n = 0; n < argv.size(); ++n) {
		const size_t argc = argv.size();
		const std::string arg(argv[n]);
		std::string arg_name, arg_value;
		std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '=');
		if(equal != arg.end()) {
			arg_name = std::string(arg.begin(), equal);
			arg_value = std::string(equal+1, arg.end());
		}
		std::cerr << "ARGS: " << arg << std::endl;
		if(arg_name == "--module") {
			// ignore already processed.
		} else if(arg_name == "--profile" || arg == "--profile") {
			profile_output_buf = arg_value;
			profile_output = profile_output_buf.c_str();
		} else if(arg_name == "--utility" || arg_name == "--utility-child") {
			if(arg_name == "--utility-child") {
				is_child_utility = true;
			}
			utility_program = arg_value;
			for(++n; n < argc; ++n) {
				const std::string arg(argv[n]);
				util_args.push_back(arg);
			}

			break;
		} else if(arg == "--benchmarks") {
			run_benchmarks = true;
		} else if(arg_name == "--benchmarks") {
			run_benchmarks = true;
			benchmarks_list = util::split(arg_value);
		} else if(arg == "--tests") {
			unit_tests_only = true;
		} else if(arg == "--no-tests") {
			skip_tests = true;
		} else if(arg_name == "--width") {
			std::string w(arg_value);
			preferences::set_actual_screen_width(boost::lexical_cast<int>(w));
		} else if(arg == "--width" && n+1 < argc) {
			std::string w(argv[++n]);
			preferences::set_actual_screen_width(boost::lexical_cast<int>(w));
		} else if(arg_name == "--height") {
			std::string h(arg_value);
			preferences::set_actual_screen_height(boost::lexical_cast<int>(h));
		} else if(arg == "--height" && n+1 < argc) {
			std::string h(argv[++n]);
			preferences::set_actual_screen_height(boost::lexical_cast<int>(h));
		} else if(arg_name == "--level") {
			override_level_cfg = arg_value;
		} else if(arg == "--level" && n+1 < argc) {
			override_level_cfg = argv[++n];
		} else if(arg_name == "--host") {
			server = arg_value;
		} else if(arg == "--host" && n+1 < argc) {
			server = argv[++n];
		} else if(arg == "--compiled") {
			preferences::set_load_compiled(true);
#ifndef NO_EDITOR
		} else if(arg == "--edit") {
			preferences::set_edit_on_start(true);
#endif
		} else if(arg == "--no-compiled") {
			preferences::set_load_compiled(false);
#if defined(TARGET_PANDORA)
		} else if(arg == "--no-fbo") {
			preferences::set_fbo(false);
		} else if(arg == "--no-bequ") {
			preferences::set_bequ(false);
#endif
		} else if(arg == "--help" || arg == "-h") {
			print_help(std::string(argvec[0]));
			return 0;
		} else {
			const bool res = preferences::parse_arg(argv[n].c_str());
			if(!res) {
				std::cerr << "unrecognized arg: '" << arg << "'\n";
				return -1;
			}
		}
	}

	checksum::manager checksum_manager;
#ifndef NO_EDITOR
	sys::filesystem_manager fs_manager;
#endif // NO_EDITOR

	preferences::expand_data_paths();

	background_task_pool::manager bg_task_pool_manager;
	LOG( "After expand_data_paths()" );

	std::cerr << "Preferences dir: " << preferences::user_data_path() << '\n';

	//make sure that the user data path exists.
	if(!preferences::setup_preferences_dir()) {
		std::cerr << "cannot create preferences dir!\n";
	}

	std::cerr << "\n";

	if(preferences::internal_tbs_server()) {
		tbs::internal_server::init();
	}

	if(utility_program.empty() == false 
		&& test::utility_needs_video(utility_program) == false) {
#if defined(UTILITY_IN_PROC)
		if(is_child_utility) {
			ASSERT_LOG(ipc::semaphore::create(shared_sem_name, 1) != false, 
				"Unable to create shared semaphore: " << errno);
			std::cerr.sync_with_stdio(true);
		}
#endif
		test::run_utility(utility_program, util_args);
		return 0;
	}

#if defined(TARGET_PANDORA)
    EGL_Open();
#endif

#if defined(__ANDROID__)
	std::freopen("stdout.txt","w",stdout);
	std::freopen("stderr.txt","w",stderr);
	std::cerr.sync_with_stdio(true);
#endif

	LOG( "Start of main" );
	
#if !defined(__native_client__)
	Uint32 sdl_init_flags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK;
#if defined(_WINDOWS) || defined(TARGET_OS_IPHONE)
	sdl_init_flags |= SDL_INIT_TIMER;
#endif
	if(SDL_Init(sdl_init_flags) < 0) {
		std::cerr << "could not init SDL\n";
		return -1;
	}
	LOG( "After SDL_Init" );
#endif

#ifdef TARGET_OS_HARMATTAN
	g_type_init();
#endif
	i18n::init ();
	LOG( "After i18n::init()" );

	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

#if defined(TARGET_OS_IPHONE) || defined(TARGET_BLACKBERRY) || defined(__ANDROID__)
	//on the iPhone and PlayBook, try to restore the auto-save if it exists
	if(sys::file_exists(preferences::auto_save_file_path()) && sys::read_file(std::string(preferences::auto_save_file_path()) + ".stat") == "1") {
		level_cfg = "autosave.cfg";
		sys::write_file(std::string(preferences::auto_save_file_path()) + ".stat", "0");

	}
#endif

	if(override_level_cfg.empty() != true) {
		level_cfg = override_level_cfg;
		orig_level_cfg = level_cfg;
	}

#if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(USE_GLES2)
	wm.create_window(preferences::actual_screen_width(),
		preferences::actual_screen_height(),
		0,
		(preferences::resizable() ? SDL_RESIZABLE : 0) | (preferences::fullscreen() ? SDL_FULLSCREEN : 0));
#else

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
	int width, height;
	iphone_screen_res(&width, &height);
	preferences::set_actual_screen_width(width);
	preferences::set_actual_screen_height(height);
	int multiplier = 2;
	if (width > 320)
	{
		//preferences::set_use_pretty_scaling(true);
		multiplier = 1;
	}
	preferences::set_virtual_screen_width(height*multiplier);
	preferences::set_virtual_screen_height(width*multiplier);
	preferences::set_control_scheme(height % 1024 ? "iphone_2d" : "ipad_2d");
	
	SDL_WindowID windowID = SDL_CreateWindow (NULL, 0, 0, preferences::actual_screen_width(), preferences::actual_screen_height(),
		SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
		SDL_WINDOW_BORDERLESS);
	if (windowID == 0) { 
		std::cerr << "Could not create window: " << SDL_GetError() << "\n"; 
		return -1;
	}
	
	//	if (SDL_GL_CreateContext(windowID) == 0) {
	//		std::cerr << "Could not create GL context: " << SDL_GetError() << "\n";
	//		return -1;
	//	}
	if (SDL_CreateRenderer(windowID, -1, 0) != 0) {
		std::cerr << "Could not create renderer\n";
		return -1;
	}
	
#else
#ifdef TARGET_OS_HARMATTAN
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGLES | SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}

	preferences::init_oes();
	SDL_ShowCursor(0);
#else

#if defined(TARGET_PANDORA)
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),16,SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
    EGL_Init();
    preferences::init_oes();
#elif defined(TARGET_TEGRA)
	//if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,preferences::resizable() ? SDL_RESIZABLE : 0|preferences::fullscreen() ? SDL_FULLSCREEN : 0) == NULL) {
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
    EGL_Init();
    preferences::init_oes();
#elif defined(TARGET_BLACKBERRY)
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
	preferences::init_oes();
#elif defined(__ANDROID__)
#if SDL_VERSION_ATLEAST(2, 0, 0)
	int num_video_displays = SDL_GetNumVideoDisplays();
	SDL_Rect r;
	if(num_video_displays < 0) {
		std::cerr << "no video displays available" << std::endl;
		return -1;
	}
	if(SDL_GetDisplayBounds(0, &r) < 0) {
        preferences::set_actual_screen_width(r.w);
        preferences::set_actual_screen_height(r.h);
		if(r.w < 640) {
        	preferences::set_virtual_screen_width(r.w*2);
        	preferences::set_virtual_screen_height(r.h*2);
		} else {
			preferences::set_virtual_screen_width(r.w);
			preferences::set_virtual_screen_height(r.h);
		}
		preferences::set_control_scheme(r.h >= 1024 ? "ipad_2d" : "android_med");
    }
#else
    SDL_Rect** r = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL);
    if( r != (SDL_Rect**)0 && r != (SDL_Rect**)-1 ) {
        preferences::set_actual_screen_width(r[0]->w);
        preferences::set_actual_screen_height(r[0]->h);
		if(r[0]->w < 640) {
        	preferences::set_virtual_screen_width(r[0]->w*2);
        	preferences::set_virtual_screen_height(r[0]->h*2);
		} else {
			preferences::set_virtual_screen_width(r[0]->w);
			preferences::set_virtual_screen_height(r[0]->h);
		}
		preferences::set_control_scheme(r[0]->h >= 1024 ? "ipad_2d" : "android_med");
    }
#endif

#if SDL_VERSION_ATLEAST(2, 0, 0)
	if(!graphics::set_video_mode(preferences::actual_screen_width(), preferences::actual_screen_height())) {
#else
    if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_FULLSCREEN|SDL_OPENGL) == NULL) {
#endif
		std::cerr << "could not set video mode\n";
		return -1;
    }
#elif defined(__native_client__)
    SDL_Rect** r = SDL_ListModes(NULL, SDL_OPENGL);
	std::cerr << "Video modes";
	if(r == (SDL_Rect**)0) {
		std::cerr << "No modes available";
		return -1;
	}
	if(r == (SDL_Rect**)-1) {
		std::cerr << "All modes available";
	} else {
		for(int i = 0; r[i]; ++i) {
			std::cerr << r[i]->w << r[i]->h << std::endl;
		}
	}

    if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,0) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
    }
#else
#if SDL_VERSION_ATLEAST(2, 0, 0)
	if(preferences::auto_size_window()) {
		const SDL_DisplayMode mode = graphics::set_video_mode_auto_select();
		preferences::set_actual_screen_width(mode.w);
		preferences::set_actual_screen_height(mode.h);
		preferences::set_virtual_screen_width(mode.w);
		preferences::set_virtual_screen_height(mode.h);
	} else if(!graphics::set_video_mode(preferences::actual_screen_width(), preferences::actual_screen_height())) {
#else
	if(SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|(preferences::resizable() ? SDL_RESIZABLE : 0)|(preferences::fullscreen() ? SDL_FULLSCREEN : 0)) == NULL) {
#endif
		std::cerr << "could not set video mode\n";
		return -1;
	}
#ifndef __APPLE__
	graphics::surface wm_icon = graphics::surface_cache::get("window-icon.png");
	if(!wm_icon.null()) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
		SDL_SetWindowIcon(graphics::get_window(), wm_icon.get());
#else
		SDL_WM_SetIcon(wm_icon, NULL);
#endif
	}
#endif // __APPLE__
#endif
#endif
#endif

#endif

#if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(__GLEW_H__)
	GLenum glew_status = glewInit();
	ASSERT_EQ(glew_status, GLEW_OK);
#endif

#if defined(USE_GLES2)
	if(glCreateShader == NULL) {
		const GLubyte* glstrings;
		if(glGetString != NULL && (glstrings = glGetString(GL_VERSION)) != NULL) {
			std::cerr << "OpenGL version: " << reinterpret_cast<const char *>(glstrings) << std::endl;
		}
		std::cerr << "glCreateShader is NULL. Check that your current video card drivers support "
			<< "an OpenGL version >= 2. Exiting." << std::endl;
		return 0;
	}
	// Has to happen after the call to glewInit().
	gles2::init_default_shader();
#endif

//	srand(time(NULL));

	const stats::manager stats_manager;
#ifndef NO_EDITOR
	const external_text_editor::manager editor_manager;
#endif // NO_EDITOR

#if defined(USE_BOX2D)
	box2d::manager b2d_manager;
#endif

	std::cerr << std::endl;
	const GLubyte* glstrings;
	if((glstrings = glGetString(GL_VENDOR)) != NULL) {
		std::cerr << "OpenGL vendor: " << reinterpret_cast<const char *>(glstrings) << std::endl;
	} else {
		GLenum err = glGetError();
		std::cerr << "Error in vendor string: " << std::hex << err << std::endl;
	}
	if((glstrings = glGetString(GL_VERSION)) != NULL) {
		std::cerr << "OpenGL version: " << reinterpret_cast<const char *>(glstrings) << std::endl;
	} else {
		GLenum err = glGetError();
		std::cerr << "Error in version string: " << std::hex << err << std::endl;
	}
	if((glstrings = glGetString(GL_EXTENSIONS)) != NULL) {
		std::cerr << "OpenGL extensions: " << reinterpret_cast<const char *>(glstrings) << std::endl;
	} else {
		GLenum err = glGetError();
		std::cerr << "Error in extensions string: " << std::hex << err << std::endl;
	}
#ifdef GL_SHADING_LANGUAGE_VERSION
	if((glstrings = glGetString(GL_SHADING_LANGUAGE_VERSION)) != NULL) {
		std::cerr << "GLSL Version: " << reinterpret_cast<const char *>(glstrings) << std::endl;
	} else {
		GLenum err = glGetError();
		std::cerr << "Error in GLSL string: " << std::hex << err << std::endl;
	}
#endif
	std::cerr << std::endl;

	GLint stencil_bits = 0;
	glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
	std::cerr << "Stencil bits: " << stencil_bits << std::endl;

#if defined(USE_GLES2)
	GLfloat min_pt_sz;
	glGetFloatv(GL_POINT_SIZE_MIN, &min_pt_sz);
	GLfloat max_pt_sz;
	glGetFloatv(GL_POINT_SIZE_MAX, &max_pt_sz);
	std::cerr << "Point size range: " << min_pt_sz << " < size < " << max_pt_sz << std::endl;
#if !defined(GL_ES_VERSION_2_0)
	glEnable(GL_POINT_SPRITE);
	glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
#endif

	glShadeModel(GL_SMOOTH);
	glEnable(GL_BLEND);
#if !defined(USE_GLES2)
	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#endif

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	std::cerr << "JOYSTICKS: " << SDL_NumJoysticks() << "\n";

	const load_level_manager load_manager;

	{ //manager scope
	const font::manager font_manager;
	const sound::manager sound_manager;
#if !defined(__native_client__)
	const joystick::manager joystick_manager;
#endif 
	
	graphics::texture::manager texture_manager;

#ifndef NO_EDITOR
	editor::manager editor_manager;
#endif

	variant preloads;
	loading_screen loader;
	try {
		sound::init_music(json::parse_from_file("data/music.cfg"));
		graphical_font::init_for_locale(i18n::get_locale());
		preloads = json::parse_from_file("data/preload.cfg");
		int preload_items = preloads["preload"].num_elements();
		loader.set_number_of_items(preload_items+7); // 7 is the number of items that will be loaded below
		custom_object::init();
		loader.draw_and_increment(_("Initializing custom object functions"));
		init_custom_object_functions(json::parse_from_file("data/functions.cfg"));
		loader.draw_and_increment(_("Initializing textures"));
		loader.load(preloads);
		loader.draw_and_increment(_("Initializing tiles"));
		tile_map::init(json::parse_from_file("data/tiles.cfg"));
		loader.draw_and_increment(_("Initializing GUI"));

		variant gui_node = json::parse_from_file(preferences::load_compiled() ? "data/compiled/gui.cfg" : "data/gui.cfg");
		gui_section::init(gui_node);
		loader.draw_and_increment(_("Initializing GUI"));
		framed_gui_element::init(gui_node);

		preferences::set_edit_and_continue(true);

		game_logic::formula_object::load_all_classes();

	} catch(const json::parse_error& e) {
		std::cerr << "ERROR PARSING: " << e.error_message() << "\n";
		return 0;
	}
	loader.draw(_("Loading level"));

#if defined(__native_client__)
	while(1) {
	}
#endif

	if(!skip_tests && !test::run_tests()) {
		return -1;
	}

	if(unit_tests_only) {
		return 0;
	}
#if defined(__APPLE__) && !(TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE) && !defined(USE_GLES2)
	GLint swapInterval = 1;
	CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
#endif

	loader.finish_loading();
	//look to see if we got any quit events while loading.
	{
	SDL_Event event;
	while(SDL_PollEvent(&event)) {
		if(event.type == SDL_QUIT) {
			return 0;
		}
	}
	}

	formula_profiler::manager profiler(profile_output);

#ifdef USE_GLES2
	texture_frame_buffer::init(preferences::actual_screen_width(), preferences::actual_screen_height());
#else
	texture_frame_buffer::init();
#endif

	if(run_benchmarks) {
		if(benchmarks_list.empty() == false) {
			test::run_benchmarks(&benchmarks_list);
		} else {
			test::run_benchmarks();
		}
		return 0;
	} else if(utility_program.empty() == false && test::utility_needs_video(utility_program) == true) {
		test::run_utility(utility_program, util_args);
		return 0;
	}

	bool quit = false;

	while(!quit && !show_title_screen(level_cfg)) {
		boost::intrusive_ptr<level> lvl(load_level(level_cfg));
		

#if !defined(__native_client__)
		//see if we're loading a multiplayer level, in which case we
		//connect to the server.
		multiplayer::manager mp_manager(lvl->is_multiplayer());
		if(lvl->is_multiplayer()) {
			multiplayer::setup_networked_game(server);
		}

		if(lvl->is_multiplayer()) {
			last_draw_position() = screen_position();
			std::string level_cfg = "waiting-room.cfg";
			boost::intrusive_ptr<level> wait_lvl(load_level(level_cfg));
			wait_lvl->finish_loading();
			wait_lvl->set_multiplayer_slot(0);
			if(wait_lvl->player()) {
				wait_lvl->player()->set_current_level(level_cfg);
			}
			wait_lvl->set_as_current_level();

			level_runner runner(wait_lvl, level_cfg, orig_level_cfg);

			multiplayer::sync_start_time(*lvl, boost::bind(&level_runner::play_cycle, &runner));

			lvl->set_multiplayer_slot(multiplayer::slot());
		}
#endif

		last_draw_position() = screen_position();

		assert(lvl.get());
		if(!lvl->music().empty()) {
			sound::play_music(lvl->music());
		}

		if(lvl->player() && level_cfg != "autosave.cfg") {
			lvl->player()->set_current_level(level_cfg);
			lvl->player()->get_entity().save_game();
		}

		set_scene_title(lvl->title());

		try {
			quit = level_runner(lvl, level_cfg, orig_level_cfg).play_level();
			level_cfg = orig_level_cfg;
		} catch(multiplayer_exception&) {
		}
	}

	level::clear_current_level();

	} //end manager scope, make managers destruct before calling SDL_Quit
//	controls::debug_dump_controls();
#if defined(TARGET_PANDORA) || defined(TARGET_TEGRA)
    EGL_Destroy();
#endif

#if SDL_VERSION_ATLEAST(2, 0, 0)
	// Be nice and destroy the GL context and the window.
	graphics::set_video_mode(0, 0, CLEANUP_WINDOW_CONTEXT);
#elif defined(USE_GLES2)
	wm.destroy_window();
#endif
	SDL_Quit();
	
	preferences::save_preferences();
	std::cerr << SDL_GetError() << "\n";
#if !defined(TARGET_OS_HARMATTAN) && !defined(TARGET_TEGRA) && !defined(TARGET_BLACKBERRY) && !defined(__ANDROID__) && !defined(USE_GLES2)
	std::cerr << gluErrorString(glGetError()) << "\n";
#endif

#if !defined(_MSC_VER) && defined(UTILITY_IN_PROC)
	if(create_utility_in_new_process) {
		terminate_utility_process();
	}
#endif

#ifdef _MSC_VER
	ExitProcess(0);
#endif

	return 0;
}
示例#5
0
int main(int argc, char *argv[]) {
	std::string app_name;
	std::string app_name_nice;
	bool landscape;
	NativeGetAppInfo(&app_name, &app_name_nice, &landscape);

	net::Init();
#ifdef __APPLE__
	// Make sure to request a somewhat modern GL context at least - the
	// latest supported by MacOSX (really, really sad...)
	// Requires SDL 2.0
	// We really should upgrade to SDL 2.0 soon.
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
#endif

	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) {
		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
		return 1;
	}
#ifdef EGL
	if (EGL_Open())
		return 1;
#endif

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

	int mode;
#ifdef USING_GLES2
	mode = SDL_SWSURFACE | SDL_FULLSCREEN;
#else
	mode = SDL_OPENGL;
	for (int i = 1; i < argc; i++)
		if (!strcmp(argv[i],"--fullscreen"))
			mode |= SDL_FULLSCREEN;
#endif
	if (mode & SDL_FULLSCREEN) {
		const SDL_VideoInfo* info = SDL_GetVideoInfo();
		pixel_xres = info->current_w;
		pixel_yres = info->current_h;
		g_Config.bFullScreen = true;
	} else {
		// set a sensible default resolution (2x)
		pixel_xres = 480 * 2;
		pixel_yres = 272 * 2;
		g_Config.bFullScreen = false;
	}
	dp_xres = (float)pixel_xres;
	dp_yres = (float)pixel_yres;

	if (SDL_SetVideoMode(pixel_xres, pixel_yres, 0, mode) == NULL) {
		fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
		SDL_Quit();
		return(2);
	}
#ifdef EGL
	EGL_Init();
#endif

	SDL_WM_SetCaption((app_name_nice + " " + PPSSPP_GIT_VERSION).c_str(), NULL);
#ifdef MAEMO
	SDL_ShowCursor(SDL_DISABLE);
#endif


#ifndef USING_GLES2
	if (GLEW_OK != glewInit()) {
		printf("Failed to initialize glew!\n");
		return 1;
	}

	if (GLEW_VERSION_2_0) {
		printf("OpenGL 2.0 or higher.\n");
	} else {
		printf("Sorry, this program requires OpenGL 2.0.\n");
		return 1;
	}
#endif

#ifdef _MSC_VER
	// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
	TCHAR path[MAX_PATH];
	SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
	PathAppend(path, (app_name + "\\").c_str());
#else
	// Mac / Linux
	char path[512];
	const char *the_path = getenv("HOME");
	if (!the_path) {
		struct passwd* pwd = getpwuid(getuid());
		if (pwd)
			the_path = pwd->pw_dir;
	}
	strcpy(path, the_path);
	if (path[strlen(path)-1] != '/')
		strcat(path, "/");
#endif

#ifdef _WIN32
	NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE");
#else
	NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
#endif

	pixel_in_dps = (float)pixel_xres / dp_xres;

	float dp_xscale = (float)dp_xres / pixel_xres;
	float dp_yscale = (float)dp_yres / pixel_yres;

	g_dpi_scale = dp_xres / (float)pixel_xres;

	printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
	printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
	NativeInitGraphics();

	SDL_AudioSpec fmt;
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, NULL) < 0)
		ELOG("Failed to open audio: %s", SDL_GetError());

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#ifdef PANDORA
	int numjoys = SDL_NumJoysticks();
	// Joysticks init, we the nubs if setup as Joystick
	if (numjoys > 0) {
		ljoy = SDL_JoystickOpen(0);
		if (numjoys > 1)
			rjoy = SDL_JoystickOpen(1);
	}
#else
	joystick = new SDLJoystick();
#endif
	EnableFZ();

	int framecount = 0;
	float t = 0;
	float lastT = 0;
	while (true) {
		input_state.accelerometer_valid = false;
		input_state.mouse_valid = true;
		int quitRequested = 0;

		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			float mx = event.motion.x * dp_xscale;
			float my = event.motion.y * dp_yscale;

			switch (event.type) {
			case SDL_QUIT:
				quitRequested = 1;
				break;
			case SDL_KEYDOWN:
				{
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_DOWN;
					key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_KEYUP:
				{
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_UP;
					key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_MOUSEBUTTONDOWN:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						input_state.pointer_x[0] = mx;
						input_state.pointer_y[0] = my;
						//input_state.mouse_buttons_down = 1;
						input_state.pointer_down[0] = true;
						input_state.mouse_valid = true;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_DOWN;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_WHEELUP:
					{
						KeyInput key;
						key.deviceId = DEVICE_ID_MOUSE;
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
						key.flags = KEY_DOWN;
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_WHEELDOWN:
					{
						KeyInput key;
						key.deviceId = DEVICE_ID_MOUSE;
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
						key.flags = KEY_DOWN;
						NativeKey(key);
					}
					break;
				}
				break;
			case SDL_MOUSEMOTION:
				if (input_state.pointer_down[0]) {
					input_state.pointer_x[0] = mx;
					input_state.pointer_y[0] = my;
					input_state.mouse_valid = true;
					TouchInput input;
					input.x = mx;
					input.y = my;
					input.flags = TOUCH_MOVE;
					input.id = 0;
					NativeTouch(input);
				}
				break;
			case SDL_MOUSEBUTTONUP:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						input_state.pointer_x[0] = mx;
						input_state.pointer_y[0] = my;
						input_state.pointer_down[0] = false;
						input_state.mouse_valid = true;
						//input_state.mouse_buttons_up = 1;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_UP;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_WHEELUP:
					{
						KeyInput key;
						key.deviceId = DEVICE_ID_DEFAULT;
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
						key.flags = KEY_UP;
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_WHEELDOWN:
					{
						KeyInput key;
						key.deviceId = DEVICE_ID_DEFAULT;
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
						key.flags = KEY_UP;
						NativeKey(key);
					}
					break;
				}
				break;
			default:
				joystick->ProcessInput(event);
				break;
			}
		}

		if (quitRequested)
			break;

		const uint8 *keys = (const uint8 *)SDL_GetKeyState(NULL);
		SimulateGamepad(keys, &input_state);
		UpdateInputState(&input_state);
		NativeUpdate(input_state);
		NativeRender();
#ifndef MAEMO
		if (lastUIState != globalUIState) {
			lastUIState = globalUIState;
			if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls)
				SDL_ShowCursor(SDL_DISABLE);
			if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen)
				SDL_ShowCursor(SDL_ENABLE);
		}
#endif

		EndInputState(&input_state);

		if (framecount % 60 == 0) {
			// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
		}

#ifdef EGL
		eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
		if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
		{
			SDL_GL_SwapBuffers();
			lastT = t;
		}
#endif
		time_update();
		t = time_now();
		framecount++;
	}
#ifndef PANDORA
	delete joystick;
	joystick = NULL;
#endif
	// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
	// The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifdef _WIN32
	exit(0);
#endif
	NativeShutdownGraphics();
	SDL_PauseAudio(1);
	SDL_CloseAudio();
	NativeShutdown();
#ifdef EGL
	EGL_Close();
#endif
	SDL_Quit();
	net::Shutdown();
	exit(0);
	return 0;
}
示例#6
0
extern "C" int main(int argcount, char** argvec)
{

	#ifdef NO_STDERR
	std::freopen("/dev/null", "w", stderr);
	std::cerr.sync_with_stdio(true);
	#endif

	std::cerr << "Frogatto engine version " << preferences::version() << "\n";
	LOG( "After print engine version" );

	#if defined(TARGET_BLACKBERRY)
		chdir("app/native");
		std::cout<< "Changed working directory to: " << getcwd(0, 0) << std::endl;
	#endif

	std::string level_cfg = "titlescreen.cfg";
	bool unit_tests_only = false, skip_tests = false;
	bool run_benchmarks = false;
	std::vector<std::string> benchmarks_list;
	std::string utility_program;
	std::vector<std::string> util_args;
	std::string server = "wesnoth.org";

	const char* profile_output = NULL;
	std::string profile_output_buf;

	std::string orig_level_cfg = level_cfg;
	std::string override_level_cfg = "";

	int modules_loaded = 0;

	std::vector<std::string> argv;
	for(int n = 1; n < argcount; ++n) {
		argv.push_back(argvec[n]);
        
        if(argv.size() >= 2 && argv[argv.size()-2] == "-NSDocumentRevisionsDebugMode" && argv.back() == "YES") {
            //XCode passes these arguments by default when debugging -- make sure they are ignored.
            argv.resize(argv.size()-2);
        }
	}

	if(sys::file_exists("./master-config.cfg")) {
		variant cfg = json::parse_from_file("./master-config.cfg");
		if(cfg.is_map()) {
			if( cfg["id"].is_null() == false) {
				preferences::set_preferences_path_from_module(cfg["id"].as_string());
				//XXX module::set_module_name(cfg["id"].as_string(), cfg["id"].as_string());
			}
			if(cfg["arguments"].is_null() == false) {
				std::vector<std::string> additional_args = cfg["arguments"].as_list_string();
				argv.insert(argv.begin(), additional_args.begin(), additional_args.end());
			}
		}
	}

	for(int n = 0; n < argv.size(); ++n) {
		const int argc = argv.size();
		const std::string arg(argv[n]);
		std::string arg_name, arg_value;
		std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '=');
		if(equal != arg.end()) {
			arg_name = std::string(arg.begin(), equal);
			arg_value = std::string(equal+1, arg.end());
		}
		if(arg_name == "--module") {
			if(load_module(arg_value, &argv) != 0) {
				std::cerr << "FAILED TO LOAD MODULE: " << arg_value << "\n";
				return -1;
			}
			++modules_loaded;
		}
	}

	if(modules_loaded == 0) {
		if(load_module(DEFAULT_MODULE, &argv) != 0) {
			std::cerr << "FAILED TO LOAD MODULE: " << DEFAULT_MODULE << "\n";
			return -1;
		}
	}

	preferences::load_preferences();
	LOG( "After load_preferences()" );

	// load difficulty settings after module, before rest of args.
	difficulty::manager();

	for(int n = 0; n < argv.size(); ++n) {
		const int argc = argv.size();
		const std::string arg(argv[n]);
		std::string arg_name, arg_value;
		std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '=');
		if(equal != arg.end()) {
			arg_name = std::string(arg.begin(), equal);
			arg_value = std::string(equal+1, arg.end());
		}
		
		if(arg_name == "--module") {
			// ignore already processed.
		} else if(arg_name == "--profile" || arg == "--profile") {
			profile_output_buf = arg_value;
			profile_output = profile_output_buf.c_str();
		} else if(arg_name == "--utility") {
			utility_program = arg_value;
			for(++n; n < argc; ++n) {
				const std::string arg(argv[n]);
				util_args.push_back(arg);
			}

			break;
		} else if(arg == "--benchmarks") {
			run_benchmarks = true;
		} else if(arg_name == "--benchmarks") {
			run_benchmarks = true;
			benchmarks_list = util::split(arg_value);
		} else if(arg == "--tests") {
			unit_tests_only = true;
		} else if(arg == "--no-tests") {
			skip_tests = true;
		} else if(arg == "--width" && n+1 < argc) {
			std::string w(argv[++n]);
			preferences::set_actual_screen_width(boost::lexical_cast<int>(w));
		} else if(arg == "--height" && n+1 < argc) {
			std::string h(argv[++n]);
			preferences::set_actual_screen_height(boost::lexical_cast<int>(h));
		} else if(arg == "--level" && n+1 < argc) {
			override_level_cfg = argv[++n];
		} else if(arg == "--host" && n+1 < argc) {
			server = argv[++n];
		} else if(arg == "--compiled") {
			preferences::set_load_compiled(true);
#ifndef NO_EDITOR
		} else if(arg == "--edit") {
			preferences::set_edit_on_start(true);
#endif
		} else if(arg == "--no-compiled") {
			preferences::set_load_compiled(false);
#if defined(TARGET_PANDORA)
		} else if(arg == "--no-fbo") {
			preferences::set_fbo(false);
		} else if(arg == "--no-bequ") {
			preferences::set_bequ(false);
#endif
		} else if(arg == "--help" || arg == "-h") {
			print_help(std::string(argvec[0]));
			return 0;
		} else {
			const bool res = preferences::parse_arg(argv[n].c_str());
			if(!res) {
				std::cerr << "unrecognized arg: '" << arg << "'\n";
				return -1;
			}
		}
	}

	checksum::manager checksum_manager;

	preferences::expand_data_paths();
	LOG( "After expand_data_paths()" );

	std::cerr << "Preferences dir: " << preferences::user_data_path() << '\n';

	//make sure that the user data path exists.
	if(!preferences::setup_preferences_dir()) {
		std::cerr << "cannot create preferences dir!\n";
	}

	std::cerr << "\n";

	if(utility_program.empty() == false && test::utility_needs_video(utility_program) == false) {
		test::run_utility(utility_program, util_args);
		return 0;
	}

#if defined(TARGET_PANDORA)
    EGL_Open();
#endif

#if defined(__ANDROID__)
	std::freopen("stdout.txt","w",stdout);
	std::freopen("stderr.txt","w",stderr);
	std::cerr.sync_with_stdio(true);
#endif

	LOG( "Start of main" );
	
	Uint32 sdl_init_flags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK;
#ifdef _WINDOWS
	sdl_init_flags |= SDL_INIT_TIMER;
#endif
	if(SDL_Init(sdl_init_flags) < 0) {
		std::cerr << "could not init SDL\n";
		return -1;
	}
	LOG( "After SDL_Init" );

#ifdef TARGET_OS_HARMATTAN
	g_type_init();
#endif
	i18n::init ();
	LOG( "After i18n::init()" );

//	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);

#if defined(TARGET_OS_IPHONE) || defined(TARGET_BLACKBERRY) || defined(__ANDROID__)
	//on the iPhone and PlayBook, try to restore the auto-save if it exists
	if(sys::file_exists(preferences::auto_save_file_path()) && sys::read_file(std::string(preferences::auto_save_file_path()) + ".stat") == "1") {
		level_cfg = "autosave.cfg";
		sys::write_file(std::string(preferences::auto_save_file_path()) + ".stat", "0");

	}
#endif

	if(override_level_cfg.empty() != true) {
		level_cfg = override_level_cfg;
		orig_level_cfg = level_cfg;
	}

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
	int width, height;
	iphone_screen_res(&width, &height);
	preferences::set_actual_screen_width(width);
	preferences::set_actual_screen_height(height);
	int multiplier = 2;
	if (width > 320)
	{
		//preferences::set_use_pretty_scaling(true);
		multiplier = 1;
	}
	preferences::set_virtual_screen_width(height*multiplier);
	preferences::set_virtual_screen_height(width*multiplier);
	preferences::set_control_scheme(height % 1024 ? "iphone_2d" : "ipad_2d");
	
	SDL_WindowID windowID = SDL_CreateWindow (NULL, 0, 0, preferences::actual_screen_width(), preferences::actual_screen_height(),
		SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
		SDL_WINDOW_BORDERLESS);
	if (windowID == 0) { 
		std::cerr << "Could not create window: " << SDL_GetError() << "\n"; 
		return -1;
	}
	
	//	if (SDL_GL_CreateContext(windowID) == 0) {
	//		std::cerr << "Could not create GL context: " << SDL_GetError() << "\n";
	//		return -1;
	//	}
	if (SDL_CreateRenderer(windowID, -1, 0) != 0) {
		std::cerr << "Could not create renderer\n";
		return -1;
	}
	
#else
#ifdef TARGET_OS_HARMATTAN
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGLES | SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}

	preferences::init_oes();
	SDL_ShowCursor(0);
#else
#ifndef __APPLE__
	graphics::surface wm_icon = graphics::surface_cache::get("window-icon.png");
	if(!wm_icon.null()) {
		SDL_WM_SetIcon(wm_icon, NULL);
	}
#endif

#if defined(TARGET_PANDORA)
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),16,SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
    EGL_Init();
    preferences::init_oes();
#elif defined(TARGET_TEGRA)
	//if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,preferences::resizable() ? SDL_RESIZABLE : 0|preferences::fullscreen() ? SDL_FULLSCREEN : 0) == NULL) {
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
    EGL_Init();
    preferences::init_oes();
#elif defined(TARGET_BLACKBERRY)
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|SDL_FULLSCREEN) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
	preferences::init_oes();
#elif defined(__ANDROID__)
    SDL_Rect** r = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL);
    if( r != (SDL_Rect**)0 && r != (SDL_Rect**)-1 ) {
        preferences::set_actual_screen_width(r[0]->w);
        preferences::set_actual_screen_height(r[0]->h);
		if(r[0]->w < 640) {
        	preferences::set_virtual_screen_width(r[0]->w*2);
        	preferences::set_virtual_screen_height(r[0]->h*2);
		} else {
			preferences::set_virtual_screen_width(r[0]->w);
			preferences::set_virtual_screen_height(r[0]->h);
		}
		preferences::set_control_scheme(r[0]->h >= 1024 ? "ipad_2d" : "android_med");
    }

    if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),16,SDL_FULLSCREEN|SDL_OPENGL) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
    }
#else
	if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|(preferences::resizable() ? SDL_RESIZABLE : 0)|(preferences::fullscreen() ? SDL_FULLSCREEN : 0)) == NULL) {
		std::cerr << "could not set video mode\n";
		return -1;
	}
#endif
#endif

#endif

//	srand(time(NULL));

	const stats::manager stats_manager;
#ifndef NO_EDITOR
	const external_text_editor::manager editor_manager;
#endif // NO_EDITOR

	std::cerr
		<< "\n"
		<< "OpenGL vendor: " << reinterpret_cast<const char *>(glGetString(GL_VENDOR)) << "\n"
		<< "OpenGL version: " << reinterpret_cast<const char *>(glGetString(GL_VERSION)) << "\n"
		<< "OpenGL extensions: " << reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)) << "\n"
		<< "\n";
	glShadeModel(GL_SMOOTH);
	glEnable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	SDL_WM_SetCaption(module::get_module_pretty_name().c_str(), module::get_module_pretty_name().c_str());

	std::cerr << "JOYSTICKS: " << SDL_NumJoysticks() << "\n";

	const load_level_manager load_manager;

	{ //manager scope
	const font::manager font_manager;
	const sound::manager sound_manager;
	const joystick::manager joystick_manager;
		
	#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
	const SDL_Surface* fb = SDL_GetVideoSurface();
	if(fb == NULL) {
		return 0;
	}
	#endif

	graphics::texture::manager texture_manager;

#ifndef NO_EDITOR
	editor::manager editor_manager;
#endif

	variant preloads;
	loading_screen loader;
	try {
		sound::init_music(json::parse_from_file(module::map_file("data/music.cfg")));

		std::string filename = "data/fonts." + i18n::get_locale() + ".cfg";
		if (!sys::file_exists(filename))
			filename = "data/fonts.cfg";
		graphical_font::init(json::parse_from_file(module::map_file(filename)));

		preloads = json::parse_from_file(module::map_file("data/preload.cfg"));
		int preload_items = preloads["preload"].num_elements();
		loader.set_number_of_items(preload_items+7); // 7 is the number of items that will be loaded below
		custom_object::init();
		loader.draw_and_increment(_("Initializing custom object functions"));
		init_custom_object_functions(json::parse_from_file(module::map_file("data/functions.cfg")));
		loader.draw_and_increment(_("Initializing textures"));
		loader.load(preloads);
		loader.draw_and_increment(_("Initializing tiles"));
		tile_map::init(json::parse_from_file(module::map_file("data/tiles.cfg")));
		loader.draw_and_increment(_("Initializing GUI"));

		variant gui_node = json::parse_from_file(module::map_file(preferences::load_compiled() ? "data/compiled/gui.cfg" : "data/gui.cfg"));
		gui_section::init(gui_node);
		loader.draw_and_increment(_("Initializing GUI"));
		framed_gui_element::init(gui_node);

	} catch(const json::parse_error& e) {
		std::cerr << "ERROR PARSING: " << e.error_message() << "\n";
		return 0;
	}
	loader.draw(_("Loading level"));

	if(!skip_tests && !test::run_tests()) {
		return -1;
	}

	if(unit_tests_only) {
		return 0;
	}
#if defined(__APPLE__) && !(TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE)
	GLint swapInterval = 1;
	CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
#endif

#ifndef SDL_VIDEO_OPENGL_ES
	GLenum glew_status = glewInit();
	ASSERT_EQ(glew_status, GLEW_OK);
#endif

	loader.finish_loading();
	//look to see if we got any quit events while loading.
	{
	SDL_Event event;
	while(SDL_PollEvent(&event)) {
		if(event.type == SDL_QUIT) {
			return 0;
		}
	}
	}

	formula_profiler::manager profiler(profile_output);
	texture_frame_buffer::init();

	if(run_benchmarks) {
		if(benchmarks_list.empty() == false) {
			test::run_benchmarks(&benchmarks_list);
		} else {
			test::run_benchmarks();
		}
		return 0;
	} else if(utility_program.empty() == false) {
		test::run_utility(utility_program, util_args);
		return 0;
	}

	bool quit = false;
	bool of_initialized = false;

	while(!quit && !show_title_screen(level_cfg)) {
		boost::intrusive_ptr<level> lvl(load_level(level_cfg));
		
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
		if (!of_initialized)
		{
			of_init();
			of_initialized = true;
		}
#endif

		//see if we're loading a multiplayer level, in which case we
		//connect to the server.
		multiplayer::manager mp_manager(lvl->is_multiplayer());
		if(lvl->is_multiplayer()) {
			multiplayer::setup_networked_game(server);
		}

		if(lvl->is_multiplayer()) {
			last_draw_position() = screen_position();
			std::string level_cfg = "waiting-room.cfg";
			boost::intrusive_ptr<level> wait_lvl(load_level(level_cfg));
			wait_lvl->finish_loading();
			wait_lvl->set_multiplayer_slot(0);
			if(wait_lvl->player()) {
				wait_lvl->player()->set_current_level(level_cfg);
			}
			wait_lvl->set_as_current_level();

			level_runner runner(wait_lvl, level_cfg, orig_level_cfg);

			multiplayer::sync_start_time(*lvl, boost::bind(&level_runner::play_cycle, &runner));

			lvl->set_multiplayer_slot(multiplayer::slot());
		}

		last_draw_position() = screen_position();

		assert(lvl.get());
		if(!lvl->music().empty()) {
			sound::play_music(lvl->music());
		}

		if(lvl->player() && level_cfg != "autosave.cfg") {
			lvl->player()->set_current_level(level_cfg);
			lvl->player()->get_entity().save_game();
		}

		set_scene_title(lvl->title());

		try {
			quit = level_runner(lvl, level_cfg, orig_level_cfg).play_level();
			level_cfg = orig_level_cfg;
		} catch(multiplayer_exception&) {
		}
	}

	level::clear_current_level();

	} //end manager scope, make managers destruct before calling SDL_Quit
//	controls::debug_dump_controls();
#if defined(TARGET_PANDORA) || defined(TARGET_TEGRA)
    EGL_Destroy();
#endif

	SDL_Quit();
	
	preferences::save_preferences();
	std::cerr << SDL_GetError() << "\n";
#if !defined(TARGET_OS_HARMATTAN) && !defined(TARGET_TEGRA) && !defined(TARGET_BLACKBERRY) && !defined(__ANDROID__)
	std::cerr << gluErrorString(glGetError()) << "\n";
#endif
	return 0;
}
示例#7
0
int fs_ml_video_create_window(const char *title) {
    fs_log("fs_ml_video_create_window\n");
    g_window_title = g_strdup(title);

    static int initialized = 0;
    SDL_Init(SDL_INIT_VIDEO);
#ifdef HAVE_GLES
    if (!EGL_Open())
        exit(1);
#endif

    if (!initialized) {
        const SDL_VideoInfo* info = SDL_GetVideoInfo();
        g_fullscreen_width = fs_config_get_int("fullscreen_width");
        if (g_fullscreen_width == FS_CONFIG_NONE) {
            g_fullscreen_width = info->current_w;
        }
        g_fullscreen_height = fs_config_get_int("fullscreen_height");
        if (g_fullscreen_height == FS_CONFIG_NONE) {
            g_fullscreen_height = info->current_h;
        }

        if (g_fs_emu_video_fullscreen_mode == NULL) {
            g_fs_emu_video_fullscreen_window = -1;
        }
        else if (g_strcasecmp(g_fs_emu_video_fullscreen_mode,
                "window") == 0) {
            g_fs_emu_video_fullscreen_window = 1;
        }
        else if (g_strcasecmp(g_fs_emu_video_fullscreen_mode,
                "fullscreen") == 0) {
            g_fs_emu_video_fullscreen_window = 0;
        }
        if (g_fs_emu_video_fullscreen_window == -1) {
#ifdef MACOSX
            g_fs_emu_video_fullscreen_window = 0;
#else
            g_fs_emu_video_fullscreen_window = 0;
#endif
        }
        initialized = 1;
    }

    if (g_fs_ml_video_sync) {
        g_fs_ml_vblank_sync = 1;
    }

#ifndef HAVE_GLES
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    if (g_fs_ml_vblank_sync) {
        fs_emu_log("*** SDL_GL_SWAP_CONTROL is enabled ***\n");
        SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
    }
    else {
        fs_emu_log("*** SDL_GL_SWAP_CONTROL is disabled ***\n");
        SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
    }

    if (g_fsaa) {
        fs_log("setting FSAA samples to %d\n", g_fsaa);
        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, g_fsaa);
    }
#endif

    g_window_width = fs_config_get_int("window_width");
    if (g_window_width == FS_CONFIG_NONE) {
    	g_window_width = 1920 / 2;
    }
    g_window_height = fs_config_get_int("window_height");
    if (g_window_height == FS_CONFIG_NONE) {
    	g_window_height = 1080/ 2;
    }
    g_window_resizable = fs_config_get_boolean("window_resizable");
    if (g_window_resizable == FS_CONFIG_NONE) {
    	g_window_resizable = 1;
    }

    set_video_mode();
#ifdef HAVE_GLES
    EGL_Init();
#endif

    // we display a black frame as soon as possible (to reduce flickering on
    // startup)
    glClear(GL_COLOR_BUFFER_BIT);
    SDL_GL_SwapBuffers();
    fs_gl_finish();

    SDL_WM_SetCaption(g_window_title, g_get_application_name());

    if (fs_config_get_boolean("grab_input") != 0) {
        fs_ml_grab_input(1, 1);
    }
    fs_ml_show_cursor(0, 1);

    // this function must be called from the video thread
    fs_log("init_opengl\n");
    fs_emu_video_init_opengl();

#ifdef WINDOWS
    fs_ml_init_raw_input();
#else
    // enable keysym to unicode char translation
    SDL_EnableUNICODE(1);
#endif
    fs_log("create windows is done\n");
    return 1;
}
示例#8
0
文件: PCMain.cpp 项目: Bigpet/native
int main(int argc, char *argv[]) {
#ifdef RPI
    bcm_host_init();
#endif
    putenv((char*)"SDL_VIDEO_CENTERED=1");

    std::string app_name;
    std::string app_name_nice;
    bool landscape;
    NativeGetAppInfo(&app_name, &app_name_nice, &landscape);

    net::Init();
#ifdef __APPLE__
    // Make sure to request a somewhat modern GL context at least - the
    // latest supported by MacOSX (really, really sad...)
    // Requires SDL 2.0
    // We really should upgrade to SDL 2.0 soon.
    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
#endif

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) {
        fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
        return 1;
    }
#ifdef USING_EGL
    if (EGL_Open())
        return 1;
#endif

    // Get the video info before doing anything else, so we don't get skewed resolution results.
    const SDL_VideoInfo* desktopVideoInfo = SDL_GetVideoInfo();
    g_DesktopWidth = desktopVideoInfo->current_w;
    g_DesktopHeight = desktopVideoInfo->current_h;

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

    int mode;
#ifdef USING_GLES2
    mode = SDL_SWSURFACE | SDL_FULLSCREEN;
#else
    mode = SDL_OPENGL | SDL_RESIZABLE;
#endif
    int set_xres = -1;
    int set_yres = -1;
    bool portrait = false;
    bool set_ipad = false;
    float set_dpi = 1.0f;
    float set_scale = 1.0f;

    for (int i = 1; i < argc; i++) {
        if (!strcmp(argv[i],"--fullscreen"))
            mode |= SDL_FULLSCREEN;
        if (set_xres == -2) {
            set_xres = parseInt(argv[i]);
        } else if (set_yres == -2) {
            set_yres = parseInt(argv[i]);
        }
        if (set_dpi == -2)
            set_dpi = parseFloat(argv[i]);
        if (set_scale == -2)
            set_scale = parseFloat(argv[i]);

        if (!strcmp(argv[i],"--xres"))
            set_xres = -2;
        if (!strcmp(argv[i],"--yres"))
            set_yres = -2;
        if (!strcmp(argv[i],"--dpi"))
            set_dpi = -2;
        if (!strcmp(argv[i],"--scale"))
            set_scale = -2;

        if (!strcmp(argv[i],"--ipad"))
            set_ipad = true;
        if (!strcmp(argv[i],"--portrait"))
            portrait = true;
    }

    if (mode & SDL_FULLSCREEN) {
        const SDL_VideoInfo* info = SDL_GetVideoInfo();
        pixel_xres = info->current_w;
        pixel_yres = info->current_h;
#ifdef PPSSPP
        g_Config.bFullScreen = true;
#endif
    } else {
        // set a sensible default resolution (2x)
        pixel_xres = 480 * 2 * set_scale;
        pixel_yres = 272 * 2 * set_scale;
        if (portrait) {
            std::swap(pixel_xres, pixel_yres);
        }
#ifdef PPSSPP
        g_Config.bFullScreen = false;
#endif
    }

    set_dpi = 1.0f / set_dpi;

    if (set_ipad) {
        pixel_xres = 1024;
        pixel_yres = 768;
    }
    if (!landscape) {
        std::swap(pixel_xres, pixel_yres);
    }

    if (set_xres > 0) {
        pixel_xres = set_xres;
    }
    if (set_yres > 0) {
        pixel_yres = set_yres;
    }
    float dpi_scale = 1.0f;
    if (set_dpi > 0) {
        dpi_scale = set_dpi;
    }

    dp_xres = (float)pixel_xres * dpi_scale;
    dp_yres = (float)pixel_yres * dpi_scale;

    g_Screen = SDL_SetVideoMode(pixel_xres, pixel_yres, 0, mode);
    if (g_Screen == NULL) {
        fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
        SDL_Quit();
        return 2;
    }

#ifdef USING_EGL
    EGL_Init();
#endif

#ifdef PPSSPP
    SDL_WM_SetCaption((app_name_nice + " " + PPSSPP_GIT_VERSION).c_str(), NULL);
#endif

#ifdef MOBILE_DEVICE
    SDL_ShowCursor(SDL_DISABLE);
#endif


#ifndef USING_GLES2
    if (GLEW_OK != glewInit()) {
        printf("Failed to initialize glew!\n");
        return 1;
    }

    if (GLEW_VERSION_2_0) {
        printf("OpenGL 2.0 or higher.\n");
    } else {
        printf("Sorry, this program requires OpenGL 2.0.\n");
        return 1;
    }
#endif

#ifdef _MSC_VER
    // VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
    TCHAR path[MAX_PATH];
    SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
    PathAppend(path, (app_name + "\\").c_str());
#else
    // Mac / Linux
    char path[512];
    const char *the_path = getenv("HOME");
    if (!the_path) {
        struct passwd* pwd = getpwuid(getuid());
        if (pwd)
            the_path = pwd->pw_dir;
    }
    strcpy(path, the_path);
    if (path[strlen(path)-1] != '/')
        strcat(path, "/");
#endif

#ifdef _WIN32
    NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE");
#else
    NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
#endif

    pixel_in_dps = (float)pixel_xres / dp_xres;
    g_dpi_scale = dp_xres / (float)pixel_xres;

    printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
    printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);

    NativeInitGraphics();
    NativeResized();

    SDL_AudioSpec fmt, ret_fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.freq = 44100;
    fmt.format = AUDIO_S16;
    fmt.channels = 2;
    fmt.samples = 2048;
    fmt.callback = &mixaudio;
    fmt.userdata = (void *)0;

    if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
        ELOG("Failed to open audio: %s", SDL_GetError());
    } else {
        if (ret_fmt.freq != 44100 || ret_fmt.format != AUDIO_S16 || ret_fmt.channels != 2 || fmt.samples != 2048) {
            ELOG("Sound buffer format does not match requested format.");
            ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, 44100);
            ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, AUDIO_S16);
            ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, 2);
            ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, 2048);
        }

        if (ret_fmt.freq != 44100 || ret_fmt.format != AUDIO_S16 || ret_fmt.channels != 2) {
            ELOG("Provided output format does not match requirement, turning audio off");
            SDL_CloseAudio();
        } else {
            ELOG("Provided output audio format is usable, thus using it");
        }
    }

    // Audio must be unpaused _after_ NativeInit()
    SDL_PauseAudio(0);
#ifndef _WIN32
    joystick = new SDLJoystick();
#endif
    EnableFZ();

    int framecount = 0;
    float t = 0;
    float lastT = 0;
    uint32_t pad_buttons = 0;	 // legacy pad buttons
    while (true) {
        input_state.accelerometer_valid = false;
        input_state.mouse_valid = true;

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            float mx = event.motion.x * g_dpi_scale;
            float my = event.motion.y * g_dpi_scale;

            switch (event.type) {
            case SDL_QUIT:
                g_QuitRequested = 1;
                break;
#if !defined(MOBILE_DEVICE)
            case SDL_VIDEORESIZE:
            {
                g_Screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_OPENGL | SDL_RESIZABLE);
                if (g_Screen == NULL) {
                    fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
                    SDL_Quit();
                    return 2;
                }
                pixel_xres = event.resize.w;
                pixel_yres = event.resize.h;
                dp_xres = (float)pixel_xres * dpi_scale;
                dp_yres = (float)pixel_yres * dpi_scale;
                NativeResized();
                break;
            }
#endif
            case SDL_KEYDOWN:
            {
                int k = event.key.keysym.sym;
                KeyInput key;
                key.flags = KEY_DOWN;
                key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
                key.deviceId = DEVICE_ID_KEYBOARD;
                NativeKey(key);

                for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
                    if (legacyKeyMap[i] == key.keyCode)
                        pad_buttons |= 1 << i;
                }
                break;
            }
            case SDL_KEYUP:
            {
                int k = event.key.keysym.sym;
                KeyInput key;
                key.flags = KEY_UP;
                key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
                key.deviceId = DEVICE_ID_KEYBOARD;
                NativeKey(key);
                for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
                    if (legacyKeyMap[i] == key.keyCode)
                        pad_buttons &= ~(1 << i);
                }
                break;
            }
            case SDL_MOUSEBUTTONDOWN:
                switch (event.button.button) {
                case SDL_BUTTON_LEFT:
                {
                    input_state.pointer_x[0] = mx;
                    input_state.pointer_y[0] = my;
                    input_state.pointer_down[0] = true;
                    input_state.mouse_valid = true;
                    TouchInput input;
                    input.x = mx;
                    input.y = my;
                    input.flags = TOUCH_DOWN;
                    input.id = 0;
                    NativeTouch(input);
                    KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN);
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_RIGHT:
                {
                    KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN);
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_WHEELUP:
                {
                    KeyInput key;
                    key.deviceId = DEVICE_ID_MOUSE;
                    key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
                    key.flags = KEY_DOWN;
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_WHEELDOWN:
                {
                    KeyInput key;
                    key.deviceId = DEVICE_ID_MOUSE;
                    key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
                    key.flags = KEY_DOWN;
                    NativeKey(key);
                }
                break;
                }
                break;
            case SDL_MOUSEMOTION:
                if (input_state.pointer_down[0]) {
                    input_state.pointer_x[0] = mx;
                    input_state.pointer_y[0] = my;
                    input_state.mouse_valid = true;
                    TouchInput input;
                    input.x = mx;
                    input.y = my;
                    input.flags = TOUCH_MOVE;
                    input.id = 0;
                    NativeTouch(input);
                }
                break;
            case SDL_MOUSEBUTTONUP:
                switch (event.button.button) {
                case SDL_BUTTON_LEFT:
                {
                    input_state.pointer_x[0] = mx;
                    input_state.pointer_y[0] = my;
                    input_state.pointer_down[0] = false;
                    input_state.mouse_valid = true;
                    //input_state.mouse_buttons_up = 1;
                    TouchInput input;
                    input.x = mx;
                    input.y = my;
                    input.flags = TOUCH_UP;
                    input.id = 0;
                    NativeTouch(input);
                    KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP);
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_RIGHT:
                {
                    KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP);
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_WHEELUP:
                {
                    KeyInput key;
                    key.deviceId = DEVICE_ID_DEFAULT;
                    key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
                    key.flags = KEY_UP;
                    NativeKey(key);
                }
                break;
                case SDL_BUTTON_WHEELDOWN:
                {
                    KeyInput key;
                    key.deviceId = DEVICE_ID_DEFAULT;
                    key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
                    key.flags = KEY_UP;
                    NativeKey(key);
                }
                break;
                }
                break;
            default:
#ifndef _WIN32
                joystick->ProcessInput(event);
#endif
                break;
            }
        }
        if (g_QuitRequested)
            break;
        const uint8 *keys = (const uint8 *)SDL_GetKeyState(NULL);
        SimulateGamepad(keys, &input_state);
        input_state.pad_buttons = pad_buttons;
        UpdateInputState(&input_state, true);
        NativeUpdate(input_state);
        if (g_QuitRequested)
            break;
        NativeRender();
#if defined(PPSSPP) && !defined(MOBILE_DEVICE)
        if (lastUIState != globalUIState) {
            lastUIState = globalUIState;
            if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls)
                SDL_ShowCursor(SDL_DISABLE);
            if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen)
                SDL_ShowCursor(SDL_ENABLE);
        }
#endif

        EndInputState(&input_state);

        if (framecount % 60 == 0) {
            // glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
        }

#ifdef USING_EGL
        eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
        if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
        {
            SDL_GL_SwapBuffers();
            lastT = t;
        }
#endif

        ToggleFullScreenIfFlagSet();
        time_update();
        t = time_now();
        framecount++;
    }
#ifndef _WIN32
    delete joystick;
#endif
    // Faster exit, thanks to the OS. Remove this if you want to debug shutdown
    // The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifndef MOBILE_DEVICE
    exit(0);
#endif
    NativeShutdownGraphics();
    SDL_PauseAudio(1);
    SDL_CloseAudio();
    NativeShutdown();
#ifdef USING_EGL
    EGL_Close();
#endif
    SDL_Quit();
    net::Shutdown();
#ifdef RPI
    bcm_host_deinit();
#endif

    exit(0);
    return 0;
}
示例#9
0
文件: PCMain.cpp 项目: Orphis/ppsspp
int main(int argc, char *argv[]) {
#if PPSSPP_PLATFORM(RPI)
	bcm_host_init();
#endif
	putenv((char*)"SDL_VIDEO_CENTERED=1");
	SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");

	std::string app_name;
	std::string app_name_nice;
	std::string version;
	bool landscape;
	NativeGetAppInfo(&app_name, &app_name_nice, &landscape, &version);

	bool joystick_enabled = true;
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) {
		joystick_enabled = false;
		if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
			fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
			return 1;
		}
	}

#ifdef __APPLE__
	// Make sure to request a somewhat modern GL context at least - the
	// latest supported by MacOSX (really, really sad...)
	// Requires SDL 2.0
	// We really should upgrade to SDL 2.0 soon.
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#endif

#ifdef USING_EGL
	if (EGL_Open())
		return 1;
#endif

	// Get the video info before doing anything else, so we don't get skewed resolution results.
	// TODO: support multiple displays correctly
	SDL_DisplayMode displayMode;
	int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode);
	if (should_be_zero != 0) {
		fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError());
		return 1;
	}
	g_DesktopWidth = displayMode.w;
	g_DesktopHeight = displayMode.h;

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetSwapInterval(1);

	Uint32 mode;
#ifdef USING_GLES2
	mode = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
#else
	mode = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
#endif
	int set_xres = -1;
	int set_yres = -1;
	bool portrait = false;
	bool set_ipad = false;
	float set_dpi = 1.0f;
	float set_scale = 1.0f;

	// Produce a new set of arguments with the ones we skip.
	int remain_argc = 1;
	const char *remain_argv[256] = { argv[0] };

	for (int i = 1; i < argc; i++) {
		if (!strcmp(argv[i],"--fullscreen"))
			mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
		else if (set_xres == -2)
			set_xres = parseInt(argv[i]);
		else if (set_yres == -2)
			set_yres = parseInt(argv[i]);
		else if (set_dpi == -2)
			set_dpi = parseFloat(argv[i]);
		else if (set_scale == -2)
			set_scale = parseFloat(argv[i]);
		else if (!strcmp(argv[i],"--xres"))
			set_xres = -2;
		else if (!strcmp(argv[i],"--yres"))
			set_yres = -2;
		else if (!strcmp(argv[i],"--dpi"))
			set_dpi = -2;
		else if (!strcmp(argv[i],"--scale"))
			set_scale = -2;
		else if (!strcmp(argv[i],"--ipad"))
			set_ipad = true;
		else if (!strcmp(argv[i],"--portrait"))
			portrait = true;
		else {
			remain_argv[remain_argc++] = argv[i];
		}
	}

	// Is resolution is too low to run windowed
	if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) {
		mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
	}

	if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) {
		pixel_xres = g_DesktopWidth;
		pixel_yres = g_DesktopHeight;
		g_Config.bFullScreen = true;
	} else {
		// set a sensible default resolution (2x)
		pixel_xres = 480 * 2 * set_scale;
		pixel_yres = 272 * 2 * set_scale;
		if (portrait) {
			std::swap(pixel_xres, pixel_yres);
		}
		g_Config.bFullScreen = false;
	}

	set_dpi = 1.0f / set_dpi;

	if (set_ipad) {
		pixel_xres = 1024;
		pixel_yres = 768;
	}
	if (!landscape) {
		std::swap(pixel_xres, pixel_yres);
	}

	if (set_xres > 0) {
		pixel_xres = set_xres;
	}
	if (set_yres > 0) {
		pixel_yres = set_yres;
	}
	float dpi_scale = 1.0f;
	if (set_dpi > 0) {
		dpi_scale = set_dpi;
	}

	dp_xres = (float)pixel_xres * dpi_scale;
	dp_yres = (float)pixel_yres * dpi_scale;

#ifdef _MSC_VER
	// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
	TCHAR path[MAX_PATH];
	SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
	PathAppend(path, (app_name + "\\").c_str());
#else
	// Mac / Linux
	char path[2048];
	const char *the_path = getenv("HOME");
	if (!the_path) {
		struct passwd* pwd = getpwuid(getuid());
		if (pwd)
			the_path = pwd->pw_dir;
	}
	strcpy(path, the_path);
	if (path[strlen(path)-1] != '/')
		strcat(path, "/");
#endif

#ifdef _WIN32
	NativeInit(remain_argc, (const char **)remain_argv, path, "D:\\", nullptr);
#else
	NativeInit(remain_argc, (const char **)remain_argv, path, "/tmp", nullptr);
#endif

	// Use the setting from the config when initing the window.
	if (g_Config.bFullScreen)
		mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;

	g_Screen = SDL_CreateWindow(app_name_nice.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()),\
					SDL_WINDOWPOS_UNDEFINED, pixel_xres, pixel_yres, mode);

	if (g_Screen == NULL) {
		NativeShutdown();
		fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
		SDL_Quit();
		return 2;
	}

	SDL_GLContext glContext = SDL_GL_CreateContext(g_Screen);
	if (glContext == NULL) {
		NativeShutdown();
		fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
		SDL_Quit();
		return 2;
	}

#ifdef USING_EGL
	EGL_Init();
#endif

	SDL_SetWindowTitle(g_Screen, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());

#ifdef MOBILE_DEVICE
	SDL_ShowCursor(SDL_DISABLE);
#endif


#ifndef USING_GLES2
	// Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc.
	// glewExperimental allows us to force GLEW to search for the pointers anyway.
	if (gl_extensions.IsCoreContext)
		glewExperimental = true;
	if (GLEW_OK != glewInit()) {
		printf("Failed to initialize glew!\n");
		return 1;
	}
	// Unfortunately, glew will generate an invalid enum error, ignore.
	if (gl_extensions.IsCoreContext)
		glGetError();

	if (GLEW_VERSION_2_0) {
		printf("OpenGL 2.0 or higher.\n");
	} else {
		printf("Sorry, this program requires OpenGL 2.0.\n");
		return 1;
	}
#endif


	pixel_in_dps_x = (float)pixel_xres / dp_xres;
	pixel_in_dps_y = (float)pixel_yres / dp_yres;
	g_dpi_scale_x = dp_xres / (float)pixel_xres;
	g_dpi_scale_y = dp_yres / (float)pixel_yres;
	g_dpi_scale_real_x = g_dpi_scale_x;
	g_dpi_scale_real_y = g_dpi_scale_y;

	printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
	printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);

	GraphicsContext *graphicsContext = new GLDummyGraphicsContext();
	NativeInitGraphics(graphicsContext);

	NativeResized();

	SDL_AudioSpec fmt, ret_fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
	} else {
		if (ret_fmt.samples != fmt.samples) // Notify, but still use it
			ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
		if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
			ELOG("Sound buffer format does not match requested format.");
			ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
			ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
			ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
			ELOG("Provided output format does not match requirement, turning audio off");
			SDL_CloseAudio();
		}
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#ifndef _WIN32
	if (joystick_enabled) {
		joystick = new SDLJoystick();
	} else {
		joystick = nullptr;
	}
#endif
	EnableFZ();

	int framecount = 0;
	float t = 0;
	float lastT = 0;
	bool mouseDown = false;

	while (true) {
		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			float mx = event.motion.x * g_dpi_scale_x;
			float my = event.motion.y * g_dpi_scale_y;

			switch (event.type) {
			case SDL_QUIT:
				g_QuitRequested = 1;
				break;

#if !defined(MOBILE_DEVICE)
			case SDL_WINDOWEVENT:
				switch (event.window.event) {
				case SDL_WINDOWEVENT_RESIZED:
				{
					Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
					bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);

					pixel_xres = event.window.data1;
					pixel_yres = event.window.data2;
					dp_xres = (float)pixel_xres * dpi_scale;
					dp_yres = (float)pixel_yres * dpi_scale;
					NativeResized();

					// Set variable here in case fullscreen was toggled by hotkey
					g_Config.bFullScreen = fullscreen;

					// Hide/Show cursor correctly toggling fullscreen
					if (lastUIState == UISTATE_INGAME && fullscreen && !g_Config.bShowTouchControls) {
						SDL_ShowCursor(SDL_DISABLE);
					} else if (lastUIState != UISTATE_INGAME || !fullscreen) {
						SDL_ShowCursor(SDL_ENABLE);
					}
					break;
				}

				default:
					break;
				}
				break;
#endif
			case SDL_KEYDOWN:
				{
					if (event.key.repeat > 0) { break;}
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_DOWN;
					auto mapped = KeyMapRawSDLtoNative.find(k);
					if (mapped == KeyMapRawSDLtoNative.end() || mapped->second == NKCODE_UNKNOWN) {
						break;
					}
					key.keyCode = mapped->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_KEYUP:
				{
					if (event.key.repeat > 0) { break;}
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_UP;
					auto mapped = KeyMapRawSDLtoNative.find(k);
					if (mapped == KeyMapRawSDLtoNative.end() || mapped->second == NKCODE_UNKNOWN) {
						break;
					}
					key.keyCode = mapped->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_TEXTINPUT:
				{
					int pos = 0;
					int c = u8_nextchar(event.text.text, &pos);
					KeyInput key;
					key.flags = KEY_CHAR;
					key.keyCode = c;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_MOUSEBUTTONDOWN:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						mouseDown = true;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_DOWN | TOUCH_MOUSE;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN);
						NativeKey(key);
					}
					break;
				}
				break;
			case SDL_MOUSEWHEEL:
				{
					KeyInput key;
					key.deviceId = DEVICE_ID_MOUSE;
					if (event.wheel.y > 0) {
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
					} else {
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
					}
					key.flags = KEY_DOWN;
					NativeKey(key);

					// SDL2 doesn't consider the mousewheel a button anymore
					// so let's send the KEY_UP right away.
					// Maybe KEY_UP alone will suffice?
					key.flags = KEY_UP;
					NativeKey(key);
				}
			case SDL_MOUSEMOTION:
				if (mouseDown) {
					TouchInput input;
					input.x = mx;
					input.y = my;
					input.flags = TOUCH_MOVE | TOUCH_MOUSE;
					input.id = 0;
					NativeTouch(input);
				}
				break;
			case SDL_MOUSEBUTTONUP:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						mouseDown = false;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_UP | TOUCH_MOUSE;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP);
						NativeKey(key);
					}
					break;
				}
				break;
			default:
#ifndef _WIN32
				if (joystick) {
					joystick->ProcessInput(event);
				}
#endif
				break;
			}
		}
		if (g_QuitRequested)
			break;
		const uint8_t *keys = SDL_GetKeyboardState(NULL);
		UpdateRunLoop();
		if (g_QuitRequested)
			break;
#if !defined(MOBILE_DEVICE)
		if (lastUIState != GetUIState()) {
			lastUIState = GetUIState();
			if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls)
				SDL_ShowCursor(SDL_DISABLE);
			if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen)
				SDL_ShowCursor(SDL_ENABLE);
		}
#endif

		if (framecount % 60 == 0) {
			// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
		}

#ifdef USING_EGL
		eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
		if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0) {
			SDL_GL_SwapWindow(g_Screen);
			lastT = t;
		}
#endif

		ToggleFullScreenIfFlagSet();
		time_update();
		t = time_now();
		framecount++;
	}
#ifndef _WIN32
	delete joystick;
#endif
	NativeShutdownGraphics();
	graphicsContext->Shutdown();
	NativeShutdown();
	delete graphicsContext;
	// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
	// The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifndef MOBILE_DEVICE
	exit(0);
#endif
	SDL_PauseAudio(1);
	SDL_CloseAudio();
#ifdef USING_EGL
	EGL_Close();
#endif
	SDL_GL_DeleteContext(glContext);
	SDL_Quit();
#if PPSSPP_PLATFORM(RPI)
	bcm_host_deinit();
#endif

	exit(0);
	return 0;
}