[DDraw] Add buffer saving on Flip.

Lionel Ulmer lionel.ulmer at free.fr
Mon Apr 12 09:48:41 CDT 2004


This is handy when debugging interactions between DInput and DDraw (ie to
see what keypress makes the game switch from one screen to another).

This does work only for 2D games for now.

Changelog:
 - add the possibility to save a snapshot of the backbuffer at Flip-time

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
? dlls/ddraw/a.out
? dlls/ddraw/test.c
Index: dlls/ddraw/d3dtexture.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3dtexture.c,v
retrieving revision 1.61
diff -u -r1.61 d3dtexture.c
--- dlls/ddraw/d3dtexture.c	5 Sep 2003 23:08:41 -0000	1.61
+++ dlls/ddraw/d3dtexture.c	12 Apr 2004 14:45:59 -0000
@@ -52,7 +52,7 @@
     
     sprintf(buf, "tex_%05d_%02d.pnm", glThis->tex_name, This->mipmap_level);
     f = fopen(buf, "wb");
-    DDRAW_dump_surface_to_disk(This, f);
+    DDRAW_dump_surface_to_disk(This, f, 1);
 }
 
 static IDirectDrawSurfaceImpl *
Index: dlls/ddraw/ddraw_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddraw_private.h,v
retrieving revision 1.41
diff -u -r1.41 ddraw_private.h
--- dlls/ddraw/ddraw_private.h	16 Mar 2004 01:13:29 -0000	1.41
+++ dlls/ddraw/ddraw_private.h	12 Apr 2004 14:45:59 -0000
@@ -402,7 +402,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) ;
+extern void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale) ;
 
 /* Used for generic dumping */
 typedef struct
Index: dlls/ddraw/helper.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/helper.c,v
retrieving revision 1.30
diff -u -r1.30 helper.c
--- dlls/ddraw/helper.c	6 Oct 2003 21:03:32 -0000	1.30
+++ dlls/ddraw/helper.c	12 Apr 2004 14:45:59 -0000
@@ -580,15 +580,26 @@
     return shift;
 }
 
-void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f)
+void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale)
 {
-    int i;
+    int rwidth, rheight, x, y;
+    static char *output = NULL;
+    static int size = 0;
 
-    fprintf(f, "P6\n%ld %ld\n255\n", surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
+    rwidth  = (surface->surface_desc.dwWidth  + scale - 1) / scale;
+    rheight = (surface->surface_desc.dwHeight + scale - 1) / scale;
+
+    if (rwidth > size) {
+	output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rwidth * 3);
+	size = rwidth;
+    }
+    
+    fprintf(f, "P6\n%d %d\n255\n", rwidth, rheight);
 
     if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
         unsigned char table[256][3];
-	unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface;
+	int i;
+	
 	if (surface->palette == NULL) {
 	    fclose(f);
 	    return;
@@ -598,38 +609,56 @@
 	    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);
+	for (y = 0; y < rheight; y++) {
+	    unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
+	    for (x = 0; x < rwidth; x++) {
+		unsigned char color = *src;
+		src += scale;
+
+		output[3 * x + 0] = table[color][0];
+		output[3 * x + 1] = table[color][1];
+		output[3 * x + 2] = table[color][2];
+	    }
+	    fwrite(output, 3 * rwidth, 1, f);
 	}
     } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) {
-        int red_shift, green_shift, blue_shift;
+        int red_shift, green_shift, blue_shift, pix_width;
+	
+	if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	    pix_width = 1;
+	} else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+	    pix_width = 2;
+	} else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+	    pix_width = 4;
+	} else {
+	    pix_width = 3;
+	}
+	
 	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)));
+	for (y = 0; y < rheight; y++) {
+	    unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch);
+	    for (x = 0; x < rwidth; x++) {	    
+		unsigned int color;
+		unsigned int comp;
+		int i;
+
+		color = 0;
+		for (i = 0; i < pix_width; i++) {
+		    color |= src[i] << (8 * i);
+		}
+		src += scale * pix_width;
+		
+		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;
+		output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
+		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;
+		output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
+		comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;
+		output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
 	    }
-	    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);
+	    fwrite(output, 3 * rwidth, 1, f);
 	}
     }
     fclose(f);
Index: dlls/ddraw/dsurface/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.c,v
retrieving revision 1.55
diff -u -r1.55 main.c
--- dlls/ddraw/dsurface/main.c	30 Jan 2004 22:58:03 -0000	1.55
+++ dlls/ddraw/dsurface/main.c	12 Apr 2004 14:46:00 -0000
@@ -34,6 +34,7 @@
 #include "dsurface/thunks.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip);
 
 /** Creation/Destruction functions */
 
@@ -575,9 +576,26 @@
     }
 
     TRACE("flip to backbuffer: %p\n",target);
+    if (TRACE_ON(ddraw_flip)) {
+	static unsigned int flip_count = 0;
+	IDirectDrawPaletteImpl *palette;
+	char buf[32];
+	FILE *f;
+
+	/* Hack for paletted games... */
+	palette = target->palette;
+	target->palette = This->palette;
+	
+	sprintf(buf, "flip_%08d.ppm", flip_count++);
+	TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf);
+	f = fopen(buf, "wb");
+	DDRAW_dump_surface_to_disk(target, f, 8);
+	target->palette = palette;
+    }
+
     if (This->flip_data(This, target, dwFlags))
 	This->flip_update(This, dwFlags);
-
+    
     return DD_OK;
 }
 


More information about the wine-patches mailing list