summaryrefslogtreecommitdiffstatshomepage
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
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.
-rw-r--r--scripts/src/emu.lua2
-rw-r--r--src/devices/machine/tc009xlvc.cpp2
-rw-r--r--src/devices/video/v9938.cpp54
-rw-r--r--src/devices/video/v9938.h17
-rw-r--r--src/emu/digfx.cpp36
-rw-r--r--src/emu/digfx.h6
-rw-r--r--src/emu/dipalette.cpp503
-rw-r--r--src/emu/dipalette.h144
-rw-r--r--src/emu/divideo.cpp16
-rw-r--r--src/emu/drawgfx.cpp4
-rw-r--r--src/emu/drawgfx.h10
-rw-r--r--src/emu/driver.h2
-rw-r--r--src/emu/emu.h1
-rw-r--r--src/emu/emupal.cpp475
-rw-r--r--src/emu/emupal.h101
-rw-r--r--src/emu/screen.cpp49
-rw-r--r--src/emu/screen.h12
-rw-r--r--src/emu/tilemap.h6
-rw-r--r--src/frontend/mame/ui/viewgfx.cpp23
-rw-r--r--src/mame/drivers/meritm.cpp4
-rw-r--r--src/mame/video/atari400.cpp2
-rw-r--r--src/mame/video/bfm_adr2.cpp2
-rw-r--r--src/mame/video/k007121.cpp2
-rw-r--r--src/mame/video/k007121.h2
-rw-r--r--src/mame/video/konami_helper.cpp2
25 files changed, 807 insertions, 670 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua
index f2f8d82829a..0b6a770bdfc 100644
--- a/scripts/src/emu.lua
+++ b/scripts/src/emu.lua
@@ -82,6 +82,8 @@ files {
MAME_DIR .. "src/emu/dinvram.h",
MAME_DIR .. "src/emu/dioutput.cpp",
MAME_DIR .. "src/emu/dioutput.h",
+ MAME_DIR .. "src/emu/dipalette.cpp",
+ MAME_DIR .. "src/emu/dipalette.h",
MAME_DIR .. "src/emu/dipty.cpp",
MAME_DIR .. "src/emu/dipty.h",
MAME_DIR .. "src/emu/dirom.cpp",
diff --git a/src/devices/machine/tc009xlvc.cpp b/src/devices/machine/tc009xlvc.cpp
index f8c289fa4d1..10a9387a9c4 100644
--- a/src/devices/machine/tc009xlvc.cpp
+++ b/src/devices/machine/tc009xlvc.cpp
@@ -277,7 +277,7 @@ void tc0091lvc_device::device_start()
//printf("m_gfx_index %d\n", m_gfx_index);
- palette_device &palette = m_gfxdecode->palette();
+ device_palette_interface &palette = m_gfxdecode->palette();
m_gfxdecode->set_gfx(m_gfx_index, std::make_unique<gfx_element>(palette, char_layout, (uint8_t *)m_pcg_ram, 0, palette.entries() / 16, 0));
}
diff --git a/src/devices/video/v9938.cpp b/src/devices/video/v9938.cpp
index 469bf2c7a93..510ff787501 100644
--- a/src/devices/video/v9938.cpp
+++ b/src/devices/video/v9938.cpp
@@ -91,6 +91,7 @@ const device_type V9958 = device_creator<v9958_device>;
v99x8_device::v99x8_device(const machine_config &mconfig, device_type type, const char *name, const char *shortname, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
device_memory_interface(mconfig, *this),
+ device_palette_interface(mconfig, *this),
device_video_interface(mconfig, *this),
m_space_config("vram", ENDIANNESS_BIG, 8, 18),
m_model(0),
@@ -116,7 +117,6 @@ v99x8_device::v99x8_device(const machine_config &mconfig, device_type type, cons
m_button_state(0),
m_vdp_ops_count(0),
m_vdp_engine(nullptr),
- m_palette(*this, "palette"),
m_pal_ntsc(0)
{
static_set_addrmap(*this, AS_DATA, ADDRESS_MAP_NAME(memmap));
@@ -301,13 +301,13 @@ b0 is set if b2 and b1 are set (remember, color bus is 3 bits)
*/
-PALETTE_INIT_MEMBER(v9938_device, v9938)
+void v9938_device::palette_init()
{
int i;
// create the full 512 colour palette
for (i=0;i<512;i++)
- palette.set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0));
+ set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0));
}
/*
@@ -323,17 +323,16 @@ to emulate this. Also it keeps the palette a reasonable size. :)
uint16_t v99x8_device::s_pal_indYJK[0x20000];
-PALETTE_INIT_MEMBER(v9958_device, v9958)
+void v9958_device::palette_init()
{
int r,g,b,y,j,k,i,k0,j0,n;
uint8_t pal[19268*3];
// init v9938 512-color palette
for (i=0;i<512;i++)
- palette.set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0));
+ set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0));
-
- if(palette.entries() != 19780)
+ if (entries() != 19780)
fatalerror("V9958: not enough palette, must be 19780");
// set up YJK table
@@ -372,7 +371,7 @@ PALETTE_INIT_MEMBER(v9958_device, v9958)
pal[i*3+0] = r;
pal[i*3+1] = g;
pal[i*3+2] = b;
- palette.set_pen_color(i+512, rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)));
+ set_pen_color(i+512, rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)));
v99x8_device::s_pal_indYJK[y | j << 5 | k << (5 + 6)] = i + 512;
i++;
}
@@ -639,6 +638,8 @@ void v99x8_device::device_start()
m_line_timer = timer_alloc(TIMER_LINE);
+ palette_init();
+
save_item(NAME(m_offset_x));
save_item(NAME(m_offset_y));
save_item(NAME(m_visible_y));
@@ -1853,7 +1854,6 @@ void v99x8_device::set_mode()
void v99x8_device::refresh_16(int line)
{
- const pen_t *pens = m_palette->pens();
bool double_lines = false;
uint8_t col[256];
uint16_t *ln, *ln2 = nullptr;
@@ -1871,15 +1871,15 @@ void v99x8_device::refresh_16(int line)
if ( !(m_cont_reg[1] & 0x40) || (m_stat_reg[2] & 0x40) )
{
- (this->*s_modes[m_mode].border_16)(pens, ln);
+ (this->*s_modes[m_mode].border_16)(pens(), ln);
}
else
{
- (this->*s_modes[m_mode].visible_16)(pens, ln, line);
+ (this->*s_modes[m_mode].visible_16)(pens(), ln, line);
if (s_modes[m_mode].sprites)
{
(this->*s_modes[m_mode].sprites)(line, col);
- (this->*s_modes[m_mode].draw_sprite_16)(pens, ln, col);
+ (this->*s_modes[m_mode].draw_sprite_16)(pens(), ln, col);
}
}
@@ -3050,33 +3050,3 @@ void v99x8_device::update_command()
if(m_vdp_engine) (this->*m_vdp_engine)();
}
}
-
-static MACHINE_CONFIG_FRAGMENT( v9938 )
- MCFG_PALETTE_ADD("palette", 512)
- MCFG_PALETTE_INIT_OWNER(v9938_device, v9938)
-MACHINE_CONFIG_END
-
-//-------------------------------------------------
-// machine_config_additions - return a pointer to
-// the device's machine fragment
-//-------------------------------------------------
-
-machine_config_constructor v9938_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME( v9938 );
-}
-
-static MACHINE_CONFIG_FRAGMENT( v9958 )
- MCFG_PALETTE_ADD("palette", 19780)
- MCFG_PALETTE_INIT_OWNER(v9958_device, v9958)
-MACHINE_CONFIG_END
-
-//-------------------------------------------------
-// machine_config_additions - return a pointer to
-// the device's machine fragment
-//-------------------------------------------------
-
-machine_config_constructor v9958_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME( v9958 );
-}
diff --git a/src/devices/video/v9938.h b/src/devices/video/v9938.h
index a927de33bd3..2e7efa60677 100644
--- a/src/devices/video/v9938.h
+++ b/src/devices/video/v9938.h
@@ -37,7 +37,7 @@
v99x8_device::VERTICAL_ADJUST * 2, \
v99x8_device::VVISIBLE_NTSC * 2 - 1 - v99x8_device::VERTICAL_ADJUST * 2) \
MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) \
- MCFG_SCREEN_PALETTE(_v9938_tag":palette")
+ MCFG_SCREEN_PALETTE(_v9938_tag)
#define MCFG_V99X8_SCREEN_ADD_PAL(_screen_tag, _v9938_tag, _clock) \
MCFG_SCREEN_ADD(_screen_tag, RASTER) \
@@ -49,7 +49,7 @@
v99x8_device::VERTICAL_ADJUST * 2, \
v99x8_device::VVISIBLE_PAL * 2 - 1 - v99x8_device::VERTICAL_ADJUST * 2) \
MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) \
- MCFG_SCREEN_PALETTE(_v9938_tag":palette")
+ MCFG_SCREEN_PALETTE(_v9938_tag)
#define MCFG_V99X8_INTERRUPT_CALLBACK(_irq) \
devcb = &downcast<v99x8_device *>(device)->set_interrupt_callback(DEVCB_##_irq);
@@ -73,6 +73,7 @@ extern const device_type V9958;
class v99x8_device : public device_t,
public device_memory_interface,
+ public device_palette_interface,
public device_video_interface
{
protected:
@@ -133,6 +134,8 @@ protected:
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_DATA) const override { return (spacenum == AS_DATA) ? &m_space_config : nullptr; }
+ virtual void palette_init() = 0;
+
void configure_pal_ntsc();
void set_screen_parameters();
@@ -263,7 +266,6 @@ private:
void (v99x8_device::*draw_sprite_16)(const pen_t *, uint16_t*, uint8_t*);
} ;
static const v99x8_mode s_modes[];
- required_device<palette_device> m_palette;
emu_timer *m_line_timer;
uint8_t m_pal_ntsc;
int m_scanline_start;
@@ -280,9 +282,9 @@ class v9938_device : public v99x8_device
public:
v9938_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- DECLARE_PALETTE_INIT(v9938);
protected:
- virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void palette_init() override;
+ virtual int palette_entries() const override { return 512; }
};
class v9958_device : public v99x8_device
@@ -290,10 +292,9 @@ class v9958_device : public v99x8_device
public:
v9958_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- DECLARE_PALETTE_INIT(v9958);
-
protected:
- virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void palette_init() override;
+ virtual int palette_entries() const override { return 19780; }
};
diff --git a/src/emu/digfx.cpp b/src/emu/digfx.cpp
index e47d44036a8..b5db1116e71 100644
--- a/src/emu/digfx.cpp
+++ b/src/emu/digfx.cpp
@@ -79,22 +79,28 @@ void device_gfx_interface::static_set_palette(device_t &device, const char *tag)
void device_gfx_interface::interface_pre_start()
{
if (m_palette_tag == nullptr)
- fatalerror("No palette specified for device '%s'\n", device().tag());
+ fatalerror("No palette specified for device\n");
// find our palette device, either as a sibling device or subdevice
+ device_t *paldev;
if (m_palette_is_sibling)
- m_palette = device().owner()->subdevice<palette_device>(m_palette_tag);
+ paldev = device().owner()->subdevice(m_palette_tag);
else
- m_palette = device().subdevice<palette_device>(m_palette_tag);
+ paldev = device().subdevice(m_palette_tag);
- if (m_palette == nullptr)
+ if (paldev == nullptr)
fatalerror("Device '%s' specifies nonexistent %sdevice '%s' as palette\n",
device().tag(),
(m_palette_is_sibling ? "sibling " : "sub"),
m_palette_tag);
+ if (!paldev->interface(m_palette))
+ fatalerror("Device '%s' specifies %sdevice '%s' as palette, but it has no palette interface\n",
+ device().tag(),
+ (m_palette_is_sibling ? "sibling " : "sub"),
+ m_palette_tag);
// if palette device isn't started, wait for it
- // if (!m_palette->started())
+ // if (!m_palette->device().started())
// throw device_missing_dependencies();
}
@@ -295,17 +301,23 @@ void device_gfx_interface::interface_validity_check(validity_checker &valid) con
osd_printf_error("No palette specified for device '%s'\n", device().tag());
else
{
- palette_device *palette;
+ device_t *paldev;
if (m_palette_is_sibling)
- palette = device().owner()->subdevice<palette_device>(m_palette_tag);
+ paldev = device().owner()->subdevice(m_palette_tag);
else
- palette = device().subdevice<palette_device>(m_palette_tag);
-
- if (palette == nullptr)
- osd_printf_error("Device '%s' specifies nonexistent %sdevice '%s' as palette\n",
- device().tag(),
+ paldev = device().subdevice(m_palette_tag);
+ if (paldev == nullptr)
+ osd_printf_error("Nonexistent %sdevice '%s' specified as palette\n",
(m_palette_is_sibling ? "sibling " : "sub"),
m_palette_tag);
+ else
+ {
+ device_palette_interface *palintf;
+ if (!paldev->interface(palintf))
+ osd_printf_error("%sdevice '%s' specified as palette, but it has no palette interface\n",
+ (m_palette_is_sibling ? "Sibling " : "Sub"),
+ m_palette_tag);
+ }
}
if (!m_gfxdecodeinfo)
diff --git a/src/emu/digfx.h b/src/emu/digfx.h
index a8f8a80f672..539266190d6 100644
--- a/src/emu/digfx.h
+++ b/src/emu/digfx.h
@@ -156,7 +156,7 @@ const gfx_layout name = { width, height, RGN_FRAC(1,1), 8, { GFX_RAW }, { 0 }, {
// forward declarations
class gfx_element;
-class palette_device;
+class device_palette_interface;
struct gfx_layout
{
@@ -200,7 +200,7 @@ public:
static void static_set_palette(device_t &device, const char *tag);
// getters
- palette_device &palette() const { assert(m_palette != nullptr); return *m_palette; }
+ device_palette_interface &palette() const { assert(m_palette != nullptr); return *m_palette; }
gfx_element *gfx(u8 index) const { assert(index < MAX_GFX_ELEMENTS); return m_gfx[index].get(); }
// decoding
@@ -216,7 +216,7 @@ protected:
virtual void interface_post_start() override;
private:
- palette_device * m_palette; // pointer to the palette device
+ device_palette_interface * m_palette; // pointer to the palette device interface
std::unique_ptr<gfx_element> m_gfx[MAX_GFX_ELEMENTS]; // array of pointers to graphic sets
// configuration
diff --git a/src/emu/dipalette.cpp b/src/emu/dipalette.cpp
new file mode 100644
index 00000000000..125f7b2c53c
--- /dev/null
+++ b/src/emu/dipalette.cpp
@@ -0,0 +1,503 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ dipalette.cpp
+
+ Device palette interface.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "screen.h"
+
+#define VERBOSE 0
+
+
+//**************************************************************************
+// DEVICE INTERFACE MANAGEMENT
+//**************************************************************************
+
+//-------------------------------------------------
+// device_palette_interface - constructor
+//-------------------------------------------------
+
+device_palette_interface::device_palette_interface(const machine_config &mconfig, device_t &device)
+ : device_interface(device, "palette"),
+ 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)
+{
+}
+
+
+//-------------------------------------------------
+// interface_pre_start - work to be done prior to
+// actually starting a device
+//-------------------------------------------------
+
+void device_palette_interface::interface_pre_start()
+{
+ // reset all our data
+ screen_device *screen = device().machine().first_screen();
+ m_format = (screen != nullptr) ? screen->format() : BITMAP_FORMAT_INVALID;
+
+ // allocate the palette
+ int numentries = palette_entries();
+ if (numentries > 0)
+ {
+ allocate_palette(numentries);
+ allocate_color_tables();
+ allocate_shadow_tables();
+
+ // allocate indirection tables
+ int indirect_colors = palette_indirect_entries();
+ if (indirect_colors > 0)
+ {
+ m_indirect_colors.resize(indirect_colors);
+ for (int color = 0; color < indirect_colors; 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(numentries);
+ for (int pen = 0; pen < numentries; pen++)
+ m_indirect_pens[pen] = pen % indirect_colors;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// interface_post_start - work to be done after
+// actually starting a device
+//-------------------------------------------------
+
+void device_palette_interface::interface_post_start()
+{
+ // set up save/restore of the palette
+ m_save_pen.resize(m_palette->num_colors());
+ m_save_contrast.resize(m_palette->num_colors());
+ device().save_item(NAME(m_save_pen));
+ device().save_item(NAME(m_save_contrast));
+
+ // save indirection tables if we have them
+ if (m_indirect_colors.size() > 0)
+ {
+ device().save_item(NAME(m_indirect_colors));
+ device().save_item(NAME(m_indirect_pens));
+ }
+}
+
+
+//-------------------------------------------------
+// interface_pre_save - prepare the save arrays
+// for saving
+//-------------------------------------------------
+
+void device_palette_interface::interface_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);
+ }
+}
+
+
+//-------------------------------------------------
+// interface_post_load - called after restore to
+// actually update the palette
+//-------------------------------------------------
+
+void device_palette_interface::interface_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]);
+ }
+}
+
+
+//-------------------------------------------------
+// interface_post_stop - final cleanup
+//-------------------------------------------------
+
+void device_palette_interface::interface_post_stop()
+{
+ // dereference the palette
+ if (m_palette != nullptr)
+ m_palette->deref();
+}
+
+
+//**************************************************************************
+// INDIRECTION (AKA COLORTABLES)
+//**************************************************************************
+
+//-------------------------------------------------
+// set_indirect_color - set an indirect color
+//-------------------------------------------------
+
+void device_palette_interface::set_indirect_color(int index, rgb_t rgb)
+{
+ // make sure we are in range
+ assert(index < m_indirect_pens.size());
+
+ // 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 device_palette_interface::set_pen_indirect(pen_t pen, indirect_pen_t index)
+{
+ // make sure we are in range
+ assert(pen < entries() && index < 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 device_palette_interface::transpen_mask(gfx_element &gfx, u32 color, indirect_pen_t transcolor) const
+{
+ 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 device_palette_interface::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)
+ device().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();
+ }
+}
+
+
+//**************************************************************************
+// INTERNAL FUNCTIONS
+//**************************************************************************
+
+//-------------------------------------------------
+// allocate_palette - allocate and configure the
+// palette object itself
+//-------------------------------------------------
+
+void device_palette_interface::allocate_palette(int numentries)
+{
+ // determine the number of groups we need
+ int numgroups = 1;
+ if (palette_shadows_enabled())
+ m_shadow_group = numgroups++;
+ if (palette_hilights_enabled())
+ m_hilight_group = numgroups++;
+ assert_always(numentries * numgroups <= 65536, "Palette has more than 65536 colors.");
+
+ // allocate a palette object containing all the colors and groups
+ m_palette = palette_t::alloc(numentries, numgroups);
+
+ // configure the groups
+ if (m_shadow_group != 0)
+ set_shadow_factor(PALETTE_DEFAULT_SHADOW_FACTOR);
+ if (m_hilight_group != 0)
+ set_highlight_factor(PALETTE_DEFAULT_HIGHLIGHT_FACTOR);
+
+ // set the initial colors to a standard rainbow
+ for (int index = 0; index < numentries; 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 device_palette_interface::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 device_palette_interface::allocate_shadow_tables()
+{
+ int numentries = m_palette->num_colors();
+
+ // if we have shadows, allocate shadow tables
+ if (m_shadow_group != 0)
+ {
+ 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 < numentries) ? (i + numentries) : 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, PALETTE_DEFAULT_SHADOW_FACTOR);
+ }
+ }
+
+ // if we have hilights, allocate shadow tables
+ if (m_hilight_group != 0)
+ {
+ 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 < numentries) ? (i + 2 * numentries) : 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, 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 device_palette_interface::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();
+ }
+}
diff --git a/src/emu/dipalette.h b/src/emu/dipalette.h
new file mode 100644
index 00000000000..dcc3d38e2c0
--- /dev/null
+++ b/src/emu/dipalette.h
@@ -0,0 +1,144 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ dipalette.h
+
+ Device palette interface.
+
+******************************************************************************/
+
+#pragma once
+
+#ifndef __EMU_H__
+#error Dont include this file directly; include emu.h instead.
+#endif
+
+#ifndef MAME_EMU_DIPALETTE_H
+#define MAME_EMU_DIPALETTE_H
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+constexpr float PALETTE_DEFAULT_SHADOW_FACTOR = 0.6;
+constexpr float PALETTE_DEFAULT_HIGHLIGHT_FACTOR = 1/PALETTE_DEFAULT_SHADOW_FACTOR;
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class gfx_element;
+
+typedef u16 indirect_pen_t;
+
+
+// ======================> device_palette_interface
+
+class device_palette_interface : public device_interface
+{
+ static constexpr int MAX_SHADOW_PRESETS = 4;
+
+public:
+ // construction/destruction
+ device_palette_interface(const machine_config &mconfig, device_t &device);
+
+ // getters
+ int entries() const { return (m_palette != nullptr) ? m_palette->num_colors() : 0; }
+ int indirect_entries() const { return m_indirect_colors.size(); }
+ palette_t *palette() const { return m_palette; }
+ const pen_t &pen(int index) const { return m_pens[index]; }
+ const pen_t *pens() const { return m_pens; }
+ pen_t *shadow_table() const { return m_shadow_table; }
+ rgb_t pen_color(pen_t pen) const { return m_palette->entry_color(pen); }
+ double pen_contrast(pen_t pen) const { return m_palette->entry_contrast(pen); }
+ pen_t black_pen() const { return m_black_pen; }
+ pen_t white_pen() const { return m_white_pen; }
+ bool shadows_enabled() const { return m_shadow_group != 0; }
+ bool hilights_enabled() const { return m_hilight_group != 0; }
+
+ // setters
+ void set_pen_color(pen_t pen, rgb_t rgb) { m_palette->entry_set_color(pen, rgb); }
+ void set_pen_red_level(pen_t pen, u8 level) { m_palette->entry_set_red_level(pen, level); }
+ void set_pen_green_level(pen_t pen, u8 level) { m_palette->entry_set_green_level(pen, level); }
+ void set_pen_blue_level(pen_t pen, u8 level) { m_palette->entry_set_blue_level(pen, level); }
+ void set_pen_color(pen_t pen, u8 r, u8 g, u8 b) { m_palette->entry_set_color(pen, rgb_t(r, g, b)); }
+ void set_pen_colors(pen_t color_base, const rgb_t *colors, int color_count) { while (color_count--) set_pen_color(color_base++, *colors++); }
+ void set_pen_colors(pen_t color_base, const std::vector<rgb_t> &colors) { for (unsigned int i=0; i != colors.size(); i++) set_pen_color(color_base+i, colors[i]); }
+ void set_pen_contrast(pen_t pen, double bright) { m_palette->entry_set_contrast(pen, bright); }
+
+ // indirection (aka colortables)
+ indirect_pen_t pen_indirect(int index) const { return m_indirect_pens[index]; }
+ rgb_t indirect_color(int index) const { return m_indirect_colors[index]; }
+ void set_indirect_color(int index, rgb_t rgb);
+ void set_pen_indirect(pen_t pen, indirect_pen_t index);
+ u32 transpen_mask(gfx_element &gfx, u32 color, indirect_pen_t transcolor) const;
+
+ // shadow config
+ void set_shadow_factor(double factor) { assert(m_shadow_group != 0); m_palette->group_set_contrast(m_shadow_group, factor); }
+ void set_highlight_factor(double factor) { assert(m_hilight_group != 0); m_palette->group_set_contrast(m_hilight_group, factor); }
+ void set_shadow_mode(int mode) { assert(mode >= 0 && mode < MAX_SHADOW_PRESETS); m_shadow_table = m_shadow_tables[mode].base; }
+
+protected:
+ // interface-level overrides
+ virtual void interface_pre_start() override;
+ virtual void interface_post_start() override;
+ virtual void interface_pre_save() override;
+ virtual void interface_post_load() override;
+ virtual void interface_post_stop() override;
+
+ // configuration-related overrides
+ virtual int palette_entries() const = 0;
+ virtual int palette_indirect_entries() const { return 0; }
+ virtual bool palette_shadows_enabled() const { return false; }
+ virtual bool palette_hilights_enabled() const { return false; }
+
+private:
+ // internal helpers
+ void allocate_palette(int numentries);
+ void allocate_color_tables();
+ void allocate_shadow_tables();
+public: // needed by konamigx
+ void set_shadow_dRGB32(int mode, int dr, int dg, int db, bool noclip);
+private:
+ void configure_rgb_shadows(int mode, float factor);
+
+ // internal state
+ palette_t * m_palette; // the palette itself
+ const pen_t * m_pens; // remapped palette pen numbers
+ bitmap_format m_format; // format assumed for palette data
+ pen_t * m_shadow_table; // table for looking up a shadowed pen
+ u32 m_shadow_group; // index of the shadow group, or 0 if none
+ u32 m_hilight_group; // index of the hilight group, or 0 if none
+ pen_t m_white_pen; // precomputed white pen value
+ pen_t m_black_pen; // precomputed black pen value
+
+ // indirection state
+ std::vector<rgb_t> m_indirect_colors; // actual colors set for indirection
+ std::vector<indirect_pen_t> m_indirect_pens; // indirection values
+
+ struct shadow_table_data
+ {
+ pen_t * base; // pointer to the base of the table
+ s16 dr; // delta red value
+ s16 dg; // delta green value
+ s16 db; // delta blue value
+ bool noclip; // clip?
+ };
+ shadow_table_data m_shadow_tables[MAX_SHADOW_PRESETS]; // array of shadow table data
+
+ std::vector<pen_t> m_save_pen; // pens for save/restore
+ std::vector<float> m_save_contrast; // brightness for save/restore
+
+ std::vector<pen_t> m_pen_array;
+ std::vector<pen_t> m_shadow_array;
+ std::vector<pen_t> m_hilight_array;
+};
+
+// interface type iterator
+typedef device_interface_iterator<device_palette_interface> palette_interface_iterator;
+
+
+#endif // MAME_EMU_DIPALETTE_H
diff --git a/src/emu/divideo.cpp b/src/emu/divideo.cpp
index c2ac42fd1b2..a8e86fe0bd1 100644
--- a/src/emu/divideo.cpp
+++ b/src/emu/divideo.cpp
@@ -126,6 +126,20 @@ void device_video_interface::interface_pre_start()
throw emu_fatalerror("Device '%s' requires a screen", device().tag());
// if we have a screen and it's not started, wait for it
+ device_palette_interface *palintf;
if (m_screen != nullptr && !m_screen->started())
- throw device_missing_dependencies();
+ {
+ // avoid circular dependency if we are also a palette device
+ if (!device().interface(palintf))
+ throw device_missing_dependencies();
+ else
+ {
+ // resolve the palette for the sake of register_screen_bitmap
+ m_screen->resolve_palette();
+
+ // no other palette may be specified
+ if (m_screen->has_palette() && palintf != &m_screen->palette())
+ throw emu_fatalerror("Device '%s' cannot control screen '%s' with palette '%s'", m_screen_tag, device().tag(), m_screen->palette().device().tag());
+ }
+ }
}
diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp
index 0107d6418ba..009dc064d28 100644
--- a/src/emu/drawgfx.cpp
+++ b/src/emu/drawgfx.cpp
@@ -86,7 +86,7 @@ gfxdecode_device::gfxdecode_device(const machine_config &mconfig, const char *ta
// gfx_element - constructor
//-------------------------------------------------
-gfx_element::gfx_element(palette_device &palette, u8 *base, u16 width, u16 height, u32 rowbytes, u32 total_colors, u32 color_base, u32 color_granularity)
+gfx_element::gfx_element(device_palette_interface &palette, u8 *base, u16 width, u16 height, u32 rowbytes, u32 total_colors, u32 color_base, u32 color_granularity)
: m_palette(&palette),
m_width(width),
m_height(height),
@@ -111,7 +111,7 @@ gfx_element::gfx_element(palette_device &palette, u8 *base, u16 width, u16 heigh
{
}
-gfx_element::gfx_element(palette_device &palette, const gfx_layout &gl, const u8 *srcdata, u32 xormask, u32 total_colors, u32 color_base)
+gfx_element::gfx_element(device_palette_interface &palette, const gfx_layout &gl, const u8 *srcdata, u32 xormask, u32 total_colors, u32 color_base)
: m_palette(&palette),
m_width(0),
m_height(0),
diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h
index bd5c7bde99e..4ff720b3054 100644
--- a/src/emu/drawgfx.h
+++ b/src/emu/drawgfx.h
@@ -151,11 +151,11 @@ public:
#ifdef UNUSED_FUNCTION
gfx_element();
#endif
- gfx_element(palette_device &palette, const gfx_layout &gl, const u8 *srcdata, u32 xormask, u32 total_colors, u32 color_base);
- gfx_element(palette_device &palette, u8 *base, u16 width, u16 height, u32 rowbytes, u32 total_colors, u32 color_base, u32 color_granularity);
+ gfx_element(device_palette_interface &palette, const gfx_layout &gl, const u8 *srcdata, u32 xormask, u32 total_colors, u32 color_base);
+ gfx_element(device_palette_interface &palette, u8 *base, u16 width, u16 height, u32 rowbytes, u32 total_colors, u32 color_base, u32 color_granularity);
// getters
- palette_device &palette() const { return *m_palette; }
+ device_palette_interface &palette() const { return *m_palette; }
u16 width() const { return m_width; }
u16 height() const { return m_height; }
u32 elements() const { return m_total_elements; }
@@ -175,7 +175,7 @@ public:
void set_source(const u8 *source);
void set_source_and_total(const u8 *source, u32 total);
void set_xormask(u32 xormask) { m_layout_xormask = xormask; }
- void set_palette(palette_device &palette) { m_palette = &palette; }
+ void set_palette(device_palette_interface &palette) { m_palette = &palette; }
void set_colors(u32 colors) { m_total_colors = colors; }
void set_colorbase(u16 colorbase) { m_color_base = colorbase; }
void set_granularity(u16 granularity) { m_color_granularity = granularity; }
@@ -269,7 +269,7 @@ private:
void decode(u32 code);
// internal state
- palette_device *m_palette; // palette used for drawing
+ device_palette_interface *m_palette; // palette used for drawing
u16 m_width; // current pixel width of each element (changeable with source clipping)
u16 m_height; // current pixel height of each element (changeable with source clipping)
diff --git a/src/emu/driver.h b/src/emu/driver.h
index 133e354a26d..eb3de5e8596 100644
--- a/src/emu/driver.h
+++ b/src/emu/driver.h
@@ -89,8 +89,6 @@
//**************************************************************************
// forward declarations
-class gfxdecode_device;
-class palette_device;
typedef delegate<void ()> driver_callback_delegate;
diff --git a/src/emu/emu.h b/src/emu/emu.h
index 66832b06dea..1c11bf5aeea 100644
--- a/src/emu/emu.h
+++ b/src/emu/emu.h
@@ -73,6 +73,7 @@ typedef device_t * (*machine_config_constructor)(machine_config &config, device_
#include "dirom.h"
#include "diexec.h"
#include "opresolv.h"
+#include "dipalette.h"
#include "digfx.h"
#include "diimage.h"
#include "dioutput.h"
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();
- }
}
diff --git a/src/emu/emupal.h b/src/emu/emupal.h
index 42b1c1253cc..31f6937fb52 100644
--- a/src/emu/emupal.h
+++ b/src/emu/emupal.h
@@ -104,9 +104,6 @@
// CONSTANTS
//**************************************************************************
-#define PALETTE_DEFAULT_SHADOW_FACTOR (0.6)
-#define PALETTE_DEFAULT_HIGHLIGHT_FACTOR (1/PALETTE_DEFAULT_SHADOW_FACTOR)
-
#define PALETTE_INIT_NAME(_Name) palette_init_##_Name
#define DECLARE_PALETTE_INIT(_Name) void PALETTE_INIT_NAME(_Name)(palette_device &palette)
#define PALETTE_INIT_MEMBER(_Class, _Name) void _Class::PALETTE_INIT_NAME(_Name)(palette_device &palette)
@@ -288,10 +285,9 @@
// TYPE DEFINITIONS
//**************************************************************************
+class palette_device; // forward declaration
typedef device_delegate<void (palette_device &)> palette_init_delegate;
-typedef u16 indirect_pen_t;
-
// ======================> raw_to_rgb_converter
@@ -360,10 +356,8 @@ private:
// device type definition
extern const device_type PALETTE;
-class palette_device : public device_t
+class palette_device : public device_t, public device_palette_interface
{
- static const int MAX_SHADOW_PRESETS = 4;
-
public:
// construction/destruction
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
@@ -378,21 +372,9 @@ public:
static void static_enable_shadows(device_t &device);
static void static_enable_hilights(device_t &device);
- // getters
- int entries() const { return m_entries; }
- int indirect_entries() const { return m_indirect_entries; }
- palette_t *palette() const { return m_palette; }
- const pen_t &pen(int index) const { return m_pens[index]; }
- const pen_t *pens() const { return m_pens; }
- pen_t *shadow_table() const { return m_shadow_table; }
- rgb_t pen_color(pen_t pen) { return m_palette->entry_color(pen); }
- double pen_contrast(pen_t pen) { return m_palette->entry_contrast(pen); }
- pen_t black_pen() const { return m_black_pen; }
- pen_t white_pen() const { return m_white_pen; }
+ // palette RAM accessors
memory_array &basemem() { return m_paletteram; }
memory_array &extmem() { return m_paletteram_ext; }
- bool shadows_enabled() { return m_enable_shadows; }
- bool hilights_enabled() { return m_enable_hilights; }
// raw entry reading
u32 read_entry(pen_t pen) const
@@ -403,28 +385,6 @@ public:
return data;
}
- // setters
- void set_pen_color(pen_t pen, rgb_t rgb) { m_palette->entry_set_color(pen, rgb); }
- void set_pen_red_level(pen_t pen, u8 level) { m_palette->entry_set_red_level(pen, level); }
- void set_pen_green_level(pen_t pen, u8 level) { m_palette->entry_set_green_level(pen, level); }
- void set_pen_blue_level(pen_t pen, u8 level) { m_palette->entry_set_blue_level(pen, level); }
- void set_pen_color(pen_t pen, u8 r, u8 g, u8 b) { m_palette->entry_set_color(pen, rgb_t(r, g, b)); }
- void set_pen_colors(pen_t color_base, const rgb_t *colors, int color_count) { while (color_count--) set_pen_color(color_base++, *colors++); }
- void set_pen_colors(pen_t color_base, const std::vector<rgb_t> &colors) { for(unsigned int i=0; i != colors.size(); i++) set_pen_color(color_base+i, colors[i]); }
- void set_pen_contrast(pen_t pen, double bright) { m_palette->entry_set_contrast(pen, bright); }
-
- // indirection (aka colortables)
- indirect_pen_t pen_indirect(int index) const { return m_indirect_pens[index]; }
- rgb_t indirect_color(int index) const { return m_indirect_colors[index]; }
- void set_indirect_color(int index, rgb_t rgb);
- void set_pen_indirect(pen_t pen, indirect_pen_t index);
- u32 transpen_mask(gfx_element &gfx, u32 color, indirect_pen_t transcolor);
-
- // shadow config
- void set_shadow_factor(double factor) { assert(m_shadow_group != 0); m_palette->group_set_contrast(m_shadow_group, factor); }
- void set_highlight_factor(double factor) { assert(m_hilight_group != 0); m_palette->group_set_contrast(m_hilight_group, factor); }
- void set_shadow_mode(int mode) { assert(mode >= 0 && mode < MAX_SHADOW_PRESETS); m_shadow_table = m_shadow_tables[mode].base; }
-
// generic read/write handlers
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
@@ -455,25 +415,20 @@ public:
// helper to update palette when data changed
void update() { if (!m_init.isnull()) m_init(*this); }
+
protected:
// device-level overrides
- virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_start() override;
- virtual void device_pre_save() override;
- virtual void device_post_load() override;
- virtual void device_stop() override;
- void allocate_palette();
- void allocate_color_tables();
- void allocate_shadow_tables();
+ // device_palette_interface overrides
+ virtual int palette_entries() const override { return m_entries; }
+ virtual int palette_indirect_entries() const override { return m_indirect_entries; }
+ virtual bool palette_shadows_enabled() const override { return m_enable_shadows; }
+ virtual bool palette_hilights_enabled() const override { return m_enable_hilights; }
+private:
void update_for_write(offs_t byte_offset, int bytes_modified, bool indirect = false);
-public: // needed by konamigx
- void set_shadow_dRGB32(int mode, int dr, int dg, int db, bool noclip);
-protected:
- void configure_rgb_shadows(int mode, float factor);
-private:
// configuration state
int m_entries; // number of entries in the palette
int m_indirect_entries; // number of indirect colors in the palette
@@ -483,47 +438,13 @@ private:
bool m_membits_supplied; // true if membits forced in static config
endianness_t m_endianness; // endianness of palette RAM, if different from native
bool m_endianness_supplied; // true if endianness forced in static config
+ palette_init_delegate m_init;
// palette RAM
raw_to_rgb_converter m_raw_to_rgb; // format of palette RAM
memory_array m_paletteram; // base memory
memory_array m_paletteram_ext; // extended memory
-
- // internal state
- palette_t * m_palette; // the palette itself
- const pen_t * m_pens; // remapped palette pen numbers
- bitmap_format m_format; // format assumed for palette data
- pen_t * m_shadow_table; // table for looking up a shadowed pen
- u32 m_shadow_group; // index of the shadow group, or 0 if none
- u32 m_hilight_group; // index of the hilight group, or 0 if none
- pen_t m_white_pen; // precomputed white pen value
- pen_t m_black_pen; // precomputed black pen value
-
- // indirection state
- std::vector<rgb_t> m_indirect_colors; // actual colors set for indirection
- std::vector<indirect_pen_t> m_indirect_pens; // indirection values
-
- struct shadow_table_data
- {
- pen_t * base; // pointer to the base of the table
- s16 dr; // delta red value
- s16 dg; // delta green value
- s16 db; // delta blue value
- bool noclip; // clip?
- };
- shadow_table_data m_shadow_tables[MAX_SHADOW_PRESETS]; // array of shadow table data
-
- std::vector<pen_t> m_save_pen; // pens for save/restore
- std::vector<float> m_save_contrast; // brightness for save/restore
-
- std::vector<pen_t> m_pen_array;
- std::vector<pen_t> m_shadow_array;
- std::vector<pen_t> m_hilight_array;
- palette_init_delegate m_init;
};
-// device type iterator
-typedef device_type_iterator<palette_device> palette_device_iterator;
-
#endif // MAME_EMU_EMUPAL_H
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 8b4bcfa0cff..63004cc4978 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -558,7 +558,8 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
m_xscale(1.0f),
m_yscale(1.0f),
m_screen_vblank(*this),
- m_palette(*this, finder_base::DUMMY_TAG),
+ m_palette(nullptr),
+ m_palette_tag(nullptr),
m_video_attributes(0),
m_svg_region(nullptr),
m_container(nullptr),
@@ -727,7 +728,7 @@ void screen_device::static_set_screen_update(device_t &device, screen_update_rgb
void screen_device::static_set_palette(device_t &device, const char *tag)
{
- downcast<screen_device &>(device).m_palette.set_tag(tag);
+ downcast<screen_device &>(device).m_palette_tag = tag;
}
@@ -785,10 +786,23 @@ void screen_device::device_validity_check(validity_checker &valid) const
osd_printf_error("Invalid (zero) refresh rate\n");
texture_format texformat = !m_screen_update_ind16.isnull() ? TEXFORMAT_PALETTE16 : TEXFORMAT_RGB32;
- if (m_palette == nullptr && texformat == TEXFORMAT_PALETTE16)
+ if (m_palette_tag != nullptr)
+ {
+ if (texformat == TEXFORMAT_RGB32)
+ osd_printf_warning("Screen does not need palette defined\n");
+
+ device_t *paldev = owner()->subdevice(m_palette_tag);
+ if (paldev == nullptr)
+ osd_printf_error("Nonexistent device '%s' specified as palette\n", m_palette_tag);
+ else
+ {
+ device_palette_interface *palintf;
+ if (!paldev->interface(palintf))
+ osd_printf_error("Device '%s' specified as palette, but it has no palette interface\n", m_palette_tag);
+ }
+ }
+ else if (texformat == TEXFORMAT_PALETTE16)
osd_printf_error("Screen does not have palette defined\n");
- if (m_palette != nullptr && texformat == TEXFORMAT_RGB32)
- osd_printf_warning("Screen does not need palette defined\n");
}
@@ -821,7 +835,8 @@ void screen_device::device_start()
m_screen_vblank.resolve_safe();
// if we have a palette and it's not started, wait for it
- if (m_palette != nullptr && !m_palette->started())
+ resolve_palette();
+ if (m_palette != nullptr && !m_palette->device().started())
throw device_missing_dependencies();
// configure bitmap formats and allocate screen bitmaps
@@ -1470,6 +1485,28 @@ void screen_device::register_screen_bitmap(bitmap_t &bitmap)
//-------------------------------------------------
+// resolve_palette - find the specified palette
+//-------------------------------------------------
+
+void screen_device::resolve_palette()
+{
+ if (m_palette_tag != nullptr && m_palette == nullptr)
+ {
+ // find our palette as a sibling device
+ device_t *palette = owner()->subdevice(m_palette_tag);
+ if (palette == nullptr)
+ fatalerror("Screen '%s' specifies nonexistent device '%s' as palette\n",
+ tag(),
+ m_palette_tag);
+ if (!palette->interface(m_palette))
+ fatalerror("Screen '%s' specifies device '%s' as palette, but it has no palette interface\n",
+ tag(),
+ m_palette_tag);
+ }
+}
+
+
+//-------------------------------------------------
// vblank_begin - call any external callbacks to
// signal the VBLANK period has begun
//-------------------------------------------------
diff --git a/src/emu/screen.h b/src/emu/screen.h
index e9d87561c7c..9176bead392 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -213,8 +213,8 @@ public:
// information getters
render_container &container() const { assert(m_container != nullptr); return *m_container; }
bitmap_ind8 &priority() { return m_priority; }
- palette_device &palette() const { assert(m_palette.found()); return *m_palette; }
- bool has_palette() const { return m_palette.found(); }
+ device_palette_interface &palette() const { assert(m_palette != nullptr); return *m_palette; }
+ bool has_palette() const { return m_palette != nullptr; }
// dynamic configuration
void configure(int width, int height, const rectangle &visarea, attoseconds_t frame_period);
@@ -247,6 +247,7 @@ public:
// additional helpers
void register_vblank_callback(vblank_state_delegate vblank_callback);
void register_screen_bitmap(bitmap_t &bitmap);
+ void resolve_palette();
// internal to the video system
bool update_quads();
@@ -292,7 +293,8 @@ private:
screen_update_ind16_delegate m_screen_update_ind16; // screen update callback (16-bit palette)
screen_update_rgb32_delegate m_screen_update_rgb32; // screen update callback (32-bit RGB)
devcb_write_line m_screen_vblank; // screen vblank line callback
- optional_device<palette_device> m_palette; // our palette
+ device_palette_interface *m_palette; // our palette
+ const char * m_palette_tag; // configured tag for palette device
u32 m_video_attributes; // flags describing the video system
const char * m_svg_region; // the region in which the svg data is in
@@ -496,9 +498,9 @@ extern template class device_finder<screen_device, true>;
#define MCFG_SCREEN_VBLANK_CALLBACK(_devcb) \
devcb = &screen_device::static_set_screen_vblank(*device, DEVCB_##_devcb);
#define MCFG_SCREEN_PALETTE(_palette_tag) \
- screen_device::static_set_palette(*device, "^" _palette_tag);
+ screen_device::static_set_palette(*device, _palette_tag);
#define MCFG_SCREEN_NO_PALETTE \
- screen_device::static_set_palette(*device, finder_base::DUMMY_TAG);
+ screen_device::static_set_palette(*device, nullptr);
#define MCFG_SCREEN_VIDEO_ATTRIBUTES(_flags) \
screen_device::static_set_video_attributes(*device, _flags);
#define MCFG_SCREEN_COLOR(_color) \
diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h
index 729e0dc99d0..f4261c209d1 100644
--- a/src/emu/tilemap.h
+++ b/src/emu/tilemap.h
@@ -502,7 +502,7 @@ public:
// getters
running_machine &machine() const;
tilemap_device *device() const { return m_device; }
- palette_device &palette() const { return *m_palette; }
+ device_palette_interface &palette() const { return *m_palette; }
device_gfx_interface &decoder() const { return *m_tileinfo.decoder; }
tilemap_t *next() const { return m_next; }
@@ -530,7 +530,7 @@ public:
// setters
void enable(bool enable = true) { m_enable = enable; }
void set_user_data(void *user_data) { m_user_data = user_data; }
- void set_palette(palette_device &palette) { m_palette = &palette; }
+ void set_palette(device_palette_interface &palette) { m_palette = &palette; }
void set_palette_offset(u32 offset) { m_palette_offset = offset; }
void set_scrolldx(int dx, int dx_flipped) { m_dx = dx; m_dx_flipped = dx_flipped; }
void set_scrolldy(int dy, int dy_flipped) { m_dy = dy; m_dy_flipped = dy_flipped; }
@@ -634,7 +634,7 @@ private:
// managers and devices
tilemap_manager * m_manager; // reference to the owning manager
tilemap_device * m_device; // pointer to our owning device
- palette_device * m_palette; // palette used for drawing
+ device_palette_interface * m_palette; // palette used for drawing
tilemap_t * m_next; // pointer to next tilemap
void * m_user_data; // user data value
diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp
index f87afd67d20..085f2d25d7b 100644
--- a/src/frontend/mame/ui/viewgfx.cpp
+++ b/src/frontend/mame/ui/viewgfx.cpp
@@ -61,7 +61,7 @@ struct ui_gfx_state
// palette-specific data
struct
{
- palette_device *device; // pointer to current device
+ device_palette_interface *interface; // pointer to current palette
int devcount; // how many palette devices exist
int devindex; // which palette device is visible
uint8_t which; // which subset (pens or indirect colors)?
@@ -169,7 +169,7 @@ void ui_gfx_init(running_machine &machine)
static void ui_gfx_count_devices(running_machine &machine, ui_gfx_state &state)
{
// count the palette devices
- state.palette.devcount = palette_device_iterator(machine.root_device()).count();
+ state.palette.devcount = palette_interface_iterator(machine.root_device()).count();
// set the pointer to the first palette
if (state.palette.devcount > 0)
@@ -330,8 +330,8 @@ cancel:
static void palette_set_device(running_machine &machine, ui_gfx_state &state)
{
- palette_device_iterator pal_iter(machine.root_device());
- state.palette.device = pal_iter.byindex(state.palette.devindex);
+ palette_interface_iterator pal_iter(machine.root_device());
+ state.palette.interface = pal_iter.byindex(state.palette.devindex);
}
@@ -342,7 +342,8 @@ static void palette_set_device(running_machine &machine, ui_gfx_state &state)
static void palette_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state)
{
- palette_device *palette = state.palette.device;
+ device_palette_interface *palette = state.palette.interface;
+ palette_device *paldev = dynamic_cast<palette_device *>(&palette->device());
int total = state.palette.which ? palette->indirect_entries() : palette->entries();
const rgb_t *raw_color = palette->palette()->entry_list_raw();
@@ -381,7 +382,7 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
// figure out the title
std::ostringstream title_buf;
- util::stream_format(title_buf, "'%s'", palette->tag());
+ util::stream_format(title_buf, "'%s'", palette->device().tag());
if (palette->indirect_entries() > 0)
title_buf << (state.palette.which ? _(" COLORS") : _(" PENS"));
@@ -400,8 +401,8 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
util::stream_format(title_buf, " #%X", index);
if (palette->indirect_entries() > 0 && !state.palette.which)
util::stream_format(title_buf, " => %X", palette->pen_indirect(index));
- else if (palette->basemem().base() != nullptr)
- util::stream_format(title_buf, " = %X", palette->read_entry(index));
+ else if (paldev != nullptr && paldev->basemem().base() != nullptr)
+ util::stream_format(title_buf, " = %X", paldev->read_entry(index));
rgb_t col = state.palette.which ? palette->indirect_color(index) : raw_color[index];
util::stream_format(title_buf, " (R:%X G:%X B:%X)", col.r(), col.g(), col.b());
@@ -492,7 +493,7 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
static void palette_handle_keys(running_machine &machine, ui_gfx_state &state)
{
- palette_device *palette = state.palette.device;
+ device_palette_interface *palette = state.palette.interface;
int rowcount, screencount;
int total;
@@ -517,7 +518,7 @@ static void palette_handle_keys(running_machine &machine, ui_gfx_state &state)
{
state.palette.devindex--;
palette_set_device(machine, state);
- palette = state.palette.device;
+ palette = state.palette.interface;
state.palette.which = (palette->indirect_entries() > 0);
}
}
@@ -529,7 +530,7 @@ static void palette_handle_keys(running_machine &machine, ui_gfx_state &state)
{
state.palette.devindex++;
palette_set_device(machine, state);
- palette = state.palette.device;
+ palette = state.palette.interface;
state.palette.which = 0;
}
}
diff --git a/src/mame/drivers/meritm.cpp b/src/mame/drivers/meritm.cpp
index 77937db1ddb..63fbe829be4 100644
--- a/src/mame/drivers/meritm.cpp
+++ b/src/mame/drivers/meritm.cpp
@@ -201,7 +201,6 @@ public:
m_microtouch(*this, "microtouch") ,
m_uart(*this, "ns16550"),
m_maincpu(*this, "maincpu"),
- m_palette(*this, "v9938_0:palette"),
m_bank1(*this, "bank1"),
m_bank2(*this, "bank2"),
m_bank3(*this, "bank3"),
@@ -217,7 +216,6 @@ public:
optional_device<microtouch_device> m_microtouch;
optional_device<ns16550_device> m_uart;
required_device<cpu_device> m_maincpu;
- required_device<palette_device> m_palette;
required_memory_bank m_bank1;
optional_memory_bank m_bank2;
optional_memory_bank m_bank3;
@@ -347,7 +345,7 @@ uint32_t meritm_state::screen_update_meritm(screen_device &screen, bitmap_ind16
popmessage("Layer 1 %sabled",m_layer1_enabled ? "en" : "dis");
}
- bitmap.fill(m_palette->black_pen(), cliprect);
+ bitmap.fill(m_v9938_0->black_pen(), cliprect);
if ( m_layer0_enabled )
{
diff --git a/src/mame/video/atari400.cpp b/src/mame/video/atari400.cpp
index c57ed2d8aaa..33d60408ad1 100644
--- a/src/mame/video/atari400.cpp
+++ b/src/mame/video/atari400.cpp
@@ -24,7 +24,7 @@
void atari_common_state::video_start()
{
- palette_device &palette = machine().first_screen()->palette();
+ device_palette_interface &palette = machine().first_screen()->palette();
for (int i = 0; i < 256; i++)
m_gtia->set_color_lookup(i, (palette.pen(0) << 8) + palette.pen(0));
diff --git a/src/mame/video/bfm_adr2.cpp b/src/mame/video/bfm_adr2.cpp
index bb7b46f2844..ca941ef9781 100644
--- a/src/mame/video/bfm_adr2.cpp
+++ b/src/mame/video/bfm_adr2.cpp
@@ -215,7 +215,7 @@ void bfm_adder2_device::device_reset()
void bfm_adder2_device::device_start()
{
- if (!palette().started())
+ if (!palette().device().started())
throw device_missing_dependencies();
adder2_decode_char_roms();
diff --git a/src/mame/video/k007121.cpp b/src/mame/video/k007121.cpp
index 312c2d0b4b1..c8dcb08cb15 100644
--- a/src/mame/video/k007121.cpp
+++ b/src/mame/video/k007121.cpp
@@ -219,7 +219,7 @@ WRITE8_MEMBER( k007121_device::ctrl_w )
*
*/
-void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, palette_device &palette,
+void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, device_palette_interface &palette,
const uint8_t *source, int base_color, int global_x_offset, int bank_base, bitmap_ind8 &priority_bitmap, uint32_t pri_mask, bool is_flakatck )
{
// gfx_element *gfx = gfxs[chip];
diff --git a/src/mame/video/k007121.h b/src/mame/video/k007121.h
index 22948934bf8..e972362a12d 100644
--- a/src/mame/video/k007121.h
+++ b/src/mame/video/k007121.h
@@ -17,7 +17,7 @@ public:
/* shall we move source in the interface? */
/* also notice that now we directly pass *gfx[chip] instead of **gfx !! */
- void sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, palette_device &palette, const uint8_t *source, int base_color, int global_x_offset, int bank_base, bitmap_ind8 &priority_bitmap, uint32_t pri_mask, bool is_flakatck = false );
+ void sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, device_palette_interface &palette, const uint8_t *source, int base_color, int global_x_offset, int bank_base, bitmap_ind8 &priority_bitmap, uint32_t pri_mask, bool is_flakatck = false );
protected:
// device-level overrides
diff --git a/src/mame/video/konami_helper.cpp b/src/mame/video/konami_helper.cpp
index 2c77d923a97..e2c76140256 100644
--- a/src/mame/video/konami_helper.cpp
+++ b/src/mame/video/konami_helper.cpp
@@ -8,7 +8,7 @@
void konami_decode_gfx(device_gfx_interface &gfxdecode, int gfx_index, uint8_t *data, uint32_t total, const gfx_layout *layout, int bpp)
{
gfx_layout gl;
- palette_device &palette = gfxdecode.palette();
+ device_palette_interface &palette = gfxdecode.palette();
memcpy(&gl, layout, sizeof(gl));
gl.total = total;