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),
411 DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
414 void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
416 static const flag_info flags[] = {
417 FE(DDSCAPS_RESERVED1),
419 FE(DDSCAPS_BACKBUFFER),
422 FE(DDSCAPS_FRONTBUFFER),
423 FE(DDSCAPS_OFFSCREENPLAIN),
426 FE(DDSCAPS_PRIMARYSURFACE),
427 FE(DDSCAPS_PRIMARYSURFACELEFT),
428 FE(DDSCAPS_SYSTEMMEMORY),
430 FE(DDSCAPS_3DDEVICE),
431 FE(DDSCAPS_VIDEOMEMORY),
433 FE(DDSCAPS_WRITEONLY),
436 FE(DDSCAPS_LIVEVIDEO),
440 FE(DDSCAPS_RESERVED2),
441 FE(DDSCAPS_ALLOCONLOAD),
442 FE(DDSCAPS_VIDEOPORT),
443 FE(DDSCAPS_LOCALVIDMEM),
444 FE(DDSCAPS_NONLOCALVIDMEM),
445 FE(DDSCAPS_STANDARDVGAMODE),
446 FE(DDSCAPS_OPTIMIZED)
448 static const flag_info flags2[] = {
449 FE(DDSCAPS2_HARDWAREDEINTERLACE),
450 FE(DDSCAPS2_HINTDYNAMIC),
451 FE(DDSCAPS2_HINTSTATIC),
452 FE(DDSCAPS2_TEXTUREMANAGE),
453 FE(DDSCAPS2_RESERVED1),
454 FE(DDSCAPS2_RESERVED2),
456 FE(DDSCAPS2_HINTANTIALIASING),
457 FE(DDSCAPS2_CUBEMAP),
458 FE(DDSCAPS2_CUBEMAP_POSITIVEX),
459 FE(DDSCAPS2_CUBEMAP_NEGATIVEX),
460 FE(DDSCAPS2_CUBEMAP_POSITIVEY),
461 FE(DDSCAPS2_CUBEMAP_NEGATIVEY),
462 FE(DDSCAPS2_CUBEMAP_POSITIVEZ),
463 FE(DDSCAPS2_CUBEMAP_NEGATIVEZ),
464 FE(DDSCAPS2_MIPMAPSUBLEVEL),
465 FE(DDSCAPS2_D3DTEXTUREMANAGE),
466 FE(DDSCAPS2_DONOTPERSIST),
467 FE(DDSCAPS2_STEREOSURFACELEFT)
470 DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0);
471 DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0);
474 void DDRAW_dump_DDSCAPS(const DDSCAPS *in) {
477 in_bis.dwCaps = in->dwCaps;
482 DDRAW_dump_DDSCAPS2(&in_bis);
485 void DDRAW_dump_pixelformat_flag(DWORD flagmask)
487 static const flag_info flags[] =
489 FE(DDPF_ALPHAPIXELS),
492 FE(DDPF_PALETTEINDEXED4),
493 FE(DDPF_PALETTEINDEXEDTO8),
494 FE(DDPF_PALETTEINDEXED8),
500 FE(DDPF_PALETTEINDEXED1),
501 FE(DDPF_PALETTEINDEXED2),
505 DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0);
508 void DDRAW_dump_paletteformat(DWORD dwFlags)
510 static const flag_info flags[] =
513 FE(DDPCAPS_8BITENTRIES),
515 FE(DDPCAPS_INITIALIZE),
516 FE(DDPCAPS_PRIMARYSURFACE),
517 FE(DDPCAPS_PRIMARYSURFACELEFT),
518 FE(DDPCAPS_ALLOW256),
525 DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
528 void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) {
530 DDRAW_dump_pixelformat_flag(pf->dwFlags);
531 if (pf->dwFlags & DDPF_FOURCC) {
532 DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
533 (unsigned char)( pf->dwFourCC &0xff),
534 (unsigned char)((pf->dwFourCC>> 8)&0xff),
535 (unsigned char)((pf->dwFourCC>>16)&0xff),
536 (unsigned char)((pf->dwFourCC>>24)&0xff),
541 if (pf->dwFlags & DDPF_RGB) {
543 DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount);
544 switch (pf->u1.dwRGBBitCount) {
545 case 4: cmd = "%1lx"; break;
546 case 8: cmd = "%02lx"; break;
547 case 16: cmd = "%04lx"; break;
548 case 24: cmd = "%06lx"; break;
549 case 32: cmd = "%08lx"; break;
550 default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
552 DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask);
553 DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask);
554 DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask);
555 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
556 DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask);
558 if (pf->dwFlags & DDPF_ZPIXELS) {
559 DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask);
562 if (pf->dwFlags & DDPF_ZBUFFER) {
563 DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth);
565 if (pf->dwFlags & DDPF_ALPHA) {
566 DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth);
571 void DDRAW_dump_colorkeyflag(DWORD ck)
573 static const flag_info flags[] =
575 FE(DDCKEY_COLORSPACE),
577 FE(DDCKEY_DESTOVERLAY),
579 FE(DDCKEY_SRCOVERLAY)
582 DDRAW_dump_flags(ck, flags, sizeof(flags)/sizeof(flags[0]));
585 void DDRAW_dump_lockflag(DWORD lockflag)
587 static const flag_info flags[] =
589 FE(DDLOCK_SURFACEMEMORYPTR),
593 FE(DDLOCK_WRITEONLY),
594 FE(DDLOCK_NOSYSLOCK),
595 FE(DDLOCK_DISCARDCONTENTS),
596 FE(DDLOCK_NOOVERWRITE)
599 DDRAW_dump_flags(lockflag, flags, sizeof(flags)/sizeof(flags[0]));
602 static void DDRAW_dump_DWORD(const void *in) {
603 DPRINTF("%ld", *((const DWORD *) in));
605 static void DDRAW_dump_PTR(const void *in) {
606 DPRINTF("%p", *((const void * const*) in));
608 void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) {
609 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
612 void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
614 #define STRUCT DDSURFACEDESC2
615 static const member_info members[] =
617 ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight),
618 ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth),
619 ME(DDSD_PITCH, DDRAW_dump_DWORD, u1.lPitch),
620 ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize),
621 ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
622 ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount),
623 ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2.dwMipMapCount), /* This is for 'old-style' D3D */
624 ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate),
625 ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
626 ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),
627 ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3.ddckCKDestOverlay),
628 ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt),
629 ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay),
630 ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt),
631 ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4.ddpfPixelFormat)
633 static const member_info members_caps[] =
635 ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps)
637 static const member_info members_caps2[] =
639 ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps)
643 if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) {
644 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1);
646 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
649 DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
650 sizeof(members)/sizeof(members[0]));
653 void DDRAW_dump_cooperativelevel(DWORD cooplevel)
655 static const flag_info flags[] =
657 FE(DDSCL_FULLSCREEN),
658 FE(DDSCL_ALLOWREBOOT),
659 FE(DDSCL_NOWINDOWCHANGES),
661 FE(DDSCL_ALLOWMODEX),
663 FE(DDSCL_SETFOCUSWINDOW),
664 FE(DDSCL_SETDEVICEWINDOW),
665 FE(DDSCL_CREATEDEVICEWINDOW)
671 DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
675 void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) {
676 static const flag_info flags1[] = {
678 FE(DDCAPS_ALIGNBOUNDARYDEST),
679 FE(DDCAPS_ALIGNSIZEDEST),
680 FE(DDCAPS_ALIGNBOUNDARYSRC),
681 FE(DDCAPS_ALIGNSIZESRC),
682 FE(DDCAPS_ALIGNSTRIDE),
685 FE(DDCAPS_BLTFOURCC),
686 FE(DDCAPS_BLTSTRETCH),
689 FE(DDCAPS_OVERLAYCANTCLIP),
690 FE(DDCAPS_OVERLAYFOURCC),
691 FE(DDCAPS_OVERLAYSTRETCH),
693 FE(DDCAPS_PALETTEVSYNC),
694 FE(DDCAPS_READSCANLINE),
695 FE(DDCAPS_STEREOVIEW),
698 FE(DDCAPS_ZOVERLAYS),
701 FE(DDCAPS_COLORKEYHWASSIST),
702 FE(DDCAPS_NOHARDWARE),
703 FE(DDCAPS_BLTCOLORFILL),
704 FE(DDCAPS_BANKSWITCHED),
705 FE(DDCAPS_BLTDEPTHFILL),
707 FE(DDCAPS_CANCLIPSTRETCHED),
708 FE(DDCAPS_CANBLTSYSMEM)
710 static const flag_info flags2[] = {
711 FE(DDCAPS2_CERTIFIED),
712 FE(DDCAPS2_NO2DDURING3DSCENE),
713 FE(DDCAPS2_VIDEOPORT),
714 FE(DDCAPS2_AUTOFLIPOVERLAY),
715 FE(DDCAPS2_CANBOBINTERLEAVED),
716 FE(DDCAPS2_CANBOBNONINTERLEAVED),
717 FE(DDCAPS2_COLORCONTROLOVERLAY),
718 FE(DDCAPS2_COLORCONTROLPRIMARY),
719 FE(DDCAPS2_CANDROPZ16BIT),
720 FE(DDCAPS2_NONLOCALVIDMEM),
721 FE(DDCAPS2_NONLOCALVIDMEMCAPS),
722 FE(DDCAPS2_NOPAGELOCKREQUIRED),
723 FE(DDCAPS2_WIDESURFACES),
724 FE(DDCAPS2_CANFLIPODDEVEN),
725 FE(DDCAPS2_CANBOBHARDWARE),
726 FE(DDCAPS2_COPYFOURCC),
727 FE(DDCAPS2_PRIMARYGAMMA),
728 FE(DDCAPS2_CANRENDERWINDOWED),
729 FE(DDCAPS2_CANCALIBRATEGAMMA),
730 FE(DDCAPS2_FLIPINTERVAL),
731 FE(DDCAPS2_FLIPNOVSYNC),
732 FE(DDCAPS2_CANMANAGETEXTURE),
733 FE(DDCAPS2_TEXMANINNONLOCALVIDMEM),
735 FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL)
737 static const flag_info flags3[] = {
738 FE(DDCKEYCAPS_DESTBLT),
739 FE(DDCKEYCAPS_DESTBLTCLRSPACE),
740 FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV),
741 FE(DDCKEYCAPS_DESTBLTYUV),
742 FE(DDCKEYCAPS_DESTOVERLAY),
743 FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE),
744 FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV),
745 FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE),
746 FE(DDCKEYCAPS_DESTOVERLAYYUV),
747 FE(DDCKEYCAPS_SRCBLT),
748 FE(DDCKEYCAPS_SRCBLTCLRSPACE),
749 FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV),
750 FE(DDCKEYCAPS_SRCBLTYUV),
751 FE(DDCKEYCAPS_SRCOVERLAY),
752 FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE),
753 FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV),
754 FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE),
755 FE(DDCKEYCAPS_SRCOVERLAYYUV),
756 FE(DDCKEYCAPS_NOCOSTOVERLAY)
758 static const flag_info flags4[] = {
759 FE(DDFXCAPS_BLTALPHA),
760 FE(DDFXCAPS_OVERLAYALPHA),
761 FE(DDFXCAPS_BLTARITHSTRETCHYN),
762 FE(DDFXCAPS_BLTARITHSTRETCHY),
763 FE(DDFXCAPS_BLTMIRRORLEFTRIGHT),
764 FE(DDFXCAPS_BLTMIRRORUPDOWN),
765 FE(DDFXCAPS_BLTROTATION),
766 FE(DDFXCAPS_BLTROTATION90),
767 FE(DDFXCAPS_BLTSHRINKX),
768 FE(DDFXCAPS_BLTSHRINKXN),
769 FE(DDFXCAPS_BLTSHRINKY),
770 FE(DDFXCAPS_BLTSHRINKYN),
771 FE(DDFXCAPS_BLTSTRETCHX),
772 FE(DDFXCAPS_BLTSTRETCHXN),
773 FE(DDFXCAPS_BLTSTRETCHY),
774 FE(DDFXCAPS_BLTSTRETCHYN),
775 FE(DDFXCAPS_OVERLAYARITHSTRETCHY),
776 FE(DDFXCAPS_OVERLAYARITHSTRETCHYN),
777 FE(DDFXCAPS_OVERLAYSHRINKX),
778 FE(DDFXCAPS_OVERLAYSHRINKXN),
779 FE(DDFXCAPS_OVERLAYSHRINKY),
780 FE(DDFXCAPS_OVERLAYSHRINKYN),
781 FE(DDFXCAPS_OVERLAYSTRETCHX),
782 FE(DDFXCAPS_OVERLAYSTRETCHXN),
783 FE(DDFXCAPS_OVERLAYSTRETCHY),
784 FE(DDFXCAPS_OVERLAYSTRETCHYN),
785 FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT),
786 FE(DDFXCAPS_OVERLAYMIRRORUPDOWN)
788 static const flag_info flags5[] = {
789 FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND),
790 FE(DDFXALPHACAPS_BLTALPHAPIXELS),
791 FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG),
792 FE(DDFXALPHACAPS_BLTALPHASURFACES),
793 FE(DDFXALPHACAPS_BLTALPHASURFACESNEG),
794 FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND),
795 FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS),
796 FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG),
797 FE(DDFXALPHACAPS_OVERLAYALPHASURFACES),
798 FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG)
800 static const flag_info flags6[] = {
802 FE(DDPCAPS_8BITENTRIES),
804 FE(DDPCAPS_INITIALIZE),
805 FE(DDPCAPS_PRIMARYSURFACE),
806 FE(DDPCAPS_PRIMARYSURFACELEFT),
807 FE(DDPCAPS_ALLOW256),
813 static const flag_info flags7[] = {
814 FE(DDSVCAPS_RESERVED1),
815 FE(DDSVCAPS_RESERVED2),
816 FE(DDSVCAPS_RESERVED3),
817 FE(DDSVCAPS_RESERVED4),
818 FE(DDSVCAPS_STEREOSEQUENTIAL),
821 DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize);
822 DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
823 DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
824 DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
825 DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
826 DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
827 DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
828 DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
830 DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes);
831 DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays);
832 DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch);
833 DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
835 DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
838 /* Debug function that can be helpful to debug various surface-related problems */
839 static int get_shift(DWORD color_mask) {
841 while (color_mask > 0xFF) {
845 while ((color_mask & 0x80) == 0) {
852 void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale)
854 int rwidth, rheight, x, y;
855 static char *output = NULL;
858 rwidth = (surface->surface_desc.dwWidth + scale - 1) / scale;
859 rheight = (surface->surface_desc.dwHeight + scale - 1) / scale;
862 output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rwidth * 3);
866 fprintf(f, "P6\n%d %d\n255\n", rwidth, rheight);
868 if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
869 unsigned char table[256][3];
872 if (surface->palette == NULL) {
876 for (i = 0; i < 256; i++) {
877 table[i][0] = surface->palette->palents[i].peRed;
878 table[i][1] = surface->palette->palents[i].peGreen;
879 table[i][2] = surface->palette->palents[i].peBlue;
881 for (y = 0; y < rheight; y++) {
882 unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
883 for (x = 0; x < rwidth; x++) {
884 unsigned char color = *src;
887 output[3 * x + 0] = table[color][0];
888 output[3 * x + 1] = table[color][1];
889 output[3 * x + 2] = table[color][2];
891 fwrite(output, 3 * rwidth, 1, f);
893 } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
894 int red_shift, green_shift, blue_shift, pix_width;
896 if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
898 } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
900 } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
906 red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask);
907 green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask);
908 blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask);
910 for (y = 0; y < rheight; y++) {
911 unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
912 for (x = 0; x < rwidth; x++) {
918 for (i = 0; i < pix_width; i++) {
919 color |= src[i] << (8 * i);
921 src += scale * pix_width;
923 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
924 output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
925 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
926 output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
927 comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
928 output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
930 fwrite(output, 3 * rwidth, 1, f);