[D3D 27] Some surface dumping code...

Lionel Ulmer lionel.ulmer at free.fr
Wed Dec 18 15:55:38 CST 2002


Hi all,

Often, when chasing a bug, one does not know where the bug lies (ie is it
when uploading the texture to the GL, is the game provided data correct,
...). For this, I implemented a function that enables anyone to dump any
surface to disk in a 'pnm' file format. I changed also the texture dumping
code to use this new function.

Changelog:
 Added surface dumping function for debug.

                    Lionel

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- ../wine_base/dlls/ddraw/d3dtexture.c	Tue Dec 17 19:59:05 2002
+++ dlls/ddraw/d3dtexture.c	Wed Dec 18 22:47:43 2002
@@ -36,95 +36,26 @@
 /* Define this if you want to save to a file all the textures used by a game
    (can be funny to see how they managed to cram all the pictures in
    texture memory) */
 #undef TEXTURE_SNOOP
 
 #ifdef TEXTURE_SNOOP
+
 #include <stdio.h>
 
-#define SNOOP_PALETTED() 									\
-      {												\
-	FILE *f;										\
-	char buf[32];										\
-	int x, y;										\
-												\
-	sprintf(buf, "%ld.pnm", glThis->tex_name);						\
-	f = fopen(buf, "wb");									\
-	fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);			\
-	for (y = 0; y < src_d->dwHeight; y++) {							\
-	  for (x = 0; x < src_d->dwWidth; x++) {						\
-	    unsigned char c = ((unsigned char *) src_d->lpSurface)[y * src_d->dwWidth + x];	\
-	    fputc(table[c][0], f);								\
-	    fputc(table[c][1], f);								\
-	    fputc(table[c][2], f);								\
-	  }											\
-	}											\
-	fclose(f);										\
-      }
-
-#define SNOOP_5650()											\
-	  {												\
-	    FILE *f;											\
-	    char buf[32];										\
-	    int x, y;											\
-	    												\
-	    sprintf(buf, "%ld.pnm", glThis->tex_name);							\
-	    f = fopen(buf, "wb");									\
-	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
-	    for (y = 0; y < src_d->dwHeight; y++) {							\
-	      for (x = 0; x < src_d->dwWidth; x++) {							\
-		unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x];	\
-		fputc((c & 0xF800) >> 8, f);								\
-		fputc((c & 0x07E0) >> 3, f);								\
-		fputc((c & 0x001F) << 3, f);								\
-	      }												\
-	    }												\
-	    fclose(f);											\
-	  }
-
-#define SNOOP_5551()											\
-	  {												\
-	    FILE *f;											\
-	    char buf[32];										\
-	    int x, y;											\
-	    												\
-	    sprintf(buf, "%ld.pnm", glThis->tex_name);							\
-	    f = fopen(buf, "wb");									\
-	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
-	    for (y = 0; y < src_d->dwHeight; y++) {							\
-	      for (x = 0; x < src_d->dwWidth; x++) {							\
-		unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x];	\
-		fputc((c & 0xF800) >> 8, f);								\
-		fputc((c & 0x07C0) >> 3, f);								\
-		fputc((c & 0x003E) << 2, f);								\
-	      }												\
-	    }												\
-	    fclose(f);											\
-	  }
-
-#define SNOOP_1555()											\
-	  {												\
-	    FILE *f;											\
-	    char buf[32];										\
-	    int x, y;											\
-	    												\
-	    sprintf(buf, "%ld.pnm", glThis->tex_name);							\
-	    f = fopen(buf, "wb");									\
-	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
-	    for (y = 0; y < src_d->dwHeight; y++) {							\
-	      for (x = 0; x < src_d->dwWidth; x++) {							\
-		unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x];	\
-		fputc((c & 0x7C00) >> 7, f);								\
-		fputc((c & 0x03E0) >> 2, f);								\
-		fputc((c & 0x001F) << 3, f);								\
-	      }												\
-	    }												\
-	    fclose(f);											\
-	  }
+static void snoop_texture(IDirectDrawSurfaceImpl *This) {
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    char buf[128];
+    FILE *f;
+    
+    sprintf(buf, "tex_%05d.pnm", glThis->tex_name);
+    f = fopen(buf, "wb");
+    DDRAW_dump_surface_to_disk(This, f);
+}
+
 #else
-#define SNOOP_PALETTED()
-#define SNOOP_5650()
-#define SNOOP_5551()
-#define SNOOP_1555()
+
+#define snoop_texture(a)
+
 #endif
 
 /*******************************************************************************
@@ -224,6 +155,9 @@
     glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
     glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
 
+    /* Texture snooping for the curious :-) */
+    snoop_texture(This);
+    
     if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
 	  /* ****************
 	     Paletted Texture
@@ -257,9 +191,6 @@
 	        table[i][3] = 0xFF;
 	}
 
-	/* Texture snooping */
-	SNOOP_PALETTED();
-
 	if (ptr_ColorTableEXT != NULL) {
 	    /* use Paletted Texture Extension */
 	    ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
@@ -337,9 +268,6 @@
 				src_d->lpSurface);
 	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
   	    if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
-	        /* Texture snooping */
-	        SNOOP_5650();
-		    
 		if (init_upload)
 		    glTexImage2D(GL_TEXTURE_2D,
 				 glThis->mipmap_level,
@@ -359,9 +287,6 @@
 				    src_d->lpSurface);
 
 	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
-	        /* Texture snooping */
-  	        SNOOP_5551();
-		    
 		if (init_upload)
 		    glTexImage2D(GL_TEXTURE_2D,
 				 glThis->mipmap_level,
@@ -439,7 +364,6 @@
 			      ((*src & 0x7FFF) <<  1));
 		    src++;
 		}
-		SNOOP_1555();
 		
 		if (init_upload)
 		    glTexImage2D(GL_TEXTURE_2D,
--- ../wine_base/dlls/ddraw/ddraw_private.h	Sun Dec 15 12:15:49 2002
+++ dlls/ddraw/ddraw_private.h	Tue Dec 17 21:52:22 2002
@@ -21,6 +21,8 @@
 
 /* MAY NOT CONTAIN X11 or DGA specific includes/defines/structs! */
 
+#include <stdio.h>
+
 #include "winbase.h"
 #include "wtypes.h"
 #include "wingdi.h"
@@ -371,6 +373,7 @@
 extern void DDRAW_dump_lockflag(DWORD lockflag);
 extern void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *in);
 extern void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps);
+extern void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f) ;
 
 /* Used for generic dumping */
 typedef struct
--- ../wine_base/dlls/ddraw/helper.c	Sat Dec 14 13:51:24 2002
+++ dlls/ddraw/helper.c	Wed Dec 18 22:34:27 2002
@@ -24,6 +24,7 @@
 #include "wine/port.h"
 
 #include <stddef.h>
+#include <stdio.h>
 
 #include "d3d.h"
 #include "ddraw.h"
@@ -556,4 +557,75 @@
     DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch);
     DPRINTF("...\n");
     DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n");
+}
+
+/* Debug function that can be helpful to debug various surface-related problems */
+static int get_shift(DWORD color_mask) {
+    int shift = 0;
+    while (color_mask > 0xFF) {
+        color_mask >>= 1;
+	shift += 1;
+    }
+    while ((color_mask & 0x80) == 0) {
+        color_mask <<= 1;
+	shift -= 1;
+    }
+    return shift;
+}
+
+void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f)
+{
+    int i;
+
+    DDRAW_dump_surface_desc(&(surface->surface_desc));
+    
+    fprintf(f, "P6\n%ld %ld\n255\n", surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
+
+    if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+        unsigned char table[256][3];
+	unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface;
+	if (surface->palette == NULL) {
+	    fclose(f);
+	    return;
+	}
+	for (i = 0; i < 256; i++) {
+	    table[i][0] = surface->palette->palents[i].peRed;
+	    table[i][1] = surface->palette->palents[i].peGreen;
+	    table[i][2] = surface->palette->palents[i].peBlue;
+	}
+	for (i = 0; i < surface->surface_desc.dwHeight * surface->surface_desc.dwWidth; i++) {
+	    unsigned char color = *src++;
+	    fputc(table[color][0], f);
+	    fputc(table[color][1], f);
+	    fputc(table[color][2], f);
+	}
+    } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
+        int red_shift, green_shift, blue_shift;
+	red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask);
+	green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask);
+	blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask);
+
+	for (i = 0; i < surface->surface_desc.dwHeight * surface->surface_desc.dwWidth; i++) {
+	    int color;
+	    int comp;
+	    
+	    if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	        color = ((unsigned char *) surface->surface_desc.lpSurface)[i];
+	    } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+	        color = ((unsigned short *) surface->surface_desc.lpSurface)[i];
+	    } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+	        color = ((unsigned int *) surface->surface_desc.lpSurface)[i];
+	    } else {
+	        /* Well, this won't work on platforms without support for non-aligned memory accesses or big endian :-) */
+	        color = *((unsigned int *) (((char *) surface->surface_desc.lpSurface) + (3 * i)));
+	    }
+	    comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
+	    fputc(red_shift > 0 ? comp >> red_shift : comp << -red_shift, f);
+	    comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
+	    fputc(green_shift > 0 ? comp >> green_shift : comp << -green_shift, f);
+	    comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
+	    fputc(blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift, f);
+	}
+    }
+    fclose(f);
 }


More information about the wine-patches mailing list