📄 vo_directx.c.orig
字号:
return 1; } //get current screen siz for selected monitor ... ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd); if (vo_screenwidth && vo_screenheight) { vm_height=vo_screenheight; vm_width=vo_screenwidth; } else { vm_height=ddsd.dwHeight; vm_width=ddsd.dwWidth; } if (vo_dbpp)vm_bpp=vo_dbpp; else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount; if (vidmode) { if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK) { mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n"); return 1; } /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/ if (g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width, vm_height, vm_bpp,0,0) != DD_OK) { mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n"); return 1; } mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>Inited adapter %i for %i x %i @ %i \n",vo_adapter_num,vm_width,vm_height,vm_bpp); return 0; } if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW { mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n"); return 1; } mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Inited\n"); return 0;}static void check_events(void){ MSG msg; while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); }}static uint32_t Directx_ManageDisplay(){ HRESULT ddrval; DDCAPS capsDrv; DDOVERLAYFX ovfx; DWORD dwUpdateFlags=0; int width,height; if (!vidmode && !vo_fs && WinID!=-1) { RECT current_rect = {0, 0, 0, 0}; GetWindowRect(hWnd, ¤t_rect); if ((current_rect.left == last_rect.left) && (current_rect.top == last_rect.top) && (current_rect.right == last_rect.right) && (current_rect.bottom == last_rect.bottom)) return 0; last_rect = current_rect; } if (vo_fs || vidmode) { aspect(&width,&height,A_ZOOM); rd.left=(vo_screenwidth-width)/2; rd.top=(vo_screenheight-height)/2; if (WinID == -1) if (ShowCursor(FALSE)>=0)while (ShowCursor(FALSE)>=0){} } else if (WinID != -1 && vo_geometry) { POINT pt; pt.x = vo_dx; pt.y = vo_dy; ClientToScreen(hWnd,&pt); width=d_image_width; height=d_image_height; rd.left = pt.x; rd.top = pt.y; while (ShowCursor(TRUE)<=0){} } else { POINT pt; pt.x = 0; //overlayposition relative to the window pt.y = 0; ClientToScreen(hWnd,&pt); GetClientRect(hWnd, &rd); width=rd.right - rd.left; height=rd.bottom - rd.top; pt.x -= monitor_rect.left; /* move coordinates from global to local monitor space */ pt.y -= monitor_rect.top; rd.right -= monitor_rect.left; rd.bottom -= monitor_rect.top; rd.left = pt.x; rd.top = pt.y; if (!nooverlay && (!width || !height)) { /*window is minimized*/ ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); return 0; } if (vo_keepaspect) { int tmpheight=((float)width/window_aspect); tmpheight+=tmpheight%2; if (tmpheight > height) { width=((float)height*window_aspect); width+=width%2; } else height=tmpheight; } if (WinID == -1) while (ShowCursor(TRUE)<=0){} } rd.right=rd.left+width; rd.bottom=rd.top+height; /*ok, let's workaround some overlay limitations*/ if (!nooverlay) { uint32_t uStretchFactor1000; //minimum stretch uint32_t xstretch1000,ystretch1000; /*get driver capabilities*/ ZeroMemory(&capsDrv, sizeof(capsDrv)); capsDrv.dwSize = sizeof(capsDrv); if (g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL) != DD_OK)return 1; /*get minimum stretch, depends on display adaptor and mode (refresh rate!) */ uStretchFactor1000 = capsDrv.dwMinOverlayStretch>1000 ? capsDrv.dwMinOverlayStretch : 1000; rd.right = ((width+rd.left)*uStretchFactor1000+999)/1000; rd.bottom = (height+rd.top)*uStretchFactor1000/1000; /*calculate xstretch1000 and ystretch1000*/ xstretch1000 = ((rd.right - rd.left)* 1000)/image_width ; ystretch1000 = ((rd.bottom - rd.top)* 1000)/image_height; rs.left=0; rs.right=image_width; rs.top=0; rs.bottom=image_height; if (rd.left < 0)rs.left=(-rd.left*1000)/xstretch1000; if (rd.top < 0)rs.top=(-rd.top*1000)/ystretch1000; if (rd.right > vo_screenwidth)rs.right=((vo_screenwidth-rd.left)*1000)/xstretch1000; if (rd.bottom > vo_screenheight)rs.bottom=((vo_screenheight-rd.top)*1000)/ystretch1000; /*do not allow to zoom or shrink if hardware isn't able to do so*/ if ((width < image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX)) { if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n"); else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink x\n"); rd.right=rd.left+image_width; } else if ((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX)) { if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n"); else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch x\n"); rd.right = rd.left+image_width; } if ((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY)) { if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n"); else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink y\n"); rd.bottom = rd.top + image_height; } else if ((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY)) { if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n"); else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch y\n"); rd.bottom = rd.top + image_height; } /*the last thing to check are alignment restrictions these expressions (x & -y) just do alignment by dropping low order bits... so to round up, we add first, then truncate*/ if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc) rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc); if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc) rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc)); if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest) rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest); if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest) rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest)); /*create an overlay FX structure to specify a destination color key*/ ZeroMemory(&ovfx, sizeof(ovfx)); ovfx.dwSize = sizeof(ovfx); if (vo_fs||vidmode) { ovfx.dckDestColorkey.dwColorSpaceLowValue = 0; ovfx.dckDestColorkey.dwColorSpaceHighValue = 0; } else { ovfx.dckDestColorkey.dwColorSpaceLowValue = destcolorkey; ovfx.dckDestColorkey.dwColorSpaceHighValue = destcolorkey; } // set the flags we'll send to UpdateOverlay //DDOVER_AUTOFLIP|DDOVERFX_MIRRORLEFTRIGHT|DDOVERFX_MIRRORUPDOWN could be useful?; dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; /*if hardware can't do colorkeying set the window on top*/ if (capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE; else if (!tmp_image) vo_ontop = 1; } else { g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,(vo_fs && !vidmode)?hWndFS: hWnd); } if (!vidmode && !vo_fs) { if (WinID == -1) { RECT rdw=rd; if (vo_border) AdjustWindowRect(&rdw,WNDSTYLE,FALSE); // printf("window: %i %i %ix%i\n",rdw.left,rdw.top,rdw.right - rdw.left,rdw.bottom - rdw.top); rdw.left += monitor_rect.left; /* move to global coordinate space */ rdw.top += monitor_rect.top; rdw.right += monitor_rect.left; rdw.bottom += monitor_rect.top; SetWindowPos(hWnd,(vo_ontop)?HWND_TOPMOST:(vo_rootwin?HWND_BOTTOM:HWND_NOTOPMOST),rdw.left,rdw.top,rdw.right-rdw.left,rdw.bottom-rdw.top,SWP_NOOWNERZORDER); } } else SetWindowPos(vidmode?hWnd:hWndFS,vo_rootwin?HWND_BOTTOM:HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER|SWP_NOCOPYBITS); /*make sure the overlay is inside the screen*/ if (rd.left<0)rd.left=0; if (rd.right>vo_screenwidth)rd.right=vo_screenwidth; if (rd.top<0)rd.top=0; if (rd.bottom>vo_screenheight)rd.bottom=vo_screenheight; /*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/ if (nooverlay)return 0; // printf("overlay: %i %i %ix%i\n",rd.left,rd.top,rd.right - rd.left,rd.bottom - rd.top); ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx); if (FAILED(ddrval)) { // one cause might be the driver lied about minimum stretch // we should try upping the destination size a bit, or // perhaps shrinking the source size mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>UpdateOverlay failed\n" ); mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top ); mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>"); switch (ddrval) { case DDERR_NOSTRETCHHW: { mp_msg(MSGT_VO, MSGL_ERR ,"hardware can't stretch: try to size the window back\n"); break; } case DDERR_INVALIDRECT: { mp_msg(MSGT_VO, MSGL_ERR ,"invalid rectangle\n"); break; } case DDERR_INVALIDPARAMS: { mp_msg(MSGT_VO, MSGL_ERR ,"invalid parameters\n"); break; } case DDERR_HEIGHTALIGN: { mp_msg(MSGT_VO, MSGL_ERR ,"height align\n"); break; } case DDERR_XALIGN: { mp_msg(MSGT_VO, MSGL_ERR ,"x align\n"); break; } case DDERR_UNSUPPORTED: { mp_msg(MSGT_VO, MSGL_ERR ,"unsupported\n"); break; } case DDERR_INVALIDSURFACETYPE: { mp_msg(MSGT_VO, MSGL_ERR ,"invalid surfacetype\n"); break; } case DDERR_INVALIDOBJECT: { mp_msg(MSGT_VO, MSGL_ERR ,"invalid object\n"); break; } case DDERR_SURFACELOST: { mp_msg(MSGT_VO, MSGL_ERR ,"surfaces lost\n"); g_lpddsOverlay->lpVtbl->Restore( g_lpddsOverlay ); //restore and try again g_lpddsPrimary->lpVtbl->Restore( g_lpddsPrimary ); ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx); if (ddrval !=DD_OK)mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>UpdateOverlay failed again\n" ); break; } default: mp_msg(MSGT_VO, MSGL_ERR ," 0x%x\n",ddrval); } /*ok we can't do anything about it -> hide overlay*/ if (ddrval != DD_OK) { ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); return 1; } } return 0;}//find out supported overlay pixelformatsstatic uint32_t Directx_CheckOverlayPixelformats(){ DDCAPS capsDrv; HRESULT ddrval; DDSURFACEDESC2 ddsdOverlay; uint32_t i; uint32_t formatcount = 0; //get driver caps to determine overlay support ZeroMemory(&capsDrv, sizeof(capsDrv)); capsDrv.dwSize = sizeof(capsDrv); ddrval = g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL); if (FAILED(ddrval)) { mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>failed getting ddrawcaps\n"); return 1; } if (!(capsDrv.dwCaps & DDCAPS_OVERLAY)) { mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Your card doesn't support overlay\n"); return 1; } mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>testing supported overlay pixelformats\n"); //it is not possible to query for pixel formats supported by the //overlay hardware: try out various formats till one works ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay)); ddsdOverlay.dwSize = sizeof(ddsdOverlay); ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| DDSD_PIXELFORMAT; ddsdOverlay.dwWidth=300; ddsdOverlay.dwHeight=280; ddsdOverlay.dwBackBufferCount=0; //try to create an overlay surface using one of the pixel formats in our global list i=0; do { ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay; ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL); if (ddrval == DD_OK) { mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s supported\n",i,g_ddpf[i].img_format_name); g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD |VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP; formatcount++; } else mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s not supported\n",i,g_ddpf[i].img_format_name); if (g_lpddsOverlay != NULL) { g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay); g_lpddsOverlay = NULL; } } while ( ++i < NUM_FORMATS ); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>Your card supports %i of %i overlayformats\n",formatcount, NUM_FORMATS); if (formatcount == 0) { mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><WARN>Your card supports overlay, but we couldn't create one\n"); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>This can have the following reasons:\n"); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you are already using an overlay with another app\n"); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you don't have enough videomemory\n"); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- vo_directx doesn't support the cards overlay pixelformat\n"); return 1; } if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror left right\n"); //I don't have hardware which if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror up down\n"); //supports those send me one and I'll implement ;) return 0;}//find out the Pixelformat of the Primary Surfacestatic uint32_t Directx_CheckPrimaryPixelformat(){ uint32_t i=0; uint32_t formatcount = 0; DDPIXELFORMAT ddpf; DDSURFACEDESC2 ddsd; HDC hdc; HRESULT hres; COLORREF rgbT=RGB(0,0,0); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n"); memset( &ddpf, 0, sizeof( DDPIXELFORMAT )); ddpf.dwSize = sizeof( DDPIXELFORMAT ); //we have to create a primary surface first if (Directx_CreatePrimarySurface()!=0)return 1; if (g_lpddsPrimary->lpVtbl->GetPixelFormat( g_lpddsPrimary, &ddpf ) != DD_OK ) { mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>can't get pixelformat\n"); return 1; } while ( i < NUM_FORMATS ) { if (g_ddpf[i].g_ddpfOverlay.dwRGBBitCount == ddpf.dwRGBBitCount) { if (g_ddpf[i].g_ddpfOverlay.dwRBitMask == ddpf.dwRBitMask) { mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT PRIMARY>%i %s supported\n",i,g_ddpf[i].img_format_name); g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD; formatcount++; primary_image_format=g_ddpf[i].img_format; } } i++; } //get the colorkey for overlay mode destcolorkey = CLR_INVALID; if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -