📄 ddrawoverlay.cpp
字号:
} while ((p!=0)&&(p->pDispNode->u.SRgn.pMDispRgn!=prgn));
if (p!=0)
{
h=p; //return one sub region handle
pSav=p;
}
}
}
g_StartSearch=2; //have begin search
} //end g_StartSearch==1
else if (g_StartSearch==2)
{
p=pSav;
if (p)
{
if (IsSearchMainRgn)
{
do {
p=p->pnext;
} while ((p!=0) && (!(p->pDispNode->RgnType&MASKMAINREIGON)) );
if (p!=0)
{
h=p; //return one sub region handle
pSav=p=p->pnext;
}
}
else //search one sub region
{ //get the main region id
prgn=(DispRegion *)p->pDispNode->u.SRgn.pMDispRgn;
do {
p=p->pnext;
} while ((p!=0)&&(p->pDispNode->u.SRgn.pMDispRgn!=prgn));
if (p!=0)
{
h=p; //return one sub region handle
pSav=p;
}
}
}
}
return h;
}
void CDDrawOverlay::MoveOneSubRegion(void * pSRgn)
{
int type,sx,sy;
DispRegion * pSubRgn=(DispRegion *) pSRgn;
DispRegion * pMrgn=(DispRegion *) pSubRgn->u.SRgn.pMDispRgn;
type=pSubRgn->RgnType;//&0xff;
if (type==PRIMARY_NODIRECTW)
{
}
else if (type==PRIMARY_DIRECTW)
{
//screen coord
sy=pMrgn->u.MRgn.DRect.top+pSubRgn->u.SRgn.DesRect.top;
sx=pMrgn->u.MRgn.DRect.left+pSubRgn->u.SRgn.DesRect.left;
//StartAddress point this subregion
pSubRgn->u.SRgn.StartAddress=g_lpPrimaryStartAddr+ sy*g_PrimaryPitch
+sx*(g_PrimaryPixelDepth);
}
else if (type==OVERLAY_NODIRECTW)
{
}
else //OVERLAY_DIRECTW
{
//screen coord
sy=pMrgn->u.MRgn.DRect.top+pSubRgn->u.SRgn.DesRect.top;
sx=pMrgn->u.MRgn.DRect.left+pSubRgn->u.SRgn.DesRect.left;
//StartAddress point this subregion
pSubRgn->u.SRgn.StartAddress=g_lpOverlayStartAddr + sy * g_OverlayPitch
+sx * g_OverlayPixelDepth;
}
}
//the hRgn must be main region handle
BOOL CDDrawOverlay::SizeDispRegion(HANDLE hRgn,int dx, int dy)
{
DispRegionList * pl=(DispRegionList *)hRgn;
DispRegionList * p;
// DispRegion * prgn;
DispRegion * pMrgn;
//int type;
// int w,h;
POINT po1;
double xc,yc;
int retv=FALSE;
//check if the hRgn is valid HANDLE
if ((!hRgn)||(((DispRegionList *)hRgn)->ValidID!=0x10540001)) return FALSE;
if (dx>(int)g_ScreenW||dx<0||dy>(int)g_ScreenH||dy<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))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
ReSetSurfaceParams(this);
//type=pMrgn->RgnType&0xff;
po1.x=0;
po1.y=0;
ClientToScreen(pMrgn->u.MRgn.hWnd, &po1);
xc=(double)dx;
xc=xc/pMrgn->u.MRgn.StartWidth; //(pMrgn->u.MRgn.DRect.right-pMrgn->u.MRgn.DRect.left);
yc=(double)dy;
yc=yc/pMrgn->u.MRgn.StartHeight; //(pMrgn->u.MRgn.DRect.bottom-pMrgn->u.MRgn.DRect.top);
pMrgn->u.MRgn.DRect.left=po1.x&0xfffffffe;
pMrgn->u.MRgn.DRect.top=po1.y;
pMrgn->u.MRgn.DRect.right=(po1.x&0xfffffffe)+dx;
pMrgn->u.MRgn.DRect.bottom=po1.y+dy;
StartSearchNode();
do {
p=(DispRegionList *) SearchOneNode(pl); //search sub region
if (p==0) break;
else
{
SizeOneSubRegion(p->pDispNode,xc,yc);
ClearRegion(p);//,g_OverlayDestColorKey);
//DisplayOverlay(p);
retv=TRUE;
}
} while (p!=0);//&&(pl->pDispNode->u.MRgn.hWnd!=hDispWnd));
StopSearchNode();
if (g_lpOverlayStartAddr==0) //primary,not support overlay,do not need clear surface
return retv;
if (g_OverlayPixelID==YUY2_FOURCCDD)
return ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,TRUE);
else
return ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,g_OverlayClearColor,FALSE);
}
BOOL CDDrawOverlay::SizeOneSubRegion(void * pSRgn,double xc,double yc)
{
int type,x0,y0;
int x,y;
DispRegion * pSubRgn=(DispRegion *) pSRgn;
DispRegion * pMrgn=(DispRegion *) pSubRgn->u.SRgn.pMDispRgn;
type=pSubRgn->RgnType;//&0xff;
BOOL retv=FALSE;
x0=(int)(xc*pSubRgn->u.SRgn.StartRect.left); //(pSubRgn->u.SRgn.DesRect.top));
y0=(int)(yc*pSubRgn->u.SRgn.StartRect.top); //(pSubRgn->u.SRgn.DesRect.top));
//Sub region Left,top point screen coord
y=pMrgn->u.MRgn.DRect.top+(int) y0;//(yc*y0); //(pSubRgn->u.SRgn.DesRect.top));
x=pMrgn->u.MRgn.DRect.left+(int)x0;//(xc*x0);//(pSubRgn->u.SRgn.DesRect.left));
//ScreenToClient(pMrgn->u.MRgn.hWnd,&po);
pSubRgn->u.SRgn.DesRect.left=x0;//po.x;
pSubRgn->u.SRgn.DesRect.top=y0;//po.y;
pSubRgn->u.SRgn.DesRect.bottom=(int)(yc*pSubRgn->u.SRgn.StartRect.bottom);//(pSubRgn->u.SRgn.DesRect.bottom));
pSubRgn->u.SRgn.DesRect.right=(int)(xc*pSubRgn->u.SRgn.StartRect.right);//(pSubRgn->u.SRgn.DesRect.right));
retv=TRUE;
if (type==PRIMARY_DIRECTW)//PRIMARY_NODIRECTW or PRIMARY_DIRECTW
{
//StartAddress point this subregion
pSubRgn->u.SRgn.StartAddress=g_lpPrimaryStartAddr+ y*g_PrimaryPitch
+x*(g_PrimaryPixelDepth);
}
else if (type==PRIMARY_NODIRECTW)
{
pSubRgn->u.SRgn.StartAddress=g_lpPrimaryStartAddr+ y*g_PrimaryPitch
+x*(g_PrimaryPixelDepth);
//SrcRect.left and top allways equal 0
pSubRgn->u.SRgn.SrcRect.bottom=pSubRgn->u.SRgn.DesRect.bottom-pSubRgn->u.SRgn.DesRect.top;
pSubRgn->u.SRgn.SrcRect.right=pSubRgn->u.SRgn.DesRect.right-pSubRgn->u.SRgn.DesRect.left;
pSubRgn->u.SRgn.SrcPitch=pMrgn->u.MRgn.PixelDepth * pSubRgn->u.SRgn.SrcRect.right;
}
else if (type==OVERLAY_NODIRECTW)
{
pSubRgn->u.SRgn.StartAddress=g_lpOverlayStartAddr+ y*g_OverlayPitch
+x*(g_OverlayPixelDepth);
//SrcRect.left and top allways equal 0
pSubRgn->u.SRgn.SrcRect.bottom=pSubRgn->u.SRgn.DesRect.bottom-pSubRgn->u.SRgn.DesRect.top;
pSubRgn->u.SRgn.SrcRect.right=pSubRgn->u.SRgn.DesRect.right-pSubRgn->u.SRgn.DesRect.left;
pSubRgn->u.SRgn.SrcPitch=pMrgn->u.MRgn.PixelDepth * pSubRgn->u.SRgn.SrcRect.right;
}
else //OVERLAY_DIRECTW
{
pSubRgn->u.SRgn.StartAddress=g_lpOverlayStartAddr + y * g_OverlayPitch
+x * g_OverlayPixelDepth;
pSubRgn->u.SRgn.SrcRect.left=pSubRgn->u.SRgn.SrcRect.top=0;
pSubRgn->u.SRgn.SrcRect.bottom=pSubRgn->u.SRgn.DesRect.bottom-pSubRgn->u.SRgn.DesRect.top;
pSubRgn->u.SRgn.SrcRect.right=pSubRgn->u.SRgn.DesRect.right-pSubRgn->u.SRgn.DesRect.left;
}
return retv;
}
/*
//only use for OVERLAY_NODIRECTW or OVERLAY_NODIRECTW Mode
BOOL CDDrawOverlay::CopyDataToSubRegion(HANDLE hSubRgn)
{
HRESULT ddrval;
DWORD flags;
int x,y;
DispRegionList * pl=(DispRegionList *)hSubRgn;
int type;
DispRegion * prgn;
DispRegion * pMrgn;
//DispRegion * pMrgn=(DispRegion *) pSubRgn->u.SRgn.pMDispRgn;
//type=pSubRgn->RgnType;//&0xff;
if (!pl||(pl->pDispNode->RgnType&(MASKHWDIRECTWRITE|MASKMAINREIGON)))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
type=pl->pDispNode->RgnType;
prgn=pl->pDispNode;
pMrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
flags=DDBLTFAST_WAIT;
if (type==PRIMARY_NODIRECTW)
{
// if (DESCOLORKEY)
// flags |= DDBLTFAST_SRCCOLORKEY;
//screen coord
x=pMrgn->u.MRgn.DRect.top + prgn->u.SRgn.DesRect.top;
y=pMrgn->u.MRgn.DRect.left+ prgn->u.SRgn.DesRect.left;
ddrval=g_lpDDSPrimary->BltFast( x, y, prgn->u.SRgn.pSrcSurf, &prgn->u.SRgn.SrcRect, flags);
m_Err.err=ddrval;
m_Err.errloc=DD_BltFast_LOC;
return (ddrval==DD_OK);
}
else //OVERLAY_NODIRECTW
{
}
}
*/
// after call this fun you must alloc sysmem and set pSrc->psrc
BOOL CDDrawOverlay::GetSubRgnSrcBuf(HANDLE hSubRgn,SubRgnSrcBuf * pSrc)
{
DispRegionList * pl=(DispRegionList *)hSubRgn;
DispRegion * prgn;
if (!pl||(pl->pDispNode->RgnType&(MASKHWDIRECTWRITE|MASKMAINREIGON)))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
if (pSrc==0)
{
m_Err.err=INPUT_POINTER_ZERO_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
prgn=pl->pDispNode;
pSrc->psrcbuf=(BYTE *)prgn->u.SRgn.SrcBufAddress;
pSrc->buflength=(prgn->u.SRgn.SrcRect.bottom)*(prgn->u.SRgn.SrcRect.right)*
( (((DispRegion *)prgn->u.SRgn.pMDispRgn)->u.MRgn.PixelDepth));
return TRUE;
}
//before call this fun pSrc->psrc must be a valid dma sysmem (not 0)
BOOL CDDrawOverlay::SetSubRgnSrcBuf(HANDLE hSubRgn,SubRgnSrcBuf * pSrc)
{
DispRegionList * pl=(DispRegionList *)hSubRgn;
DispRegion * prgn;
DispRegion * pMrgn;
if (!pl||(pl->pDispNode->RgnType&(MASKHWDIRECTWRITE|MASKMAINREIGON)))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
if (pSrc==0)//||(pSrc->psrcbuf==0))
{
m_Err.err=INPUT_POINTER_ZERO_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
prgn=pl->pDispNode;
pMrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
//use for copydata
prgn->u.SRgn.SrcBufAddress=(DWORD)pSrc->psrcbuf;
prgn->u.SRgn.SrcBufW_bytes=prgn->u.SRgn.SrcRect.right*(pMrgn->u.MRgn.PixelDepth);
prgn->u.SRgn.SrcBufH=prgn->u.SRgn.SrcRect.bottom;
prgn->u.SRgn.SrcBufPitch=prgn->u.SRgn.SrcBufW_bytes;
return TRUE;
}
BOOL CDDrawOverlay::CheckSubRegion(void * p,RECT * pSubRect)
{
DispRegion * pMrgn=(DispRegion * ) p;
//is the sub region in main region
if ((pMrgn->u.MRgn.DRect.right-pMrgn->u.MRgn.DRect.left<
pSubRect->right-pSubRect->left))
goto too_large;
if ((pMrgn->u.MRgn.DRect.bottom-pMrgn->u.MRgn.DRect.top<
pSubRect->bottom-pSubRect->top))
goto too_large;
if (pSubRect->bottom-pSubRect->top<MINREGION_H)
goto too_small;
if (pSubRect->right-pSubRect->left<MINREGION_W)
goto too_small;
return TRUE;
too_large:
m_Err.err=SUBREGION_TOO_LARGE_ERR;
m_Err.errloc=CheckSubRegion_LOC;
return FALSE;
too_small:
m_Err.err=SUBREGION_TOO_SMALL_ERR;
m_Err.errloc=CheckSubRegion_LOC;
return FALSE;
}
//only use for OVERLAY_NODIRECTW or OVERLAY_NODIRECTW Mode
BOOL CDDrawOverlay::CopyDataToSubRegion(HANDLE hSubRgn)
{
HRESULT ddrval;
int x,y,h,i,w_byte;
DispRegionList * pl=(DispRegionList *)hSubRgn;
int type;
DispRegion * prgn;
DispRegion * pMrgn;
register BYTE * pDest;
register BYTE * pSrc;
int Pitch;
int SPitch;
DDSURFACEDESC DDSDesc;
// DWORD dw;
if (!pl||(pl->pDispNode->RgnType&(MASKHWDIRECTWRITE|MASKMAINREIGON)))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
prgn=pl->pDispNode;
INIT_DIRECTDRAW_STRUCT(DDSDesc);
//ie Lock fun //wait 10s
if (!LockBuffer(&prgn->u.SRgn.VidBufLockVar,(PVOID)2,10000))
{
m_Err.err=NORMAL_ERR;
m_Err.errloc=WAIT_LOCK_OUTOFTIME_LOC;
return FALSE;
}
/*
//ie Lock fun //wait 10s
if ((dw=WaitForSingleObject(prgn->u.SRgn.VidBufMutex,10000))!=WAIT_OBJECT_0 )
{
m_Err.err=NORMAL_ERR;
m_Err.errloc=WAIT_LOCK_OUTOFTIME_LOC;
return FALSE;
}
*/
pSrc=(BYTE *)prgn->u.SRgn.SrcBufAddress;
if (!pSrc)
{
//UNLOCK
//ReleaseMutex(prgn->u.SRgn.VidBufMutex);
UnLockBuffer(&prgn->u.SRgn.VidBufLockVar);
m_Err.err=POINTER_ZERO_ERR;
m_Err.errloc=CHECK_PARAMS_LOC;
return FALSE;
}
type=prgn->RgnType;
pMrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
h=prgn->u.SRgn.SrcBufH;
w_byte=prgn->u.SRgn.SrcBufW_bytes;
//SPitch=prgn->u.SRgn.SrcPitch;
SPitch=prgn->u.SRgn.SrcBufPitch;
// INIT_DIRECTDRAW_STRUCT(DDSDesc);
// ie Lock fun //wait 10s
// if ((dw=WaitForSingleObject(prgn->u.SRgn.VidBufMutex,10000))!=WAIT_OBJECT_0 )
// return FALSE;
if (type==PRIMARY_NODIRECTW)
{
if((ddrval = g_lpDDSPrimary->Lock(NULL,&DDSDesc,DDLOCK_WAIT , NULL )) == DD_OK)
{
pDest = (BYTE *)DDSDesc.lpSurface; //note: pDest==pMrgn->u.MRgn.MStartAddress
Pitch = DDSDesc.lPitch;
if(pDest == NULL)// || iPitch < iWidth)
{
g_lpDDSPrimary->Unlock( NULL );
m_Err.err=INVALIDE_RARAMS_ERR;
m_Err.errloc=CHECK_PARAMS_LOC;
//UNLOCK
//ReleaseMutex(prgn->u.SRgn.VidBufMutex);
UnLockBuffer(&prgn->u.SRgn.VidBufLockVar);
return FALSE;
}
y=pMrgn->u.MRgn.DRect.top + prgn->u.SRgn.DesRect.top;
x=pMrgn->u.MRgn.DRect.left+ prgn->u.SRgn.DesRect.left;
if (x>(int)g_ScreenW||y>(int)g_ScreenH)
{
UnLockBuffer(&prgn->u.SRgn.VidBufLockVar);
OutputDebugString("Copy Out of Range Error");
return FALSE;
}
pDest =(BYTE *) (pDest + y * Pitch + x * (pMrgn->u.MRgn.PixelDepth));
//FastCopy((DWORD *)pSrc, iWidth, (DWORD *)pDest, iPitch, iWidth, iHeight, FALSE);
for(i=0; i<h; i++)
{
memcpy( pDest, pSrc, SPitch);
pDest += Pitch;
pSrc += SPitch;//w_byte;
}
g_lpDDSPrimary->Unlock(NULL);
//UNLOCK
//ReleaseMutex(prgn->u.SRgn.VidBufMutex);
UnLockBuffer(&prgn->u.SRgn.VidBufLockVar);
return TRUE;
}
else
{
m_Err.err=ddrval;
m_Err.errloc=DD_Lock_LOC;
//UNLOCK
//ReleaseMutex(prg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -