mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
814 lines
22 KiB
C
814 lines
22 KiB
C
// license:BSD-3-Clause
|
|
// copyright-holders:Aaron Giles
|
|
/***************************************************************************
|
|
|
|
emupal.c
|
|
|
|
Palette device.
|
|
|
|
***************************************************************************/
|
|
|
|
#include "emu.h"
|
|
|
|
#define VERBOSE 0
|
|
|
|
|
|
//**************************************************************************
|
|
// DEVICE DEFINITIONS
|
|
//**************************************************************************
|
|
|
|
const device_type PALETTE = &device_creator<palette_device>;
|
|
|
|
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
|
: device_t(mconfig, PALETTE, "palette", tag, owner, clock, "palette", __FILE__),
|
|
m_entries(0),
|
|
m_enable_shadows(0),
|
|
m_enable_hilights(0),
|
|
m_raw_to_rgb(raw_to_rgb_converter()),
|
|
m_palette(NULL),
|
|
m_pens(NULL),
|
|
m_shadow_table(NULL),
|
|
m_shadow_group(0),
|
|
m_hilight_group(0),
|
|
m_init(palette_init_delegate())
|
|
{
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
// INITIALIZATION AND CONFIGURATION
|
|
//**************************************************************************
|
|
|
|
void palette_device::static_set_init(device_t &device, palette_init_delegate init)
|
|
{
|
|
downcast<palette_device &>(device).m_init = init;
|
|
}
|
|
|
|
|
|
void palette_device::static_set_format(device_t &device, raw_to_rgb_converter raw_to_rgb)
|
|
{
|
|
downcast<palette_device &>(device).m_raw_to_rgb = raw_to_rgb;
|
|
}
|
|
|
|
|
|
void palette_device::static_set_entries(device_t &device, int entries)
|
|
{
|
|
downcast<palette_device &>(device).m_entries = entries;
|
|
}
|
|
|
|
|
|
void palette_device::static_enable_shadows(device_t &device)
|
|
{
|
|
downcast<palette_device &>(device).m_enable_shadows = true;
|
|
}
|
|
|
|
|
|
void palette_device::static_enable_hilights(device_t &device)
|
|
{
|
|
downcast<palette_device &>(device).m_enable_hilights = true;
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// INDIRECTION (AKA COLORTABLES)
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// set_indirect_color - set an indirect color
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::set_indirect_color(int index, rgb_t rgb)
|
|
{
|
|
// ensure the array is expanded enough to handle the index, then set it
|
|
m_indirect_colors.resize_keep(((index + 1 + 255) / 256) * 256);
|
|
|
|
// alpha doesn't matter
|
|
rgb.set_a(0);
|
|
|
|
// update if it has changed
|
|
if (m_indirect_colors[index] != rgb)
|
|
{
|
|
m_indirect_colors[index] = rgb;
|
|
|
|
// update the palette for any colortable entries that reference it
|
|
for (UINT32 pen = 0; pen < m_indirect_entry.count(); pen++)
|
|
if (m_indirect_entry[pen] == index)
|
|
m_palette->entry_set_color(pen, rgb);
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// set_pen_indirect - set an indirect pen index
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::set_pen_indirect(pen_t pen, UINT16 index)
|
|
{
|
|
assert(pen < m_entries);
|
|
|
|
// allocate the array if needed
|
|
m_indirect_entry.resize(m_entries);
|
|
|
|
// update if changed
|
|
if (m_indirect_entry[pen] != index)
|
|
{
|
|
m_indirect_entry[pen] = index;
|
|
|
|
// permit drivers to configure the pens prior to the colors if they desire
|
|
if (index < m_indirect_colors.count())
|
|
m_palette->entry_set_color(pen, m_indirect_colors[index]);
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// transpen_mask - return a mask of pens that
|
|
// whose indirect values match the given
|
|
// transcolor
|
|
//-------------------------------------------------
|
|
|
|
UINT32 palette_device::transpen_mask(gfx_element &gfx, int color, int transcolor)
|
|
{
|
|
UINT32 entry = gfx.colorbase() + (color % gfx.colors()) * gfx.granularity();
|
|
|
|
// make sure we are in range
|
|
assert(entry < m_indirect_entry.count());
|
|
assert(gfx.depth() <= 32);
|
|
|
|
// either gfx->color_depth entries or as many as we can get up until the end
|
|
int count = MIN(gfx.depth(), m_indirect_entry.count() - entry);
|
|
|
|
// set a bit anywhere the transcolor matches
|
|
UINT32 mask = 0;
|
|
for (int bit = 0; bit < count; bit++)
|
|
if (m_indirect_entry[entry++] == transcolor)
|
|
mask |= 1 << bit;
|
|
|
|
// return the final mask
|
|
return mask;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// configure_tilemap_groups - configure groups
|
|
// within a tilemap to match the indirect masks
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::configure_tilemap_groups(tilemap_t &tmap, gfx_element &gfx, int transcolor)
|
|
{
|
|
int color;
|
|
|
|
assert(gfx.colors() <= TILEMAP_NUM_GROUPS);
|
|
|
|
// iterate over all colors in the tilemap
|
|
for (color = 0; color < gfx.colors(); color++)
|
|
tmap.set_transmask(color, transpen_mask(gfx, color, transcolor), 0);
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// SHADOW TABLE CONFIGURATION
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// palette_set_shadow_mode(mode)
|
|
//
|
|
// mode: 0 = use preset 0 (default shadow)
|
|
// 1 = use preset 1 (default highlight)
|
|
// 2 = use preset 2 *
|
|
// 3 = use preset 3 *
|
|
//
|
|
// * Preset 2 & 3 work independently under 32bpp,
|
|
// supporting up to four different types of
|
|
// shadows at one time. They mirror preset 1 & 2
|
|
// in lower depth settings to maintain
|
|
// compatibility.
|
|
//
|
|
//
|
|
// set_shadow_dRGB32(mode, dr, dg, db, noclip)
|
|
//
|
|
// mode: 0 to 3 (which preset to configure)
|
|
//
|
|
// dr: -255 to 255 ( red displacement )
|
|
// dg: -255 to 255 ( green displacement )
|
|
// db: -255 to 255 ( blue displacement )
|
|
//
|
|
// noclip: 0 = resultant RGB clipped at 0x00/0xff
|
|
// 1 = resultant RGB wraparound 0x00/0xff
|
|
//
|
|
//
|
|
// * Color shadows only work under 32bpp.
|
|
// This function has no effect in lower color
|
|
// depths where
|
|
//
|
|
// set_shadow_factor() or
|
|
// set_highlight_factor()
|
|
//
|
|
// should be used instead.
|
|
//
|
|
// * 32-bit shadows are lossy. Even with zero RGB
|
|
// displacements the affected area will still look
|
|
// slightly darkened.
|
|
//
|
|
// Drivers should ensure all shadow pens in
|
|
// gfx_drawmode_table[] are set to DRAWMODE_NONE
|
|
// when RGB displacements are zero to avoid the
|
|
// darkening effect.
|
|
//-------------------------------------------------
|
|
|
|
//-------------------------------------------------
|
|
// set_shadow_dRGB32 - configure delta RGB values
|
|
// for 1 of 4 shadow tables
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::set_shadow_dRGB32(int mode, int dr, int dg, int db, bool noclip)
|
|
{
|
|
shadow_table_data &stable = m_shadow_tables[mode];
|
|
|
|
// only applies to RGB direct modes
|
|
assert(m_format != BITMAP_FORMAT_IND16);
|
|
assert(stable.base != NULL);
|
|
|
|
// clamp the deltas (why?)
|
|
if (dr < -0xff) dr = -0xff; else if (dr > 0xff) dr = 0xff;
|
|
if (dg < -0xff) dg = -0xff; else if (dg > 0xff) dg = 0xff;
|
|
if (db < -0xff) db = -0xff; else if (db > 0xff) db = 0xff;
|
|
|
|
// early exit if nothing changed
|
|
if (dr == stable.dr && dg == stable.dg && db == stable.db && noclip == stable.noclip)
|
|
return;
|
|
stable.dr = dr;
|
|
stable.dg = dg;
|
|
stable.db = db;
|
|
stable.noclip = noclip;
|
|
|
|
if (VERBOSE)
|
|
popmessage("shadow %d recalc %d %d %d %02x", mode, dr, dg, db, noclip);
|
|
|
|
// regenerate the table
|
|
for (int i = 0; i < 32768; i++)
|
|
{
|
|
int r = pal5bit(i >> 10) + dr;
|
|
int g = pal5bit(i >> 5) + dg;
|
|
int b = pal5bit(i >> 0) + db;
|
|
|
|
// apply clipping
|
|
if (!noclip)
|
|
{
|
|
r = rgb_t::clamp(r);
|
|
g = rgb_t::clamp(g);
|
|
b = rgb_t::clamp(b);
|
|
}
|
|
rgb_t final = rgb_t(r, g, b);
|
|
|
|
// store either 16 or 32 bit
|
|
if (m_format == BITMAP_FORMAT_RGB32)
|
|
stable.base[i] = final;
|
|
else
|
|
stable.base[i] = final.as_rgb15();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// GENERIC WRITE HANDLERS
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// update_for_write - given a write of a given
|
|
// length to a given byte offset, update all
|
|
// potentially modified palette entries
|
|
//-------------------------------------------------
|
|
|
|
inline void palette_device::update_for_write(offs_t byte_offset, int bytes_modified)
|
|
{
|
|
// determine how many entries were modified
|
|
int bpe = m_paletteram.bytes_per_entry();
|
|
assert(bpe != 0);
|
|
int count = (bytes_modified + bpe - 1) / bpe;
|
|
|
|
// for each entry modified, fetch the palette data and set the pen color
|
|
offs_t base = byte_offset / bpe;
|
|
for (int index = 0; index < count; index++)
|
|
{
|
|
UINT32 data = m_paletteram.read(base + index);
|
|
if (m_paletteram_ext.base() != NULL)
|
|
data |= m_paletteram_ext.read(base + index) << (8 * bpe);
|
|
set_pen_color(base + index, m_raw_to_rgb(data));
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// write - write a byte to the base paletteram
|
|
//-------------------------------------------------
|
|
|
|
WRITE8_MEMBER(palette_device::write)
|
|
{
|
|
m_paletteram.write8(offset, data);
|
|
update_for_write(offset, 1);
|
|
}
|
|
|
|
WRITE16_MEMBER(palette_device::write)
|
|
{
|
|
m_paletteram.write16(offset, data, mem_mask);
|
|
update_for_write(offset * 2, 2);
|
|
}
|
|
|
|
WRITE32_MEMBER(palette_device::write)
|
|
{
|
|
m_paletteram.write32(offset, data, mem_mask);
|
|
update_for_write(offset * 4, 4);
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// write_ext - write a byte to the extended
|
|
// paletteram
|
|
//-------------------------------------------------
|
|
|
|
WRITE8_MEMBER(palette_device::write_ext)
|
|
{
|
|
m_paletteram_ext.write8(offset, data);
|
|
update_for_write(offset, 1);
|
|
}
|
|
|
|
|
|
WRITE16_MEMBER(palette_device::write_ext)
|
|
{
|
|
m_paletteram_ext.write16(offset, data, mem_mask);
|
|
update_for_write(offset * 2, 2);
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// DEVICE MANAGEMENT
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// device_start - start up the device
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::device_start()
|
|
{
|
|
// bind the init function
|
|
m_init.bind_relative_to(*owner());
|
|
|
|
// find the memory, if present
|
|
const memory_share *share = memshare(tag());
|
|
if (share != NULL)
|
|
{
|
|
// find the extended (split) memory, if present
|
|
astring tag_ext(tag(), "_ext");
|
|
const memory_share *share_ext = memshare(tag_ext.cstr());
|
|
|
|
// make sure we have specified a format
|
|
assert(m_raw_to_rgb.bytes_per_entry() > 0);
|
|
|
|
// determine bytes per entry
|
|
int bytes_per_entry = m_raw_to_rgb.bytes_per_entry();
|
|
if (share_ext == NULL)
|
|
m_paletteram.set(*share, bytes_per_entry);
|
|
else
|
|
{
|
|
m_paletteram.set(*share, bytes_per_entry / 2);
|
|
m_paletteram_ext.set(*share_ext, bytes_per_entry / 2);
|
|
}
|
|
|
|
// look for an extension entry
|
|
if (share_ext != NULL)
|
|
m_paletteram_ext.set(*share_ext, m_raw_to_rgb.bytes_per_entry());
|
|
}
|
|
|
|
// reset all our data
|
|
screen_device *device = machine().first_screen();
|
|
m_format = (device != NULL) ? device->format() : BITMAP_FORMAT_INVALID;
|
|
if (m_entries > 0)
|
|
{
|
|
allocate_palette();
|
|
allocate_color_tables();
|
|
allocate_shadow_tables();
|
|
}
|
|
|
|
// call the initialization helper if present (this will expand the indirection tables to full size)
|
|
if (!m_init.isnull())
|
|
m_init(*this);
|
|
|
|
// set up save/restore of the palette
|
|
int numcolors = m_palette->num_colors();
|
|
m_save_pen.resize(numcolors);
|
|
m_save_contrast.resize(numcolors);
|
|
save_item(NAME(m_save_pen));
|
|
save_item(NAME(m_save_contrast));
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// INTERNAL FUNCTIONS
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// device_pre_save - prepare the save arrays
|
|
// for saving
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::device_pre_save()
|
|
{
|
|
// fill the save arrays with updated pen and brightness information
|
|
int numcolors = m_palette->num_colors();
|
|
for (int index = 0; index < numcolors; index++)
|
|
{
|
|
m_save_pen[index] = pen_color(index);
|
|
m_save_contrast[index] = pen_contrast(index);
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_post_load - called after restore to
|
|
// actually update the palette
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::device_post_load()
|
|
{
|
|
// reset the pen and brightness for each entry
|
|
int numcolors = m_palette->num_colors();
|
|
for (int index = 0; index < numcolors; index++)
|
|
{
|
|
set_pen_color(index, m_save_pen[index]);
|
|
set_pen_contrast(index, m_save_contrast[index]);
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_stop - final cleanup
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::device_stop()
|
|
{
|
|
// dereference the palette
|
|
if (m_palette != NULL)
|
|
m_palette->deref();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_validity_check - validate device
|
|
// configuration
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::device_validity_check(validity_checker &valid) const
|
|
{
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// allocate_palette - allocate and configure the
|
|
// palette object itself
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::allocate_palette()
|
|
{
|
|
// determine the number of groups we need
|
|
int numgroups = 1;
|
|
if (m_enable_shadows)
|
|
m_shadow_group = numgroups++;
|
|
if (m_enable_hilights)
|
|
m_hilight_group = numgroups++;
|
|
assert_always(m_entries * numgroups <= 65536, "Error: palette has more than 65536 colors.");
|
|
|
|
// allocate a palette object containing all the colors and groups
|
|
m_palette = palette_t::alloc(m_entries, numgroups);
|
|
|
|
// configure the groups
|
|
if (m_shadow_group != 0)
|
|
set_shadow_factor(float(PALETTE_DEFAULT_SHADOW_FACTOR));
|
|
if (m_hilight_group != 0)
|
|
set_highlight_factor(float(PALETTE_DEFAULT_HIGHLIGHT_FACTOR));
|
|
|
|
// set the initial colors to a standard rainbow
|
|
for (int index = 0; index < m_entries; index++)
|
|
set_pen_color(index, rgbexpand<1,1,1>(index, 0, 1, 2));
|
|
|
|
// switch off the color mode
|
|
switch (m_format)
|
|
{
|
|
// 16-bit paletteized case
|
|
case BITMAP_FORMAT_IND16:
|
|
m_black_pen = m_palette->black_entry();
|
|
m_white_pen = m_palette->white_entry();
|
|
if (m_black_pen >= 65536)
|
|
m_black_pen = 0;
|
|
if (m_white_pen >= 65536)
|
|
m_white_pen = 65535;
|
|
break;
|
|
|
|
// 32-bit direct case
|
|
case BITMAP_FORMAT_RGB32:
|
|
m_black_pen = rgb_t::black;
|
|
m_white_pen = rgb_t::white;
|
|
break;
|
|
|
|
// screenless case
|
|
case BITMAP_FORMAT_INVALID:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// allocate_color_tables - allocate memory for
|
|
// pen and color tables
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::allocate_color_tables()
|
|
{
|
|
int total_colors = m_palette->num_colors() * m_palette->num_groups();
|
|
|
|
// allocate memory for the pen table
|
|
switch (m_format)
|
|
{
|
|
case BITMAP_FORMAT_IND16:
|
|
// create a dummy 1:1 mapping
|
|
{
|
|
m_pen_array.resize(total_colors + 2);
|
|
pen_t *pentable = &m_pen_array[0];
|
|
m_pens = &m_pen_array[0];
|
|
for (int i = 0; i < total_colors + 2; i++)
|
|
pentable[i] = i;
|
|
}
|
|
break;
|
|
|
|
case BITMAP_FORMAT_RGB32:
|
|
m_pens = reinterpret_cast<const pen_t *>(m_palette->entry_list_adjusted());
|
|
break;
|
|
|
|
default:
|
|
m_pens = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// allocate_shadow_tables - allocate memory for
|
|
// shadow tables
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::allocate_shadow_tables()
|
|
{
|
|
// if we have shadows, allocate shadow tables
|
|
if (m_enable_shadows)
|
|
{
|
|
m_shadow_array.resize(65536);
|
|
|
|
// palettized mode gets a single 64k table in slots 0 and 2
|
|
if (m_format == BITMAP_FORMAT_IND16)
|
|
{
|
|
m_shadow_tables[0].base = m_shadow_tables[2].base = &m_shadow_array[0];
|
|
for (int i = 0; i < 65536; i++)
|
|
m_shadow_array[i] = (i < m_entries) ? (i + m_entries) : i;
|
|
}
|
|
|
|
// RGB mode gets two 32k tables in slots 0 and 2
|
|
else
|
|
{
|
|
m_shadow_tables[0].base = &m_shadow_array[0];
|
|
m_shadow_tables[2].base = &m_shadow_array[32768];
|
|
configure_rgb_shadows(0, float(PALETTE_DEFAULT_SHADOW_FACTOR));
|
|
}
|
|
}
|
|
|
|
// if we have hilights, allocate shadow tables
|
|
if (m_enable_hilights)
|
|
{
|
|
m_hilight_array.resize(65536);
|
|
|
|
// palettized mode gets a single 64k table in slots 1 and 3
|
|
if (m_format == BITMAP_FORMAT_IND16)
|
|
{
|
|
m_shadow_tables[1].base = m_shadow_tables[3].base = &m_hilight_array[0];
|
|
for (int i = 0; i < 65536; i++)
|
|
m_hilight_array[i] = (i < m_entries) ? (i + 2 * m_entries) : i;
|
|
}
|
|
|
|
// RGB mode gets two 32k tables in slots 1 and 3
|
|
else
|
|
{
|
|
m_shadow_tables[1].base = &m_hilight_array[0];
|
|
m_shadow_tables[3].base = &m_hilight_array[32768];
|
|
configure_rgb_shadows(1, float(PALETTE_DEFAULT_HIGHLIGHT_FACTOR));
|
|
}
|
|
}
|
|
|
|
// set the default table
|
|
m_shadow_table = m_shadow_tables[0].base;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// configure_rgb_shadows - configure shadows
|
|
// for the RGB tables
|
|
//-------------------------------------------------
|
|
|
|
void palette_device::configure_rgb_shadows(int mode, float factor)
|
|
{
|
|
// only applies to RGB direct modes
|
|
assert(m_format != BITMAP_FORMAT_IND16);
|
|
|
|
// verify the shadow table
|
|
assert(mode >= 0 && mode < ARRAY_LENGTH(m_shadow_tables));
|
|
shadow_table_data &stable = m_shadow_tables[mode];
|
|
assert(stable.base != NULL);
|
|
|
|
// regenerate the table
|
|
int ifactor = int(factor * 256.0f);
|
|
for (int rgb555 = 0; rgb555 < 32768; rgb555++)
|
|
{
|
|
UINT8 r = rgb_t::clamp((pal5bit(rgb555 >> 10) * ifactor) >> 8);
|
|
UINT8 g = rgb_t::clamp((pal5bit(rgb555 >> 5) * ifactor) >> 8);
|
|
UINT8 b = rgb_t::clamp((pal5bit(rgb555 >> 0) * ifactor) >> 8);
|
|
|
|
// store either 16 or 32 bit
|
|
rgb_t final = rgb_t(r, g, b);
|
|
if (m_format == BITMAP_FORMAT_RGB32)
|
|
stable.base[rgb555] = final;
|
|
else
|
|
stable.base[rgb555] = final.as_rgb15();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// COMMON PALETTE INITIALIZATION
|
|
//**************************************************************************
|
|
|
|
/*-------------------------------------------------
|
|
black - completely black palette
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_all_black(palette_device &palette)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < palette.entries(); i++)
|
|
{
|
|
palette.set_pen_color(i,rgb_t::black); // black
|
|
}
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
black_and_white - basic 2-color black & white
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_black_and_white(palette_device &palette)
|
|
{
|
|
palette.set_pen_color(0,rgb_t::black); // black
|
|
palette.set_pen_color(1,rgb_t::white); // white
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
white_and_black - basic 2-color white & black
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_white_and_black(palette_device &palette)
|
|
{
|
|
palette.set_pen_color(0,rgb_t::white); // white
|
|
palette.set_pen_color(1,rgb_t::black); // black
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
monochrome_amber - 2-color black & amber
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_monochrome_amber(palette_device &palette)
|
|
{
|
|
palette.set_pen_color(0, rgb_t::black); // black
|
|
palette.set_pen_color(1, rgb_t(0xf7, 0xaa, 0x00)); // amber
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
monochrome_green - 2-color black & green
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_monochrome_green(palette_device &palette)
|
|
{
|
|
palette.set_pen_color(0, rgb_t::black); // black
|
|
palette.set_pen_color(1, rgb_t(0x00, 0xff, 0x00)); // green
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
RRRR_GGGG_BBBB - standard 4-4-4 palette,
|
|
assuming the commonly used resistor values:
|
|
|
|
bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE
|
|
-- 470 ohm resistor -- RED/GREEN/BLUE
|
|
-- 1 kohm resistor -- RED/GREEN/BLUE
|
|
bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_RRRRGGGGBBBB_proms(palette_device &palette)
|
|
{
|
|
const UINT8 *color_prom = machine().root_device().memregion("proms")->base();
|
|
int i;
|
|
|
|
for (i = 0; i < palette.entries(); i++)
|
|
{
|
|
int bit0,bit1,bit2,bit3,r,g,b;
|
|
|
|
// red component
|
|
bit0 = (color_prom[i] >> 0) & 0x01;
|
|
bit1 = (color_prom[i] >> 1) & 0x01;
|
|
bit2 = (color_prom[i] >> 2) & 0x01;
|
|
bit3 = (color_prom[i] >> 3) & 0x01;
|
|
r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
|
|
|
|
// green component
|
|
bit0 = (color_prom[i + palette.entries()] >> 0) & 0x01;
|
|
bit1 = (color_prom[i + palette.entries()] >> 1) & 0x01;
|
|
bit2 = (color_prom[i + palette.entries()] >> 2) & 0x01;
|
|
bit3 = (color_prom[i + palette.entries()] >> 3) & 0x01;
|
|
g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
|
|
|
|
// blue component
|
|
bit0 = (color_prom[i + 2*palette.entries()] >> 0) & 0x01;
|
|
bit1 = (color_prom[i + 2*palette.entries()] >> 1) & 0x01;
|
|
bit2 = (color_prom[i + 2*palette.entries()] >> 2) & 0x01;
|
|
bit3 = (color_prom[i + 2*palette.entries()] >> 3) & 0x01;
|
|
b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
|
|
|
|
palette.set_pen_color(i,rgb_t(r,g,b));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------
|
|
RRRRR_GGGGG_BBBBB/BBBBB_GGGGG_RRRRR -
|
|
standard 5-5-5 palette for games using a
|
|
15-bit color space
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_RRRRRGGGGGBBBBB(palette_device &palette)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 0x8000; i++)
|
|
palette.set_pen_color(i, rgbexpand<5,5,5>(i, 10, 5, 0));
|
|
}
|
|
|
|
|
|
void palette_device::palette_init_BBBBBGGGGGRRRRR(palette_device &palette)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 0x8000; i++)
|
|
palette.set_pen_color(i, rgbexpand<5,5,5>(i, 0, 5, 10));
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------
|
|
RRRRR_GGGGGG_BBBBB -
|
|
standard 5-6-5 palette for games using a
|
|
16-bit color space
|
|
-------------------------------------------------*/
|
|
|
|
void palette_device::palette_init_RRRRRGGGGGGBBBBB(palette_device &palette)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 0x10000; i++)
|
|
palette.set_pen_color(i, rgbexpand<5,6,5>(i, 11, 5, 0));
|
|
}
|
|
|
|
|
|
rgb_t raw_to_rgb_converter::RRRRGGGGBBBBRGBx_decoder(UINT32 raw)
|
|
{
|
|
UINT8 r = pal5bit(((raw >> 11) & 0x1e) | ((raw >> 3) & 0x01));
|
|
UINT8 g = pal5bit(((raw >> 7) & 0x1e) | ((raw >> 2) & 0x01));
|
|
UINT8 b = pal5bit(((raw >> 3) & 0x1e) | ((raw >> 1) & 0x01));
|
|
return rgb_t(r, g, b);
|
|
}
|
|
|
|
rgb_t raw_to_rgb_converter::xRGBRRRRGGGGBBBB_decoder(UINT32 raw)
|
|
{
|
|
UINT8 r = pal5bit(((raw >> 8) & 0x1e) | ((raw >> 12) & 0x01));
|
|
UINT8 g = pal5bit(((raw >> 4) & 0x1e) | ((raw >> 13) & 0x01));
|
|
UINT8 b = pal5bit(((raw >> 0) & 0x1e) | ((raw >> 14) & 0x01));
|
|
return rgb_t(r, g, b);
|
|
}
|