示例#1
0
//
// WI_GetHeight
//
// Returns the height of the area that the intermission screen will be
// drawn to. The intermisison screen should be 4:3, except in 320x200 mode.
//
static int WI_GetHeight()
{
	int surface_width = I_GetPrimarySurface()->getWidth();
	int surface_height = I_GetPrimarySurface()->getHeight();

	if (I_IsProtectedResolution(I_GetVideoWidth(), I_GetVideoHeight()))
		return surface_height;

	if (surface_width * 3 >= surface_height * 4)
		return surface_height;
	else
		return surface_width * 3 / 4;
}
示例#2
0
//
// SDLMouse::center
//
// Moves the mouse to the center of the screen to prevent absolute position
// methods from causing problems when the mouse is near the screen edges.
//
void SDLMouse::center()
{
	// warp the mouse to the center of the screen
	SDL_WarpMouse(I_GetVideoWidth() / 2, I_GetVideoHeight() / 2);

	// SDL_WarpMouse inserts a mouse event to warp the cursor to the center of the screen
	// we need to filter out this event
	SDL_PumpEvents();
	int num_events = SDL_PeepEvents(mEvents, MAX_EVENTS, SDL_GETEVENT, SDL_MOUSEMOTIONMASK);

	for (int i = 0; i < num_events; i++)
	{
		SDL_Event* sdl_ev = &mEvents[i];
		if (sdl_ev->type != SDL_MOUSEMOTION ||
			sdl_ev->motion.x != I_GetVideoWidth() / 2 ||
			sdl_ev->motion.y != I_GetVideoHeight() / 2)
		{
			// this event is not the event caused by SDL_WarpMouse so add it back
			// to the event queue
			SDL_PushEvent(sdl_ev);
		}
	}
}
示例#3
0
//
// ISDL12MouseInputDevice::center
//
// Moves the mouse to the center of the screen to prevent absolute position
// methods from causing problems when the mouse is near the screen edges.
//
void ISDL12MouseInputDevice::center()
{
	if (active())
	{
		const int centerx = I_GetVideoWidth() / 2, centery = I_GetVideoHeight() / 2;
		int prevx, prevy;

		// get the x and y mouse position prior to centering it
		SDL_GetMouseState(&prevx, &prevy);

		// warp the mouse to the center of the screen
		SDL_WarpMouse(centerx, centery);

		// SDL_WarpMouse inserts a mouse event to warp the cursor to the center of the screen.
		// Filter out this mouse event by reading all of the mouse events in SDL'S queue and
		// re-insert any mouse events that were not inserted by SDL_WarpMouse.
		SDL_PumpEvents();

		// Retrieve chunks of up to 1024 events from SDL
		const int max_events = 1024;
		int num_events = 0;
		SDL_Event sdl_events[max_events];

		num_events = SDL_PeepEvents(sdl_events, max_events, SDL_GETEVENT, SDL_MOUSEMOTIONMASK);
		assert(num_events < max_events);
		for (int i = 0; i < num_events; i++)
		{
			SDL_Event& sdl_ev = sdl_events[i];
			assert(sdl_ev.type == SDL_MOUSEMOTION);

			// drop the events caused by SDL_WarpMouse
			if (sdl_ev.motion.x == centerx && sdl_ev.motion.y == centery && 
				sdl_ev.motion.xrel == centerx - prevx && sdl_ev.motion.yrel == centery - prevy)
				continue;

			// this event is not the event caused by SDL_WarpMouse so add it back
			// to the event queue
			SDL_PushEvent(&sdl_ev);
		}
	}
}
示例#4
0
//
// I_SetVideoMode
//
// Main function to set the video mode at the hardware level.
//
void I_SetVideoMode(int width, int height, int surface_bpp, bool fullscreen, bool vsync)
{
	// ensure the requested mode is valid
	IVideoMode desired_mode(width, height, surface_bpp, fullscreen);
	IVideoMode mode = I_ValidateVideoMode(&desired_mode);
	assert(mode.isValid());

	IWindow* window = I_GetWindow();

	window->setMode(mode.getWidth(), mode.getHeight(), mode.getBitsPerPixel(), mode.isFullScreen(), vsync);
	I_ForceUpdateGrab();

	// [SL] 2011-11-30 - Prevent the player's view angle from moving
	I_FlushInput();
		
	// Set up the primary and emulated surfaces
	primary_surface = window->getPrimarySurface();
	int surface_width = primary_surface->getWidth(), surface_height = primary_surface->getHeight();

	I_FreeSurface(converted_surface);
	converted_surface = NULL;
	I_FreeSurface(matted_surface);
	matted_surface = NULL;
	I_FreeSurface(emulated_surface);
	emulated_surface = NULL;

	// Handle a requested 8bpp surface when the video capabilities only support 32bpp
	if (surface_bpp != mode.getBitsPerPixel())
	{
		const PixelFormat* format = surface_bpp == 8 ? I_Get8bppPixelFormat() : I_Get32bppPixelFormat();
		converted_surface = new IWindowSurface(surface_width, surface_height, format);
		primary_surface = converted_surface;
	}

	// clear window's surface to all black;
	primary_surface->lock();
	primary_surface->clear();
	primary_surface->unlock();

	// [SL] Determine the size of the matted surface.
	// A matted surface will be used if pillar-boxing or letter-boxing are used, or
	// if vid_320x200/vid_640x400 are being used in a wide-screen video mode, or
	// if vid_overscan is used to create a matte around the entire screen.
	//
	// Only vid_overscan creates a matted surface if the video mode is 320x200 or 640x400.
	//

	if (vid_overscan < 1.0f)
	{
		surface_width *= vid_overscan;
		surface_height *= vid_overscan;
	}

	if (!I_IsProtectedResolution(I_GetVideoWidth(), I_GetVideoHeight()))
	{
		if (vid_320x200 || vid_640x400)
			surface_width = surface_height * 4 / 3;
		else if (V_UsePillarBox())
			surface_width = surface_height * 4 / 3;
		else if (V_UseLetterBox())
			surface_height = surface_width * 9 / 16;
	}

	// Ensure matted surface dimensions are sane and sanitized.
	surface_width = clamp<uint16_t>(surface_width, 320, MAXWIDTH);
	surface_height = clamp<uint16_t>(surface_height, 200, MAXHEIGHT);
	
	// Anything wider than 16:9 starts to look more distorted and provides even more advantage, so for now
	// if the monitor aspect ratio is wider than 16:9, clamp it to that (TODO: Aspect ratio selection)
	if (surface_width / surface_height > 16 / 9)
		surface_width = (surface_height * 16) / 9;

	// Is matting being used? Create matted_surface based on the primary_surface.
	if (surface_width != primary_surface->getWidth() ||
		surface_height != primary_surface->getHeight())
	{
		matted_surface = new IWindowSurface(primary_surface, surface_width, surface_height);
		primary_surface = matted_surface;
	}

	// Create emulated_surface for emulating low resolution modes.
	if (vid_320x200)
	{
		emulated_surface = new IWindowSurface(320, 200, primary_surface->getPixelFormat());
		emulated_surface->clear();
	}
	else if (vid_640x400)
	{
		emulated_surface = new IWindowSurface(640, 400, primary_surface->getPixelFormat());
		emulated_surface->clear();
	}

	screen = primary_surface->getDefaultCanvas();

	assert(I_VideoInitialized());

	if (*window->getVideoMode() != desired_mode)
		DPrintf("I_SetVideoMode: could not set video mode to %s. Using %s instead.\n",
						I_GetVideoModeString(&desired_mode).c_str(),
						I_GetVideoModeString(window->getVideoMode()).c_str());
	else
		DPrintf("I_SetVideoMode: set video mode to %s\n",
					I_GetVideoModeString(window->getVideoMode()).c_str());

	const argb_t* palette = V_GetGamePalette()->colors;
	if (matted_surface)
		matted_surface->setPalette(palette);
	if (emulated_surface)
		emulated_surface->setPalette(palette);
	if (converted_surface)
		converted_surface->setPalette(palette);

	// handle the -noblit parameter when playing a LMP demo
	if (noblit)
		window->disableRefresh();
	else
		window->enableRefresh();
}