📄 ddrawoverlay.cpp
字号:
//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 + -