1 /******************************************************************************
2
3 palette.c
4
5 Palette handling functions.
6
7 There are several levels of abstraction in the way MAME handles the palette,
8 and several display modes which can be used by the drivers.
9
10 Palette
11 -------
12 Note: in the following text, "color" refers to a color in the emulated
13 game's virtual palette. For example, a game might be able to display 1024
14 colors at the same time. If the game uses RAM to change the available
15 colors, the term "palette" refers to the colors available at any given time,
16 not to the whole range of colors which can be produced by the hardware. The
17 latter is referred to as "color space".
18 The term "pen" refers to one of the maximum MAX_PENS colors that can be
19 used to generate the display.
20
21 So, to summarize, the three layers of palette abstraction are:
22
23 P1) The game virtual palette (the "colors")
24 P2) MAME's MAX_PENS colors palette (the "pens")
25 P3) The OS specific hardware color registers (the "OS specific pens")
26
27 The array Machine->pens[] is a lookup table which maps game colors to OS
28 specific pens (P1 to P3). When you are working on bitmaps at the pixel level,
29 *always* use Machine->pens to map the color numbers. *Never* use constants.
30 For example if you want to make pixel (x,y) of color 3, do:
31 bitmap->line[y][x] = Machine->pens[3];
32
33
34 Lookup table
35 ------------
36 Palettes are only half of the story. To map the gfx data to colors, the
37 graphics routines use a lookup table. For example if we have 4bpp tiles,
38 which can have 256 different color codes, the lookup table for them will have
39 256 * 2^4 = 4096 elements. For games using a palette RAM, the lookup table is
40 usually a 1:1 map. For games using PROMs, the lookup table is often larger
41 than the palette itself so for example the game can display 256 colors out
42 of a palette of 16.
43
44 The palette and the lookup table are initialized to default values by the
45 main core, but can be initialized by the driver using the function
46 MachineDriver->vh_init_palette(). For games using palette RAM, that
47 function is usually not needed, and the lookup table can be set up by
48 properly initializing the color_codes_start and total_color_codes fields in
49 the GfxDecodeInfo array.
50 When vh_init_palette() initializes the lookup table, it maps gfx codes
51 to game colors (P1 above). The lookup table will be converted by the core to
52 map to OS specific pens (P3 above), and stored in Machine->remapped_colortable.
53
54
55 Display modes
56 -------------
57 The available display modes can be summarized in three categories:
58 1) Static palette. Use this for games which use PROMs for color generation.
59 The palette is initialized by palette_init(), and never changed
60 again.
61 2) Dynamic palette. Use this for games which use RAM for color generation.
62 The palette can be dynamically modified by the driver using the function
63 palette_set_color().
64 3) Direct mapped 16-bit or 32-bit color. This should only be used in special
65 cases, e.g. to support alpha blending.
66 MachineDriver->video_attributes must contain VIDEO_RGB_DIRECT.
67
68 ******************************************************************************/
69
70 #ifndef PALETTE_H
71 #define PALETTE_H
72
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76
77
78 /*-------------------------------------------------
79 TYPE DEFINITIONS
80 -------------------------------------------------*/
81
82 struct mame_display; /* declared elsewhere */
83
84 typedef UINT32 pen_t;
85 typedef UINT32 rgb_t;
86 typedef UINT16 rgb15_t;
87
88
89
90 /*-------------------------------------------------
91 CONSTANTS
92 -------------------------------------------------*/
93
94 #define PALETTE_DEFAULT_SHADOW_FACTOR (0.6)
95 #define PALETTE_DEFAULT_HIGHLIGHT_FACTOR (1/PALETTE_DEFAULT_SHADOW_FACTOR)
96
97 #define PALETTE_DEFAULT_SHADOW_FACTOR32 (0.6)
98 #define PALETTE_DEFAULT_HIGHLIGHT_FACTOR32 (1/PALETTE_DEFAULT_SHADOW_FACTOR32)
99
100
101
102 /*-------------------------------------------------
103 MACROS
104 -------------------------------------------------*/
105
106 #define MAKE_RGB(r,g,b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff))
107 #define MAKE_ARGB(a,r,g,b) (MAKE_RGB(r,g,b) | (((a) & 0xff) << 24))
108 #define RGB_ALPHA(rgb) (((rgb) >> 24) & 0xff)
109 #define RGB_RED(rgb) (((rgb) >> 16) & 0xff)
110 #define RGB_GREEN(rgb) (((rgb) >> 8) & 0xff)
111 #define RGB_BLUE(rgb) ((rgb) & 0xff)
112
113
114
115 /*-------------------------------------------------
116 GLOBAL VARIABLES
117 -------------------------------------------------*/
118
119 extern UINT32 direct_rgb_components[3];
120 extern UINT16 *palette_shadow_table;
121
122 extern data8_t *paletteram;
123 extern data8_t *paletteram_2; /* use when palette RAM is split in two parts */
124 extern data16_t *paletteram16;
125 extern data16_t *paletteram16_2;
126 extern data32_t *paletteram32;
127
128
129
130 /*-------------------------------------------------
131 PROTOTYPES
132 -------------------------------------------------*/
133
134 int palette_start(void);
135 int palette_init(void);
136 int palette_get_total_colors_with_ui(void);
137
138 void palette_update_display(struct mame_display *display);
139
140 void palette_set_color(pen_t pen, UINT8 r, UINT8 g, UINT8 b);
141 void palette_get_color(pen_t pen, UINT8 *r, UINT8 *g, UINT8 *b);
142 void palette_set_colors(pen_t color_base, const UINT8 *colors, int color_count);
143
144 void palette_set_brightness(pen_t pen, double bright);
145 void palette_set_shadow_factor(double factor);
146 void palette_set_highlight_factor(double factor);
147
148 /*
149 Shadows(Highlights) Quick Reference
150 -----------------------------------
151
152 1) declare MDRV_VIDEO_ATTRIBUTES( ... VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS ... )
153
154 2) set gfx_drawmode_table[0-n] to DRAWMODE_NONE, DRAWMODE_SOURCE or DRAWMODE_SHADOW
155
156 3) (optional) set shadow darkness or highlight brightness by
157 palette_set_shadow_factor32(0.0-1.0) or
158 palette_set_highlight_factor32(1.0-n.n)
159
160 4) before calling drawgfx use
161 palette_set_shadow_mode(0) to arm shadows or
162 palette_set_shadow_mode(1) to arm highlights
163
164 5) call drawgfx with the TRANSPARENCY_PEN_TABLE flag
165 drawgfx( ..., cliprect, TRANSPARENCY_PEN_TABLE, transparent_color )
166 */
167 void palette_set_shadow_mode(int mode);
168 void palette_set_shadow_factor32(double factor);
169 void palette_set_highlight_factor32(double factor);
170 void palette_set_shadow_dRGB32(int mode, int dr, int dg, int db, int noclip);
171 void palette_set_highlight_method(int method);
172 /*0=default, 1=multiplication with flooding, 2=addition */
173
174 void palette_set_global_gamma(double _gamma);
175 double palette_get_global_gamma(void);
176
177 void palette_set_global_brightness(double brightness);
178 void palette_set_global_brightness_adjust(double adjustment);
179 double palette_get_global_brightness(void);
180
181 pen_t get_black_pen(void);
182
183
184 /* here are some functions to handle commonly used palette layouts, so you don't
185 have to write your own paletteram_w() function. */
186
187 READ_HANDLER( paletteram_r );
188 READ_HANDLER( paletteram_2_r );
189 READ16_HANDLER( paletteram16_word_r );
190 READ16_HANDLER( paletteram16_2_word_r );
191 READ32_HANDLER( paletteram32_r );
192
193 WRITE_HANDLER( paletteram_BBGGGRRR_w );
194 WRITE_HANDLER( paletteram_RRRGGGBB_w );
195 WRITE_HANDLER( paletteram_BBBGGGRR_w );
196 WRITE_HANDLER( paletteram_IIBBGGRR_w );
197 WRITE_HANDLER( paletteram_BBGGRRII_w );
198
199 /* _w least significant byte first */
200 /* _swap_w most significant byte first */
201 /* _split_w least and most significant bytes are not consecutive */
202 /* _word_w use with 16 bit CPU */
203 /* R, G, B are bits, r, g, b are bytes */
204 /* MSB LSB */
205 WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_w );
206 WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_swap_w );
207 WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_split1_w ); /* uses paletteram[] */
208 WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_split2_w ); /* uses paletteram_2[] */
209 WRITE16_HANDLER( paletteram16_xxxxBBBBGGGGRRRR_word_w );
210 WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_w );
211 WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_swap_w );
212 WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_split1_w ); /* uses paletteram[] */
213 WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_split2_w ); /* uses paletteram_2[] */
214 WRITE16_HANDLER( paletteram16_xxxxBBBBRRRRGGGG_word_w );
215 WRITE_HANDLER( paletteram_xxxxRRRRBBBBGGGG_split1_w ); /* uses paletteram[] */
216 WRITE_HANDLER( paletteram_xxxxRRRRBBBBGGGG_split2_w ); /* uses paletteram_2[] */
217 WRITE_HANDLER( paletteram_xxxxRRRRGGGGBBBB_w );
218 WRITE_HANDLER( paletteram_xxxxRRRRGGGGBBBB_swap_w );
219 WRITE16_HANDLER( paletteram16_xxxxRRRRGGGGBBBB_word_w );
220 WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_swap_w );
221 WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_split1_w ); /* uses paletteram[] */
222 WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_split2_w ); /* uses paletteram_2[] */
223 WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBxxxx_word_w );
224 WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_swap_w );
225 WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_split1_w ); /* uses paletteram[] */
226 WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_split2_w ); /* uses paletteram_2[] */
227 WRITE16_HANDLER( paletteram16_BBBBGGGGRRRRxxxx_word_w );
228 WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_w );
229 WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_swap_w );
230 WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_split1_w ); /* uses paletteram[] */
231 WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_split2_w ); /* uses paletteram_2[] */
232 WRITE16_HANDLER( paletteram16_xBBBBBGGGGGRRRRR_word_w );
233 WRITE_HANDLER( paletteram_xRRRRRGGGGGBBBBB_w );
234 WRITE16_HANDLER( paletteram16_xRRRRRGGGGGBBBBB_word_w );
235 WRITE16_HANDLER( paletteram16_xGGGGGRRRRRBBBBB_word_w );
236 WRITE16_HANDLER( paletteram16_xGGGGGBBBBBRRRRR_word_w );
237 WRITE_HANDLER( paletteram_RRRRRGGGGGBBBBBx_w );
238 WRITE16_HANDLER( paletteram16_RRRRRGGGGGBBBBBx_word_w );
239 WRITE16_HANDLER( paletteram16_IIIIRRRRGGGGBBBB_word_w );
240 WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBIIII_word_w );
241 WRITE16_HANDLER( paletteram16_xrgb_word_w );
242 WRITE16_HANDLER( paletteram16_xbgr_word_w );
243 WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBRGBx_word_w );
244
245
246 /******************************************************************************
247
248 Commonly used color PROM handling functions
249
250 ******************************************************************************/
251
252 void palette_init_black_and_white(UINT16 *colortable, const UINT8 *color_prom);
253 void palette_init_RRRR_GGGG_BBBB(UINT16 *colortable, const UINT8 *color_prom);
254
255
256
257 /***************************************************************************
258 static INLINE FUNCTIONS
259 ***************************************************************************/
260
261 /*-------------------------------------------------
262 rgb_to_rgb15 - convert an RGB triplet to
263 a 15-bit OSD-specified RGB value
264 -------------------------------------------------*/
265
rgb_to_rgb15(rgb_t rgb)266 static INLINE rgb15_t rgb_to_rgb15(rgb_t rgb)
267 {
268 return ((RGB_RED(rgb) >> 3) << 10) | ((RGB_GREEN(rgb) >> 3) << 5) | ((RGB_BLUE(rgb) >> 3) << 0);
269 }
270
271
272 /*-------------------------------------------------
273 rgb_clamp - clamp an RGB component to 0-255
274 -------------------------------------------------*/
275
rgb_clamp(INT32 value)276 static INLINE UINT8 rgb_clamp(INT32 value)
277 {
278 if (value < 0)
279 return 0;
280 if (value > 255)
281 return 255;
282 return value;
283 }
284
285
286 /*-------------------------------------------------
287 pal1bit - convert a 1-bit value to 8 bits
288 -------------------------------------------------*/
289
pal1bit(UINT8 bits)290 static INLINE UINT8 pal1bit(UINT8 bits)
291 {
292 return (bits & 1) ? 0xff : 0x00;
293 }
294
295
296 /*-------------------------------------------------
297 pal2bit - convert a 2-bit value to 8 bits
298 -------------------------------------------------*/
299
pal2bit(UINT8 bits)300 static INLINE UINT8 pal2bit(UINT8 bits)
301 {
302 bits &= 3;
303 return (bits << 6) | (bits << 4) | (bits << 2) | bits;
304 }
305
306
307 /*-------------------------------------------------
308 pal3bit - convert a 3-bit value to 8 bits
309 -------------------------------------------------*/
310
pal3bit(UINT8 bits)311 static INLINE UINT8 pal3bit(UINT8 bits)
312 {
313 bits &= 7;
314 return (bits << 5) | (bits << 2) | (bits >> 1);
315 }
316
317
318 /*-------------------------------------------------
319 pal4bit - convert a 4-bit value to 8 bits
320 -------------------------------------------------*/
321
pal4bit(UINT8 bits)322 static INLINE UINT8 pal4bit(UINT8 bits)
323 {
324 bits &= 0xf;
325 return (bits << 4) | bits;
326 }
327
328
329 /*-------------------------------------------------
330 pal5bit - convert a 5-bit value to 8 bits
331 -------------------------------------------------*/
332
pal5bit(UINT8 bits)333 static INLINE UINT8 pal5bit(UINT8 bits)
334 {
335 bits &= 0x1f;
336 return (bits << 3) | (bits >> 2);
337 }
338
339
340 /*-------------------------------------------------
341 pal6bit - convert a 6-bit value to 8 bits
342 -------------------------------------------------*/
343
pal6bit(UINT8 bits)344 static INLINE UINT8 pal6bit(UINT8 bits)
345 {
346 bits &= 0x3f;
347 return (bits << 2) | (bits >> 4);
348 }
349
350
351 /*-------------------------------------------------
352 pal7bit - convert a 7-bit value to 8 bits
353 -------------------------------------------------*/
354
pal7bit(UINT8 bits)355 static INLINE UINT8 pal7bit(UINT8 bits)
356 {
357 bits &= 0x7f;
358 return (bits << 1) | (bits >> 6);
359 }
360
361 #ifdef __cplusplus
362 }
363 #endif
364
365 #endif
366