1 /* DirectDraw - IDirectPalette base interface
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 2000 TransGaming Technologies Inc.
9 #include "debugtools.h"
14 #include "ddraw_private.h"
15 #include "dpalette/main.h"
16 #include "ddraw/main.h"
18 DEFAULT_DEBUG_CHANNEL(ddraw);
20 #define SIZE_BITS (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT)
22 /* For unsigned x. 0 is not a power of 2. */
23 #define IS_POW_2(x) (((x) & ((x) - 1)) == 0)
25 static ICOM_VTABLE(IDirectDrawPalette) DDRAW_Main_Palette_VTable;
27 /******************************************************************************
30 HRESULT Main_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
31 IDirectDrawImpl* pDD, DWORD dwFlags)
33 if (!IS_POW_2(dwFlags & SIZE_BITS)) return DDERR_INVALIDPARAMS;
35 if (dwFlags & DDPCAPS_8BITENTRIES)
36 WARN("creating palette with 8 bit entries\n");
38 This->flags = dwFlags;
39 This->palNumEntries = Main_DirectDrawPalette_Size(dwFlags);
41 This->final_release = Main_DirectDrawPalette_final_release;
42 ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_Main_Palette_VTable);
44 /* we could defer hpal creation until we need it,
45 * but does anyone have a case where it would be useful? */
46 This->hpal = CreatePalette((const LOGPALETTE*)&(This->palVersion));
48 Main_DirectDraw_AddPalette(pDD, This);
54 Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
55 LPDIRECTDRAWPALETTE* ppPalette,
58 IDirectDrawPaletteImpl* This;
61 if (pUnkOuter != NULL)
62 return CLASS_E_NOAGGREGATION; /* unchecked */
64 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
65 if (This == NULL) return E_OUTOFMEMORY;
67 hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags);
69 HeapFree(GetProcessHeap(), 0, This);
71 *ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette);
76 DWORD Main_DirectDrawPalette_Size(DWORD dwFlags)
78 switch (dwFlags & SIZE_BITS)
80 case DDPCAPS_1BIT: return 2;
81 case DDPCAPS_2BIT: return 4;
82 case DDPCAPS_4BIT: return 16;
83 case DDPCAPS_8BIT: return 256;
84 default: assert(0); return 256;
89 Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
90 DWORD dwStart, DWORD dwCount,
91 LPPALETTEENTRY palent)
93 ICOM_THIS(IDirectDrawPaletteImpl,iface);
95 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
98 if (dwFlags != 0) return DDERR_INVALIDPARAMS; /* unchecked */
99 if (dwStart + dwCount > Main_DirectDrawPalette_Size(This->flags))
100 return DDERR_INVALIDPARAMS;
102 if (This->flags & DDPCAPS_8BITENTRIES)
105 LPBYTE entry = (LPBYTE)palent;
107 for (i=dwStart; i < dwCount+dwStart; i++)
108 *entry++ = This->palents[i].peRed;
111 memcpy(palent, This->palents+dwStart, dwCount * sizeof(PALETTEENTRY));
117 Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
118 DWORD dwStart, DWORD dwCount,
119 LPPALETTEENTRY palent)
121 ICOM_THIS(IDirectDrawPaletteImpl,iface);
123 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
126 if (This->flags & DDPCAPS_8BITENTRIES)
129 const BYTE* entry = (const BYTE*)palent;
131 for (i=dwStart; i < dwCount+dwStart; i++)
132 This->palents[i].peRed = *entry++;
135 memcpy(This->palents+dwStart, palent, dwCount * sizeof(PALETTEENTRY));
138 SetPaletteEntries(This->hpal, dwStart, dwCount, This->palents+dwStart);
140 if (This->flags & DDPCAPS_PRIMARYSURFACE) {
141 /* update physical palette */
142 LPDIRECTDRAWSURFACE7 psurf = NULL;
143 IDirectDraw7_GetGDISurface(ICOM_INTERFACE(This->ddraw_owner,IDirectDraw7), &psurf);
145 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
146 IDirectDrawSurface7, psurf);
147 surf->update_palette(surf, This, dwStart, dwCount, palent);
148 IDirectDrawSurface7_Release(psurf);
150 else ERR("can't find GDI surface!!\n");
155 /* Now, if we are in 'depth conversion mode', update the screen palette */
156 /* FIXME: we need to update the image or we won't get palette fading. */
157 if (This->ddraw->d->palette_convert != NULL)
158 This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
164 void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This)
166 Main_DirectDraw_RemovePalette(This->ddraw_owner, This);
168 if (This->hpal) DeleteObject(This->hpal);
171 static void Main_DirectDrawPalette_Destroy(IDirectDrawPaletteImpl* This)
173 This->final_release(This);
175 if (This->private != This+1)
176 HeapFree(GetProcessHeap(), 0, This->private);
178 HeapFree(GetProcessHeap(),0,This);
181 void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This)
183 WARN("deleting palette %p with refcnt %lu\n", This, This->ref);
184 Main_DirectDrawPalette_Destroy(This);
188 Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface)
190 ICOM_THIS(IDirectDrawPaletteImpl,iface);
191 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
195 Main_DirectDrawPalette_Destroy(This);
202 ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface) {
203 ICOM_THIS(IDirectDrawPaletteImpl,iface);
204 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
209 Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface,
210 LPDIRECTDRAW ddraw, DWORD dwFlags,
211 LPPALETTEENTRY palent)
213 ICOM_THIS(IDirectDrawPaletteImpl,iface);
214 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, dwFlags, palent);
215 return DDERR_ALREADYINITIALIZED;
219 Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps)
221 ICOM_THIS(IDirectDrawPaletteImpl,iface);
222 TRACE("(%p)->(%p)\n",This,lpdwCaps);
224 *lpdwCaps = This->flags;
230 Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface,
231 REFIID refiid, LPVOID *obj)
233 ICOM_THIS(IDirectDrawPaletteImpl,iface);
234 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
236 if (IsEqualGUID(refiid, &IID_IUnknown)
237 || IsEqualGUID(refiid, &IID_IDirectDrawPalette))
240 IDirectDrawPalette_AddRef(iface);
245 return E_NOINTERFACE;
249 static ICOM_VTABLE(IDirectDrawPalette) DDRAW_Main_Palette_VTable =
251 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
252 Main_DirectDrawPalette_QueryInterface,
253 Main_DirectDrawPalette_AddRef,
254 Main_DirectDrawPalette_Release,
255 Main_DirectDrawPalette_GetCaps,
256 Main_DirectDrawPalette_GetEntries,
257 Main_DirectDrawPalette_Initialize,
258 Main_DirectDrawPalette_SetEntries