2 * Copyright 2000 Marcus Meissner
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "ddraw_private.h"
21 #include "wine/debug.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
25 /* *************************************
26 16 / 15 bpp to palettized 8 bpp
27 ************************************* */
28 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
29 unsigned char *c_src = (unsigned char *) src;
30 unsigned short *c_dst = (unsigned short *) dst;
33 if (palette != NULL) {
34 const unsigned int * pal = (unsigned int *) palette->screen_palents;
36 for (y = height; y--; ) {
37 #if defined(__i386__) && defined(__GNUC__)
38 /* gcc generates slightly inefficient code for the the copy/lookup,
39 * it generates one excess memory access (to pal) per pixel. Since
40 * we know that pal is not modified by the memory write we can
41 * put it into a register and reduce the number of memory accesses
42 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
43 * stalls. (This is not guaranteed to be the fastest method.)
49 " movw (%%edx,%%eax,4),%%ax\n"
53 : "=S" (c_src), "=D" (c_dst)
54 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
55 : "eax", "cc", "memory"
59 unsigned char * srclineend = c_src+width;
60 while (c_src < srclineend)
61 *c_dst++ = pal[*c_src++];
66 FIXME("No palette set...\n");
67 memset(dst, 0, width * height * 2);
70 static void palette_convert_16_to_8(
71 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
74 unsigned int *pal = (unsigned int *) screen_palette;
76 for (i = 0; i < count; i++)
77 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
78 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
79 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
82 static void palette_convert_15_to_8(
83 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
86 unsigned int *pal = (unsigned int *) screen_palette;
88 for (i = 0; i < count; i++)
89 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
90 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
91 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
94 /* *************************************
95 24 to palettized 8 bpp
96 ************************************* */
97 static void pixel_convert_24_to_8(
98 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
99 IDirectDrawPaletteImpl* palette
101 unsigned char *c_src = (unsigned char *) src;
102 unsigned char *c_dst = (unsigned char *) dst;
105 if (palette != NULL) {
106 const unsigned int *pal = (unsigned int *) palette->screen_palents;
108 for (y = height; y--; ) {
109 unsigned char * srclineend = c_src+width;
110 while (c_src < srclineend ) {
111 register long pixel = pal[*c_src++];
114 *c_dst++ = pixel>>16;
116 c_src+=(pitch-width);
119 FIXME("No palette set...\n");
120 memset(dst, 0, width * height * 3);
124 /* *************************************
125 32 bpp to palettized 8 bpp
126 ************************************* */
127 static void pixel_convert_32_to_8(
128 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
129 IDirectDrawPaletteImpl* palette
131 unsigned char *c_src = (unsigned char *) src;
132 unsigned int *c_dst = (unsigned int *) dst;
135 if (palette != NULL) {
136 const unsigned int *pal = (unsigned int *) palette->screen_palents;
138 for (y = height; y--; ) {
139 #if defined(__i386__) && defined(__GNUC__)
140 /* See comment in pixel_convert_16_to_8 */
141 __asm__ __volatile__(
145 " movl (%%edx,%%eax,4),%%eax\n"
149 : "=S" (c_src), "=D" (c_dst)
150 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
151 : "eax", "cc", "memory"
153 c_src+=(pitch-width);
155 unsigned char * srclineend = c_src+width;
156 while (c_src < srclineend )
157 *c_dst++ = pal[*c_src++];
158 c_src+=(pitch-width);
162 FIXME("No palette set...\n");
163 memset(dst, 0, width * height * 4);
167 static void palette_convert_24_to_8(
168 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
171 unsigned int *pal = (unsigned int *) screen_palette;
173 for (i = 0; i < count; i++)
174 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
175 (((unsigned int) palent[i].peGreen) << 8) |
176 ((unsigned int) palent[i].peBlue));
179 /* *************************************
181 ************************************* */
182 static void pixel_convert_15_to_16(
183 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
184 IDirectDrawPaletteImpl* palette
186 unsigned short *c_src = (unsigned short *) src;
187 unsigned short *c_dst = (unsigned short *) dst;
190 for (y = height; y--; ) {
191 unsigned short * srclineend = c_src+width;
192 while (c_src < srclineend ) {
193 unsigned short val = *c_src++;
194 *c_dst++=((val&0xFFC0)>>1)|(val&0x001f);
196 c_src+=((pitch/2)-width);
200 /* *************************************
202 ************************************* */
203 static void pixel_convert_32_to_16(
204 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
205 IDirectDrawPaletteImpl* palette
207 unsigned short *c_src = (unsigned short *) src;
208 unsigned int *c_dst = (unsigned int *) dst;
211 for (y = height; y--; ) {
212 unsigned short * srclineend = c_src+width;
213 while (c_src < srclineend ) {
214 *c_dst++ = (((*c_src & 0xF800) << 8) |
215 ((*c_src & 0x07E0) << 5) |
216 ((*c_src & 0x001F) << 3));
219 c_src+=((pitch/2)-width);
223 /* *************************************
225 ************************************* */
226 static void pixel_convert_32_to_24(
227 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
228 IDirectDrawPaletteImpl* palette
230 unsigned char *c_src = (unsigned char *) src;
231 unsigned int *c_dst = (unsigned int *) dst;
234 for (y = height; y--; ) {
235 unsigned char * srclineend = c_src+width*3;
236 while (c_src < srclineend ) {
237 /* FIXME: wrong for big endian */
238 memcpy(c_dst,c_src,3);
242 c_src+=pitch-width*3;
246 /* *************************************
248 ************************************* */
249 static void pixel_convert_16_to_32(
250 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
251 IDirectDrawPaletteImpl* palette
253 unsigned int *c_src = (unsigned int *) src;
254 unsigned short *c_dst = (unsigned short *) dst;
257 for (y = height; y--; ) {
258 unsigned int * srclineend = c_src+width;
259 while (c_src < srclineend ) {
260 *c_dst++ = (((*c_src & 0xF80000) >> 8) |
261 ((*c_src & 0x00FC00) >> 5) |
262 ((*c_src & 0x0000F8) >> 3));
265 c_src+=((pitch/4)-width);
269 Convert ModeEmulations[8] = {
270 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { pixel_convert_32_to_24, NULL } },
271 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
272 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
273 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
274 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 16,16, 0xf800, 0x07e0, 0x001f }, { pixel_convert_15_to_16, NULL } },
275 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
276 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
277 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { pixel_convert_16_to_32, NULL } }