1 /* DirectDrawSurface base implementation
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
17 #include "debugtools.h"
19 #include "ddraw_private.h"
21 DEFAULT_DEBUG_CHANNEL(ddraw);
23 /******************************************************************************
24 * IDirectDrawSurface methods
26 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
27 * DDS and DDS2 use those functions. (Function calls did not change (except
28 * using different DirectDrawSurfaceX version), just added flags and functions)
31 HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
32 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
34 ICOM_THIS(IDirectDrawSurface4Impl,iface);
36 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
37 This,lprect,lpddsd,flags,(DWORD)hnd);
39 /* DO NOT AddRef the surface! Lock/Unlock must not come in matched pairs
40 * -Marcus Meissner 20000509
42 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
43 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
44 This,lprect,lpddsd,flags,(DWORD)hnd);
46 /* First, copy the Surface description */
47 *lpddsd = This->s.surface_desc;
48 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
49 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
51 /* If asked only for a part, change the surface pointer */
53 TRACE(" lprect: %dx%d-%dx%d\n",
54 lprect->top,lprect->left,lprect->bottom,lprect->right
56 if ((lprect->top < 0) ||
58 (lprect->bottom < 0) ||
59 (lprect->right < 0)) {
60 ERR(" Negative values in LPRECT !!!\n");
61 return DDERR_INVALIDPARAMS;
64 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
65 (lprect->top*This->s.surface_desc.lPitch) +
66 lprect->left*GET_BPP(This->s.surface_desc));
68 assert(This->s.surface_desc.u1.lpSurface);
73 HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(
74 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
76 ICOM_THIS(IDirectDrawSurface4Impl,iface);
78 /* DO NOT Release the surface! Lock/Unlock MUST NOT come in matched pairs
79 * Marcus Meissner 20000509
81 TRACE("(%p)->Unlock(%p)\n",This,surface);
85 IDirectDrawSurface4Impl* _common_find_flipto(
86 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
89 struct _surface_chain *chain = This->s.chain;
92 ERR("No flip chain? -> returning This.\n");
96 /* if there was no override flipto, look for current backbuffer */
98 /* walk the flip chain looking for backbuffer */
99 for (i=0;i<chain->nrofsurfaces;i++) {
100 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
102 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
103 flipto = chain->surfaces[i];
105 /* sanity checks ... */
108 for (i=0;i<chain->nrofsurfaces;i++)
109 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
111 if (i==chain->nrofsurfaces) {
112 /* we do not have a frontbuffer either */
113 for (i=0;i<chain->nrofsurfaces;i++)
114 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
115 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
118 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
119 int k = j % chain->nrofsurfaces;
120 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
121 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
122 flipto = chain->surfaces[k];
131 TRACE("flipping to %p\n",flipto);
136 static HRESULT _Blt_ColorFill(
137 LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color
144 #define COLORFILL_ROW(type) { \
145 type *d = (type *) buf; \
146 for (x = 0; x < width; x++) \
147 d[x] = (type) color; \
152 case 1: COLORFILL_ROW(BYTE)
153 case 2: COLORFILL_ROW(WORD)
154 case 4: COLORFILL_ROW(DWORD)
156 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
157 return DDERR_UNSUPPORTED;
162 /* Now copy first row */
164 for (y = 1; y < height; y++) {
166 memcpy(buf, first, width * bpp);
171 HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
172 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,
173 DWORD dwFlags,LPDDBLTFX lpbltfx
175 ICOM_THIS(IDirectDrawSurface4Impl,iface);
177 DDSURFACEDESC ddesc,sdesc;
179 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
183 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
185 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
186 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
188 if (TRACE_ON(ddraw)) {
189 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
190 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
192 _dump_DDBLT(dwFlags);
193 if (dwFlags & DDBLT_DDFX) {
195 _dump_DDBLTFX(lpbltfx->dwDDFX);
200 if ((rdst->top < 0) ||
202 (rdst->bottom < 0) ||
204 ERR(" Negative values in LPRECT !!!\n");
207 memcpy(&xdst,rdst,sizeof(xdst));
210 xdst.bottom = ddesc.dwHeight;
212 xdst.right = ddesc.dwWidth;
216 if ((rsrc->top < 0) ||
218 (rsrc->bottom < 0) ||
220 ERR(" Negative values in LPRECT !!!\n");
223 memcpy(&xsrc,rsrc,sizeof(xsrc));
227 xsrc.bottom = sdesc.dwHeight;
229 xsrc.right = sdesc.dwWidth;
231 memset(&xsrc,0,sizeof(xsrc));
234 if (src) assert((xsrc.bottom-xsrc.top) <= sdesc.dwHeight);
235 assert((xdst.bottom-xdst.top) <= ddesc.dwHeight);
237 bpp = GET_BPP(ddesc);
238 srcheight = xsrc.bottom - xsrc.top;
239 srcwidth = xsrc.right - xsrc.left;
240 dstheight = xdst.bottom - xdst.top;
241 dstwidth = xdst.right - xdst.left;
242 width = (xdst.right - xdst.left) * bpp;
244 assert(width <= ddesc.lPitch);
246 dbuf = (BYTE*)ddesc.u1.lpSurface+(xdst.top*ddesc.lPitch)+(xdst.left*bpp);
248 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
250 /* First, all the 'source-less' blits */
251 if (dwFlags & DDBLT_COLORFILL) {
252 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
253 ddesc.lPitch, lpbltfx->u4.dwFillColor);
254 dwFlags &= ~DDBLT_COLORFILL;
257 if (dwFlags & DDBLT_DEPTHFILL)
258 FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
259 if (dwFlags & DDBLT_ROP) {
260 /* Catch some degenerate cases here */
261 switch(lpbltfx->dwROP) {
263 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,0);
265 case 0xAA0029: /* No-op */
268 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,~0);
271 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
274 dwFlags &= ~DDBLT_ROP;
276 if (dwFlags & DDBLT_DDROPS) {
277 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
279 /* Now the 'with source' blits */
282 int sx, xinc, sy, yinc;
284 sbase = (BYTE*)sdesc.u1.lpSurface+(xsrc.top*sdesc.lPitch)+xsrc.left*bpp;
285 xinc = (srcwidth << 16) / dstwidth;
286 yinc = (srcheight << 16) / dstheight;
289 /* No effects, we can cheat here */
290 if (dstwidth == srcwidth) {
291 if (dstheight == srcheight) {
292 /* No stretching in either direction. This needs to be as
293 * fast as possible */
295 for (y = 0; y < dstheight; y++) {
296 memcpy(dbuf, sbuf, width);
297 sbuf += sdesc.lPitch;
298 dbuf += ddesc.lPitch;
301 /* Stretching in Y direction only */
302 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
303 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
304 memcpy(dbuf, sbuf, width);
305 dbuf += ddesc.lPitch;
309 /* Stretching in X direction */
311 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
312 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
314 if ((sy >> 16) == (last_sy >> 16)) {
315 /* this sourcerow is the same as last sourcerow -
316 * copy already stretched row
318 memcpy(dbuf, dbuf - ddesc.lPitch, width);
320 #define STRETCH_ROW(type) { \
321 type *s = (type *) sbuf, *d = (type *) dbuf; \
322 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
323 d[x] = s[sx >> 16]; \
327 case 1: STRETCH_ROW(BYTE)
328 case 2: STRETCH_ROW(WORD)
329 case 4: STRETCH_ROW(DWORD)
332 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
336 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
337 d[0] = (pixel>>16)&0xff;
338 d[1] = (pixel>> 8)&0xff;
339 d[2] = (pixel )&0xff;
345 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
346 ret = DDERR_UNSUPPORTED;
351 dbuf += ddesc.lPitch;
355 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
356 DWORD keylow, keyhigh;
358 if (dwFlags & DDBLT_KEYSRC) {
359 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
360 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
362 /* I'm not sure if this is correct */
363 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
364 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
365 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
369 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
370 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
372 #define COPYROW_COLORKEY(type) { \
373 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
374 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
376 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
381 case 1: COPYROW_COLORKEY(BYTE)
382 case 2: COPYROW_COLORKEY(WORD)
383 case 4: COPYROW_COLORKEY(DWORD)
385 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
386 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
387 ret = DDERR_UNSUPPORTED;
390 dbuf += ddesc.lPitch;
392 #undef COPYROW_COLORKEY
393 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
398 if (dwFlags && FIXME_ON(ddraw)) {
399 FIXME("\tUnsupported flags: ");
400 _dump_DDBLT(dwFlags);
404 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
405 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
409 HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
410 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,
411 LPRECT rsrc,DWORD trans
413 ICOM_THIS(IDirectDrawSurface4Impl,iface);
415 DDSURFACEDESC ddesc,sdesc;
421 if (TRACE_ON(ddraw)) {
422 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
423 This,dstx,dsty,src,rsrc,trans
427 _dump_DDBLTFAST(trans);
429 FIXME("\tsrcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
431 FIXME(" srcrect: NULL\n");
434 /* We need to lock the surfaces, or we won't get refreshes when done. */
435 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
436 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
439 WARN("rsrc is NULL!\n");
441 rsrc->left = rsrc->top = 0;
442 rsrc->right = sdesc.dwWidth;
443 rsrc->bottom = sdesc.dwHeight;
446 bpp = GET_BPP(This->s.surface_desc);
447 sbuf = (BYTE *)sdesc.u1.lpSurface+(rsrc->top*sdesc.lPitch)+rsrc->left*bpp;
448 dbuf = (BYTE *)ddesc.u1.lpSurface+(dsty*ddesc.lPitch)+dstx* bpp;
451 h=rsrc->bottom-rsrc->top;
452 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
453 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
456 w=rsrc->right-rsrc->left;
457 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
458 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
461 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
462 DWORD keylow, keyhigh;
463 if (trans & DDBLTFAST_SRCCOLORKEY) {
464 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
465 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
467 /* I'm not sure if this is correct */
468 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
469 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
470 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
473 #define COPYBOX_COLORKEY(type) { \
474 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
475 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
476 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
477 for (y = 0; y < h; y++) { \
478 for (x = 0; x < w; x++) { \
480 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
482 (LPBYTE)s += sdesc.lPitch; \
483 (LPBYTE)d += ddesc.lPitch; \
489 case 1: COPYBOX_COLORKEY(BYTE)
490 case 2: COPYBOX_COLORKEY(WORD)
491 case 4: COPYBOX_COLORKEY(DWORD)
493 FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
494 ret = DDERR_UNSUPPORTED;
497 #undef COPYBOX_COLORKEY
501 for (y = 0; y < h; y++) {
502 memcpy(dbuf, sbuf, width);
503 sbuf += sdesc.lPitch;
504 dbuf += ddesc.lPitch;
508 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
509 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
513 HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
514 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
516 ICOM_THIS(IDirectDrawSurface4Impl,iface);
517 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",This,ddbltbatch,x,y);
521 HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
522 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
524 ICOM_THIS(IDirectDrawSurface4Impl,iface);
525 TRACE("(%p)->GetCaps(%p)\n",This,caps);
526 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
530 HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
531 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
533 ICOM_THIS(IDirectDrawSurface4Impl,iface);
534 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
536 /* Simply copy the surface description stored in the object */
537 *ddsd = This->s.surface_desc;
539 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
544 ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
545 ICOM_THIS(IDirectDrawSurface4Impl,iface);
546 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
547 return ++(This->ref);
551 HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
552 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
554 ICOM_THIS(IDirectDrawSurface4Impl,iface);
555 int i,found = 0,xstart;
556 struct _surface_chain *chain;
558 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
559 if (TRACE_ON(ddraw)) {
560 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
563 chain = This->s.chain;
565 return DDERR_NOTFOUND;
567 for (i=0;i<chain->nrofsurfaces;i++)
568 if (chain->surfaces[i] == This)
572 for (i=0;i<chain->nrofsurfaces;i++) {
573 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
575 if (found) /* may not find the same caps twice, (doc) */
576 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
578 found = (i+1)+xstart;
582 return DDERR_NOTFOUND;
583 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
585 /* For EverQuest testing */
586 IDirectDrawSurface4_AddRef(*lpdsf);
588 TRACE("found %p\n",*lpdsf);
592 HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
593 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
595 ICOM_THIS(IDirectDrawSurface4Impl,iface);
596 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
598 return DDERR_ALREADYINITIALIZED;
601 HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
602 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
604 ICOM_THIS(IDirectDrawSurface4Impl,iface);
605 TRACE("(%p)->(%p)\n",This,pf);
607 *pf = This->s.surface_desc.ddpfPixelFormat;
608 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
612 HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
613 ICOM_THIS(IDirectDrawSurface4Impl,iface);
614 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
618 HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
619 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
621 ICOM_THIS(IDirectDrawSurface4Impl,iface);
622 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
626 HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
627 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
629 ICOM_THIS(IDirectDrawSurface4Impl,iface);
630 TRACE("(%p)->(%p)!\n",This,lpClipper);
632 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
633 This->s.lpClipper = lpClipper;
634 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
638 HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
639 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
641 ICOM_THIS(IDirectDrawSurface4Impl,iface);
642 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
644 struct _surface_chain *chain;
646 FIXME("(%p)->(%p)\n",This,surf);
647 chain = This->s.chain;
649 /* IDirectDrawSurface4_AddRef(surf); */
652 for (i=0;i<chain->nrofsurfaces;i++)
653 if (chain->surfaces[i] == isurf)
654 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
656 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
657 chain->nrofsurfaces = 1;
658 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
659 chain->surfaces[0] = This;
660 This->s.chain = chain;
664 chain->surfaces = HeapReAlloc(
668 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
671 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
672 isurf->s.chain = chain;
673 chain->surfaces[chain->nrofsurfaces++] = isurf;
677 HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
678 ICOM_THIS(IDirectDrawSurface4Impl,iface);
684 TRACE("(%p)->GetDC(%p)\n",This,lphdc);
686 /* Creates a DIB Section of the same size / format as the surface */
687 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
689 if (This->s.hdc == 0) {
690 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
693 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
694 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
699 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
703 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
704 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
708 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
709 b_info->bmiHeader.biWidth = desc.dwWidth;
710 b_info->bmiHeader.biHeight = -desc.dwHeight;
711 b_info->bmiHeader.biPlanes = 1;
712 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
714 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
715 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
717 b_info->bmiHeader.biCompression = BI_RGB;
720 b_info->bmiHeader.biCompression = BI_BITFIELDS;
722 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
723 b_info->bmiHeader.biXPelsPerMeter = 0;
724 b_info->bmiHeader.biYPelsPerMeter = 0;
725 b_info->bmiHeader.biClrUsed = 0;
726 b_info->bmiHeader.biClrImportant = 0;
728 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
733 DWORD *masks = (DWORD *) &(b_info->bmiColors);
736 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
737 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
738 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
744 usage = DIB_RGB_COLORS;
750 /* Fill the palette */
751 usage = DIB_RGB_COLORS;
753 if (This->s.palette == NULL) {
754 ERR("Bad palette !!!\n");
756 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
757 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
759 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
760 rgb[i].rgbBlue = pent[i].peBlue;
761 rgb[i].rgbRed = pent[i].peRed;
762 rgb[i].rgbGreen = pent[i].peGreen;
768 ddc = CreateDCA("DISPLAY",NULL,NULL,NULL);
769 This->s.DIBsection = ddc ? DIB_CreateDIBSection(ddc,
772 &(This->s.bitmap_data),
774 (DWORD)desc.u1.lpSurface,
777 if (!This->s.DIBsection) {
778 ERR("CreateDIBSection failed!\n");
779 if (ddc) DeleteDC(ddc);
780 HeapFree(GetProcessHeap(), 0, b_info);
783 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
785 /* b_info is not useful anymore */
786 HeapFree(GetProcessHeap(), 0, b_info);
789 This->s.hdc = CreateCompatibleDC(ddc);
790 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
792 if (ddc) DeleteDC(ddc);
795 if (This->s.bitmap_data != desc.u1.lpSurface) {
796 FIXME("DIBSection not created for frame buffer, reverting to old code\n");
797 /* Copy our surface in the DIB section */
798 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
799 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
802 FIXME("This case has to be done :/\n");
806 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
807 *lphdc = This->s.hdc;
813 HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
814 ICOM_THIS(IDirectDrawSurface4Impl,iface);
816 TRACE("(%p)->(0x%08lx)\n",This,(long)hdc);
818 if (This->s.bitmap_data != This->s.surface_desc.u1.lpSurface) {
819 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
820 /* Copy the DIB section to our surface */
821 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
822 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
825 FIXME("This case has to be done :/\n");
828 /* Unlock the surface */
829 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
833 HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(
834 LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
836 ICOM_THIS(IDirectDrawSurface4Impl,iface);
838 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
840 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
841 * the same interface. And IUnknown does that too of course.
843 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
844 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
845 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
846 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
847 IsEqualGUID( &IID_IUnknown, refiid )
850 IDirectDrawSurface4_AddRef(iface);
852 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
855 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
856 return OLE_E_ENUM_NOMORE;
859 HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
860 ICOM_THIS(IDirectDrawSurface4Impl,iface);
861 TRACE("(%p)->(), stub!\n",This);
862 return DD_OK; /* hmm */
865 HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(
866 LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb
868 ICOM_THIS(IDirectDrawSurface4Impl,iface);
870 struct _surface_chain *chain = This->s.chain;
872 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
874 for (i=0;i<chain->nrofsurfaces;i++) {
875 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
876 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
877 return DD_OK; /* FIXME: return value correct? */
883 HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
884 ICOM_THIS(IDirectDrawSurface4Impl,iface);
885 FIXME("(%p)->(),stub!\n",This);
889 HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
890 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
892 ICOM_THIS(IDirectDrawSurface4Impl,iface);
893 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
894 if (TRACE_ON(ddraw)) {
895 _dump_colorkeyflag(dwFlags);
897 _dump_DDCOLORKEY((void *) ckey);
901 /* If this surface was loaded as a texture, call also the texture
902 * SetColorKey callback. FIXME: hack approach :(
905 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
907 if( dwFlags & DDCKEY_SRCBLT ) {
908 dwFlags &= ~DDCKEY_SRCBLT;
909 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
910 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
913 if( dwFlags & DDCKEY_DESTBLT ) {
914 dwFlags &= ~DDCKEY_DESTBLT;
915 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
916 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
919 if( dwFlags & DDCKEY_SRCOVERLAY ) {
920 dwFlags &= ~DDCKEY_SRCOVERLAY;
921 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
922 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
925 if( dwFlags & DDCKEY_DESTOVERLAY ) {
926 dwFlags &= ~DDCKEY_DESTOVERLAY;
927 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
928 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
931 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
935 HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
936 LPDIRECTDRAWSURFACE4 iface, LPRECT lpRect
938 ICOM_THIS(IDirectDrawSurface4Impl,iface);
939 FIXME("(%p)->(%p),stub!\n",This,lpRect);
944 HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
945 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags,
946 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
948 ICOM_THIS(IDirectDrawSurface4Impl,iface);
950 struct _surface_chain *chain;
952 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
953 chain = This->s.chain;
954 for (i=0;i<chain->nrofsurfaces;i++) {
955 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
956 /* There is no AddRef in AddAttachedSurface, so why a release here :-)
957 IDirectDrawSurface4_Release(lpDDSAttachedSurface); */
959 chain->surfaces[i]->s.chain = NULL;
960 memcpy( chain->surfaces+i,
961 chain->surfaces+(i+1),
962 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
964 chain->surfaces = HeapReAlloc(
968 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
970 chain->nrofsurfaces--;
977 HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
978 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPVOID lpContext,
979 LPDDENUMSURFACESCALLBACK lpfnCallback
981 ICOM_THIS(IDirectDrawSurface4Impl,iface);
982 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
983 lpContext, lpfnCallback );
988 HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
989 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWCLIPPER* lplpDDClipper
991 ICOM_THIS(IDirectDrawSurface4Impl,iface);
992 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
997 HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
998 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey
1000 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1001 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1003 if( dwFlags & DDCKEY_SRCBLT ) {
1004 dwFlags &= ~DDCKEY_SRCBLT;
1005 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1007 if( dwFlags & DDCKEY_DESTBLT ) {
1008 dwFlags &= ~DDCKEY_DESTBLT;
1009 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1011 if( dwFlags & DDCKEY_SRCOVERLAY ) {
1012 dwFlags &= ~DDCKEY_SRCOVERLAY;
1013 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1015 if( dwFlags & DDCKEY_DESTOVERLAY ) {
1016 dwFlags &= ~DDCKEY_DESTOVERLAY;
1017 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1020 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1024 HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1025 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1027 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1028 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1033 HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1034 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWPALETTE* lplpDDPalette
1036 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1037 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
1039 if (!This->s.palette)
1040 return DDERR_NOPALETTEATTACHED;
1042 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
1043 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
1047 HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1048 LPDIRECTDRAWSURFACE4 iface, LONG lX, LONG lY
1050 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1051 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1056 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1057 LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
1058 LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
1059 LPDDOVERLAYFX lpDDOverlayFx
1061 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1062 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1063 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1068 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1069 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1071 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1072 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1077 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1078 LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference
1080 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1081 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1086 HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1087 LPDIRECTDRAWSURFACE4 iface, LPVOID* lplpDD
1089 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1090 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
1092 /* Not sure about that... */
1094 IDirectDraw_AddRef((LPDIRECTDRAW)This->s.ddraw),
1095 *lplpDD = (void *) This->s.ddraw;
1100 HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1101 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1103 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1104 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1109 HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1110 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1112 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1113 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1118 HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1119 LPDIRECTDRAWSURFACE4 iface, LPDDSURFACEDESC lpDDSD, DWORD dwFlags
1121 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1122 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1127 HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(
1128 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpData, DWORD cbSize,
1131 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1132 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1137 HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(
1138 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpBuffer,
1139 LPDWORD lpcbBufferSize
1141 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1142 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1147 HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(
1148 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag
1150 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1151 FIXME("(%p)->(%p)\n", This, guidTag);
1156 HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(
1157 LPDIRECTDRAWSURFACE4 iface, LPDWORD lpValue
1159 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1160 FIXME("(%p)->(%p)\n", This, lpValue);
1165 HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(
1166 LPDIRECTDRAWSURFACE4 iface
1168 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1169 FIXME("(%p)\n", This);