3 * Copyright 1997,1998 Marcus Meissner
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X
6 * applications nor can you switch to a virtual console. Also, enabling
7 * only works, if you have switched to the screen where the application
9 * Some ways to debug this stuff are:
10 * - A terminal connected to the serial port. Can be bought used for cheap.
11 * (This is the method I am using.)
12 * - Another machine connected over some kind of network.
14 /* Progress on following programs:
17 * The movies play. The game doesn't yet. No sound. (Needs clone())
19 * - WingCommander 4 (not 5!) / Win95 Patch:
20 * The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
21 * "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
22 * my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
23 * 555. Specifying it in DDPIXELFORMAT didn't help.
24 * Requires to be run in 640x480xdepth mode (doesn't seem to heed
25 * DDSURFACEDESC.lPitch).
28 * Goes to the easy/hard selection screen, then hangs due to not MT safe
31 * - Dark Angel Demo (Some shoot and run game):
32 * The graphics stuff works fine, you can play it.
35 * Doesn't work, I am still unsure why not.
43 #include <sys/signal.h>
47 #include "interfaces.h"
59 #ifdef HAVE_LIBXXF86DGA
60 #include <X11/extensions/xf86dga.h>
63 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE,REFIID,LPVOID*);
64 static HRESULT WINAPI IDirectDraw_QueryInterface(LPDIRECTDRAW this,REFIID refiid,LPVOID *obj);
65 static HRESULT WINAPI IDirectDraw2_CreateSurface( LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
66 static HRESULT WINAPI IDirectDraw_CreateSurface( LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
67 static struct IDirectDrawSurface2_VTable dds2vt;
68 static struct IDirectDrawSurface_VTable ddsvt;
72 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
73 fprintf(stderr,"DirectDrawEnumerateA(%p,%p).\n",ddenumproc,data);
74 ddenumproc(0,"WINE Display","display",data);
75 ddenumproc((void*)&IID_IDirectDraw,"WINE DirectDraw","directdraw",data);
76 ddenumproc((void*)&IID_IDirectDrawPalette,"WINE DirectPalette","directpalette",data);
81 DSoundHelp(DWORD x,DWORD y,DWORD z) {
82 fprintf(stderr,"DSoundHelp(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
86 #ifdef HAVE_LIBXXF86DGA
88 static void _dump_DDSCAPS(DWORD flagmask) {
94 #define FE(x) { x, #x},
97 FE(DDSCAPS_BACKBUFFER)
100 FE(DDSCAPS_FRONTBUFFER)
101 FE(DDSCAPS_OFFSCREENPLAIN)
104 FE(DDSCAPS_PRIMARYSURFACE)
105 FE(DDSCAPS_PRIMARYSURFACELEFT)
106 FE(DDSCAPS_SYSTEMMEMORY)
109 FE(DDSCAPS_VIDEOMEMORY)
111 FE(DDSCAPS_WRITEONLY)
114 FE(DDSCAPS_LIVEVIDEO)
118 FE(DDSCAPS_ALLOCONLOAD)
120 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
121 if (flags[i].mask & flagmask)
122 fprintf(stderr,"%s ",flags[i].name);
125 static void _dump_DDCAPS(DWORD flagmask) {
131 #define FE(x) { x, #x},
133 FE(DDCAPS_ALIGNBOUNDARYDEST)
134 FE(DDCAPS_ALIGNSIZEDEST)
135 FE(DDCAPS_ALIGNBOUNDARYSRC)
136 FE(DDCAPS_ALIGNSIZESRC)
137 FE(DDCAPS_ALIGNSTRIDE)
141 FE(DDCAPS_BLTSTRETCH)
144 FE(DDCAPS_OVERLAYCANTCLIP)
145 FE(DDCAPS_OVERLAYFOURCC)
146 FE(DDCAPS_OVERLAYSTRETCH)
148 FE(DDCAPS_PALETTEVSYNC)
149 FE(DDCAPS_READSCANLINE)
150 FE(DDCAPS_STEREOVIEW)
156 FE(DDCAPS_COLORKEYHWASSIST)
157 FE(DDCAPS_NOHARDWARE)
158 FE(DDCAPS_BLTCOLORFILL)
159 FE(DDCAPS_BANKSWITCHED)
160 FE(DDCAPS_BLTDEPTHFILL)
162 FE(DDCAPS_CANCLIPSTRETCHED)
163 FE(DDCAPS_CANBLTSYSMEM)
165 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
166 if (flags[i].mask & flagmask)
167 fprintf(stderr,"%s ",flags[i].name);
170 static void _dump_DDSD(DWORD flagmask) {
180 FE(DDSD_BACKBUFFERCOUNT)
181 FE(DDSD_ZBUFFERBITDEPTH)
182 FE(DDSD_ALPHABITDEPTH)
184 FE(DDSD_CKDESTOVERLAY)
186 FE(DDSD_CKSRCOVERLAY)
191 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
192 if (flags[i].mask & flagmask)
193 fprintf(stderr,"%s ",flags[i].name);
196 static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) {
197 static XVisualInfo *vi;
202 vi = XGetVisualInfo(display,VisualNoMask,&vt,&nitems);
204 pf->dwFourCC = mmioFOURCC('R','G','B',' ');
205 if (ddraw->d.depth==8) {
206 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
207 pf->x.dwRGBBitCount = 8;
208 pf->y.dwRBitMask = 0;
209 pf->z.dwGBitMask = 0;
210 pf->xx.dwBBitMask = 0;
213 if (ddraw->d.depth==16) {
214 pf->dwFlags = DDPF_RGB;
215 pf->x.dwRGBBitCount = 16;
216 pf->y.dwRBitMask = vi[0].red_mask;
217 pf->z.dwGBitMask = vi[0].green_mask;
218 pf->xx.dwBBitMask = vi[0].blue_mask;
221 fprintf(stderr,"_getpixelformat:oops?\n");
222 return DDERR_GENERIC;
226 static HRESULT WINAPI IDirectDrawSurface_Lock(
227 LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
230 fprintf(stderr,"IDirectDrawSurface(%p)->Lock(%p,%p,%08lx,%08lx)\n",
231 this,lprect,lpddsd,flags,(DWORD)hnd
237 fprintf(stderr," lprect: %dx%d-%dx%d\n",
238 lprect->top,lprect->left,lprect->bottom,lprect->right
241 lpddsd->lpSurface = this->surface+
242 (lprect->top*this->lpitch)+
243 (lprect->left*(this->ddraw->d.depth/8));
245 lpddsd->lpSurface = this->surface;
246 lpddsd->dwWidth = this->width;
247 lpddsd->dwHeight = this->height;
248 lpddsd->lPitch = this->lpitch;
249 _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
253 static HRESULT WINAPI IDirectDrawSurface2_Lock(
254 LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
256 fprintf(stderr,"IDirectDrawSurface2(%p)->Lock(%p,%p,%08lx,%08lx)\n",
257 this,lprect,lpddsd,flags,(DWORD)hnd
259 /*fprintf(stderr,".");*/
262 fprintf(stderr," lprect: %dx%d-%dx%d\n",
263 lprect->top,lprect->left,lprect->bottom,lprect->right
266 lpddsd->lpSurface = this->surface+
267 (lprect->top*this->lpitch)+
268 (lprect->left*(this->ddraw->d.depth/8));
270 lpddsd->lpSurface = this->surface;
271 lpddsd->dwWidth = this->width;
272 lpddsd->dwHeight = this->height;
273 lpddsd->lPitch = this->lpitch;
274 _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
278 static HRESULT WINAPI IDirectDrawSurface_Unlock(
279 LPDIRECTDRAWSURFACE this,LPVOID surface
281 dprintf_relay(stderr,"IDirectDrawSurface(%p)->Unlock(%p)\n",this,surface);
285 static HRESULT WINAPI IDirectDrawSurface_Flip(
286 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags
288 /* fprintf(stderr,"IDirectDrawSurface(%p)->Flip(%p,%08lx),STUB\n",this,flipto,dwFlags);*/
290 if (this->backbuffer)
291 flipto = this->backbuffer;
295 /* fprintf(stderr,"f>%ld",flipto->fb_height);*/
296 XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->fb_height);
297 if (flipto->palette && flipto->palette->cm)
298 XF86DGAInstallColormap(display,DefaultScreen(display),flipto->palette->cm);
299 while (!XF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
302 /* is this a good idea ? */
307 tmp = this->fb_height;
308 this->fb_height = flipto->fb_height;
309 flipto->fb_height = tmp;
311 ptmp = this->surface;
312 this->surface = flipto->surface;
313 flipto->surface = ptmp;
318 static HRESULT WINAPI IDirectDrawSurface2_Unlock(
319 LPDIRECTDRAWSURFACE2 this,LPVOID surface
321 dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Unlock(%p)\n",this,surface);
325 static HRESULT WINAPI IDirectDrawSurface_SetPalette(
326 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal
328 fprintf(stderr,"IDirectDrawSurface(%p)->SetPalette(%p)\n",this,pal);
333 static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
334 LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
336 fprintf(stderr,"IDirectDrawSurface2(%p)->SetPalette(%p)\n",this,pal);
341 static HRESULT WINAPI IDirectDrawSurface_Blt(
342 LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
344 fprintf(stderr,"IDirectDrawSurface(%p)->Blt(%p,%p,%p,%08lx,%p),stub!\n",
345 this,rdst,src,rsrc,dwFlags,lpbltfx
347 if (rdst) fprintf(stderr," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
348 if (rsrc) fprintf(stderr," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
349 fprintf(stderr," blitfx: 0x%08lx\n",lpbltfx->dwDDFX);
353 static HRESULT WINAPI IDirectDrawSurface_BltFast(
354 LPDIRECTDRAWSURFACE this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD trans
357 fprintf(stderr,"IDirectDrawSurface(%p)->BltFast(%ld,%ld,%p,%p,%08lx),stub!\n",
358 this,dstx,dsty,src,rsrc,trans
360 fprintf(stderr," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
361 bpp = this->ddraw->d.depth/8;
362 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
363 memcpy( this->surface+((i+dsty)*this->width*bpp)+dstx*bpp,
364 src->surface +(rsrc->top+i)*src->width*bpp+rsrc->left*bpp,
365 (rsrc->right-rsrc->left)*bpp
371 static HRESULT WINAPI IDirectDrawSurface_BltBatch(
372 LPDIRECTDRAWSURFACE this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
374 fprintf(stderr,"IDirectDrawSurface(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
380 static HRESULT WINAPI IDirectDrawSurface_GetCaps(
381 LPDIRECTDRAWSURFACE this,LPDDSCAPS caps
383 fprintf(stderr,"IDirectDrawSurface(%p)->GetCaps(%p)\n",this,caps);
384 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
388 static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc(
389 LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd
391 fprintf(stderr,"IDirectDrawSurface(%p)->GetSurfaceDesc(%p)\n",this,ddsd);
392 fprintf(stderr," flags: ");
393 _dump_DDSD(ddsd->dwFlags);
394 fprintf(stderr,"\n");
396 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
397 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
398 ddsd->dwBackBufferCount = 1;
399 ddsd->dwHeight = this->height;
400 ddsd->dwWidth = this->width;
401 ddsd->lPitch = this->lpitch;
402 if (this->backbuffer)
403 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
404 _getpixelformat(this->ddraw,&(ddsd->ddpfPixelFormat));
409 static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) {
410 dprintf_relay(stderr,"IDirectDrawSurface(%p)->AddRef()\n",this);
411 return ++(this->ref);
414 static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) {
415 dprintf_relay(stderr,"IDirectDrawSurface(%p)->Release()\n",this);
416 if (!--(this->ref)) {
417 this->ddraw->lpvtbl->fnRelease(this->ddraw);
418 /* clear out of surface list */
419 this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
420 HeapFree(GetProcessHeap(),0,this);
426 static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
427 dprintf_relay(stderr,"IDirectDrawSurface2(%p)->AddRef()\n",this);
428 return ++(this->ref);
431 static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
432 dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Release()\n",this);
433 if (!--(this->ref)) {
434 this->ddraw->lpvtbl->fnRelease(this->ddraw);
435 this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
436 HeapFree(GetProcessHeap(),0,this);
442 static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
443 LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
445 fprintf(stderr,"IDirectDrawSurface2(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
446 fprintf(stderr," caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
447 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
448 fprintf(stderr,"whoops, can only handle backbuffers for now\n");
451 /* FIXME: should handle more than one backbuffer */
452 *lpdsf = this->backbuffer;
456 static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface(
457 LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf
459 fprintf(stderr,"IDirectDrawSurface(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
460 fprintf(stderr," caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
461 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
462 fprintf(stderr,"whoops, can only handle backbuffers for now\n");
465 /* FIXME: should handle more than one backbuffer */
466 *lpdsf = this->backbuffer;
470 static HRESULT WINAPI IDirectDrawSurface_Initialize(
471 LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
473 fprintf(stderr,"IDirectDrawSurface(%p)->Initialize(%p,%p)\n",
476 return DDERR_ALREADYINITIALIZED;
479 static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat(
480 LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf
482 fprintf(stderr,"IDirectDrawSurface(%p)->GetPixelFormat(%p)\n",this,pf);
483 return _getpixelformat(this->ddraw,pf);
486 static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) {
487 fprintf(stderr,"IDirectDrawSurface(%p)->GetBltStatus(0x%08lx),stub!\n",
493 static HRESULT WINAPI IDirectDrawSurface_GetOverlayPosition(
494 LPDIRECTDRAWSURFACE this,LPLONG x1,LPLONG x2
496 fprintf(stderr,"IDirectDrawSurface(%p)->GetOverlayPosition(%p,%p),stub!\n",
502 static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) {
503 fprintf(stderr,"IDirectDrawSurface(%p)->GetDC(%p),stub!\n",this,lphdc);
507 static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
512 static struct IDirectDrawSurface2_VTable dds2vt = {
513 (void*)1/*IDirectDrawSurface2_QueryInterface*/,
514 IDirectDrawSurface2_AddRef,
515 IDirectDrawSurface2_Release,
518 (void*)6/*IDirectDrawSurface_Blt*/,
519 (void*)7/*IDirectDrawSurface_BltBatch*/,
522 IDirectDrawSurface2_EnumAttachedSurfaces,
525 IDirectDrawSurface2_GetAttachedSurface,
527 (void*)15/*IDirectDrawSurface_GetCaps*/,
535 (void*)23/*IDirectDrawSurface_GetSurfaceDesc*/,
538 IDirectDrawSurface2_Lock,
544 IDirectDrawSurface2_SetPalette,
545 IDirectDrawSurface2_Unlock,
555 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
558 StringFromCLSID((LPCLSID)refiid,xrefiid);
559 fprintf(stderr,"IDirectDrawSurface(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
561 /* thats version 2 */
562 if ( !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
563 this->lpvtbl->fnAddRef(this);
564 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
569 if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
570 this->lpvtbl->fnAddRef(this);
574 return OLE_E_ENUM_NOMORE;
577 static struct IDirectDrawSurface_VTable ddsvt = {
578 IDirectDrawSurface_QueryInterface,
579 IDirectDrawSurface_AddRef,
580 IDirectDrawSurface_Release,
583 IDirectDrawSurface_Blt,
584 IDirectDrawSurface_BltBatch,
585 IDirectDrawSurface_BltFast,
589 IDirectDrawSurface_Flip,
590 IDirectDrawSurface_GetAttachedSurface,
591 IDirectDrawSurface_GetBltStatus,
592 IDirectDrawSurface_GetCaps,
595 IDirectDrawSurface_GetDC,
597 IDirectDrawSurface_GetOverlayPosition,
599 IDirectDrawSurface_GetPixelFormat,
600 IDirectDrawSurface_GetSurfaceDesc,
601 IDirectDrawSurface_Initialize,
603 IDirectDrawSurface_Lock,
609 IDirectDrawSurface_SetPalette,
610 IDirectDrawSurface_Unlock,
616 static HRESULT WINAPI IDirectDraw_CreateSurface(
617 LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
621 fprintf(stderr,"IDirectDraw(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
622 fprintf(stderr," [w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
623 _dump_DDSD(lpddsd->dwFlags);
624 fprintf(stderr,"caps ");_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
625 fprintf(stderr,"]\n");
627 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
628 this->lpvtbl->fnAddRef(this);
630 (*lpdsf)->lpvtbl = &ddsvt;
632 if (!(this->d.vpmask & (1<<i)))
634 fprintf(stderr,"using viewport %d for a primary surface\n",i);
635 /* if i == 32 or maximum ... return error */
636 this->d.vpmask|=(1<<i);
637 (*lpdsf)->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
638 (*lpdsf)->fb_height = i*this->d.fb_height;
640 (*lpdsf)->width = this->d.width;
641 (*lpdsf)->height = this->d.height;
642 (*lpdsf)->ddraw = this;
643 (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
644 (*lpdsf)->backbuffer = NULL;
645 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
646 LPDIRECTDRAWSURFACE back;
648 if (lpddsd->dwBackBufferCount>1)
649 fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
651 (*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
652 this->lpvtbl->fnAddRef(this);
654 back->lpvtbl = &ddsvt;
656 if (!(this->d.vpmask & (1<<i)))
658 fprintf(stderr,"using viewport %d for backbuffer\n",i);
659 /* if i == 32 or maximum ... return error */
660 this->d.vpmask|=(1<<i);
661 back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
662 back->fb_height = i*this->d.fb_height;
664 back->width = this->d.width;
665 back->height = this->d.height;
667 back->lpitch = this->d.fb_width*this->d.depth/8;
668 back->backbuffer = NULL; /* does not have a backbuffer, it is
674 static HRESULT WINAPI IDirectDraw_DuplicateSurface(
675 LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
677 fprintf(stderr,"IDirectDraw(%p)->DuplicateSurface(%p,%p)\n",this,src,dst);
678 *dst = src; /* FIXME */
682 static HRESULT WINAPI IDirectDraw2_CreateSurface(
683 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
687 fprintf(stderr,"IDirectDraw2(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
688 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
689 this->lpvtbl->fnAddRef(this);
691 (*lpdsf)->lpvtbl = &ddsvt;
694 if (!(this->d.vpmask & (1<<i)))
696 fprintf(stderr,"using viewport %d for primary\n",i);
697 /* if i == 32 or maximum ... return error */
698 this->d.vpmask|=(1<<i);
699 (*lpdsf)->surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
700 (*lpdsf)->width = this->d.width;
701 (*lpdsf)->height = this->d.height;
702 (*lpdsf)->ddraw = (LPDIRECTDRAW)this;
703 (*lpdsf)->fb_height = i*this->d.fb_height;
704 (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
705 (*lpdsf)->backbuffer = NULL;
706 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
707 LPDIRECTDRAWSURFACE back;
709 if (lpddsd->dwBackBufferCount>1)
710 fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
712 (*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface2));
713 this->lpvtbl->fnAddRef(this);
715 back->lpvtbl = &ddsvt;
717 if (!(this->d.vpmask & (1<<i)))
719 fprintf(stderr,"using viewport %d for backbuffer\n",i);
720 /* if i == 32 or maximum ... return error */
721 this->d.vpmask|=(1<<i);
722 back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
723 back->fb_height = i*this->d.fb_height;
725 back->width = this->d.width;
726 back->height = this->d.height;
727 back->ddraw = (LPDIRECTDRAW)this;
728 back->lpitch = this->d.fb_width*this->d.depth/8;
729 back->backbuffer = NULL; /* does not have a backbuffer, it is
735 static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
736 LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
744 FE(DDSCL_ALLOWREBOOT)
745 FE(DDSCL_NOWINDOWCHANGES)
750 fprintf(stderr,"IDirectDraw(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
751 this,(DWORD)hwnd,cooplevel
753 fprintf(stderr," cooperative level ");
754 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
755 if (flagmap[i].mask & cooplevel)
756 fprintf(stderr,"%s ",flagmap[i].name);
757 fprintf(stderr,"\n");
758 this->d.mainwindow = hwnd;
762 extern BOOL32 SIGNAL_InitEmulator(void);
764 static HRESULT WINAPI IDirectDraw_SetDisplayMode(
765 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
767 int i,*depths,depcount;
770 fprintf(stderr,"IDirectDraw(%p)->SetDisplayMode(%ld,%ld,%ld),stub!\n",this,width,height,depth);
772 depths = XListDepths(display,DefaultScreen(display),&depcount);
773 for (i=0;i<depcount;i++)
774 if (depths[i]==depth)
777 if (i==depcount) {/* not found */
778 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
779 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
780 return DDERR_UNSUPPORTEDMODE;
782 if (this->d.fb_width < width) {
783 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.fb_width);
784 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
785 return DDERR_UNSUPPORTEDMODE;
787 this->d.width = width;
788 this->d.height = height;
789 /* adjust fb_height, so we don't overlap */
790 if (this->d.fb_height < height)
791 this->d.fb_height = height;
792 this->d.depth = depth;
794 /* FIXME: this function OVERWRITES several signal handlers.
795 * can we save them? and restore them later? In a way that
796 * it works for the library too?
798 XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
799 /* FIXME: can't call this in winelib... so comment only in for debugging.
800 SIGNAL_InitEmulator();
805 static HRESULT WINAPI IDirectDraw_GetCaps(
806 LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
808 fprintf(stderr,"IDirectDraw(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
809 caps1->dwVidMemTotal = this->d.fb_memsize;
810 caps1->dwCaps = 0; /* we cannot do anything */
811 caps1->ddsCaps.dwCaps = 0; /* we cannot do anything */
815 static HRESULT WINAPI IDirectDraw2_GetCaps(
816 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
818 fprintf(stderr,"IDirectDraw2(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
819 caps1->dwVidMemTotal = this->d.fb_memsize;
820 caps1->dwCaps = 0; /* we cannot do anything */
821 caps1->ddsCaps.dwCaps = 0;
826 static struct IDirectDrawClipper_VTable ddclipvt = {
828 (void*)2,(void*)3,(void*)4,(void*)5,
830 (void*)7,(void*)8,(void*)9
833 static HRESULT WINAPI IDirectDraw_CreateClipper(
834 LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
836 fprintf(stderr,"IDirectDraw(%p)->CreateClipper(%08lx,%p,%p),stub!\n",
837 this,x,lpddclip,lpunk
839 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
840 (*lpddclip)->ref = 1;
841 (*lpddclip)->lpvtbl = &ddclipvt;
845 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
846 LPDIRECTDRAWPALETTE this,DWORD x,DWORD y,DWORD z,LPPALETTEENTRY palent
848 fprintf(stderr,"IDirectDrawPalette(%p)->GetEntries(%08lx,%08lx,%08lx,%p),stub!\n",
854 static HRESULT WINAPI IDirectDrawPalette_SetEntries(
855 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
861 fprintf(stderr,"IDirectDrawPalette(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
862 this,x,start,end,palent
865 if (!this->cm) /* should not happen */ {
866 fprintf(stderr,"no colormap in SetEntries???\n");
867 return DDERR_GENERIC;
869 /* FIXME: free colorcells instead of freeing whole map */
870 XFreeColormap(display,this->cm);
871 this->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
873 xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; XStoreColor(display,this->cm,&xc);
876 xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; XStoreColor(display,this->cm,&xc);
878 for (i=start;i<end;i++) {
879 xc.red = palent[i-start].peRed<<8;
880 xc.blue = palent[i-start].peBlue<<8;
881 xc.green = palent[i-start].peGreen<<8;
882 xc.flags = DoRed|DoBlue|DoGreen;
884 XStoreColor(display,this->cm,&xc);
886 XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
890 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
891 fprintf(stderr,"IDirectDrawPalette(%p)->Release()\n",this);
892 if (!--(this->ref)) {
893 fprintf(stderr,"IDirectDrawPalette(%p) freed!\n",this);
895 XFreeColormap(display,this->cm);
898 HeapFree(GetProcessHeap(),0,this);
904 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
905 fprintf(stderr,"IDirectDrawPalette(%p)->AddRef()\n",this);
906 return ++(this->ref);
909 static HRESULT WINAPI IDirectDrawPalette_Initialize(
910 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
912 fprintf(stderr,"IDirectDrawPalette(%p)->Initialize(%p,0x%08lx,%p)\n",this,ddraw,x,palent);
913 return DDERR_ALREADYINITIALIZED;
916 static struct IDirectDrawPalette_VTable ddpalvt = {
918 IDirectDrawPalette_AddRef,
919 IDirectDrawPalette_Release,
921 IDirectDrawPalette_GetEntries,
922 IDirectDrawPalette_Initialize,
923 IDirectDrawPalette_SetEntries
926 static HRESULT WINAPI IDirectDraw_CreatePalette(
927 LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
929 fprintf(stderr,"IDirectDraw(%p)->CreatePalette(%08lx,%p,%p,%p),stub!\n",
930 this,x,palent,lpddpal,lpunk
932 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
934 (*lpddpal)->lpvtbl = &ddpalvt;
935 (*lpddpal)->ddraw = this;
936 if (this->d.depth<=8) {
937 (*lpddpal)->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
938 fprintf(stderr,"created colormap...\n");
939 } else /* we don't want palettes in hicolor or truecolor */
945 static HRESULT WINAPI IDirectDraw2_CreatePalette(
946 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
948 return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
951 static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
952 LPDIRECTDRAW this,DWORD x,HANDLE32 h
954 fprintf(stderr,"IDirectDraw(%p)->WaitForVerticalBlank(0x%08lx,0x%08x),stub!\n",this,x,h);
958 static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
959 dprintf_relay(stderr,"IDirectDraw(%p)->AddRef()\n",this);
960 return ++(this->ref);
963 static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) {
964 dprintf_relay(stderr,"IDirectDraw(%p)->Release()\n",this);
965 if (!--(this->ref)) {
966 fprintf(stderr,"IDirectDraw::Release:freeing IDirectDraw(%p)\n",this);
967 XF86DGADirectVideo(display,DefaultScreen(display),0);
968 HeapFree(GetProcessHeap(),0,this);
974 static HRESULT WINAPI IDirectDraw2_QueryInterface(
975 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
977 return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
980 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
981 return IDirectDraw_AddRef((LPDIRECTDRAW)this);
984 static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
985 return IDirectDraw_Release((LPDIRECTDRAW)this);
988 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
989 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
991 fprintf(stderr,"IDirectDraw2(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
994 this->d.mainwindow = hwnd;
998 static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
999 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
1001 fprintf(stderr,"IDirectDraw2(%p)->SetDisplayMode(%ld,%ld,%ld,%08lx,%08lx),stub!\n",this,width,height,depth,xx,yy);
1003 return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
1006 static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1007 fprintf(stderr,"IDirectDraw2(%p)->RestoreDisplayMode(),stub!\n",this);
1008 XF86DGADirectVideo(display,DefaultScreen(display),0);
1012 static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
1013 fprintf(stderr,"IDirectDraw(%p)->RestoreDisplayMode(),stub!\n",this);
1014 XF86DGADirectVideo(display,DefaultScreen(display),0);
1018 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1019 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1021 fprintf(stderr,"IDirectDraw2(%p)->EnumSurfaces(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1025 static IDirectDraw2_VTable dd2vt = {
1026 IDirectDraw2_QueryInterface,
1027 IDirectDraw2_AddRef,
1028 IDirectDraw2_Release,
1030 (void*)5/*IDirectDraw_CreateClipper*/,
1031 IDirectDraw2_CreatePalette,
1032 IDirectDraw2_CreateSurface,
1035 IDirectDraw2_EnumSurfaces,
1037 IDirectDraw2_GetCaps,
1045 IDirectDraw2_RestoreDisplayMode,
1046 IDirectDraw2_SetCooperativeLevel,
1047 IDirectDraw2_SetDisplayMode,
1048 (void*)23/*IDirectDraw_WaitForVerticalBlank*/,
1052 static HRESULT WINAPI IDirectDraw_QueryInterface(
1053 LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
1057 StringFromCLSID((LPCLSID)refiid,xrefiid);
1058 fprintf(stderr,"IDirectDraw(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
1059 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1061 this->lpvtbl->fnAddRef(this);
1064 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1065 /* FIXME FIXME FIXME */
1066 this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt;
1067 this->lpvtbl->fnAddRef(this);
1071 return OLE_E_ENUM_NOMORE;
1074 static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus(
1075 LPDIRECTDRAW this,BOOL32 *status
1077 fprintf(stderr,"IDirectDraw(%p)->GetVerticalBlankSatus(%p)\n",this,status);
1082 static HRESULT WINAPI IDirectDraw_EnumDisplayModes(
1083 LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1085 DDSURFACEDESC ddsfd;
1087 fprintf(stderr,"IDirectDraw(%p)->EnumDisplayModes(0x%08lx,%p,%p,%p),stub!\n",this,dwFlags,lpddsfd,context,modescb);
1088 ddsfd.dwSize = sizeof(ddsfd);
1089 fprintf(stderr,"size is %d\n",sizeof(ddsfd));
1090 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1091 ddsfd.dwHeight = 480;
1092 ddsfd.dwWidth = 640;
1094 ddsfd.dwBackBufferCount = 1;
1095 ddsfd.x.dwRefreshRate = 60;
1096 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1098 _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1099 fprintf(stderr,"modescb returned: 0x%lx\n",(DWORD)modescb(&ddsfd,context));
1103 static HRESULT WINAPI IDirectDraw_GetDisplayMode(
1104 LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
1106 fprintf(stderr,"IDirectDraw(%p)->GetDisplayMode(%p),stub!\n",this,lpddsfd);
1107 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1108 lpddsfd->dwHeight = this->d.vp_height;
1109 lpddsfd->dwWidth = this->d.vp_width;
1110 lpddsfd->lPitch = this->d.fb_width*this->d.depth/8;
1111 lpddsfd->dwBackBufferCount = 1;
1112 lpddsfd->x.dwRefreshRate = 60;
1113 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1114 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1119 static IDirectDraw_VTable ddvt = {
1120 IDirectDraw_QueryInterface,
1122 IDirectDraw_Release,
1124 IDirectDraw_CreateClipper,
1125 IDirectDraw_CreatePalette,
1126 IDirectDraw_CreateSurface,
1127 IDirectDraw_DuplicateSurface,
1128 IDirectDraw_EnumDisplayModes,
1131 IDirectDraw_GetCaps,
1132 IDirectDraw_GetDisplayMode,
1137 IDirectDraw_GetVerticalBlankStatus,
1139 IDirectDraw_RestoreDisplayMode,
1140 IDirectDraw_SetCooperativeLevel,
1141 IDirectDraw_SetDisplayMode,
1142 IDirectDraw_WaitForVerticalBlank,
1146 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1149 int memsize,banksize,width,evbase,evret,major,minor,flags,height;
1154 StringFromCLSID(lpGUID,xclsid);
1156 strcpy(xclsid,"<null>");
1158 fprintf(stderr,"DirectDrawCreate(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
1160 MessageBox32A(0,"Using the XF86DGA extensions requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1161 return E_UNEXPECTED;
1163 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
1164 (*lplpDD)->lpvtbl = &ddvt;
1166 if (!XF86DGAQueryExtension(display,&evbase,&evret)) {
1167 fprintf(stderr,"No XF86DGA detected.\n");
1170 XF86DGAQueryVersion(display,&major,&minor);
1171 fprintf(stderr,"XF86DGA is version %d.%d\n",major,minor);
1172 XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
1173 if (!(flags & XF86DGADirectPresent))
1174 fprintf(stderr,"direct video is NOT ENABLED.\n");
1175 XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
1176 fprintf(stderr,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
1177 addr,width,banksize,memsize
1179 (*lplpDD)->d.fb_width = width;
1180 (*lplpDD)->d.fb_addr = addr;
1181 (*lplpDD)->d.fb_memsize = memsize;
1182 (*lplpDD)->d.fb_banksize = banksize;
1184 XF86DGASetViewPort(display,DefaultScreen(display),0,0);
1185 XF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
1186 (*lplpDD)->d.vp_width = width;
1187 (*lplpDD)->d.vp_height = height;
1188 (*lplpDD)->d.fb_height = height;
1189 (*lplpDD)->d.vpmask = 0;
1194 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1195 MessageBox32A(0,"WINE DirectDraw needs the XF86DGA extensions compiled in. (libXxf86dga.a).","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1196 return E_OUTOFMEMORY;