| 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 vh_init_palette(), 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 |
typedef UINT32 pen_t; |
| 78 |
typedef UINT32 rgb_t; |
| 79 |
|
| 80 |
#define MAKE_RGB(r,g,b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff)) |
| 81 |
#define RGB_RED(rgb) (((rgb) >> 16) & 0xff) |
| 82 |
#define RGB_GREEN(rgb) (((rgb) >> 8) & 0xff) |
| 83 |
#define RGB_BLUE(rgb) ((rgb) & 0xff) |
| 84 |
|
| 85 |
int palette_start(void); |
| 86 |
void palette_stop(void); |
| 87 |
int palette_init(void); |
| 88 |
|
| 89 |
void palette_set_color(pen_t color,UINT8 r,UINT8 g,UINT8 b); |
| 90 |
void palette_get_color(pen_t color,UINT8 *r,UINT8 *g,UINT8 *b); |
| 91 |
|
| 92 |
|
| 93 |
extern UINT16 *palette_shadow_table; |
| 94 |
|
| 95 |
#define PALETTE_DEFAULT_SHADOW_FACTOR (0.6) |
| 96 |
#define PALETTE_DEFAULT_HIGHLIGHT_FACTOR (1/PALETTE_DEFAULT_SHADOW_FACTOR) |
| 97 |
|
| 98 |
void palette_set_brightness(pen_t color,double bright); |
| 99 |
void palette_set_shadow_factor(double factor); |
| 100 |
void palette_set_highlight_factor(double factor); |
| 101 |
|
| 102 |
/* use this if you need to fillbitmap() the background with black */ |
| 103 |
pen_t get_black_pen(void); |
| 104 |
|
| 105 |
|
| 106 |
/* here are some functions to handle commonly used palette layouts, so you don't |
| 107 |
have to write your own paletteram_w() function. */ |
| 108 |
|
| 109 |
extern data8_t *paletteram; |
| 110 |
extern data8_t *paletteram_2; /* use when palette RAM is split in two parts */ |
| 111 |
extern data16_t *paletteram16; |
| 112 |
extern data16_t *paletteram16_2; |
| 113 |
extern data32_t *paletteram32; |
| 114 |
|
| 115 |
READ_HANDLER( paletteram_r ); |
| 116 |
READ_HANDLER( paletteram_2_r ); |
| 117 |
READ16_HANDLER( paletteram16_word_r ); |
| 118 |
READ16_HANDLER( paletteram16_2_word_r ); |
| 119 |
READ32_HANDLER( paletteram32_r ); |
| 120 |
|
| 121 |
WRITE_HANDLER( paletteram_BBGGGRRR_w ); |
| 122 |
WRITE_HANDLER( paletteram_RRRGGGBB_w ); |
| 123 |
WRITE_HANDLER( paletteram_BBBGGGRR_w ); |
| 124 |
WRITE_HANDLER( paletteram_IIBBGGRR_w ); |
| 125 |
WRITE_HANDLER( paletteram_BBGGRRII_w ); |
| 126 |
|
| 127 |
/* _w least significant byte first */ |
| 128 |
/* _swap_w most significant byte first */ |
| 129 |
/* _split_w least and most significant bytes are not consecutive */ |
| 130 |
/* _word_w use with 16 bit CPU */ |
| 131 |
/* R, G, B are bits, r, g, b are bytes */ |
| 132 |
/* MSB LSB */ |
| 133 |
WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_w ); |
| 134 |
WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_swap_w ); |
| 135 |
WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_split1_w ); /* uses paletteram[] */ |
| 136 |
WRITE_HANDLER( paletteram_xxxxBBBBGGGGRRRR_split2_w ); /* uses paletteram_2[] */ |
| 137 |
WRITE16_HANDLER( paletteram16_xxxxBBBBGGGGRRRR_word_w ); |
| 138 |
WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_w ); |
| 139 |
WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_swap_w ); |
| 140 |
WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_split1_w ); /* uses paletteram[] */ |
| 141 |
WRITE_HANDLER( paletteram_xxxxBBBBRRRRGGGG_split2_w ); /* uses paletteram_2[] */ |
| 142 |
WRITE_HANDLER( paletteram_xxxxRRRRBBBBGGGG_split1_w ); /* uses paletteram[] */ |
| 143 |
WRITE_HANDLER( paletteram_xxxxRRRRBBBBGGGG_split2_w ); /* uses paletteram_2[] */ |
| 144 |
WRITE_HANDLER( paletteram_xxxxRRRRGGGGBBBB_w ); |
| 145 |
WRITE_HANDLER( paletteram_xxxxRRRRGGGGBBBB_swap_w ); |
| 146 |
WRITE16_HANDLER( paletteram16_xxxxRRRRGGGGBBBB_word_w ); |
| 147 |
WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_swap_w ); |
| 148 |
WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_split1_w ); /* uses paletteram[] */ |
| 149 |
WRITE_HANDLER( paletteram_RRRRGGGGBBBBxxxx_split2_w ); /* uses paletteram_2[] */ |
| 150 |
WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBxxxx_word_w ); |
| 151 |
WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_swap_w ); |
| 152 |
WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_split1_w ); /* uses paletteram[] */ |
| 153 |
WRITE_HANDLER( paletteram_BBBBGGGGRRRRxxxx_split2_w ); /* uses paletteram_2[] */ |
| 154 |
WRITE16_HANDLER( paletteram16_BBBBGGGGRRRRxxxx_word_w ); |
| 155 |
WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_w ); |
| 156 |
WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_swap_w ); |
| 157 |
WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_split1_w ); /* uses paletteram[] */ |
| 158 |
WRITE_HANDLER( paletteram_xBBBBBGGGGGRRRRR_split2_w ); /* uses paletteram_2[] */ |
| 159 |
WRITE16_HANDLER( paletteram16_xBBBBBGGGGGRRRRR_word_w ); |
| 160 |
WRITE_HANDLER( paletteram_xRRRRRGGGGGBBBBB_w ); |
| 161 |
WRITE16_HANDLER( paletteram16_xRRRRRGGGGGBBBBB_word_w ); |
| 162 |
WRITE16_HANDLER( paletteram16_xGGGGGRRRRRBBBBB_word_w ); |
| 163 |
WRITE_HANDLER( paletteram_RRRRRGGGGGBBBBBx_w ); |
| 164 |
WRITE16_HANDLER( paletteram16_RRRRRGGGGGBBBBBx_word_w ); |
| 165 |
WRITE16_HANDLER( paletteram16_IIIIRRRRGGGGBBBB_word_w ); |
| 166 |
WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBIIII_word_w ); |
| 167 |
WRITE16_HANDLER( paletteram16_xrgb_word_w ); |
| 168 |
WRITE16_HANDLER( paletteram16_RRRRGGGGBBBBRGBx_word_w ); |
| 169 |
|
| 170 |
PALETTE_INIT( RRRR_GGGG_BBBB ); |
| 171 |
|
| 172 |
#ifdef __cplusplus |
| 173 |
} |
| 174 |
#endif |
| 175 |
|
| 176 |
#endif |