/***************************************************************************** * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: overlay_ddraw.c 615 2006-01-26 16:57:51Z picard $ * * The Core Pocket Media Player * Copyright (c) 2004-2005 Gabor Kovacs * ****************************************************************************/ #include "../common.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #ifndef STRICT #define STRICT #endif #include #if _MSC_VER > 1000 #pragma warning( push, 3 ) #endif #include "ddraw.h" #include "overlay_ddraw.h" /* #undef DEBUG_BIN #undef DEBUG_MSG #undef DEBUG_MSG1 #undef DEBUG_MSG2 #undef DEBUG_MSG3 #undef DEBUG_MSG4 #undef DEBUG_MSG5 #undef DEBUG_MSG6 #undef DEBUG_MSG7 #define DEBUG_BIN(m,x,p,n) DebugBinary(x,p,n) #define DEBUG_MSG(m,x) DebugMessage(x) #define DEBUG_MSG1(m,x,a) DebugMessage(x,a) #define DEBUG_MSG2(m,x,a,b) DebugMessage(x,a,b) #define DEBUG_MSG3(m,x,a,b,c) DebugMessage(x,a,b,c) #define DEBUG_MSG4(m,x,a,b,c,d) DebugMessage(x,a,b,c,d) #define DEBUG_MSG5(m,x,a,b,c,d,e) DebugMessage(x,a,b,c,d,e) #define DEBUG_MSG6(m,x,a,b,c,d,e,f) DebugMessage(x,a,b,c,d,e,f) #define DEBUG_MSG7(m,x,a,b,c,d,e,f,g) DebugMessage(x,a,b,c,d,e,f,g) */ static void Desc2Surface( const DDSURFACEDESC* Desc, video* p ) { memset(p,0,sizeof(video)); p->Width = Desc->dwWidth; p->Height = Desc->dwHeight; p->Aspect = ASPECT_ONE; p->Direction = 0; if (Desc->ddpfPixelFormat.dwFlags & DDPF_FOURCC) { p->Pixel.Flags = PF_FOURCC; p->Pixel.FourCC = Desc->ddpfPixelFormat.dwFourCC; } else if (Desc->ddpfPixelFormat.dwFlags & DDPF_RGB) { p->Pixel.Flags = PF_RGB; p->Pixel.BitCount = Desc->ddpfPixelFormat.dwRGBBitCount; p->Pixel.BitMask[0] = Desc->ddpfPixelFormat.dwRBitMask; p->Pixel.BitMask[1] = Desc->ddpfPixelFormat.dwGBitMask; p->Pixel.BitMask[2] = Desc->ddpfPixelFormat.dwBBitMask; } else if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1) { p->Pixel.Flags = PF_PALETTE; p->Pixel.BitCount = 1; } else if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2) { p->Pixel.Flags = PF_PALETTE; p->Pixel.BitCount = 2; } else if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) { p->Pixel.Flags = PF_PALETTE; p->Pixel.BitCount = 4; } else if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { p->Pixel.Flags = PF_PALETTE; p->Pixel.BitCount = 8; } } static bool_t Surface2Desc( const video* p, DDSURFACEDESC* Desc, bool_t PixelFormat ) { memset(Desc,0,sizeof(DDSURFACEDESC)); Desc->dwSize = sizeof(DDSURFACEDESC); Desc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; Desc->dwWidth = p->Width; Desc->dwHeight = p->Height; if (PixelFormat) { Desc->dwFlags |= DDSD_PIXELFORMAT; Desc->ddpfPixelFormat.dwSize = sizeof(Desc->ddpfPixelFormat); if (p->Pixel.Flags & PF_FOURCC) { Desc->ddpfPixelFormat.dwFlags = DDPF_FOURCC; Desc->ddpfPixelFormat.dwFourCC = p->Pixel.FourCC; } else if (p->Pixel.Flags & PF_RGB) { Desc->ddpfPixelFormat.dwFlags = DDPF_RGB; Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount; Desc->ddpfPixelFormat.dwRBitMask = p->Pixel.BitMask[0]; Desc->ddpfPixelFormat.dwGBitMask = p->Pixel.BitMask[1]; Desc->ddpfPixelFormat.dwBBitMask = p->Pixel.BitMask[2]; } else if (p->Pixel.Flags & PF_PALETTE) { switch (p->Pixel.BitCount) { case 1: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED1; break; case 2: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED2; break; case 4: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4; break; case 8: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; break; } Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount; } else return 0; } return 1; } static bool_t ClearBuffer(ddraw* p,LPDIRECTDRAWSURFACE Buffer) { bool_t Result = 0; DDSURFACEDESC Desc; Desc.dwSize = sizeof(Desc); TRY_BEGIN if (IDirectDrawSurface_Lock(Buffer,NULL,&Desc,DDLOCK_WAIT,NULL) == DD_OK) { int v,x2,y2,pitch2; FillInfo(&p->Overlay.Pixel); v = RGBToFormat(CRGB(0,0,0),&p->Overlay.Pixel); TRY_BEGIN if (PlanarYUV(&p->Overlay.Pixel,&x2,&y2,&pitch2) && p->Overlay.Pixel.BitCount==8) { uint8_t* i = (uint8_t*)Desc.lpSurface; FillColor(i,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,8,v & 255); i += Desc.lPitch * p->Overlay.Height; FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>8)&255); i += (Desc.lPitch >> x2) * (p->Overlay.Height >> y2); FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>16)&255); } else if (PackedYUV(&p->Overlay.Pixel) && p->Overlay.Pixel.BitCount==16) FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width >> 1,p->Overlay.Height,32,v); else FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,p->Overlay.Pixel.BitCount,v); Result = 1; TRY_END IDirectDrawSurface_Unlock(Buffer,NULL); } TRY_END return Result; } static void ReleaseBuffers(ddraw* p) { if (p->DDBackBuffer) { IDirectDrawSurface_Release(p->DDBackBuffer); p->DDBackBuffer = NULL; } if (p->DDBuffer) { if (p->Mode == MODE_OVERLAY) IDirectDrawSurface_UpdateOverlay(p->DDBuffer,NULL,p->DDPrimary,NULL,DDOVER_HIDE,NULL); IDirectDrawSurface_Release(p->DDBuffer); p->DDBuffer = NULL; } } static bool_t CreateBuffer(ddraw* p,bool_t PixelFormat) { DDSURFACEDESC Desc; p->BufferPixelFormat = PixelFormat; if (p->DDBackBuffer) { IDirectDrawSurface_Release(p->DDBackBuffer); p->DDBackBuffer = NULL; } if (p->DDBuffer) { IDirectDrawSurface_Release(p->DDBuffer); p->DDBuffer = NULL; } if (!Surface2Desc(&p->Overlay,&Desc,PixelFormat)) return 0; Desc.dwFlags |= DDSD_CAPS; Desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; if (p->Mode == MODE_OVERLAY) { Desc.ddsCaps.dwCaps |= DDSCAPS_OVERLAY; Desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; Desc.dwFlags |= DDSD_BACKBUFFERCOUNT; Desc.dwBackBufferCount = 1; } DEBUG_MSG5(DEBUG_VIDEO,T("DDRAW CreateSurface %08x %dx%d %08x %08x"),Desc.ddsCaps.dwCaps,Desc.dwWidth,Desc.dwHeight,Desc.ddpfPixelFormat.dwFlags,Desc.ddpfPixelFormat.dwFourCC); if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL) != DD_OK) { if (p->Mode == MODE_OVERLAY) { // try without backbuffer... Desc.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP); Desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL); } if (!p->DDBuffer) { DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Failed")); return 0; } } else if (p->Mode == MODE_OVERLAY) { Desc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; IDirectDrawSurface_GetAttachedSurface(p->DDBuffer,&Desc.ddsCaps,&p->DDBackBuffer); } if (IDirectDrawSurface_GetSurfaceDesc(p->DDBuffer,&Desc) == DD_OK) Desc2Surface(&Desc,&p->Overlay); DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Ok")); if (!ClearBuffer(p,p->DDBuffer)) { ReleaseBuffers(p); return 0; } if (p->DDBackBuffer) ClearBuffer(p,p->DDBackBuffer); return 1; } static int UpdateOverlay(ddraw* p) { p->Src.left = p->OverlayRect.x; p->Src.top = p->OverlayRect.y; p->Src.right = p->OverlayRect.x + p->OverlayRect.Width; p->Src.bottom = p->OverlayRect.y + p->OverlayRect.Height; p->Dst.left = p->p.DstAlignedRect.x; p->Dst.top = p->p.DstAlignedRect.y; p->Dst.right = p->p.DstAlignedRect.x + p->p.DstAlignedRect.Width; p->Dst.bottom = p->p.DstAlignedRect.y + p->p.DstAlignedRect.Height; if (p->Mode == MODE_OVERLAY && p->OverlayRect.Width>0 && p->OverlayRect.Height>0 && p->p.DstAlignedRect.Width>0 && p->p.DstAlignedRect.Height>0) { DWORD hResult; int Flags = 0; DDOVERLAYFX DDFX; memset(&DDFX,0,sizeof(DDFX)); DDFX.dwSize = sizeof(DDFX); if (p->OvlFX.Flags & (BLITFX_ARITHSTRETCH50|BLITFX_ARITHSTRETCHALWAYS)) { Flags |= DDOVER_DDFX; DDFX.dwDDFX |= DDOVERFX_ARITHSTRETCHY; } if (p->p.Show) Flags |= DDOVER_SHOW; else Flags |= DDOVER_HIDE; if (p->p.ColorKey != RGB_NULL) { Flags |= DDOVER_KEYDEST; //Flags |= DDOVER_KEYDESTOVERRIDE; //DDFX.dckDestColorkey.dwColorSpaceLowValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel); //DDFX.dckDestColorkey.dwColorSpaceHighValue = 0; } hResult = IDirectDrawSurface_UpdateOverlay(p->DDBuffer,&p->Src,p->DDPrimary,&p->Dst,Flags,&DDFX); if (hResult != DD_OK) DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW UpdateOverlay failed %08x"),hResult); } return ERR_NONE; } static void GetMode(ddraw *p) { DDSURFACEDESC Desc; memset(&Desc,0,sizeof(DDSURFACEDESC)); Desc.dwSize = sizeof(DDSURFACEDESC); IDirectDraw_GetDisplayMode(p->DD,&Desc); Desc2Surface(&Desc,&p->p.Output.Format.Video); FillInfo(&p->p.Output.Format.Video.Pixel); } static int GetAlign(int i) { int v=1; while (v<16 && vp.ColorKey = RGB_NULL; if (p->SetupColorKey && IsWindow(Context()->Wnd)) p->p.ColorKey = COLORKEY; if (p->DDCaps.dwCaps & DDCAPS_OVERLAYSTRETCH) { 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; } if (p->DDCaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) p->DstAlignPos = GetAlign(p->DDCaps.dwAlignBoundaryDest); else p->DstAlignPos = 1; if (p->DDCaps.dwCaps & DDCAPS_ALIGNSIZEDEST) p->DstAlignSize = GetAlign(p->DDCaps.dwAlignSizeDest); else p->DstAlignSize = 1; GetMode(p); // 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; 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")); if (IsWindow(Context()->Wnd) && IDirectDraw_CreateClipper(p->DD,0,&p->DDClipper,NULL) == DD_OK && IDirectDrawClipper_SetHWnd(p->DDClipper,0,Context()->Wnd) == DD_OK) IDirectDrawSurface_SetClipper(p->DDPrimary,p->DDClipper); } } 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) { if (p->DDClipper) { IDirectDrawClipper_Release(p->DDClipper); p->DDClipper = NULL; } ReleaseBuffers(p); if (p->DDPrimary) { IDirectDrawSurface_Release(p->DDPrimary); p->DDPrimary = NULL; } } static int Update(ddraw* p) { 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->Mode == MODE_BLIT && !(p->DDCaps.dwFXCaps & DDFXCAPS_BLTARITHSTRETCHY)) || (p->Mode == MODE_OVERLAY && !(p->DDCaps.dwFXCaps & DDFXCAPS_OVERLAYARITHSTRETCHY))) p->OvlFX.Flags &= ~(BLITFX_ARITHSTRETCH50|BLITFX_ARITHSTRETCHALWAYS); if (p->SoftFX.Direction & DIR_SWAPXY) SwapInt(&p->OvlFX.ScaleX,&p->OvlFX.ScaleY); if ((p->p.OrigFX.Direction ^ p->p.InputDirection) & DIR_SWAPXY) SwapInt(&OvlWidth,&OvlHeight); if (p->Overlay.Width != OvlWidth || p->Overlay.Height != OvlHeight) { p->Overlay.Width = OvlWidth; p->Overlay.Height = OvlHeight; CreateBuffer(p,p->BufferPixelFormat); } VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video); VirtToPhy(NULL,&p->OverlayRect,&p->Overlay); AnyAlign(&p->p.DstAlignedRect, &p->OverlayRect, &p->OvlFX, p->DstAlignSize,p->DstAlignPos,p->MinScale,p->MaxScale); PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video); VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video); 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); p->p.ColorKey = RGB_NULL; } } 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) return ERR_NOT_SUPPORTED; Desc.dwSize = sizeof(Desc); while ((hResult = IDirectDrawSurface_Lock(Output,NULL,&Desc,DDLOCK_WAIT,NULL)) != DD_OK) if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(Output) != DD_OK) return ERR_NOT_SUPPORTED; Planes[0] = Desc.lpSurface; 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_ASYNC,NULL)) != DD_OK) if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(p->DDPrimary) != DD_OK) break; } else if (p->Mode == MODE_OVERLAY && Output == p->DDBackBuffer) IDirectDrawSurface_Flip(p->DDBuffer,NULL,DDFLIP_WAIT); return ERR_NONE; } static const datatable Params[] = { { DDRAW_FORMAT, TYPE_INT, DF_SETUP|DF_ENUMSTRING|DF_ENUMUNSORT, DDRAWFORMAT_ENUM }, { DDRAW_COLORKEY, TYPE_BOOL, DF_SETUP|DF_CHECKLIST }, { DDRAW_BLIT, TYPE_BOOL, DF_SETUP|DF_CHECKLIST }, { DDRAW_BLITSTRETCH, TYPE_BOOL, DF_SETUP|DF_CHECKLIST }, DATATABLE_END(DDRAW_ID) }; static int Enum(ddraw* p, int* No, datadef* Param) { // same for ce and win32 version if (OverlayEnum(&p->p,No,Param)==ERR_NONE) return ERR_NONE; return NodeEnumTable(No,Param,Params); } static int Get(ddraw* p,int No,void* Data,int Size) { // same for ce and win32 version int Result = OverlayGet(&p->p,No,Data,Size); switch (No) { case DDRAW_FORMAT: GETVALUE(p->Format,int); break; case DDRAW_COLORKEY: GETVALUE(p->SetupColorKey,bool_t); break; case DDRAW_BLIT: GETVALUE(p->SetupBlit,bool_t); break; case DDRAW_BLITSTRETCH: GETVALUE(p->SetupBlitStretch,bool_t); break; } return Result; } static int ReInit(ddraw* p) { // same for ce and win32 version if (p->p.Inited) { player* Player; p->p.Done(p); p->p.Init(p); OverlayUpdateFX(&p->p,1); if ((Player = (player*)Context()->Player) != NULL) Player->Set(Player,PLAYER_UPDATEVIDEO,NULL,0); } return ERR_NONE; } static int Set(ddraw* p,int No,const void* Data,int Size) { // same for ce and win32 version int Result = OverlaySet(&p->p,No,Data,Size); switch (No) { case NODE_CRASH: p->p.Done(p); break; case DDRAW_FORMAT: SETVALUE(p->Format,int,ReInit(p)); break; case DDRAW_COLORKEY: SETVALUE(p->SetupColorKey,bool_t,ReInit(p)); break; case DDRAW_BLIT: SETVALUE(p->SetupBlit,bool_t,ReInit(p)); break; case DDRAW_BLITSTRETCH: SETVALUE(p->SetupBlitStretch,bool_t,ReInit(p)); break; } return Result; } static int Create(ddraw* p) { DWORD FourCC[32+1]; DWORD FourCCCount = 32; LPDIRECTDRAW DD = NULL; HRESULT (WINAPI* DirectDrawCreate)( void*, LPDIRECTDRAW*, void* ) = NULL; #if defined(TARGET_WINCE) // some crashing problem on NOVOGO V30/50/70/90 if (NodeEnumClass(NULL,RAW_ID) || NodeEnumClass(NULL,GAPI_ID) || NodeEnumClass(NULL,XSCALEDRIVER_ID)) { int Type = QueryPlatform(PLATFORM_TYPENO); if (Type != TYPE_SMARTPHONE && Type != TYPE_POCKETPC && QueryPlatform(PLATFORM_VER)<500) { video Desktop; QueryDesktop(&Desktop); if (Desktop.Width * Desktop.Height <= 320*320) return ERR_NOT_SUPPORTED; // fallback to RawFrameBuffer/GAPI/XScale until things get fixed } } #endif p->p.Node.Enum = (nodeenum)Enum; p->p.Node.Get = (nodeget)Get; p->p.Node.Set = (nodeset)Set; p->Format = DDRAWFORMAT_AUTO; p->p.Module = LoadLibrary(T("DDRAW.DLL")); GetProc(&p->p.Module,&DirectDrawCreate,T("DirectDrawCreate"),0); if (!p->p.Module || DirectDrawCreate(NULL,&DD,NULL)!=DD_OK || IDirectDraw_QueryInterface(DD,&IID_IDirectDraw,&p->DD)!=DD_OK) { if (DD && DDrawCECreate(p,DD)==ERR_NONE) return ERR_NONE; if (DD) IDirectDraw_Release(DD); if (p->p.Module) { FreeLibrary(p->p.Module); p->p.Module = NULL; } 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); DEBUG_BIN(DEBUG_VIDEO,T("DDRAW Caps"),&p->DDCaps,sizeof(p->DDCaps)); IDirectDraw_GetFourCCCodes(p->DD,&FourCCCount,FourCC); DEBUG_BIN(DEBUG_VIDEO,T("DDRAW FourCC"),FourCC,sizeof(DWORD)*FourCCCount); p->SetupColorKey = (p->DDCaps.dwCaps & DDCAPS_COLORKEY); p->SetupBlit = !(p->DDCaps.dwCaps & DDCAPS_OVERLAY) && p->DDCaps.dwMaxVisibleOverlays==0; p->SetupBlitStretch = (p->DDCaps.dwCaps & DDCAPS_BLTSTRETCH) != 0; if (QueryPlatform(PLATFORM_MODEL)==MODEL_NEXIO_XP40) p->SetupColorKey = 0; // todo: figure out what is wrong with colorkey... p->p.DoPowerOff = 1; p->p.Init = Init; p->p.Done = Done; p->p.Blit = Blit; p->p.Update = Update; p->p.UpdateShow = UpdateOverlay; return ERR_NONE; } static void Delete(ddraw* p) { // same for ce and win32 version if (p->DD) IDirectDraw_Release(p->DD); } static const nodedef DDraw = { sizeof(ddraw)|CF_GLOBAL|CF_SETTINGS, DDRAW_ID, OVERLAY_CLASS, PRI_DEFAULT+100, (nodecreate)Create, (nodedelete)Delete, }; void OverlayDDraw_Init() { NodeRegisterClass(&DDraw); } void OverlayDDraw_Done() { NodeUnRegisterClass(DDRAW_ID); } #endif