summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/emupal.cpp
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2017-04-05 16:48:43 -0400
committer Vas Crabb <cuavas@users.noreply.github.com>2017-04-06 11:30:40 +1000
commit8fe18e9eccb5f0ca5884c76402d7db9911795079 (patch)
tree29b2766835f55c50f38dced2a155d45e23e745a3 /src/emu/emupal.cpp
parentfbb7d927d3a58de18850ad3079621e0a78e5e6bd (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.cpp475
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();
- }
}