⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vo_directx.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
        {            selected_guid = *lpGUID;            selected_guid_ptr = &selected_guid;        }        mi.cbSize = sizeof(mi);        if (myGetMonitorInfo(hm, &mi)) {			monitor_rect = mi.rcMonitor;        }        mp_msg(MSGT_VO, MSGL_INFO ,"\t\t<--");    }    mp_msg(MSGT_VO, MSGL_INFO ,"\n");        adapter_count++;        return 1; // list all adapters}static uint32_t Directx_InitDirectDraw(){	HRESULT    (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *); 	LPDIRECTDRAW lpDDraw;	DDSURFACEDESC2 ddsd;	LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;	HINSTANCE user32dll=LoadLibrary("user32.dll");		adapter_count = 0;	if(user32dll){		myGetMonitorInfo=GetProcAddress(user32dll,"GetMonitorInfoA");		if(!myGetMonitorInfo && vo_adapter_num){			mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx> -adapter is not supported on Win95\n");			vo_adapter_num = 0;		}	}		mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" );	//load direct draw DLL: based on videolans code	hddraw_dll = LoadLibrary("DDRAW.DLL");	if( hddraw_dll == NULL )    {        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" );		return 1;    }	    last_rect.left = 0xDEADC0DE;   // reset window position cache	if(vo_adapter_num){ //display other than default        OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hddraw_dll,"DirectDrawEnumerateExA");        if (!OurDirectDrawEnumerateEx){            FreeLibrary( hddraw_dll );            hddraw_dll = NULL;            mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawEnumerateEx\n");            mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 7 or higher installed\n");            return 1;        }        // enumerate all display devices attached to the desktop        OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES );        if(vo_adapter_num >= adapter_count)            mp_msg(MSGT_VO, MSGL_ERR,"Selected adapter (%d) doesn't exist: Default Display Adapter selected\n",vo_adapter_num);    }    FreeLibrary(user32dll);	OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");    if ( OurDirectDrawCreateEx == NULL )     {         FreeLibrary( hddraw_dll );         hddraw_dll = NULL;        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawCreateEx\n"); 		return 1;     }	// initialize DirectDraw and create directx v7 object    if (OurDirectDrawCreateEx(selected_guid_ptr, (VOID**)&g_lpdd, &IID_IDirectDraw7, NULL ) != DD_OK )    {        FreeLibrary( hddraw_dll );        hddraw_dll = NULL;        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n");		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, &current_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 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -