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