📄 ddrawoverlay.cpp
字号:
m_Err.err=DO_NOT_SUPPORT_MUTIL_DISP_REGION_ERR;
m_Err.errloc=CreateDispRegion_LOC;
return 0;
}
*/
try
{
//check input params
if (!IsWindow(hDispWnd)) {throw apierr(DDRAW_BASEERR+INVALIDEPARAM," in CDDraw::CreateDispWind err",TRUE);};
//if ((typeOverlay)&&(g_lpDDSOverlay)) throw apierr(DDRAW_BASEERR+15,"Overlay Region can only be created one time in CDDraw::CreateDispRegion err",TRUE);
//check if the window client region is over the screen region
GetClientRect(hDispWnd, &rect );
if ((rect.right-rect.left)<MINREGION_W||(rect.bottom-rect.top)<MINREGION_H)
{
throw apierr(DDRAW_BASEERR+INVALIDEPARAM," in CDDraw::CreateDispRegion the Window is small",TRUE);
}
po1.x=rect.left;
po1.y=rect.top;
po2.x=rect.right;
po2.y=rect.bottom;
if (rect.right-rect.left>m_display.right) {throw apierr(DDRAW_BASEERR+5," in CDDraw::CreateDispRegion err",TRUE);};
if (rect.bottom-rect.top>m_display.bottom) {throw apierr(DDRAW_BASEERR+6," in CDDraw::CreateDispRegion err",TRUE);};
if (!ClientToScreen(hDispWnd, &po1)) {throw apierr(DDRAW_BASEERR+7," in CDDraw::CreateDispRegion err",TRUE);};
if (!ClientToScreen(hDispWnd, &po2)) {throw apierr(DDRAW_BASEERR+8," in CDDraw::CreateDispRegion err",TRUE);};
prgn=(DispRegion *)AllocNode();
if (prgn==0) {throw apierr(DDRAW_BASEERR+9," in CDDraw::CreateDispRegion err",TRUE);};
prgn->RgnType=RgnType|MASKMAINREIGON; //Set Main region
prgn->u.MRgn.hWnd=hDispWnd;
prgn->u.MRgn.hWnd=hDispWnd;
//screen coord
prgn->u.MRgn.DRect.left=po1.x&0xfffffffe;
prgn->u.MRgn.DRect.top=po1.y;
prgn->u.MRgn.DRect.right=po2.x;
prgn->u.MRgn.DRect.bottom=po2.y;
prgn->u.MRgn.StartHeight=rect.bottom-rect.top; //the Region initialized height
prgn->u.MRgn.StartWidth=rect.right-rect.left; //the Region initialized width
if (typeOverlay)
{
// prgn->u.MRgn.MStartAddress=g_lpOverlayStartAddr;
prgn->u.MRgn.Pitch=g_OverlayPitch;
prgn->u.MRgn.PixelDepth=g_OverlayPixelDepth;
prgn->u.MRgn.PixelId=g_OverlayPixelID;
if (g_OverlayPixelID==YUY2_FOURCCDD)
ClearSurface(g_lpDDSOverlay,&prgn->u.MRgn.DRect,g_OverlayClearColor,TRUE);
else
ClearSurface(g_lpDDSOverlay,&prgn->u.MRgn.DRect,g_OverlayClearColor,FALSE);
}
else
{
// prgn->u.MRgn.MStartAddress=g_lpPrimaryStartAddr;
prgn->u.MRgn.Pitch=g_PrimaryPitch;
prgn->u.MRgn.PixelDepth=g_PrimaryPixelDepth;
prgn->u.MRgn.PixelId=m_PrimaryPixelID;
}
hRgn=InsertNode(prgn);
}
catch(...)
{
if (!g_apierr)
{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::CreateDispRegion",TRUE);};
}
g_MainDispRegionIsInstalled=TRUE;
return hRgn;
}
BOOL CDDrawOverlay::DestoryDispRegion(HANDLE hRgn)
{
BOOL ret=FALSE;
DispRegionList * pn=(DispRegionList *)hRgn;
//check if the hRgn is valid HANDLE
if ((!hRgn)||(((DispRegionList *)hRgn)->ValidID!=0x10540001)) return ret;
try {
if (!(pn->pDispNode->RgnType&MASKMAINREIGON)) {throw apierr(DDRAW_BASEERR+12,"hRgn invalide err in CDDraw::DestoryDispRegion",TRUE);};
//if is main region
DestoryAllSubDispRegion(pn);
/*
if (pn->pDispNode->RgnType&MASKPRIMARYOVERLAY)
{ //if is overlay
DestoryOverlay();
}
*/
//DELETE this main node
//DestoryMainRegion(pn->pDispNode);
RemoveNode(pn);
ret=TRUE;
}
catch(...)
{
if (!g_apierr)
{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::DestoryDispRegion",TRUE);};
}
g_MainDispRegionIsInstalled=FALSE;
return ret;
}
BOOL CDDrawOverlay::CheckFourCCPixel(int PixelId)
{
DWORD * FourCCArry;
DWORD yuy2C=0x32595559;
int i;
//only support YUY2_FOURCC
if (PixelId==YUY2_FOURCCDD)
{
FourCCArry=(DWORD *)malloc(m_MyHWCaps.dwNumFourCCCodes*sizeof(DWORD));
g_lpDD2->GetFourCCCodes(&m_MyHWCaps.dwNumFourCCCodes,FourCCArry);
for (i=0;i<(int)m_MyHWCaps.dwNumFourCCCodes;i++)
{
if (yuy2C==FourCCArry[i])
{
return TRUE;
}
}
};
return FALSE;
}
BOOL CDDrawOverlay::CheckRGBPixel(int PixelId)
{//only support YUY2_FOURCC
BOOL ret=FALSE;
DDPIXELFORMAT ddpf;
try {
ZeroMemory( &ddpf, sizeof(DDPIXELFORMAT) );
ddpf.dwSize=sizeof(DDPIXELFORMAT);
if ((m_Err.err=g_lpDDSPrimary->GetPixelFormat(&ddpf)))
{
m_Err.errloc=DD_GetPixelFormat_LOC;
{throw apierr(DDRAW_BASEERR+11,"except err in CDDraw::CheckRGBPixel",TRUE);};
};
if (PixelId==RGB565DD)
{
if ((ddpf.dwRBitMask==0x0000f800)&&
(ddpf.dwGBitMask==0x000007e0)&&
(ddpf.dwBBitMask==0x0000001f))
ret=TRUE;
}
else if (PixelId==RGB888DD)
{
if ((ddpf.dwRBitMask==0x00ff0000)&&
(ddpf.dwGBitMask==0x0000ff00)&&
(ddpf.dwBBitMask==0x000000ff)&&(ddpf.dwRGBBitCount!=0x20))
ret=TRUE;
}
else if (PixelId==RGB555DD)
{
if ((ddpf.dwRBitMask==0x00007c00)&&
(ddpf.dwGBitMask==0x000003e0)&&
(ddpf.dwBBitMask==0x0000001f))
ret=TRUE;
}
else if (PixelId==RGB888A)
{
if ((ddpf.dwRBitMask==0x00ff0000)&&
(ddpf.dwGBitMask==0x0000ff00)&&
(ddpf.dwBBitMask==0x000000ff)&&(ddpf.dwRGBBitCount==0x20))
ret=TRUE;
}
}
catch (...)
{
if (!g_apierr)
{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::CheckRGBPixel",TRUE);}
}
return ret;
}
int CDDrawOverlay::GetRGBPixelID(int PixelID)
{
int id=-1;
int i;
int APixelID[4]={RGB555DD,RGB565DD,RGB888DD,RGB888A};
/*
if (RgnType&MASKPRIMARYOVERLAY) //overlay
{
if (IsSupportOverlay())
{
//if (RgnType&MASKHWDIRECTWRITE)
//{
if (PixelID==0) //default
{
id =CheckOverlayPixel();
if (CheckFourCCPixel(APixelID[3])) //YUY2
{
id=APixelID[3];
}
}
//}
//else
//{
// if
//}
}
}
else //Primary
{
*/
if (PixelID<0) //default
{
for (i=0;i<4;i++)
{
if (CheckRGBPixel(APixelID[i]))
{
id=APixelID[i];
break;
}
}
}
else
{
if (CheckRGBPixel(PixelID))
{
id=PixelID;
}
}
return id;
}
BOOL CDDrawOverlay::DestoryAllRegions()
{
DispRegionList * p=pHeadList;
while (p)
{
//pn=p->pDispnode;
if (p->pDispNode->RgnType&MASKMAINREIGON)
{
DestoryDispRegion(p);
}
else
{
DestoryDispSubRegion(p);
}
p=pHeadList;
}
pHeadList=0;
pTailList=0;
return TRUE;
}
//input pn is the main disp region block pointer
BOOL CDDrawOverlay::DestoryAllSubDispRegion(void * pmlist)
{
DispRegionList * pn=(DispRegionList * ) pmlist;
DispRegionList * p=pHeadList;
DispRegionList * ptemp;
//search all sub region of this main region pn
while (p)
{
ptemp=p;
p=p->pnext;
//is sub region
if (!(ptemp->pDispNode->RgnType&MASKMAINREIGON))
{
//if the sub region is the sub region of pn
if ((DispRegion *)ptemp->pDispNode->u.SRgn.pMDispRgn==pn->pDispNode)
{
//DestoryDispSubRegion(pn); //delete one sub region node
DestoryDispSubRegionI(ptemp);
// RemoveNode(ptemp);
}
}
} //end while
return TRUE;
}
//create disp SubRegion inside the Region
//if success return one SubRegion HANDLE>0,if failed return 0
// the RECT must be inside the Region,the coordinate is relative to the Region
HANDLE CDDrawOverlay::CreateDispSubRegion(HANDLE hRgn,RECT * pDRect)
{
DispRegionList * pn=(DispRegionList *)hRgn;
DispRegion * prgn=0;
DispRegion * pMrgn;
RECT DRect;
RECT * pDesRect=pDRect;
HANDLE h=0;
try
{
if ((!hRgn)||((DWORD)hRgn>0xc0000000)||(((DispRegionList *)hRgn)->ValidID!=0x10540001)) {throw apierr(DDRAW_BASEERR+INVALIDEPARAM," in CDDraw::CreateDispSubRegion err",TRUE);};
pMrgn=pn->pDispNode;
//if pDRect is 0 then use the main region for sub region
//buf change the screen coordinate to relative coordinate
if (!pDRect)
{
DRect.left=0;
DRect.top=0;
DRect.right=pMrgn->u.MRgn.DRect.right-pMrgn->u.MRgn.DRect.left;
DRect.bottom=pMrgn->u.MRgn.DRect.bottom-pMrgn->u.MRgn.DRect.top;
pDesRect=&DRect;
}
if (!CheckSubRegion(pMrgn,pDesRect))
{throw apierr(DDRAW_BASEERR+14," in call CheckSubRegion of CreateDispSubRegion err",TRUE);};
if ((pDesRect->right-pDesRect->left)<MINREGION_W||(pDesRect->bottom-pDesRect->top)<MINREGION_H)
{throw apierr(DDRAW_BASEERR+INVALIDEPARAM," in CDDraw::CreateDispSubRegion the Region is too small",TRUE);};
//check input params,the hRgn must be one Main Region handle
if (!(pn->pDispNode->RgnType&MASKMAINREIGON)) {throw apierr(DDRAW_BASEERR+INVALIDEPARAM," in CDDraw::CreateDispSubRegion err",TRUE);};
prgn=(DispRegion *)AllocNode();
if (prgn==0) {throw apierr(DDRAW_BASEERR+10," in CDDraw::CreateDispSubRegion err",TRUE);};
prgn->RgnType=pn->pDispNode->RgnType&(~MASKMAINREIGON); //Set sub region RgnType
prgn->u.SRgn.pMDispRgn=(void *)pMrgn;
if (!ProcessSubRegion(prgn,pDesRect)) {throw apierr(DDRAW_BASEERR+13," in call ProcessSubRegion of CreateDispSubRegion err",TRUE);};
h=InsertNode(prgn);
ClearRegion(h);
/*
static int b=0;
static HANDLE h1,h2;
if (b==0)
{
h1=h;
ClearRegion(h);//,DESCOLORKEY);
//DisplayOverlay(h);
b++;
}
else
{
if (b==1)
h2=h;
//DisplayOverlay(h2);
ClearRegion(h1);//,DESCOLORKEY);
//DisplayOverlay(h1);
ClearRegion(h2,0);//,DESCOLORKEY);
//DisplayOverlay(h2);
if (b==2)
{
//ClearSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,0,TRUE);
//RECT rc;
//rc.bottom=599;
//rc.left=0;
//rc.right=799;
//rc.top=0;
//ClearSurface(g_lpDDSOverlay,&rc,RGB(0x0,0,0xff),TRUE);//&pMrgn->u.MRgn.DRect,0,TRUE);
//FillSurface(g_lpDDSOverlay,&pMrgn->u.MRgn.DRect,0,TRUE);
ClearRegion(h);//,DESCOLORKEY);
// DisplayOverlay(h);
}
b++;
}
*/
}
catch(...)
{
if (!g_apierr)
{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::CreateDispSubRegion",TRUE);}
else
{
DeleteNode(prgn);
h=0;
}
}
return h;
}
BOOL CDDrawOverlay::DestoryDispSubRegionI(void * p)
{
BOOL ret=FALSE;
DispRegionList * pn=(DispRegionList *) p;
if (!p) return FALSE;
try {
//delete this sub region proce can insert here
//DestorySubRegion(pn->pDispNode);
// if (LockBuffer(&pn->pDispNode->u.SRgn.VidBufLockVar,(PVOID)3,10000)
/*
if (pn->pDispNode->u.SRgn.VidBufMutex)
{
WaitForSingleObject(pn->pDispNode->u.SRgn.VidBufMutex,10000);
CloseHandle(pn->pDispNode->u.SRgn.VidBufMutex);
pn->pDispNode->u.SRgn.VidBufMutex=0;
}
*/
if (pn->pDispNode->u.SRgn.pSrcSurf)
{
DestorySurface(pn->pDispNode->u.SRgn.pSrcSurf);
pn->pDispNode->u.SRgn.pSrcSurf=0;
}
if (pn->pDispNode->u.SRgn.pDesSurf)
{
DestorySurface(pn->pDispNode->u.SRgn.pDesSurf);
pn->pDispNode->u.SRgn.pDesSurf=0;
}
RemoveNode(pn);
ret=TRUE;
}
catch(...)
{
if (!g_apierr)
{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::DestoryDispSubRegionI",TRUE);};
}
return ret;
}
BOOL CDDrawOverlay::DestoryDispSubRegion(HANDLE hSubRgn)
{
BOOL ret=FALSE;
//check if the hRgn is valid HANDLE
if ((!hSubRgn)||(((DispRegionList *)hSubRgn)->ValidID!=0x10540001)) return ret;
DispRegionList * pn=(DispRegionList *)hSubRgn;
if ((pn->pDispNode->RgnType&MASKMAINREIGON)) return ret;
return DestoryDispSubRegionI(pn);
}
//FOR main region,the coordinate of RECT is screen coordinate
//fro sub region,the coordinate of RECT is relative to main Region RECT left,top point
BOOL CDDrawOverlay::GetDispRegion(HANDLE hRgn,RECT * pct)
{
DispRegionList * pn=(DispRegionList *)hRgn;
//check if the hRgn is valid HANDLE
if ((!pn)||(pn->ValidID!=0x10540001))
{
m_Err.err=INPUT_HANDLE_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
if (!pct)
{
m_Err.err=INPUT_POINTER_ZERO_ERR;
m_Err.errloc=CHECK_INPUT_PARAMS_LOC;
return FALSE;
}
//if main region
if (pn->pDispNode->RgnType&MASKMAINREIGON)
*pct=pn->pDispNode->u.MRgn.DRect;
else //sub region
*pct=pn->pDispNode->u.SRgn.DesRect;
return TRUE;
}
BOOL CDDrawOverlay::ProcessSubRegion(void * p,RECT * pDRect)
{
// HRESULT ddrval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -