HRESULT DDVideo::InitDirectDraw()
{
	DDSURFACEDESC2 ddsd;
    DDSCAPS2 ddscaps;
	HRESULT		hRet;
 
    //Create the main DirectDraw object - updated to do it the hard way.... 7/10
    LPDIRECTDRAW pDD;

	HINSTANCE hInstDDraw;
    LPDIRECTDRAWCREATE pDDCreate = NULL;
    hInstDDraw = LoadLibrary("ddraw.dll");
	pDDCreate = ( LPDIRECTDRAWCREATE )GetProcAddress( hInstDDraw, "DirectDrawCreate" );
    pDDCreate( NULL, &pDD, NULL );
	//hRet = DirectDrawCreate(NULL,&pDD, NULL);

    hRet = pDD->QueryInterface(IID_IDirectDraw7, (LPVOID *) & m_lpDD);
      
	//Set cooperative level
	if (m_bWindowed) { //#112
		m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_ALLOWREBOOT | DDSCL_NORMAL | DDSCL_MULTITHREADED);
	} else {
		hRet = m_lpDD->SetCooperativeLevel(m_hWnd,DDSCL_EXCLUSIVE |DDSCL_ALLOWREBOOT| DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_MULTITHREADED);
		m_lpDD->SetDisplayMode(800,600,16,g_DX9Settings.m_refreshrate,0);
	}
	
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	//#112
	ddsd.dwFlags = (m_bWindowed) ? DDSD_CAPS : DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	ddsd.ddsCaps.dwCaps = (m_bWindowed) ? DDSCAPS_PRIMARYSURFACE : DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

	if (m_bWindowed) {
		LPDIRECTDRAWCLIPPER lpClipper;
		hRet = m_lpDD->CreateSurface(&ddsd, &m_lpDDSPrimary, NULL);
		hRet = m_lpDD->CreateClipper( 0, &lpClipper, NULL );
		hRet = lpClipper->SetHWnd( 0, m_hWnd );
		hRet = m_lpDDSPrimary->SetClipper( lpClipper );
		ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
		ddsd.dwWidth = 800;
		ddsd.dwHeight = 600;
		hRet = m_lpDD->CreateSurface(&ddsd, &m_lpDDSBack, NULL);
	} else {
		ddsd.dwBackBufferCount = 1;
		hRet = m_lpDD->CreateSurface(&ddsd, &m_lpDDSPrimary, NULL);
		ZeroMemory( &ddscaps, sizeof( ddscaps ) );
		ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
		hRet = m_lpDDSPrimary->GetAttachedSurface(&ddscaps,&m_lpDDSBack);
	}

	pDD->Release();
	return hRet;
}
Beispiel #2
0
void DDShutdown(void)
{
    // release clipper
    if (lpDDClipper) {
        lpDDClipper->Release();
        lpDDClipper = NULL;
    }
    
    // release the secondary surface
    if (lpDDSBack) {
        lpDDSBack->Release();
        lpDDSBack = NULL;
    }
    
    // release the primary surface
    if (lpDDSPrimary) {
        lpDDSPrimary->Release();
        lpDDSPrimary = NULL;
    }
    
    // finally, the main dd object
    if (lpDD) {
        lpDD->Release();
        lpDD = NULL;
    }
}
int DD_Shutdown(void)
{
// this function release all the resources directdraw
// allocated, mainly to com objects

// release the clipper first
if (lpddclipper)
    lpddclipper->Release();

// release the palette
if (lpddpal)
   lpddpal->Release();

// release the secondary surface
if (lpddsback)
    lpddsback->Release();

// release the primary surface
if (lpddsprimary)
   lpddsprimary->Release();

// finally, the main dd object
if (lpdd)
    lpdd->Release();

// return success
return(1);
} // end DD_Shutdown
void DirectDrawDisplay::cleanup()
{
  if(pDirectDraw != NULL) {
    if(ddsClipper != NULL) {
      ddsClipper->Release();
      ddsClipper = NULL;
    }

    if(ddsFlip != NULL) {
      ddsFlip->Release();
      ddsFlip = NULL;
    }

    if(ddsOffscreen != NULL) {
      ddsOffscreen->Release();
      ddsOffscreen = NULL;
    }
    
    if(ddsPrimary != NULL) {
      ddsPrimary->Release();
      ddsPrimary = NULL;
    }
    
    pDirectDraw->Release();
    pDirectDraw = NULL;
  }

  if(ddrawDLL != NULL) {
    AfxFreeLibrary(ddrawDLL);
    ddrawDLL = NULL;
  }
  width = 0;
  height = 0;
}
Beispiel #5
0
//-----------------------------------------------------------------------------
// Name: CDisplay::InitClipper
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CDisplay::InitClipper()
{
    LPDIRECTDRAWCLIPPER pClipper;
    HRESULT hr;

    // Create a clipper when using GDI to draw on the primary surface 
    if( FAILED( hr = m_pDD->CreateClipper( 0, &pClipper, NULL ) ) )
        return hr;

    pClipper->SetHWnd( 0, m_hWnd );

    if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pClipper ) ) )
        return hr;

    // We can release the clipper now since g_pDDSPrimary 
    // now maintains a ref count on the clipper
    SAFE_RELEASE( pClipper );

    return S_OK;
}
Beispiel #6
0
//! Releases the overlay surface
void DestroyOverlay()
{
    if (g_pClipper)
        g_pClipper->Release();
    if (g_pDDSOverlay) {
        g_pImg = 0; LPDIRECTDRAWSURFACE7 pDDSOverlay(g_pDDSOverlay);
        g_pDDSOverlay = NULL;
        YIELD_TO_THREAD();
        pDDSOverlay->Release(); // be sure nobody uses old value
    }
}
	~WSurfaceData() {
		if (clipper) clipper->Release();
		if (LeftBuffer) ((LPDIRECTDRAWSURFACE)LeftBuffer)->Release();
		if (RightBuffer) ((LPDIRECTDRAWSURFACE)RightBuffer)->Release();
		if (screen) screen->Release();
		if (ddraw) {
			if (!window_mode)
				ddraw->RestoreDisplayMode();
			ddraw->Release();
		}
		LeftBuffer=RightBuffer=0;
		ddraw=0,screen=0;
	}
Beispiel #8
0
static LPDIRECTDRAWCLIPPER createClipper (LPDIRECTDRAW7 pDDRAW, HWND hwnd)
{
    LPDIRECTDRAWCLIPPER pClipper = NULL;

    HRESULT rc = pDDRAW->CreateClipper (0, &pClipper, NULL);

    if (rc != DD_OK)
    {
        LOGDDRAW(("DDRAW: Could not create DirectDraw clipper rc = 0x%08X\n", rc));
    }
    else
    {
        rc = pClipper->SetHWnd (0, hwnd);

        if (rc != DD_OK)
        {
            LOGDDRAW(("DDRAW: Could not set the HWND on clipper rc = 0x%08X\n", rc));
            pClipper->Release ();
        }
    }

    return rc == DD_OK? pClipper: NULL;
}
Beispiel #9
0
//-----------------------------------------------------------------------------
// Name: AttachClipper()
// Desc: creates and attaches a clipper to a surface
//-----------------------------------------------------------------------------
LPDIRECTDRAWCLIPPER AttachClipper(LPDIRECTDRAWSURFACE7 lpddsSurface, HWND hWnd)
{
	LPDIRECTDRAWCLIPPER lpddClipper;  //pointer to the newly created dd clipper
	
	//first create the DD clipper
	ddReturnVal = lpddObj->CreateClipper(0,&lpddClipper, NULL);
	if (DDFailedCheck(ddReturnVal, "CreateClipper() failed", cpErrorBuf ))
	{	MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   return(NULL); }
	
	ddReturnVal = lpddClipper->SetHWnd(NULL,hWnd);
	if (DDFailedCheck(ddReturnVal, "lpddClipper->SetHWnd() failed", cpErrorBuf ))
	{	MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   return(NULL); }

	// now attach the clipper to the surface
	ddReturnVal = lpddsSurface->SetClipper(lpddClipper);
	if (DDFailedCheck(ddReturnVal, "SetClipper() failed", cpErrorBuf ))
	{	
		MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   
		// release memory and return error
		return(NULL); 
	}

	return(lpddClipper);
}
Beispiel #10
0
int DDInitWindowed(int width, int height, int bpp, HWND hwnd)
{
    HRESULT ret;
    
    // create object and test for error
    if (DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK) {
        return(0);
    }
    
    // set cooperation level to windowed mode normal
    if (lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL) != DD_OK) {
        return(0);
    }
    
    // set globals
    screen_height = height;
    screen_width = width;
    screen_bpp = bpp;
    
    // Create the primary surface
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    
    // all we need for windowed mode is access to the primary surface
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    
    // create the primary surface
    ret = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
    
    // create an offscreen and system mem back surface
    lpDDSBack = DDCreateSurface(width, height, NULL);
    
    lpDD->CreateClipper(0, &lpDDClipper, NULL);
    lpDDClipper->SetHWnd(0, hwnd);
    lpDDSPrimary->SetClipper(lpDDClipper);
    
    // clear out both primary and secondary surfaces
    DDFillSurface(lpDDSPrimary, 0);
    DDFillSurface(lpDDSBack, 0);
    
    DDGetRGB16();
    
    return 1;
}
Beispiel #11
0
void DDEnd(void)
{
        if (m_pDD)
        {
                if (m_pddsFrontBuffer != NULL)
                {
                        if (m_pddsFrame) m_pddsFrame->Release();
                        m_pddsFrame = NULL;

                        if (pcClipper) pcClipper->Release();
                        pcClipper = NULL;

                        if (m_pddsFrontBuffer) m_pddsFrontBuffer->Release();
                        m_pddsFrontBuffer = NULL;
                }
                m_pDD->Release();
                m_pDD = NULL;
        }
}
Beispiel #12
0
//! Load the bitmap and copy it to the overlay surface
bool DrawOverlay()
{
    HRESULT        hRet;       // This is where we put return values from DirectDraw.
    DDSURFACEDESC2 surfDesc;
    // Setup structure
    memset(&surfDesc, 0, sizeof(surfDesc)); surfDesc.dwSize = sizeof(surfDesc);

    hRet = g_pDDSOverlay->Lock(NULL, &surfDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WRITEONLY, NULL);
    if (hRet != DD_OK ||  surfDesc.lpSurface == NULL)
        return DisplayError("Can't lock overlay surface", hRet);
    else {
        g_pImg = (unsigned int *)surfDesc.lpSurface;
        //g_pDDSOverlay->Unlock(NULL); is not needed?
    }
    // Setup effects structure
    memset(&g_OverlayFX, 0, sizeof(g_OverlayFX)); g_OverlayFX.dwSize = sizeof(g_OverlayFX);
    // Setup overlay flags.
    g_OverlayFlags = DDOVER_SHOW;
    // Check for destination color keying capability
    if ((g_DDCaps.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) && ((g_DDCaps.dwCaps & DDCAPS_OVERLAYCANTCLIP) || (g_DDCaps.dwCKeyCaps & DDCKEYCAPS_NOCOSTOVERLAY) ))
    {
        // If so, we'll use it to clip the bitmap when other windows go on top
        // of us. Just for the record - this color range for color keying (the
        // high/low values) are not heavily supported right now, so for almost
        // all cards, just use the same color for both.
        g_OverlayFX.dckDestColorkey.dwColorSpaceLowValue =
        g_OverlayFX.dckDestColorkey.dwColorSpaceHighValue = DDColorMatch(g_pDDSPrimary, RGBKEY);
        g_OverlayFlags |= DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
    } else {
        // If not, we'll setup a clipper for the window.  This will fix the
        // problem on a few video cards - but the ones that don't shouldn't care.
        hRet = g_pDD->CreateClipper(0, &g_pClipper, NULL);
        if (hRet != DD_OK)
            return DisplayError("Can't create clipper", hRet);
        hRet = g_pClipper->SetHWnd(0, g_hAppWnd);
        if (hRet != DD_OK)
            return DisplayError("Can't attach clipper", hRet);
        hRet = g_pDDSPrimary->SetClipper(g_pClipper);
        if (hRet != DD_OK)
            return DisplayError("Can't set clipper", hRet);
    }
    return true;
}
Beispiel #13
0
/**
 * vdraw_ddraw_free_all(): Free all DirectDraw objects.
 * @param scl If true, sets the cooperative level of lpDD before freeing it.
 */
static void WINAPI vdraw_ddraw_free_all(bool scl)
{
	if (lpDDC_Clipper)
	{
		lpDDC_Clipper->Release();
		lpDDC_Clipper = NULL;
	}
	
	if (lpDDS_Back)
	{
		lpDDS_Back->Release();
		lpDDS_Back = NULL;
	}
	
	if (lpDDS_Flip)
	{
		lpDDS_Flip->Release();
		lpDDS_Flip = NULL;
	}
	
	if (lpDDS_Primary)
	{
		lpDDS_Primary->Release();
		lpDDS_Primary = NULL;
	}
	
	if (lpDD)
	{
		if (scl)
			lpDD->SetCooperativeLevel(gens_window, DDSCL_NORMAL);
		lpDD->Release();
		lpDD = NULL;
	}
	
	lpDDS_Blit = NULL;
}
BOOL CH264Decode::PreviewDraw(H264_DEC_FRAME_S DecodeData)
{
	if (!m_bPreEnable)
	{
		return true;
	}

 	DDSURFACEDESC2 ddsd;
	const HI_U8 *pY = DecodeData.pY;
    const HI_U8 *pU = DecodeData.pU;
    const HI_U8 *pV = DecodeData.pV;
    HI_U32 width    = DecodeData.uWidth;
    HI_U32 height   = DecodeData.uHeight;
    HI_U32 yStride  = DecodeData.uYStride;
    HI_U32 uvStride = DecodeData.uUVStride;
	if (0 == width || 0 == height)
	{
		return true;
	}
	ZeroMemory(&ddsd,sizeof(DDSURFACEDESC2));
	ddsd.dwSize = sizeof(DDSURFACEDESC2);
	HRESULT hr;
	hr = m_pOffscreenSurface->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
	if (FAILED(hr))
	{
		m_dwLastError = hr;//GetLastError();
		switch(hr)
		{
		case DDERR_SURFACELOST:
			g_pDirectDraw7->RestoreAllSurfaces();
			break;
		case DDERR_SURFACEBUSY:
			m_pOffscreenSurface->Unlock(NULL);
			break;
		default:
			break;
		}
		return FALSE;
	}
	
	
	PBYTE pDestY = (PBYTE)ddsd.lpSurface;
	PBYTE pDestV = (PBYTE)ddsd.lpSurface + ddsd.lPitch * ddsd.dwHeight;
	PBYTE pDestU = (PBYTE)ddsd.lpSurface + ddsd.lPitch * ddsd.dwHeight*5/4;
	for (HI_U32 i = 0;i<height;i++)
	{
		memcpy(pDestY,pY,yStride);
		pDestY += ddsd.lPitch;
		pY += yStride;
	}
	

	for (i = 0;i<height/2;i++)
	{
		memcpy(pDestU,pU,uvStride);
		pDestU += ddsd.lPitch/2;
		pU += uvStride;
	}

	for (i = 0;i<height/2;i++)
	{
		memcpy(pDestV,pV,uvStride);
		pDestV += ddsd.lPitch/2;
		pV += uvStride;
	}
	hr = m_pOffscreenSurface->Unlock(NULL);

    EnterCriticalSection(&m_csCritial);
	if (m_PlayWnd != NULL)
	{
		RECT rcDsp;
		::GetClientRect( m_PlayWnd,&rcDsp);
		POINT ptTL;
		POINT ptRB;
		ptTL.x = rcDsp.left + 1;
		ptTL.y = rcDsp.top + 1;
		ptRB.x = rcDsp.right - 1;
		ptRB.y = rcDsp.bottom - 1;
		::ClientToScreen( m_PlayWnd,&ptTL);
		::ClientToScreen( m_PlayWnd,&ptRB);
		SetRect(&rcDsp,ptTL.x,ptTL.y,ptRB.x,ptRB.y);
		
		//写OSD

/*		HDC		dcTemp;
 		hr = m_pOSDSurface->GetDC(&dcTemp);
		DDSURFACEDESC2 ddsdOsd = {0};
		ddsdOsd.dwSize = sizeof(ddsdOsd);
		m_pOSDSurface->GetSurfaceDesc(&ddsdOsd);

		HBRUSH BackBrush = CreateSolidBrush(RGB(0,0,0));
		RECT rcOsd;
		SetRect(&rcOsd,0,0,ddsdOsd.dwWidth,ddsdOsd.dwHeight);
		FillRect(dcTemp,&rcOsd,BackBrush);
		DeleteObject(BackBrush);

		EnterCriticalSection(&m_csDcCallback);
 		if (NULL != dccallbackFun)
 		{
 			dccallbackFun(dcTemp,m_nDcChl,lpDcUser);
 		}
		LeaveCriticalSection(&m_csDcCallback);
		m_pOSDSurface->ReleaseDC(dcTemp);

		DDSURFACEDESC2 ddsdFin = {0};
		ddsdFin.dwSize = sizeof(ddsdFin);
		m_pFinSurface->GetSurfaceDesc(&ddsdFin);
		RECT rcFin;
		SetRect(&rcFin,0,0,ddsdFin.dwWidth,ddsdFin.dwHeight);

		hr = m_pFinSurface->Blt(&rcFin,m_pOffscreenSurface,&rcSrc,DDBLT_WAIT,NULL);
		hr = m_pFinSurface->Blt(&rcFin,m_pOSDSurface,NULL,DDBLT_WAIT | DDBLT_KEYSRC,NULL);*/
		RECT rcSrc;
		SetRect(&rcSrc,0,0,width,height);
		EnterCriticalSection(&g_csClipper);
		g_pClipper->SetHWnd(NULL,m_PlayWnd);
		if (::IsWindowVisible(m_PlayWnd))
		{
			g_pPrimarySurface->Blt(&rcDsp,m_pOffscreenSurface,&rcSrc,DDBLT_WAIT,0);	
		}
		LeaveCriticalSection(&g_csClipper);
	}
	 LeaveCriticalSection(&m_csCritial);

	return TRUE;
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// Name: AttachClipper()
// Desc: creates and attaches a clipper to a surface
//-----------------------------------------------------------------------------
LPDIRECTDRAWCLIPPER AttachClipper(LPDIRECTDRAWSURFACE7 lpddsSurface, int iNumRects, LPRECT cliplist)
{
	int index;                        //loop va
	LPDIRECTDRAWCLIPPER lpddClipper;  //pointer to the newly created dd clipper
	LPRGNDATA regionData;             //pointer to the region data that contains the header and clip list

	//first create the DD clipper
	ddReturnVal = lpddObj->CreateClipper(0,&lpddClipper, NULL);
	if (DDFailedCheck(ddReturnVal, "CreateClipper() failed", cpErrorBuf ))
	{	MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   return(NULL); }
	
	//now create the clip list from the sent data
	//first allocate memory for region data
	regionData = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + iNumRects*sizeof(RECT));
	//now copy the rects into region data
	memcpy(regionData->Buffer, cliplist, sizeof(RECT)*iNumRects);
	
	// set up fields of header
	regionData->rdh.dwSize          = sizeof(RGNDATAHEADER);
	regionData->rdh.iType           = RDH_RECTANGLES;
	regionData->rdh.nCount          = iNumRects;
	regionData->rdh.nRgnSize        = iNumRects*sizeof(RECT);

	regionData->rdh.rcBound.left    =  -64000;
	regionData->rdh.rcBound.top     =  -64000;
	regionData->rdh.rcBound.right   = 64000;
	regionData->rdh.rcBound.bottom  = 64000;

	// find bounds of all clipping regions
	for (index=0; index<iNumRects; index++)
    {
		// test if the next rectangle unioned with the current bound is larger
		if (cliplist[index].top < regionData->rdh.rcBound.top)
			regionData->rdh.rcBound.top = cliplist[index].top;

		if (cliplist[index].left < regionData->rdh.rcBound.left)
			 regionData->rdh.rcBound.left = cliplist[index].left;

		if (cliplist[index].bottom > regionData->rdh.rcBound.bottom)
			regionData->rdh.rcBound.bottom = cliplist[index].bottom;

		if (cliplist[index].right > regionData->rdh.rcBound.right)
			regionData->rdh.rcBound.right = cliplist[index].right;

    } // end for index

	// now we have computed the bounding rectangle region and set up the data
	// now let's set the clipping list
	
	ddReturnVal = lpddClipper->SetClipList(regionData, 0); //can also give lpddClipper a hWnd
	if (DDFailedCheck(ddReturnVal, "SetClipList() failed", cpErrorBuf ))
	{	
		MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   
		// release memory and return error
		free(regionData);
		return(NULL); 
	}
	
	// now attach the clipper to the surface
	ddReturnVal = lpddsSurface->SetClipper(lpddClipper);
	if (DDFailedCheck(ddReturnVal, "SetClipper() failed", cpErrorBuf ))
	{	
		MessageBox(main_window_handle, cpErrorBuf, "AttachClipper()", MB_ICONEXCLAMATION);   
		// release memory and return error
		free(regionData);
		return(NULL); 
	}
	
	// all is well, so release memory and send back the pointer to the new clipper
	free(regionData);
	return(lpddClipper);

} // end AttachClipper
Beispiel #16
0
PRBool nsWindow::OnPaint(HDC aDC)
{
#ifdef MOZ_IPC
  if (mWindowType == eWindowType_plugin) {

    /**
     * After we CallUpdateWindow to the child, occasionally a WM_PAINT message
     * is posted to the parent event loop with an empty update rect. Do a
     * dummy paint so that Windows stops dispatching WM_PAINT in an inifinite
     * loop. See bug 543788.
     */
    RECT updateRect;
    if (!GetUpdateRect(mWnd, &updateRect, FALSE) ||
        (updateRect.left == updateRect.right &&
         updateRect.top == updateRect.bottom)) {
      PAINTSTRUCT ps;
      BeginPaint(mWnd, &ps);
      EndPaint(mWnd, &ps);
      return PR_TRUE;
    }

    PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>(
      ::GetPropW(mWnd, L"PluginInstanceParentProperty"));
    if (instance) {
      instance->CallUpdateWindow();
      ValidateRect(mWnd, NULL);
      return PR_TRUE;
    }
  }
#endif

#ifdef MOZ_IPC
  // We never have reentrant paint events, except when we're running our RPC
  // windows event spin loop. If we don't trap for this, we'll try to paint,
  // but view manager will refuse to paint the surface, resulting is black
  // flashes on the plugin rendering surface.
  if (mozilla::ipc::RPCChannel::IsSpinLoopActive() && mPainting)
    return PR_FALSE;
#endif

  nsPaintEvent willPaintEvent(PR_TRUE, NS_WILL_PAINT, this);
  DispatchWindowEvent(&willPaintEvent);

#ifdef CAIRO_HAS_DDRAW_SURFACE
  if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_DDRAW16)) {
    return OnPaintImageDDraw16();
  }
#endif

  PRBool result = PR_TRUE;
  PAINTSTRUCT ps;
  nsEventStatus eventStatus = nsEventStatus_eIgnore;

#ifdef MOZ_XUL
  if (!aDC && (eTransparencyTransparent == mTransparencyMode))
  {
    // For layered translucent windows all drawing should go to memory DC and no
    // WM_PAINT messages are normally generated. To support asynchronous painting
    // we force generation of WM_PAINT messages by invalidating window areas with
    // RedrawWindow, InvalidateRect or InvalidateRgn function calls.
    // BeginPaint/EndPaint must be called to make Windows think that invalid area
    // is painted. Otherwise it will continue sending the same message endlessly.
    ::BeginPaint(mWnd, &ps);
    ::EndPaint(mWnd, &ps);

    aDC = mMemoryDC;
  }
#endif

  mPainting = PR_TRUE;

#ifdef WIDGET_DEBUG_OUTPUT
  HRGN debugPaintFlashRegion = NULL;
  HDC debugPaintFlashDC = NULL;

  if (debug_WantPaintFlashing())
  {
    debugPaintFlashRegion = ::CreateRectRgn(0, 0, 0, 0);
    ::GetUpdateRgn(mWnd, debugPaintFlashRegion, TRUE);
    debugPaintFlashDC = ::GetDC(mWnd);
  }
#endif // WIDGET_DEBUG_OUTPUT

  HDC hDC = aDC ? aDC : (::BeginPaint(mWnd, &ps));
  if (!IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) {
    mPaintDC = hDC;
  }

#ifdef MOZ_XUL
  PRBool forceRepaint = aDC || (eTransparencyTransparent == mTransparencyMode);
#else
  PRBool forceRepaint = NULL != aDC;
#endif
  nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(forceRepaint, ps, hDC);

  if (paintRgnWin &&
      !paintRgnWin->IsEmpty() &&
      mEventCallback)
  {
    // generate the event and call the event callback
    nsPaintEvent event(PR_TRUE, NS_PAINT, this);

    InitEvent(event);

    event.region = paintRgnWin;
    event.rect = nsnull;
 
    // Should probably pass in a real region here, using GetRandomRgn
    // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp

#ifdef WIDGET_DEBUG_OUTPUT
    debug_DumpPaintEvent(stdout,
                         this,
                         &event,
                         nsCAutoString("noname"),
                         (PRInt32) mWnd);
#endif // WIDGET_DEBUG_OUTPUT

    nsRefPtr<gfxASurface> targetSurface;

#if defined(MOZ_XUL)
    // don't support transparency for non-GDI rendering, for now
    if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) && eTransparencyTransparent == mTransparencyMode) {
      if (mTransparentSurface == nsnull)
        SetupTranslucentWindowMemoryBitmap(mTransparencyMode);
      targetSurface = mTransparentSurface;
    }
#endif

    nsRefPtr<gfxWindowsSurface> targetSurfaceWin;
    if (!targetSurface &&
        IsRenderMode(gfxWindowsPlatform::RENDER_GDI))
    {
      targetSurfaceWin = new gfxWindowsSurface(hDC);
      targetSurface = targetSurfaceWin;
    }
#ifdef CAIRO_HAS_D2D_SURFACE
    if (!targetSurface &&
        IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D))
    {
      if (!mD2DWindowSurface) {
        mD2DWindowSurface = new gfxD2DSurface(mWnd);
      }
      targetSurface = mD2DWindowSurface;
    }
#endif
#ifdef CAIRO_HAS_DDRAW_SURFACE
    nsRefPtr<gfxDDrawSurface> targetSurfaceDDraw;
    if (!targetSurface &&
        (IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW) ||
         IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW_GL)))
    {
      if (!glpDD) {
        if (!nsWindowGfx::InitDDraw()) {
          NS_WARNING("DirectDraw init failed; falling back to RENDER_IMAGE_STRETCH24");
          gfxWindowsPlatform::GetPlatform()->SetRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24);
          goto DDRAW_FAILED;
        }
      }

      // create a rect that maps the window in screen space
      // create a new sub-surface that aliases this one
      RECT winrect;
      GetClientRect(mWnd, &winrect);
      MapWindowPoints(mWnd, NULL, (LPPOINT)&winrect, 2);

      targetSurfaceDDraw = new gfxDDrawSurface(gpDDSurf.get(), winrect);
      targetSurface = targetSurfaceDDraw;
    }
#endif

DDRAW_FAILED:
    nsRefPtr<gfxImageSurface> targetSurfaceImage;
    if (!targetSurface &&
        (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32) ||
         IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24)))
    {
      gfxIntSize surfaceSize(ps.rcPaint.right - ps.rcPaint.left,
                             ps.rcPaint.bottom - ps.rcPaint.top);

      if (!EnsureSharedSurfaceSize(surfaceSize)) {
        NS_ERROR("Couldn't allocate a shared image surface!");
        return NS_ERROR_FAILURE;
      }

      // don't use the shared surface directly; instead, create a new one
      // that just reuses its buffer.
      targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(),
                                               surfaceSize,
                                               surfaceSize.width * 4,
                                               gfxASurface::ImageFormatRGB24);

      if (targetSurfaceImage && !targetSurfaceImage->CairoStatus()) {
        targetSurfaceImage->SetDeviceOffset(gfxPoint(-ps.rcPaint.left, -ps.rcPaint.top));
        targetSurface = targetSurfaceImage;
      }
    }

    if (!targetSurface) {
      NS_ERROR("Invalid RenderMode!");
      return NS_ERROR_FAILURE;
    }

    nsRefPtr<gfxContext> thebesContext = new gfxContext(targetSurface);
    thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
    if (IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D) && paintRgnWin) {
      PRUint32 rects;
      paintRgnWin->GetNumRects(&rects);
      nsRegionRectSet *rectSet = NULL;
      paintRgnWin->GetRects(&rectSet);
      for (int i = 0; i < rectSet->mNumRects; i++) {
        thebesContext->Rectangle(
        gfxRect(
               rectSet->mRects[i].x,
               rectSet->mRects[i].y,
               rectSet->mRects[i].width,
               rectSet->mRects[i].height), PR_TRUE);
      }
      thebesContext->Clip();

      paintRgnWin->FreeRects(rectSet);
    }
#ifdef WINCE
    thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
#endif

    // don't need to double buffer with anything but GDI
    if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) {
# if defined(MOZ_XUL) && !defined(WINCE)
      if (eTransparencyGlass == mTransparencyMode && nsUXThemeData::sHaveCompositor) {
        thebesContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
      } else if (eTransparencyTransparent == mTransparencyMode) {
        // If we're rendering with translucency, we're going to be
        // rendering the whole window; make sure we clear it first
        thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR);
        thebesContext->Paint();
        thebesContext->SetOperator(gfxContext::OPERATOR_OVER);
      } else
#endif
      {
        // If we're not doing translucency, then double buffer
        thebesContext->PushGroup(gfxASurface::CONTENT_COLOR);
      }
    }

    nsCOMPtr<nsIRenderingContext> rc;
    nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
    if (NS_FAILED(rv)) {
      NS_WARNING("CreateRenderingContextInstance failed");
      return PR_FALSE;
    }

    rv = rc->Init(mContext, thebesContext);
    if (NS_FAILED(rv)) {
      NS_WARNING("RC::Init failed");
      return PR_FALSE;
    }

    event.renderingContext = rc;
    result = DispatchWindowEvent(&event, eventStatus);
    event.renderingContext = nsnull;

#ifdef MOZ_XUL
    if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) &&
        eTransparencyTransparent == mTransparencyMode) {
      // Data from offscreen drawing surface was copied to memory bitmap of transparent
      // bitmap. Now it can be read from memory bitmap to apply alpha channel and after
      // that displayed on the screen.
      UpdateTranslucentWindow();
    } else
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
    if (result) {
      if (mD2DWindowSurface) {
        mD2DWindowSurface->Present();
      }
    }
#endif
    if (result) {
      if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) {
        // Only update if DispatchWindowEvent returned TRUE; otherwise, nothing handled
        // this, and we'll just end up painting with black.
        thebesContext->PopGroupToSource();
        thebesContext->SetOperator(gfxContext::OPERATOR_SOURCE);
        thebesContext->Paint();
      } else if (IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW) ||
                 IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW_GL))
      {
#ifdef CAIRO_HAS_DDRAW_SURFACE
        // blit with direct draw
        HRESULT hr = glpDDClipper->SetHWnd(0, mWnd);

#ifdef DEBUG
        if (FAILED(hr))
          DDError("SetHWnd", hr);
#endif

        // blt from the affected area from the window back-buffer to the
        // screen-relative coordinates of the window paint area
        RECT dst_rect = ps.rcPaint;
        MapWindowPoints(mWnd, NULL, (LPPOINT)&dst_rect, 2);
        hr = glpDDPrimary->Blt(&dst_rect,
                               gpDDSurf->GetDDSurface(),
                               &dst_rect,
                               DDBLT_WAITNOTBUSY,
                               NULL);
#ifdef DEBUG
        if (FAILED(hr))
          DDError("SetHWnd", hr);
#endif
#endif
      } else if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24) ||
                 IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32)) 
      {
        gfxIntSize surfaceSize = targetSurfaceImage->GetSize();

        // Just blit this directly
        BITMAPINFOHEADER bi;
        memset(&bi, 0, sizeof(BITMAPINFOHEADER));
        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = surfaceSize.width;
        bi.biHeight = - surfaceSize.height;
        bi.biPlanes = 1;
        bi.biBitCount = 32;
        bi.biCompression = BI_RGB;

        if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24)) {
          // On Windows CE/Windows Mobile, 24bpp packed-pixel sources
          // seem to be far faster to blit than 32bpp (see bug 484864).
          // So, convert the bits to 24bpp by stripping out the unused
          // alpha byte.  24bpp DIBs also have scanlines that are 4-byte
          // aligned though, so that must be taken into account.
          int srcstride = surfaceSize.width*4;
          int dststride = surfaceSize.width*3;
          dststride = (dststride + 3) & ~3;

          // Convert in place
          for (int j = 0; j < surfaceSize.height; ++j) {
            unsigned int *src = (unsigned int*) (targetSurfaceImage->Data() + j*srcstride);
            unsigned int *dst = (unsigned int*) (targetSurfaceImage->Data() + j*dststride);

            // go 4 pixels at a time, since each 4 pixels
            // turns into 3 DWORDs when converted into BGR:
            // BGRx BGRx BGRx BGRx -> BGRB GRBG RBGR
            //
            // However, since we're dealing with little-endian ints, this is actually:
            // xRGB xrgb xRGB xrgb -> bRGB GBrg rgbR
            int width_left = surfaceSize.width;
            while (width_left >= 4) {
              unsigned int a = *src++;
              unsigned int b = *src++;
              unsigned int c = *src++;
              unsigned int d = *src++;

              *dst++ =  (a & 0x00ffffff)        | (b << 24);
              *dst++ = ((b & 0x00ffff00) >> 8)  | (c << 16);
              *dst++ = ((c & 0x00ff0000) >> 16) | (d << 8);

              width_left -= 4;
            }

            // then finish up whatever number of pixels are left,
            // using bytes.
            unsigned char *bsrc = (unsigned char*) src;
            unsigned char *bdst = (unsigned char*) dst;
            switch (width_left) {
              case 3:
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                bsrc++;
              case 2:
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                bsrc++;
              case 1:
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                *bdst++ = *bsrc++;
                bsrc++;
              case 0:
                break;
            }
          }

          bi.biBitCount = 24;
        }

        StretchDIBits(hDC,
                      ps.rcPaint.left, ps.rcPaint.top,
                      surfaceSize.width, surfaceSize.height,
                      0, 0,
                      surfaceSize.width, surfaceSize.height,
                      targetSurfaceImage->Data(),
                      (BITMAPINFO*) &bi,
                      DIB_RGB_COLORS,
                      SRCCOPY);
      }
    }
Beispiel #17
0
int dd_Window::set_win(int w, int h, int bpp)
{
//	RECT r, r2;
	HRESULT hr;

	shutdown_win();

	dx_win_bsd.dwWidth = w;
	dx_win_bsd.dwHeight = h;
	hr = dx_dd->CreateSurface(&dx_win_bsd, &dx_win_bs, NULL);
	if (hr != DD_OK)
	{
		return 0;
	}
	hr = dx_win_bs->Lock(0, &dx_win_bsd, 0, 0);
	if (hr != DD_OK)
	{
		DX_RELEASE(dx_win_bs);
		return 0;
	}
	dx_win_bs->Unlock(0);
	hr = dx_dd->CreateClipper(0, &clipper, 0);
	if (hr != DD_OK)
	{
		DX_RELEASE(dx_win_bs);
		return 0;
	}
	hr = clipper->SetHWnd(0, hwnd);
	if (hr != DD_OK)
	{
		DX_RELEASE(dx_win_bs);
		DX_RELEASE(clipper);
		return 0;
	}

	if(bGameWindow)
	{
		int ws = GetWindowLong(hwnd,GWL_STYLE);
		ws &= ~WS_POPUP;
		ws |= WS_OVERLAPPEDWINDOW | WS_THICKFRAME;
		SetWindowLong(hwnd, GWL_STYLE, ws);
	}

	//set pixelformat parameters
	//if(bGameWindow)
	//{
	//	DDPIXELFORMAT ddpf;
	//	ddpf.dwSize = sizeof(ddpf);
	//	ddpf.dwFlags = DDPF_RGB;
	//	hr = dx_win_ps->GetPixelFormat(&ddpf);
	//	if (hr != DD_OK) err("Could not get pixel format!");
	//	//if (ddpf.dwRBitMask == 0x7C00 && bpp == 16)
	//	//	vid_bpp = 15, vid_bytesperpixel = 2;
	//	//else
	//	//	vid_bpp = bpp, vid_bytesperpixel = bpp / 8;
	//}

	delete img;
	img = new image();
	img->width = w;
	img->height = h;
	img->cx1 = 0;
	img->cx2 = w-1;
	img->cy1 = 0;
	img->cy2 = h-1;
	
	if(vid_bpp == DesktopBPP) {
		img->shell = true;
		img->data = (quad*)dx_win_bsd.lpSurface;
		img->pitch = dx_win_bsd.lPitch / vid_bytesperpixel;
	} else {
		img->alloc_data();
	}

	SetHandleImage(imgHandle,img);
	if(bGameWindow)
	{
		SetHandleImage(1,img);
		screen = img;
	}
	

	return 1;
}
HRESULT __stdcall DDRAW4_HOOK_CreateSurface(LPVOID *ppvOut, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4 FAR *lplpDDSurface4, IUnknown FAR *pUnkOuter)
{
	const unsigned int hpos = 6;

	if(g_config.displaymode != 0)
	{
		/*if((void *)lpDDSurfaceDesc == (void *)0x00134518) {
				lpDDSurfaceDesc->dwWidth = displaymode_options[g_config.displaymode].resX;
				lpDDSurfaceDesc->dwHeight = displaymode_options[g_config.displaymode].resY;
		}*/
		if(lpDDSurfaceDesc != NULL && lpDDSurfaceDesc->dwWidth == 640 && lpDDSurfaceDesc->dwHeight == 480) {
				lpDDSurfaceDesc->dwWidth = displaymode_options[g_config.displaymode].resX;
				lpDDSurfaceDesc->dwHeight = displaymode_options[g_config.displaymode].resY;
		}
	}

	// 8-bit Paletted Textures Fix (VISTA Compatible)
	if(g_config.b8_paletted_textures_fix >= 1)
	{
		if(lpDDSurfaceDesc != NULL && (lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) == (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) {
			lpDDSurfaceDesc->dwFlags |= DDSD_CKSRCBLT;
			lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue = 0x000000;
			lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue = 0x000000;
		}
	}

#ifdef FF8_WINDOWED
	if((void *)lpDDSurfaceDesc == (void *)0x00134658)
	{
		Log("IF[lpDDSurfaceDesc == 0x00134658] THEN\n");
		lpDDSurfaceDesc->dwFlags &= ~(DDSD_BACKBUFFERCOUNT);
		//lpDDSurfaceDesc->dwFlags |= (DDSD_WIDTH | DDSD_HEIGHT);
		lpDDSurfaceDesc->dwWidth = 0;
		lpDDSurfaceDesc->dwHeight = 0;
		lpDDSurfaceDesc->dwBackBufferCount = 0;
		lpDDSurfaceDesc->ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE );
		lpDDSurfaceDesc->ddsCaps.dwCaps |= (DDSCAPS_PRIMARYSURFACE);
	} /*else if((lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) && (lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) && (lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask == 0x7c00 && lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask == 0x3e0 && lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask == 0x1f) {
		lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &= ~(DDPF_ALPHAPIXELS);
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask = 0x00;
	//Does not work: Crash in battle swirl
	}*/ /*else if((lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE)) && (lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) && (lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 0x020) {
		lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &= ~(DDPF_ALPHAPIXELS);
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpBitCount = 0x10;
		lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDuBitMask = 0xf800;
		lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwUBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDvBitMask = 0x7e0;
		lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwVBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpLuminanceBitMask = 0x1f;
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask = 0x00;
	}*/

/*
16BIT
->lpDDSurfaceDesc { dwSize=0x0000007c, dwFlags=0x00001007 (DDSD_CAPS | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_WIDTH), dwWidth=0x00000100 (256), dwHeight=0x00000100 (256), lPitch=0000000000 , dwLinearSize=0000000000, dwBackBufferCount=0000000000, dwMipMapCount=0000000000, dwRefreshRate=0000000000, dwAlphaBitDepth=0000000000, dwReserved=0000000000,
lpSurface=0000000000, ddckCKDestOverlay={ 0000000000, 0000000000 }, ddckCKDestBlt={ 0000000000, 0000000000 }, ddckCKSrcOverlay={ 0000000000, 0000000000 }, ddckCKSrcBlt={ 0000000000, 0000000000 },
ddpfPixelFormat={ dwSize=0x00000020, dwFlags=0x00000040 (DDPF_RGB), dwFourCC=0000000000, dwRGBBitCount=0x00000010, dwYUVBitCount=0x00000010, dwZBufferBitDepth=0x00000010, dwAlphaBitDepth=0x00000010, dwLuminanceBitCount=0x00000010, dwBumpBitCount=0x00000010, dwRBitMask=0x0000f800,
dwYBitMask=0x0000f800, dwStencilBitDepth=0x0000f800, dwLuminanceBitMask=0x0000f800, dwBumpDuBitMask=0x0000f800, dwGBitMask=0x000007e0, dwUBitMask=0x000007e0, dwZBitMask=0x000007e0, dwBumpDvBitMask=0x000007e0, dwBBitMask=0x0000001f, dwVBitMask=0x0000001f, dwStencilBitMask=0x0000001f,
dwBumpLuminanceBitMask=0x0000001f, dwRGBAlphaBitMask=0000000000, dwYUVAlphaBitMask=0000000000, dwLuminanceAlphaBitMask=0000000000, dwRGBZBitMask=0000000000, dwYUVZBitMask=0000000000 },
ddsCaps={ 0x00001800 (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE), 0000000000, 0000000000, 0000000000 }, dwTextureStage=0000000000 }

32BIT
->lpDDSurfaceDesc { dwSize=0x0000007c, dwFlags=0x00001007 (DDSD_CAPS | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_WIDTH), dwWidth=0x00000100 (256), dwHeight=0x00000100 (256), lPitch=0000000000 , dwLinearSize=0000000000, dwBackBufferCount=0000000000, dwMipMapCount=0000000000, dwRefreshRate=0000000000, dwAlphaBitDepth=0000000000, dwReserved=0000000000,
lpSurface=0000000000, ddckCKDestOverlay={ 0000000000, 0000000000 }, ddckCKDestBlt={ 0000000000, 0000000000 }, ddckCKSrcOverlay={ 0000000000, 0000000000 }, ddckCKSrcBlt={ 0000000000, 0000000000 },
ddpfPixelFormat={ dwSize=0x00000020, dwFlags=0x00000041 (DDPF_ALPHAPIXELS | DDPF_RGB), dwFourCC=0000000000, dwRGBBitCount=0x00000020, dwYUVBitCount=0x00000020, dwZBufferBitDepth=0x00000020, dwAlphaBitDepth=0x00000020, dwLuminanceBitCount=0x00000020, dwBumpBitCount=0x00000020, dwRBitMask=0x00ff0000,
dwYBitMask=0x00ff0000, dwStencilBitDepth=0x00ff0000, dwLuminanceBitMask=0x00ff0000, dwBumpDuBitMask=0x00ff0000, dwGBitMask=0x0000ff00, dwUBitMask=0x0000ff00, dwZBitMask=0x0000ff00, dwBumpDvBitMask=0x0000ff00, dwBBitMask=0x000000ff, dwVBitMask=0x000000ff, dwStencilBitMask=0x000000ff,
dwBumpLuminanceBitMask=0x000000ff, dwRGBAlphaBitMask=0xff000000, dwYUVAlphaBitMask=0xff000000, dwLuminanceAlphaBitMask=0xff000000, dwRGBZBitMask=0xff000000, dwYUVZBitMask=0xff000000 },
ddsCaps={ 0x00001800 (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE), 0000000000, 0000000000, 0000000000 }, dwTextureStage=0000000000 }
*/
#endif

	DDRAW4_CreateSurface_Type ofn = (DDRAW4_CreateSurface_Type)ddraw4_hooks[hpos].oldFunc;
	HRESULT ret = ofn(ppvOut, lpDDSurfaceDesc, lplpDDSurface4, pUnkOuter);
	LogDXError(ret);
	
	Log("IDirectDraw4::%s(this=%#010lx, lpDDSurfaceDesc=%#010lx, lplpDDSurface=%#010lx *[%#010lx], pUnkOuter=%#010lx)\n", ddraw4_hooks[hpos].name, ppvOut, lpDDSurfaceDesc, lplpDDSurface4, (lplpDDSurface4 != NULL ? *lplpDDSurface4 : NULL), pUnkOuter);
	if(lpDDSurfaceDesc != NULL)
	{
		char dwFlags_buffer[LOGBUFFER_MAX], ddscaps1_buffer[LOGBUFFER_MAX], ddpf_buffer[LOGBUFFER_MAX];
		FlagsToString(FLAGS_DDSD, CFLAGS_DDSD, lpDDSurfaceDesc->dwFlags, (char *)&dwFlags_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDSCAPS1, CFLAGS_DDSCAPS1, lpDDSurfaceDesc->ddsCaps.dwCaps, (char *)&ddscaps1_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDPF, CFLAGS_DDPF, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, (char *)&ddpf_buffer, LOGBUFFER_MAX);

		Log("->lpDDSurfaceDesc { dwSize=%#010lx, dwFlags=%#010lx (%s), dwWidth=%#010lx (%d), dwHeight=%#010lx (%d), lPitch=%#010lx , dwLinearSize=%#010lx, dwBackBufferCount=%#010lx, dwMipMapCount=%#010lx, dwRefreshRate=%#010lx, dwAlphaBitDepth=%#010lx, dwReserved=%#010lx,\n"
			"  lpSurface=%#010lx, ddckCKDestOverlay={ %#010lx, %#010lx }, ddckCKDestBlt={ %#010lx, %#010lx }, ddckCKSrcOverlay={ %#010lx, %#010lx }, ddckCKSrcBlt={ %#010lx, %#010lx },\n"
			"  ddpfPixelFormat={ dwSize=%#010lx, dwFlags=%#010lx (%s), dwFourCC=%#010lx, dwRGBBitCount=%#010lx, dwYUVBitCount=%#010lx, dwZBufferBitDepth=%#010lx, dwAlphaBitDepth=%#010lx, dwLuminanceBitCount=%#010lx, dwBumpBitCount=%#010lx, dwRBitMask=%#010lx,\n"
			"    dwYBitMask=%#010lx, dwStencilBitDepth=%#010lx, dwLuminanceBitMask=%#010lx, dwBumpDuBitMask=%#010lx, dwGBitMask=%#010lx, dwUBitMask=%#010lx, dwZBitMask=%#010lx, dwBumpDvBitMask=%#010lx, dwBBitMask=%#010lx, dwVBitMask=%#010lx, dwStencilBitMask=%#010lx,\n"
			"    dwBumpLuminanceBitMask=%#010lx, dwRGBAlphaBitMask=%#010lx, dwYUVAlphaBitMask=%#010lx, dwLuminanceAlphaBitMask=%#010lx, dwRGBZBitMask=%#010lx, dwYUVZBitMask=%#010lx },\n"
			"  ddsCaps={ %#010lx (%s), %#010lx, %#010lx, %#010lx }, dwTextureStage=%#010lx }\n",
			lpDDSurfaceDesc->dwSize, lpDDSurfaceDesc->dwFlags, dwFlags_buffer, lpDDSurfaceDesc->dwWidth, (unsigned int)lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, (unsigned int)lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->lPitch,
			lpDDSurfaceDesc->dwLinearSize, lpDDSurfaceDesc->dwBackBufferCount, lpDDSurfaceDesc->dwMipMapCount, lpDDSurfaceDesc->dwRefreshRate, lpDDSurfaceDesc->dwAlphaBitDepth, lpDDSurfaceDesc->dwReserved, lpDDSurfaceDesc->lpSurface,
			lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceHighValue,
			lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue,
			
			lpDDSurfaceDesc->ddpfPixelFormat.dwSize, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, ddpf_buffer, lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDuBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwUBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwZBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDvBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwVBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask,
			
			lpDDSurfaceDesc->ddsCaps.dwCaps, ddscaps1_buffer, lpDDSurfaceDesc->ddsCaps.dwCaps2, lpDDSurfaceDesc->ddsCaps.dwCaps3, lpDDSurfaceDesc->ddsCaps.dwCaps4, lpDDSurfaceDesc->dwTextureStage
		);
	}
	if(ishooked_ddrawsurface4_hooks == false)
	{
		HookVTBLCalls((LPVOID *)lplpDDSurface4, ddrawsurface4_hooks, count_ddrawsurface4_hooks, "IDirectDrawSurface4");
		ishooked_ddrawsurface4_hooks = true;
	}

	// ------------------------------------------------------------------
	// Create a DirectX window
	// ----------------------------
#ifdef FF8_WINDOWED
	if((void *)lpDDSurfaceDesc == (void *)0x00134658)
	{
		Log("IF[lpDDSurfaceDesc == 0x00134658] THEN\n");
		if(SUCCEEDED(ret))
		{

			LPDIRECTDRAWCLIPPER pcClipper;
			if(FAILED(((LPDIRECTDRAW4)ppvOut)->CreateClipper(0, &pcClipper, NULL)))
			{
				Log("ERROR: Couldn't create clipper\n");
			}

			// Associate the clipper with the window
			Log("g_hwnd=%#01lx\n", g_hwnd);
			pcClipper->SetHWnd(0, g_hwnd);
			(*lplpDDSurface4)->SetClipper(pcClipper);
			//SAFE_RELEASE(pcClipper);

			HRESULT hr = 0;
			LPDIRECTDRAWSURFACE4 lpddsB = NULL;
			LPDIRECTDRAWSURFACE4 lpddsZ = NULL;
			DDSURFACEDESC2 ddsd;
			ZeroMemory(&ddsd, sizeof(ddsd));
			ddsd.dwSize = sizeof(ddsd);
			ddsd.dwFlags = (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT);
			ddsd.ddsCaps.dwCaps    = (lpDDSurfaceDesc->ddsCaps.dwCaps);
			ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE);
			ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN);
			ddsd.dwWidth           = 640;
			ddsd.dwHeight          = 480;
			//hRes = lpdd->lpVtbl->CreateSurface(lpdd, &ddsd, &lpddZBuffer,NULL);
			hr = ((LPDIRECTDRAW4)ppvOut)->CreateSurface(&ddsd, &lpddsB, NULL);
			if(FAILED(hr))
			{
				Log("ERROR: Failed to create WINDOWED backbuffer!");
			} else {
				//hr = (*lplpDDSurface4)->AddAttachedSurface(lpddsB);
				//if(FAILED(hr)) {
				//	Log("ERROR: Failed to attach WINDOWED backbuffer to frontbuffer!");
				//} else {
					g_frontbuffer = (*lplpDDSurface4);
					g_backbuffer = lpddsB;
					/*hr = ((LPDIRECTDRAW4)ppvOut)->CreateSurface(&ddsd, &lpddsZ, NULL);
					if(FAILED(hr)) {
						Log("ERROR: Failed to create WINDOWED z-buffer!");
					} else {
						hr = lpddsB->AddAttachedSurface(lpddsZ);
						if(FAILED(hr)) {
							Log("ERROR: Failed to attach WINDOWED z-buffer to backbuffer!");
						} else {
							
						}
					}*/
				//}
			}
		}
	}
#endif
	// ----------------------------------

	return ret;
}
// 비디오 모드 전환
BOOL SetDisplayModeWin( HWND hWnd, DWORD Width, DWORD Height, DWORD BPP )
{
    // Set Cooperative Level

	
    HRESULT hresult = lpDD->SetCooperativeLevel( hWnd,DDSCL_NORMAL );

    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->SetCooperativeLevel" );
        return FALSE;
	}


    // Primary Surface 생성
    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof( ddsd ) );

    ddsd.dwSize             = sizeof(ddsd);
    ddsd.ddsCaps.dwCaps     = DDSCAPS_PRIMARYSURFACE |
                              DDSCAPS_3DDEVICE;

    // Primary surface 생성
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSPrimary)" );
        return FALSE;
	}


	int w,h;
	RECT lpRect;
	GetWindowRect( GetDesktopWindow() , &lpRect );
	w = lpRect.right - lpRect.left;
	h = lpRect.bottom - lpRect.top;

	// 백 버퍼 1 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
	ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE| DDSCAPS_VIDEOMEMORY;
    ddsd.dwWidth  = w;
    ddsd.dwHeight = h;
    lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL);

	lpDD->CreateClipper( 0, &lpDDClipper , NULL );
	lpDDClipper->SetHWnd( 0, hWnd );
	lpDDSPrimary->SetClipper( lpDDClipper );
	lpDDClipper->Release();


	DDPIXELFORMAT	ddpx;
    // z-buffer Surface 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
    ddsd.dwSize            = sizeof(ddsd);
    ddsd.dwFlags           = DDSD_CAPS |
                             DDSD_WIDTH |
                             DDSD_HEIGHT|
                             DDSD_PIXELFORMAT;

    ddsd.dwWidth           = w;
    ddsd.dwHeight          = h;

	lpD3D->EnumZBufferFormats( lpD3DDeviceDesc->guid , EnumZBufferCallback , (VOID *)&ddpx );

	memcpy( &ddsd.ddpfPixelFormat , &ddpx , sizeof( DDPIXELFORMAT ) );

	//######################################################################################
	//작 성 자 : 오 영 석
	::CopyMemory( &g_ddpfPixelFormatZ, &ddsd.ddpfPixelFormat, sizeof(g_ddpfPixelFormatZ) );
	//######################################################################################

    // 하드웨어 이면 z-buffer를 비디오 메모리에 만든다.
    if ( lpD3DDeviceDesc->bIsHardware )
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
    else
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;

    // Create the ZBuffer surface.
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSZBuffer, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSZBuffer)" );
        return FALSE;
	}

    // Back Surface에 Z-buffer를 붙인다.
    hresult = lpDDSBack->AddAttachedSurface( lpDDSZBuffer );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSBack->AddAttachedSurface" );
        return FALSE;
	}

    // Direct3D Device 생성
    hresult = lpD3D->CreateDevice( lpD3DDeviceDesc->guid,
									lpDDSBack,
									&lpD3DDevice,
									NULL );
    if ( hresult != D3D_OK )
	{
		MESSAGE( "lpD3D->CreateDevice" );
        return FALSE;
	}

    // Viewport 크기 설정
    D3DRect.x1 = 0;
    D3DRect.y1 = 0;
    D3DRect.x2 = w;
    D3DRect.y2 = h;

	smScreenWidth = Width;
	smScreenHeight = Height;

	return TRUE;
}
Beispiel #20
0
BOOL _GameMode( HINSTANCE hInstance, int nCmdShow, int x, int y, int bpp )
{
    HRESULT result;
    WNDCLASS wc;
    DDSURFACEDESC ddsd;
    DDSCAPS ddscaps;
    LPDIRECTDRAW pdd;

    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = GetStockBrush(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "EXAM3";
    RegisterClass( &wc );

    MainHwnd = CreateWindowEx (
            0, "EXAM3", NULL, WS_POPUP, 0, 0,
            GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
            NULL, NULL, hInstance, NULL );


    if ( !MainHwnd ) return FALSE;

    SetFocus( MainHwnd );
    ShowWindow( MainHwnd, nCmdShow );
    UpdateWindow( MainHwnd );
    ShowCursor( FALSE );

    result = DirectDrawCreate( NULL, &pdd, NULL );
    if ( result != DD_OK ) return Fail( MainHwnd );

    result = pdd->QueryInterface(IID_IDirectDraw, (LPVOID *) &DirectOBJ);
    if ( result != DD_OK ) return Fail( MainHwnd );

	gWidth=x;
	gHeight=y;

	// 윈도우 핸들의 협력 단계를 설정한다.
	if(gFullScreen){
	    result = DirectOBJ->SetCooperativeLevel( MainHwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
		if ( result != DD_OK ) return Fail( MainHwnd );

		result = DirectOBJ->SetDisplayMode( x, y, bpp);
		if ( result != DD_OK ) return Fail( MainHwnd );

		memset( &ddsd, 0, sizeof(ddsd) );
		ddsd.dwSize = sizeof( ddsd );
		ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
		ddsd.dwBackBufferCount = 1;

	    result = DirectOBJ -> CreateSurface( &ddsd, &RealScreen, NULL );
	   if ( result != DD_OK ) return Fail( MainHwnd );

		memset( &ddscaps, 0, sizeof(ddscaps) );
		ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
		result = RealScreen -> GetAttachedSurface( &ddscaps, &BackScreen );
		if ( result != DD_OK ) return Fail( MainHwnd );

	}
	else{
	    result = DirectOBJ->SetCooperativeLevel( MainHwnd, DDSCL_NORMAL );
		if ( result != DD_OK ) return Fail( MainHwnd );

		memset( &ddsd, 0, sizeof(ddsd) );
	    ddsd.dwSize = sizeof( ddsd );
		ddsd.dwFlags = DDSD_CAPS;
	    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
		ddsd.dwBackBufferCount = 0;

		result = DirectOBJ -> CreateSurface( &ddsd, &RealScreen, NULL );
	    if(result != DD_OK) return Fail(MainHwnd);

		memset( &ddsd, 0, sizeof(ddsd) );
		ddsd.dwSize = sizeof(ddsd);
	    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
		ddsd.dwWidth = x; 
		ddsd.dwHeight = y;
		result = DirectOBJ->CreateSurface( &ddsd, &BackScreen, NULL );
		if ( result != DD_OK ) return Fail( MainHwnd );

		result = DirectOBJ->CreateClipper( 0, &ClipScreen, NULL);
		if ( result != DD_OK ) return Fail( MainHwnd );

		result = ClipScreen->SetHWnd( 0, MainHwnd );
		if ( result != DD_OK ) return Fail( MainHwnd );

		result = RealScreen->SetClipper( ClipScreen );
		if ( result != DD_OK ) return Fail( MainHwnd );

		SetWindowPos(MainHwnd, NULL, 100, 100, x, y, SWP_NOZORDER | SWP_NOACTIVATE); 
	}


    return TRUE;
}
static HRESULT CreateWindowedDisplay(HWND hWnd, DWORD dwWidth, DWORD dwHeight)
{
	// Set cooperative level
	if (FAILED(lpdd->SetCooperativeLevel(hWnd, DDSCL_NORMAL)))
	{
		return E_FAIL;
	}

	RECT  rcWork;
	RECT  rc;
	DWORD dwStyle;
	// If we are still a WS_POPUP window
	// We should convert to a normal app window so we look like a windows app.
	dwStyle = GetWindowLong(hWnd, GWL_STYLE);
	dwStyle &= ~WS_POPUP;
	dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
	SetWindowLong(hWnd, GWL_STYLE, dwStyle);
	// Adapt window size
	SetRect(&rc, 0, 0, dwWidth, dwHeight);
	AdjustWindowRectEx(&rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL, GetWindowExStyle(hWnd));
	SetWindowPos(hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
	SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
	// Make sure our window does not hang outside of the work area
	SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
	GetWindowRect(hWnd, &rc);
	if (rc.left < rcWork.left) rc.left = rcWork.left;
	if (rc.top < rcWork.top)  rc.top = rcWork.top;
	SetWindowPos(hWnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);

	// Create the primary surface
	DDSURFACEDESC2 ddsd;
	DDRAW_INIT_STRUCT(ddsd);
	ddsd.dwFlags = DDSD_CAPS;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsMain, NULL)))
	{
		return E_FAIL;
	}
	// Create the backbuffer surface
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
	ddsd.dwWidth = dwWidth;
	ddsd.dwHeight = dwHeight;
	if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsBack, NULL)))
	{
		return E_FAIL;
	}

	// Set surface color key
	DDCOLORKEY ddCK;
	ddCK.dwColorSpaceLowValue = 0;
	ddCK.dwColorSpaceHighValue = 0;
	if (lpddsBack->SetColorKey(DDCKEY_SRCBLT, &ddCK))
	{
		return E_FAIL;
	}

	// Create clipper for the primary surface
	LPDIRECTDRAWCLIPPER lpClipper;
	if (FAILED(lpdd->CreateClipper(0, &lpClipper, NULL)))
	{
		return E_FAIL;
	}
	if (FAILED(lpClipper->SetHWnd(0, hWnd)))
	{
		lpClipper->Release();
		return E_FAIL;
	}
	if (FAILED(lpddsMain->SetClipper(lpClipper)))
	{
		lpClipper->Release();
		return E_FAIL;
	}
	lpClipper->Release();
	lpClipper = NULL;

	// Update window flag
	SetClassLong(hWnd, GCL_HICONSM, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONSM)));
	SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONSM)));
	UpdateWindow(hWnd);

	return S_OK;
}
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,
                                         int num_rects,
                                         LPRECT clip_list)

{
// this function creates a clipper from the sent clip list and attaches
// it to the sent surface

int index;                         // looping var
LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper
LPRGNDATA region_data;             // pointer to the region data that contains
                                   // the header and clip list

// first create the direct draw clipper
if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
   return(NULL);

// now create the clip list from the sent data

// first allocate memory for region data
region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));

// now copy the rects into region data
memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);

// set up fields of header
region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);
region_data->rdh.iType           = RDH_RECTANGLES;
region_data->rdh.nCount          = num_rects;
region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);

region_data->rdh.rcBound.left    =  64000;
region_data->rdh.rcBound.top     =  64000;
region_data->rdh.rcBound.right   = -64000;
region_data->rdh.rcBound.bottom  = -64000;

// find bounds of all clipping regions
for (index=0; index<num_rects; index++)
    {
    // test if the next rectangle unioned with the current bound is larger
    if (clip_list[index].left < region_data->rdh.rcBound.left)
       region_data->rdh.rcBound.left = clip_list[index].left;

    if (clip_list[index].right > region_data->rdh.rcBound.right)
       region_data->rdh.rcBound.right = clip_list[index].right;

    if (clip_list[index].top < region_data->rdh.rcBound.top)
       region_data->rdh.rcBound.top = clip_list[index].top;

    if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
       region_data->rdh.rcBound.bottom = clip_list[index].bottom;

    } // end for index

// now we have computed the bounding rectangle region and set up the data
// now let's set the clipping list

if (FAILED(lpddclipper->SetClipList(region_data, 0)))
   {
   // release memory and return error
   free(region_data);
   return(NULL);
   } // end if

// now attach the clipper to the surface
if (FAILED(lpdds->SetClipper(lpddclipper)))
   {
   // release memory and return error
   free(region_data);
   return(NULL);
   } // end if

// all is well, so release memory and send back the pointer to the new clipper
free(region_data);
return(lpddclipper);

} // end DDraw_Attach_Clipper
Beispiel #23
0
int DDInit(void)
{
        HRESULT hRet;

        hWnd = Form1->Handle;

        DDEnd();
        hRet = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);
        if(DDError(hRet != DD_OK,"DDCreateEX")) return(false);

        if (Form1->FullScreen)
        {
                hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
                hRet = m_pDD->SetDisplayMode(FScreen.Width, FScreen.Height, FScreen.Bpp,NULL,NULL);

        }
        else    hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
        if(DDError(hRet != DD_OK,"DDSetCoop")) return(false);

        HRESULT hr;

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

        if(DDError(hr = m_pDD->CreateSurface(&ddsd, &m_pddsFrontBuffer, NULL)
                ,"CreateFrontSurface")) return(false);

        // Create the backbuffer surface
        ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
        ddsd.dwWidth = 1024;
        ddsd.dwHeight = 768;

        hr = m_pDD->CreateSurface(&ddsd, &m_pddsFrame, NULL);
        if (hr)
        {
                ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
                ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
                ddsd.dwWidth = 460;
                ddsd.dwHeight = 400;
                hr = m_pDD->CreateSurface(&ddsd, &m_pddsFrame, NULL);
                if(DDError(hr,"CreateBackSurface")) return(false);
                tv.DisableAdvanced=1;
        }

        if (!Form1->FullScreen)
        {
                if(DDError(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)
                        ,"CreateClipper")) return(false);

                if(DDError(hr = pcClipper->SetHWnd(0, hWnd)
                        ,"SetClipperHwnd"))
                {
                        pcClipper->Release();
                        return(false);
                }


                if(DDError(hr = m_pddsFrontBuffer->SetClipper(pcClipper)
                        ,"SetClipperSurface"))
                {
                        pcClipper->Release();
                        return(false);
                }
        }

        return(true);
}
Beispiel #24
0
//-----------------------------------------------------------------------------
// Name: InitGraphics()
// Desc:
//-----------------------------------------------------------------------------
HRESULT InitGraphics()
{
    DDCAPS          ddcaps;
    HRESULT         hr;
    DDSURFACEDESC   ddsd;
    DDSCAPS         ddscaps;

    // Create a window
    g_hwndMain = CreateWindowEx( WS_EX_APPWINDOW, TEXT("DuelClass"),
                                 TEXT("Duel"), WS_POPUP | WS_SYSMENU, 0, 0, 
                                 GetSystemMetrics(SM_CXSCREEN),
                                 GetSystemMetrics(SM_CYSCREEN),
                                 NULL, NULL, g_hInst, NULL );
    if( NULL == g_hwndMain )
        return E_FAIL;

    UpdateWindow( g_hwndMain );
    SetFocus( g_hwndMain );

    // DDraw stuff begins here
    if( FAILED( hr = DirectDrawCreate( NULL, &g_pDD, NULL ) ) )
    {
        ShowError(IDS_DDRAW_ERROR_DDC);
        return E_FAIL;
    }

    // Set access mode based on fullscreen/window
    if( g_bFullscreen ) 
    {
        hr = g_pDD->SetCooperativeLevel( g_hwndMain,
                            DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
    }
    else
    {
        hr = g_pDD->SetCooperativeLevel( g_hwndMain,
                            DDSCL_NORMAL);
    }

    if( FAILED(hr) )
    {
        ShowError(IDS_DDRAW_ERROR_SCL);
        return E_FAIL;
    }

    if( g_bFullscreen )
    {
        // Set the mode to 640 by 480 by 8
        if( FAILED( g_pDD->SetDisplayMode( 640, 480, 8 ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_SDM);
            return E_FAIL;
        }
    }
    else
    {
        RECT  rcWork;
        RECT  rc;
        DWORD dwStyle;

        // If we are still a WS_POPUP window we should convert to a
        // normal app window so we look like a windows app.
        dwStyle  = GetWindowStyle(g_hwndMain);
        dwStyle &= ~WS_POPUP;
        dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
        SetWindowLong( g_hwndMain, GWL_STYLE, dwStyle );

        // Aet window size
        SetRect( &rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y );

        AdjustWindowRectEx( &rc, GetWindowStyle(g_hwndMain),
                            GetMenu(g_hwndMain) != NULL,
                            GetWindowExStyle(g_hwndMain) );

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

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

        //  Make sure our window does not hang outside of the work area
        SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
        GetWindowRect( g_hwndMain, &rc );
        if( rc.left < rcWork.left ) rc.left = rcWork.left;
        if( rc.top  < rcWork.top )  rc.top  = rcWork.top;
        SetWindowPos( g_hwndMain, NULL, rc.left, rc.top, 0, 0,
                      SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
    }

    // Check the color key hardware capabilities
    ddcaps.dwSize = sizeof( ddcaps );
    memset( &ddsd, 0, sizeof( ddsd ) );
    ddsd.dwSize = sizeof( ddsd );

    if( g_bFullscreen )
    {
        // Create surfaces
        ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
                              DDSCAPS_FLIP |
                              DDSCAPS_COMPLEX;
        ddsd.dwBackBufferCount = 1;
        if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer,
                                               NULL ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
            return E_FAIL;
        }

        // Get a pointer to the back buffer
        ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
        if( FAILED( hr = g_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
                                                         &g_pddsBackBuffer ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_GAS);
            return E_FAIL;
        }
    }
    else
    {
        LPDIRECTDRAWCLIPPER pcClipper;
        
        // Window case, create the primary surface
        // and create a backbuffer in offscreen memory
        ddsd.dwFlags = DDSD_CAPS;
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

        if( FAILED( g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer, NULL ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
            return E_FAIL;
        }

        ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
        ddsd.dwWidth = MAX_DEFWIN_X;
        ddsd.dwHeight = MAX_DEFWIN_Y;
        if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
            return E_FAIL;
        }

        if( FAILED( hr = g_pDD->CreateClipper( 0, &pcClipper, NULL) ) )
        {
            ShowError(IDS_DDRAW_ERROR_CC);
            return E_FAIL;
        }

        if( FAILED( hr = pcClipper->SetHWnd( 0, g_hwndMain) ) )
        {
            pcClipper->Release();
            ShowError(IDS_DDRAW_ERROR_SH);
            return E_FAIL;
        }

        if( FAILED( hr = g_pddsFrontBuffer->SetClipper( pcClipper) ) )
        {
            pcClipper->Release();
            ShowError(IDS_DDRAW_ERROR_SC);
            return E_FAIL;
        }

        // Done with clipper
        pcClipper->Release();
    }

    ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; 
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

    ddsd.dwWidth  = 320;
    ddsd.dwHeight = 128;
    
    for( DWORD i=0; i<4; i++ )
    {
        if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsShip[i], NULL ) ) )
        {
            ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
            return E_FAIL;
        }   
    }

    ddsd.dwHeight = 16;
    if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsNumbers, NULL ) ) )
    {
        ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
        return E_FAIL;
    }

    if( FAILED( RestoreSurfaces() ) )
    {
        ShowError(IDS_DDRAW_ERROR_RS);
        return E_FAIL;
    }
    
    g_dwKeys = 0;
    ShowWindow( g_hwndMain, SW_SHOW);
    return S_OK;
}
Beispiel #25
0
/**
 * vdraw_ddraw_init(): Initialize the DirectDraw video subsystem.
 * @return 0 on success; non-zero on error.
 */
int vdraw_ddraw_init(void)
{
	DDSURFACEDESC2 ddsd;
	
	vdraw_ddraw_end();
	
	mdp_render_t *rendMode = get_mdp_render_t();
	const int scale = rendMode->scale;
	
	// Determine the window size using the scaling factor.
	if (scale <= 0)
		return -1;
	const int w = 320 * scale;
	const int h = 240 * scale;
	
	if (vdraw_get_fullscreen())
	{
		Res_X = w;
		Res_Y = h;
	}
	
	// Return value.
	int rval;
	
	// Initialize DirectDraw.
	// TODO: Initialize DirectDraw on the monitor with most of Gens/GS onscreen.
	LPDIRECTDRAW lpDD_Init;
	rval = DirectDrawCreate(NULL, &lpDD_Init, NULL);
	if (FAILED(rval))
	{
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"DirectDrawCreate() failed: 0x%08X", rval);
		return -2;
	}
	
	rval = lpDD_Init->QueryInterface(IID_IDirectDraw7, (LPVOID*)&lpDD);
	if (FAILED(rval))
	{
		if (lpDD_Init)
			lpDD_Init->Release();
		
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"lpDD_Init->QueryInterface(IID_IDirectDraw4) failed: 0x%08X", rval);
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"This can usually be fixed by upgrading DirectX.");
		return -3;
	}
	
	// Free the DirectDraw initialization object.
	lpDD_Init->Release();
	
	// Set the cooperative level.
	vdraw_ddraw_set_cooperative_level();
	
	// TODO: 15-bit color override. ("Force 555" or "Force 565" in the config file.)
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	// TODO: Figure out what FS_No_Res_Change is for.
	// TODO: Figure out if this is correct.
	if (vdraw_get_fullscreen() /* && !FS_No_Res_Change*/)
	{
		// Use the color depth setting.
		// NOTE: "15-bit" color requires 16-bit to be specified.
		rval = lpDD->SetDisplayMode(Res_X, Res_Y, (bppOut == 15 ? 16 : bppOut), 0, 0);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->SetDisplayMode() failed: 0x%08X", rval);
			
			// If render mode is set to Normal, try using Double instead.
			if (rendMode_FS == RenderMgr::begin() && rendMode_FS != RenderMgr::end())
			{
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"Renderer is set to Normal; attempting to use Double instead.");
				rendMode_FS++;
				vdraw_set_renderer(rendMode_FS);
				vdraw_text_write("Normal rendering failed. Using Double.", 1500);
				Sync_Gens_Window_GraphicsMenu();
			}
			
			return -4;
		}
	}
	
#if 0
	// Check the current color depth.
	unsigned char newBpp;
	lpDD->GetDisplayMode(&ddsd);
	switch (ddsd.ddpfPixelFormat.dwGBitMask)
	{
		case 0x03E0:
			// 15-bit color.
			newBpp = 15;
			break;
		case 0x07E0:
			// 16-bit color.
			newBpp = 16;
			break;
		case 0x00FF00:
		default:
			// 32-bit color.
			newBpp = 32;
			break;
	}
	
	if (newBpp != bppOut)
		vdraw_set_bpp(newBpp, false);
#endif
	
	// Clear ddsd.
	memset(&ddsd, 0x00, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	if (vdraw_get_fullscreen() && Video.VSync_FS)
	{
		ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
		ddsd.dwBackBufferCount = 2;
	}
	else
	{
		ddsd.dwFlags = DDSD_CAPS;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	}
	
	// Create the primary surface.
	rval = lpDD->CreateSurface(&ddsd, &lpDDS_Primary, NULL);
	if (FAILED(rval))
	{
		vdraw_ddraw_free_all(false);
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"lpDD->CreateSurface(&lpDDS_Primary) failed: 0x%08X", rval);
		return -5;
	}
	
	if (vdraw_get_fullscreen())
	{
		if (Video.VSync_FS)
		{
			ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
			
			rval = lpDDS_Primary->GetAttachedSurface(&ddsd.ddsCaps, &lpDDS_Flip);
			if (FAILED(rval))
			{
				vdraw_ddraw_free_all(false);
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"lpDDS_Primary->GetAttachSurface() failed: 0x%08X", rval);
				return -6;
			}
			
			lpDDS_Blit = lpDDS_Flip;
		}
		else
		{
			lpDDS_Blit = lpDDS_Primary;
		}
	}
	else
	{
		rval = lpDD->CreateClipper(0, &lpDDC_Clipper, NULL);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateClipper() failed: 0x%08X", rval);
			return -7;
		}
		
		rval = lpDDC_Clipper->SetHWnd(0, gens_window);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDC_Clipper->SetHWnd() failed: 0x%08X", rval);
			return -8;
		}
		
		rval = lpDDS_Primary->SetClipper(lpDDC_Clipper);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDC_Primary->SetClipper() failed: 0x%08X", rval);
			return -9;
		}
	}
	
	// Clear ddsd again.
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
	
	// Determine the width and height.
	// NOTE: For DirectDraw, the actual 336 width is used.
	if (vdraw_ddraw_is_hw_render())
	{
		// Normal render mode. 320x240 [336x240]
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
		ddsd.dwWidth = 336;
		ddsd.dwHeight = 240;
	}
	else
	{
		// Larger than 1x.
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
		ddsd.dwWidth = w;
		ddsd.dwHeight = h;
	}
	
	// Set the pixel format.
	ddsd.dwFlags |= DDSD_PIXELFORMAT;
	ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
	ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
	ddsd.ddpfPixelFormat.dwFourCC = 0; // RGB
	ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0;
	
	// Bits per component.
	switch (bppOut)
	{
		case 15:
			// 15-bit color. (555)
			ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
			ddsd.ddpfPixelFormat.dwRBitMask = 0x7C00;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x03E0;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
			break;
		
		case 16:
			// 16-bit color. (555)
			ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
			ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
			break;
		
		case 32:
		default:
			// 32-bit color.
			ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
			ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x00FF00;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x0000FF;
			break;
	}
	
	// Create the back surface.
	rval = lpDD->CreateSurface(&ddsd, &lpDDS_Back, NULL);
	if (FAILED(rval))
	{
		// Failed to create the back surface.
		// If we attempted to create it in video memory, try system memory instead.
		if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
		{
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_VIDEOMEMORY) failed: 0x%08X", rval);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"Attempting to use DDSCAPS_SYSTEMMEMORY instead.");
			ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
			ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
			rval = lpDD->CreateSurface(&ddsd, &lpDDS_Back, NULL);
			if (FAILED(rval))
			{
				// Failed to create the back surface in system memory.
				vdraw_ddraw_free_all(false);
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_SYSTEMMEMORY) failed: 0x%08X", rval);
				return -10;
			}
		}
		else
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_SYSTEMMEMORY) failed: 0x%08X", rval);
			return -11;
		}
	}
	
	// TODO: Check if this is right.
	// I think this might be causing the frame counter flicker in full screen mode.
	//if (!vdraw_get_fullscreen() || (rendMode >= 1 && (/*FS_No_Res_Change ||*/ Res_X != 640 || Res_Y != 480)))
	if (!vdraw_get_fullscreen() || !vdraw_ddraw_is_hw_render())
		lpDDS_Blit = lpDDS_Back;
	
	if (vdraw_ddraw_is_hw_render())
	{
		// Normal rendering mode uses MD_Screen directly.
		memset(&ddsd, 0, sizeof(ddsd));
		ddsd.dwSize = sizeof(ddsd);
		
		// TODO: This causes issues if the selected color depth isn't the
		// same as the desktop color depth. This only affects windowed mode,
		// since in fullscreen, the desktop color depth is changed.
		rval = lpDDS_Back->GetSurfaceDesc(&ddsd);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDS_Back->GetSurfaceDesc() failed: 0x%08X", rval);
			return -12;
		}
		
		ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE | DDSD_PIXELFORMAT;
		ddsd.dwWidth = 336;
		ddsd.dwHeight = 240;
		
		if (ddsd.ddpfPixelFormat.dwRGBBitCount > 16)
		{
			// 32-bit color.
			ddsd.lpSurface = MD_Screen.u32;
			ddsd.lPitch = 336 * 4;
		}
		else
		{
			// 15-bit or 16-bit color.
			ddsd.lpSurface = MD_Screen.u16;
			ddsd.lPitch = 336 * 2;
		}
		
		rval = lpDDS_Back->SetSurfaceDesc(&ddsd, 0);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDS_Back->SetSurfaceDesc() failed: 0x%08X", rval);
			return -13;
		}
	}
	
	// Initialize the destination rectangle.
	vdraw_ddraw_adjust_RectDest();
	
	// Reset the render mode.
	vdraw_reset_renderer(false);
	
	// Synchronize menus.
	Sync_Gens_Window();
	
	// vdraw_ddraw initialized.
	return 0;
}
Beispiel #26
0
//-----------------------------------------------------------------------------
// Name: CreateWindowedDisplay()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
{
    HRESULT hr;

    // Cleanup anything from a previous call
    DestroyObjects();

    // DDraw stuff begins here
    if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
                                         IID_IDirectDraw7, NULL ) ) )
        return E_FAIL;

    // Set cooperative level
    hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
    if( FAILED(hr) )
        return E_FAIL;

    RECT  rcWork;
    RECT  rc;
    DWORD dwStyle;

    // If we are still a WS_POPUP window we should convert to a normal app
    // window so we look like a windows app.
    dwStyle  = GetWindowStyle( hWnd );
    dwStyle &= ~WS_POPUP;
    dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
    SetWindowLong( hWnd, GWL_STYLE, dwStyle );

    // Aet window size
    SetRect( &rc, 0, 0, dwWidth, dwHeight );

    AdjustWindowRectEx( &rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL,
                        GetWindowExStyle(hWnd) );

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

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

    //  Make sure our window does not hang outside of the work area
    SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
    GetWindowRect( hWnd, &rc );
    if( rc.left < rcWork.left ) rc.left = rcWork.left;
    if( rc.top  < rcWork.top )  rc.top  = rcWork.top;
    SetWindowPos( hWnd, NULL, rc.left, rc.top, 0, 0,
                  SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );

    LPDIRECTDRAWCLIPPER pcClipper;
    
    // Create the primary surface
    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof( ddsd ) );
    ddsd.dwSize         = sizeof( ddsd );
    ddsd.dwFlags        = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
        return E_FAIL;

    // Create the backbuffer surface
    ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
    ddsd.dwWidth        = dwWidth;
    ddsd.dwHeight       = dwHeight;

    if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
        return E_FAIL;

    if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
        return E_FAIL;

    if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
    {
        pcClipper->Release();
        return E_FAIL;
    }

    if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
    {
        pcClipper->Release();
        return E_FAIL;
    }

    // Done with clipper
    pcClipper->Release();

    m_hWnd      = hWnd;
    m_bWindowed = TRUE;
    UpdateBounds();

    return S_OK;
}
ErrorType MyDrawEngine::SetClipper(int numRects, LPRECT clipList)
{
	int i;								// For loops
	LPDIRECTDRAWCLIPPER theDDClipper;	// The DirectDraw clipper
	LPRGNDATA regionData;				// Pointer to region data

	// Create the clipper, and if it fails, return zero
	HRESULT err=lpdd->CreateClipper(0,&theDDClipper,NULL);
	if(FAILED(err))
	{
		ErrorLogger::Writeln("Failed to create clipper.");
		ErrorLogger::Writeln(ErrorString(err));
		return FAILURE;
	}

	// Allocate some memory for the region data, and store location in regionData
	regionData = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+numRects*sizeof(RECT));

	// Copy the rects into that memory area
	memcpy(regionData->Buffer, clipList, sizeof(RECT)*numRects);

	// Set up the header data in the regionData
	regionData->rdh.dwSize = sizeof(RGNDATAHEADER); // Set the size of the header
	regionData->rdh.iType  = RDH_RECTANGLES;		// Region stores data about rectangles
	regionData->rdh.nCount = numRects;				// Set number of regions
	regionData->rdh.nRgnSize = numRects*sizeof(RECT);	// Storing the size of the region data

	// Set some impossible bounding values for the regionData's bounding box
	regionData->rdh.rcBound.left   =  50000;
	regionData->rdh.rcBound.right  = -50000;
	regionData->rdh.rcBound.top	   =  50000;
	regionData->rdh.rcBound.bottom = -50000;

	// Now cycle through the rects sent to refine these values, so that they
	//  specify a box that surrounds all the individual rects
	for (i=0;i<numRects;i++)
	{
		if (clipList[i].left < regionData->rdh.rcBound.left)
			regionData->rdh.rcBound.left = clipList[i].left;
		if (clipList[i].right > regionData->rdh.rcBound.right)
			regionData->rdh.rcBound.right = clipList[i].right;
		if (clipList[i].top < regionData->rdh.rcBound.top)
			regionData->rdh.rcBound.top = clipList[i].top;
		if (clipList[i].bottom > regionData->rdh.rcBound.bottom)
			regionData->rdh.rcBound.bottom = clipList[i].bottom;
	}

	// Set the clip list (and return error if failed)
	err=theDDClipper->SetClipList(regionData,0);
	
	if(FAILED(err))
	{
		ErrorLogger::Writeln("Failed to send clip list.");
		ErrorLogger::Writeln(ErrorString(err));
		free(regionData);
		return FAILURE;
	}


	// Attach clipper to the surface
	err=lpBackBuffer->SetClipper(theDDClipper);
	if(FAILED(err))
	{
		ErrorLogger::Writeln("Failed to set clipper.");
		ErrorLogger::Writeln(ErrorString(err));
		free(regionData);
		return FAILURE;
	}

	// All done
	free(regionData);
	return SUCCESS;
}	
// 비디오 모드 전환
BOOL SetDisplayMode( HWND hWnd, DWORD Width, DWORD Height, DWORD BPP )
{
    // Set Cooperative Level

	smTextureBPP = BPP;

	if ( WindowMode ) return SetDisplayModeWin( hWnd , Width , Height , BPP );
	
    HRESULT hresult = lpDD->SetCooperativeLevel( hWnd,
                                                  DDSCL_EXCLUSIVE |
                                                  DDSCL_FULLSCREEN |
												  DDSCL_ALLOWMODEX );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->SetCooperativeLevel" );
        return FALSE;
	}


    // 풀화면 모드로 전환
    hresult = lpDD->SetDisplayMode( Width, Height, BPP, 0, 0 );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD3->SetDisplayMode" );
        return FALSE;
	}


    // Primary Surface 생성
    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof(ddsd) );

    ddsd.dwSize             = sizeof(ddsd);
    ddsd.dwBackBufferCount  = 1;
    ddsd.dwFlags            = DDSD_CAPS |
                              DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps     = DDSCAPS_PRIMARYSURFACE |
                              DDSCAPS_FLIP |
                              DDSCAPS_COMPLEX |
                              DDSCAPS_VIDEOMEMORY |
                              DDSCAPS_3DDEVICE;

    // Primary surface 생성
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->CreateSurface(lpDDSPrimary)" );
        return FALSE;
	}

    // Back Surface 생성(?)
    DDSCAPS2 ddscaps;
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    hresult = lpDDSPrimary->GetAttachedSurface( &ddscaps, &lpDDSBack );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSPrimary->GetAttachedSurface" );
        return FALSE;
	}


	//////////// 클리퍼 생성 ////////////////////////
	lpDD->CreateClipper( 0, &lpDDClipper , NULL );
	lpDDClipper->SetHWnd( 0, hWnd );
	lpDDSPrimary->SetClipper( lpDDClipper );
	lpDDClipper->Release();



    // z-buffer Surface 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
    ddsd.dwSize            = sizeof(ddsd);
    ddsd.dwFlags           = DDSD_CAPS |
                             DDSD_WIDTH |
                             DDSD_HEIGHT |
                             DDSD_PIXELFORMAT;
    ddsd.dwWidth           = Width;
    ddsd.dwHeight          = Height;

	lpD3D->EnumZBufferFormats( IID_IDirect3DHALDevice , EnumZBufferCallback , (VOID *)&ddsd.ddpfPixelFormat );

	//######################################################################################
	//작 성 자 : 오 영 석
	::CopyMemory( &g_ddpfPixelFormatZ, &ddsd.ddpfPixelFormat, sizeof(g_ddpfPixelFormatZ) );
	//######################################################################################

    // 하드웨어 이면 z-buffer를 비디오 메모리에 만든다.
    if ( lpD3DDeviceDesc->bIsHardware )
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
    else
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;

    // Create the ZBuffer surface.
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSZBuffer, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSZBuffer)" );
        return FALSE;
	}

    // Back Surface에 Z-buffer를 붙인다.
    hresult = lpDDSBack->AddAttachedSurface( lpDDSZBuffer );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSBack->AddAttachedSurface" );
        return FALSE;
	}

    // Direct3D Device 생성
    hresult = lpD3D->CreateDevice( lpD3DDeviceDesc->guid,
                                    lpDDSBack,
                                    &lpD3DDevice,
									NULL );
    if ( hresult != D3D_OK )
	{
		MESSAGE( "lpD3D->CreateDevice" );
        return FALSE;
	}

    // Viewport 크기 설정
    D3DRect.x1 = 0;
    D3DRect.y1 = 0;
    D3DRect.x2 = Width;
    D3DRect.y2 = Height;

	smScreenWidth = Width;
	smScreenHeight = Height;

    return TRUE;
}
Beispiel #29
0
LRESULT CALLBACK DDWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	bool paintwnd = true;
	POINT p;
	RECT srcrect,destrect;
	HRESULT error;
	PAINTSTRUCT paintstruct;
	switch(Msg)
	{
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;
	case WM_DESTROY:
		StopTimer();
		for(int i = 0; i < 16; i++)
			if(sprites[i].surface) sprites[i].surface->Release();
		if(ddsrender)
		{
			ddsrender->Release();
			ddsrender = NULL;
		}
		if(ddsurface)
		{
			ddsurface->Release();
			ddsurface = NULL;
		}
		if(pal)
		{
			pal->Release();
			pal = NULL;
		}
		if(ddclipper)
		{
			ddclipper->Release();
			ddclipper = NULL;
		}
		if(ddinterface)
		{
			ddinterface->Release();
			ddinterface = NULL;
		}
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		if(wParam == VK_ESCAPE) DestroyWindow(hWnd);
		break;
	case WM_APP:
		RunTestTimed2D(testnum);
		break;
	case WM_SIZE:
		paintwnd = false;
	case WM_PAINT:
		if(paintwnd) BeginPaint(hWnd,&paintstruct);
		if(!fullscreen)
		{
			p.x = 0;
			p.y = 0;
			ClientToScreen(hWnd,&p);
			GetClientRect(hWnd,&destrect);
			OffsetRect(&destrect,p.x,p.y);
			SetRect(&srcrect,0,0,width,height);
			if(ddsurface && ddsrender)error = ddsurface->Blt(&destrect,ddsrender,&srcrect,DDBLT_WAIT,NULL);
		}
		if(paintwnd) EndPaint(hWnd,&paintstruct);
		return 0;
	case WM_MOUSEMOVE:
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_LBUTTONDBLCLK:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
	case WM_RBUTTONDBLCLK:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
	case WM_MBUTTONDBLCLK:
	case WM_MOUSEWHEEL:
	case WM_XBUTTONDOWN:
	case WM_XBUTTONUP:
	case WM_XBUTTONDBLCLK:
	case WM_MOUSEHWHEEL:
		RunTestMouse2D(testnum,Msg,wParam,lParam);
		if(!fullscreen)
		{
			p.x = 0;
			p.y = 0;
			ClientToScreen(hWnd,&p);
			GetClientRect(hWnd,&destrect);
			OffsetRect(&destrect,p.x,p.y);
			SetRect(&srcrect,0,0,width,height);
			if(ddsurface && ddsrender)error = ddsurface->Blt(&destrect,ddsrender,&srcrect,DDBLT_WAIT,NULL);
		}
		break;
	default:
		return DefWindowProc(hWnd,Msg,wParam,lParam);
	}
	return FALSE;
}
Beispiel #30
0
//-----------------------------------------------------------------------------
// Name: dx_Initialise (...)
// Desc: Initialise et configure DirectX (DirectDraw)
//-----------------------------------------------------------------------------
bool dx_Initialise (uint8  pNombreSurfaces,
                    HWND   pFenetre,
                    uint16 pResolutionX,
                    uint16 pResolutionY,
                    uint16 pBitsParPixel,
                    uint16 pFrequence,
                    bool   pPleinEcran,
                    bool   pTailleFenetre,
                    void   (*pRestaure)())
{
    // InitialiseDX a déjà été appelé

    if (DirectDraw7 != NULL) {
        return dx_Finalise (ERR_NO_UTILISATEUR);
    }

    dx_InitVars ();

    // Initialise toutes les variables

    Fenetre = pFenetre;

    NombreSurfaces = pNombreSurfaces;

    ResolutionX   = pResolutionX;
    ResolutionY   = pResolutionY;
    BitsParPixel  = pBitsParPixel;
    Frequence     = pFrequence;
    PleinEcran    = pPleinEcran;
    TailleFenetre = pTailleFenetre;

    Restaure = pRestaure;

    Surfaces = new LPDIRECTDRAWSURFACE7[NombreSurfaces];

    // Initialisation de directdraw

    ErrDd = DirectDrawCreateEx (0,(LPVOID*)&DirectDraw7,IID_IDirectDraw7,0);

    if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_CREATION);

    ModeCoop = PleinEcran ? COOP_PLEIN_ECRAN : COOP_FENETRE;

    // Utilisation de la résolution active ou donnée

    if (ResolutionX  == 0 || ResolutionY == 0 ||
            BitsParPixel == 0 || Frequence   == 0)
    {
        DDSURFACEDESC2 ModeActif;
        ZeroMemory (&ModeActif, sizeof(ModeActif));
        ModeActif.dwSize = sizeof(ModeActif);

        ErrDd = DirectDraw7->GetDisplayMode (&ModeActif);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_MODE_ACTIF);

        if (ResolutionX  == 0) ResolutionX = ModeActif.dwWidth;
        if (ResolutionY  == 0) ResolutionY = ModeActif.dwHeight;
        if (BitsParPixel == 0) BitsParPixel = ModeActif.
                                                  ddpfPixelFormat.dwRGBBitCount;
        if (Frequence == 0) Frequence = ModeActif.dwRefreshRate;
    }

    // Sélection du mode de coopération

    ErrDd = DirectDraw7->SetCooperativeLevel (Fenetre, ModeCoop);

    if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_COOPERATION);

    ErrDd = DirectDraw7->SetDisplayMode (ResolutionX,
                                         ResolutionY,BitsParPixel,0,0);

    if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_MODE_AFFICHAGE);

    // Création des surfaces d'affichage

    SurfaceDesc.dwFlags = DDSD_CAPS;
    SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    if (PleinEcran)
    {   // Surface avec backbuffer
        SurfaceDesc.dwFlags	|= DDSD_BACKBUFFERCOUNT;
        SurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
        SurfaceDesc.dwBackBufferCount = 1;
    }

    ErrDd = DirectDraw7->CreateSurface (&SurfaceDesc,&SurfacePrimaire,NULL);

    if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_PRIMAIRE);

    if (PleinEcran)
    {
        SurfaceCaps.dwCaps = DDSCAPS_BACKBUFFER;

        ErrDd = SurfacePrimaire->GetAttachedSurface (&SurfaceCaps,&SurfaceBack);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_BACKBUFFER);
    }
    else
    {
        // Surface avec clipper pour dessiner que dans la fenêtre
        ErrDd = DirectDraw7->CreateClipper (0, &SurfaceClipper, NULL);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_CLIPPER);

        // Coordonnées de la fenêtre dans le clipper
        ErrDd = SurfaceClipper->SetHWnd (0, Fenetre);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_CLIPPER_HWND);

        // Attache le clipper à la surface primaire
        ErrDd = SurfacePrimaire->SetClipper (SurfaceClipper);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_CLIPPER_PRIMAIRE);

        ZeroMemory (&SurfaceDesc, sizeof(SurfaceDesc));
        SurfaceDesc.dwSize = sizeof(SurfaceDesc);
        SurfaceDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
        SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
        SurfaceDesc.dwWidth  = ResolutionX;
        SurfaceDesc.dwHeight = ResolutionY;

        // Création du backbuffer séparément
        ErrDd = DirectDraw7->CreateSurface (&SurfaceDesc,&SurfaceBack,NULL);

        if (ErrDd != DD_OK) return dx_Finalise (ERR_NO_BACKBUFFER);
    }

    if (PleinEcran) ShowCursor (false);

    return true;
}