xref: /reactos/dll/directx/wine/wined3d/palette.c (revision da5f10af)
1 /*              DirectDraw - IDirectPalette base interface
2  *
3  * Copyright 1997-2000 Marcus Meissner
4  * Copyright 2000-2001 TransGaming Technologies Inc.
5  * Copyright 2006 Stefan Dösinger for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 #include "config.h"
22 #include "wine/port.h"
23 #include "wined3d_private.h"
24 
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
26 
27 ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette)
28 {
29     ULONG refcount = InterlockedIncrement(&palette->ref);
30 
31     TRACE("%p increasing refcount to %u.\n", palette, refcount);
32 
33     return refcount;
34 }
35 
36 static void wined3d_palette_destroy_object(void *object)
37 {
38     heap_free(object);
39 }
40 
41 ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
42 {
43     ULONG refcount = InterlockedDecrement(&palette->ref);
44 
45     TRACE("%p decreasing refcount to %u.\n", palette, refcount);
46 
47     if (!refcount)
48         wined3d_cs_destroy_object(palette->device->cs, wined3d_palette_destroy_object, palette);
49 
50     return refcount;
51 }
52 
53 HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette,
54         DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries)
55 {
56     unsigned int i;
57     TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
58             palette, flags, start, count, entries);
59 
60     if (flags)
61         return WINED3DERR_INVALIDCALL; /* unchecked */
62     if (start > palette->size || count > palette->size - start)
63         return WINED3DERR_INVALIDCALL;
64 
65     if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES)
66     {
67         BYTE *entry = (BYTE *)entries;
68 
69         for (i = start; i < count + start; ++i)
70             *entry++ = palette->colors[i].rgbRed;
71     }
72     else
73     {
74         for (i = 0; i < count; ++i)
75         {
76             entries[i].peRed = palette->colors[i + start].rgbRed;
77             entries[i].peGreen = palette->colors[i + start].rgbGreen;
78             entries[i].peBlue = palette->colors[i + start].rgbBlue;
79             entries[i].peFlags = palette->colors[i + start].rgbReserved;
80         }
81     }
82 
83     return WINED3D_OK;
84 }
85 
86 void CDECL wined3d_palette_apply_to_dc(const struct wined3d_palette *palette, HDC dc)
87 {
88     if (SetDIBColorTable(dc, 0, 256, palette->colors) != 256)
89 #ifdef __REACTOS__
90     {
91         static int warn_once;
92         if (!warn_once++)
93             ERR("Failed to set DIB color table. (Only printing once)\n");
94     }
95 #else
96         ERR("Failed to set DIB color table.\n");
97 #endif
98 }
99 
100 HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
101         DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries)
102 {
103     unsigned int i;
104 
105     TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
106             palette, flags, start, count, entries);
107     TRACE("Palette flags: %#x.\n", palette->flags);
108 
109     if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES)
110     {
111         const BYTE *entry = (const BYTE *)entries;
112 
113         for (i = start; i < count + start; ++i)
114             palette->colors[i].rgbRed = *entry++;
115     }
116     else
117     {
118         for (i = 0; i < count; ++i)
119         {
120             palette->colors[i + start].rgbRed = entries[i].peRed;
121             palette->colors[i + start].rgbGreen = entries[i].peGreen;
122             palette->colors[i + start].rgbBlue = entries[i].peBlue;
123             palette->colors[i + start].rgbReserved = entries[i].peFlags;
124         }
125 
126         /* When WINEDDCAPS_ALLOW256 isn't set we need to override entry 0 with black and 255 with white */
127         if (!(palette->flags & WINED3D_PALETTE_ALLOW_256))
128         {
129             TRACE("WINED3D_PALETTE_ALLOW_256 not set, overriding palette entry 0 with black and 255 with white.\n");
130             palette->colors[0].rgbRed = 0;
131             palette->colors[0].rgbGreen = 0;
132             palette->colors[0].rgbBlue = 0;
133 
134             palette->colors[255].rgbRed = 255;
135             palette->colors[255].rgbGreen = 255;
136             palette->colors[255].rgbBlue = 255;
137         }
138     }
139 
140     return WINED3D_OK;
141 }
142 
143 static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device,
144         DWORD flags, unsigned int entry_count, const PALETTEENTRY *entries)
145 {
146     HRESULT hr;
147 
148     palette->ref = 1;
149     palette->device = device;
150     palette->flags = flags;
151     palette->size = entry_count;
152 
153     if (FAILED(hr = wined3d_palette_set_entries(palette, 0, 0, entry_count, entries)))
154     {
155         WARN("Failed to set palette entries, hr %#x.\n", hr);
156         return hr;
157     }
158 
159     return WINED3D_OK;
160 }
161 
162 HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags,
163         unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette)
164 {
165     struct wined3d_palette *object;
166     HRESULT hr;
167 
168     TRACE("device %p, flags %#x, entry_count %u, entries %p, palette %p.\n",
169             device, flags, entry_count, entries, palette);
170 
171     if (!(object = heap_alloc_zero(sizeof(*object))))
172         return E_OUTOFMEMORY;
173 
174     if (FAILED(hr = wined3d_palette_init(object, device, flags, entry_count, entries)))
175     {
176         WARN("Failed to initialize palette, hr %#x.\n", hr);
177         heap_free(object);
178         return hr;
179     }
180 
181     TRACE("Created palette %p.\n", object);
182     *palette = object;
183 
184     return WINED3D_OK;
185 }
186