static M4Err DD_FlushVideo(VideoOutput *dr, M4Window *dest) { RECT rc; HRESULT hr; DDCONTEXT; if (!dd) return M4BadParam; if (dd->is_3D_out) { SwapBuffers(dd->gl_HDC); return M4OK; } if (!dd->ddraw_init) return M4BadParam; if (dest) { POINT pt; pt.x = dest->x; pt.y = dest->y; ClientToScreen(dd->hWnd, &pt); dest->x = pt.x; dest->y = pt.y; MAKERECT(rc, dest); hr = IDirectDrawSurface_Blt(dd->pPrimary, &rc, dd->pBack, NULL, DDBLT_WAIT, NULL ); } else { hr = IDirectDrawSurface_Blt(dd->pPrimary, NULL, dd->pBack, NULL, DDBLT_WAIT, NULL ); } if (hr == DDERR_SURFACELOST) { IDirectDrawSurface_Restore(dd->pPrimary); IDirectDrawSurface_Restore(dd->pBack); } return FAILED(hr) ? M4IOErr : M4OK; }
static boolean BltCopy( LPDIRECTDRAWSURFACE src_surface, RECT * src_rect, LPDIRECTDRAWSURFACE dst_surface, RECT * dst_rect ) { DDSURFACEDESC ddsd_target; HRESULT result; memset( &ddsd_target, 0, sizeof( ddsd_target ) ); ddsd_target.dwSize = sizeof( ddsd_target ); /* attempt to blt the surface sontents */ result = IDirectDrawSurface_Blt( dst_surface, dst_rect, src_surface, src_rect, DDBLT_WAIT, 0 ); if( result != DD_OK ) { if( result != DDERR_SURFACELOST ) { IDirectDrawSurface_Restore( src_surface ); IDirectDrawSurface_Restore( dst_surface ); IDirectDrawSurface_Blt( dst_surface, dst_rect, src_surface, src_rect, DDBLT_WAIT, 0 ); } else { Error( 0, "IDirectDrawSurface_Blt : error 0x%lx", result ); return FALSE; } } return TRUE; }
/* Display buffer */ static void PaintDD() { DWORD ddrval; if (!IsWindowVisible(hWnd) || !active || !initialized || !BackSurface[0]) return; IDirectDrawSurface_Unlock(BackSurface[0], surface[0].lpSurface); IDirectDrawSurface_Unlock(BackSurface[1], surface[1].lpSurface); if (directX == DXFULLSCREEN) { if (storeddata) free(storeddata), storeddata = NULL; storeddata = store(currentbuff ? buffer2 : buffer1, bitDepth, lineSize, displayX, displayY, mouseX, mouseY); drawmouse(currentbuff ? buffer2 : buffer1, mousepointer, bitDepth, lineSize, displayX, displayY, mouseX, mouseY); ddrval = IDirectDrawSurface_BltFast(lpSurfaces[0], 0, 0, BackSurface[currentbuff], &rcScreen, FALSE); restore(currentbuff ? buffer2 : buffer1, storeddata, bitDepth, lineSize, displayX, displayY, mouseX, mouseY); oldmouseX = mouseX; oldmouseY = mouseY; } else { ddrval = IDirectDrawSurface_Blt(lpSurfaces[0], &rcScreen, BackSurface[currentbuff], &rcViewport, DDBLT_WAIT, NULL); } if (ddrval != DD_OK) { if ((int) ddrval == (int) DDERR_SURFACELOST) { IDirectDrawSurface_Restore(lpSurfaces[0]); IDirectDrawSurface_Restore(BackSurface[0]); IDirectDrawSurface_Restore(BackSurface[1]); ddrval = IDirectDrawSurface_Blt(lpSurfaces[0], &rcScreen, BackSurface[currentbuff], &rcViewport, DDBLT_WAIT, NULL); //if (ddrval == DDERR_SURFACELOST) resized=1; /*We've lost our fractal*/ } } ddrval = IDirectDrawSurface_Lock(BackSurface[0], NULL, &surface[0], DDLOCK_WAIT, NULL); ddrval = IDirectDrawSurface_Lock(BackSurface[1], NULL, &surface[1], DDLOCK_WAIT, NULL); if (buffer1 != (char *) surface[0].lpSurface || buffer2 != (char *) surface[1].lpSurface) { DeInitDD(); x_fatalerror ("Unexpected event - buffers moved! Please contact authors!"); } needredraw = 0; }
// // Flip the real page with virtual page // - in bAppFullScreen mode, do page flipping // - in windowed mode, copy the hidden surface to the visible surface // // waitflip : if not 0, wait for page flip to end BOOL ScreenFlip(int waitflip) { HRESULT hr; RECT rect; UNREFERENCED_PARAMETER(waitflip); if (bAppFullScreen) { //hr = IDirectDrawSurface_GetFlipStatus (ScreenReal, DDGFS_); // In full-screen exclusive mode, do a hardware flip. hr = IDirectDrawSurface_Flip(ScreenReal, NULL, DDFLIP_WAIT); //return immediately // If the surface was lost, restore it. if (hr == DDERR_SURFACELOST) { IDirectDrawSurface_Restore(ScreenReal); // The restore worked, so try the flip again. hr = IDirectDrawSurface_Flip(ScreenReal, 0, DDFLIP_WAIT); } } else { rect.left = windowPosX; rect.top = windowPosY; rect.right = windowPosX + ScreenWidth - 1; rect.bottom = windowPosY + ScreenHeight - 1; // Copy the back buffer to front. hr = IDirectDrawSurface_Blt(ScreenReal, &rect, ScreenVirtual, 0, DDBLT_WAIT, 0); if (hr != DD_OK) { // If the surfaces were lost, restore them. if (IDirectDrawSurface_IsLost(ScreenReal) == DDERR_SURFACELOST) IDirectDrawSurface_Restore(ScreenReal); if (IDirectDrawSurface_IsLost(ScreenVirtual) == DDERR_SURFACELOST) IDirectDrawSurface_Restore(ScreenVirtual); // Retry the copy. hr = IDirectDrawSurface_Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0); } } if (hr != DD_OK) I_Error("ScreenFlip() : couldn't Flip surfaces because %s", DXErrorToString(hr)); return FALSE; }
void DDKillScreen() { if (_lpDDClipper) IDirectDrawClipper_Release(_lpDDClipper); if (_lpDDPalette) IDirectDrawPalette_Release(_lpDDPalette); if (_lpDDSBack) IDirectDrawSurface_Release(_lpDDSBack); if (_lpDDSPrimary) { if (!GRMODEINFO(modex)) { DDBLTFX ddbltfx; HRESULT ddresult; memset(&ddbltfx, 0, sizeof(DDBLTFX)); ddbltfx.dwSize = sizeof( ddbltfx ); ddbltfx.dwFillColor = (WORD)(BM_XRGB(0,0,0)); ddresult = IDirectDrawSurface_Blt( _lpDDSPrimary, // dest surface NULL, // dest rect NULL, // src surface NULL, // src rect DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } IDirectDrawSurface_Release(_lpDDSPrimary); } _lpDDClipper = NULL; _lpDDPalette = NULL; _lpDDSBack = NULL; _lpDDSPrimary = NULL; }
static void ptc_paint_primary() { RECT source; RECT destination; POINT point; // check if (lpDDS) { // setup source rectangle source.left = 0; source.top = 0; source.right = dx; source.bottom = dy; // get origin of client area point.x = 0; point.y = 0; ClientToScreen(wnd,&point); // get window client area GetClientRect(wnd,&destination); // offset destination rectangle destination.left += point.x; destination.top += point.y; destination.right += point.x; destination.bottom += point.y; // blt secondary to primary surface // IDirectDrawSurface_Blt(lpDDS,&destination,lpDDS_secondary,&source,DDBLT_WAIT,0);DDBLTFAST_WAIT IDirectDrawSurface_Blt(lpDDS,&destination,lpDDS_secondary,&source,DDBLTFAST_WAIT,0); } }
// // Clear the surface to color // VOID ClearSurface(IDirectDrawSurface* surface, int color) { DDBLTFX ddbltfx; // Use the blter to do a color fill to clear the back buffer ddbltfx.dwSize = sizeof (ddbltfx); ddbltfx. #ifdef DUMMYUNIONNAMEN DUMMYUNIONNAMEN(5). #endif dwFillColor = color; IDirectDrawSurface_Blt(surface,NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); }
static void flip_page(void) { DDSURFACEDESC2 ddsd; HRESULT dxresult; IDirectDrawSurface_Unlock(g_lpddsBack, NULL); if (g_doublebuffer) { dxresult = IDirectDrawSurface_Flip(g_lpddsOverlay, NULL, DDFLIP_WAIT); if (dxresult == DDERR_SURFACELOST) { av_log(NULL, AV_LOG_INFO, "vo_directx: Lost, Restoring Surface\n"); IDirectDrawSurface_Restore(g_lpddsBack); IDirectDrawSurface_Restore(g_lpddsOverlay); IDirectDrawSurface_Restore(g_lpddsPrimary); dxresult = IDirectDrawSurface_Flip(g_lpddsOverlay, NULL, DDFLIP_WAIT); } if (dxresult != DD_OK) { av_log(NULL, AV_LOG_ERROR, "vo_directx: can not flip page\n"); } } else { DDBLTFX ddbltfx; memset(&ddbltfx, 0, sizeof(DDBLTFX)); ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwDDFX = DDBLTFX_NOTEARING; IDirectDrawSurface_Blt(g_lpddsPrimary, &rd, g_lpddsBack, NULL, DDBLT_WAIT, &ddbltfx); } memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(DDSURFACEDESC2); if (IDirectDrawSurface_Lock(g_lpddsBack, NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL) == DD_OK) { if (tmp_image) { free(tmp_image); tmp_image = NULL; } g_dstride = ddsd.lPitch; g_image = ddsd.lpSurface; } else { if (!tmp_image) { av_log(NULL, AV_LOG_INFO, "Locking the surface failed, rendering to a hidden surface!\n"); tmp_image = g_image = calloc(1, g_image_height * g_dstride * 2); } } }
void dd_gfx_blt2D(unsigned short handle, int x, int y, int x2, int y2, fix u0, fix v0, fix u1, fix v1) { RECT drect, srect; if (!dd_gfx_initialized) return; Assert(handle != 0); handle--; // Convert to valid handle SetRect(&drect, x,y,x2,y2); SetRect(&srect, f2i(u0), f2i(v0), f2i(u1), f2i(v1)); IDirectDrawSurface_Blt(dd_grd_curcanv->lpdds, &drect, gfxBitmap[handle].lpdds, &srect, DDBLT_WAIT| DDBLT_KEYSRC, NULL); }
void GGI_directx_DDRedraw(struct ggi_visual *vis, int x, int y, int w, int h) { directx_priv *priv = GGIDIRECTX_PRIV(vis); RECT SrcWinPos, DestWinPos; HRESULT hr; hr = IDirectDrawSurface_IsLost(priv->lppdds); if (FAILED(hr)) return; SrcWinPos.left = x; SrcWinPos.right = x + w; SrcWinPos.top = y; SrcWinPos.bottom = y + h; DestWinPos = SrcWinPos; DestWinPos.right -= vis->origin_x; if (DestWinPos.right <= 0) return; DestWinPos.bottom -= vis->origin_y; if (DestWinPos.bottom <= 0) return; DestWinPos.left -= vis->origin_x; if (DestWinPos.left < 0) { SrcWinPos.left -= DestWinPos.left; DestWinPos.left = 0; } DestWinPos.top -= vis->origin_y; if (DestWinPos.top < 0) { SrcWinPos.top -= DestWinPos.top; DestWinPos.top = 0; } ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.left); ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.right); /* draw the stored image on the primary surface */ IDirectDrawSurface_Blt(priv->lppdds, &DestWinPos, priv->lpbdds[vis->d_frame_num], &SrcWinPos, DDBLT_WAIT, NULL); }
void GGI_directx_DDRedrawAll(struct ggi_visual *vis) { directx_priv *priv = GGIDIRECTX_PRIV(vis); RECT SrcWinPos, DestWinPos; HRESULT hr; hr = IDirectDrawSurface_IsLost(priv->lppdds); if (FAILED(hr)) return; GetClientRect(priv->hWnd, &SrcWinPos); SrcWinPos.left += vis->origin_x; SrcWinPos.top += vis->origin_y; SrcWinPos.right += vis->origin_x; SrcWinPos.bottom += vis->origin_y; GetClientRect(priv->hWnd, &DestWinPos); ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.left); ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.right); /* draw the stored image on the primary surface */ IDirectDrawSurface_Blt(priv->lppdds, &DestWinPos, priv->lpbdds[vis->d_frame_num], &SrcWinPos, DDBLT_WAIT, NULL); }
static void blit_to_primary(win_window_info *window, int srcwidth, int srcheight) { dd_info *dd = window->drawdata; IDirectDrawSurface7 *target = (dd->back != NULL) ? dd->back : dd->primary; win_monitor_info *monitor = winwindow_video_window_monitor(window, NULL); DDBLTFX blitfx = { sizeof(DDBLTFX) }; RECT clear, outer, dest, source; INT32 dstwidth, dstheight; HRESULT result; // compute source rect source.left = source.top = 0; source.right = srcwidth; source.bottom = srcheight; // compute outer rect -- windowed version if (!window->fullscreen) { GetClientRect(window->hwnd, &outer); ClientToScreen(window->hwnd, &((LPPOINT)&outer)[0]); ClientToScreen(window->hwnd, &((LPPOINT)&outer)[1]); // adjust to be relative to the monitor outer.left -= monitor->info.rcMonitor.left; outer.right -= monitor->info.rcMonitor.left; outer.top -= monitor->info.rcMonitor.top; outer.bottom -= monitor->info.rcMonitor.top; } // compute outer rect -- full screen version else { calc_fullscreen_margins(window, dd->primarydesc.dwWidth, dd->primarydesc.dwHeight, &outer); } // if we're respecting the aspect ratio, we need to adjust to fit dstwidth = rect_width(&outer); dstheight = rect_height(&outer); if (!video_config.hwstretch) { // trim the source if necessary if (rect_width(&outer) < srcwidth) { source.left += (srcwidth - rect_width(&outer)) / 2; source.right = source.left + rect_width(&outer); } if (rect_height(&outer) < srcheight) { source.top += (srcheight - rect_height(&outer)) / 2; source.bottom = source.top + rect_height(&outer); } // match the destination and source sizes dstwidth = srcwidth = source.right - source.left; dstheight = srcheight = source.bottom - source.top; } else if (video_config.keepaspect) { // compute the appropriate visible area render_target_compute_visible_area(window->target, rect_width(&outer), rect_height(&outer), winvideo_monitor_get_aspect(monitor), render_target_get_orientation(window->target), &dstwidth, &dstheight); } // center within dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2; dest.right = dest.left + dstwidth; dest.top = outer.top + (rect_height(&outer) - dstheight) / 2; dest.bottom = dest.top + dstheight; // compare against last destination; if different, force a redraw if (dest.left != dd->lastdest.left || dest.right != dd->lastdest.right || dest.top != dd->lastdest.top || dest.bottom != dd->lastdest.bottom) { dd->lastdest = dest; update_outer_rects(dd); } // clear outer rects if we need to if (dd->clearouter != 0) { dd->clearouter--; // clear the left edge if (dest.left > outer.left) { clear = outer; clear.right = dest.left; result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result); } // clear the right edge if (dest.right < outer.right) { clear = outer; clear.left = dest.right; result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result); } // clear the top edge if (dest.top > outer.top) { clear = outer; clear.bottom = dest.top; result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result); } // clear the bottom edge if (dest.bottom < outer.bottom) { clear = outer; clear.top = dest.bottom; result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result); } } // do the blit result = IDirectDrawSurface7_Blt(target, &dest, dd->blit, &source, DDBLT_WAIT, NULL); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X blitting to the screen\n", (int)result); // page flip if triple buffered if (window->fullscreen && dd->back != NULL) { result = IDirectDrawSurface7_Flip(dd->primary, NULL, DDFLIP_WAIT); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result); } }