2 * DirectDraw helper functions
4 * Copyright 1997-2000 Marcus Meissner
5 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
6 * Copyright 2000 TransGaming Technologies Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
26 #include "wine/debug.h"
38 #include "ddraw_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
42 /* *************************************
43 16 / 15 bpp to palettized 8 bpp
44 ************************************* */
45 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
46 unsigned char *c_src = (unsigned char *) src;
47 unsigned short *c_dst = (unsigned short *) dst;
50 if (palette != NULL) {
51 const unsigned int * pal = (unsigned int *) palette->screen_palents;
53 for (y = height; y--; ) {
54 #if defined(__i386__) && defined(__GNUC__)
55 /* gcc generates slightly inefficient code for the the copy/lookup,
56 * it generates one excess memory access (to pal) per pixel. Since
57 * we know that pal is not modified by the memory write we can
58 * put it into a register and reduce the number of memory accesses
59 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
60 * stalls. (This is not guaranteed to be the fastest method.)
66 " movw (%%edx,%%eax,4),%%ax\n"
70 : "=S" (c_src), "=D" (c_dst)
71 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
72 : "eax", "cc", "memory"
76 unsigned char * srclineend = c_src+width;
77 while (c_src < srclineend)
78 *c_dst++ = pal[*c_src++];
83 FIXME("No palette set...\n");
84 memset(dst, 0, width * height * 2);
87 static void palette_convert_16_to_8(
88 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
91 unsigned int *pal = (unsigned int *) screen_palette;
93 for (i = 0; i < count; i++)
94 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
95 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
96 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
99 static void palette_convert_15_to_8(
100 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
103 unsigned int *pal = (unsigned int *) screen_palette;
105 for (i = 0; i < count; i++)
106 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
107 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
108 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
111 /* *************************************
112 24 to palettized 8 bpp
113 ************************************* */
114 static void pixel_convert_24_to_8(
115 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
116 IDirectDrawPaletteImpl* palette
118 unsigned char *c_src = (unsigned char *) src;
119 unsigned char *c_dst = (unsigned char *) dst;
122 if (palette != NULL) {
123 const unsigned int *pal = (unsigned int *) palette->screen_palents;
125 for (y = height; y--; ) {
126 unsigned char * srclineend = c_src+width;
127 while (c_src < srclineend ) {
128 register long pixel = pal[*c_src++];
131 *c_dst++ = pixel>>16;
133 c_src+=(pitch-width);
136 FIXME("No palette set...\n");
137 memset(dst, 0, width * height * 3);
141 /* *************************************
142 32 bpp to palettized 8 bpp
143 ************************************* */
144 static void pixel_convert_32_to_8(
145 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
146 IDirectDrawPaletteImpl* palette
148 unsigned char *c_src = (unsigned char *) src;
149 unsigned int *c_dst = (unsigned int *) dst;
152 if (palette != NULL) {
153 const unsigned int *pal = (unsigned int *) palette->screen_palents;
155 for (y = height; y--; ) {
156 #if defined(__i386__) && defined(__GNUC__)
157 /* See comment in pixel_convert_16_to_8 */
158 __asm__ __volatile__(
162 " movl (%%edx,%%eax,4),%%eax\n"
166 : "=S" (c_src), "=D" (c_dst)
167 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
168 : "eax", "cc", "memory"
170 c_src+=(pitch-width);
172 unsigned char * srclineend = c_src+width;
173 while (c_src < srclineend )
174 *c_dst++ = pal[*c_src++];
175 c_src+=(pitch-width);
179 FIXME("No palette set...\n");
180 memset(dst, 0, width * height * 4);
184 static void palette_convert_24_to_8(
185 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
188 unsigned int *pal = (unsigned int *) screen_palette;
190 for (i = 0; i < count; i++)
191 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
192 (((unsigned int) palent[i].peGreen) << 8) |
193 ((unsigned int) palent[i].peBlue));
196 /* *************************************
198 ************************************* */
199 static void pixel_convert_15_to_16(
200 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
201 IDirectDrawPaletteImpl* palette
203 unsigned short *c_src = (unsigned short *) src;
204 unsigned short *c_dst = (unsigned short *) dst;
207 for (y = height; y--; ) {
208 unsigned short * srclineend = c_src+width;
209 while (c_src < srclineend ) {
210 unsigned short val = *c_src++;
211 *c_dst++=((val&0xFFC0)>>1)|(val&0x001f);
213 c_src+=((pitch/2)-width);
217 /* *************************************
219 ************************************* */
220 static void pixel_convert_32_to_16(
221 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
222 IDirectDrawPaletteImpl* palette
224 unsigned short *c_src = (unsigned short *) src;
225 unsigned int *c_dst = (unsigned int *) dst;
228 for (y = height; y--; ) {
229 unsigned short * srclineend = c_src+width;
230 while (c_src < srclineend ) {
231 *c_dst++ = (((*c_src & 0xF800) << 8) |
232 ((*c_src & 0x07E0) << 5) |
233 ((*c_src & 0x001F) << 3));
236 c_src+=((pitch/2)-width);
240 /* *************************************
242 ************************************* */
243 static void pixel_convert_32_to_24(
244 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
245 IDirectDrawPaletteImpl* palette
247 unsigned char *c_src = (unsigned char *) src;
248 unsigned int *c_dst = (unsigned int *) dst;
251 for (y = height; y--; ) {
252 unsigned char * srclineend = c_src+width*3;
253 while (c_src < srclineend ) {
254 /* FIXME: wrong for big endian */
255 memcpy(c_dst,c_src,3);
259 c_src+=pitch-width*3;
263 /* *************************************
265 ************************************* */
266 static void pixel_convert_16_to_32(
267 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
268 IDirectDrawPaletteImpl* palette
270 unsigned int *c_src = (unsigned int *) src;
271 unsigned short *c_dst = (unsigned short *) dst;
274 for (y = height; y--; ) {
275 unsigned int * srclineend = c_src+width;
276 while (c_src < srclineend ) {
277 *c_dst++ = (((*c_src & 0xF80000) >> 8) |
278 ((*c_src & 0x00FC00) >> 5) |
279 ((*c_src & 0x0000F8) >> 3));
282 c_src+=((pitch/4)-width);
286 Convert ModeEmulations[8] = {
287 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { pixel_convert_32_to_24, NULL } },
288 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
289 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
290 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
291 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 16,16, 0xf800, 0x07e0, 0x001f }, { pixel_convert_15_to_16, NULL } },
292 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
293 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
294 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { pixel_convert_16_to_32, NULL } }
297 void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut)
299 /* 2 adds three additional caps fields to the end. Both versions
300 * are unversioned. */
301 pOut->dwCaps = pIn->dwCaps;
307 void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn,
308 DDDEVICEIDENTIFIER* pOut)
310 /* 2 adds a dwWHQLLevel field to the end. Both structures are
312 memcpy(pOut, pIn, sizeof(*pOut));
315 /******************************************************************************
316 * debug output functions
318 void DDRAW_dump_flags_(DWORD flags, const flag_info* names,
319 size_t num_names, int newline)
323 for (i=0; i < num_names; i++)
324 if ((flags & names[i].val) || /* standard flag value */
325 ((!flags) && (!names[i].val))) /* zero value only */
326 DPRINTF("%s ", names[i].name);
332 void DDRAW_dump_members(DWORD flags, const void* data,
333 const member_info* mems, size_t num_mems)
337 for (i=0; i < num_mems; i++)
339 if (mems[i].val & flags)
341 DPRINTF(" - %s : ", mems[i].name);
342 mems[i].func((const char *)data + mems[i].offset);
348 void DDRAW_dump_DDBLTFX(DWORD flagmask)
350 static const flag_info flags[] =
352 FE(DDBLTFX_ARITHSTRETCHY),
353 FE(DDBLTFX_MIRRORLEFTRIGHT),
354 FE(DDBLTFX_MIRRORUPDOWN),
355 FE(DDBLTFX_NOTEARING),
356 FE(DDBLTFX_ROTATE180),
357 FE(DDBLTFX_ROTATE270),
358 FE(DDBLTFX_ROTATE90),
359 FE(DDBLTFX_ZBUFFERRANGE),
360 FE(DDBLTFX_ZBUFFERBASEDEST)
363 DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
366 void DDRAW_dump_DDBLTFAST(DWORD flagmask)
368 static const flag_info flags[] =
370 FE(DDBLTFAST_NOCOLORKEY),
371 FE(DDBLTFAST_SRCCOLORKEY),
372 FE(DDBLTFAST_DESTCOLORKEY),
376 DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
379 void DDRAW_dump_DDBLT(DWORD flagmask)
381 static const flag_info flags[] =
384 FE(DDBLT_ALPHADESTCONSTOVERRIDE),
385 FE(DDBLT_ALPHADESTNEG),
386 FE(DDBLT_ALPHADESTSURFACEOVERRIDE),
387 FE(DDBLT_ALPHAEDGEBLEND),
389 FE(DDBLT_ALPHASRCCONSTOVERRIDE),
390 FE(DDBLT_ALPHASRCNEG),
391 FE(DDBLT_ALPHASRCSURFACEOVERRIDE),
397 FE(DDBLT_KEYDESTOVERRIDE),
399 FE(DDBLT_KEYSRCOVERRIDE),
401 FE(DDBLT_ROTATIONANGLE),
403 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE),
404 FE(DDBLT_ZBUFFERDESTOVERRIDE),
405 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE),
406 FE(DDBLT_ZBUFFERSRCOVERRIDE),
412 DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
415 void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
417 static const flag_info flags[] = {
418 FE(DDSCAPS_RESERVED1),
420 FE(DDSCAPS_BACKBUFFER),
423 FE(DDSCAPS_FRONTBUFFER),
424 FE(DDSCAPS_OFFSCREENPLAIN),
427 FE(DDSCAPS_PRIMARYSURFACE),
428 FE(DDSCAPS_PRIMARYSURFACELEFT),
429 FE(DDSCAPS_SYSTEMMEMORY),
431 FE(DDSCAPS_3DDEVICE),
432 FE(DDSCAPS_VIDEOMEMORY),
434 FE(DDSCAPS_WRITEONLY),
437 FE(DDSCAPS_LIVEVIDEO),
441 FE(DDSCAPS_RESERVED2),
442 FE(DDSCAPS_ALLOCONLOAD),
443 FE(DDSCAPS_VIDEOPORT),
444 FE(DDSCAPS_LOCALVIDMEM),
445 FE(DDSCAPS_NONLOCALVIDMEM),
446 FE(DDSCAPS_STANDARDVGAMODE),
447 FE(DDSCAPS_OPTIMIZED)
449 static const flag_info flags2[] = {
450 FE(DDSCAPS2_HARDWAREDEINTERLACE),
451 FE(DDSCAPS2_HINTDYNAMIC),
452 FE(DDSCAPS2_HINTSTATIC),
453 FE(DDSCAPS2_TEXTUREMANAGE),
454 FE(DDSCAPS2_RESERVED1),
455 FE(DDSCAPS2_RESERVED2),
457 FE(DDSCAPS2_HINTANTIALIASING),
458 FE(DDSCAPS2_CUBEMAP),
459 FE(DDSCAPS2_CUBEMAP_POSITIVEX),
460 FE(DDSCAPS2_CUBEMAP_NEGATIVEX),
461 FE(DDSCAPS2_CUBEMAP_POSITIVEY),
462 FE(DDSCAPS2_CUBEMAP_NEGATIVEY),
463 FE(DDSCAPS2_CUBEMAP_POSITIVEZ),
464 FE(DDSCAPS2_CUBEMAP_NEGATIVEZ),
465 FE(DDSCAPS2_MIPMAPSUBLEVEL),
466 FE(DDSCAPS2_D3DTEXTUREMANAGE),
467 FE(DDSCAPS2_DONOTPERSIST),
468 FE(DDSCAPS2_STEREOSURFACELEFT)
471 DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0);
472 DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0);
475 void DDRAW_dump_DDSCAPS(const DDSCAPS *in) {
478 in_bis.dwCaps = in->dwCaps;
483 DDRAW_dump_DDSCAPS2(&in_bis);
486 void DDRAW_dump_pixelformat_flag(DWORD flagmask)
488 static const flag_info flags[] =
490 FE(DDPF_ALPHAPIXELS),
493 FE(DDPF_PALETTEINDEXED4),
494 FE(DDPF_PALETTEINDEXEDTO8),
495 FE(DDPF_PALETTEINDEXED8),
501 FE(DDPF_PALETTEINDEXED1),
502 FE(DDPF_PALETTEINDEXED2),
506 DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0);
509 void DDRAW_dump_paletteformat(DWORD dwFlags)
511 static const flag_info flags[] =
514 FE(DDPCAPS_8BITENTRIES),
516 FE(DDPCAPS_INITIALIZE),
517 FE(DDPCAPS_PRIMARYSURFACE),
518 FE(DDPCAPS_PRIMARYSURFACELEFT),
519 FE(DDPCAPS_ALLOW256),
526 DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
529 void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) {
531 DDRAW_dump_pixelformat_flag(pf->dwFlags);
532 if (pf->dwFlags & DDPF_FOURCC) {
533 DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
534 (unsigned char)( pf->dwFourCC &0xff),
535 (unsigned char)((pf->dwFourCC>> 8)&0xff),
536 (unsigned char)((pf->dwFourCC>>16)&0xff),
537 (unsigned char)((pf->dwFourCC>>24)&0xff),
542 if (pf->dwFlags & DDPF_RGB) {
544 DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount);
545 switch (pf->u1.dwRGBBitCount) {
546 case 4: cmd = "%1lx"; break;
547 case 8: cmd = "%02lx"; break;
548 case 16: cmd = "%04lx"; break;
549 case 24: cmd = "%06lx"; break;
550 case 32: cmd = "%08lx"; break;
551 default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
553 DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask);
554 DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask);
555 DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask);
556 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
557 DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask);
559 if (pf->dwFlags & DDPF_ZPIXELS) {
560 DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask);
563 if (pf->dwFlags & DDPF_ZBUFFER) {
564 DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth);
566 if (pf->dwFlags & DDPF_ALPHA) {
567 DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth);
572 void DDRAW_dump_colorkeyflag(DWORD ck)
574 static const flag_info flags[] =
576 FE(DDCKEY_COLORSPACE),
578 FE(DDCKEY_DESTOVERLAY),
580 FE(DDCKEY_SRCOVERLAY)
583 DDRAW_dump_flags(ck, flags, sizeof(flags)/sizeof(flags[0]));
586 void DDRAW_dump_lockflag(DWORD lockflag)
588 static const flag_info flags[] =
590 FE(DDLOCK_SURFACEMEMORYPTR),
594 FE(DDLOCK_WRITEONLY),
595 FE(DDLOCK_NOSYSLOCK),
596 FE(DDLOCK_DISCARDCONTENTS),
597 FE(DDLOCK_NOOVERWRITE)
600 DDRAW_dump_flags(lockflag, flags, sizeof(flags)/sizeof(flags[0]));
603 static void DDRAW_dump_DWORD(const void *in) {
604 DPRINTF("%ld", *((const DWORD *) in));
606 static void DDRAW_dump_PTR(const void *in) {
607 DPRINTF("%p", *((const void * const*) in));
609 void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) {
610 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
613 void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
615 #define STRUCT DDSURFACEDESC2
616 static const member_info members[] =
618 ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight),
619 ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth),
620 ME(DDSD_PITCH, DDRAW_dump_DWORD, u1.lPitch),
621 ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize),
622 ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
623 ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount),
624 ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2.dwMipMapCount), /* This is for 'old-style' D3D */
625 ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate),
626 ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
627 ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),
628 ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3.ddckCKDestOverlay),
629 ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt),
630 ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay),
631 ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt),
632 ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4.ddpfPixelFormat)
634 static const member_info members_caps[] =
636 ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps)
638 static const member_info members_caps2[] =
640 ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps)
644 if (NULL == lpddsd) {
647 if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) {
648 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1);
650 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
652 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
653 sizeof(members)/sizeof(members[0]));
657 void DDRAW_dump_cooperativelevel(DWORD cooplevel)
659 static const flag_info flags[] =
661 FE(DDSCL_FULLSCREEN),
662 FE(DDSCL_ALLOWREBOOT),
663 FE(DDSCL_NOWINDOWCHANGES),
665 FE(DDSCL_ALLOWMODEX),
667 FE(DDSCL_SETFOCUSWINDOW),
668 FE(DDSCL_SETDEVICEWINDOW),
669 FE(DDSCL_CREATEDEVICEWINDOW)
675 DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
679 void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) {
680 static const flag_info flags1[] = {
682 FE(DDCAPS_ALIGNBOUNDARYDEST),
683 FE(DDCAPS_ALIGNSIZEDEST),
684 FE(DDCAPS_ALIGNBOUNDARYSRC),
685 FE(DDCAPS_ALIGNSIZESRC),
686 FE(DDCAPS_ALIGNSTRIDE),
689 FE(DDCAPS_BLTFOURCC),
690 FE(DDCAPS_BLTSTRETCH),
693 FE(DDCAPS_OVERLAYCANTCLIP),
694 FE(DDCAPS_OVERLAYFOURCC),
695 FE(DDCAPS_OVERLAYSTRETCH),
697 FE(DDCAPS_PALETTEVSYNC),
698 FE(DDCAPS_READSCANLINE),
699 FE(DDCAPS_STEREOVIEW),
702 FE(DDCAPS_ZOVERLAYS),
705 FE(DDCAPS_COLORKEYHWASSIST),
706 FE(DDCAPS_NOHARDWARE),
707 FE(DDCAPS_BLTCOLORFILL),
708 FE(DDCAPS_BANKSWITCHED),
709 FE(DDCAPS_BLTDEPTHFILL),
711 FE(DDCAPS_CANCLIPSTRETCHED),
712 FE(DDCAPS_CANBLTSYSMEM)
714 static const flag_info flags2[] = {
715 FE(DDCAPS2_CERTIFIED),
716 FE(DDCAPS2_NO2DDURING3DSCENE),
717 FE(DDCAPS2_VIDEOPORT),
718 FE(DDCAPS2_AUTOFLIPOVERLAY),
719 FE(DDCAPS2_CANBOBINTERLEAVED),
720 FE(DDCAPS2_CANBOBNONINTERLEAVED),
721 FE(DDCAPS2_COLORCONTROLOVERLAY),
722 FE(DDCAPS2_COLORCONTROLPRIMARY),
723 FE(DDCAPS2_CANDROPZ16BIT),
724 FE(DDCAPS2_NONLOCALVIDMEM),
725 FE(DDCAPS2_NONLOCALVIDMEMCAPS),
726 FE(DDCAPS2_NOPAGELOCKREQUIRED),
727 FE(DDCAPS2_WIDESURFACES),
728 FE(DDCAPS2_CANFLIPODDEVEN),
729 FE(DDCAPS2_CANBOBHARDWARE),
730 FE(DDCAPS2_COPYFOURCC),
731 FE(DDCAPS2_PRIMARYGAMMA),
732 FE(DDCAPS2_CANRENDERWINDOWED),
733 FE(DDCAPS2_CANCALIBRATEGAMMA),
734 FE(DDCAPS2_FLIPINTERVAL),
735 FE(DDCAPS2_FLIPNOVSYNC),
736 FE(DDCAPS2_CANMANAGETEXTURE),
737 FE(DDCAPS2_TEXMANINNONLOCALVIDMEM),
739 FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL)
741 static const flag_info flags3[] = {
742 FE(DDCKEYCAPS_DESTBLT),
743 FE(DDCKEYCAPS_DESTBLTCLRSPACE),
744 FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV),
745 FE(DDCKEYCAPS_DESTBLTYUV),
746 FE(DDCKEYCAPS_DESTOVERLAY),
747 FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE),
748 FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV),
749 FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE),
750 FE(DDCKEYCAPS_DESTOVERLAYYUV),
751 FE(DDCKEYCAPS_SRCBLT),
752 FE(DDCKEYCAPS_SRCBLTCLRSPACE),
753 FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV),
754 FE(DDCKEYCAPS_SRCBLTYUV),
755 FE(DDCKEYCAPS_SRCOVERLAY),
756 FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE),
757 FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV),
758 FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE),
759 FE(DDCKEYCAPS_SRCOVERLAYYUV),
760 FE(DDCKEYCAPS_NOCOSTOVERLAY)
762 static const flag_info flags4[] = {
763 FE(DDFXCAPS_BLTALPHA),
764 FE(DDFXCAPS_OVERLAYALPHA),
765 FE(DDFXCAPS_BLTARITHSTRETCHYN),
766 FE(DDFXCAPS_BLTARITHSTRETCHY),
767 FE(DDFXCAPS_BLTMIRRORLEFTRIGHT),
768 FE(DDFXCAPS_BLTMIRRORUPDOWN),
769 FE(DDFXCAPS_BLTROTATION),
770 FE(DDFXCAPS_BLTROTATION90),
771 FE(DDFXCAPS_BLTSHRINKX),
772 FE(DDFXCAPS_BLTSHRINKXN),
773 FE(DDFXCAPS_BLTSHRINKY),
774 FE(DDFXCAPS_BLTSHRINKYN),
775 FE(DDFXCAPS_BLTSTRETCHX),
776 FE(DDFXCAPS_BLTSTRETCHXN),
777 FE(DDFXCAPS_BLTSTRETCHY),
778 FE(DDFXCAPS_BLTSTRETCHYN),
779 FE(DDFXCAPS_OVERLAYARITHSTRETCHY),
780 FE(DDFXCAPS_OVERLAYARITHSTRETCHYN),
781 FE(DDFXCAPS_OVERLAYSHRINKX),
782 FE(DDFXCAPS_OVERLAYSHRINKXN),
783 FE(DDFXCAPS_OVERLAYSHRINKY),
784 FE(DDFXCAPS_OVERLAYSHRINKYN),
785 FE(DDFXCAPS_OVERLAYSTRETCHX),
786 FE(DDFXCAPS_OVERLAYSTRETCHXN),
787 FE(DDFXCAPS_OVERLAYSTRETCHY),
788 FE(DDFXCAPS_OVERLAYSTRETCHYN),
789 FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT),
790 FE(DDFXCAPS_OVERLAYMIRRORUPDOWN)
792 static const flag_info flags5[] = {
793 FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND),
794 FE(DDFXALPHACAPS_BLTALPHAPIXELS),
795 FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG),
796 FE(DDFXALPHACAPS_BLTALPHASURFACES),
797 FE(DDFXALPHACAPS_BLTALPHASURFACESNEG),
798 FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND),
799 FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS),
800 FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG),
801 FE(DDFXALPHACAPS_OVERLAYALPHASURFACES),
802 FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG)
804 static const flag_info flags6[] = {
806 FE(DDPCAPS_8BITENTRIES),
808 FE(DDPCAPS_INITIALIZE),
809 FE(DDPCAPS_PRIMARYSURFACE),
810 FE(DDPCAPS_PRIMARYSURFACELEFT),
811 FE(DDPCAPS_ALLOW256),
817 static const flag_info flags7[] = {
818 FE(DDSVCAPS_RESERVED1),
819 FE(DDSVCAPS_RESERVED2),
820 FE(DDSVCAPS_RESERVED3),
821 FE(DDSVCAPS_RESERVED4),
822 FE(DDSVCAPS_STEREOSEQUENTIAL),
825 DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize);
826 DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
827 DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
828 DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
829 DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
830 DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
831 DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
832 DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
834 DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes);
835 DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays);
836 DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch);
837 DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
839 DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
842 void DDRAW_dump_DDENUMSURFACES(DWORD flagmask)
844 static const flag_info flags[] =
846 FE(DDENUMSURFACES_ALL),
847 FE(DDENUMSURFACES_MATCH),
848 FE(DDENUMSURFACES_NOMATCH),
849 FE(DDENUMSURFACES_CANBECREATED),
850 FE(DDENUMSURFACES_DOESEXIST)
852 DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
855 /* Debug function that can be helpful to debug various surface-related problems */
856 static int get_shift(DWORD color_mask) {
858 while (color_mask > 0xFF) {
862 while ((color_mask & 0x80) == 0) {
869 void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale)
871 int rwidth, rheight, x, y;
872 static char *output = NULL;
875 rwidth = (surface->surface_desc.dwWidth + scale - 1) / scale;
876 rheight = (surface->surface_desc.dwHeight + scale - 1) / scale;
879 output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rwidth * 3);
883 fprintf(f, "P6\n%d %d\n255\n", rwidth, rheight);
885 if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
886 unsigned char table[256][3];
889 if (surface->palette == NULL) {
893 for (i = 0; i < 256; i++) {
894 table[i][0] = surface->palette->palents[i].peRed;
895 table[i][1] = surface->palette->palents[i].peGreen;
896 table[i][2] = surface->palette->palents[i].peBlue;
898 for (y = 0; y < rheight; y++) {
899 unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
900 for (x = 0; x < rwidth; x++) {
901 unsigned char color = *src;
904 output[3 * x + 0] = table[color][0];
905 output[3 * x + 1] = table[color][1];
906 output[3 * x + 2] = table[color][2];
908 fwrite(output, 3 * rwidth, 1, f);
910 } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
911 int red_shift, green_shift, blue_shift, pix_width;
913 if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
915 } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
917 } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
923 red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask);
924 green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask);
925 blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask);
927 for (y = 0; y < rheight; y++) {
928 unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
929 for (x = 0; x < rwidth; x++) {
935 for (i = 0; i < pix_width; i++) {
936 color |= src[i] << (8 * i);
938 src += scale * pix_width;
940 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
941 output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
942 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
943 output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
944 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
945 output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
947 fwrite(output, 3 * rwidth, 1, f);