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);
34 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
35 This,lprect,lpddsd,flags,(DWORD)hnd);
36 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
37 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
38 This,lprect,lpddsd,flags,(DWORD)hnd);
40 /* First, copy the Surface description */
41 *lpddsd = This->s.surface_desc;
42 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
43 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
45 /* If asked only for a part, change the surface pointer */
47 TRACE(" lprect: %dx%d-%dx%d\n",
48 lprect->top,lprect->left,lprect->bottom,lprect->right
50 if ((lprect->top < 0) ||
52 (lprect->bottom < 0) ||
53 (lprect->right < 0)) {
54 ERR(" Negative values in LPRECT !!!\n");
55 return DDERR_INVALIDPARAMS;
58 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
59 (lprect->top*This->s.surface_desc.lPitch) +
60 lprect->left*GET_BPP(This->s.surface_desc));
62 assert(This->s.surface_desc.u1.lpSurface);
67 HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(
68 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
70 ICOM_THIS(IDirectDrawSurface4Impl,iface);
71 TRACE("(%p)->Unlock(%p)\n",This,surface);
75 IDirectDrawSurface4Impl* _common_find_flipto(
76 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
79 struct _surface_chain *chain = This->s.chain;
81 /* if there was no override flipto, look for current backbuffer */
83 /* walk the flip chain looking for backbuffer */
84 for (i=0;i<chain->nrofsurfaces;i++) {
85 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
87 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
88 flipto = chain->surfaces[i];
90 /* sanity checks ... */
93 for (i=0;i<chain->nrofsurfaces;i++)
94 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
96 if (i==chain->nrofsurfaces) {
97 /* we do not have a frontbuffer either */
98 for (i=0;i<chain->nrofsurfaces;i++)
99 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
100 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
103 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
104 int k = j % chain->nrofsurfaces;
105 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
106 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
107 flipto = chain->surfaces[k];
116 TRACE("flipping to %p\n",flipto);
121 static HRESULT _Blt_ColorFill(
122 LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color
129 #define COLORFILL_ROW(type) { \
130 type *d = (type *) buf; \
131 for (x = 0; x < width; x++) \
132 d[x] = (type) color; \
137 case 1: COLORFILL_ROW(BYTE)
138 case 2: COLORFILL_ROW(WORD)
139 case 4: COLORFILL_ROW(DWORD)
141 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
142 return DDERR_UNSUPPORTED;
147 /* Now copy first row */
149 for (y = 1; y < height; y++) {
151 memcpy(buf, first, width * bpp);
156 HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
157 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,
158 DWORD dwFlags,LPDDBLTFX lpbltfx
160 ICOM_THIS(IDirectDrawSurface4Impl,iface);
162 DDSURFACEDESC ddesc,sdesc;
164 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
168 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
170 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
171 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
173 if (src && sdesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
174 ERR("blitting FROM a primary surface? Hello?\n");
175 if (!(ddesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
176 ERR("NOT blitting into a primary surface? Hello?\n");
178 if (TRACE_ON(ddraw)) {
179 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
180 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
182 _dump_DDBLT(dwFlags);
183 if (dwFlags & DDBLT_DDFX) {
185 _dump_DDBLTFX(lpbltfx->dwDDFX);
190 if ((rdst->top < 0) ||
192 (rdst->bottom < 0) ||
194 ERR(" Negative values in LPRECT !!!\n");
197 memcpy(&xdst,rdst,sizeof(xdst));
200 xdst.bottom = ddesc.dwHeight;
202 xdst.right = ddesc.dwWidth;
206 if ((rsrc->top < 0) ||
208 (rsrc->bottom < 0) ||
210 ERR(" Negative values in LPRECT !!!\n");
213 memcpy(&xsrc,rsrc,sizeof(xsrc));
217 xsrc.bottom = sdesc.dwHeight;
219 xsrc.right = sdesc.dwWidth;
221 memset(&xsrc,0,sizeof(xsrc));
224 assert(xsrc.bottom <= sdesc.dwHeight);
225 assert(xdst.bottom <= ddesc.dwHeight);
227 bpp = GET_BPP(ddesc);
228 srcheight = xsrc.bottom - xsrc.top;
229 srcwidth = xsrc.right - xsrc.left;
230 dstheight = xdst.bottom - xdst.top;
231 dstwidth = xdst.right - xdst.left;
232 width = (xdst.right - xdst.left) * bpp;
234 assert(width <= ddesc.lPitch);
236 dbuf = (BYTE*)ddesc.u1.lpSurface+(xdst.top*ddesc.lPitch)+(xdst.left*bpp);
238 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
240 /* First, all the 'source-less' blits */
241 if (dwFlags & DDBLT_COLORFILL) {
242 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
243 ddesc.lPitch, lpbltfx->u4.dwFillColor);
244 dwFlags &= ~DDBLT_COLORFILL;
247 if (dwFlags & DDBLT_DEPTHFILL)
248 FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
249 if (dwFlags & DDBLT_ROP) {
250 /* Catch some degenerate cases here */
251 switch(lpbltfx->dwROP) {
253 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,0);
255 case 0xAA0029: /* No-op */
258 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,~0);
261 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
264 dwFlags &= ~DDBLT_ROP;
266 if (dwFlags & DDBLT_DDROPS) {
267 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
269 /* Now the 'with source' blits */
272 int sx, xinc, sy, yinc;
274 sbase = (BYTE*)sdesc.u1.lpSurface+(xsrc.top*sdesc.lPitch)+xsrc.left*bpp;
275 xinc = (srcwidth << 16) / dstwidth;
276 yinc = (srcheight << 16) / dstheight;
279 assert(ddesc.lPitch >= width);
280 assert(sdesc.lPitch >= width);
282 /* No effects, we can cheat here */
283 if (dstwidth == srcwidth) {
284 if (dstheight == srcheight) {
285 /* No stretching in either direction. This needs to be as
286 * fast as possible */
288 for (y = 0; y < dstheight; y++) {
289 memcpy(dbuf, sbuf, width);
290 sbuf += sdesc.lPitch;
291 dbuf += ddesc.lPitch;
294 /* Stretching in Y direction only */
295 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
296 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
297 memcpy(dbuf, sbuf, width);
298 dbuf += ddesc.lPitch;
302 /* Stretching in X direction */
304 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
305 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
307 assert((sy>>16) < srcheight);
309 if ((sy >> 16) == (last_sy >> 16)) {
310 /* this sourcerow is the same as last sourcerow -
311 * copy already stretched row
313 memcpy(dbuf, dbuf - ddesc.lPitch, width);
315 #define STRETCH_ROW(type) { \
316 type *s = (type *) sbuf, *d = (type *) dbuf; \
317 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
318 d[x] = s[sx >> 16]; \
322 case 1: STRETCH_ROW(BYTE)
323 case 2: STRETCH_ROW(WORD)
324 case 4: STRETCH_ROW(DWORD)
327 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
331 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
332 d[0] = (pixel>>16)&0xff;
333 d[1] = (pixel>> 8)&0xff;
334 d[2] = (pixel )&0xff;
340 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
341 ret = DDERR_UNSUPPORTED;
346 dbuf += ddesc.lPitch;
350 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
351 DWORD keylow, keyhigh;
353 if (dwFlags & DDBLT_KEYSRC) {
354 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
355 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
357 /* I'm not sure if this is correct */
358 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
359 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
360 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
364 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
365 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
367 #define COPYROW_COLORKEY(type) { \
368 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
369 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
371 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
376 case 1: COPYROW_COLORKEY(BYTE)
377 case 2: COPYROW_COLORKEY(WORD)
378 case 4: COPYROW_COLORKEY(DWORD)
380 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
381 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
382 ret = DDERR_UNSUPPORTED;
385 dbuf += ddesc.lPitch;
387 #undef COPYROW_COLORKEY
388 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
393 if (dwFlags && FIXME_ON(ddraw)) {
394 FIXME("\tUnsupported flags: ");
395 _dump_DDBLT(dwFlags);
399 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
400 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
404 HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
405 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,
406 LPRECT rsrc,DWORD trans
408 ICOM_THIS(IDirectDrawSurface4Impl,iface);
410 DDSURFACEDESC ddesc,sdesc;
416 if (TRACE_ON(ddraw)) {
417 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
418 This,dstx,dsty,src,rsrc,trans
422 _dump_DDBLTFAST(trans);
424 FIXME("\tsrcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
426 FIXME(" srcrect: NULL\n");
429 /* We need to lock the surfaces, or we won't get refreshes when done. */
430 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
431 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
434 WARN("rsrc is NULL!\n");
436 rsrc->left = rsrc->top = 0;
437 rsrc->right = sdesc.dwWidth;
438 rsrc->bottom = sdesc.dwHeight;
441 bpp = GET_BPP(This->s.surface_desc);
442 sbuf = (BYTE *)sdesc.u1.lpSurface+(rsrc->top*sdesc.lPitch)+rsrc->left*bpp;
443 dbuf = (BYTE *)ddesc.u1.lpSurface+(dsty*ddesc.lPitch)+dstx* bpp;
446 h=rsrc->bottom-rsrc->top;
447 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
448 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
451 w=rsrc->right-rsrc->left;
452 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
453 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
456 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
457 DWORD keylow, keyhigh;
458 if (trans & DDBLTFAST_SRCCOLORKEY) {
459 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
460 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
462 /* I'm not sure if this is correct */
463 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
464 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
465 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
468 #define COPYBOX_COLORKEY(type) { \
469 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
470 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
471 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
472 for (y = 0; y < h; y++) { \
473 for (x = 0; x < w; x++) { \
475 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
477 (LPBYTE)s += sdesc.lPitch; \
478 (LPBYTE)d += ddesc.lPitch; \
484 case 1: COPYBOX_COLORKEY(BYTE)
485 case 2: COPYBOX_COLORKEY(WORD)
486 case 4: COPYBOX_COLORKEY(DWORD)
488 FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
489 ret = DDERR_UNSUPPORTED;
492 #undef COPYBOX_COLORKEY
496 for (y = 0; y < h; y++) {
497 memcpy(dbuf, sbuf, width);
498 sbuf += sdesc.lPitch;
499 dbuf += ddesc.lPitch;
503 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
504 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
508 HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
509 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
511 ICOM_THIS(IDirectDrawSurface4Impl,iface);
512 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",This,ddbltbatch,x,y);
516 HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
517 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
519 ICOM_THIS(IDirectDrawSurface4Impl,iface);
520 TRACE("(%p)->GetCaps(%p)\n",This,caps);
521 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
525 HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
526 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
528 ICOM_THIS(IDirectDrawSurface4Impl,iface);
529 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
531 /* Simply copy the surface description stored in the object */
532 *ddsd = This->s.surface_desc;
534 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
539 ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
540 ICOM_THIS(IDirectDrawSurface4Impl,iface);
541 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
542 return ++(This->ref);
546 HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
547 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
549 ICOM_THIS(IDirectDrawSurface4Impl,iface);
550 int i,found = 0,xstart;
551 struct _surface_chain *chain;
553 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
554 if (TRACE_ON(ddraw)) {
555 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
558 chain = This->s.chain;
560 return DDERR_NOTFOUND;
562 for (i=0;i<chain->nrofsurfaces;i++)
563 if (chain->surfaces[i] == This)
567 for (i=0;i<chain->nrofsurfaces;i++) {
568 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
570 if (found) /* may not find the same caps twice, (doc) */
571 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
573 found = (i+1)+xstart;
577 return DDERR_NOTFOUND;
578 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
580 TRACE("found %p\n",*lpdsf);
584 HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
585 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
587 ICOM_THIS(IDirectDrawSurface4Impl,iface);
588 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
590 return DDERR_ALREADYINITIALIZED;
593 HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
594 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
596 ICOM_THIS(IDirectDrawSurface4Impl,iface);
597 TRACE("(%p)->(%p)\n",This,pf);
599 *pf = This->s.surface_desc.ddpfPixelFormat;
600 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
604 HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
605 ICOM_THIS(IDirectDrawSurface4Impl,iface);
606 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
610 HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
611 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
613 ICOM_THIS(IDirectDrawSurface4Impl,iface);
614 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
618 HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
619 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
621 ICOM_THIS(IDirectDrawSurface4Impl,iface);
622 TRACE("(%p)->(%p)!\n",This,lpClipper);
624 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
625 This->s.lpClipper = lpClipper;
626 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
630 HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
631 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
633 ICOM_THIS(IDirectDrawSurface4Impl,iface);
634 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
636 struct _surface_chain *chain;
638 FIXME("(%p)->(%p)\n",This,surf);
639 chain = This->s.chain;
641 /* IDirectDrawSurface4_AddRef(surf); */
644 for (i=0;i<chain->nrofsurfaces;i++)
645 if (chain->surfaces[i] == isurf)
646 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
648 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
649 chain->nrofsurfaces = 1;
650 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
651 chain->surfaces[0] = This;
652 This->s.chain = chain;
656 chain->surfaces = HeapReAlloc(
660 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
663 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
664 isurf->s.chain = chain;
665 chain->surfaces[chain->nrofsurfaces++] = isurf;
669 HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
670 ICOM_THIS(IDirectDrawSurface4Impl,iface);
675 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
677 /* Creates a DIB Section of the same size / format as the surface */
678 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
680 if (This->s.hdc == 0) {
681 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
684 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
685 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
690 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
694 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
695 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
699 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
700 b_info->bmiHeader.biWidth = desc.dwWidth;
701 b_info->bmiHeader.biHeight = desc.dwHeight;
702 b_info->bmiHeader.biPlanes = 1;
703 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
705 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
706 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
708 b_info->bmiHeader.biCompression = BI_RGB;
711 b_info->bmiHeader.biCompression = BI_BITFIELDS;
713 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
714 b_info->bmiHeader.biXPelsPerMeter = 0;
715 b_info->bmiHeader.biYPelsPerMeter = 0;
716 b_info->bmiHeader.biClrUsed = 0;
717 b_info->bmiHeader.biClrImportant = 0;
719 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
724 DWORD *masks = (DWORD *) &(b_info->bmiColors);
727 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
728 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
729 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
735 usage = DIB_RGB_COLORS;
741 /* Fill the palette */
742 usage = DIB_RGB_COLORS;
744 if (This->s.palette == NULL) {
745 ERR("Bad palette !!!\n");
747 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
748 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
750 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
751 rgb[i].rgbBlue = pent[i].peBlue;
752 rgb[i].rgbRed = pent[i].peRed;
753 rgb[i].rgbGreen = pent[i].peGreen;
759 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
762 &(This->s.bitmap_data),
766 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
767 if (!This->s.DIBsection) {
768 ERR("CreateDIBSection failed!\n");
771 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
773 /* b_info is not useful anymore */
774 HeapFree(GetProcessHeap(), 0, b_info);
777 This->s.hdc = CreateCompatibleDC(0);
778 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
781 /* Copy our surface in the DIB section */
782 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
783 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
786 FIXME("This case has to be done :/\n");
788 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
789 *lphdc = This->s.hdc;
794 HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
795 ICOM_THIS(IDirectDrawSurface4Impl,iface);
797 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
798 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
799 /* Copy the DIB section to our surface */
800 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
801 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
804 FIXME("This case has to be done :/\n");
806 /* Unlock the surface */
807 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
811 HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(
812 LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
814 ICOM_THIS(IDirectDrawSurface4Impl,iface);
816 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
818 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
819 * the same interface. And IUnknown does that too of course.
821 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
822 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
823 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
824 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
825 IsEqualGUID( &IID_IUnknown, refiid )
828 IDirectDrawSurface4_AddRef(iface);
830 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
833 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
834 return OLE_E_ENUM_NOMORE;
837 HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
838 ICOM_THIS(IDirectDrawSurface4Impl,iface);
839 TRACE("(%p)->(), stub!\n",This);
840 return DD_OK; /* hmm */
843 HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(
844 LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb
846 ICOM_THIS(IDirectDrawSurface4Impl,iface);
848 struct _surface_chain *chain = This->s.chain;
850 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
851 for (i=0;i<chain->nrofsurfaces;i++) {
852 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
853 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
854 return DD_OK; /* FIXME: return value correct? */
859 HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
860 ICOM_THIS(IDirectDrawSurface4Impl,iface);
861 FIXME("(%p)->(),stub!\n",This);
865 HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
866 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
868 ICOM_THIS(IDirectDrawSurface4Impl,iface);
869 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
870 if (TRACE_ON(ddraw)) {
871 _dump_colorkeyflag(dwFlags);
873 _dump_DDCOLORKEY((void *) ckey);
877 /* If this surface was loaded as a texture, call also the texture
878 * SetColorKey callback. FIXME: hack approach :(
881 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
883 if( dwFlags & DDCKEY_SRCBLT ) {
884 dwFlags &= ~DDCKEY_SRCBLT;
885 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
886 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
889 if( dwFlags & DDCKEY_DESTBLT ) {
890 dwFlags &= ~DDCKEY_DESTBLT;
891 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
892 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
895 if( dwFlags & DDCKEY_SRCOVERLAY ) {
896 dwFlags &= ~DDCKEY_SRCOVERLAY;
897 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
898 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
901 if( dwFlags & DDCKEY_DESTOVERLAY ) {
902 dwFlags &= ~DDCKEY_DESTOVERLAY;
903 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
904 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
907 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
911 HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
912 LPDIRECTDRAWSURFACE4 iface, LPRECT lpRect
914 ICOM_THIS(IDirectDrawSurface4Impl,iface);
915 FIXME("(%p)->(%p),stub!\n",This,lpRect);
920 HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
921 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags,
922 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
924 ICOM_THIS(IDirectDrawSurface4Impl,iface);
926 struct _surface_chain *chain;
928 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
929 chain = This->s.chain;
930 for (i=0;i<chain->nrofsurfaces;i++) {
931 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
932 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
934 chain->surfaces[i]->s.chain = NULL;
935 memcpy( chain->surfaces+i,
936 chain->surfaces+(i+1),
937 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
939 chain->surfaces = HeapReAlloc(
943 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
945 chain->nrofsurfaces--;
952 HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
953 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPVOID lpContext,
954 LPDDENUMSURFACESCALLBACK lpfnCallback
956 ICOM_THIS(IDirectDrawSurface4Impl,iface);
957 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
958 lpContext, lpfnCallback );
963 HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
964 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWCLIPPER* lplpDDClipper
966 ICOM_THIS(IDirectDrawSurface4Impl,iface);
967 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
972 HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
973 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey
975 ICOM_THIS(IDirectDrawSurface4Impl,iface);
976 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
978 if( dwFlags & DDCKEY_SRCBLT ) {
979 dwFlags &= ~DDCKEY_SRCBLT;
980 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
982 if( dwFlags & DDCKEY_DESTBLT ) {
983 dwFlags &= ~DDCKEY_DESTBLT;
984 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
986 if( dwFlags & DDCKEY_SRCOVERLAY ) {
987 dwFlags &= ~DDCKEY_SRCOVERLAY;
988 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
990 if( dwFlags & DDCKEY_DESTOVERLAY ) {
991 dwFlags &= ~DDCKEY_DESTOVERLAY;
992 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
995 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
999 HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1000 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1002 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1003 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1008 HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1009 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWPALETTE* lplpDDPalette
1011 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1012 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
1014 if (!This->s.palette)
1015 return DDERR_NOPALETTEATTACHED;
1017 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
1018 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
1022 HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1023 LPDIRECTDRAWSURFACE4 iface, LONG lX, LONG lY
1025 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1026 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1031 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1032 LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
1033 LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
1034 LPDDOVERLAYFX lpDDOverlayFx
1036 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1037 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1038 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1043 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1044 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1046 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1047 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1052 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1053 LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference
1055 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1056 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1061 HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1062 LPDIRECTDRAWSURFACE4 iface, LPVOID* lplpDD
1064 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1065 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
1067 /* Not sure about that... */
1068 *lplpDD = (void *) This->s.ddraw;
1073 HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1074 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1076 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1077 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1082 HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1083 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1085 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1086 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1091 HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1092 LPDIRECTDRAWSURFACE4 iface, LPDDSURFACEDESC lpDDSD, DWORD dwFlags
1094 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1095 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1100 HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(
1101 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpData, DWORD cbSize,
1104 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1105 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1110 HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(
1111 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpBuffer,
1112 LPDWORD lpcbBufferSize
1114 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1115 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1120 HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(
1121 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag
1123 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1124 FIXME("(%p)->(%p)\n", This, guidTag);
1129 HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(
1130 LPDIRECTDRAWSURFACE4 iface, LPDWORD lpValue
1132 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1133 FIXME("(%p)->(%p)\n", This, lpValue);
1138 HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(
1139 LPDIRECTDRAWSURFACE4 iface
1141 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1142 FIXME("(%p)\n", This);