[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, ¤t_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