Allow specifying PALETTE_INDIRECT_ENTRIES to preallocate indirection tables.

When this is done, the indirection tables are saved in save states and
pre-initialized. At the moment it is not a requirement to do so, but will
provide closer to previous behaviors for games that need it.
This commit is contained in:
Aaron Giles 2014-03-01 22:34:27 +00:00
parent 52b2f2a5bd
commit 0b68bb860d
3 changed files with 53 additions and 24 deletions

View File

@ -22,10 +22,11 @@ const device_type PALETTE = &device_creator<palette_device>;
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, PALETTE, "palette", tag, owner, clock, "palette", __FILE__),
m_entries(0),
m_indirect_entries(0),
m_enable_shadows(0),
m_enable_hilights(0),
m_raw_to_rgb(raw_to_rgb_converter()),
m_endianness_supplied(false),
m_raw_to_rgb(raw_to_rgb_converter()),
m_palette(NULL),
m_pens(NULL),
m_shadow_table(NULL),
@ -66,6 +67,12 @@ void palette_device::static_set_entries(device_t &device, int entries)
}
void palette_device::static_set_indirect_entries(device_t &device, int entries)
{
downcast<palette_device &>(device).m_indirect_entries = entries;
}
void palette_device::static_enable_shadows(device_t &device)
{
downcast<palette_device &>(device).m_enable_shadows = true;
@ -90,7 +97,9 @@ void palette_device::static_enable_hilights(device_t &device)
void palette_device::set_indirect_color(int index, rgb_t rgb)
{
// ensure the array is expanded enough to handle the index, then set it
m_indirect_colors.resize_keep_and_clear_new(((index + 1 + 255) / 256) * 256);
assert(m_indirect_entries == 0 || index < m_indirect_entries);
if (m_indirect_entries == 0)
m_indirect_colors.resize_keep_and_clear_new(((index + 1 + 255) / 256) * 256);
// alpha doesn't matter
rgb.set_a(255);
@ -118,7 +127,6 @@ void palette_device::set_pen_indirect(pen_t pen, UINT16 index)
// allocate the array if needed
m_indirect_entry.resize(m_entries);
m_indirect_entry[pen] = index;
// permit drivers to configure the pens prior to the colors if they desire
@ -374,37 +382,44 @@ void palette_device::device_start()
// make sure we have specified a format
assert(m_raw_to_rgb.bytes_per_entry() > 0);
// determine bytes per entry
// determine bytes per entry and configure
int bytes_per_entry = m_raw_to_rgb.bytes_per_entry();
if (share_ext == NULL)
m_paletteram.set(*share, bytes_per_entry);
else
{
m_paletteram.set(*share, bytes_per_entry / 2);
m_paletteram_ext.set(*share_ext, bytes_per_entry / 2);
}
// override endianness if provided
if (m_endianness_supplied)
{
// forcing endianness only makes sense when the RAM is narrower than the palette format and not split
assert(share_ext == NULL && share->width() < bytes_per_entry);
m_paletteram.set(share->ptr(), share->bytes(), share->width(), m_endianness, bytes_per_entry);
}
else
{
m_endianness = share->endianness();
if (share_ext == NULL)
m_paletteram.set(*share, bytes_per_entry);
else
{
m_paletteram.set(*share, bytes_per_entry / 2);
m_paletteram_ext.set(*share_ext, bytes_per_entry / 2);
}
assert(share_ext == NULL && share->width() / 8 < bytes_per_entry);
m_paletteram.set_endianness(m_endianness);
}
}
// reset all our data
screen_device *device = machine().first_screen();
m_format = (device != NULL) ? 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);
m_indirect_entry.resize(m_entries);
for (int pen = 0; pen < m_entries; pen++)
m_indirect_entry[pen] = pen % m_indirect_entries;
}
}
// call the initialization helper if present (this will expand the indirection tables to full size)
@ -412,11 +427,17 @@ void palette_device::device_start()
m_init(*this);
// set up save/restore of the palette
int numcolors = m_palette->num_colors();
m_save_pen.resize(numcolors);
m_save_contrast.resize(numcolors);
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 explicitly requested
if (m_indirect_entries > 0)
{
save_item(NAME(m_indirect_entries));
save_item(NAME(m_entries));
}
}

View File

@ -205,6 +205,9 @@
#define MCFG_PALETTE_ENTRIES(_entries) \
palette_device::static_set_entries(*device, _entries);
#define MCFG_PALETTE_INDIRECT_ENTRIES(_entries) \
palette_device::static_set_indirect_entries(*device, _entries);
#define MCFG_PALETTE_ENABLE_SHADOWS() \
palette_device::static_enable_shadows(*device);
@ -328,6 +331,7 @@ public:
static void static_set_format(device_t &device, raw_to_rgb_converter raw_to_rgb);
static void static_set_endianness(device_t &device, endianness_t endianness);
static void static_set_entries(device_t &device, int entries);
static void static_set_indirect_entries(device_t &device, int entries);
static void static_enable_shadows(device_t &device);
static void static_enable_hilights(device_t &device);
@ -405,13 +409,14 @@ protected:
private:
// configuration state
int m_entries; // number of entries in the palette
int m_indirect_entries; // number of initial indirect entries in the palette
bool m_enable_shadows; // are shadows enabled?
bool m_enable_hilights; // are hilights enabled?
endianness_t m_endianness; // endianness of palette RAM
bool m_endianness_supplied; // endianness supplied in static config
// palette RAM
raw_to_rgb_converter m_raw_to_rgb; // format of palette RAM
endianness_t m_endianness; // endianness of palette RAM
bool m_endianness_supplied; // endianness supplied in static config
memory_array m_paletteram; // base memory
memory_array m_paletteram_ext; // extended memory

View File

@ -57,6 +57,9 @@ public:
void set(const memory_share &share, int bpe);
void set(const memory_array &array);
// piecewise configuration
void set_endianness(endianness_t endianness) { set(m_base, m_bytes, m_membits, endianness, m_bytes_per_entry); }
// getters
void *base() const { return m_base; }
UINT32 bytes() const { return m_bytes; }