コード例 #1
0
ファイル: fabdxlib.c プロジェクト: Pupswoof117/SRB2-Public
//
// Flip the real page with virtual page
// - in bAppFullScreen mode, do page flipping
// - in windowed mode, copy the hidden surface to the visible surface
//
// waitflip : if not 0, wait for page flip to end
BOOL ScreenFlip(int waitflip)
{
	HRESULT hr;
	RECT rect;

	UNREFERENCED_PARAMETER(waitflip);
	if (bAppFullScreen)
	{
		//hr = IDirectDrawSurface_GetFlipStatus (ScreenReal, DDGFS_);

		// In full-screen exclusive mode, do a hardware flip.
		hr = IDirectDrawSurface_Flip(ScreenReal, NULL, DDFLIP_WAIT);   //return immediately

		// If the surface was lost, restore it.
		if (hr == DDERR_SURFACELOST)
		{
			IDirectDrawSurface_Restore(ScreenReal);

			// The restore worked, so try the flip again.
			hr = IDirectDrawSurface_Flip(ScreenReal, 0, DDFLIP_WAIT);
		}
	}
	else
	{
		rect.left = windowPosX;
		rect.top = windowPosY;
		rect.right = windowPosX + ScreenWidth - 1;
		rect.bottom = windowPosY + ScreenHeight - 1;

		// Copy the back buffer to front.
		hr = IDirectDrawSurface_Blt(ScreenReal, &rect, ScreenVirtual, 0, DDBLT_WAIT, 0);

		if (hr != DD_OK)
		{
			// If the surfaces were lost, restore them.
			if (IDirectDrawSurface_IsLost(ScreenReal) == DDERR_SURFACELOST)
				IDirectDrawSurface_Restore(ScreenReal);

			if (IDirectDrawSurface_IsLost(ScreenVirtual) == DDERR_SURFACELOST)
				IDirectDrawSurface_Restore(ScreenVirtual);

			// Retry the copy.
			hr = IDirectDrawSurface_Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0);
		}
	}

	if (hr != DD_OK)
		I_Error("ScreenFlip() : couldn't Flip surfaces because %s", DXErrorToString(hr));

	return FALSE;
}
コード例 #2
0
ファイル: fabdxlib.c プロジェクト: Logan-A/SRB2-Public
//
// Create the DirectDraw object for later
//
BOOL CreateDirectDrawInstance (VOID)
{
	HRESULT hr;
	IDirectDraw* DDr;
	IDirectDraw** rp = &DDr;
	IDirectDraw2** rp2 = &DDr2;
	LPVOID *tp = (LPVOID *)rp2;

	if (!LoadDirectDraw())
		return FALSE;
	//
	// create an instance of DirectDraw object
	//
	if (FAILED(hr = pfnDirectDrawCreate(NULL, rp, NULL)))
		I_Error("DirectDrawCreate FAILED: %s", DXErrorToString(hr));

	// change interface to IDirectDraw2
	if (FAILED(hr = IDirectDraw_QueryInterface(DDr, &IID_IDirectDraw2, tp)))
		I_Error("Failed to query DirectDraw2 interface: %s", DXErrorToString(hr));

	// release the interface we don't need
	IDirectDraw_Release (DDr);
	return TRUE;
}
コード例 #3
0
ファイル: fabdxlib.c プロジェクト: Logan-A/SRB2-Public
//
// - returns true if DirectDraw was initialized properly
//
int  InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr)
{
	DDSURFACEDESC ddsd; // DirectDraw surface description for allocating
	DDSCAPS       ddscaps;
	HRESULT       ddrval;

	DWORD         dwStyle;
	RECT          rect;

	// enumerate directdraw devices
	//if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL)))
	//      I_Error("Error with DirectDrawEnumerate");

	if (!DDr2)
		CreateDirectDrawInstance();

	// remember what screen mode we are in
	bAppFullScreen = fullScr;
	ScreenHeight = height;
	ScreenWidth = width;

	if (bAppFullScreen)
	{
		// Change window attributes
		dwStyle = WS_POPUP | WS_VISIBLE;
		SetWindowLong (appWin, GWL_STYLE, dwStyle);
		SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
			SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);

		// Get exclusive mode
		ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE |
		                                          DDSCL_FULLSCREEN |
		                                          DDSCL_ALLOWREBOOT);
		if (ddrval != DD_OK)
			I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval));

		// Switch from windows desktop to fullscreen

#ifdef NT4COMPAT
		ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0);
#else
		ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE);
#endif
		if (ddrval != DD_OK)
			I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval));

		// This is not really needed, except in certain cases. One case
		// is while using MFC. When the desktop is initally at 16bpp, a mode
		// switch to 8bpp somehow causes the MFC window to not fully initialize
		// and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will
		// ensure that the window is initialized properly after a mode switch.

		ShowWindow(appWin, SW_SHOW);

		// Create the primary surface with 1 back buffer. Always zero the
		// DDSURFACEDESC structure and set the dwSize member!

		ZeroMemory(&ddsd, sizeof (ddsd));
		ddsd.dwSize = sizeof (ddsd);
		ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

		// for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to
		// the visible surface, in both cases we have a visible (or 'real') surface, and a hidden
		// (or 'virtual', or 'backbuffer') surface.
		ddsd.dwBackBufferCount = 2;

		ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL);
		if (ddrval != DD_OK)
			I_Error("CreateSurface Primary Screen FAILED");

		// Get a pointer to the back buffer

		ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
		ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual);
		if (ddrval != DD_OK)
			I_Error("GetAttachedSurface FAILED");
	}
	else
	{
		rect.top = 0;
		rect.left = 0;
		rect.bottom = height;
		rect.right = width;

		// Change window attributes

		dwStyle = GetWindowStyle(appWin);
		dwStyle &= ~WS_POPUP;
		dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION;

		SetWindowLong(appWin, GWL_STYLE, dwStyle);

		// Resize the window so that the client area is the requested width/height

		AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL,
		                   GetWindowExStyle(appWin));

		// Just in case the window was moved off the visible area of the
		// screen.

		SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left,
		             rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER |
		             SWP_NOACTIVATE);

		SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0,
		             SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

		// Exclusive mode is normal since it's in windowed mode and needs
		// to cooperate with GDI

		ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL);
		if (ddrval != DD_OK)
			I_Error("SetCooperativeLevel FAILED");

		// Always zero the DDSURFACEDESC structure and set the dwSize member!

		ZeroMemory(&ddsd, sizeof (ddsd));
		ddsd.dwSize = sizeof (ddsd);
		ddsd.dwFlags = DDSD_CAPS;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

		// Create the primary surface

		ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL);
		if (ddrval != DD_OK)
			I_Error("CreateSurface Primary Screen FAILED");

		// Create a back buffer for offscreen rendering, this will be used to
		// blt to the primary

		ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN |
		                                 DDSCAPS_SYSTEMMEMORY);
		if (ScreenVirtual == NULL)
			I_Error("CreateSurface Secondary Screen FAILED");

		/// \todo get the desktop bit depth, and build a lookup table
		/// for quick conversions of 8bit color indexes 0-255 to desktop colors
		/// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format
		/// when blit virtual to real, convert pixels through lookup table..

		// Use a clipper object for clipping when in windowed mode
		// (make sure our drawing doesn't affect other windows)

		ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0);
		if (ddrval != DD_OK)
			I_Error("CreateClipper FAILED");

		// Associate the clipper with the window.
		ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin);
		if (ddrval != DD_OK)
			I_Error("Clipper -> SetHWnd  FAILED");

		// Attach the clipper to the surface.
		ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip);
		if (ddrval != DD_OK)
			I_Error("PrimaryScreen -> SetClipperClipper  FAILED");
	}

	return TRUE;
}