1 #include "ddraw_private.h"
2 #include "debugtools.h"
4 DEFAULT_DEBUG_CHANNEL(ddraw);
6 /* *************************************
7 16 / 15 bpp to palettized 8 bpp
8 ************************************* */
9 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
10 unsigned char *c_src = (unsigned char *) src;
11 unsigned short *c_dst = (unsigned short *) dst;
14 if (palette != NULL) {
15 const unsigned int * pal = (unsigned int *) palette->screen_palents;
17 for (y = height; y--; ) {
18 #if defined(__i386__) && defined(__GNUC__)
19 /* gcc generates slightly inefficient code for the the copy/lookup,
20 * it generates one excess memory access (to pal) per pixel. Since
21 * we know that pal is not modified by the memory write we can
22 * put it into a register and reduce the number of memory accesses
23 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
24 * stalls. (This is not guaranteed to be the fastest method.)
30 " movw (%%edx,%%eax,4),%%ax\n"
34 : "=S" (c_src), "=D" (c_dst)
35 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
36 : "eax", "cc", "memory"
40 unsigned char * srclineend = c_src+width;
41 while (c_src < srclineend)
42 *c_dst++ = pal[*c_src++];
47 WARN("No palette set...\n");
48 memset(dst, 0, width * height * 2);
51 static void palette_convert_16_to_8(
52 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
55 unsigned int *pal = (unsigned int *) screen_palette;
57 for (i = 0; i < count; i++)
58 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
59 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
60 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
63 static void palette_convert_15_to_8(
64 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
67 unsigned int *pal = (unsigned int *) screen_palette;
69 for (i = 0; i < count; i++)
70 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
71 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
72 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
75 /* *************************************
76 24 to palettized 8 bpp
77 ************************************* */
78 static void pixel_convert_24_to_8(
79 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
80 IDirectDrawPaletteImpl* palette
82 unsigned char *c_src = (unsigned char *) src;
83 unsigned char *c_dst = (unsigned char *) dst;
86 if (palette != NULL) {
87 const unsigned int *pal = (unsigned int *) palette->screen_palents;
89 for (y = height; y--; ) {
90 unsigned char * srclineend = c_src+width;
91 while (c_src < srclineend ) {
92 register long pixel = pal[*c_src++];
100 WARN("No palette set...\n");
101 memset(dst, 0, width * height * 4);
105 /* *************************************
106 32 bpp to palettized 8 bpp
107 ************************************* */
108 static void pixel_convert_32_to_8(
109 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
110 IDirectDrawPaletteImpl* palette
112 unsigned char *c_src = (unsigned char *) src;
113 unsigned int *c_dst = (unsigned int *) dst;
116 if (palette != NULL) {
117 const unsigned int *pal = (unsigned int *) palette->screen_palents;
119 for (y = height; y--; ) {
120 #if defined(__i386__) && defined(__GNUC__)
121 /* See comment in pixel_convert_16_to_8 */
122 __asm__ __volatile__(
126 " movl (%%edx,%%eax,4),%%eax\n"
130 : "=S" (c_src), "=D" (c_dst)
131 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
132 : "eax", "cc", "memory"
134 c_src+=(pitch-width);
136 unsigned char * srclineend = c_src+width;
137 while (c_src < srclineend )
138 *c_dst++ = pal[*c_src++];
139 c_src+=(pitch-width);
143 WARN("No palette set...\n");
144 memset(dst, 0, width * height * 4);
148 static void palette_convert_24_to_8(
149 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
152 unsigned int *pal = (unsigned int *) screen_palette;
154 for (i = 0; i < count; i++)
155 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
156 (((unsigned int) palent[i].peGreen) << 8) |
157 ((unsigned int) palent[i].peBlue));
160 /* *************************************
162 ************************************* */
163 static void pixel_convert_32_to_16(
164 void *src, void *dst, DWORD width, DWORD height, LONG pitch,
165 IDirectDrawPaletteImpl* palette
167 unsigned short *c_src = (unsigned short *) src;
168 unsigned int *c_dst = (unsigned int *) dst;
171 for (y = height; y--; ) {
172 unsigned short * srclineend = c_src+width;
173 while (c_src < srclineend ) {
174 *c_dst++ = (((*c_src & 0xF800) << 8) |
175 ((*c_src & 0x07E0) << 5) |
176 ((*c_src & 0x001F) << 3));
179 c_src+=((pitch/2)-width);
183 Convert ModeEmulations[5] = {
184 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
185 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
186 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
187 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
188 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },