1 /* DirectDrawSurface base implementation
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
17 #include "debugtools.h"
18 #include "ddraw_private.h"
20 DEFAULT_DEBUG_CHANNEL(ddraw);
22 /******************************************************************************
23 * IDirectDrawSurface methods
25 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
26 * DDS and DDS2 use those functions. (Function calls did not change (except
27 * using different DirectDrawSurfaceX version), just added flags and functions)
30 HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
31 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
33 ICOM_THIS(IDirectDrawSurface4Impl,iface);
35 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
36 This,lprect,lpddsd,flags,(DWORD)hnd);
38 /* DO NOT AddRef the surface! Lock/Unlock must not come in matched pairs
39 * -Marcus Meissner 20000509
41 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
42 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
43 This,lprect,lpddsd,flags,(DWORD)hnd);
45 /* First, copy the Surface description */
46 *lpddsd = This->s.surface_desc;
47 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
48 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
50 /* If asked only for a part, change the surface pointer */
52 TRACE(" lprect: %dx%d-%dx%d\n",
53 lprect->top,lprect->left,lprect->bottom,lprect->right
55 if ((lprect->top < 0) ||
57 (lprect->bottom < 0) ||
58 (lprect->right < 0)) {
59 ERR(" Negative values in LPRECT !!!\n");
60 return DDERR_INVALIDPARAMS;
63 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
64 (lprect->top*This->s.surface_desc.lPitch) +
65 lprect->left*GET_BPP(This->s.surface_desc));
67 assert(This->s.surface_desc.u1.lpSurface);
72 HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(
73 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
75 ICOM_THIS(IDirectDrawSurface4Impl,iface);
77 /* DO NOT Release the surface! Lock/Unlock MUST NOT come in matched pairs
78 * Marcus Meissner 20000509
80 TRACE("(%p)->Unlock(%p)\n",This,surface);
84 IDirectDrawSurface4Impl* _common_find_flipto(
85 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
88 struct _surface_chain *chain = This->s.chain;
90 /* if there was no override flipto, look for current backbuffer */
92 /* walk the flip chain looking for backbuffer */
93 for (i=0;i<chain->nrofsurfaces;i++) {
94 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
96 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
97 flipto = chain->surfaces[i];
99 /* sanity checks ... */
102 for (i=0;i<chain->nrofsurfaces;i++)
103 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
105 if (i==chain->nrofsurfaces) {
106 /* we do not have a frontbuffer either */
107 for (i=0;i<chain->nrofsurfaces;i++)
108 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
109 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
112 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
113 int k = j % chain->nrofsurfaces;
114 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
115 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
116 flipto = chain->surfaces[k];
125 TRACE("flipping to %p\n",flipto);
130 static HRESULT _Blt_ColorFill(
131 LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color
138 #define COLORFILL_ROW(type) { \
139 type *d = (type *) buf; \
140 for (x = 0; x < width; x++) \
141 d[x] = (type) color; \
146 case 1: COLORFILL_ROW(BYTE)
147 case 2: COLORFILL_ROW(WORD)
148 case 4: COLORFILL_ROW(DWORD)
150 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
151 return DDERR_UNSUPPORTED;
156 /* Now copy first row */
158 for (y = 1; y < height; y++) {
160 memcpy(buf, first, width * bpp);
165 HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
166 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,
167 DWORD dwFlags,LPDDBLTFX lpbltfx
169 ICOM_THIS(IDirectDrawSurface4Impl,iface);
171 DDSURFACEDESC ddesc,sdesc;
173 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
177 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
179 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
180 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
182 if (TRACE_ON(ddraw)) {
183 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
184 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
186 _dump_DDBLT(dwFlags);
187 if (dwFlags & DDBLT_DDFX) {
189 _dump_DDBLTFX(lpbltfx->dwDDFX);
194 if ((rdst->top < 0) ||
196 (rdst->bottom < 0) ||
198 ERR(" Negative values in LPRECT !!!\n");
201 memcpy(&xdst,rdst,sizeof(xdst));
204 xdst.bottom = ddesc.dwHeight;
206 xdst.right = ddesc.dwWidth;
210 if ((rsrc->top < 0) ||
212 (rsrc->bottom < 0) ||
214 ERR(" Negative values in LPRECT !!!\n");
217 memcpy(&xsrc,rsrc,sizeof(xsrc));
221 xsrc.bottom = sdesc.dwHeight;
223 xsrc.right = sdesc.dwWidth;
225 memset(&xsrc,0,sizeof(xsrc));
228 if (src) assert(xsrc.bottom <= sdesc.dwHeight);
229 assert(xdst.bottom <= ddesc.dwHeight);
231 bpp = GET_BPP(ddesc);
232 srcheight = xsrc.bottom - xsrc.top;
233 srcwidth = xsrc.right - xsrc.left;
234 dstheight = xdst.bottom - xdst.top;
235 dstwidth = xdst.right - xdst.left;
236 width = (xdst.right - xdst.left) * bpp;
238 assert(width <= ddesc.lPitch);
240 dbuf = (BYTE*)ddesc.u1.lpSurface+(xdst.top*ddesc.lPitch)+(xdst.left*bpp);
242 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
244 /* First, all the 'source-less' blits */
245 if (dwFlags & DDBLT_COLORFILL) {
246 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
247 ddesc.lPitch, lpbltfx->u4.dwFillColor);
248 dwFlags &= ~DDBLT_COLORFILL;
251 if (dwFlags & DDBLT_DEPTHFILL)
252 FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
253 if (dwFlags & DDBLT_ROP) {
254 /* Catch some degenerate cases here */
255 switch(lpbltfx->dwROP) {
257 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,0);
259 case 0xAA0029: /* No-op */
262 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,~0);
265 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
268 dwFlags &= ~DDBLT_ROP;
270 if (dwFlags & DDBLT_DDROPS) {
271 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
273 /* Now the 'with source' blits */
276 int sx, xinc, sy, yinc;
278 sbase = (BYTE*)sdesc.u1.lpSurface+(xsrc.top*sdesc.lPitch)+xsrc.left*bpp;
279 xinc = (srcwidth << 16) / dstwidth;
280 yinc = (srcheight << 16) / dstheight;
283 assert(ddesc.lPitch >= width);
284 assert(sdesc.lPitch >= width);
286 /* No effects, we can cheat here */
287 if (dstwidth == srcwidth) {
288 if (dstheight == srcheight) {
289 /* No stretching in either direction. This needs to be as
290 * fast as possible */
292 for (y = 0; y < dstheight; y++) {
293 memcpy(dbuf, sbuf, width);
294 sbuf += sdesc.lPitch;
295 dbuf += ddesc.lPitch;
298 /* Stretching in Y direction only */
299 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
300 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
301 memcpy(dbuf, sbuf, width);
302 dbuf += ddesc.lPitch;
306 /* Stretching in X direction */
308 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
309 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
311 assert((sy>>16) < srcheight);
313 if ((sy >> 16) == (last_sy >> 16)) {
314 /* this sourcerow is the same as last sourcerow -
315 * copy already stretched row
317 memcpy(dbuf, dbuf - ddesc.lPitch, width);
319 #define STRETCH_ROW(type) { \
320 type *s = (type *) sbuf, *d = (type *) dbuf; \
321 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
322 d[x] = s[sx >> 16]; \
326 case 1: STRETCH_ROW(BYTE)
327 case 2: STRETCH_ROW(WORD)
328 case 4: STRETCH_ROW(DWORD)
331 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
335 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
336 d[0] = (pixel>>16)&0xff;
337 d[1] = (pixel>> 8)&0xff;
338 d[2] = (pixel )&0xff;
344 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
345 ret = DDERR_UNSUPPORTED;
350 dbuf += ddesc.lPitch;
354 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
355 DWORD keylow, keyhigh;
357 if (dwFlags & DDBLT_KEYSRC) {
358 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
359 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
361 /* I'm not sure if this is correct */
362 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
363 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
364 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
368 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
369 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
371 #define COPYROW_COLORKEY(type) { \
372 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
373 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
375 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
380 case 1: COPYROW_COLORKEY(BYTE)
381 case 2: COPYROW_COLORKEY(WORD)
382 case 4: COPYROW_COLORKEY(DWORD)
384 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
385 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
386 ret = DDERR_UNSUPPORTED;
389 dbuf += ddesc.lPitch;
391 #undef COPYROW_COLORKEY
392 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
397 if (dwFlags && FIXME_ON(ddraw)) {
398 FIXME("\tUnsupported flags: ");
399 _dump_DDBLT(dwFlags);
403 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
404 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
408 HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
409 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,
410 LPRECT rsrc,DWORD trans
412 ICOM_THIS(IDirectDrawSurface4Impl,iface);
414 DDSURFACEDESC ddesc,sdesc;
420 if (TRACE_ON(ddraw)) {
421 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
422 This,dstx,dsty,src,rsrc,trans
426 _dump_DDBLTFAST(trans);
428 FIXME("\tsrcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
430 FIXME(" srcrect: NULL\n");
433 /* We need to lock the surfaces, or we won't get refreshes when done. */
434 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
435 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
438 WARN("rsrc is NULL!\n");
440 rsrc->left = rsrc->top = 0;
441 rsrc->right = sdesc.dwWidth;
442 rsrc->bottom = sdesc.dwHeight;
445 bpp = GET_BPP(This->s.surface_desc);
446 sbuf = (BYTE *)sdesc.u1.lpSurface+(rsrc->top*sdesc.lPitch)+rsrc->left*bpp;
447 dbuf = (BYTE *)ddesc.u1.lpSurface+(dsty*ddesc.lPitch)+dstx* bpp;
450 h=rsrc->bottom-rsrc->top;
451 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
452 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
455 w=rsrc->right-rsrc->left;
456 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
457 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
460 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
461 DWORD keylow, keyhigh;
462 if (trans & DDBLTFAST_SRCCOLORKEY) {
463 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
464 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
466 /* I'm not sure if this is correct */
467 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
468 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
469 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
472 #define COPYBOX_COLORKEY(type) { \
473 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
474 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
475 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
476 for (y = 0; y < h; y++) { \
477 for (x = 0; x < w; x++) { \
479 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
481 (LPBYTE)s += sdesc.lPitch; \
482 (LPBYTE)d += ddesc.lPitch; \
488 case 1: COPYBOX_COLORKEY(BYTE)
489 case 2: COPYBOX_COLORKEY(WORD)
490 case 4: COPYBOX_COLORKEY(DWORD)
492 FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
493 ret = DDERR_UNSUPPORTED;
496 #undef COPYBOX_COLORKEY
500 for (y = 0; y < h; y++) {
501 memcpy(dbuf, sbuf, width);
502 sbuf += sdesc.lPitch;
503 dbuf += ddesc.lPitch;
507 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
508 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
512 HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
513 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
515 ICOM_THIS(IDirectDrawSurface4Impl,iface);
516 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",This,ddbltbatch,x,y);
520 HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
521 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
523 ICOM_THIS(IDirectDrawSurface4Impl,iface);
524 TRACE("(%p)->GetCaps(%p)\n",This,caps);
525 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
529 HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
530 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
532 ICOM_THIS(IDirectDrawSurface4Impl,iface);
533 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
535 /* Simply copy the surface description stored in the object */
536 *ddsd = This->s.surface_desc;
538 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
543 ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
544 ICOM_THIS(IDirectDrawSurface4Impl,iface);
545 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
546 return ++(This->ref);
550 HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
551 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
553 ICOM_THIS(IDirectDrawSurface4Impl,iface);
554 int i,found = 0,xstart;
555 struct _surface_chain *chain;
557 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
558 if (TRACE_ON(ddraw)) {
559 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
562 chain = This->s.chain;
564 return DDERR_NOTFOUND;
566 for (i=0;i<chain->nrofsurfaces;i++)
567 if (chain->surfaces[i] == This)
571 for (i=0;i<chain->nrofsurfaces;i++) {
572 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
574 if (found) /* may not find the same caps twice, (doc) */
575 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
577 found = (i+1)+xstart;
581 return DDERR_NOTFOUND;
582 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
584 TRACE("found %p\n",*lpdsf);
588 HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
589 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
591 ICOM_THIS(IDirectDrawSurface4Impl,iface);
592 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
594 return DDERR_ALREADYINITIALIZED;
597 HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
598 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
600 ICOM_THIS(IDirectDrawSurface4Impl,iface);
601 TRACE("(%p)->(%p)\n",This,pf);
603 *pf = This->s.surface_desc.ddpfPixelFormat;
604 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
608 HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
609 ICOM_THIS(IDirectDrawSurface4Impl,iface);
610 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
614 HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
615 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
617 ICOM_THIS(IDirectDrawSurface4Impl,iface);
618 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
622 HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
623 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
625 ICOM_THIS(IDirectDrawSurface4Impl,iface);
626 TRACE("(%p)->(%p)!\n",This,lpClipper);
628 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
629 This->s.lpClipper = lpClipper;
630 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
634 HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
635 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
638 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
640 struct _surface_chain *chain;
642 FIXME("(%p)->(%p)\n",This,surf);
643 chain = This->s.chain;
645 /* IDirectDrawSurface4_AddRef(surf); */
648 for (i=0;i<chain->nrofsurfaces;i++)
649 if (chain->surfaces[i] == isurf)
650 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
652 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
653 chain->nrofsurfaces = 1;
654 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
655 chain->surfaces[0] = This;
656 This->s.chain = chain;
660 chain->surfaces = HeapReAlloc(
664 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
667 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
668 isurf->s.chain = chain;
669 chain->surfaces[chain->nrofsurfaces++] = isurf;
673 HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
674 ICOM_THIS(IDirectDrawSurface4Impl,iface);
679 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
681 /* Creates a DIB Section of the same size / format as the surface */
682 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
684 if (This->s.hdc == 0) {
685 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
688 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
689 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
694 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
698 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
699 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
703 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
704 b_info->bmiHeader.biWidth = desc.dwWidth;
705 b_info->bmiHeader.biHeight = desc.dwHeight;
706 b_info->bmiHeader.biPlanes = 1;
707 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
709 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
710 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
712 b_info->bmiHeader.biCompression = BI_RGB;
715 b_info->bmiHeader.biCompression = BI_BITFIELDS;
717 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
718 b_info->bmiHeader.biXPelsPerMeter = 0;
719 b_info->bmiHeader.biYPelsPerMeter = 0;
720 b_info->bmiHeader.biClrUsed = 0;
721 b_info->bmiHeader.biClrImportant = 0;
723 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
728 DWORD *masks = (DWORD *) &(b_info->bmiColors);
731 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
732 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
733 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
739 usage = DIB_RGB_COLORS;
745 /* Fill the palette */
746 usage = DIB_RGB_COLORS;
748 if (This->s.palette == NULL) {
749 ERR("Bad palette !!!\n");
751 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
752 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
754 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
755 rgb[i].rgbBlue = pent[i].peBlue;
756 rgb[i].rgbRed = pent[i].peRed;
757 rgb[i].rgbGreen = pent[i].peGreen;
763 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
766 &(This->s.bitmap_data),
770 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
771 if (!This->s.DIBsection) {
772 ERR("CreateDIBSection failed!\n");
775 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
777 /* b_info is not useful anymore */
778 HeapFree(GetProcessHeap(), 0, b_info);
781 This->s.hdc = CreateCompatibleDC(0);
782 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
785 /* Copy our surface in the DIB section */
786 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
787 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
790 FIXME("This case has to be done :/\n");
792 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
793 *lphdc = This->s.hdc;
798 HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
799 ICOM_THIS(IDirectDrawSurface4Impl,iface);
801 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
802 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
803 /* Copy the DIB section to our surface */
804 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
805 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
808 FIXME("This case has to be done :/\n");
810 /* Unlock the surface */
811 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
815 HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(
816 LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
818 ICOM_THIS(IDirectDrawSurface4Impl,iface);
820 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
822 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
823 * the same interface. And IUnknown does that too of course.
825 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
826 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
827 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
828 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
829 IsEqualGUID( &IID_IUnknown, refiid )
832 IDirectDrawSurface4_AddRef(iface);
834 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
837 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
838 return OLE_E_ENUM_NOMORE;
841 HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
842 ICOM_THIS(IDirectDrawSurface4Impl,iface);
843 TRACE("(%p)->(), stub!\n",This);
844 return DD_OK; /* hmm */
847 HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(
848 LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb
850 ICOM_THIS(IDirectDrawSurface4Impl,iface);
852 struct _surface_chain *chain = This->s.chain;
854 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
855 for (i=0;i<chain->nrofsurfaces;i++) {
856 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
857 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
858 return DD_OK; /* FIXME: return value correct? */
863 HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
864 ICOM_THIS(IDirectDrawSurface4Impl,iface);
865 FIXME("(%p)->(),stub!\n",This);
869 HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
870 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
872 ICOM_THIS(IDirectDrawSurface4Impl,iface);
873 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
874 if (TRACE_ON(ddraw)) {
875 _dump_colorkeyflag(dwFlags);
877 _dump_DDCOLORKEY((void *) ckey);
881 /* If this surface was loaded as a texture, call also the texture
882 * SetColorKey callback. FIXME: hack approach :(
885 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
887 if( dwFlags & DDCKEY_SRCBLT ) {
888 dwFlags &= ~DDCKEY_SRCBLT;
889 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
890 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
893 if( dwFlags & DDCKEY_DESTBLT ) {
894 dwFlags &= ~DDCKEY_DESTBLT;
895 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
896 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
899 if( dwFlags & DDCKEY_SRCOVERLAY ) {
900 dwFlags &= ~DDCKEY_SRCOVERLAY;
901 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
902 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
905 if( dwFlags & DDCKEY_DESTOVERLAY ) {
906 dwFlags &= ~DDCKEY_DESTOVERLAY;
907 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
908 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
911 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
915 HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
916 LPDIRECTDRAWSURFACE4 iface, LPRECT lpRect
918 ICOM_THIS(IDirectDrawSurface4Impl,iface);
919 FIXME("(%p)->(%p),stub!\n",This,lpRect);
924 HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
925 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags,
926 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
928 ICOM_THIS(IDirectDrawSurface4Impl,iface);
930 struct _surface_chain *chain;
932 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
933 chain = This->s.chain;
934 for (i=0;i<chain->nrofsurfaces;i++) {
935 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
936 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
938 chain->surfaces[i]->s.chain = NULL;
939 memcpy( chain->surfaces+i,
940 chain->surfaces+(i+1),
941 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
943 chain->surfaces = HeapReAlloc(
947 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
949 chain->nrofsurfaces--;
956 HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
957 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPVOID lpContext,
958 LPDDENUMSURFACESCALLBACK lpfnCallback
960 ICOM_THIS(IDirectDrawSurface4Impl,iface);
961 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
962 lpContext, lpfnCallback );
967 HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
968 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWCLIPPER* lplpDDClipper
970 ICOM_THIS(IDirectDrawSurface4Impl,iface);
971 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
976 HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
977 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey
979 ICOM_THIS(IDirectDrawSurface4Impl,iface);
980 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
982 if( dwFlags & DDCKEY_SRCBLT ) {
983 dwFlags &= ~DDCKEY_SRCBLT;
984 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
986 if( dwFlags & DDCKEY_DESTBLT ) {
987 dwFlags &= ~DDCKEY_DESTBLT;
988 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
990 if( dwFlags & DDCKEY_SRCOVERLAY ) {
991 dwFlags &= ~DDCKEY_SRCOVERLAY;
992 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
994 if( dwFlags & DDCKEY_DESTOVERLAY ) {
995 dwFlags &= ~DDCKEY_DESTOVERLAY;
996 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
999 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1003 HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1004 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1006 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1007 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1012 HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1013 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWPALETTE* lplpDDPalette
1015 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1016 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
1018 if (!This->s.palette)
1019 return DDERR_NOPALETTEATTACHED;
1021 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
1022 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
1026 HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1027 LPDIRECTDRAWSURFACE4 iface, LONG lX, LONG lY
1029 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1030 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1035 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1036 LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
1037 LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
1038 LPDDOVERLAYFX lpDDOverlayFx
1040 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1041 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1042 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1047 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1048 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1050 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1051 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1056 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1057 LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference
1059 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1060 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1065 HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1066 LPDIRECTDRAWSURFACE4 iface, LPVOID* lplpDD
1068 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1069 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
1071 /* Not sure about that... */
1072 *lplpDD = (void *) This->s.ddraw;
1077 HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1078 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1080 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1081 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1086 HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1087 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1089 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1090 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1095 HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1096 LPDIRECTDRAWSURFACE4 iface, LPDDSURFACEDESC lpDDSD, DWORD dwFlags
1098 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1099 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1104 HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(
1105 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpData, DWORD cbSize,
1108 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1109 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1114 HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(
1115 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpBuffer,
1116 LPDWORD lpcbBufferSize
1118 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1119 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1124 HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(
1125 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag
1127 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1128 FIXME("(%p)->(%p)\n", This, guidTag);
1133 HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(
1134 LPDIRECTDRAWSURFACE4 iface, LPDWORD lpValue
1136 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1137 FIXME("(%p)->(%p)\n", This, lpValue);
1142 HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(
1143 LPDIRECTDRAWSURFACE4 iface
1145 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1146 FIXME("(%p)\n", This);