diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b2743939e71..5928561b224 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -7435,24 +7435,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i UINT YHotSpot, IWineD3DSurface *pCursorBitmap) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; /* TODO: the use of Impl is deprecated. */ - /* some basic validation checks */ IWineD3DSurfaceImpl * pSur = (IWineD3DSurfaceImpl *) pCursorBitmap; TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot); - if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) { - ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap); - return WINED3DERR_INVALIDCALL; + /* some basic validation checks */ + if(pCursorBitmap) { + /* MSDN: Cursor must be A8R8G8B8 */ + if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) { + ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap); + return WINED3DERR_INVALIDCALL; + } + + /* MSDN: Cursor must be smaller than the display mode */ + if(pSur->currentDesc.Width > This->ddraw_width || + pSur->currentDesc.Height > This->ddraw_height) { + ERR("(%p) : Surface(%p) is %dx%d pixels, but screen res is %ldx%ld\n", This, pSur, pSur->currentDesc.Width, pSur->currentDesc.Height, This->ddraw_width, This->ddraw_height); + return WINED3DERR_INVALIDCALL; + } + + /* TODO: MSDN: Cursor sizes must be a power of 2 */ + if(This->mouseCursor) { + ((IWineD3DSurfaceImpl *) This->mouseCursor)->Flags &= ~SFLAG_FORCELOAD; + } + /* This is to tell our texture code to load a SCRATCH surface. This allows us to use out + * Texture and Blitting code to draw the cursor + */ + pSur->Flags |= SFLAG_FORCELOAD; } - if (32 != pSur->currentDesc.Height || 32 != pSur->currentDesc.Width) { - ERR("(%p) : surface(%p) has an invalid size\n", This, pCursorBitmap); - return WINED3DERR_INVALIDCALL; - } - /* TODO: make the cursor 'real' */ This->xHotSpot = XHotSpot; This->yHotSpot = YHotSpot; + This->mouseCursor = pCursorBitmap; return WINED3D_OK; } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 0e90f13c3f6..9c2ed607eaf 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1638,7 +1638,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) { * these resources cannot be accessed by the Direct3D device nor set as textures or render targets. * However, these resources can always be created, locked, and copied. */ - if (This->resource.pool == WINED3DPOOL_SCRATCH) + if (This->resource.pool == WINED3DPOOL_SCRATCH && !(This->Flags & SFLAG_FORCELOAD) ) { FIXME("(%p) Operation not supported for scratch textures\n",This); return WINED3DERR_INVALIDCALL; @@ -2034,7 +2034,7 @@ extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, C This->dirtyRect.right = This->currentDesc.Width; This->dirtyRect.bottom = This->currentDesc.Height; } - TRACE("(%p) : Dirty?%d, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left, + TRACE("(%p) : Dirty?%ld, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left, This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom); /* if the container is a basetexture then mark it dirty. */ if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e4b385de89f..9dde98723ee 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -141,6 +141,20 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO ENTER_GL(); + /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ + if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->mouseCursor) { + IWineD3DSurfaceImpl *cursor = (IWineD3DSurfaceImpl *) This->wineD3DDevice->mouseCursor; + RECT destRect = {This->wineD3DDevice->xScreenSpace - This->wineD3DDevice->xHotSpot, + This->wineD3DDevice->yScreenSpace - This->wineD3DDevice->yHotSpot, + This->wineD3DDevice->xScreenSpace + cursor->currentDesc.Width - This->wineD3DDevice->xHotSpot, + This->wineD3DDevice->yScreenSpace + cursor->currentDesc.Height - This->wineD3DDevice->yHotSpot}; + TRACE("Rendering the cursor\n"); + /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0, + * which is exactly what we want :-) + */ + IWineD3DSurface_Blt(This->backBuffer[0], &destRect, This->wineD3DDevice->mouseCursor, NULL, DDBLT_KEYSRC, NULL); + } + if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect); /* TODO: If only source rect or dest rect are supplied then clip the window to match */ TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d542086daca..c910c670150 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -540,6 +540,7 @@ typedef struct IWineD3DDeviceImpl UINT yHotSpot; UINT xScreenSpace; UINT yScreenSpace; + IWineD3DSurface *mouseCursor; /* Textures for when no other textures are mapped */ UINT dummyTextureName[MAX_TEXTURES]; @@ -853,7 +854,7 @@ struct IWineD3DSurfaceImpl UINT bytesPerPixel; /* TODO: move this off into a management class(maybe!) */ - WORD Flags; + DWORD Flags; UINT pow2Width; UINT pow2Height; @@ -930,22 +931,24 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPitch(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface); /* Surface flags: */ -#define SFLAG_OVERSIZE 0x0001 /* Surface is bigger than gl size, blts only */ -#define SFLAG_CONVERTED 0x0002 /* Converted for color keying or Palettized */ -#define SFLAG_DIBSECTION 0x0004 /* Has a DIB section attached for getdc */ -#define SFLAG_DIRTY 0x0008 /* Surface was locked by the app */ -#define SFLAG_LOCKABLE 0x0010 /* Surface can be locked */ -#define SFLAG_DISCARD 0x0020 /* ??? */ -#define SFLAG_LOCKED 0x0040 /* Surface is locked atm */ -#define SFLAG_ACTIVELOCK 0x0080 /* Not locked, but surface memory is needed */ -#define SFLAG_INTEXTURE 0x0100 /* ??? */ -#define SFLAG_INPBUFFER 0x0200 /* ??? */ -#define SFLAG_NONPOW2 0x0400 /* Surface sizes are not a power of 2 */ -#define SFLAG_DYNLOCK 0x0800 /* Surface is often locked by the app */ -#define SFLAG_DYNCHANGE 0x1800 /* Surface contents are changed very often, implies DYNLOCK */ -#define SFLAG_DCINUSE 0x2000 /* Set between GetDC and ReleaseDC calls */ -#define SFLAG_GLDIRTY 0x4000 /* The opengl texture is more up to date than the surface mem */ -#define SFLAG_LOST 0x8000 /* Surface lost flag for DDraw */ +#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ +#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */ +#define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for getdc */ +#define SFLAG_DIRTY 0x00000008 /* Surface was locked by the app */ +#define SFLAG_LOCKABLE 0x00000010 /* Surface can be locked */ +#define SFLAG_DISCARD 0x00000020 /* ??? */ +#define SFLAG_LOCKED 0x00000040 /* Surface is locked atm */ +#define SFLAG_ACTIVELOCK 0x00000080 /* Not locked, but surface memory is needed */ +#define SFLAG_INTEXTURE 0x00000100 /* ??? */ +#define SFLAG_INPBUFFER 0x00000200 /* ??? */ +#define SFLAG_NONPOW2 0x00000400 /* Surface sizes are not a power of 2 */ +#define SFLAG_DYNLOCK 0x00000800 /* Surface is often locked by the app */ +#define SFLAG_DYNCHANGE 0x00001800 /* Surface contents are changed very often, implies DYNLOCK */ +#define SFLAG_DCINUSE 0x00002000 /* Set between GetDC and ReleaseDC calls */ +#define SFLAG_GLDIRTY 0x00004000 /* The opengl texture is more up to date than the surface mem */ +#define SFLAG_LOST 0x00008000 /* Surface lost flag for DDraw */ +#define SFLAG_FORCELOAD 0x00010000 /* To force PreLoading of a scratch cursor */ + /* In some conditions the surface memory must not be freed: * SFLAG_OVERSIZE: Not all data can be kept in GL