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);
236 /* truncate dst rect to dest surface. */
237 if ((xdst.bottom-xdst.top) > ddesc.dwHeight)
238 xdst.bottom = xdst.top+ddesc.dwHeight;
239 if ((xdst.right-xdst.left) > ddesc.dwWidth)
240 xdst.right = xdst.left+ddesc.dwWidth;
242 bpp = GET_BPP(ddesc);
243 srcheight = xsrc.bottom - xsrc.top;
244 srcwidth = xsrc.right - xsrc.left;
245 dstheight = xdst.bottom - xdst.top;
246 dstwidth = xdst.right - xdst.left;
247 width = (xdst.right - xdst.left) * bpp;
249 assert(width <= ddesc.lPitch);
251 dbuf = (BYTE*)ddesc.u1.lpSurface+(xdst.top*ddesc.lPitch)+(xdst.left*bpp);
253 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
255 /* First, all the 'source-less' blits */
256 if (dwFlags & DDBLT_COLORFILL) {
257 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
258 ddesc.lPitch, lpbltfx->u4.dwFillColor);
259 dwFlags &= ~DDBLT_COLORFILL;
262 if (dwFlags & DDBLT_DEPTHFILL)
263 FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
264 if (dwFlags & DDBLT_ROP) {
265 /* Catch some degenerate cases here */
266 switch(lpbltfx->dwROP) {
268 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,0);
270 case 0xAA0029: /* No-op */
273 ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,~0);
276 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
279 dwFlags &= ~DDBLT_ROP;
281 if (dwFlags & DDBLT_DDROPS) {
282 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
284 /* Now the 'with source' blits */
287 int sx, xinc, sy, yinc;
289 if (!dstwidth || !dstheight) /* hmm... stupid program ? */
291 sbase = (BYTE*)sdesc.u1.lpSurface+(xsrc.top*sdesc.lPitch)+xsrc.left*bpp;
292 xinc = (srcwidth << 16) / dstwidth;
293 yinc = (srcheight << 16) / dstheight;
296 /* No effects, we can cheat here */
297 if (dstwidth == srcwidth) {
298 if (dstheight == srcheight) {
299 /* No stretching in either direction. This needs to be as
300 * fast as possible */
302 for (y = 0; y < dstheight; y++) {
303 memcpy(dbuf, sbuf, width);
304 sbuf += sdesc.lPitch;
305 dbuf += ddesc.lPitch;
308 /* Stretching in Y direction only */
309 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
310 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
311 memcpy(dbuf, sbuf, width);
312 dbuf += ddesc.lPitch;
316 /* Stretching in X direction */
318 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
319 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
321 if ((sy >> 16) == (last_sy >> 16)) {
322 /* this sourcerow is the same as last sourcerow -
323 * copy already stretched row
325 memcpy(dbuf, dbuf - ddesc.lPitch, width);
327 #define STRETCH_ROW(type) { \
328 type *s = (type *) sbuf, *d = (type *) dbuf; \
329 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
330 d[x] = s[sx >> 16]; \
334 case 1: STRETCH_ROW(BYTE)
335 case 2: STRETCH_ROW(WORD)
336 case 4: STRETCH_ROW(DWORD)
339 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
343 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
344 d[0] = (pixel>>16)&0xff;
345 d[1] = (pixel>> 8)&0xff;
346 d[2] = (pixel )&0xff;
352 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
353 ret = DDERR_UNSUPPORTED;
358 dbuf += ddesc.lPitch;
362 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
363 DWORD keylow, keyhigh;
365 if (dwFlags & DDBLT_KEYSRC) {
366 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
367 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
369 /* I'm not sure if this is correct */
370 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
371 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
372 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
376 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
377 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
379 #define COPYROW_COLORKEY(type) { \
380 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
381 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
383 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
388 case 1: COPYROW_COLORKEY(BYTE)
389 case 2: COPYROW_COLORKEY(WORD)
390 case 4: COPYROW_COLORKEY(DWORD)
392 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
393 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
394 ret = DDERR_UNSUPPORTED;
397 dbuf += ddesc.lPitch;
399 #undef COPYROW_COLORKEY
400 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
405 if (dwFlags && FIXME_ON(ddraw)) {
406 FIXME("\tUnsupported flags: ");
407 _dump_DDBLT(dwFlags);
411 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
412 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
416 HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
417 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,
418 LPRECT rsrc,DWORD trans
420 ICOM_THIS(IDirectDrawSurface4Impl,iface);
422 DDSURFACEDESC ddesc,sdesc;
428 if (TRACE_ON(ddraw)) {
429 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
430 This,dstx,dsty,src,rsrc,trans
434 _dump_DDBLTFAST(trans);
436 FIXME("\tsrcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
438 FIXME(" srcrect: NULL\n");
441 /* We need to lock the surfaces, or we won't get refreshes when done. */
442 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
443 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
446 WARN("rsrc is NULL!\n");
448 rsrc->left = rsrc->top = 0;
449 rsrc->right = sdesc.dwWidth;
450 rsrc->bottom = sdesc.dwHeight;
453 bpp = GET_BPP(This->s.surface_desc);
454 sbuf = (BYTE *)sdesc.u1.lpSurface+(rsrc->top*sdesc.lPitch)+rsrc->left*bpp;
455 dbuf = (BYTE *)ddesc.u1.lpSurface+(dsty*ddesc.lPitch)+dstx* bpp;
458 h=rsrc->bottom-rsrc->top;
459 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
460 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
463 w=rsrc->right-rsrc->left;
464 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
465 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
468 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
469 DWORD keylow, keyhigh;
470 if (trans & DDBLTFAST_SRCCOLORKEY) {
471 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
472 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
474 /* I'm not sure if this is correct */
475 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
476 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
477 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
480 #define COPYBOX_COLORKEY(type) { \
481 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
482 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
483 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
484 for (y = 0; y < h; y++) { \
485 for (x = 0; x < w; x++) { \
487 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
489 (LPBYTE)s += sdesc.lPitch; \
490 (LPBYTE)d += ddesc.lPitch; \
496 case 1: COPYBOX_COLORKEY(BYTE)
497 case 2: COPYBOX_COLORKEY(WORD)
498 case 4: COPYBOX_COLORKEY(DWORD)
500 FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
501 ret = DDERR_UNSUPPORTED;
504 #undef COPYBOX_COLORKEY
508 for (y = 0; y < h; y++) {
509 memcpy(dbuf, sbuf, width);
510 sbuf += sdesc.lPitch;
511 dbuf += ddesc.lPitch;
515 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
516 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
520 HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
521 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
523 ICOM_THIS(IDirectDrawSurface4Impl,iface);
524 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",This,ddbltbatch,x,y);
528 HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
529 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
531 ICOM_THIS(IDirectDrawSurface4Impl,iface);
532 TRACE("(%p)->GetCaps(%p)\n",This,caps);
533 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
537 HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
538 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
540 ICOM_THIS(IDirectDrawSurface4Impl,iface);
541 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
543 /* Simply copy the surface description stored in the object */
544 *ddsd = This->s.surface_desc;
546 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
551 ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
552 ICOM_THIS(IDirectDrawSurface4Impl,iface);
553 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
554 return ++(This->ref);
558 HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
559 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
561 ICOM_THIS(IDirectDrawSurface4Impl,iface);
562 int i,found = 0,xstart;
563 struct _surface_chain *chain;
565 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
566 if (TRACE_ON(ddraw)) {
567 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
570 chain = This->s.chain;
572 return DDERR_NOTFOUND;
574 for (i=0;i<chain->nrofsurfaces;i++)
575 if (chain->surfaces[i] == This)
579 for (i=0;i<chain->nrofsurfaces;i++) {
580 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
582 if (found) /* may not find the same caps twice, (doc) */
583 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
585 found = (i+1)+xstart;
589 return DDERR_NOTFOUND;
590 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
592 /* For EverQuest testing */
593 IDirectDrawSurface4_AddRef(*lpdsf);
595 TRACE("found %p\n",*lpdsf);
599 HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
600 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
602 ICOM_THIS(IDirectDrawSurface4Impl,iface);
603 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
605 return DDERR_ALREADYINITIALIZED;
608 HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
609 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
611 ICOM_THIS(IDirectDrawSurface4Impl,iface);
612 TRACE("(%p)->(%p)\n",This,pf);
614 *pf = This->s.surface_desc.ddpfPixelFormat;
615 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
619 HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
620 ICOM_THIS(IDirectDrawSurface4Impl,iface);
621 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
625 HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
626 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
628 ICOM_THIS(IDirectDrawSurface4Impl,iface);
629 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
633 HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
634 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
636 ICOM_THIS(IDirectDrawSurface4Impl,iface);
637 TRACE("(%p)->(%p)!\n",This,lpClipper);
639 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
640 This->s.lpClipper = lpClipper;
641 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
645 HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
646 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
648 ICOM_THIS(IDirectDrawSurface4Impl,iface);
649 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
651 struct _surface_chain *chain;
653 FIXME("(%p)->(%p)\n",This,surf);
654 chain = This->s.chain;
656 /* IDirectDrawSurface4_AddRef(surf); */
659 for (i=0;i<chain->nrofsurfaces;i++)
660 if (chain->surfaces[i] == isurf)
661 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
663 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
664 chain->nrofsurfaces = 1;
665 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
666 chain->surfaces[0] = This;
667 This->s.chain = chain;
671 chain->surfaces = HeapReAlloc(
675 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
678 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
679 isurf->s.chain = chain;
680 chain->surfaces[chain->nrofsurfaces++] = isurf;
684 HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
685 ICOM_THIS(IDirectDrawSurface4Impl,iface);
691 TRACE("(%p)->GetDC(%p)\n",This,lphdc);
693 /* Creates a DIB Section of the same size / format as the surface */
694 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
696 if (This->s.hdc == 0) {
697 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
700 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
701 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
706 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
710 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
711 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
715 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
716 b_info->bmiHeader.biWidth = desc.dwWidth;
717 b_info->bmiHeader.biHeight = -desc.dwHeight;
718 b_info->bmiHeader.biPlanes = 1;
719 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
721 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
722 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
724 b_info->bmiHeader.biCompression = BI_RGB;
727 b_info->bmiHeader.biCompression = BI_BITFIELDS;
729 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
730 b_info->bmiHeader.biXPelsPerMeter = 0;
731 b_info->bmiHeader.biYPelsPerMeter = 0;
732 b_info->bmiHeader.biClrUsed = 0;
733 b_info->bmiHeader.biClrImportant = 0;
735 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
740 DWORD *masks = (DWORD *) &(b_info->bmiColors);
743 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
744 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
745 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
751 usage = DIB_RGB_COLORS;
757 /* Fill the palette */
758 usage = DIB_RGB_COLORS;
760 if (This->s.palette == NULL) {
761 ERR("Bad palette !!!\n");
763 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
764 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
766 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
767 rgb[i].rgbBlue = pent[i].peBlue;
768 rgb[i].rgbRed = pent[i].peRed;
769 rgb[i].rgbGreen = pent[i].peGreen;
775 ddc = CreateDCA("DISPLAY",NULL,NULL,NULL);
776 This->s.DIBsection = ddc ? DIB_CreateDIBSection(ddc,
779 &(This->s.bitmap_data),
781 (DWORD)desc.u1.lpSurface,
784 if (!This->s.DIBsection) {
785 ERR("CreateDIBSection failed!\n");
786 if (ddc) DeleteDC(ddc);
787 HeapFree(GetProcessHeap(), 0, b_info);
790 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
792 /* b_info is not useful anymore */
793 HeapFree(GetProcessHeap(), 0, b_info);
796 This->s.hdc = CreateCompatibleDC(ddc);
797 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
799 if (ddc) DeleteDC(ddc);
802 if (This->s.bitmap_data != desc.u1.lpSurface) {
803 FIXME("DIBSection not created for frame buffer, reverting to old code\n");
804 /* Copy our surface in the DIB section */
805 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
806 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
809 FIXME("This case has to be done :/\n");
813 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
814 *lphdc = This->s.hdc;
820 HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
821 ICOM_THIS(IDirectDrawSurface4Impl,iface);
823 TRACE("(%p)->(0x%08lx)\n",This,(long)hdc);
825 if (This->s.bitmap_data != This->s.surface_desc.u1.lpSurface) {
826 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
827 /* Copy the DIB section to our surface */
828 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
829 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
832 FIXME("This case has to be done :/\n");
835 /* Unlock the surface */
836 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
840 HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(
841 LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
843 ICOM_THIS(IDirectDrawSurface4Impl,iface);
845 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
847 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
848 * the same interface. And IUnknown does that too of course.
850 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
851 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
852 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
853 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
854 IsEqualGUID( &IID_IUnknown, refiid )
857 IDirectDrawSurface4_AddRef(iface);
859 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
862 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
863 return OLE_E_ENUM_NOMORE;
866 HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
867 ICOM_THIS(IDirectDrawSurface4Impl,iface);
868 TRACE("(%p)->(), stub!\n",This);
869 return DD_OK; /* hmm */
872 HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(
873 LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb
875 ICOM_THIS(IDirectDrawSurface4Impl,iface);
877 struct _surface_chain *chain = This->s.chain;
879 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
881 for (i=0;i<chain->nrofsurfaces;i++) {
882 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
883 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
884 return DD_OK; /* FIXME: return value correct? */
890 HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
891 ICOM_THIS(IDirectDrawSurface4Impl,iface);
892 FIXME("(%p)->(),stub!\n",This);
896 HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
897 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
899 ICOM_THIS(IDirectDrawSurface4Impl,iface);
900 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
901 if (TRACE_ON(ddraw)) {
902 _dump_colorkeyflag(dwFlags);
904 _dump_DDCOLORKEY((void *) ckey);
908 /* If this surface was loaded as a texture, call also the texture
909 * SetColorKey callback. FIXME: hack approach :(
912 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
914 if( dwFlags & DDCKEY_SRCBLT ) {
915 dwFlags &= ~DDCKEY_SRCBLT;
916 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
917 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
920 if( dwFlags & DDCKEY_DESTBLT ) {
921 dwFlags &= ~DDCKEY_DESTBLT;
922 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
923 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
926 if( dwFlags & DDCKEY_SRCOVERLAY ) {
927 dwFlags &= ~DDCKEY_SRCOVERLAY;
928 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
929 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
932 if( dwFlags & DDCKEY_DESTOVERLAY ) {
933 dwFlags &= ~DDCKEY_DESTOVERLAY;
934 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
935 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
938 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
942 HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
943 LPDIRECTDRAWSURFACE4 iface, LPRECT lpRect
945 ICOM_THIS(IDirectDrawSurface4Impl,iface);
946 FIXME("(%p)->(%p),stub!\n",This,lpRect);
951 HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
952 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags,
953 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
955 ICOM_THIS(IDirectDrawSurface4Impl,iface);
957 struct _surface_chain *chain;
959 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
960 chain = This->s.chain;
961 for (i=0;i<chain->nrofsurfaces;i++) {
962 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
963 /* There is no AddRef in AddAttachedSurface, so why a release here :-)
964 IDirectDrawSurface4_Release(lpDDSAttachedSurface); */
966 chain->surfaces[i]->s.chain = NULL;
967 memcpy( chain->surfaces+i,
968 chain->surfaces+(i+1),
969 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
971 chain->surfaces = HeapReAlloc(
975 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
977 chain->nrofsurfaces--;
984 HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
985 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPVOID lpContext,
986 LPDDENUMSURFACESCALLBACK lpfnCallback
988 ICOM_THIS(IDirectDrawSurface4Impl,iface);
989 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
990 lpContext, lpfnCallback );
995 HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
996 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWCLIPPER* lplpDDClipper
998 ICOM_THIS(IDirectDrawSurface4Impl,iface);
999 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
1004 HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1005 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey
1007 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1008 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1010 if( dwFlags & DDCKEY_SRCBLT ) {
1011 dwFlags &= ~DDCKEY_SRCBLT;
1012 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1014 if( dwFlags & DDCKEY_DESTBLT ) {
1015 dwFlags &= ~DDCKEY_DESTBLT;
1016 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1018 if( dwFlags & DDCKEY_SRCOVERLAY ) {
1019 dwFlags &= ~DDCKEY_SRCOVERLAY;
1020 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1022 if( dwFlags & DDCKEY_DESTOVERLAY ) {
1023 dwFlags &= ~DDCKEY_DESTOVERLAY;
1024 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1027 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1031 HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1032 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1034 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1035 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1040 HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1041 LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWPALETTE* lplpDDPalette
1043 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1044 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
1046 if (!This->s.palette)
1047 return DDERR_NOPALETTEATTACHED;
1049 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
1050 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
1054 HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1055 LPDIRECTDRAWSURFACE4 iface, LONG lX, LONG lY
1057 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1058 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1063 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1064 LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
1065 LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
1066 LPDDOVERLAYFX lpDDOverlayFx
1068 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1069 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1070 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1075 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1076 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1078 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1079 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1084 HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1085 LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference
1087 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1088 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1093 HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1094 LPDIRECTDRAWSURFACE4 iface, LPVOID* lplpDD
1096 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1097 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
1099 /* Not sure about that... */
1101 IDirectDraw_AddRef((LPDIRECTDRAW)This->s.ddraw),
1102 *lplpDD = (void *) This->s.ddraw;
1107 HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1108 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1110 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1111 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1116 HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1117 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
1119 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1120 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1125 HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1126 LPDIRECTDRAWSURFACE4 iface, LPDDSURFACEDESC lpDDSD, DWORD dwFlags
1128 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1129 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1134 HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(
1135 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpData, DWORD cbSize,
1138 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1139 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1144 HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(
1145 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpBuffer,
1146 LPDWORD lpcbBufferSize
1148 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1149 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1154 HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(
1155 LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag
1157 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1158 FIXME("(%p)->(%p)\n", This, guidTag);
1163 HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(
1164 LPDIRECTDRAWSURFACE4 iface, LPDWORD lpValue
1166 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1167 FIXME("(%p)->(%p)\n", This, lpValue);
1172 HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(
1173 LPDIRECTDRAWSURFACE4 iface
1175 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1176 FIXME("(%p)\n", This);