1 /* DirectDraw - IDirectPalette base interface
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 2000-2001 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);
42 This->local.lpGbl = &This->global;
43 This->local.lpDD_lcl = &pDD->local;
44 This->global.lpDD_lcl = &pDD->local;
45 This->global.dwProcessId = GetCurrentProcessId();
47 This->final_release = Main_DirectDrawPalette_final_release;
48 ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_Main_Palette_VTable);
50 /* we could defer hpal creation until we need it,
51 * but does anyone have a case where it would be useful? */
52 This->hpal = CreatePalette((const LOGPALETTE*)&(This->palVersion));
54 Main_DirectDraw_AddPalette(pDD, This);
60 Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
61 LPDIRECTDRAWPALETTE* ppPalette,
64 IDirectDrawPaletteImpl* This;
67 if (pUnkOuter != NULL)
68 return CLASS_E_NOAGGREGATION; /* unchecked */
70 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
71 if (This == NULL) return E_OUTOFMEMORY;
73 hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags);
75 HeapFree(GetProcessHeap(), 0, This);
77 *ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette);
82 DWORD Main_DirectDrawPalette_Size(DWORD dwFlags)
84 switch (dwFlags & SIZE_BITS)
86 case DDPCAPS_1BIT: return 2;
87 case DDPCAPS_2BIT: return 4;
88 case DDPCAPS_4BIT: return 16;
89 case DDPCAPS_8BIT: return 256;
90 default: assert(0); return 256;
95 Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
96 DWORD dwStart, DWORD dwCount,
97 LPPALETTEENTRY palent)
99 ICOM_THIS(IDirectDrawPaletteImpl,iface);
101 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
104 if (dwFlags != 0) return DDERR_INVALIDPARAMS; /* unchecked */
105 if (dwStart + dwCount > Main_DirectDrawPalette_Size(This->flags))
106 return DDERR_INVALIDPARAMS;
108 if (This->flags & DDPCAPS_8BITENTRIES)
111 LPBYTE entry = (LPBYTE)palent;
113 for (i=dwStart; i < dwCount+dwStart; i++)
114 *entry++ = This->palents[i].peRed;
117 memcpy(palent, This->palents+dwStart, dwCount * sizeof(PALETTEENTRY));
123 Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
124 DWORD dwStart, DWORD dwCount,
125 LPPALETTEENTRY palent)
127 ICOM_THIS(IDirectDrawPaletteImpl,iface);
129 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
132 if (This->flags & DDPCAPS_8BITENTRIES)
135 const BYTE* entry = (const BYTE*)palent;
137 for (i=dwStart; i < dwCount+dwStart; i++)
138 This->palents[i].peRed = *entry++;
141 memcpy(This->palents+dwStart, palent, dwCount * sizeof(PALETTEENTRY));
144 SetPaletteEntries(This->hpal, dwStart, dwCount, This->palents+dwStart);
146 if (This->flags & DDPCAPS_PRIMARYSURFACE) {
147 /* update physical palette */
148 LPDIRECTDRAWSURFACE7 psurf = NULL;
149 IDirectDraw7_GetGDISurface(ICOM_INTERFACE(This->ddraw_owner,IDirectDraw7), &psurf);
151 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
152 IDirectDrawSurface7, psurf);
153 surf->update_palette(surf, This, dwStart, dwCount, palent);
154 IDirectDrawSurface7_Release(psurf);
156 else ERR("can't find GDI surface!!\n");
161 /* Now, if we are in 'depth conversion mode', update the screen palette */
162 /* FIXME: we need to update the image or we won't get palette fading. */
163 if (This->ddraw->d->palette_convert != NULL)
164 This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
170 void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This)
172 Main_DirectDraw_RemovePalette(This->ddraw_owner, This);
174 if (This->hpal) DeleteObject(This->hpal);
177 static void Main_DirectDrawPalette_Destroy(IDirectDrawPaletteImpl* This)
179 This->final_release(This);
181 if (This->private != This+1)
182 HeapFree(GetProcessHeap(), 0, This->private);
184 HeapFree(GetProcessHeap(),0,This);
187 void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This)
189 WARN("deleting palette %p with refcnt %lu\n", This, This->ref);
190 Main_DirectDrawPalette_Destroy(This);
194 Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface)
196 ICOM_THIS(IDirectDrawPaletteImpl,iface);
197 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
201 Main_DirectDrawPalette_Destroy(This);
208 ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface) {
209 ICOM_THIS(IDirectDrawPaletteImpl,iface);
210 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
215 Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface,
216 LPDIRECTDRAW ddraw, DWORD dwFlags,
217 LPPALETTEENTRY palent)
219 ICOM_THIS(IDirectDrawPaletteImpl,iface);
220 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, dwFlags, palent);
221 return DDERR_ALREADYINITIALIZED;
225 Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps)
227 ICOM_THIS(IDirectDrawPaletteImpl,iface);
228 TRACE("(%p)->(%p)\n",This,lpdwCaps);
230 *lpdwCaps = This->flags;
236 Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface,
237 REFIID refiid, LPVOID *obj)
239 ICOM_THIS(IDirectDrawPaletteImpl,iface);
240 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
242 if (IsEqualGUID(refiid, &IID_IUnknown)
243 || IsEqualGUID(refiid, &IID_IDirectDrawPalette))
246 IDirectDrawPalette_AddRef(iface);
251 return E_NOINTERFACE;
255 static ICOM_VTABLE(IDirectDrawPalette) DDRAW_Main_Palette_VTable =
257 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
258 Main_DirectDrawPalette_QueryInterface,
259 Main_DirectDrawPalette_AddRef,
260 Main_DirectDrawPalette_Release,
261 Main_DirectDrawPalette_GetCaps,
262 Main_DirectDrawPalette_GetEntries,
263 Main_DirectDrawPalette_Initialize,
264 Main_DirectDrawPalette_SetEntries