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 short * pal
= (unsigned short *) 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,2),%%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 short *pal
= (unsigned short *) 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 short *pal
= (unsigned short *) 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
} },