- added depth conversion routines (only 8bpp -> 16 bpp for now)

- added support of DEPTH_FILL for Blits
- added some flags in GetCaps to get some games working
This commit is contained in:
Lionel Ulmer 1999-01-26 15:16:41 +00:00 committed by Alexandre Julliard
parent 22c904d3ca
commit 6e95399049
2 changed files with 200 additions and 54 deletions

View File

@ -412,17 +412,31 @@ static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
return DD_OK; return DD_OK;
} }
static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock( static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE3 this) {
LPDIRECTDRAWSURFACE3 this,LPVOID surface) if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
{ /* Pixel convertion ! */
TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); if ((this->s.ddraw->d.depth == 8) && (this->s.ddraw->d.screen_depth == 16)) {
unsigned char *src = (unsigned char *) this->s.surface_desc.y.lpSurface;
unsigned short *dst = (unsigned short *) this->t.xlib.image->data;
unsigned short *pal;
int x, y;
if (!this->s.ddraw->d.paintable) if (this->s.palette != NULL) {
return DD_OK; pal = (unsigned short *) this->s.palette->screen_palents;
for (y = 0; y < this->s.surface_desc.dwHeight; y++) {
for (x = 0; x < this->s.surface_desc.dwWidth; x++) {
dst[x + y * this->s.surface_desc.lPitch] = pal[src[x + y * this->s.surface_desc.lPitch]];
}
}
} else {
WARN(ddraw, "No palette set...\n");
memset(dst, 0, this->s.surface_desc.lPitch * this->s.surface_desc.dwHeight * 2);
}
} else {
ERR(ddraw, "Unsupported pixel convertion...\n");
}
}
/* Only redraw the screen when unlocking the buffer that is on screen */
if ((this->t.xlib.image != NULL) &&
(this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
if (this->s.ddraw->e.xlib.xshm_active) if (this->s.ddraw->e.xlib.xshm_active)
TSXShmPutImage(display, TSXShmPutImage(display,
@ -442,7 +456,21 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
0, 0, 0, 0, 0, 0, 0, 0,
this->t.xlib.image->width, this->t.xlib.image->width,
this->t.xlib.image->height); this->t.xlib.image->height);
}
static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
LPDIRECTDRAWSURFACE3 this,LPVOID surface)
{
TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
if (!this->s.ddraw->d.paintable)
return DD_OK;
/* Only redraw the screen when unlocking the buffer that is on screen */
if ((this->t.xlib.image != NULL) &&
(this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
Xlib_copy_surface_on_screen(this);
if (this->s.palette && this->s.palette->cm) if (this->s.palette && this->s.palette->cm)
TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm); TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
} }
@ -500,25 +528,7 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
flipto = this; flipto = this;
} }
#ifdef HAVE_LIBXXSHM Xlib_copy_surface_on_screen(this);
if (this->s.ddraw->e.xlib.xshm_active) {
TSXShmPutImage(display,
this->s.ddraw->d.drawable,
DefaultGCOfScreen(screen),
flipto->t.xlib.image,
0, 0, 0, 0,
flipto->t.xlib.image->width,
flipto->t.xlib.image->height,
False);
} else
#endif
TSXPutImage(display,
this->s.ddraw->d.drawable,
DefaultGCOfScreen(screen),
flipto->t.xlib.image,
0, 0, 0, 0,
flipto->t.xlib.image->width,
flipto->t.xlib.image->height);
if (flipto->s.palette && flipto->s.palette->cm) { if (flipto->s.palette && flipto->s.palette->cm) {
TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm); TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
@ -555,7 +565,7 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
return DD_OK; return DD_OK;
} }
if( !(pal->cm) && (this->s.ddraw->d.depth<=8)) if( !(pal->cm) && (this->s.ddraw->d.screen_depth<=8))
{ {
pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,DefaultVisualOfScreen(screen),AllocAll); pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,DefaultVisualOfScreen(screen),AllocAll);
@ -702,6 +712,22 @@ static HRESULT WINAPI IDirectDrawSurface3_Blt(
dwFlags &= ~(DDBLT_COLORFILL); dwFlags &= ~(DDBLT_COLORFILL);
} }
if (dwFlags & DDBLT_DEPTHFILL) {
#ifdef HAVE_MESAGL
GLboolean ztest;
/* Clears the screen */
TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
glGetBooleanv(GL_DEPTH_TEST, &ztest);
glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
glClear(GL_DEPTH_BUFFER_BIT);
glDepthMask(ztest);
dwFlags &= ~(DDBLT_DEPTHFILL);
#endif HAVE_MESAGL
}
if (!src) { if (!src) {
if (dwFlags) { if (dwFlags) {
TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n"); TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
@ -734,7 +760,7 @@ static HRESULT WINAPI IDirectDrawSurface3_Blt(
/* I think we should do a Blit with 'stretching' here.... /* I think we should do a Blit with 'stretching' here....
Tomb Raider II uses this to display the background during the menu selection Tomb Raider II uses this to display the background during the menu selection
when the screen resolution is != than 40x480 */ when the screen resolution is != than 640x480 */
TRACE(ddraw, "Blt with stretching\n"); TRACE(ddraw, "Blt with stretching\n");
/* This is a basic stretch implementation. It is painfully slow and quite ugly. */ /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
@ -891,6 +917,25 @@ static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this)
this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer); this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
if (this->t.xlib.image != NULL) { if (this->t.xlib.image != NULL) {
if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
/* In pixel conversion mode, there are two buffers to release... */
HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
#ifdef HAVE_LIBXXSHM
if (this->s.ddraw->e.xlib.xshm_active) {
TSXShmDetach(display, &(this->t.xlib.shminfo));
TSXDestroyImage(this->t.xlib.image);
shmdt(this->t.xlib.shminfo.shmaddr);
} else {
#endif
HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
this->t.xlib.image->data = NULL;
TSXDestroyImage(this->t.xlib.image);
#ifdef HAVE_LIBXXSHM
}
#endif
} else {
this->t.xlib.image->data = NULL; this->t.xlib.image->data = NULL;
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
@ -905,6 +950,7 @@ static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this)
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
} }
#endif #endif
}
this->t.xlib.image = 0; this->t.xlib.image = 0;
} else { } else {
@ -1553,6 +1599,28 @@ static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
this->palents[start+i].peGreen = palent[i].peGreen; this->palents[start+i].peGreen = palent[i].peGreen;
this->palents[start+i].peFlags = palent[i].peFlags; this->palents[start+i].peFlags = palent[i].peFlags;
} }
/* Now, if we are in 'depth conversion mode', update the screen palette */
if (this->ddraw->d.depth != this->ddraw->d.screen_depth) {
int i;
switch (this->ddraw->d.screen_depth) {
case 16: {
unsigned short *screen_palette = (unsigned short *) this->screen_palents;
for (i = 0; i < count; i++) {
screen_palette[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
}
} break;
default:
ERR(ddraw, "Memory corruption !\n");
break;
}
}
if (!this->cm) /* should not happen */ { if (!this->cm) /* should not happen */ {
} }
return DD_OK; return DD_OK;
@ -2089,12 +2157,13 @@ static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) { static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
XImage *img; XImage *img;
void *img_data;
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
if (this->e.xlib.xshm_active) { if (this->e.xlib.xshm_active) {
img = TSXShmCreateImage(display, img = TSXShmCreateImage(display,
DefaultVisualOfScreen(screen), DefaultVisualOfScreen(screen),
this->d.depth, this->d.screen_depth,
ZPixmap, ZPixmap,
NULL, NULL,
&(lpdsf->t.xlib.shminfo), &(lpdsf->t.xlib.shminfo),
@ -2124,7 +2193,14 @@ static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
if (this->d.depth != this->d.screen_depth) {
lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
(this->d.depth / 8));
} else {
lpdsf->s.surface_desc.y.lpSurface = img->data; lpdsf->s.surface_desc.y.lpSurface = img->data;
}
} else { } else {
#endif #endif
/* Allocate surface memory */ /* Allocate surface memory */
@ -2133,24 +2209,37 @@ static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
lpdsf->s.surface_desc.dwHeight * lpdsf->s.surface_desc.dwHeight *
(this->d.depth / 8)); (this->d.depth / 8));
if (this->d.depth != this->d.screen_depth) {
img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
(this->d.screen_depth / 8));
} else {
img_data = lpdsf->s.surface_desc.y.lpSurface;
}
/* In this case, create an XImage */ /* In this case, create an XImage */
img = img =
TSXCreateImage(display, TSXCreateImage(display,
DefaultVisualOfScreen(screen), DefaultVisualOfScreen(screen),
this->d.depth, this->d.screen_depth,
ZPixmap, ZPixmap,
0, 0,
lpdsf->s.surface_desc.y.lpSurface, img_data,
lpdsf->s.surface_desc.dwWidth, lpdsf->s.surface_desc.dwWidth,
lpdsf->s.surface_desc.dwHeight, lpdsf->s.surface_desc.dwHeight,
32, 32,
lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8) lpdsf->s.surface_desc.dwWidth * (this->d.screen_depth / 8)
); );
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
} }
#endif #endif
if (this->d.depth != this->d.screen_depth) {
lpdsf->s.surface_desc.lPitch = (this->d.depth / 8) * lpdsf->s.surface_desc.dwWidth;
} else {
lpdsf->s.surface_desc.lPitch = img->bytes_per_line; lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
}
return img; return img;
} }
@ -2447,16 +2536,30 @@ static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n", TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
this, width, height, depth); this, width, height, depth);
/* We hope getting the asked for depth */
this->d.screen_depth = depth;
depths = TSXListDepths(display,DefaultScreen(display),&depcount); depths = TSXListDepths(display,DefaultScreen(display),&depcount);
for (i=0;i<depcount;i++) for (i=0;i<depcount;i++)
if (depths[i]==depth) if (depths[i]==depth)
break; break;
TSXFree(depths);
if (i==depcount) {/* not found */ if (i==depcount) {/* not found */
for (i=0;i<depcount;i++)
if (depths[i]==16)
break;
if (i==depcount) {
sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth); sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
TSXFree(depths);
return DDERR_UNSUPPORTEDMODE; return DDERR_UNSUPPORTEDMODE;
} else {
WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
this->d.screen_depth = 16;
}
} }
TSXFree(depths);
this->d.width = width; this->d.width = width;
this->d.height = height; this->d.height = height;
this->d.depth = depth; this->d.depth = depth;
@ -2497,11 +2600,11 @@ static void fill_caps(LPDDCAPS caps) {
return; return;
caps->dwSize = sizeof(*caps); caps->dwSize = sizeof(*caps);
caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS; DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_ZBLTS;
caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED | caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
DDCAPS2_WIDESURFACES; DDCAPS2_WIDESURFACES;
caps->dwCKeyCaps = 0; caps->dwCKeyCaps = 0xFFFFFFFF;
caps->dwFXCaps = 0; caps->dwFXCaps = 0;
caps->dwFXAlphaCaps = 0; caps->dwFXAlphaCaps = 0;
caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256; caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
@ -2547,16 +2650,14 @@ static HRESULT WINAPI IDirectDraw2_CreateClipper(
static HRESULT WINAPI common_IDirectDraw2_CreatePalette( static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
) { ) {
int size = 0;
*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette)); *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
if (*lpddpal == NULL) return E_OUTOFMEMORY; if (*lpddpal == NULL) return E_OUTOFMEMORY;
(*lpddpal)->ref = 1; (*lpddpal)->ref = 1;
(*lpddpal)->ddraw = (LPDIRECTDRAW)this; (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
(*lpddpal)->installed = 0; (*lpddpal)->installed = 0;
if (palent)
{
int size = 0;
if (dwFlags & DDPCAPS_1BIT) if (dwFlags & DDPCAPS_1BIT)
size = 2; size = 2;
else if (dwFlags & DDPCAPS_2BIT) else if (dwFlags & DDPCAPS_2BIT)
@ -2567,10 +2668,50 @@ static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
size = 256; size = 256;
else else
ERR(ddraw, "unhandled palette format\n"); ERR(ddraw, "unhandled palette format\n");
*psize = size;
if (palent)
{
/* Now, if we are in 'depth conversion mode', create the screen palette */
if (this->d.depth != this->d.screen_depth) {
int i;
switch (this->d.screen_depth) {
case 16: {
unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
for (i = 0; i < size; i++) {
screen_palette[i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
}
} break;
default:
ERR(ddraw, "Memory corruption !\n");
break;
}
}
memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY)); memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
*psize = size; } else if (this->d.depth != this->d.screen_depth) {
int i;
switch (this->d.screen_depth) {
case 16: {
unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
for (i = 0; i < size; i++) {
screen_palette[i] = 0xFFFF;
} }
} break;
default:
ERR(ddraw, "Memory corruption !\n");
break;
}
}
return DD_OK; return DD_OK;
} }
@ -2873,19 +3014,19 @@ static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
/* FIXME: We should query those from X itself */ /* FIXME: We should query those from X itself */
switch (depths[i]) { switch (depths[i]) {
case 16: case 16:
ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f; ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0; ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00; ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
break; break;
case 24: case 24:
ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff; ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00; ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000; ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
break; break;
case 32: case 32:
ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff; ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00; ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000; ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
break; break;
} }
} }
@ -3289,6 +3430,7 @@ HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
(*lplpDD)->ref = 1; (*lplpDD)->ref = 1;
(*lplpDD)->d.drawable = 0; /* in SetDisplayMode */ (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
(*lplpDD)->d.screen_depth = DefaultDepthOfScreen(screen);
(*lplpDD)->d.depth = DefaultDepthOfScreen(screen); (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
(*lplpDD)->d.height = screenHeight; (*lplpDD)->d.height = screenHeight;
(*lplpDD)->d.width = screenWidth; (*lplpDD)->d.width = screenWidth;
@ -3296,7 +3438,7 @@ HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
/* Test if XShm is available. /* Test if XShm is available.
As XShm is not ready yet for 'prime-time', it is disabled for now */ As XShm is not ready yet for 'prime-time', it is disabled for now */
if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */)) if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
TRACE(ddraw, "Using XShm extesion.\n"); TRACE(ddraw, "Using XShm extesion.\n");
#endif #endif

View File

@ -837,6 +837,9 @@ struct IDirectDrawPalette {
Colormap cm; Colormap cm;
PALETTEENTRY palents[256]; PALETTEENTRY palents[256];
int installed; int installed;
/* This is to store the palette in 'screen format' */
int screen_palents[256];
}; };
#undef THIS #undef THIS
@ -893,7 +896,8 @@ FAR * ) PURE;
} *LPDIRECTDRAW_VTABLE,IDirectDraw_VTable; } *LPDIRECTDRAW_VTABLE,IDirectDraw_VTable;
struct _common_directdrawdata { struct _common_directdrawdata {
DWORD depth; DWORD screen_depth;
DWORD depth; /* SetDisplayMode */
DWORD height,width; /* SetDisplayMode */ DWORD height,width; /* SetDisplayMode */
HWND32 mainWindow; /* SetCooperativeLevel */ HWND32 mainWindow; /* SetCooperativeLevel */