Fix miscellaneous spelling errors and typos.
[wine] / dlls / ddraw / helper.c
1
2 /*              DirectDraw Base Functions
3  *
4  * Copyright 1997-1999 Marcus Meissner
5  * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
6  * Copyright 2000 TransGaming Technologies Inc.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <stddef.h>
27 #include <stdio.h>
28
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
31 #include "d3d.h"
32 #include "ddraw.h"
33 #include "winerror.h"
34
35 #include "wine/exception.h"
36 #include "ddraw_private.h"
37
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
41
42 /******************************************************************************
43  *              debug output functions
44  */
45 void DDRAW_dump_flags_(DWORD flags, const flag_info* names,
46                        size_t num_names, int newline)
47 {
48     unsigned int        i;
49
50     for (i=0; i < num_names; i++)
51         if ((flags & names[i].val) ||      /* standard flag value */
52             ((!flags) && (!names[i].val))) /* zero value only */
53             DPRINTF("%s ", names[i].name);
54
55     if (newline)
56         DPRINTF("\n");
57 }
58
59 void DDRAW_dump_members(DWORD flags, const void* data,
60                         const member_info* mems, size_t num_mems)
61 {
62     unsigned int i;
63
64     for (i=0; i < num_mems; i++)
65     {
66         if (mems[i].val & flags)
67         {
68             DPRINTF(" - %s : ", mems[i].name);
69             mems[i].func((const char *)data + mems[i].offset);
70             DPRINTF("\n");
71         }
72     }
73 }
74
75 void DDRAW_dump_DDBLTFX(DWORD flagmask)
76 {
77     static const flag_info flags[] =
78         {
79             FE(DDBLTFX_ARITHSTRETCHY),
80             FE(DDBLTFX_MIRRORLEFTRIGHT),
81             FE(DDBLTFX_MIRRORUPDOWN),
82             FE(DDBLTFX_NOTEARING),
83             FE(DDBLTFX_ROTATE180),
84             FE(DDBLTFX_ROTATE270),
85             FE(DDBLTFX_ROTATE90),
86             FE(DDBLTFX_ZBUFFERRANGE),
87             FE(DDBLTFX_ZBUFFERBASEDEST)
88         };
89
90     DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
91 }
92
93 void DDRAW_dump_DDBLTFAST(DWORD flagmask)
94 {
95     static const flag_info flags[] =
96         {
97             FE(DDBLTFAST_NOCOLORKEY),
98             FE(DDBLTFAST_SRCCOLORKEY),
99             FE(DDBLTFAST_DESTCOLORKEY),
100             FE(DDBLTFAST_WAIT)
101         };
102
103     DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
104 }
105
106 void DDRAW_dump_DDBLT(DWORD flagmask)
107 {
108     static const flag_info flags[] =
109         {
110             FE(DDBLT_ALPHADEST),
111             FE(DDBLT_ALPHADESTCONSTOVERRIDE),
112             FE(DDBLT_ALPHADESTNEG),
113             FE(DDBLT_ALPHADESTSURFACEOVERRIDE),
114             FE(DDBLT_ALPHAEDGEBLEND),
115             FE(DDBLT_ALPHASRC),
116             FE(DDBLT_ALPHASRCCONSTOVERRIDE),
117             FE(DDBLT_ALPHASRCNEG),
118             FE(DDBLT_ALPHASRCSURFACEOVERRIDE),
119             FE(DDBLT_ASYNC),
120             FE(DDBLT_COLORFILL),
121             FE(DDBLT_DDFX),
122             FE(DDBLT_DDROPS),
123             FE(DDBLT_KEYDEST),
124             FE(DDBLT_KEYDESTOVERRIDE),
125             FE(DDBLT_KEYSRC),
126             FE(DDBLT_KEYSRCOVERRIDE),
127             FE(DDBLT_ROP),
128             FE(DDBLT_ROTATIONANGLE),
129             FE(DDBLT_ZBUFFER),
130             FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE),
131             FE(DDBLT_ZBUFFERDESTOVERRIDE),
132             FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE),
133             FE(DDBLT_ZBUFFERSRCOVERRIDE),
134             FE(DDBLT_WAIT),
135             FE(DDBLT_DEPTHFILL)
136     };
137
138     DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0]));
139 }
140
141 void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in)
142 {
143     static const flag_info flags[] = {
144         FE(DDSCAPS_RESERVED1),
145         FE(DDSCAPS_ALPHA),
146         FE(DDSCAPS_BACKBUFFER),
147         FE(DDSCAPS_COMPLEX),
148         FE(DDSCAPS_FLIP),
149         FE(DDSCAPS_FRONTBUFFER),
150         FE(DDSCAPS_OFFSCREENPLAIN),
151         FE(DDSCAPS_OVERLAY),
152         FE(DDSCAPS_PALETTE),
153         FE(DDSCAPS_PRIMARYSURFACE),
154         FE(DDSCAPS_PRIMARYSURFACELEFT),
155         FE(DDSCAPS_SYSTEMMEMORY),
156         FE(DDSCAPS_TEXTURE),
157         FE(DDSCAPS_3DDEVICE),
158         FE(DDSCAPS_VIDEOMEMORY),
159         FE(DDSCAPS_VISIBLE),
160         FE(DDSCAPS_WRITEONLY),
161         FE(DDSCAPS_ZBUFFER),
162         FE(DDSCAPS_OWNDC),
163         FE(DDSCAPS_LIVEVIDEO),
164         FE(DDSCAPS_HWCODEC),
165         FE(DDSCAPS_MODEX),
166         FE(DDSCAPS_MIPMAP),
167         FE(DDSCAPS_RESERVED2),
168         FE(DDSCAPS_ALLOCONLOAD),
169         FE(DDSCAPS_VIDEOPORT),
170         FE(DDSCAPS_LOCALVIDMEM),
171         FE(DDSCAPS_NONLOCALVIDMEM),
172         FE(DDSCAPS_STANDARDVGAMODE),
173         FE(DDSCAPS_OPTIMIZED)
174     };
175     static const flag_info flags2[] = {
176         FE(DDSCAPS2_HARDWAREDEINTERLACE),
177         FE(DDSCAPS2_HINTDYNAMIC),
178         FE(DDSCAPS2_HINTSTATIC),
179         FE(DDSCAPS2_TEXTUREMANAGE),
180         FE(DDSCAPS2_RESERVED1),
181         FE(DDSCAPS2_RESERVED2),
182         FE(DDSCAPS2_OPAQUE),
183         FE(DDSCAPS2_HINTANTIALIASING),
184         FE(DDSCAPS2_CUBEMAP),
185         FE(DDSCAPS2_CUBEMAP_POSITIVEX),
186         FE(DDSCAPS2_CUBEMAP_NEGATIVEX),
187         FE(DDSCAPS2_CUBEMAP_POSITIVEY),
188         FE(DDSCAPS2_CUBEMAP_NEGATIVEY),
189         FE(DDSCAPS2_CUBEMAP_POSITIVEZ),
190         FE(DDSCAPS2_CUBEMAP_NEGATIVEZ),
191         FE(DDSCAPS2_MIPMAPSUBLEVEL),
192         FE(DDSCAPS2_D3DTEXTUREMANAGE),
193         FE(DDSCAPS2_DONOTPERSIST),
194         FE(DDSCAPS2_STEREOSURFACELEFT)
195     };
196  
197     DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0);
198     DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0);
199 }
200
201 void DDRAW_dump_DDSCAPS(const DDSCAPS *in) {
202     DDSCAPS2 in_bis;
203
204     in_bis.dwCaps = in->dwCaps;
205     in_bis.dwCaps2 = 0;
206     in_bis.dwCaps3 = 0;
207     in_bis.dwCaps4 = 0;
208
209     DDRAW_dump_DDSCAPS2(&in_bis);
210 }
211
212 void DDRAW_dump_pixelformat_flag(DWORD flagmask)
213 {
214     static const flag_info flags[] =
215         {
216             FE(DDPF_ALPHAPIXELS),
217             FE(DDPF_ALPHA),
218             FE(DDPF_FOURCC),
219             FE(DDPF_PALETTEINDEXED4),
220             FE(DDPF_PALETTEINDEXEDTO8),
221             FE(DDPF_PALETTEINDEXED8),
222             FE(DDPF_RGB),
223             FE(DDPF_COMPRESSED),
224             FE(DDPF_RGBTOYUV),
225             FE(DDPF_YUV),
226             FE(DDPF_ZBUFFER),
227             FE(DDPF_PALETTEINDEXED1),
228             FE(DDPF_PALETTEINDEXED2),
229             FE(DDPF_ZPIXELS)
230     };
231
232     DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0);
233 }
234
235 void DDRAW_dump_paletteformat(DWORD dwFlags)
236 {
237     static const flag_info flags[] =
238         {
239             FE(DDPCAPS_4BIT),
240             FE(DDPCAPS_8BITENTRIES),
241             FE(DDPCAPS_8BIT),
242             FE(DDPCAPS_INITIALIZE),
243             FE(DDPCAPS_PRIMARYSURFACE),
244             FE(DDPCAPS_PRIMARYSURFACELEFT),
245             FE(DDPCAPS_ALLOW256),
246             FE(DDPCAPS_VSYNC),
247             FE(DDPCAPS_1BIT),
248             FE(DDPCAPS_2BIT),
249             FE(DDPCAPS_ALPHA)
250     };
251
252     DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
253 }
254
255 void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) {
256     DPRINTF("( ");
257     DDRAW_dump_pixelformat_flag(pf->dwFlags);
258     if (pf->dwFlags & DDPF_FOURCC) {
259         DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
260                 (unsigned char)( pf->dwFourCC     &0xff),
261                 (unsigned char)((pf->dwFourCC>> 8)&0xff),
262                 (unsigned char)((pf->dwFourCC>>16)&0xff),
263                 (unsigned char)((pf->dwFourCC>>24)&0xff),
264                 pf->dwFourCC,
265                 pf->u1.dwYUVBitCount
266         );
267     }
268     if (pf->dwFlags & DDPF_RGB) {
269         char *cmd;
270         DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount);
271         switch (pf->u1.dwRGBBitCount) {
272         case 4: cmd = "%1lx"; break;
273         case 8: cmd = "%02lx"; break;
274         case 16: cmd = "%04lx"; break;
275         case 24: cmd = "%06lx"; break;
276         case 32: cmd = "%08lx"; break;
277         default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
278         }
279         DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask);
280         DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask);
281         DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask);
282         if (pf->dwFlags & DDPF_ALPHAPIXELS) {
283             DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask);
284         }
285         if (pf->dwFlags & DDPF_ZPIXELS) {
286             DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask);
287         }
288     }
289     if (pf->dwFlags & DDPF_ZBUFFER) {
290         DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth);
291     }
292     if (pf->dwFlags & DDPF_ALPHA) {
293         DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth);
294     }
295     DPRINTF(")");
296 }
297
298 void DDRAW_dump_colorkeyflag(DWORD ck)
299 {
300     static const flag_info flags[] =
301         {
302             FE(DDCKEY_COLORSPACE),
303             FE(DDCKEY_DESTBLT),
304             FE(DDCKEY_DESTOVERLAY),
305             FE(DDCKEY_SRCBLT),
306             FE(DDCKEY_SRCOVERLAY)
307     };
308
309     DDRAW_dump_flags(ck, flags, sizeof(flags)/sizeof(flags[0]));
310 }
311
312 void DDRAW_dump_lockflag(DWORD lockflag)
313 {
314     static const flag_info flags[] =
315         {
316             FE(DDLOCK_SURFACEMEMORYPTR),
317             FE(DDLOCK_WAIT),
318             FE(DDLOCK_EVENT),
319             FE(DDLOCK_READONLY),
320             FE(DDLOCK_WRITEONLY),
321             FE(DDLOCK_NOSYSLOCK),
322             FE(DDLOCK_DISCARDCONTENTS),
323             FE(DDLOCK_NOOVERWRITE)
324         };
325
326     DDRAW_dump_flags(lockflag, flags, sizeof(flags)/sizeof(flags[0]));
327 }
328
329 static void DDRAW_dump_DWORD(const void *in) {
330     DPRINTF("%ld", *((const DWORD *) in));
331 }
332 static void DDRAW_dump_PTR(const void *in) {
333     DPRINTF("%p", *((const void **) in));
334 }
335 void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) {
336     DPRINTF(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
337 }
338
339 void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
340 {
341 #define STRUCT DDSURFACEDESC2
342     static const member_info members[] =
343         {
344             ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight),
345             ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth),
346             ME(DDSD_PITCH, DDRAW_dump_DWORD, u1.lPitch),
347             ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize),
348             ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
349             ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount),
350             ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate),
351             ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
352             ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),
353             ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3.ddckCKDestOverlay),
354             ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt),
355             ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay),
356             ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt),
357             ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4.ddpfPixelFormat)
358         };
359     static const member_info members_caps[] =
360         {
361             ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps)
362         };
363     static const member_info members_caps2[] =
364         {
365             ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps)
366         };
367 #undef STRUCT
368
369     if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) {
370         DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1);
371     } else {
372         DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1);
373     }
374                                                   
375     DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members,
376                        sizeof(members)/sizeof(members[0]));
377 }
378
379 void DDRAW_dump_cooperativelevel(DWORD cooplevel)
380 {
381     static const flag_info flags[] =
382         {
383             FE(DDSCL_FULLSCREEN),
384             FE(DDSCL_ALLOWREBOOT),
385             FE(DDSCL_NOWINDOWCHANGES),
386             FE(DDSCL_NORMAL),
387             FE(DDSCL_ALLOWMODEX),
388             FE(DDSCL_EXCLUSIVE),
389             FE(DDSCL_SETFOCUSWINDOW),
390             FE(DDSCL_SETDEVICEWINDOW),
391             FE(DDSCL_CREATEDEVICEWINDOW)
392     };
393
394     if (TRACE_ON(ddraw))
395     {
396         DPRINTF(" - ");
397         DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0]));
398     }
399 }
400
401 void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) {
402     static const flag_info flags1[] = {
403       FE(DDCAPS_3D),
404       FE(DDCAPS_ALIGNBOUNDARYDEST),
405       FE(DDCAPS_ALIGNSIZEDEST),
406       FE(DDCAPS_ALIGNBOUNDARYSRC),
407       FE(DDCAPS_ALIGNSIZESRC),
408       FE(DDCAPS_ALIGNSTRIDE),
409       FE(DDCAPS_BLT),
410       FE(DDCAPS_BLTQUEUE),
411       FE(DDCAPS_BLTFOURCC),
412       FE(DDCAPS_BLTSTRETCH),
413       FE(DDCAPS_GDI),
414       FE(DDCAPS_OVERLAY),
415       FE(DDCAPS_OVERLAYCANTCLIP),
416       FE(DDCAPS_OVERLAYFOURCC),
417       FE(DDCAPS_OVERLAYSTRETCH),
418       FE(DDCAPS_PALETTE),
419       FE(DDCAPS_PALETTEVSYNC),
420       FE(DDCAPS_READSCANLINE),
421       FE(DDCAPS_STEREOVIEW),
422       FE(DDCAPS_VBI),
423       FE(DDCAPS_ZBLTS),
424       FE(DDCAPS_ZOVERLAYS),
425       FE(DDCAPS_COLORKEY),
426       FE(DDCAPS_ALPHA),
427       FE(DDCAPS_COLORKEYHWASSIST),
428       FE(DDCAPS_NOHARDWARE),
429       FE(DDCAPS_BLTCOLORFILL),
430       FE(DDCAPS_BANKSWITCHED),
431       FE(DDCAPS_BLTDEPTHFILL),
432       FE(DDCAPS_CANCLIP),
433       FE(DDCAPS_CANCLIPSTRETCHED),
434       FE(DDCAPS_CANBLTSYSMEM)
435     };
436     static const flag_info flags2[] = {
437       FE(DDCAPS2_CERTIFIED),
438       FE(DDCAPS2_NO2DDURING3DSCENE),
439       FE(DDCAPS2_VIDEOPORT),
440       FE(DDCAPS2_AUTOFLIPOVERLAY),
441       FE(DDCAPS2_CANBOBINTERLEAVED),
442       FE(DDCAPS2_CANBOBNONINTERLEAVED),
443       FE(DDCAPS2_COLORCONTROLOVERLAY),
444       FE(DDCAPS2_COLORCONTROLPRIMARY),
445       FE(DDCAPS2_CANDROPZ16BIT),
446       FE(DDCAPS2_NONLOCALVIDMEM),
447       FE(DDCAPS2_NONLOCALVIDMEMCAPS),
448       FE(DDCAPS2_NOPAGELOCKREQUIRED),
449       FE(DDCAPS2_WIDESURFACES),
450       FE(DDCAPS2_CANFLIPODDEVEN),
451       FE(DDCAPS2_CANBOBHARDWARE),
452       FE(DDCAPS2_COPYFOURCC),
453       FE(DDCAPS2_PRIMARYGAMMA),
454       FE(DDCAPS2_CANRENDERWINDOWED),
455       FE(DDCAPS2_CANCALIBRATEGAMMA),
456       FE(DDCAPS2_FLIPINTERVAL),
457       FE(DDCAPS2_FLIPNOVSYNC),
458       FE(DDCAPS2_CANMANAGETEXTURE),
459       FE(DDCAPS2_TEXMANINNONLOCALVIDMEM),
460       FE(DDCAPS2_STEREO),
461       FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL)
462     };
463     static const flag_info flags3[] = {
464       FE(DDCKEYCAPS_DESTBLT),
465       FE(DDCKEYCAPS_DESTBLTCLRSPACE),
466       FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV),
467       FE(DDCKEYCAPS_DESTBLTYUV),
468       FE(DDCKEYCAPS_DESTOVERLAY),
469       FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE),
470       FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV),
471       FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE),
472       FE(DDCKEYCAPS_DESTOVERLAYYUV),
473       FE(DDCKEYCAPS_SRCBLT),
474       FE(DDCKEYCAPS_SRCBLTCLRSPACE),
475       FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV),
476       FE(DDCKEYCAPS_SRCBLTYUV),
477       FE(DDCKEYCAPS_SRCOVERLAY),
478       FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE),
479       FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV),
480       FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE),
481       FE(DDCKEYCAPS_SRCOVERLAYYUV),
482       FE(DDCKEYCAPS_NOCOSTOVERLAY)
483     };
484     static const flag_info flags4[] = {
485       FE(DDFXCAPS_BLTALPHA),
486       FE(DDFXCAPS_OVERLAYALPHA),
487       FE(DDFXCAPS_BLTARITHSTRETCHYN),
488       FE(DDFXCAPS_BLTARITHSTRETCHY),
489       FE(DDFXCAPS_BLTMIRRORLEFTRIGHT),
490       FE(DDFXCAPS_BLTMIRRORUPDOWN),
491       FE(DDFXCAPS_BLTROTATION),
492       FE(DDFXCAPS_BLTROTATION90),
493       FE(DDFXCAPS_BLTSHRINKX),
494       FE(DDFXCAPS_BLTSHRINKXN),
495       FE(DDFXCAPS_BLTSHRINKY),
496       FE(DDFXCAPS_BLTSHRINKYN),
497       FE(DDFXCAPS_BLTSTRETCHX),
498       FE(DDFXCAPS_BLTSTRETCHXN),
499       FE(DDFXCAPS_BLTSTRETCHY),
500       FE(DDFXCAPS_BLTSTRETCHYN),
501       FE(DDFXCAPS_OVERLAYARITHSTRETCHY),
502       FE(DDFXCAPS_OVERLAYARITHSTRETCHYN),
503       FE(DDFXCAPS_OVERLAYSHRINKX),
504       FE(DDFXCAPS_OVERLAYSHRINKXN),
505       FE(DDFXCAPS_OVERLAYSHRINKY),
506       FE(DDFXCAPS_OVERLAYSHRINKYN),
507       FE(DDFXCAPS_OVERLAYSTRETCHX),
508       FE(DDFXCAPS_OVERLAYSTRETCHXN),
509       FE(DDFXCAPS_OVERLAYSTRETCHY),
510       FE(DDFXCAPS_OVERLAYSTRETCHYN),
511       FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT),
512       FE(DDFXCAPS_OVERLAYMIRRORUPDOWN)
513     };
514     static const flag_info flags5[] = {
515       FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND),
516       FE(DDFXALPHACAPS_BLTALPHAPIXELS),
517       FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG),
518       FE(DDFXALPHACAPS_BLTALPHASURFACES),
519       FE(DDFXALPHACAPS_BLTALPHASURFACESNEG),
520       FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND),
521       FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS),
522       FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG),
523       FE(DDFXALPHACAPS_OVERLAYALPHASURFACES),
524       FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG)
525     };
526     static const flag_info flags6[] = {
527       FE(DDPCAPS_4BIT),
528       FE(DDPCAPS_8BITENTRIES),
529       FE(DDPCAPS_8BIT),
530       FE(DDPCAPS_INITIALIZE),
531       FE(DDPCAPS_PRIMARYSURFACE),
532       FE(DDPCAPS_PRIMARYSURFACELEFT),
533       FE(DDPCAPS_ALLOW256),
534       FE(DDPCAPS_VSYNC),
535       FE(DDPCAPS_1BIT),
536       FE(DDPCAPS_2BIT),
537       FE(DDPCAPS_ALPHA),
538     };
539     static const flag_info flags7[] = {
540       FE(DDSVCAPS_RESERVED1),
541       FE(DDSVCAPS_RESERVED2),
542       FE(DDSVCAPS_RESERVED3),
543       FE(DDSVCAPS_RESERVED4),
544       FE(DDSVCAPS_STEREOSEQUENTIAL),
545     };
546
547     DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize);
548     DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0]));
549     DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]));
550     DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0]));
551     DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0]));
552     DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0]));
553     DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0]));
554     DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0]));
555     DPRINTF("...\n");
556     DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes);
557     DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays);
558     DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch);
559     DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
560     DPRINTF("...\n");
561     DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
562 }
563
564 /* Debug function that can be helpful to debug various surface-related problems */
565 static int get_shift(DWORD color_mask) {
566     int shift = 0;
567     while (color_mask > 0xFF) {
568         color_mask >>= 1;
569         shift += 1;
570     }
571     while ((color_mask & 0x80) == 0) {
572         color_mask <<= 1;
573         shift -= 1;
574     }
575     return shift;
576 }
577
578 void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f)
579 {
580     int i;
581
582     if (TRACE_ON(ddraw)) {
583         DPRINTF("Dumping surface : \n");
584         DDRAW_dump_surface_desc(&(surface->surface_desc));
585     }
586     
587     fprintf(f, "P6\n%ld %ld\n255\n", surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
588
589     if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
590         unsigned char table[256][3];
591         unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface;
592         if (surface->palette == NULL) {
593             fclose(f);
594             return;
595         }
596         for (i = 0; i < 256; i++) {
597             table[i][0] = surface->palette->palents[i].peRed;
598             table[i][1] = surface->palette->palents[i].peGreen;
599             table[i][2] = surface->palette->palents[i].peBlue;
600         }
601         for (i = 0; i < surface->surface_desc.dwHeight * surface->surface_desc.dwWidth; i++) {
602             unsigned char color = *src++;
603             fputc(table[color][0], f);
604             fputc(table[color][1], f);
605             fputc(table[color][2], f);
606         }
607     } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
608         int red_shift, green_shift, blue_shift;
609         red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask);
610         green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask);
611         blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask);
612
613         for (i = 0; i < surface->surface_desc.dwHeight * surface->surface_desc.dwWidth; i++) {
614             int color;
615             int comp;
616             
617             if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
618                 color = ((unsigned char *) surface->surface_desc.lpSurface)[i];
619             } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
620                 color = ((unsigned short *) surface->surface_desc.lpSurface)[i];
621             } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
622                 color = ((unsigned int *) surface->surface_desc.lpSurface)[i];
623             } else {
624                 /* Well, this won't work on platforms without support for non-aligned memory accesses or big endian :-) */
625                 color = *((unsigned int *) (((char *) surface->surface_desc.lpSurface) + (3 * i)));
626             }
627             comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
628             fputc(red_shift > 0 ? comp >> red_shift : comp << -red_shift, f);
629             comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
630             fputc(green_shift > 0 ? comp >> green_shift : comp << -green_shift, f);
631             comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
632             fputc(blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift, f);
633         }
634     }
635     fclose(f);
636 }