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; }
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; }
//----------------------------------------------------------------------------- // 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; }
//! 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; }
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; }
//----------------------------------------------------------------------------- // 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); }
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; }
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; } }
//! 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; }
/** * 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; }
//----------------------------------------------------------------------------- // 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
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); } }
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; }
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
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); }
//----------------------------------------------------------------------------- // 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; }
/** * 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; }
//----------------------------------------------------------------------------- // 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; }
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; }
//----------------------------------------------------------------------------- // 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; }