overlay_ddraw.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:21k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: overlay_ddraw.c 615 2006-01-26 16:57:51Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #ifdef _WIN32
  25. #define WIN32_LEAN_AND_MEAN
  26. #ifndef STRICT
  27. #define STRICT
  28. #endif
  29. #include <windows.h>
  30. #if _MSC_VER > 1000
  31. #pragma warning( push, 3 )
  32. #endif
  33. #include "ddraw.h"
  34. #include "overlay_ddraw.h"
  35. /*
  36. #undef DEBUG_BIN
  37. #undef DEBUG_MSG
  38. #undef DEBUG_MSG1
  39. #undef DEBUG_MSG2
  40. #undef DEBUG_MSG3
  41. #undef DEBUG_MSG4
  42. #undef DEBUG_MSG5
  43. #undef DEBUG_MSG6
  44. #undef DEBUG_MSG7
  45. #define DEBUG_BIN(m,x,p,n) DebugBinary(x,p,n)
  46. #define DEBUG_MSG(m,x) DebugMessage(x)
  47. #define DEBUG_MSG1(m,x,a) DebugMessage(x,a)
  48. #define DEBUG_MSG2(m,x,a,b) DebugMessage(x,a,b)
  49. #define DEBUG_MSG3(m,x,a,b,c) DebugMessage(x,a,b,c)
  50. #define DEBUG_MSG4(m,x,a,b,c,d) DebugMessage(x,a,b,c,d)
  51. #define DEBUG_MSG5(m,x,a,b,c,d,e) DebugMessage(x,a,b,c,d,e)
  52. #define DEBUG_MSG6(m,x,a,b,c,d,e,f) DebugMessage(x,a,b,c,d,e,f)
  53. #define DEBUG_MSG7(m,x,a,b,c,d,e,f,g) DebugMessage(x,a,b,c,d,e,f,g)
  54. */
  55. static void Desc2Surface( const DDSURFACEDESC* Desc, video* p )
  56. {
  57. memset(p,0,sizeof(video));
  58. p->Width = Desc->dwWidth;
  59. p->Height = Desc->dwHeight;
  60. p->Aspect = ASPECT_ONE;
  61. p->Direction = 0;
  62. if (Desc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
  63. {
  64. p->Pixel.Flags = PF_FOURCC;
  65. p->Pixel.FourCC = Desc->ddpfPixelFormat.dwFourCC;
  66. }
  67. else
  68. if (Desc->ddpfPixelFormat.dwFlags & DDPF_RGB)
  69. {
  70. p->Pixel.Flags = PF_RGB;
  71. p->Pixel.BitCount = Desc->ddpfPixelFormat.dwRGBBitCount;
  72. p->Pixel.BitMask[0] = Desc->ddpfPixelFormat.dwRBitMask;
  73. p->Pixel.BitMask[1] = Desc->ddpfPixelFormat.dwGBitMask;
  74. p->Pixel.BitMask[2] = Desc->ddpfPixelFormat.dwBBitMask;
  75. }
  76. else
  77. if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1)
  78. {
  79. p->Pixel.Flags = PF_PALETTE;
  80. p->Pixel.BitCount = 1;
  81. }
  82. else
  83. if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2)
  84. {
  85. p->Pixel.Flags = PF_PALETTE;
  86. p->Pixel.BitCount = 2;
  87. }
  88. else
  89. if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
  90. {
  91. p->Pixel.Flags = PF_PALETTE;
  92. p->Pixel.BitCount = 4;
  93. }
  94. else
  95. if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
  96. {
  97. p->Pixel.Flags = PF_PALETTE;
  98. p->Pixel.BitCount = 8;
  99. }
  100. }
  101. static bool_t Surface2Desc( const video* p, DDSURFACEDESC* Desc, bool_t PixelFormat )
  102. {
  103. memset(Desc,0,sizeof(DDSURFACEDESC));
  104. Desc->dwSize = sizeof(DDSURFACEDESC);
  105. Desc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
  106. Desc->dwWidth = p->Width;
  107. Desc->dwHeight = p->Height;
  108. if (PixelFormat)
  109. {
  110. Desc->dwFlags |= DDSD_PIXELFORMAT;
  111. Desc->ddpfPixelFormat.dwSize = sizeof(Desc->ddpfPixelFormat);
  112. if (p->Pixel.Flags & PF_FOURCC)
  113. {
  114. Desc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
  115. Desc->ddpfPixelFormat.dwFourCC = p->Pixel.FourCC;
  116. }
  117. else
  118. if (p->Pixel.Flags & PF_RGB)
  119. {
  120. Desc->ddpfPixelFormat.dwFlags = DDPF_RGB;
  121. Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
  122. Desc->ddpfPixelFormat.dwRBitMask = p->Pixel.BitMask[0];
  123. Desc->ddpfPixelFormat.dwGBitMask = p->Pixel.BitMask[1];
  124. Desc->ddpfPixelFormat.dwBBitMask = p->Pixel.BitMask[2];
  125. }
  126. else
  127. if (p->Pixel.Flags & PF_PALETTE)
  128. {
  129. switch (p->Pixel.BitCount)
  130. {
  131. case 1: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED1; break;
  132. case 2: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED2; break;
  133. case 4: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4; break;
  134. case 8: Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; break;
  135. }
  136. Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
  137. }
  138. else
  139. return 0;
  140. }
  141. return 1;
  142. }
  143. static bool_t ClearBuffer(ddraw* p,LPDIRECTDRAWSURFACE Buffer)
  144. {
  145. bool_t Result = 0;
  146. DDSURFACEDESC Desc;
  147. Desc.dwSize = sizeof(Desc);
  148. TRY_BEGIN
  149. if (IDirectDrawSurface_Lock(Buffer,NULL,&Desc,DDLOCK_WAIT,NULL) == DD_OK)
  150. {
  151. int v,x2,y2,pitch2;
  152. FillInfo(&p->Overlay.Pixel);
  153. v = RGBToFormat(CRGB(0,0,0),&p->Overlay.Pixel);
  154. TRY_BEGIN
  155. if (PlanarYUV(&p->Overlay.Pixel,&x2,&y2,&pitch2) && p->Overlay.Pixel.BitCount==8)
  156. {
  157. uint8_t* i = (uint8_t*)Desc.lpSurface;
  158. FillColor(i,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,8,v & 255);
  159. i += Desc.lPitch * p->Overlay.Height;
  160. FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>8)&255);
  161. i += (Desc.lPitch >> x2) * (p->Overlay.Height >> y2);
  162. FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>16)&255);
  163. }
  164. else
  165. if (PackedYUV(&p->Overlay.Pixel) && p->Overlay.Pixel.BitCount==16)
  166. FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width >> 1,p->Overlay.Height,32,v);
  167. else
  168. FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,p->Overlay.Pixel.BitCount,v);
  169. Result = 1;
  170. TRY_END
  171. IDirectDrawSurface_Unlock(Buffer,NULL);
  172. }
  173. TRY_END
  174. return Result;
  175. }
  176. static void ReleaseBuffers(ddraw* p)
  177. {
  178. if (p->DDBackBuffer) 
  179. IDirectDrawSurface_Release(p->DDBackBuffer); 
  180. p->DDBackBuffer = NULL;
  181. }
  182. if (p->DDBuffer) 
  183. if (p->Mode == MODE_OVERLAY)
  184. IDirectDrawSurface_UpdateOverlay(p->DDBuffer,NULL,p->DDPrimary,NULL,DDOVER_HIDE,NULL);
  185. IDirectDrawSurface_Release(p->DDBuffer); 
  186. p->DDBuffer = NULL;
  187. }
  188. }
  189. static bool_t CreateBuffer(ddraw* p,bool_t PixelFormat)
  190. {
  191. DDSURFACEDESC Desc;
  192. p->BufferPixelFormat = PixelFormat;
  193. if (p->DDBackBuffer) 
  194. IDirectDrawSurface_Release(p->DDBackBuffer); 
  195. p->DDBackBuffer = NULL;
  196. }
  197. if (p->DDBuffer) 
  198. IDirectDrawSurface_Release(p->DDBuffer); 
  199. p->DDBuffer = NULL;
  200. }
  201. if (!Surface2Desc(&p->Overlay,&Desc,PixelFormat))
  202. return 0;
  203. Desc.dwFlags |= DDSD_CAPS;
  204. Desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
  205. if (p->Mode == MODE_OVERLAY)
  206. {
  207. Desc.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
  208. Desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;
  209. Desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
  210. Desc.dwBackBufferCount = 1;
  211. }
  212. 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);
  213. if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL) != DD_OK)
  214. {
  215. if (p->Mode == MODE_OVERLAY)
  216. {
  217. // try without backbuffer...
  218. Desc.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP);
  219. Desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
  220. IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL);
  221. }
  222. if (!p->DDBuffer)
  223. {
  224. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Failed"));
  225. return 0;
  226. }
  227. }
  228. else
  229. if (p->Mode == MODE_OVERLAY)
  230. {
  231. Desc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
  232. IDirectDrawSurface_GetAttachedSurface(p->DDBuffer,&Desc.ddsCaps,&p->DDBackBuffer);
  233. }
  234. if (IDirectDrawSurface_GetSurfaceDesc(p->DDBuffer,&Desc) == DD_OK)
  235. Desc2Surface(&Desc,&p->Overlay);
  236. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Ok"));
  237. if (!ClearBuffer(p,p->DDBuffer))
  238. {
  239. ReleaseBuffers(p);
  240. return 0;
  241. }
  242. if (p->DDBackBuffer)
  243. ClearBuffer(p,p->DDBackBuffer);
  244. return 1;
  245. }
  246. static int UpdateOverlay(ddraw* p)
  247. {
  248. p->Src.left = p->OverlayRect.x;
  249. p->Src.top = p->OverlayRect.y;
  250. p->Src.right = p->OverlayRect.x + p->OverlayRect.Width;
  251. p->Src.bottom = p->OverlayRect.y + p->OverlayRect.Height;
  252.  
  253. p->Dst.left = p->p.DstAlignedRect.x;
  254. p->Dst.top = p->p.DstAlignedRect.y;
  255. p->Dst.right = p->p.DstAlignedRect.x + p->p.DstAlignedRect.Width;
  256. p->Dst.bottom = p->p.DstAlignedRect.y + p->p.DstAlignedRect.Height;
  257. if (p->Mode == MODE_OVERLAY &&
  258. p->OverlayRect.Width>0 && p->OverlayRect.Height>0 &&
  259. p->p.DstAlignedRect.Width>0 && p->p.DstAlignedRect.Height>0)
  260. {
  261. DWORD hResult;
  262. int Flags = 0;
  263. DDOVERLAYFX DDFX;
  264. memset(&DDFX,0,sizeof(DDFX));
  265. DDFX.dwSize = sizeof(DDFX);
  266. if (p->OvlFX.Flags & (BLITFX_ARITHSTRETCH50|BLITFX_ARITHSTRETCHALWAYS))
  267. {
  268. Flags |= DDOVER_DDFX;
  269. DDFX.dwDDFX |= DDOVERFX_ARITHSTRETCHY;
  270. }
  271. if (p->p.Show)
  272. Flags |= DDOVER_SHOW;
  273. else
  274. Flags |= DDOVER_HIDE;
  275. if (p->p.ColorKey != RGB_NULL)
  276. {
  277. Flags |= DDOVER_KEYDEST;
  278. //Flags |= DDOVER_KEYDESTOVERRIDE;
  279. //DDFX.dckDestColorkey.dwColorSpaceLowValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel);
  280. //DDFX.dckDestColorkey.dwColorSpaceHighValue = 0;
  281. }
  282. hResult = IDirectDrawSurface_UpdateOverlay(p->DDBuffer,&p->Src,p->DDPrimary,&p->Dst,Flags,&DDFX);
  283. if (hResult != DD_OK)
  284. DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW UpdateOverlay failed %08x"),hResult);
  285. }
  286. return ERR_NONE;
  287. }
  288. static void GetMode(ddraw *p)
  289. {
  290. DDSURFACEDESC Desc;
  291. memset(&Desc,0,sizeof(DDSURFACEDESC));
  292. Desc.dwSize = sizeof(DDSURFACEDESC);
  293. IDirectDraw_GetDisplayMode(p->DD,&Desc);
  294. Desc2Surface(&Desc,&p->p.Output.Format.Video);
  295. FillInfo(&p->p.Output.Format.Video.Pixel);
  296. }
  297. static int GetAlign(int i)
  298. {
  299. int v=1;
  300. while (v<16 && v<i)
  301. v<<=1;
  302. return v;
  303. }
  304. static int Init(ddraw* p)
  305. {
  306. DDSURFACEDESC Desc;
  307. p->p.ColorKey = RGB_NULL;
  308. if (p->SetupColorKey && IsWindow(Context()->Wnd))
  309. p->p.ColorKey = COLORKEY;
  310. if (p->DDCaps.dwCaps & DDCAPS_OVERLAYSTRETCH)
  311. {
  312. p->MinScale = (p->DDCaps.dwMinOverlayStretch * SCALE_ONE) / 1000;
  313. p->MaxScale = (p->DDCaps.dwMaxOverlayStretch * SCALE_ONE) / 1000;
  314. }
  315. else
  316. {
  317. p->MinScale = SCALE_ONE;
  318. p->MaxScale = SCALE_ONE;
  319. }
  320. if (p->DDCaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST)
  321. p->DstAlignPos = GetAlign(p->DDCaps.dwAlignBoundaryDest);
  322. else
  323. p->DstAlignPos = 1;
  324. if (p->DDCaps.dwCaps & DDCAPS_ALIGNSIZEDEST)
  325. p->DstAlignSize = GetAlign(p->DDCaps.dwAlignSizeDest);
  326. else
  327. p->DstAlignSize = 1;
  328. GetMode(p);
  329. // get primary surface
  330. memset(&Desc,0,sizeof(DDSURFACEDESC));
  331. Desc.dwSize = sizeof(DDSURFACEDESC);
  332. Desc.dwFlags = DDSD_CAPS;
  333. Desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  334. if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDPrimary,NULL) != DD_OK)
  335. return ERR_DEVICE_ERROR;
  336. p->p.Overlay = 1;
  337. p->p.UpdateShow = UpdateOverlay;
  338. p->Overlay = p->p.Input.Format.Video;
  339. p->Mode = MODE_OVERLAY;
  340. // first try the optimal overlay format
  341. if (!p->SetupBlit && (p->Format != DDRAWFORMAT_AUTO || !CreateBuffer(p,1)))
  342. {
  343. if (PlanarYUV(&p->Overlay.Pixel,NULL,NULL,NULL))
  344. {
  345. // try other formats
  346. static const uint32_t FourCC[] = 
  347. // prefer planar420 formats
  348. FOURCC_YV12, DDRAWFORMAT_YV12, 
  349. FOURCC_IYUV, DDRAWFORMAT_YV12,
  350. FOURCC_I420, DDRAWFORMAT_YV12,
  351. FOURCC_IMC2, DDRAWFORMAT_YV12, 
  352. FOURCC_IMC4, DDRAWFORMAT_YV12, 
  353. // next planar422 formats
  354. FOURCC_YV16, DDRAWFORMAT_YV12,
  355. // next packed formats
  356. FOURCC_YUY2, DDRAWFORMAT_YUY2, 
  357. FOURCC_YUNV, DDRAWFORMAT_YUY2,  
  358. FOURCC_V422, DDRAWFORMAT_YUY2,  
  359. FOURCC_YUYV, DDRAWFORMAT_YUY2,  
  360. FOURCC_YVYU, DDRAWFORMAT_YUY2,  
  361. FOURCC_UYVY, DDRAWFORMAT_YUY2,  
  362. FOURCC_Y422, DDRAWFORMAT_YUY2,  
  363. FOURCC_UYNV, DDRAWFORMAT_YUY2,
  364. };
  365. const uint32_t* i;
  366. for (i=FourCC;i[0];i+=2)
  367. {
  368. p->Overlay.Pixel.Flags = PF_FOURCC;
  369. p->Overlay.Pixel.FourCC = i[0];
  370. if ((p->Format == DDRAWFORMAT_AUTO || p->Format == (int)i[1]) && CreateBuffer(p,1))
  371. break;
  372. }
  373. }
  374. // last hope is the device's current RGB mode (still better as blit mode)
  375. if (!p->DDBuffer && (p->Format == DDRAWFORMAT_AUTO || p->Format == DDRAWFORMAT_RGB))
  376. CreateBuffer(p,0);
  377. }
  378. if (!p->DDBuffer)
  379. {
  380. // try blit mode
  381. p->p.Overlay = 0;
  382. p->p.UpdateShow = NULL;
  383. p->p.ColorKey = RGB_NULL;
  384. p->DstAlignPos = 1;
  385. p->DstAlignSize = 1;
  386. p->MinScale = SCALE_ONE/256;
  387. p->MaxScale = SCALE_ONE*256;
  388. if (p->SetupBlitStretch)
  389. {
  390. p->Mode = MODE_BLIT; 
  391. CreateBuffer(p,0);
  392. }
  393. if (!p->DDBuffer)
  394. {
  395. p->Mode = MODE_PRIMARY; // use primary mode
  396. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Primary Mode"));
  397. }
  398. else
  399. {
  400. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Stretch Mode"));
  401. if (IsWindow(Context()->Wnd) &&
  402. IDirectDraw_CreateClipper(p->DD,0,&p->DDClipper,NULL) == DD_OK && 
  403. IDirectDrawClipper_SetHWnd(p->DDClipper,0,Context()->Wnd) == DD_OK)
  404. IDirectDrawSurface_SetClipper(p->DDPrimary,p->DDClipper);
  405. }
  406. }
  407. else
  408. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Overlay Mode"));
  409. if (p->Mode != MODE_BLIT)
  410. p->p.SetFX = BLITFX_AVOIDTEARING;
  411. return ERR_NONE;
  412. }
  413. static void Done(ddraw* p)
  414. {
  415. if (p->DDClipper) 
  416. {
  417. IDirectDrawClipper_Release(p->DDClipper); 
  418. p->DDClipper = NULL;
  419. }
  420. ReleaseBuffers(p);
  421. if (p->DDPrimary) 
  422. IDirectDrawSurface_Release(p->DDPrimary); 
  423. p->DDPrimary = NULL;
  424. }
  425. }
  426. static int Update(ddraw* p)
  427. {
  428. int OvlWidth = p->p.Input.Format.Video.Width;
  429. int OvlHeight = p->p.Input.Format.Video.Height;
  430. if (p->Mode == MODE_PRIMARY)
  431. return OverlayUpdateAlign(&p->p);
  432. p->OvlFX = p->p.FX;
  433. p->SoftFX = p->p.FX;
  434. p->OvlFX.Brightness = 0;
  435. p->OvlFX.Contrast = 0;
  436. p->OvlFX.Saturation = 0;
  437. p->OvlFX.RGBAdjust[0] = p->OvlFX.RGBAdjust[1] = p->OvlFX.RGBAdjust[2] = 0;
  438. p->OvlFX.Direction &= ~(DIR_SWAPXY|DIR_MIRRORLEFTRIGHT|DIR_MIRRORUPDOWN); //rotate handled by SoftFX
  439. p->SoftFX.ScaleX = SCALE_ONE; // scale handled by overlay or blit
  440. p->SoftFX.ScaleY = SCALE_ONE;
  441. if ((p->Mode == MODE_BLIT && !(p->DDCaps.dwFXCaps & DDFXCAPS_BLTARITHSTRETCHY)) ||
  442.     (p->Mode == MODE_OVERLAY && !(p->DDCaps.dwFXCaps & DDFXCAPS_OVERLAYARITHSTRETCHY)))
  443. p->OvlFX.Flags &= ~(BLITFX_ARITHSTRETCH50|BLITFX_ARITHSTRETCHALWAYS);
  444. if (p->SoftFX.Direction & DIR_SWAPXY)
  445. SwapInt(&p->OvlFX.ScaleX,&p->OvlFX.ScaleY);
  446. if ((p->p.OrigFX.Direction ^ p->p.InputDirection) & DIR_SWAPXY)
  447. SwapInt(&OvlWidth,&OvlHeight);
  448. if (p->Overlay.Width != OvlWidth || p->Overlay.Height != OvlHeight)
  449. {
  450. p->Overlay.Width = OvlWidth;
  451. p->Overlay.Height = OvlHeight;
  452. CreateBuffer(p,p->BufferPixelFormat);
  453. }
  454. VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  455. VirtToPhy(NULL,&p->OverlayRect,&p->Overlay);
  456. AnyAlign(&p->p.DstAlignedRect, &p->OverlayRect, &p->OvlFX,
  457. p->DstAlignSize,p->DstAlignPos,p->MinScale,p->MaxScale);
  458. PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video);
  459. VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
  460. BlitRelease(p->p.Soft);
  461. p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
  462. BlitAlign(p->p.Soft,&p->OverlayRect,&p->p.SrcAlignedRect);
  463. if (p->p.ColorKey!=RGB_NULL && p->DDPrimary)
  464. DWORD hResult;
  465. DDCOLORKEY Key;
  466. Key.dwColorSpaceLowValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel);
  467. Key.dwColorSpaceHighValue = 0;
  468. WinInvalidate(&p->p.Viewport,1);
  469. if ((hResult = IDirectDrawSurface_SetColorKey(p->DDPrimary,DDCKEY_DESTOVERLAY,&Key))!=DD_OK)
  470. {
  471. DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW SetColorKey failed %08x"),hResult);
  472. p->p.ColorKey = RGB_NULL;
  473. }
  474. }
  475. return UpdateOverlay(p);
  476. }
  477. static int Blit(ddraw* p, const constplanes Data, const constplanes DataLast )
  478. {
  479. DDSURFACEDESC Desc;
  480. HRESULT hResult;
  481. planes Planes;
  482. LPDIRECTDRAWSURFACE Output = p->Mode == MODE_PRIMARY ? p->DDPrimary:p->DDBuffer;
  483. if (p->Mode == MODE_OVERLAY && p->DDBackBuffer && p->p.CurrTime!=TIME_BENCH)
  484. Output = p->DDBackBuffer;
  485. if (!Output)
  486. return ERR_NOT_SUPPORTED;
  487. Desc.dwSize = sizeof(Desc);
  488. while ((hResult = IDirectDrawSurface_Lock(Output,NULL,&Desc,DDLOCK_WAIT,NULL)) != DD_OK)
  489. if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(Output) != DD_OK)
  490. return ERR_NOT_SUPPORTED;
  491. Planes[0] = Desc.lpSurface;
  492. BlitImage(p->p.Soft,Planes,Data,DataLast,Desc.lPitch,-1);
  493. IDirectDrawSurface_Unlock(Output,NULL);
  494. if (p->Mode == MODE_BLIT)
  495. {
  496. while ((hResult = IDirectDrawSurface_Blt(p->DDPrimary,&p->Dst,Output,&p->Src,DDBLT_ASYNC,NULL)) != DD_OK)
  497. if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(p->DDPrimary) != DD_OK)
  498. break;
  499. }
  500. else 
  501. if (p->Mode == MODE_OVERLAY && Output == p->DDBackBuffer)
  502. IDirectDrawSurface_Flip(p->DDBuffer,NULL,DDFLIP_WAIT);
  503. return ERR_NONE;
  504. }
  505. static const datatable Params[] = 
  506. {
  507. { DDRAW_FORMAT, TYPE_INT,  DF_SETUP|DF_ENUMSTRING|DF_ENUMUNSORT, DDRAWFORMAT_ENUM },
  508. { DDRAW_COLORKEY, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  509. { DDRAW_BLIT, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  510. { DDRAW_BLITSTRETCH, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  511. DATATABLE_END(DDRAW_ID)
  512. };
  513. static int Enum(ddraw* p, int* No, datadef* Param)
  514. {
  515. // same for ce and win32 version
  516. if (OverlayEnum(&p->p,No,Param)==ERR_NONE)
  517. return ERR_NONE;
  518. return NodeEnumTable(No,Param,Params);
  519. }
  520. static int Get(ddraw* p,int No,void* Data,int Size)
  521. {
  522. // same for ce and win32 version
  523. int Result = OverlayGet(&p->p,No,Data,Size);
  524. switch (No)
  525. {
  526. case DDRAW_FORMAT: GETVALUE(p->Format,int); break;
  527. case DDRAW_COLORKEY: GETVALUE(p->SetupColorKey,bool_t); break;
  528. case DDRAW_BLIT: GETVALUE(p->SetupBlit,bool_t); break;
  529. case DDRAW_BLITSTRETCH: GETVALUE(p->SetupBlitStretch,bool_t); break;
  530. }
  531. return Result;
  532. }
  533. static int ReInit(ddraw* p)
  534. {
  535. // same for ce and win32 version
  536. if (p->p.Inited)
  537. {
  538. player* Player;
  539. p->p.Done(p);
  540. p->p.Init(p);
  541. OverlayUpdateFX(&p->p,1);
  542. if ((Player = (player*)Context()->Player) != NULL)
  543. Player->Set(Player,PLAYER_UPDATEVIDEO,NULL,0);
  544. }
  545. return ERR_NONE;
  546. }
  547. static int Set(ddraw* p,int No,const void* Data,int Size)
  548. {
  549. // same for ce and win32 version
  550. int Result = OverlaySet(&p->p,No,Data,Size);
  551. switch (No)
  552. {
  553. case NODE_CRASH: p->p.Done(p); break;
  554. case DDRAW_FORMAT: SETVALUE(p->Format,int,ReInit(p)); break;
  555. case DDRAW_COLORKEY: SETVALUE(p->SetupColorKey,bool_t,ReInit(p)); break;
  556. case DDRAW_BLIT: SETVALUE(p->SetupBlit,bool_t,ReInit(p)); break;
  557. case DDRAW_BLITSTRETCH: SETVALUE(p->SetupBlitStretch,bool_t,ReInit(p)); break;
  558. }
  559. return Result;
  560. }
  561. static int Create(ddraw* p)
  562. {
  563. DWORD FourCC[32+1];
  564. DWORD FourCCCount = 32;
  565. LPDIRECTDRAW DD = NULL;
  566. HRESULT (WINAPI* DirectDrawCreate)( void*, LPDIRECTDRAW*, void* ) = NULL;
  567. #if defined(TARGET_WINCE)
  568. // some crashing problem on NOVOGO V30/50/70/90
  569. if (NodeEnumClass(NULL,RAW_ID) || NodeEnumClass(NULL,GAPI_ID) || NodeEnumClass(NULL,XSCALEDRIVER_ID))
  570. {
  571. int Type = QueryPlatform(PLATFORM_TYPENO);
  572. if (Type != TYPE_SMARTPHONE && Type != TYPE_POCKETPC && QueryPlatform(PLATFORM_VER)<500)
  573. {
  574. video Desktop;
  575. QueryDesktop(&Desktop);
  576. if (Desktop.Width * Desktop.Height <= 320*320)
  577. return ERR_NOT_SUPPORTED; // fallback to RawFrameBuffer/GAPI/XScale until things get fixed
  578. }
  579. }
  580. #endif
  581. p->p.Node.Enum = (nodeenum)Enum;
  582. p->p.Node.Get = (nodeget)Get;
  583. p->p.Node.Set = (nodeset)Set;
  584. p->Format = DDRAWFORMAT_AUTO;
  585. p->p.Module = LoadLibrary(T("DDRAW.DLL"));
  586. GetProc(&p->p.Module,&DirectDrawCreate,T("DirectDrawCreate"),0);
  587. if (!p->p.Module || DirectDrawCreate(NULL,&DD,NULL)!=DD_OK ||
  588. IDirectDraw_QueryInterface(DD,&IID_IDirectDraw,&p->DD)!=DD_OK)
  589. {
  590. if (DD && DDrawCECreate(p,DD)==ERR_NONE)
  591. return ERR_NONE;
  592. if (DD) IDirectDraw_Release(DD);
  593. if (p->p.Module) { FreeLibrary(p->p.Module); p->p.Module = NULL; }
  594. return ERR_DEVICE_ERROR;
  595. }
  596. IDirectDraw_Release(DD);
  597. IDirectDraw_SetCooperativeLevel(p->DD, NULL, DDSCL_NORMAL);
  598. p->DDCaps.dwSize = sizeof(p->DDCaps);
  599. IDirectDraw_GetCaps(p->DD,&p->DDCaps,NULL);
  600. DEBUG_BIN(DEBUG_VIDEO,T("DDRAW Caps"),&p->DDCaps,sizeof(p->DDCaps));
  601. IDirectDraw_GetFourCCCodes(p->DD,&FourCCCount,FourCC);
  602. DEBUG_BIN(DEBUG_VIDEO,T("DDRAW FourCC"),FourCC,sizeof(DWORD)*FourCCCount);
  603. p->SetupColorKey = (p->DDCaps.dwCaps & DDCAPS_COLORKEY);
  604. p->SetupBlit = !(p->DDCaps.dwCaps & DDCAPS_OVERLAY) && p->DDCaps.dwMaxVisibleOverlays==0;
  605. p->SetupBlitStretch = (p->DDCaps.dwCaps & DDCAPS_BLTSTRETCH) != 0;
  606. if (QueryPlatform(PLATFORM_MODEL)==MODEL_NEXIO_XP40)
  607. p->SetupColorKey = 0; // todo: figure out what is wrong with colorkey...
  608. p->p.DoPowerOff = 1;
  609. p->p.Init = Init;
  610. p->p.Done = Done;
  611. p->p.Blit = Blit;
  612. p->p.Update = Update;
  613. p->p.UpdateShow = UpdateOverlay;
  614. return ERR_NONE;
  615. }
  616. static void Delete(ddraw* p)
  617. {
  618. // same for ce and win32 version
  619. if (p->DD)
  620. IDirectDraw_Release(p->DD);
  621. }
  622. static const nodedef DDraw = 
  623. {
  624. sizeof(ddraw)|CF_GLOBAL|CF_SETTINGS,
  625. DDRAW_ID,
  626. OVERLAY_CLASS,
  627. PRI_DEFAULT+100,
  628. (nodecreate)Create,
  629. (nodedelete)Delete,
  630. };
  631. void OverlayDDraw_Init() 
  632. NodeRegisterClass(&DDraw);
  633. }
  634. void OverlayDDraw_Done()
  635. {
  636. NodeUnRegisterClass(DDRAW_ID);
  637. }
  638. #endif