Add the possibility to save a snapshot of the backbuffer at

flip-time.
This commit is contained in:
Lionel Ulmer 2004-04-12 22:07:33 +00:00 committed by Alexandre Julliard
parent 9fccb024be
commit d069312de6
4 changed files with 79 additions and 32 deletions

View file

@ -52,7 +52,7 @@ snoop_texture(IDirectDrawSurfaceImpl *This) {
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 *

View file

@ -402,7 +402,7 @@ extern void DDRAW_dump_cooperativelevel(DWORD cooplevel);
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

View file

@ -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 @@ Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface,
}
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;
}

View file

@ -580,15 +580,26 @@ static int get_shift(DWORD color_mask) {
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 @@ void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f)
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);