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

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_ddrawce.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 "ddrawce.h"
  34. #include "overlay_ddraw.h"
  35. static int AdjustDesc( DDSURFACEDESC* Desc )
  36. {
  37. int Dir = 0;
  38. if (abs(Desc->lPitch) < abs(Desc->lXPitch))
  39. {
  40. DWORD Tmp;
  41. Tmp = Desc->dwWidth;
  42. Desc->dwWidth = Desc->dwHeight;
  43. Desc->dwHeight = Tmp;
  44. Tmp = Desc->lPitch;
  45. Desc->lPitch = Desc->lXPitch;
  46. Desc->lXPitch = Tmp;
  47. Dir |= DIR_SWAPXY;
  48. }
  49. if (Desc->lXPitch < 0)
  50. {
  51. Dir |= DIR_MIRRORLEFTRIGHT;
  52. Desc->lpSurface = (char*)Desc->lpSurface + Desc->lXPitch * (Desc->dwWidth-1);
  53. Desc->lXPitch = -Desc->lXPitch;
  54. }
  55. if (Desc->lPitch < 0)
  56. {
  57. Dir |= DIR_MIRRORUPDOWN;
  58. Desc->lpSurface = (char*)Desc->lpSurface + Desc->lPitch * (Desc->dwHeight-1);
  59. Desc->lPitch = -Desc->lPitch;
  60. }
  61. return Dir;
  62. }
  63. static void Desc2Surface( DDSURFACEDESC* Desc, video* p )
  64. {
  65. memset(p,0,sizeof(video));
  66. p->Direction = AdjustDesc(Desc);
  67. p->Aspect = ASPECT_ONE;
  68. p->Width = Desc->dwWidth;
  69. p->Height = Desc->dwHeight;
  70. if (Desc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
  71. {
  72. p->Pixel.Flags = PF_FOURCC;
  73. p->Pixel.FourCC = Desc->ddpfPixelFormat.dwFourCC;
  74. }
  75. else
  76. if (Desc->ddpfPixelFormat.dwFlags & DDPF_RGB)
  77. {
  78. p->Pixel.Flags = PF_RGB;
  79. p->Pixel.BitCount = Desc->ddpfPixelFormat.dwRGBBitCount;
  80. p->Pixel.BitMask[0] = Desc->ddpfPixelFormat.dwRBitMask;
  81. p->Pixel.BitMask[1] = Desc->ddpfPixelFormat.dwGBitMask;
  82. p->Pixel.BitMask[2] = Desc->ddpfPixelFormat.dwBBitMask;
  83. }
  84. else
  85. if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED)
  86. {
  87. p->Pixel.Flags = PF_PALETTE;
  88. p->Pixel.BitCount = 8;
  89. }
  90. }
  91. static bool_t Surface2Desc( const video* p, DDSURFACEDESC* Desc, bool_t PixelFormat )
  92. {
  93. memset(Desc,0,sizeof(DDSURFACEDESC));
  94. Desc->dwSize = sizeof(DDSURFACEDESC);
  95. Desc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
  96. Desc->dwWidth = p->Width;
  97. Desc->dwHeight = p->Height;
  98. if (PixelFormat)
  99. {
  100. Desc->dwFlags |= DDSD_PIXELFORMAT;
  101. Desc->ddpfPixelFormat.dwSize = sizeof(Desc->ddpfPixelFormat);
  102. if (p->Pixel.Flags & PF_FOURCC)
  103. {
  104. Desc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
  105. Desc->ddpfPixelFormat.dwFourCC = p->Pixel.FourCC;
  106. }
  107. else
  108. if (p->Pixel.Flags & PF_RGB)
  109. {
  110. Desc->ddpfPixelFormat.dwFlags = DDPF_RGB;
  111. Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
  112. Desc->ddpfPixelFormat.dwRBitMask = p->Pixel.BitMask[0];
  113. Desc->ddpfPixelFormat.dwGBitMask = p->Pixel.BitMask[1];
  114. Desc->ddpfPixelFormat.dwBBitMask = p->Pixel.BitMask[2];
  115. }
  116. else
  117. if (p->Pixel.Flags & PF_PALETTE && p->Pixel.BitCount==8)
  118. {
  119. Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED;
  120. Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
  121. }
  122. else
  123. return 0;
  124. }
  125. return 1;
  126. }
  127. static bool_t ClearBuffer(ddraw* p,LPDIRECTDRAWSURFACE Buffer)
  128. {
  129. bool_t Result = 0;
  130. DDSURFACEDESC Desc;
  131. Desc.dwSize = sizeof(Desc);
  132. TRY_BEGIN
  133. if (IDirectDrawSurface_Lock(p->DDBuffer,NULL,&Desc,DDLOCK_WAITNOTBUSY,NULL) == DD_OK)
  134. {
  135. int v,x2,y2,pitch2;
  136. AdjustDesc(&Desc);
  137. FillInfo(&p->Overlay.Pixel);
  138. v = RGBToFormat(CRGB(0,0,0),&p->Overlay.Pixel);
  139. TRY_BEGIN
  140. if (PlanarYUV(&p->Overlay.Pixel,&x2,&y2,&pitch2) && p->Overlay.Pixel.BitCount==8)
  141. {
  142. uint8_t* i = (uint8_t*)Desc.lpSurface;
  143. FillColor(i,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,8,v & 255);
  144. i += Desc.lPitch * p->Overlay.Height;
  145. FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>8)&255);
  146. i += (Desc.lPitch >> x2) * (p->Overlay.Height >> y2);
  147. FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>16)&255);
  148. }
  149. else
  150. if (PackedYUV(&p->Overlay.Pixel) && p->Overlay.Pixel.BitCount==16)
  151. FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width >> 1,p->Overlay.Height,32,v);
  152. else
  153. FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,p->Overlay.Pixel.BitCount,v);
  154. Result = 1;
  155. TRY_END
  156. IDirectDrawSurface_Unlock(p->DDBuffer,NULL);
  157. }
  158. TRY_END
  159. return Result;
  160. }
  161. static HRESULT PASCAL EnumBackBuffer(LPDIRECTDRAWSURFACE p, LPDDSURFACEDESC Desc, LPVOID Context)
  162. {
  163.     if (*((LPDIRECTDRAWSURFACE *)Context)) 
  164. {
  165. IDirectDrawSurface_Release(p);
  166. return DDENUMRET_CANCEL;
  167. }
  168. *((LPDIRECTDRAWSURFACE *)Context) = p;
  169. return DDENUMRET_OK;
  170. }
  171. static void ReleaseBuffers(ddraw* p)
  172. {
  173. if (p->DDBackBuffer) 
  174. IDirectDrawSurface_Release(p->DDBackBuffer); 
  175. p->DDBackBuffer = NULL;
  176. }
  177. if (p->DDBuffer) 
  178. if (p->Mode == MODE_OVERLAY)
  179. IDirectDrawSurface_UpdateOverlay(p->DDBuffer,NULL,p->DDPrimary,NULL,DDOVER_HIDE,NULL);
  180. IDirectDrawSurface_Release(p->DDBuffer); 
  181. p->DDBuffer = NULL;
  182. }
  183. }
  184. static bool_t CreateBuffer(ddraw* p,bool_t PixelFormat)
  185. {
  186. DDSURFACEDESC Desc;
  187. p->BufferPixelFormat = PixelFormat;
  188. ReleaseBuffers(p);
  189. if (!Surface2Desc(&p->Overlay,&Desc,PixelFormat))
  190. return 0;
  191. Desc.dwFlags |= DDSD_CAPS;
  192. Desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
  193. if (p->Mode == MODE_OVERLAY)
  194. {
  195. Desc.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
  196. Desc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
  197. Desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
  198. Desc.dwBackBufferCount = 1;
  199. }
  200. 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);
  201. if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL) != DD_OK)
  202. {
  203. if (p->Mode == MODE_OVERLAY)
  204. {
  205. // try without backbuffer...
  206. Desc.ddsCaps.dwCaps &= ~(DDSCAPS_FLIP);
  207. Desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
  208. IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL);
  209. }
  210. if (!p->DDBuffer)
  211. {
  212. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Failed"));
  213. return 0;
  214. }
  215. }
  216. else
  217. if (p->Mode == MODE_OVERLAY)
  218. IDirectDrawSurface_EnumAttachedSurfaces(p->DDBuffer,&p->DDBackBuffer,EnumBackBuffer);
  219. if (IDirectDrawSurface_GetSurfaceDesc(p->DDBuffer,&Desc) == DD_OK)
  220. Desc2Surface(&Desc,&p->Overlay);
  221. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Ok"));
  222. if (!ClearBuffer(p,p->DDBuffer))
  223. {
  224. ReleaseBuffers(p);
  225. return 0;
  226. }
  227. if (p->DDBackBuffer)
  228. ClearBuffer(p,p->DDBackBuffer);
  229. return 1;
  230. }
  231. static int UpdateOverlay(ddraw* p)
  232. {
  233. rect OverlayRect;
  234. rect DstAlignedRect;
  235. DstAlignedRect = p->p.GUIAlignedRect;
  236. PhyToVirt(&p->OverlayRect,&OverlayRect,&p->Overlay);
  237. p->Src.left = OverlayRect.x;
  238. p->Src.top = OverlayRect.y;
  239. p->Src.right = OverlayRect.x + OverlayRect.Width;
  240. p->Src.bottom = OverlayRect.y + OverlayRect.Height;
  241.  
  242. p->Dst.left = DstAlignedRect.x;
  243. p->Dst.top = DstAlignedRect.y;
  244. p->Dst.right = DstAlignedRect.x + DstAlignedRect.Width;
  245. p->Dst.bottom = DstAlignedRect.y + DstAlignedRect.Height;
  246. if (p->Mode == MODE_OVERLAY && p->DDBuffer &&
  247. OverlayRect.Width>0 && OverlayRect.Height>0 &&
  248. DstAlignedRect.Width>0 && DstAlignedRect.Height>0)
  249. {
  250. DWORD hResult;
  251. int Flags = 0;
  252. if (p->p.Show)
  253. Flags |= DDOVER_SHOW;
  254. else
  255. Flags |= DDOVER_HIDE;
  256. if (p->p.ColorKey != RGB_NULL)
  257. Flags |= DDOVER_KEYDEST;
  258. hResult = IDirectDrawSurface_UpdateOverlay(p->DDBuffer,&p->Src,p->DDPrimary,&p->Dst,Flags,NULL);
  259. if (hResult != DD_OK)
  260. {
  261. DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW UpdateOverlay failed %08x"),hResult);
  262. }
  263. }
  264. return ERR_NONE;
  265. }
  266. static int GetAlign(int i)
  267. {
  268. int v=1;
  269. while (v<16 && v<i)
  270. v<<=1;
  271. return v;
  272. }
  273. static int Init(ddraw* p)
  274. {
  275. DDSURFACEDESC Desc;
  276. p->p.ColorKey = RGB_NULL;
  277. if (p->SetupColorKey && IsWindow(Context()->Wnd))
  278. p->p.ColorKey = COLORKEY;
  279. if (p->DDCaps.dwMinOverlayStretch && p->DDCaps.dwMaxOverlayStretch)
  280. {
  281. p->MinScale = (p->DDCaps.dwMinOverlayStretch * SCALE_ONE) / 1000;
  282. p->MaxScale = (p->DDCaps.dwMaxOverlayStretch * SCALE_ONE) / 1000;
  283. }
  284. else
  285. {
  286. p->MinScale = SCALE_ONE;
  287. p->MaxScale = SCALE_ONE;
  288. }
  289. p->DstAlignPos = GetAlign(p->DDCaps.dwAlignBoundaryDest);
  290. p->DstAlignSize = GetAlign(p->DDCaps.dwAlignSizeDest);
  291. // get primary surface
  292. memset(&Desc,0,sizeof(DDSURFACEDESC));
  293. Desc.dwSize = sizeof(DDSURFACEDESC);
  294. Desc.dwFlags = DDSD_CAPS;
  295. Desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  296. if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDPrimary,NULL) != DD_OK)
  297. return ERR_DEVICE_ERROR;
  298. if (IDirectDrawSurface_GetSurfaceDesc(p->DDPrimary,&Desc) != DD_OK)
  299. return ERR_DEVICE_ERROR;
  300. //{ int i; for (i=0;i<sizeof(Desc)/4;++i)
  301. // DEBUG_MSG(DEBUG_VIDEO,T("DDRAW PrimaryDesc %02x:%08x"),i*4,((int*)&Desc)[i]); }
  302. Desc2Surface(&Desc,&p->p.Output.Format.Video);
  303. FillInfo(&p->p.Output.Format.Video.Pixel);
  304. //{ int i; for (i=0;i<sizeof(p->p.Output.Format.Video)/4;++i)
  305. // DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Output %02x:%08x"),i*4,((int*)&p->p.Output.Format.Video)[i]); }
  306. p->p.Overlay = 1;
  307. p->p.UpdateShow = UpdateOverlay;
  308. p->Overlay = p->p.Input.Format.Video;
  309. p->Mode = MODE_OVERLAY;
  310. // first try the optimal overlay format
  311. if (!p->SetupBlit && (p->Format != DDRAWFORMAT_AUTO || !CreateBuffer(p,1)))
  312. {
  313. if (PlanarYUV(&p->Overlay.Pixel,NULL,NULL,NULL))
  314. {
  315. // try other formats
  316. static const uint32_t FourCC[] = 
  317. // prefer planar420 formats
  318. FOURCC_YV12, DDRAWFORMAT_YV12, 
  319. FOURCC_IYUV, DDRAWFORMAT_YV12,
  320. FOURCC_I420, DDRAWFORMAT_YV12,
  321. FOURCC_IMC2, DDRAWFORMAT_YV12, 
  322. FOURCC_IMC4, DDRAWFORMAT_YV12, 
  323. // next planar422 formats
  324. FOURCC_YV16, DDRAWFORMAT_YV12,
  325. // next packed formats
  326. FOURCC_YUY2, DDRAWFORMAT_YUY2, 
  327. FOURCC_YUNV, DDRAWFORMAT_YUY2,  
  328. FOURCC_V422, DDRAWFORMAT_YUY2,  
  329. FOURCC_YUYV, DDRAWFORMAT_YUY2,  
  330. FOURCC_YVYU, DDRAWFORMAT_YUY2,  
  331. FOURCC_UYVY, DDRAWFORMAT_YUY2,  
  332. FOURCC_Y422, DDRAWFORMAT_YUY2,  
  333. FOURCC_UYNV, DDRAWFORMAT_YUY2,
  334. };
  335. const uint32_t* i;
  336. for (i=FourCC;i[0];i+=2)
  337. {
  338. p->Overlay.Pixel.Flags = PF_FOURCC;
  339. p->Overlay.Pixel.FourCC = i[0];
  340. if ((p->Format == DDRAWFORMAT_AUTO || p->Format == (int)i[1]) && CreateBuffer(p,1))
  341. break;
  342. }
  343. }
  344. // last hope is the device's current RGB mode (still better as blit mode)
  345. if (!p->DDBuffer && (p->Format == DDRAWFORMAT_AUTO || p->Format == DDRAWFORMAT_RGB))
  346. CreateBuffer(p,0);
  347. }
  348. if (!p->DDBuffer)
  349. {
  350. // try blit mode
  351. p->p.Overlay = 0;
  352. p->p.UpdateShow = NULL;
  353. p->p.ColorKey = RGB_NULL;
  354. p->DstAlignPos = 1;
  355. p->DstAlignSize = 1;
  356. p->MinScale = SCALE_ONE/256;
  357. p->MaxScale = SCALE_ONE*256;
  358. if (p->SetupBlitStretch)
  359. {
  360. p->Mode = MODE_BLIT; 
  361. CreateBuffer(p,0);
  362. }
  363. if (!p->DDBuffer)
  364. {
  365. p->Mode = MODE_PRIMARY; // use primary mode
  366. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Primary Mode"));
  367. }
  368. else
  369. {
  370. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit Stretch Mode"));
  371. }
  372. }
  373. else
  374. {
  375. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Overlay Mode"));
  376. }
  377. if (p->Mode != MODE_BLIT)
  378. p->p.SetFX = BLITFX_AVOIDTEARING;
  379. return ERR_NONE;
  380. }
  381. static void Done(ddraw* p)
  382. {
  383. ReleaseBuffers(p);
  384. if (p->DDPrimary) 
  385. IDirectDrawSurface_Release(p->DDPrimary); 
  386. p->DDPrimary = NULL;
  387. }
  388. }
  389. static int Reset(ddraw* p)
  390. {
  391. Done(p);
  392. Init(p);
  393. return ERR_NONE;
  394. }
  395. static int Update(ddraw* p)
  396. {
  397. rect GUIOverlayRect;
  398. int OvlWidth = p->p.Input.Format.Video.Width;
  399. int OvlHeight = p->p.Input.Format.Video.Height;
  400. if (p->Mode == MODE_PRIMARY)
  401. return OverlayUpdateAlign(&p->p);
  402. p->OvlFX = p->p.FX;
  403. p->SoftFX = p->p.FX;
  404. p->OvlFX.Brightness = 0;
  405. p->OvlFX.Contrast = 0;
  406. p->OvlFX.Saturation = 0;
  407. p->OvlFX.RGBAdjust[0] = p->OvlFX.RGBAdjust[1] = p->OvlFX.RGBAdjust[2] = 0;
  408. p->OvlFX.Direction &= ~(DIR_SWAPXY|DIR_MIRRORLEFTRIGHT|DIR_MIRRORUPDOWN); //rotate handled by SoftFX
  409. p->SoftFX.ScaleX = SCALE_ONE; // scale handled by overlay or blit
  410. p->SoftFX.ScaleY = SCALE_ONE;
  411. if (p->SoftFX.Direction & DIR_SWAPXY)
  412. SwapInt(&p->OvlFX.ScaleX,&p->OvlFX.ScaleY);
  413. if (CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->Overlay.Direction) & DIR_SWAPXY)
  414. SwapInt(&OvlWidth,&OvlHeight);
  415. if (p->Overlay.Width != OvlWidth || p->Overlay.Height != OvlHeight)
  416. {
  417. p->Overlay.Direction = 0;
  418. p->Overlay.Width = p->p.Input.Format.Video.Width;
  419. p->Overlay.Height = p->p.Input.Format.Video.Height;
  420. if (CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,0) & DIR_SWAPXY)
  421. SwapInt(&p->Overlay.Width,&p->Overlay.Height);
  422. if (!CreateBuffer(p,p->BufferPixelFormat))
  423. {
  424. p->Overlay.Width = 0;
  425. p->Overlay.Height = 0;
  426. return ERR_OUT_OF_MEMORY;
  427. }
  428. }
  429. p->SoftFX.Direction = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->Overlay.Direction);
  430. p->p.GUIAlignedRect = p->p.Viewport;
  431. PhyToVirt(NULL,&GUIOverlayRect,&p->Overlay);
  432. AnyAlign(&p->p.GUIAlignedRect, &GUIOverlayRect, &p->OvlFX,
  433. p->DstAlignSize,p->DstAlignPos,p->MinScale,p->MaxScale);
  434. VirtToPhy(&p->p.GUIAlignedRect,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  435. VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
  436. VirtToPhy(&GUIOverlayRect,&p->OverlayRect,&p->Overlay);
  437. BlitRelease(p->p.Soft);
  438. p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
  439. BlitAlign(p->p.Soft,&p->OverlayRect,&p->p.SrcAlignedRect);
  440. if (p->p.ColorKey!=RGB_NULL && p->DDPrimary)
  441. DWORD hResult;
  442. DDCOLORKEY Key;
  443. Key.dwColorSpaceLowValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel);
  444. Key.dwColorSpaceHighValue = 0;
  445. WinInvalidate(&p->p.Viewport,1);
  446. if ((hResult = IDirectDrawSurface_SetColorKey(p->DDPrimary,DDCKEY_DESTOVERLAY,&Key))!=DD_OK)
  447. {
  448. DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW SetColorKey failed %08x"),hResult);
  449. return ERR_NOT_SUPPORTED;
  450. }
  451. }
  452. return UpdateOverlay(p);
  453. }
  454. static int Blit(ddraw* p, const constplanes Data, const constplanes DataLast )
  455. {
  456. DDSURFACEDESC Desc;
  457. HRESULT hResult;
  458. planes Planes;
  459. LPDIRECTDRAWSURFACE Output = p->Mode == MODE_PRIMARY ? p->DDPrimary:p->DDBuffer;
  460. if (p->Mode == MODE_OVERLAY && p->DDBackBuffer && p->p.CurrTime!=TIME_BENCH)
  461. Output = p->DDBackBuffer;
  462. if (!Output)
  463. {
  464. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blit no output"));
  465. return ERR_NOT_SUPPORTED;
  466. }
  467. Desc.dwSize = sizeof(Desc);
  468. while ((hResult = IDirectDrawSurface_Lock(Output,NULL,&Desc,DDLOCK_WAITNOTBUSY,NULL)) != DD_OK)
  469. {
  470. if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(Output) != DD_OK)
  471. {
  472. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW surface Lock() failed"));
  473. return ERR_NOT_SUPPORTED;
  474. }
  475. }
  476. //{ int i; for (i=0;i<sizeof(Desc)/4;++i)
  477. // DEBUG_MSG(DEBUG_VIDEO,T("DDRAW LockDesc %02x:%08x"),i*4,((int*)&Desc)[i]); }
  478. AdjustDesc(&Desc);
  479. Planes[0] = Desc.lpSurface;
  480. DEBUG_MSG4(DEBUG_VIDEO,T("DDRAW Blit %08x,%08x,%08x,%08x"),p->p.Soft,Planes[0],Desc.lPitch,Data);
  481. BlitImage(p->p.Soft,Planes,Data,DataLast,Desc.lPitch,-1);
  482. IDirectDrawSurface_Unlock(Output,NULL);
  483. if (p->Mode == MODE_BLIT)
  484. {
  485. while ((hResult = IDirectDrawSurface_Blt(p->DDPrimary,&p->Dst,Output,&p->Src,DDBLT_WAITNOTBUSY,NULL)) != DD_OK)
  486. if (hResult != DDERR_SURFACELOST || IDirectDrawSurface_Restore(p->DDPrimary) != DD_OK)
  487. {
  488. DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Blt() failed"));
  489. break;
  490. }
  491. }
  492. else 
  493. if (p->Mode == MODE_OVERLAY && Output == p->DDBackBuffer)
  494. IDirectDrawSurface_Flip(p->DDBuffer,NULL,DDFLIP_WAITNOTBUSY);
  495. return ERR_NONE;
  496. }
  497. int DDrawCECreate(ddraw* p,LPDIRECTDRAW DD)
  498. {
  499. int Model = QueryPlatform(PLATFORM_MODEL);
  500. if (Model==MODEL_AXIM_X50)
  501. return ERR_NOT_SUPPORTED; // buggy WM5 driver...
  502. if (IDirectDraw_QueryInterface(DD,&IID_IDirectDraw,&p->DD)!=DD_OK)
  503. return ERR_DEVICE_ERROR;
  504. IDirectDraw_Release(DD);
  505. IDirectDraw_SetCooperativeLevel(p->DD, NULL, DDSCL_NORMAL);
  506. p->DDCaps.dwSize = sizeof(p->DDCaps);
  507. IDirectDraw_GetCaps(p->DD,&p->DDCaps,NULL);
  508. //{ int i; for (i=0;i<sizeof(p->DDCaps)/4;++i)
  509. // DEBUG_MSG(DEBUG_VIDEO,T("DDRAW Caps %02x:%08x"),i*4,((int*)&p->DDCaps)[i]); }
  510. p->SetupColorKey = (p->DDCaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYDEST) != 0;
  511. p->SetupBlit = (p->DDCaps.dwOverlayCaps & DDOVERLAYCAPS_OVERLAYSUPPORT) == 0;
  512. p->SetupBlitStretch = 1;
  513. if (p->SetupBlit && !p->DDCaps.dwVidMemTotal && 
  514. (NodeEnumClass(NULL,RAW_ID) || NodeEnumClass(NULL,GAPI_ID)))
  515. return ERR_NOT_SUPPORTED; // fallback to RawFrameBuffer or GAPI until things get fixed
  516. p->p.DoPowerOff = 1;
  517. p->p.Init = Init;
  518. p->p.Done = Done;
  519. p->p.Reset = Reset;
  520. p->p.Blit = Blit;
  521. p->p.Update = Update;
  522. p->p.UpdateShow = UpdateOverlay;
  523. return ERR_NONE;
  524. }
  525. #endif