📄 ddrawoverlay.cpp
字号:
//ddsd.dwSize = sizeof(ddsd); // Sizeof the variable - these two steps required for most DDraw structs
if (!IsSupportFlip)
{
ddsd.dwFlags = DDSD_CAPS; // Set flags for variables we're using...
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // Set the variables we said we would in dwFlags
}
else //create primary and BACKBUFFER surface
{
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
}
LPDIRECTDRAWSURFACE lpDDSTemp;
ddrval = g_lpDD2->CreateSurface( &ddsd, &lpDDSTemp, NULL );
if( ddrval != DD_OK )
{
m_Err.err=ddrval;
m_Err.errloc=DD_CreateSurface_LOC;
return FALSE;
}
ddrval = lpDDSTemp->QueryInterface(IID_IDirectDrawSurface3, (void**)&g_lpDDSPrimary);
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 FALSE;
}
// ddrval = g_lpDD2->CreateSurface(&ddsd, &g_lpDDSPrimary, NULL);
// m_Err.err=ddrval;
// if (ddrval!=DD_OK) return FALSE;
INIT_DIRECTDRAW_STRUCT(DDSDesc);
ddrval = g_lpDDSPrimary->Lock( NULL , &DDSDesc , DDLOCK_WAIT , NULL );
m_Err.err=ddrval;
m_Err.errloc=DD_Lock_LOC;
if(ddrval!=DD_OK)
{
DestoryPrimary();
g_lpDDSPrimary= 0;
return FALSE;
}
g_lpPrimaryStartAddr = (UINT)DDSDesc.lpSurface;
g_PrimaryPitch = DDSDesc.lPitch;
g_PrimaryPixelDepth=(DDSDesc.ddpfPixelFormat.dwRGBBitCount>>3); //BYTES
g_ScreenH=DDSDesc.dwHeight;
g_ScreenW=DDSDesc.dwWidth;
g_lpDDSPrimary->Unlock( NULL );
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: DestroyPrimary()
// Desc: Releases the primary surface
//-----------------------------------------------------------------------------
void CDDrawOverlay::DestoryPrimary()
{
if (g_lpDDSPrimary)
{
g_lpDDSPrimary->Release();
g_lpDDSPrimary = NULL;
g_lpPrimaryStartAddr = 0;
g_PrimaryPitch = 0;
g_PrimaryPixelDepth=0;
}
}
//return Surf pointer
void * CDDrawOverlay::CreateSurface(int Mode, DWORD w, DWORD h )
{
LPDIRECTDRAWSURFACE3 surf;
LPDIRECTDRAWSURFACE lpDDSTemp;
HRESULT ddrval;
//DWORD bytes=w*h*(m_display.displaydepth/8);
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = w;
desc.dwHeight = h;
if (Mode==VIDMEMSURF)
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
if (Mode==SYSMEMSURF)
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddrval = g_lpDD2->CreateSurface( &desc, &lpDDSTemp, NULL );
if( ddrval != DD_OK )
{
m_Err.err=ddrval;
m_Err.errloc=DD_CreateSurface_LOC;
return 0;
}
HRESULT r=g_lpDD2->CreateSurface( &desc, &lpDDSTemp, 0 );
if (r!=DD_OK)
{
m_Err.err=ddrval;
m_Err.errloc=DD_CreateSurface_LOC;
return 0; //create failed
}
ddrval = lpDDSTemp->QueryInterface(IID_IDirectDrawSurface3, (void**)&surf);
lpDDSTemp->Release();
if (ddrval!=DD_OK)
{
m_Err.err=ddrval;
m_Err.errloc=DD_QueryIDDrawSurface3_LOC;
}
if ((ddrval=surf->PageLock(0))==DD_OK)
return surf; //success
else
{
m_Err.err=ddrval;
m_Err.errloc=DD_PageLock_LOC;
DestorySurface(surf);
return 0;
}
}
void CDDrawOverlay::DestorySurface(void * pSurf)
{
LPDIRECTDRAWSURFACE3 pSurface=(LPDIRECTDRAWSURFACE3)pSurf;
if (pSurf)
{
pSurface->PageUnlock(0);
pSurface->Release();
}
}
BOOL CDDrawOverlay::IsSupportOverlay()
{
BOOL b;
b= ( m_MyHWCaps.Overlay
&&m_MyHWCaps.OverlayStretch
&&m_MyHWCaps.OverlayDesColorKey
&&(m_MyHWCaps.dwMinOverlayStretch<=1000)
);
if (!b)
{
m_Err.err=DO_NOT_SUPPORT_OVERLAY_ERR;
m_Err.errloc=IsSupportOverlay_LOC;
apierr(m_MyHWCaps.Overlay,"Caps.Overlay",FALSE);
apierr(m_MyHWCaps.OverlayStretch,"Caps.OverlayStretch",FALSE);
apierr(m_MyHWCaps.dwMinOverlayStretch,"Caps.dwMinOverlayStretch",FALSE);
apierr(m_MyHWCaps.OverlayDesColorKey,"Caps.OverlayDesColorKey",TRUE);
}
return b;
//&&m_MyHWCaps.OverlaySrcColorKey;
}
BOOL CDDrawOverlay::GetScreenDispParams()
{
HDC dc;
if (!g_lpDDSPrimary) return FALSE;
m_Err.err=g_lpDDSPrimary->GetDC(&dc);
m_Err.errloc=DD_GetDC_LOC;
if (m_Err.err) return FALSE;
m_display.displaydepth=GetDeviceCaps(dc, BITSPIXEL);
m_display.left=0;
m_display.top=0;
m_display.right=GetDeviceCaps(dc, HORZRES );
m_display.bottom=GetDeviceCaps(dc, VERTRES );
g_lpDDSPrimary->ReleaseDC(dc);
return TRUE;
}
//videomode=VIDEO_MODE_NTSC,VIDEO_MODE_PAL
BOOL CDDrawOverlay::GetDispSubRegionVideoWindow(HANDLE hSubRgn,VIDEOWINDOW * pHWVidWind,BOOL VideoIsPAL)
{
BOOL ret=FALSE;
DispRegionList * pn=(DispRegionList *)hSubRgn;
DispRegion * prgn;
DispRegion * pmrgn;
int w,h;
ReSetSurfaceParams(this);
//check if the hRgn is valid HANDLE
if ((!pn)||(pn->ValidID!=0x10540001)) return FALSE;
//the hSubRgn must be one sub region handle
if (pn->pDispNode->RgnType&MASKMAINREIGON) return FALSE;
//Set sub video window type
//pn->pDispNode->RgnType|=SVidWinType;
prgn=pn->pDispNode;
pmrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
try
{
if (!pHWVidWind) {throw apierr(DDRAW_BASEERR+ZEROPOINTER," in CDDraw::GetHWDispSubRegionParams err",TRUE);};
ZeroMemory( pHWVidWind, sizeof(VIDEOWINDOW) );
//if (!GetNode(hSubRgn,&Rgn)) throw apierr(DDRAW_BASEERR+9," in CDDraw::GetHWDispSubRegionParams err");
pHWVidWind->iTop=0;
pHWVidWind->iLeft=0;
if (prgn->RgnType==PRIMARY_DIRECTW)
{
h=prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
w=prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
pHWVidWind->iPitch=pmrgn->u.MRgn.Pitch;
pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;
}
else if (prgn->RgnType==PRIMARY_NODIRECTW)
{
h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.SrcBufAddress;
}
else if (prgn->RgnType==OVERLAY_DIRECTW)
{
h=prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
w=prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
pHWVidWind->iPitch=pmrgn->u.MRgn.Pitch;
pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;
// h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
// w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
// pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
// pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;
}
else if (prgn->RgnType==OVERLAY_NODIRECTW)
{
h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.SrcBufAddress;
}
else return FALSE;
pHWVidWind->iBottom=h;//prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
pHWVidWind->iRight=w;//prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
pHWVidWind->iPixelDepth=pmrgn->u.MRgn.PixelDepth;
if (pmrgn->u.MRgn.PixelId==RGB565DD)
{
pHWVidWind->uiPixFormat=PF_RGB16_565;
}
else if (pmrgn->u.MRgn.PixelId==RGB555DD)
{
pHWVidWind->uiPixFormat=PF_RGB15_A555;
}
else if (pmrgn->u.MRgn.PixelId==RGB888DD)
{
pHWVidWind->uiPixFormat=PF_RGB24_888;
}
else if (pmrgn->u.MRgn.PixelId==RGB888A)
{
pHWVidWind->uiPixFormat=PF_RGB32_A888;
}
else //PixelId==YUY2_FOURCC
pHWVidWind->uiPixFormat=PF_YUV422;
pHWVidWind->uiHWCompress=1; //use hw compress
pHWVidWind->mirror=FALSE;
//set default offset
pHWVidWind->HOffset=8;//0;//8;
pHWVidWind->VOffset=24;//0;//24;
if (VideoIsPAL)
{
pHWVidWind->uiVideoMode=VIDEO_MODE_PAL;
if (h<289)
pHWVidWind->uiWindowMode=HALF_CCIR601;
else
pHWVidWind->uiWindowMode=FULL_CCIR601;
}
else
{
pHWVidWind->uiVideoMode=VIDEO_MODE_NTSC;
if (h<241)
pHWVidWind->uiWindowMode=HALF_CCIR601;
else
pHWVidWind->uiWindowMode=FULL_CCIR601;
}
ret=TRUE;
}
catch(...)
{
if (!g_apierr)
{
throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::GetHWDispSubRegionParams",TRUE);
}
}
return TRUE;
}
//videomode=VIDEO_MODE_NTSC,VIDEO_MODE_PAL
BOOL CDDrawOverlay::GetDispSubRegionSubVideoWindow(HANDLE hSubRgn,SVIDEOWINDOW * pSVidWin,BOOL VideoIsPAL)
{
BOOL b;
VIDEOWINDOW vw;
DispRegionList * pn;
DispRegion * pMrgn;
if (!GetDispSubRegionVideoWindow(hSubRgn,&vw,VideoIsPAL))
return FALSE;
b=ConvertVidWinToSubVidWin(&vw ,pSVidWin);
pn=(DispRegionList *)hSubRgn;
if (b&&(pn->pDispNode->RgnType&OVERLAY_NODIRECTW))
{
pMrgn=(DispRegion *)pn->pDispNode->u.SRgn.pMDispRgn;
pn->pDispNode->u.SRgn.SrcBufW_bytes=pSVidWin->SizeW*(pMrgn->u.MRgn.PixelDepth);
pn->pDispNode->u.SRgn.SrcBufH=pSVidWin->SizeH;
}
if (!b)
{
pSVidWin->uiSystemOverlayAddress=0;
}
return b;
}
//process the DispRegion not list
BOOL DeleteNode(DispRegion * prgn)
{
if (prgn==0) return FALSE;
if (m_NodeCounter<=0) return FALSE;
free(prgn);
m_NodeCounter--;
return TRUE;
}
//return one RgnNo
DispRegion * AllocNode()
{
DispRegion * p=0;
p=(DispRegion *)malloc(sizeof(DispRegion));
if (!p) return p;
ZeroMemory( p, sizeof(DispRegion) );
m_NodeCounter++;
return p;
}
//process the DispRegion list
DispRegionList * InsertNode(DispRegion * prgn)
{
DispRegionList * p;
p=(DispRegionList *)malloc(sizeof(DispRegionList));
if (p==NULL) return p;
p->ValidID=0x10540001;
p->pDispNode=prgn;
p->pnext=NULL;
if (pHeadList==NULL)
{ //FIRST memory node process
pHeadList=(DispRegionList *)p;
pTailList=(DispRegionList *)p;
p->pfront=NULL;
}
else //insert tail
{
p->pfront=pTailList;
pTailList->pnext=(DispRegionList *)p;
pTailList=p;
}
return p;
}
//process the DispRegion list
BOOL RemoveNode(DispRegionList * pn)
{
BOOL bfind=FALSE;
pn->ValidID=0;
if ((!pn->pfront)&&(!pn->pnext))
{ //delete only node
pHeadList=0;
pTailList=0;
}
else if (!pn->pnext)
{ //delete tail node
pTailList=pn->pfront;
pTailList->pnext=0;
}
else if (!pn->pfront)
{ //delete head node
pHeadList=pHeadList->pnext;
pHeadList->pfront=0;
}
else
{ //delete middle node
pn->pfront->pnext=pn->pnext;
pn->pnext->pfront=pn->pfront;
}
if (DeleteNode(pn->pDispNode))
{
free(pn);
bfind=TRUE;
};
return bfind;
}
/*
BOOL GetNode(HANDLE hRgn,DispRegion * pn)
{
DispRegionList * p=(DispRegionList *) hRgn;
DispRegion * p=(DispRegion *)hRgn;
//copy the data
* pn= * (this_pn->pDispnode);
return TRUE;
}
*/
BOOL FindNode(DispRegion * pn,DispRegionList * front_pn,DispRegionList * this_pn)
{
DispRegionList * p=pHeadList;
DispRegionList * pfront=pHeadList;
if (p==NULL) return FALSE;
do {
//find the node
if (p->pDispNode==pn)
{
if (p==pHeadList)
{
front_pn=this_pn=p;
}
else
{
front_pn=pfront;
this_pn=p;
}
return TRUE;
}
//not this node,find next
pfront=p;
p=p->pnext;
} while (p!=NULL);
return FALSE;
}
//create disp Region in Primary or Overlay surface with RGB16 or RGB24 or YUY2
//the Region is the the client region of the window
//if success return Region HANDLE >0 ,else RETURN 0
HANDLE CDDrawOverlay::CreateDispRegion(HWND hDispWnd,UINT RgnType,int PixelId)
{
RECT rect;
POINT po1,po2;
DispRegion * prgn;
HANDLE hRgn=0;
BOOL typeOverlay=RgnType&MASKPRIMARYOVERLAY;
if (!m_OK) return 0; // err
if (typeOverlay&&!g_lpDDSOverlay)
{
m_Err.err=DO_NOT_SUPPORT_OVERLAY_ERR;
m_Err.errloc=CreateDispRegion_LOC;
return 0;
}
ReSetSurfaceParams(this);
/* if ((g_InitMode&SUPPORT_SINGLE_MAIN_REGION)&&g_MainDispRegionIsInstalled)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -