示例#1
0
Win32Video::~Win32Video ()
{
	FreeModes ();

	if (DDraw != NULL)
	{
		if (m_IsFullscreen)
		{
			DDraw->SetCooperativeLevel (NULL, DDSCL_NORMAL);
		}
		DDraw->Release();
		DDraw = NULL;
	}
	if (D3D != NULL)
	{
		D3D->Release();
		D3D = NULL;
	}

	STOPLOG;
}
示例#2
0
void MFDisplay_DestroyDisplay()
{
	MFCALLSTACK;

	if((!gDisplay.windowed) && (originalVidMode != NULL) && xdisplay != NULL && numModes > 1)
	{
		XF86VidModeSwitchToMode(xdisplay, screen, originalVidMode);
	}

	MFRenderer_DestroyDisplay();

	if(sizeHints != NULL)
	{
		XFree(sizeHints);
		sizeHints = NULL;
	}

	if(window != 0)
	{
		XDestroyWindow(xdisplay, window);
		window = 0;
	}

	if(colorMap != 0)
	{
		XFreeColormap(xdisplay, colorMap);
		colorMap = 0L;
	}

	if(xdisplay != NULL)
	{
		XCloseDisplay(xdisplay);
		xdisplay = NULL;
	}

	FreeModes();
}
示例#3
0
void Win32Video::InitDDraw ()
{
	DIRECTDRAWCREATEFUNC directdraw_create;
	LPDIRECTDRAW ddraw1;
	STARTLOG;

	HRESULT dderr;

	// Load the DirectDraw library.
	if ((DDraw_dll = LoadLibraryA ("ddraw.dll")) == NULL)
	{
		I_FatalError ("Could not load ddraw.dll");
	}

	// Obtain an IDirectDraw interface.
	if ((directdraw_create = (DIRECTDRAWCREATEFUNC)GetProcAddress (DDraw_dll, "DirectDrawCreate")) == NULL)
	{
		I_FatalError ("The system file ddraw.dll is missing the DirectDrawCreate export");
	}

	dderr = directdraw_create (NULL, &ddraw1, NULL);

	if (FAILED(dderr))
		I_FatalError ("Could not create DirectDraw object: %08lx", dderr);

	dderr = ddraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DDraw);
	if (FAILED(dderr))
	{
		ddraw1->Release ();
		DDraw = NULL;
		I_FatalError ("Could not initialize IDirectDraw2 interface: %08lx", dderr);
	}

	// Okay, we have the IDirectDraw2 interface now, so we can release the
	// really old-fashioned IDirectDraw one.
	ddraw1->Release ();

	DDraw->SetCooperativeLevel (Window, DDSCL_NORMAL);
	FreeModes ();
	dderr = DDraw->EnumDisplayModes (0, NULL, this, EnumDDModesCB);
	if (FAILED(dderr))
	{
		DDraw->Release ();
		DDraw = NULL;
		I_FatalError ("Could not enumerate display modes: %08lx", dderr);
	}
	if (m_Modes == NULL)
	{
		DDraw->Release ();
		DDraw = NULL;
		I_FatalError ("DirectDraw returned no display modes.\n\n"
					"If you started ZDoom from a fullscreen DOS box, run it from "
					"a DOS window instead. If that does not work, you may need to reboot.");
	}
	if (Args->CheckParm ("-2"))
	{ // Force all modes to be pixel-doubled.
		ScaleModes(1);
	}
	else if (Args->CheckParm ("-4"))
	{ // Force all modes to be pixel-quadrupled.
		ScaleModes(2);
	}
	else
	{
		if (OSPlatform == os_Win95)
		{
			// Windows 95 will let us use Mode X. If we didn't find any linear
			// modes in the loop above, add the Mode X modes here.
			AddMode (320, 200, 8, 200, 0);
			AddMode (320, 240, 8, 240, 0);
		}
		AddLowResModes ();
	}
	AddLetterboxModes ();
}
示例#4
0
bool Win32Video::InitD3D9 ()
{
	DIRECT3DCREATE9FUNC direct3d_create_9;

	if (vid_forceddraw)
	{
		return false;
	}

	// Load the Direct3D 9 library.
	if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL)
	{
		return false;
	}

	// Obtain an IDirect3D interface.
	if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL)
	{
		goto closelib;
	}
	if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL)
	{
		goto closelib;
	}

	// Check that we have at least PS 1.4 available.
	D3DCAPS9 devcaps;
	if (FAILED(D3D->GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &devcaps)))
	{
		goto d3drelease;
	}
	if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104)
	{
		goto d3drelease;
	}
	if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES))
	{
		goto d3drelease;
	}

	// Enumerate available display modes.
	FreeModes ();
	AddD3DModes (D3DFMT_X8R8G8B8);
	AddD3DModes (D3DFMT_R5G6B5);
	if (Args->CheckParm ("-2"))
	{ // Force all modes to be pixel-doubled.
		ScaleModes (1);
	}
	else if (Args->CheckParm ("-4"))
	{ // Force all modes to be pixel-quadrupled.
		ScaleModes (2);
	}
	else
	{
		AddLowResModes ();
	}
	AddLetterboxModes ();
	if (m_Modes == NULL)
	{ // Too bad. We didn't find any modes for D3D9. We probably won't find any
	  // for DDraw either...
		goto d3drelease;
	}
	return true;

d3drelease:
	D3D->Release();
	D3D = NULL;
closelib:
	FreeLibrary (D3D9_dll);
	return false;
}
示例#5
0
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive)
{
	MFCALLSTACK;

	MFZeroMemory(gXKeys, sizeof(gXKeys));
	MFZeroMemory(&gXMouse, sizeof(gXMouse));
	gXMouse.x = -1;

	gDisplay.fullscreenWidth = gDisplay.width = width;
	gDisplay.fullscreenHeight = gDisplay.height = height;
	gDisplay.refreshRate = 0;
	gDisplay.colourDepth = 0; /* Use default.  Chances are, it's something sane */
	gDisplay.windowed = true;
	gDisplay.wide = false;
	gDisplay.progressive = true;

	if(!(xdisplay = XOpenDisplay(NULL)))
	{
		MFDebug_Error("Unable to open display");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	screen = DefaultScreen(xdisplay);
	rootWindow = RootWindow(xdisplay, screen);

	// build our internal list of available video modes
	GetModes(&modes, !gDisplay.windowed);
	while(!FindMode(modes, width, height))
	{
		if(!gDisplay.windowed)
		{
			// no fullscreen mode, try windowed mode instead
			MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode");

			gDisplay.windowed = true;

			FreeModes();
			GetModes(&modes, false);
		}
		else
		{
			// default is some sort of custom mode that doesn't appear in the windowed mode list
			// HACK: we'll add it to the end..
			modes[numModes].width = width;
			modes[numModes].height = height;
			currentMode = numModes;
			++numModes;
			break;
		}
	}

	DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback);
	DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback);

	// Set full screen mode, if necessary
	if(!gDisplay.windowed && numModes > 1)
	{
		if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode]))
		{
			MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode");
			MFDisplay_DestroyDisplay();
			return 1;
		}
	}

	XVisualInfo *MFRenderer_GetVisualInfo();
	XVisualInfo *visualInfo = MFRenderer_GetVisualInfo();
	if(!visualInfo)
		return 1;

	if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone)))
	{
		MFDebug_Error("Unable to create colourmap");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XSetWindowAttributes windowAttrs;
	windowAttrs.colormap = colorMap;
	windowAttrs.cursor = None;
	windowAttrs.event_mask = StructureNotifyMask;
	windowAttrs.border_pixel = BlackPixel(xdisplay, screen);
	windowAttrs.background_pixel = BlackPixel(xdisplay, screen);

	if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs)))
	{
		MFDebug_Error("Unable to create X Window");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	// Tell the window manager not to allow our window to be resized.  But some window managers can ignore me and do it anyway.  Typical X-Windows.
	if((sizeHints = XAllocSizeHints()) == NULL)
	{
		MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	sizeHints->flags = PSize | PMinSize | PMaxSize;
    sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width;
    sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height;

	XSetWMNormalHints(xdisplay, window, sizeHints);

	// Window title
	XStoreName(xdisplay, window, gDefaults.display.pWindowTitle);

	XWMHints *wmHints;
	if((wmHints = XAllocWMHints()) == NULL)
	{
		MFDebug_Error("Unable to alloc XWMHints structure, out of memory?");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	wmHints->flags = InputHint | StateHint;
	wmHints->input = true;
	wmHints->initial_state = NormalState;
	if(!XSetWMHints(xdisplay, window, wmHints))
	{
		MFDebug_Error("Unable to set WM hints for window");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XFree(wmHints);
	XFree(visualInfo);

	// Tell the window manager that I want to be notified if the window's closed
	wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false);
	if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1))
	{
		MFDebug_Error("Unable to set Window Manager protocols");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask);

	if(!XMapRaised(xdisplay, window))
	{
		MFDebug_Error("Unable to map new window");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	// Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is.
	XEvent event;
	XIfEvent(xdisplay, &event, WaitForNotify, (char *)window);

	MFRenderer_CreateDisplay();

	if(!gDisplay.windowed && numModes > 1)
	{
		if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode]))
		{
			MFDebug_Error("Unable to set screen mode");
			MFDisplay_DestroyDisplay();
			return 1;
		}

		XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);

		XFlush(xdisplay);
		// A little trick to make sure the entire window is on the screen
		XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1);
		XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0);
		XFlush(xdisplay);
	}

	return 0;
}