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
);