Ejemplo n.º 1
0
static bool CreateMainSurface(uint w, uint h)
{
	SDL_Surface *newscreen, *icon;
	char caption[50];
	int bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();

	GetAvailableVideoMode(&w, &h);

	DEBUG(driver, 1, "SDL: using mode %ux%ux%d", w, h, bpp);

	if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals");

	/* Give the application an icon */
	icon = SDL_CALL SDL_LoadBMP(ICON_DIR PATHSEP "openttd.32.bmp");
	if (icon != NULL) {
		/* Get the colourkey, which will be magenta */
		uint32 rgbmap = SDL_CALL SDL_MapRGB(icon->format, 255, 0, 255);

		SDL_CALL SDL_SetColorKey(icon, SDL_SRCCOLORKEY, rgbmap);
		SDL_CALL SDL_WM_SetIcon(icon, NULL);
		SDL_CALL SDL_FreeSurface(icon);
	}

	/* DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK */
	newscreen = SDL_CALL SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE | SDL_HWPALETTE | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE));
	if (newscreen == NULL) {
		DEBUG(driver, 0, "SDL: Couldn't allocate a window to draw on");
		return false;
	}

	/* Delay drawing for this cycle; the next cycle will redraw the whole screen */
	_num_dirty_rects = 0;

	_screen.width = newscreen->w;
	_screen.height = newscreen->h;
	_screen.pitch = newscreen->pitch / (bpp / 8);
	_screen.dst_ptr = newscreen->pixels;
	_sdl_screen = newscreen;

	BlitterFactoryBase::GetCurrentBlitter()->PostResize();

	InitPalette();

	snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
	SDL_CALL SDL_WM_SetCaption(caption, caption);
	SDL_CALL SDL_ShowCursor(0);

	GameSizeChanged();

	return true;
}
Ejemplo n.º 2
0
static bool CreateMainSurface(uint w, uint h)
{
	int bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();
	if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals");
	set_color_depth(bpp);

	GetAvailableVideoMode(&w, &h);
	if (set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, w, h, 0, 0) != 0) {
		DEBUG(driver, 0, "Allegro: Couldn't allocate a window to draw on '%s'", allegro_error);
		return false;
	}

	/* The size of the screen might be bigger than the part we can actually draw on!
	 * So calculate the size based on the top, bottom, left and right */
	_allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct);
	_screen.width = _allegro_screen->w;
	_screen.height = _allegro_screen->h;
	_screen.pitch = ((byte*)screen->line[1] - (byte*)screen->line[0]) / (bpp / 8);
	_screen.dst_ptr = _allegro_screen->line[0];

	/* Initialise the screen so we don't blit garbage to the screen */
	memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);

	/* Set the mouse at the place where we expect it */
	poll_mouse();
	_cursor.pos.x = mouse_x;
	_cursor.pos.y = mouse_y;

	BlitterFactoryBase::GetCurrentBlitter()->PostResize();

	InitPalette();

	char caption[32];
	snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
	set_window_title(caption);

	enable_hardware_cursor();
	select_mouse_cursor(MOUSE_CURSOR_ARROW);
	show_mouse(_allegro_screen);

	GameSizeChanged();

	return true;
}
Ejemplo n.º 3
0
bool VideoDriver_SDL::CreateMainSurface(uint w, uint h)
{
	SDL_Surface *newscreen, *icon;
	char caption[50];
	int bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();
	bool want_hwpalette;

	GetAvailableVideoMode(&w, &h);

	DEBUG(driver, 1, "SDL: using mode %ux%ux%d", w, h, bpp);

	if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals");

	char icon_path[MAX_PATH];
	if (FioFindFullPath(icon_path, lengthof(icon_path), BASESET_DIR, "openttd.32.bmp") != NULL) {
		/* Give the application an icon */
		icon = SDL_CALL SDL_LoadBMP(icon_path);
		if (icon != NULL) {
			/* Get the colourkey, which will be magenta */
			uint32 rgbmap = SDL_CALL SDL_MapRGB(icon->format, 255, 0, 255);

			SDL_CALL SDL_SetColorKey(icon, SDL_SRCCOLORKEY, rgbmap);
			SDL_CALL SDL_WM_SetIcon(icon, NULL);
			SDL_CALL SDL_FreeSurface(icon);
		}
	}

	if (_use_hwpalette == 2) {
		/* Default is to autodetect when to use SDL_HWPALETTE.
		 * In this case, SDL_HWPALETTE is only used for 8bpp
		 * blitters in fullscreen.
		 *
		 * When using an 8bpp blitter on a 8bpp system in
		 * windowed mode with SDL_HWPALETTE, OpenTTD will claim
		 * the system palette, making all other applications
		 * get the wrong colours. In this case, we're better of
		 * trying to approximate the colors we need using system
		 * colors, using a shadow surface (see below).
		 *
		 * On a 32bpp system, SDL_HWPALETTE is ignored, so it
		 * doesn't matter what we do.
		 *
		 * When using a 32bpp blitter on a 8bpp system, setting
		 * SDL_HWPALETTE messes up rendering (at least on X11),
		 * so we don't do that. In this case, SDL takes care of
		 * color approximation using its own shadow surface
		 * (which we can't force in 8bpp on 8bpp mode,
		 * unfortunately).
		 */
		want_hwpalette = (bpp == 8 && _fullscreen);
	} else {
		/* User specified a value manually */
		want_hwpalette = _use_hwpalette;
	}

	if (want_hwpalette) DEBUG(driver, 1, "SDL: requesting hardware palete");

	/* Free any previously allocated shadow surface */
	if (_sdl_screen != NULL && _sdl_screen != _sdl_realscreen) SDL_CALL SDL_FreeSurface(_sdl_screen);

	if (_sdl_realscreen != NULL) {
		if (_requested_hwpalette != want_hwpalette) {
			/* SDL (at least the X11 driver), reuses the
			 * same window and palette settings when the bpp
			 * (and a few flags) are the same. Since we need
			 * to hwpalette value to change (in particular
			 * when switching between fullscreen and
			 * windowed), we restart the entire video
			 * subsystem to force creating a new window.
			 */
			DEBUG(driver, 0, "SDL: Restarting SDL video subsystem, to force hwpalette change");
			SDL_CALL SDL_QuitSubSystem(SDL_INIT_VIDEO);
			SDL_CALL SDL_InitSubSystem(SDL_INIT_VIDEO);
			ClaimMousePointer();
			SetupKeyboard();
		}
	}
	/* Remember if we wanted a hwpalette. We can't reliably query
	 * SDL for the SDL_HWPALETTE flag, since it might get set even
	 * though we didn't ask for it (when SDL creates a shadow
	 * surface, for example). */
	_requested_hwpalette = want_hwpalette;

	/* DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK */
	newscreen = SDL_CALL SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE | (want_hwpalette ? SDL_HWPALETTE : 0) | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE));
	if (newscreen == NULL) {
		DEBUG(driver, 0, "SDL: Couldn't allocate a window to draw on");
		return false;
	}
	_sdl_realscreen = newscreen;

	if (bpp == 8 && (_sdl_realscreen->flags & SDL_HWPALETTE) != SDL_HWPALETTE) {
		/* Using an 8bpp blitter, if we didn't get a hardware
		 * palette (most likely because we didn't request one,
		 * see above), we'll have to set up a shadow surface to
		 * render on.
		 *
		 * Our palette will be applied to this shadow surface,
		 * while the real screen surface will use the shared
		 * system palette (which will partly contain our colors,
		 * but most likely will not have enough free color cells
		 * for all of our colors). SDL can use these two
		 * palettes at blit time to approximate colors used in
		 * the shadow surface using system colors automatically.
		 *
		 * Note that when using an 8bpp blitter on a 32bpp
		 * system, SDL will create an internal shadow surface.
		 * This shadow surface will have SDL_HWPALLETE set, so
		 * we won't create a second shadow surface in this case.
		 */
		DEBUG(driver, 1, "SDL: using shadow surface");
		newscreen = SDL_CALL SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, bpp, 0, 0, 0, 0);
		if (newscreen == NULL) {
			DEBUG(driver, 0, "SDL: Couldn't allocate a shadow surface to draw on");
			return false;
		}
	}

	/* Delay drawing for this cycle; the next cycle will redraw the whole screen */
	_num_dirty_rects = 0;

	_screen.width = newscreen->w;
	_screen.height = newscreen->h;
	_screen.pitch = newscreen->pitch / (bpp / 8);
	_screen.dst_ptr = newscreen->pixels;
	_sdl_screen = newscreen;

	/* When in full screen, we will always have the mouse cursor
	 * within the window, even though SDL does not give us the
	 * appropriate event to know this. */
	if (_fullscreen) _cursor.in_window = true;

	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
	blitter->PostResize();

	InitPalette();
	switch (blitter->UsePaletteAnimation()) {
		case Blitter::PALETTE_ANIMATION_NONE:
		case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
			UpdatePalette();
			break;

		case Blitter::PALETTE_ANIMATION_BLITTER:
			if (_video_driver != NULL) blitter->PaletteAnimate(_local_palette);
			break;

		default:
			NOT_REACHED();
	}

	snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
	SDL_CALL SDL_WM_SetCaption(caption, caption);

	GameSizeChanged();

	return true;
}