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

📄 ddrawoverlay.cpp

📁 direct show
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 //DDSURFACEDESC DDSDesc;
 int sx,sy;
 //LPDIRECTDRAWSURFACE3 pSurf;
 BOOL ret=FALSE;
 if (!p||!pDRect) return FALSE;
 DispRegion * prgn=(DispRegion *) p;
 DispRegion * pMrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
 //DispRegion * prgn=(DispRegion *) p;
 int RgnType=MASKMODE&pMrgn->RgnType; //the region type
 
//  prgn->u.SRgn.DesRect= * pDRect;
 
/*
  if (pSRect==0)
  {
	  prgn->u.SRgn.SrcRect=* pDRect;
  }
  else
  {
      prgn->u.SRgn.SrcRect=* pSRect;
  }
*/
   //prgn->u.SRgn.VidBufMutex=0;
   prgn->u.SRgn.VidBufLockVar=0;
   prgn->u.SRgn.DesRect.left=pDRect->left;
   prgn->u.SRgn.DesRect.top=pDRect->top;
   prgn->u.SRgn.DesRect.right=pDRect->right;
   prgn->u.SRgn.DesRect.bottom=pDRect->bottom;
   prgn->u.SRgn.StartRect.bottom=pDRect->bottom;
   prgn->u.SRgn.StartRect.right=pDRect->right;
   prgn->u.SRgn.StartRect.left=pDRect->left;
   prgn->u.SRgn.StartRect.top=pDRect->top;

  if (RgnType==PRIMARY_NODIRECTW)
  {
   prgn->u.SRgn.StartAddress=0; //the region mem start linear address
   prgn->u.SRgn.SrcRect.left=0;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.top=0;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.right=pDRect->right-pDRect->left;       //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.bottom=pDRect->bottom-pDRect->top;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcPitch=pMrgn->u.MRgn.PixelDepth * (prgn->u.SRgn.SrcRect.right);//pDRect->right;// (1+prgn->u.SRgn.SrcRect.right);
/*
   prgn->u.SRgn.VidBufMutex=CreateMutex( NULL, FALSE,NULL); 
   if (!prgn->u.SRgn.VidBufMutex)
   {
      m_Err.err=CALL_WINAPI_ERR;
      m_Err.errloc=CreateMutex_LOC;
	  return  FALSE;
   }
*/
   /*
    if ((pSurf=(LPDIRECTDRAWSURFACE3)CreateSurface(SYSMEMSURF, pDRect->right-pDRect->left, pDRect->bottom-pDRect->top)))
    //if ((pSurf=(LPDIRECTDRAWSURFACE3)CreateSurface(VIDMEMSURF, pDRect->right-pDRect->left, pDRect->bottom-pDRect->top)))
	{ //success
       prgn->u.SRgn.pSrcSurf=pSurf;
	   INIT_DIRECTDRAW_STRUCT(DDSDesc);
       ddrval = pSurf->Lock( NULL , &DDSDesc , DDLOCK_WAIT , NULL );
       if(ddrval==DD_OK)
		   {
           prgn->u.SRgn.StartAddress=(DWORD)DDSDesc.lpSurface; //the region mem start linear address
           prgn->u.SRgn.SrcPitch=DDSDesc.lPitch;     //only use for software write mode
           prgn->u.SRgn.SrcRect.left=0;      //in system memory (for Blt transfer)
           prgn->u.SRgn.SrcRect.top=0;      //in system memory (for Blt transfer)
           prgn->u.SRgn.SrcRect.right=DDSDesc.dwWidth;      //in system memory (for Blt transfer)
           prgn->u.SRgn.SrcRect.bottom=DDSDesc.dwHeight;      //in system memory (for Blt transfer)
           } 
       pSurf->Unlock(NULL);
	   if (ddrval!=DD_OK)
	   {
        DestorySurface(pSurf);
	   }

	}

    */
    ret=TRUE;
  }
  else if (RgnType==PRIMARY_DIRECTW)
  {
 	//screen coord
	sy=pMrgn->u.MRgn.DRect.top+pDRect->top;
    sx=pMrgn->u.MRgn.DRect.left+pDRect->left;
	//StartAddress point this subregion
    prgn->u.SRgn.StartAddress=g_lpPrimaryStartAddr+ sy*g_PrimaryPitch
			                  +sx*(g_PrimaryPixelDepth);   

    ret=TRUE;
    //prgn->
  }
  else if (RgnType==OVERLAY_NODIRECTW)
  {
   prgn->u.SRgn.StartAddress=0; //the region mem start linear address
   prgn->u.SRgn.SrcRect.left=0;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.top=0;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.right=pDRect->right-pDRect->left;       //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcRect.bottom=pDRect->bottom-pDRect->top;      //in system memory (for Blt transfer)
   prgn->u.SRgn.SrcPitch=pMrgn->u.MRgn.PixelDepth * (prgn->u.SRgn.SrcRect.right);//pDRect->right ;
/*
   prgn->u.SRgn.VidBufMutex=CreateMutex( NULL, FALSE,NULL); 
   if (!prgn->u.SRgn.VidBufMutex)
   {
      m_Err.err=CALL_WINAPI_ERR;
      m_Err.errloc=CreateMutex_LOC;
	  return  FALSE;
   }
*/
   ret=TRUE;
  }
  else //OVERLAY_DIRECTW
  {
  //if (!CheckSubRegion(pMrgn,pDRect,pSRect) return FALSE;
   	//screen coord
	sy=pMrgn->u.MRgn.DRect.top+pDRect->top;
    sx=pMrgn->u.MRgn.DRect.left+pDRect->left;
	//StartAddress point this subregion
    prgn->u.SRgn.StartAddress=g_lpOverlayStartAddr+ sy*g_OverlayPitch
			                  +sx*(g_OverlayPixelDepth);   
    //prgn->u.SRgn.StartAddress=g_lpOverlayStartAddr;
	
	prgn->u.SRgn.SrcRect=prgn->u.SRgn.DesRect;
    prgn->u.SRgn.SrcPitch=g_OverlayPitch;

    ret=TRUE;
  }
  return ret;
}

/*
BOOL CDDrawOverlay::CheckSubRegion(void * pmrgn,RECT * pDRect, RECT * pSRect)
{
  POINT po;
  DispRegion * pMrgn=(DispRegion *)pmrgn;
  po.x=pMrgn->u.MRgn.DRect.left+pDRect->left; //scerrn coordnate
  po.y=pMrgn->u.MRgn.DRect.top+pDRect->top;

  //check if the destination rect right,bottom point is int the main region 
  if (po.x > pMrgn->u.MRgn.DRect.right) return FALSE;
  if (po.y > pMrgn->u.MRgn.DRect.bottom) return FALSE;
  //if DRect>=SRect
  if (pSRect)
  {
    if ((pDRect->bottom - pDRect->top)<(pSRect->bottom - pSRect->top)) return FALSE;
    if ((pDRect->right - pDRect->left)<(pSRect->right - pSRect->left)) return FALSE;
  }
 
  return TRUE;
}
*/
/*
int CheckOverlayPixel(int PixelId)
{

 int APixelID[4]={RGB555DD,RGB565DD,YUY2_FOURCCDD};
 int i;
 if (PixelId==0)
 {
  for (i=0;i<3;i++)
  {
   if (CreateOverlay(128,128,PixelFormatsID[i]))
   {
       CreateOverlay
	   return APixelID[i];
   }
  }
 }
 else
 {
   if (CreateOverlay(Rect * pRect,APixelID[i]))

	   return APixelID[i];

 }	 
}
 */

//return PixelId >0 if success, else return <0
int CDDrawOverlay::CreateOverlay(int w,int h,int PixelId)
{
	LPDIRECTDRAWSURFACE lpDDSTemp;
    DDSURFACEDESC   ddsdOverlay;
    HRESULT         ddrval;
	DDSURFACEDESC DDSDesc;

	int id=-1;
	int i,idtemp;
    int APixelID[3]={RGB555DD,RGB565DD,YUY2_FOURCCDD};

    if (!g_lpDD2 || !g_lpDDSPrimary)
	{
        m_Err.err=POINTER_ZERO_ERR;
        m_Err.errloc=CreateOverlay_LOC;
        return id;
    }
    // It's currently not possible to query for pixel formats supported by the
    // overlay hardware (though GetFourCCCodes() usually provides a partial 
    // list).  Instead you need to call CreateSurface() to try a variety of  
    // formats till one works.  
    INIT_DIRECTDRAW_STRUCT(ddsdOverlay);
	ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY;
	//ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_PIXELFORMAT;
	
    ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
	ddsdOverlay.dwWidth=w;
	ddsdOverlay.dwHeight=h;

    // Try to create the overlay surface
    //ddrval = g_lpdd->CreateSurface(&ddsdOverlay, &g_lpddsOverlay, NULL);
 	if (PixelId<0)
	{
       //first use current Primary RGB Pixel to create overlay
       idtemp=GetRGBPixelID(PixelId);
	   ddrval=-1;
	   if (idtemp>=0)
	   {
         ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[idtemp];
         ddrval = g_lpDD2->CreateSurface(&ddsdOverlay, &lpDDSTemp, NULL);
	   };
       //else below search one
       if (ddrval==DD_OK)
	   {
         id=idtemp;
	     goto nextproc;
	   };
      
      i=0;
	  // if failed begin search one 
      do 
		{
         ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[APixelID[i]];
         ddrval = g_lpDD2->CreateSurface(&ddsdOverlay, &lpDDSTemp, NULL);
        } while( FAILED(ddrval) && (++i < 3) );
	    //if success
	    if (i<3)
		  id=APixelID[i];
		else
		{
		 //if fail i==3
        m_Err.err=ddrval;
        m_Err.errloc=CreateOverlay_CreateSurface1_LOC;
       
		}
 	}
    else
	{
       ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[PixelId];
       ddrval = g_lpDD2->CreateSurface(&ddsdOverlay, &lpDDSTemp, NULL);
       if(!FAILED(ddrval))
	   {
        id=PixelId;
	   }
       else
	   {
        m_Err.err=ddrval;
        m_Err.errloc=CreateOverlay_CreateSurface2_LOC;
 	   }
	}

     // We just couldn't create an overlay surface.  Let's exit.
     // if id<0
nextproc:
 if (ddrval==DD_OK)
 {
    ddrval = lpDDSTemp->QueryInterface(IID_IDirectDrawSurface3, (void**)&g_lpDDSOverlay);
    lpDDSTemp->Release();
    if( ddrval != DD_OK )
    {
		m_Err.err=ddrval;
		m_Err.errloc=DD_QueryIDDrawSurface3_LOC;
		::MessageBox(0,"Disp Driver do not support DDSurface3","Error",0);
	    return -1; //EEROR
    }

   INIT_DIRECTDRAW_STRUCT(DDSDesc);
   if((ddrval = g_lpDDSOverlay->Lock( NULL , &DDSDesc , DDLOCK_WAIT , NULL )) == DD_OK)
   {

       g_lpOverlayStartAddr =(DWORD) DDSDesc.lpSurface; 
       g_OverlayPitch = DDSDesc.lPitch;
	   g_OverlayPixelDepth=2;//(BYTE) (DDSDesc.ddpfPixelFormat.dwRGBBitCount>>3);
       g_lpDDSOverlay->Unlock( NULL );
	   g_MaxOverlayStartAddr=(BYTE *)g_lpOverlayStartAddr+h*g_OverlayPitch+w*g_OverlayPixelDepth;
   }
   else
	{
      m_Err.err=ddrval;
      m_Err.errloc=CreateOverlay_Lock_LOC;
	  id=-1;
    }
 };

 return id;

}

//****************************************************************************
//* Function: DestroyOverlay()
//* Description:
//*     Hides the overlay then releases it's surface.
//****************************************************************************
void CDDrawOverlay::DestoryOverlay()
{
	//if (Dllcnt>1) return;
	if (g_lpDDSOverlay)
	{
        // Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay 
        // from the display.
        g_lpDDSOverlay->UpdateOverlay(NULL, g_lpDDSPrimary, NULL, DDOVER_HIDE, NULL);
		g_lpDDSOverlay->Release();
		g_lpDDSOverlay=NULL;
        g_lpOverlayStartAddr =0; 
        g_OverlayPitch = 0;
		g_OverlayPixelDepth=0;
        g_MaxOverlayStartAddr=0;
	}
}

int CDDrawOverlay::GetCurrentRGBPixelID()
{
 return GetRGBPixelID(-1);
}

BOOL  CDDrawOverlay::MoveDispRegion(HANDLE hRgn,int x,int y)
{
   DispRegionList  * pl=(DispRegionList *)hRgn;
   DispRegionList  * p;
//   DispRegion * prgn;
   DispRegion * pMrgn;
   int type;
   int w,h;
   int retv=FALSE;
   int x0=x&0xfffffffe;
	//check if the hRgn is valid HANDLE
  if ((!hRgn)||(((DispRegionList  *)hRgn)->ValidID!=0x10540001)) return FALSE;
//  if (x>(int)g_ScreenW||x<0||y>(int)g_ScreenH||y<0)
//  {
//    m_Err.err=INVALIDE_RARAMS_ERR;
//    m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
//    return FALSE;
//  }
  pMrgn=pl->pDispNode;
  //if no main region
  if (!(pMrgn->RgnType&MASKMAINREIGON)) return FALSE;
  type=pMrgn->RgnType&0xff;
    w=pMrgn->u.MRgn.DRect.right-pMrgn->u.MRgn.DRect.left;
    h=pMrgn->u.MRgn.DRect.bottom-pMrgn->u.MRgn.DRect.top;
    pMrgn->u.MRgn.DRect.right=x0+w;
    pMrgn->u.MRgn.DRect.bottom=y+h;
    pMrgn->u.MRgn.DRect.left=x0;
    pMrgn->u.MRgn.DRect.top=y;
  if (x0+w>(int)g_ScreenW||x0<0||y+h>(int)g_ScreenH||y<0)
  {
    m_Err.err=INVALIDE_RARAMS_ERR;
    m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
	OutputDebugString("Move Disp out of range!");
    return FALSE;
  }

	//move every Sub region
    StartSearchNode();
    do {
       p=(DispRegionList *) SearchOneNode(pl);
	   if (p==0) break;
	   else
	   {
        MoveOneSubRegion(p->pDispNode);
		ClearRegion(p);
		retv=TRUE;
	   }
	} while (p!=0);
    StopSearchNode();
 
  if (type<OVERLAY_NODIRECTW)//PRIMARY_NODIRECTW OR PRIMARY_DIRECTW
  {
    //else if (type==PRIMARY_DIRECTW)
    ::InvalidateRect(pMrgn->u.MRgn.hWnd,0,TRUE);
    //OutputDebugString("update");
    return retv; 
  }
  else if (type==OVERLAY_NODIRECTW)
  {
     if (g_OverlayPixelID==YUY2_FOURCCDD)
         ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,TRUE);
     else
	     ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,FALSE);
  }
  else //OVERLAY_DIRECTW
  {
     if (g_OverlayPixelID==YUY2_FOURCCDD)
         ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,TRUE);
     else
	     ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,FALSE);
  }
  //pMrgn->u.MRgn.DRect.;

 
  return retv;
}

//return hRgn
HANDLE  CDDrawOverlay::GetDispRegionHandle(HWND hDispWnd)
{
  DispRegionList  * pl;
  StartSearchNode();
  do {
     pl=(DispRegionList *) SearchOneNode(0); //search main region
  } while ((pl!=0)&&(pl->pDispNode->u.MRgn.hWnd!=hDispWnd));
 StopSearchNode();
 return pl;
}

void StartSearchNode()
{
 g_StartSearch=1;
}

void StopSearchNode()
{
 g_StartSearch=0;
}

//if hRgn is Main node,it may be include many  sub node,search sub region
//if hRgn==0 then begin search from List head,and search one main region
void * SearchOneNode(HANDLE hRgn)
{
 static DispRegionList * pSav;
 static BOOL IsSearchMainRgn;
 DispRegion * prgn;
 DispRegionList * h=0;
 DispRegionList * p=(DispRegionList *)hRgn;
 if (g_StartSearch==1) //first search
 {
  if (p==0) //search one main region
  {  //if the list is not empty
     if (pHeadList)
     {
       IsSearchMainRgn=TRUE;
       p=pHeadList;
	   if (p->pDispNode->RgnType&MASKMAINREIGON)
	   {  //if is main region
         h=p;
         pSav=p->pnext;
	   }
	 }
  }
  else
  {
     IsSearchMainRgn=FALSE;
   	 if (p->pDispNode->RgnType&MASKMAINREIGON)
     {
       prgn=p->pDispNode;
	   do {
          p=p->pnext; 

⌨️ 快捷键说明

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