Stefan Dösinger : wined3d: Implement IWineD3DPalette.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Apr 21 05:02:34 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: a6f71af021b0846771243026c4f3bdc55e6779bc
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=a6f71af021b0846771243026c4f3bdc55e6779bc

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Apr 21 00:00:30 2006 +0200

wined3d: Implement IWineD3DPalette.

---

 dlls/wined3d/device.c          |   22 +++++++++-
 dlls/wined3d/palette.c         |   92 ++++++++++++++++++++++++++++++++++++----
 dlls/wined3d/wined3d_private.h |   14 ++++++
 3 files changed, 117 insertions(+), 11 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 93acc84..790ac12 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1623,21 +1623,39 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
 HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DWORD Flags, PALETTEENTRY *PalEnt, IWineD3DPalette **Palette, IUnknown *Parent) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DPaletteImpl *object;
+    HRESULT hr;
     TRACE("(%p)->(%lx, %p, %p, %p)\n", This, Flags, PalEnt, Palette, Parent);
 
     /* Create the new object */
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DPaletteImpl));
     if(!object) {
         ERR("Out of memory when allocating memory for a IWineD3DPalette implementation\n");
-        return DDERR_OUTOFVIDEOMEMORY;
+        return E_OUTOFMEMORY;
     }
 
     object->lpVtbl = &IWineD3DPalette_Vtbl;
     object->ref = 1;
+    object->Flags = Flags;
+    object->parent = Parent;
+    object->wineD3DDevice = This;
+    object->palNumEntries = IWineD3DPaletteImpl_Size(Flags);
+	
+    object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion));
+
+    if(!object->hpal) {
+        HeapFree( GetProcessHeap(), 0, object);
+        return E_OUTOFMEMORY;
+    }
+
+    hr = IWineD3DPalette_SetEntries((IWineD3DPalette *) object, 0, 0, IWineD3DPaletteImpl_Size(Flags), PalEnt);
+    if(FAILED(hr)) {
+        IWineD3DPalette_Release((IWineD3DPalette *) object);
+        return hr;
+    }
 
     *Palette = (IWineD3DPalette *) object;
 
-    return DD_OK;
+    return WINED3D_OK;
 }
 
 HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) {
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index 650ac4e..ebc3429 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -29,6 +29,8 @@ #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
+#define SIZE_BITS (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT)
+
 HRESULT WINAPI IWineD3DPaletteImpl_QueryInterface(IWineD3DPalette *iface, REFIID refiid, void **obj) {
     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
@@ -67,24 +69,96 @@ ULONG WINAPI IWineD3DPaletteImpl_Release
     return ref;
 }
 
+/* Not called from the vtable */
+DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) {
+    switch (dwFlags & SIZE_BITS) {
+        case DDPCAPS_1BIT: return 2;
+        case DDPCAPS_2BIT: return 4;
+        case DDPCAPS_4BIT: return 16;
+        case DDPCAPS_8BIT: return 256;
+        default: assert(0); return 256;
+    }
+}
+
 HRESULT WINAPI IWineD3DPaletteImpl_GetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt) {
-    FIXME("This is unimplemented for now(d3d7 merge)\n");
-    return DDERR_INVALIDPARAMS;
+    IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
+
+    TRACE("(%p)->(%08lx,%ld,%ld,%p)\n",This,Flags,Start,Count,PalEnt);
+
+    if (Flags != 0) return WINED3DERR_INVALIDCALL; /* unchecked */
+    if (Start + Count > IWineD3DPaletteImpl_Size(This->Flags))
+        return WINED3DERR_INVALIDCALL;
+
+    if (This->Flags & DDPCAPS_8BITENTRIES)
+    {
+        unsigned int i;
+        LPBYTE entry = (LPBYTE)PalEnt;
+
+        for (i=Start; i < Count+Start; i++)
+            *entry++ = This->palents[i].peRed;
+    }
+    else
+        memcpy(PalEnt, This->palents+Start, Count * sizeof(PALETTEENTRY));
+
+    return WINED3D_OK;
 }
 
-HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt) {
-    FIXME("This is unimplemented for now(d3d7 merge)\n");
-    return DDERR_INVALIDPARAMS;
+HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt)
+{
+    IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
+    ResourceList *res;
+
+    TRACE("(%p)->(%08lx,%ld,%ld,%p)\n",This,Flags,Start,Count,PalEnt);
+
+    if (This->Flags & DDPCAPS_8BITENTRIES) {
+        unsigned int i;
+        const BYTE* entry = (const BYTE*)PalEnt;
+
+        for (i=Start; i < Count+Start; i++)
+            This->palents[i].peRed = *entry++;
+    }
+    else {
+        memcpy(This->palents+Start, PalEnt, Count * sizeof(PALETTEENTRY));
+
+        if (This->hpal)
+            SetPaletteEntries(This->hpal, Start, Count, This->palents+Start);
+    }
+
+#if 0
+    /* Now, if we are in 'depth conversion mode', update the screen palette */
+    /* FIXME: we need to update the image or we won't get palette fading. */
+    if (This->ddraw->d->palette_convert != NULL)
+        This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
+#endif
+
+    /* If the palette is attached to the render target, update all render targets */
+
+    for(res = This->wineD3DDevice->resources; res != NULL; res=res->next) {
+        if(IWineD3DResource_GetType(res->resource) == D3DRTYPE_SURFACE) {
+            IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res->resource;
+            if(impl->palette == This)
+                IWineD3DSurface_RealizePalette( (IWineD3DSurface *) res->resource);
+        }
+    }
+
+    return WINED3D_OK;
 }
 
 HRESULT WINAPI IWineD3DPaletteImpl_GetCaps(IWineD3DPalette *iface, DWORD *Caps) {
-    FIXME("This is unimplemented for now(d3d7 merge)\n");
-    return DDERR_INVALIDPARAMS;
+    IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
+    TRACE("(%p)->(%p)\n", This, Caps);
+
+    *Caps = This->Flags;
+    return WINED3D_OK;
 }
 
 HRESULT WINAPI IWineD3DPaletteImpl_GetParent(IWineD3DPalette *iface, IUnknown **Parent) {
-    FIXME("This is unimplemented for now(d3d7 merge)\n");
-    return DDERR_INVALIDPARAMS;
+    IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
+    TRACE("(%p)->(%p)\n", This, Parent);
+
+    *Parent = (IUnknown *) This->parent;
+    IUnknown_AddRef( (IUnknown *) This->parent);
+    return WINED3D_OK;
 }
 
 const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl =
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 55a92f7..9ac0e41 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -830,6 +830,7 @@ struct IWineD3DSurfaceImpl
     /* IWineD3DSurface fields */
     IWineD3DBase              *container;
     WINED3DSURFACET_DESC      currentDesc;
+    IWineD3DPaletteImpl      *palette;
 
     UINT                      textureName;
     UINT                      bytesPerPixel;
@@ -1282,9 +1283,22 @@ struct IWineD3DPaletteImpl {
     /* IUnknown parts */
     const IWineD3DPaletteVtbl  *lpVtbl;
     LONG                       ref;
+
+    IUnknown                   *parent;
+    IWineD3DDeviceImpl         *wineD3DDevice;
+
+    /* IWineD3DPalette */
+    HPALETTE                   hpal;
+    WORD                       palVersion;     /*|               */
+    WORD                       palNumEntries;  /*|  LOGPALETTE   */
+    PALETTEENTRY               palents[256];   /*|               */
+    /* This is to store the palette in 'screen format' */
+    int                        screen_palents[256];
+    DWORD                      Flags;
 };
 
 extern const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl;
+DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags);
 
 /* DirectDraw utility functions */
 extern WINED3DFORMAT pixelformat_for_depth(DWORD depth);




More information about the wine-cvs mailing list