if (gwin->get_win()) scale = Log2( gwin->get_win()->get_scale() );
static void Handle_event(SDL_Event& event);/* *	Initialize and create main window. */static void Init	(	){	Uint32 init_flags = SDL_INIT_VIDEO|SDL_INIT_TIMER;#ifdef NO_SDL_PARACHUTE	init_flags |= SDL_INIT_NOPARACHUTE;#endif	if (SDL_Init(init_flags) < 0)	{		cerr << "Unable to initialize SDL: " << SDL_GetError() << endl;		exit(-1);	}	std::atexit(SDL_Quit);		SDL_SysWMinfo info;		// Get system info.        SDL_GetWMInfo(&info);#ifdef XWIN					// Want drag-and-drop events.	SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);#endif	SDL_ShowCursor(0);	SDL_VERSION(&info.version);	int w, h, sc, sclr;	// Default resolution is 320x200 with 2x scaling	w = 320;	h = 200;	sc = 2;	sclr = Image_window::SaI;	int sw, sh, scaleval;	string gr, gg, gb, scaler;	config->value("config/video/width", sw, w);	config->value("config/video/height", sh, h);	config->value("config/video/scale_method", scaler, "---");	config->value("config/video/gamma/red", gr, "1.0");	config->value("config/video/gamma/green", gg, "1.0");	config->value("config/video/gamma/blue", gb, "1.0");	config->value("config/video/scale", scaleval, sc);	if (scaler == "bilinear") sclr = Image_window::bilinear;	else if (scaler == "interlaced") sclr = Image_window::interlaced;	else if (scaler == "point") sclr = Image_window::point;	else if (scaler == "SuperEagle") sclr = Image_window::SuperEagle;	else config->set("config/video/scale_method","2xSaI",true);	Image_window8::set_gamma(atof(gr.c_str()), atof(gg.c_str()), atof(gb.c_str()));		gwin = new Game_window(sw, sh, scaleval, sclr);	current_res = find_resolution(sw, sh, scaleval);	Audio::get_ptr();	string disable_fades;	config->value("config/video/disable_fades", disable_fades, "no");	if (disable_fades == "yes")		gwin->set_fades_enabled(false);	if (arg_buildmap >= 0)		BuildGameMap();	SDL_SetEventFilter(0);	// Show the banner	ExultMenu exult_menu(gwin);	Exult_Game mygame = exult_menu.run();	Game::create_game(mygame);	string yn;	gwin->init_files();					// Skip splash screen?	config->value("config/gameplay/skip_splash", yn, "no");	if(yn == "no") 		game->play_intro();	game->show_menu();//	SDL_SetEventFilter(Filter_intro_events);	gwin->setup_game();		// This will start the scene.					// Get scale factor for mouse.	if (gwin->get_win())		scale = Log2( gwin->get_win()->get_scale() );#ifdef XWIN        SDL_GetWMInfo(&info);        xfd = ConnectionNumber(info.info.x11.display);	Server_init();			// Initialize server (for map-editor).	xdnd = new Xdnd(info.info.x11.display, info.info.x11.wmwindow,				info.info.x11.window, Drop_dragged_shape);#endif}/* *	Play game. */static int Play(){	do	{		quitting_time = 0;		Handle_events(&quitting_time);		if( quitting_time == 2 )			{			Mouse::mouse->hide();	// Turn off mouse.			gwin->read();	// Restart			gwin->setup_game();			}	}	while (quitting_time == 2);	delete gwin;	delete Mouse::mouse;cerr << "About to delete Audio" << endl;cerr.flush();	delete Audio::get_ptr();	// Follow not this pointer, now, for					// that way lies madness.cerr << "Deleted Audio" << endl;cerr.flush();	delete config;	return (0);}/* *	Statics used below: */static bool show_mouse = true;		// display mouse in main loop?static bool dragging = false;		// Object or gump being moved.static bool dragged = false;		// Flag for when obj. moved.const int slow_speed = 166, medium_speed = 100, fast_speed = 50;static int avatar_speed = slow_speed;	// Avatar speed (frame delay in					//    1/1000 secs.)#if 0/* *	Filter out events during the intro. sequence. */static int Filter_intro_events	(	const SDL_Event *event	)	{	if (gwin->get_mode() == Game_window::conversation)		{		SDL_SetEventFilter(0);	// Intro. conversation started.		show_mouse = true;		return 1;		}	if (gwin->get_usecode()->get_global_flag(					Usecode_machine::did_first_scene))		{		SDL_SetEventFilter(0);	// Intro. is done.		show_mouse = true;		return 0;		}	if (gwin->get_mode() == Game_window::gump)		return 1;		// Dialog to quit.	switch (event->type)		{	case SDL_MOUSEBUTTONUP:	case SDL_MOUSEBUTTONDOWN:	case SDL_MOUSEMOTION:	case SDL_KEYDOWN:	case SDL_KEYUP:		return 0;		// The intro. is running.		}	return (1);	}#endif/* *	Handle events until a flag is set. */static void Handle_events	(	unsigned char *stop	)	{	uint32 last_repaint = 0;	// For insuring animation repaints.	uint32 last_rotate = 0;	/*	 *	Main event loop.	 */	while (!*stop)		{#ifdef XWIN		Server_delay();		// Handle requests.#else		Delay();		// Wait a fraction of a second.#endif		Mouse::mouse->hide();		// Turn off mouse.		Mouse::mouse_update = false;		SDL_Event event;		while (!*stop && SDL_PollEvent(&event))			Handle_event(event);					// Get current time.		uint32 ticks = SDL_GetTicks();					// Animate unless dormant.		if (gwin->have_focus() && !dragging)			gwin->get_tqueue()->activate(ticks);					// Show animation every 1/20 sec.		if (ticks > last_repaint + 50 || gwin->was_painted())					// This avoids jumpy walking:			{			gwin->paint_dirty();			last_repaint = ticks;			int x, y;// Check for 'stuck' Avatar.			if (!gwin->is_moving() &&			    !gwin->was_teleported())				{				int ms = SDL_GetMouseState(&x, &y);				if ((SDL_BUTTON(3) & ms) &&						(Game::get_game_type() == SERPENT_ISLE ||						gwin->get_usecode()->get_global_flag(							Usecode_machine::did_first_scene)))					gwin->start_actor(x >> scale, 							  y >> scale, 							  avatar_speed);				}			}		if (show_mouse)			Mouse::mouse->show();	// Re-display mouse.					// Rotate less often if scaling.		if (ticks > last_rotate + (100<<scale))			{		// (Blits in simulated 8-bit mode.)			gwin->get_win()->rotate_colors(0xf0, 4, 0);			gwin->get_win()->rotate_colors(0xe8, 8, 0);			gwin->get_win()->rotate_colors(0xe0, 8, 1);			last_rotate = ticks;			if (scale)	// Scaled requires explicit blit.				gwin->set_painted();			}		if (!gwin->show() &&	// Blit to screen if necessary.		    Mouse::mouse_update)	// If not, did mouse change?			Mouse::mouse->blit_dirty();		}	}/* *	Set mouse and speed. */void Set_mouse_and_speed	(	int mousex, int mousey		// Physical mouse location.	)	{	int ax, ay;			// Get Avatar/barge screen location.	Barge_object *barge = gwin->get_moving_barge();	if (barge)		{			// Use center of barge.		gwin->get_shape_location(barge, ax, ay);		ax -= barge->get_xtiles()*(c_tilesize/2);		ay -= barge->get_ytiles()*(c_tilesize/2);		}	else						gwin->get_shape_location(gwin->get_main_actor(), ax, ay);	int dy = ay - (mousey >> scale), dx = (mousex >> scale) - ax;	Direction dir = Get_direction(dy, dx);	int dist = dy*dy + dx*dx;	if (dist < 40*40)		{		if(gwin->in_combat())			Mouse::mouse->set_short_combat_arrow(dir);		else			Mouse::mouse->set_short_arrow(dir);		avatar_speed = slow_speed;		}	else if (dist < 75*75)		{		if(gwin->in_combat())			Mouse::mouse->set_medium_combat_arrow(dir);		else			Mouse::mouse->set_medium_arrow(dir);		avatar_speed = medium_speed;		}	else		{		// No long arrow in combat: use medium		if(gwin->in_combat())			Mouse::mouse->set_medium_combat_arrow(dir);		else			Mouse::mouse->set_long_arrow(dir);		avatar_speed = fast_speed;		}	}/* *	Handle an event.  This should work for all platforms, and should only *	be called in 'normal' and 'gump' modes. */static void Handle_event	(	SDL_Event& event	)	{					// For detecting double-clicks.	static uint32 last_b1_click = 0, last_b3_click = 0;	//cout << "Event " << (int) event.type << " received"<<endl;	switch (event.type)		{	case SDL_MOUSEBUTTONDOWN:		if (event.button.button == 1)			{			dragging = gwin->start_dragging(					event.button.x >> scale,					event.button.y >> scale);			//Mouse::mouse->set_shape(Mouse::hand);			dragged = false;			}					// Move sprite toward mouse					//  when right button pressed.		if (event.button.button == 3 && !gwin->showing_gumps())			{		// Try removing old queue entry.			gwin->get_tqueue()->remove(gwin->get_main_actor());			gwin->start_actor(event.button.x >> scale, 				event.button.y >> scale, avatar_speed);			}		break;	case SDL_MOUSEBUTTONUP:		if (event.button.button == 3)			{			uint32 curtime = SDL_GetTicks();					// Last click within .5 secs?			if (curtime - last_b3_click < 500)				gwin->start_actor_along_path(					event.button.x >> scale, 					event.button.y >> scale, avatar_speed);			else				gwin->stop_actor();			last_b3_click = curtime;			}		else if (event.button.button == 1)			{			uint32 curtime = SDL_GetTicks();			bool click_handled = false;			if (dragging) {				click_handled = gwin->drop_dragged(					event.button.x >> scale, 					event.button.y >> scale, dragged);			}					// Last click within .5 secs?			if (curtime - last_b1_click < 500)				{				dragging = false;				gwin->double_clicked(event.button.x >> scale, 						event.button.y >> scale);				if (gwin->showing_gumps() && gwin->find_gump(event.motion.x >> scale, 						event.motion.y >> scale))					Mouse::mouse->set_shape(Mouse::hand);				break;				}			last_b1_click = curtime;			if (!click_handled)					// Identify item(s) clicked on.				gwin->show_items(event.button.x >> scale, 						event.button.y >> scale);			dragging = false;			}		break;	case SDL_MOUSEMOTION:		{		Mouse::mouse->move(event.motion.x >> scale, 						event.motion.y >> scale);		if (!(gwin->showing_gumps() && gwin->find_gump(event.motion.x >> scale, 						event.motion.y >> scale)) && !dragging)			Set_mouse_and_speed(event.motion.x, event.motion.y);		else if ((gwin->showing_gumps() && gwin->find_gump(event.motion.x >> scale, 						event.motion.y >> scale)) || dragging)					Mouse::mouse->set_shape(Mouse::hand);		Mouse::mouse_update = true;	// Need to blit mouse.					// Dragging with left button?		if (event.motion.state & SDL_BUTTON(1))			dragged = gwin->drag(event.motion.x >> scale, 						event.motion.y >> scale);					// Dragging with right?		if ((event.motion.state & SDL_BUTTON(3)) &&					// But not right after teleport.		    !gwin->was_teleported())			gwin->start_actor(event.motion.x >> scale, 					event.motion.y >> scale, avatar_speed);		break;		}	case SDL_ACTIVEEVENT:					// Get scale factor for mouse.		scale = gwin->get_win()->get_scale() == 2 ? 1 : 0;		if (event.active.state & SDL_APPMOUSEFOCUS)			{			if (event.active.gain)				{				int x, y;				SDL_GetMouseState(&x, &y);				Mouse::mouse->set_location(x >> scale, y >> scale);				}			gwin->set_painted();			}		if (event.active.state & SDL_APPINPUTFOCUS)			{			if (event.active.gain)				gwin->get_focus();			else				gwin->lose_focus();			}#if 0		if (event.active.state & SDL_APPACTIVE)					// Became active.			if (event.active.gain)				gwin->init_actors();#endif		break;#if 0	case ConfigureNotify:		// Resize.		gwin->resized(event.xconfigure.window,			event.xconfigure.width, event.xconfigure.height);		break;#endif	case SDL_QUIT:		Okay_to_quit();		break;	case SDL_KEYDOWN:		// Keystroke.			//+++++++++TESTING://		Audio::get_ptr()->playwave("/home/jeff/exult/test.wav", false);		keybinder->HandleEvent(event);		break;#ifdef XWIN	case SDL_SYSWMEVENT:		{		XEvent& ev = event.syswm.msg->event.xevent;		if (ev.type == ClientMessage)			xdnd->client_msg((XClientMessageEvent&) ev);		else if (ev.type == SelectionNotify)			xdnd->select_msg((XSelectionEvent&) ev);		break;		}#endif#if 0//#ifdef WIN32	case SDL_SYSWMEVENT://		printf("SYSWMEVENT received, %x\n", event.syswm.msg->msg);		if (event.syswm.msg->msg == MM_MCINOTIFY) {#if DEBUG			cerr << "MM_MCINOTIFY message received"<<endl;#endif			((Windows_MCI*)(Audio::get_ptr()->get_midi()))->callback(event.syswm.msg->wParam, 							event.syswm.msg->hwnd);		}		break;#endif		}	}