File diff r24877:41f1a39844df → r24878:fb3a0559b42f
src/video/win32_v.cpp
Show inline comments
 
@@ -43,13 +43,12 @@
 
static struct {
 
	void *buffer_bits;    ///< Internal rendering buffer.
 
	int width;            ///< Width in pixels of our display surface.
 
	int height;           ///< Height in pixels of our display surface.
 
	int width_org;        ///< Original monitor resolution width, before we changed it.
 
	int height_org;       ///< Original monitor resolution height, before we changed it.
 
	bool fullscreen;      ///< Whether to use (true) fullscreen mode.
 
	bool has_focus;       ///< Does our window have system focus?
 
	bool running;         ///< Is the main loop running?
 
} _wnd;
 

	
 
bool _window_maximize;
 
static Dimension _bck_resolution;
 
@@ -139,25 +138,32 @@ static uint MapWindowsKey(uint sym)
 
	if (GetAsyncKeyState(VK_SHIFT)   < 0) key |= WKC_SHIFT;
 
	if (GetAsyncKeyState(VK_CONTROL) < 0) key |= WKC_CTRL;
 
	if (GetAsyncKeyState(VK_MENU)    < 0) key |= WKC_ALT;
 
	return key;
 
}
 

	
 
/** Colour depth to use for fullscreen display modes. */
 
uint8 VideoDriver_Win32Base::GetFullscreenBpp()
 
{
 
	/* Check modes for the relevant fullscreen bpp */
 
	return _support8bpp != S8BPP_HARDWARE ? 32 : BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 
}
 

	
 
/**
 
 * Instantiate a new window.
 
 * @param full_screen Whether to make a full screen window or not.
 
 * @return True if the window could be created.
 
 */
 
bool VideoDriver_Win32Base::MakeWindow(bool full_screen)
 
{
 
	/* full_screen is whether the new window should be fullscreen,
 
	 * _wnd.fullscreen is whether the current window is. */
 
	_fullscreen = full_screen;
 

	
 
	/* recreate window? */
 
	if ((full_screen || _wnd.fullscreen) && this->main_wnd) {
 
	if ((full_screen || this->fullscreen) && this->main_wnd) {
 
		DestroyWindow(this->main_wnd);
 
		this->main_wnd = 0;
 
	}
 

	
 
	if (full_screen) {
 
		DEVMODE settings;
 
@@ -165,19 +171,18 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
		memset(&settings, 0, sizeof(settings));
 
		settings.dmSize = sizeof(settings);
 
		settings.dmFields =
 
			DM_BITSPERPEL |
 
			DM_PELSWIDTH |
 
			DM_PELSHEIGHT;
 
		settings.dmBitsPerPel = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 
		settings.dmBitsPerPel = this->GetFullscreenBpp();
 
		settings.dmPelsWidth  = _wnd.width_org;
 
		settings.dmPelsHeight = _wnd.height_org;
 

	
 
		/* Check for 8 bpp support. */
 
		if (settings.dmBitsPerPel == 8 &&
 
				(_support8bpp != S8BPP_HARDWARE || ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL)) {
 
		if (settings.dmBitsPerPel == 8 && ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL) {
 
			settings.dmBitsPerPel = 32;
 
		}
 

	
 
		/* Test fullscreen with current resolution, if it fails use desktop resolution. */
 
		if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL) {
 
			RECT r;
 
@@ -190,13 +195,13 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
		}
 

	
 
		if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
 
			this->MakeWindow(false);  // don't care about the result
 
			return false;  // the request failed
 
		}
 
	} else if (_wnd.fullscreen) {
 
	} else if (this->fullscreen) {
 
		/* restore display? */
 
		ChangeDisplaySettings(nullptr, 0);
 
		/* restore the resolution */
 
		_wnd.width = _bck_resolution.width;
 
		_wnd.height = _bck_resolution.height;
 
	}
 
@@ -204,14 +209,14 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
	{
 
		RECT r;
 
		DWORD style, showstyle;
 
		int w, h;
 

	
 
		showstyle = SW_SHOWNORMAL;
 
		_wnd.fullscreen = full_screen;
 
		if (_wnd.fullscreen) {
 
		this->fullscreen = full_screen;
 
		if (this->fullscreen) {
 
			style = WS_POPUP;
 
			SetRect(&r, 0, 0, _wnd.width_org, _wnd.height_org);
 
		} else {
 
			style = WS_OVERLAPPEDWINDOW;
 
			/* On window creation, check if we were in maximize mode before */
 
			if (_window_maximize) showstyle = SW_SHOWMAXIMIZED;
 
@@ -658,13 +663,13 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, U
 
		}
 

	
 
		case WM_SYSKEYDOWN: // user presses F10 or Alt, both activating the title-menu
 
			switch (wParam) {
 
				case VK_RETURN:
 
				case 'F': // Full Screen on ALT + ENTER/F
 
					ToggleFullScreen(!_wnd.fullscreen);
 
					ToggleFullScreen(!video_driver->fullscreen);
 
					return 0;
 

	
 
				case VK_MENU: // Just ALT
 
					return 0; // do nothing
 

	
 
				case VK_F10: // F10, ignore activation of menu
 
@@ -777,13 +782,13 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, U
 
		case WM_ACTIVATE: {
 
			/* Don't do anything if we are closing openttd */
 
			if (_exit_game) break;
 

	
 
			bool active = (LOWORD(wParam) != WA_INACTIVE);
 
			bool minimized = (HIWORD(wParam) != 0);
 
			if (_wnd.fullscreen) {
 
			if (video_driver->fullscreen) {
 
				if (active && minimized) {
 
					/* Restore the game window */
 
					ShowWindow(hwnd, SW_RESTORE);
 
					video_driver->MakeWindow(true);
 
				} else if (!active && !minimized) {
 
					/* Minimise the window and restore desktop */
 
@@ -833,26 +838,18 @@ static const Dimension default_resolutio
 
	{ 1400, 1050 },
 
	{ 1600, 1200 },
 
	{ 1680, 1050 },
 
	{ 1920, 1200 }
 
};
 

	
 
static void FindResolutions()
 
static void FindResolutions(uint8 bpp)
 
{
 
	uint i;
 
	DEVMODEA dm;
 

	
 
	/* Check modes for the relevant fullscreen bpp */
 
	uint bpp = _support8bpp != S8BPP_HARDWARE ? 32 : BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
 

	
 
	_resolutions.clear();
 

	
 
	/* XXX - EnumDisplaySettingsW crashes with unicows.dll on Windows95
 
	 * Doesn't really matter since we don't pass a string anyways, but still
 
	 * a letdown */
 
	for (i = 0; EnumDisplaySettingsA(nullptr, i, &dm) != 0; i++) {
 
	DEVMODE dm;
 
	for (uint i = 0; EnumDisplaySettings(nullptr, i, &dm) != 0; i++) {
 
		if (dm.dmBitsPerPel != bpp || dm.dmPelsWidth < 640 || dm.dmPelsHeight < 480) continue;
 
		if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(dm.dmPelsWidth, dm.dmPelsHeight)) != _resolutions.end()) continue;
 
		_resolutions.emplace_back(dm.dmPelsWidth, dm.dmPelsHeight);
 
	}
 

	
 
	/* We have found no resolutions, show the default list */
 
@@ -860,12 +857,35 @@ static void FindResolutions()
 
		_resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions));
 
	}
 

	
 
	SortResolutions();
 
}
 

	
 
void VideoDriver_Win32Base::Initialize()
 
{
 
	this->UpdateAutoResolution();
 

	
 
	memset(&_wnd, 0, sizeof(_wnd));
 

	
 
	RegisterWndClass();
 
	FindResolutions(this->GetFullscreenBpp());
 

	
 
	/* fullscreen uses those */
 
	_wnd.width  = _wnd.width_org  = _cur_resolution.width;
 
	_wnd.height = _wnd.height_org = _cur_resolution.height;
 

	
 
	DEBUG(driver, 2, "Resolution for display: %ux%u", _cur_resolution.width, _cur_resolution.height);
 
}
 

	
 
void VideoDriver_Win32Base::Stop()
 
{
 
	DestroyWindow(this->main_wnd);
 

	
 
	if (this->fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
}
 
void VideoDriver_Win32Base::MakeDirty(int left, int top, int width, int height)
 
{
 
	Rect r = {left, top, left + width, top + height};
 
	_dirty_rect = BoundingRect(_dirty_rect, r);
 
}
 

	
 
@@ -1106,28 +1126,15 @@ void VideoDriver_Win32Base::UnlockVideoB
 
static FVideoDriver_Win32GDI iFVideoDriver_Win32GDI;
 

	
 
const char *VideoDriver_Win32GDI::Start(const StringList &param)
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
 

	
 
	this->UpdateAutoResolution();
 

	
 
	memset(&_wnd, 0, sizeof(_wnd));
 

	
 
	RegisterWndClass();
 
	this->Initialize();
 

	
 
	this->MakePalette();
 

	
 
	FindResolutions();
 

	
 
	DEBUG(driver, 2, "Resolution for display: %ux%u", _cur_resolution.width, _cur_resolution.height);
 

	
 
	/* fullscreen uses those */
 
	_wnd.width_org = _cur_resolution.width;
 
	_wnd.height_org = _cur_resolution.height;
 

	
 
	this->AllocateBackingStore(_cur_resolution.width, _cur_resolution.height);
 
	this->MakeWindow(_fullscreen);
 

	
 
	MarkWholeScreenDirty();
 

	
 
	_draw_threaded = !GetDriverParam(param, "no_threads") && !GetDriverParam(param, "no_thread") && std::thread::hardware_concurrency() > 1;
 
@@ -1136,16 +1143,14 @@ const char *VideoDriver_Win32GDI::Start(
 
}
 

	
 
void VideoDriver_Win32GDI::Stop()
 
{
 
	DeleteObject(this->gdi_palette);
 
	DeleteObject(this->dib_sect);
 
	DestroyWindow(this->main_wnd);
 

	
 
	if (_wnd.fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
	this->VideoDriver_Win32Base::Stop();
 
}
 

	
 
bool VideoDriver_Win32GDI::AllocateBackingStore(int w, int h, bool force)
 
{
 
	uint bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();