📄 overlay_ddrawce.c
字号:
return v;
}
static int Init(ddraw* p)
{
DDSURFACEDESC Desc;
p->p.ColorKey = RGB_NULL;
if (p->SetupColorKey && IsWindow(Context()->Wnd))
p->p.ColorKey = COLORKEY;
if (p->DDCaps.dwMinOverlayStretch && p->DDCaps.dwMaxOverlayStretch)
{
p->MinScale = (p->DDCaps.dwMinOverlayStretch * SCALE_ONE) / 1000;
p->MaxScale = (p->DDCaps.dwMaxOverlayStretch * SCALE_ONE) / 1000;
}
else
{
p->MinScale = SCALE_ONE;
p->MaxScale = SCALE_ONE;
}
p->DstAlignPos = GetAlign(p->DDCaps.dwAlignBoundaryDest);
p->DstAlignSize = GetAlign(p->DDCaps.dwAlignSizeDest);
// get primary surface
memset(&Desc,0,sizeof(DDSURFACEDESC));
Desc.dwSize = sizeof(DDSURFACEDESC);
Desc.dwFlags = DDSD_CAPS;
Desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDPrimary,NULL) != DD_OK)
return ERR_DEVICE_ERROR;
if (IDirectDrawSurface_GetSurfaceDesc(p->DDPrimary,&Desc) != DD_OK)
return ERR_DEVICE_ERROR;
//{ int i; for (i=0;i<sizeof(Desc)/4;++i)
// DEBUG_MSG(DEBUG_VIDEO,T("DDRAW PrimaryDesc %02x:%08x"),i*4,((int*)&Desc)[i]); }
Desc2Surface(&Desc,&p->p.Output.Format.Video);
FillInfo(&p->p.Output.Format.Video.Pixel);
//{ int i; for (i=0;i<sizeof(p->p.Output.Format.Video)/4;++i)
// DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Output %02x:%08x"),i*4,((int*)&p->p.Output.Format.Video)[i]); }
p->p.Overlay = 1;
p->p.UpdateShow = UpdateOverlay;
p->Overlay = p->p.Input.Format.Video;
p->Mode = MODE_OVERLAY;
// first try the optimal overlay format
if (!p->SetupBlit && (p->Format != DDRAWFORMAT_AUTO || !CreateBuffer(p,1)))
{
if (PlanarYUV(&p->Overlay.Pixel,NULL,NULL,NULL))
{
// try other formats
static const uint32_t FourCC[] =
{
// prefer planar420 formats
FOURCC_YV12, DDRAWFORMAT_YV12,
FOURCC_IYUV, DDRAWFORMAT_YV12,
FOURCC_I420, DDRAWFORMAT_YV12,
FOURCC_IMC2, DDRAWFORMAT_YV12,
FOURCC_IMC4, DDRAWFORMAT_YV12,
// next planar422 formats
FOURCC_YV16, DDRAWFORMAT_YV12,
// next packed formats
FOURCC_YUY2, DDRAWFORMAT_YUY2,
FOURCC_YUNV, DDRAWFORMAT_YUY2,
FOURCC_V422, DDRAWFORMAT_YUY2,
FOURCC_YUYV, DDRAWFORMAT_YUY2,
FOURCC_YVYU, DDRAWFORMAT_YUY2,
FOURCC_UYVY, DDRAWFORMAT_YUY2,
FOURCC_Y422, DDRAWFORMAT_YUY2,
FOURCC_UYNV, DDRAWFORMAT_YUY2,
0
};
const uint32_t* i;
for (i=FourCC;i[0];i+=2)
{
p->Overlay.Pixel.Flags = PF_FOURCC;
p->Overlay.Pixel.FourCC = i[0];
if ((p->Format == DDRAWFORMAT_AUTO || p->Format == (int)i[1]) && CreateBuffer(p,1))
break;
}
}
// last hope is the device's current RGB mode (still better as blit mode)
if (!p->DDBuffer && (p->Format == DDRAWFORMAT_AUTO || p->Format == DDRAWFORMAT_RGB))
CreateBuffer(p,0);
}
if (!p->DDBuffer)
{
// try blit mode
p->p.Overlay = 0;
p->p.UpdateShow = NULL;
p->p.ColorKey = RGB_NULL;
p->DstAlignPos = 1;
p->DstAlignSize = 1;
p->MinScale = SCALE_ONE/256;
p->MaxScale = SCALE_ONE*256;
if (p->SetupBlitStretch)
{
p->Mode = MODE_BLIT;
CreateBuffer(p,0);
}
if (!p->DDBuffer)
{
p->Mode = MODE_PRIMARY; // use primary mode
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Primary Mode"));
}
else
{
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Stretch Mode"));
}
}
else
{
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Overlay Mode"));
}
if (p->Mode != MODE_BLIT)
p->p.SetFX = BLITFX_AVOIDTEARING;
return ERR_NONE;
}
static void Done(ddraw* p)
{
ReleaseBuffers(p);
if (p->DDPrimary)
{
IDirectDrawSurface_Release(p->DDPrimary);
p->DDPrimary = NULL;
}
}
static int Reset(ddraw* p)
{
Done(p);
Init(p);
return ERR_NONE;
}
static int Update(ddraw* p)
{
rect GUIOverlayRect;
int OvlWidth = p->p.Input.Format.Video.Width;
int OvlHeight = p->p.Input.Format.Video.Height;
if (p->Mode == MODE_PRIMARY)
return OverlayUpdateAlign(&p->p);
p->OvlFX = p->p.FX;
p->SoftFX = p->p.FX;
p->OvlFX.Brightness = 0;
p->OvlFX.Contrast = 0;
p->OvlFX.Saturation = 0;
p->OvlFX.RGBAdjust[0] = p->OvlFX.RGBAdjust[1] = p->OvlFX.RGBAdjust[2] = 0;
p->OvlFX.Direction &= ~(DIR_SWAPXY|DIR_MIRRORLEFTRIGHT|DIR_MIRRORUPDOWN); //rotate handled by SoftFX
p->SoftFX.ScaleX = SCALE_ONE; // scale handled by overlay or blit
p->SoftFX.ScaleY = SCALE_ONE;
if (p->SoftFX.Direction & DIR_SWAPXY)
SwapInt(&p->OvlFX.ScaleX,&p->OvlFX.ScaleY);
if (CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->Overlay.Direction) & DIR_SWAPXY)
SwapInt(&OvlWidth,&OvlHeight);
if (p->Overlay.Width != OvlWidth || p->Overlay.Height != OvlHeight)
{
p->Overlay.Direction = 0;
p->Overlay.Width = p->p.Input.Format.Video.Width;
p->Overlay.Height = p->p.Input.Format.Video.Height;
if (CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,0) & DIR_SWAPXY)
SwapInt(&p->Overlay.Width,&p->Overlay.Height);
if (!CreateBuffer(p,p->BufferPixelFormat))
{
p->Overlay.Width = 0;
p->Overlay.Height = 0;
return ERR_OUT_OF_MEMORY;
}
}
p->SoftFX.Direction = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->Overlay.Direction);
p->p.GUIAlignedRect = p->p.Viewport;
PhyToVirt(NULL,&GUIOverlayRect,&p->Overlay);
AnyAlign(&p->p.GUIAlignedRect, &GUIOverlayRect, &p->OvlFX,
p->DstAlignSize,p->DstAlignPos,p->MinScale,p->MaxScale);
VirtToPhy(&p->p.GUIAlignedRect,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
VirtToPhy(&GUIOverlayRect,&p->OverlayRect,&p->Overlay);
BlitRelease(p->p.Soft);
p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
BlitAlign(p->p.Soft,&p->OverlayRect,&p->p.SrcAlignedRect);
if (p->p.ColorKey!=RGB_NULL && p->DDPrimary)
{
DWORD hResult;
DDCOLORKEY Key;
Key.dwColorSpaceLowValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel);
Key.dwColorSpaceHighValue = 0;
WinInvalidate(&p->p.Viewport,1);
if ((hResult = IDirectDrawSurface_SetColorKey(p->DDPrimary,DDCKEY_DESTOVERLAY,&Key))!=DD_OK)
{
DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW SetColorKey failed %08x"),hResult);
return ERR_NOT_SUPPORTED;
}
}
return UpdateOverlay(p);
}
static int Blit(ddraw* p, const constplanes Data, const constplanes DataLast )
{
DDSURFACEDESC Desc;
HRESULT hResult;
planes Planes;
LPDIRECTDRAWSURFACE Output = p->Mode == MODE_PRIMARY ? p->DDPrimary:p->DDBuffer;
if (p->Mode == MODE_OVERLAY && p->DDBackBuffer && p->p.CurrTime!=TIME_BENCH)
Output = p->DDBackBuffer;
if (!Output)
{
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit no output"));
return ERR_NOT_SUPPORTED;
}
Desc.dwSize = sizeof(Desc);
while ((hResult = IDirectDrawSurface_Lock(Output,NULL,&Desc,DDLOCK_WAITNOTBUSY,NULL)) != DD_OK)
{
if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(Output) != DD_OK)
{
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW surface Lock() failed"));
return ERR_NOT_SUPPORTED;
}
}
//{ int i; for (i=0;i<sizeof(Desc)/4;++i)
// DEBUG_MSG(DEBUG_VIDEO,T("DDRAW LockDesc %02x:%08x"),i*4,((int*)&Desc)[i]); }
AdjustDesc(&Desc);
Planes[0] = Desc.lpSurface;
DEBUG_MSG4(DEBUG_VIDEO,T("DDRAW Blit %08x,%08x,%08x,%08x"),p->p.Soft,Planes[0],Desc.lPitch,Data);
BlitImage(p->p.Soft,Planes,Data,DataLast,Desc.lPitch,-1);
IDirectDrawSurface_Unlock(Output,NULL);
if (p->Mode == MODE_BLIT)
{
while ((hResult = IDirectDrawSurface_Blt(p->DDPrimary,&p->Dst,Output,&p->Src,DDBLT_WAITNOTBUSY,NULL)) != DD_OK)
if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(p->DDPrimary) != DD_OK)
{
DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blt() failed"));
break;
}
}
else
if (p->Mode == MODE_OVERLAY && Output == p->DDBackBuffer)
IDirectDrawSurface_Flip(p->DDBuffer,NULL,DDFLIP_WAITNOTBUSY);
return ERR_NONE;
}
int DDrawCECreate(ddraw* p,LPDIRECTDRAW DD)
{
int Model = QueryPlatform(PLATFORM_MODEL);
if (Model==MODEL_AXIM_X50)
return ERR_NOT_SUPPORTED; // buggy WM5 driver...
if (IDirectDraw_QueryInterface(DD,&IID_IDirectDraw,&p->DD)!=DD_OK)
return ERR_DEVICE_ERROR;
IDirectDraw_Release(DD);
IDirectDraw_SetCooperativeLevel(p->DD, NULL, DDSCL_NORMAL);
p->DDCaps.dwSize = sizeof(p->DDCaps);
IDirectDraw_GetCaps(p->DD,&p->DDCaps,NULL);
//{ int i; for (i=0;i<sizeof(p->DDCaps)/4;++i)
// DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Caps %02x:%08x"),i*4,((int*)&p->DDCaps)[i]); }
p->SetupColorKey = (p->DDCaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYDEST) != 0;
p->SetupBlit = (p->DDCaps.dwOverlayCaps & DDOVERLAYCAPS_OVERLAYSUPPORT) == 0;
p->SetupBlitStretch = 1;
if (p->SetupBlit && !p->DDCaps.dwVidMemTotal &&
(NodeEnumClass(NULL,RAW_ID) || NodeEnumClass(NULL,GAPI_ID)))
return ERR_NOT_SUPPORTED; // fallback to RawFrameBuffer or GAPI until things get fixed
p->p.DoPowerOff = 1;
p->p.Init = Init;
p->p.Done = Done;
p->p.Reset = Reset;
p->p.Blit = Blit;
p->p.Update = Update;
p->p.UpdateShow = UpdateOverlay;
return ERR_NONE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -