diff options
author | 2017-04-05 16:48:43 -0400 | |
---|---|---|
committer | 2017-04-06 11:30:40 +1000 | |
commit | 8fe18e9eccb5f0ca5884c76402d7db9911795079 (patch) | |
tree | 29b2766835f55c50f38dced2a155d45e23e745a3 /src/emu/emupal.cpp | |
parent | fbb7d927d3a58de18850ad3079621e0a78e5e6bd (diff) |
New device interface for palettes
- Create device_palette_interface, which takes over most functionality from palette_device except for the initialization/decoding routines and RAM interface.
- Update screen_device and device_gfx_interface to use a device_palette_interface object rather than a palette_device. This necessitates slight alterations to a few drivers and devices.
- Modify v9938 and v9958 to use the new device_palette_interface rather than a subdevice. This entails breaking a cyclic dependency between device_video_interface and screen_device for this case.
Diffstat (limited to 'src/emu/emupal.cpp')
-rw-r--r-- | src/emu/emupal.cpp | 475 |
1 files changed, 4 insertions, 471 deletions
diff --git a/src/emu/emupal.cpp b/src/emu/emupal.cpp index 501349622ce..a2567d47250 100644 --- a/src/emu/emupal.cpp +++ b/src/emu/emupal.cpp @@ -9,9 +9,6 @@ ***************************************************************************/ #include "emu.h" -#include "screen.h" - -#define VERBOSE 0 //************************************************************************** @@ -22,6 +19,7 @@ const device_type PALETTE = device_creator<palette_device>; palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, PALETTE, "palette", tag, owner, clock, "palette", __FILE__), + device_palette_interface(mconfig, *this), m_entries(0), m_indirect_entries(0), m_enable_shadows(0), @@ -30,16 +28,8 @@ palette_device::palette_device(const machine_config &mconfig, const char *tag, d m_membits_supplied(false), m_endianness(), m_endianness_supplied(false), - m_raw_to_rgb(raw_to_rgb_converter()), - m_palette(nullptr), - m_pens(nullptr), - m_format(), - m_shadow_table(nullptr), - m_shadow_group(0), - m_hilight_group(0), - m_white_pen(0), - m_black_pen(0), - m_init(palette_init_delegate()) + m_init(palette_init_delegate()), + m_raw_to_rgb(raw_to_rgb_converter()) { } @@ -102,184 +92,6 @@ void palette_device::static_enable_hilights(device_t &device) //************************************************************************** -// INDIRECTION (AKA COLORTABLES) -//************************************************************************** - -//------------------------------------------------- -// set_indirect_color - set an indirect color -//------------------------------------------------- - -void palette_device::set_indirect_color(int index, rgb_t rgb) -{ - // make sure we are in range - assert(index < m_indirect_entries); - - // alpha doesn't matter - rgb.set_a(255); - - // 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 (u32 pen = 0; pen < m_indirect_pens.size(); pen++) - if (m_indirect_pens[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, indirect_pen_t index) -{ - // make sure we are in range - assert(pen < m_entries && index < m_indirect_entries); - - m_indirect_pens[pen] = index; - - 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 -//------------------------------------------------- - -u32 palette_device::transpen_mask(gfx_element &gfx, u32 color, indirect_pen_t transcolor) -{ - u32 entry = gfx.colorbase() + (color % gfx.colors()) * gfx.granularity(); - - // make sure we are in range - assert(entry < m_indirect_pens.size()); - assert(gfx.depth() <= 32); - - // either gfx->color_depth entries or as many as we can get up until the end - int count = std::min(size_t(gfx.depth()), m_indirect_pens.size() - entry); - - // set a bit anywhere the transcolor matches - u32 mask = 0; - for (int bit = 0; bit < count; bit++) - if (m_indirect_pens[entry++] == transcolor) - mask |= 1 << bit; - - // return the final mask - return mask; -} - - - -//************************************************************************** -// 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 != nullptr); - - // 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 //************************************************************************** @@ -305,7 +117,7 @@ inline void palette_device::update_for_write(offs_t byte_offset, int bytes_modif if (indirect) set_indirect_color(base + index, m_raw_to_rgb(read_entry(base + index))); else - m_palette->entry_set_color(base + index, m_raw_to_rgb(read_entry(base + index))); + set_pen_color(base + index, m_raw_to_rgb(read_entry(base + index))); } } @@ -445,288 +257,9 @@ void palette_device::device_start() } } - // reset all our data - screen_device *device = machine().first_screen(); - m_format = (device != nullptr) ? device->format() : BITMAP_FORMAT_INVALID; - - // allocate the palette - if (m_entries > 0) - { - allocate_palette(); - allocate_color_tables(); - allocate_shadow_tables(); - - // allocate indirection tables - if (m_indirect_entries > 0) - { - m_indirect_colors.resize(m_indirect_entries); - for (int color = 0; color < m_indirect_entries; color++) - { - // alpha = 0 ensures change is detected the first time set_indirect_color() is called - m_indirect_colors[color] = rgb_t::transparent(); - } - - m_indirect_pens.resize(m_entries); - for (int pen = 0; pen < m_entries; pen++) - m_indirect_pens[pen] = pen % m_indirect_entries; - } - } - // call the initialization helper if present if (!m_init.isnull()) m_init(*this); - - // set up save/restore of the palette - m_save_pen.resize(m_palette->num_colors()); - m_save_contrast.resize(m_palette->num_colors()); - save_item(NAME(m_save_pen)); - save_item(NAME(m_save_contrast)); - - // save indirection tables if we have them - if (m_indirect_entries > 0) - { - save_item(NAME(m_indirect_colors)); - save_item(NAME(m_indirect_pens)); - } -} - - - -//************************************************************************** -// 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 != nullptr) - 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, "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 = nullptr; - 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 != nullptr); - - // regenerate the table - int ifactor = int(factor * 256.0f); - for (int rgb555 = 0; rgb555 < 32768; rgb555++) - { - u8 const r = rgb_t::clamp((pal5bit(rgb555 >> 10) * ifactor) >> 8); - u8 const g = rgb_t::clamp((pal5bit(rgb555 >> 5) * ifactor) >> 8); - u8 const 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(); - } } |