summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2012-01-16 05:08:31 +0000
committer Aaron Giles <aaron@aarongiles.com>2012-01-16 05:08:31 +0000
commit051af55fa90955e11ba7fb08b586ba3227c4f7d1 (patch)
tree07d4184d8879abe773212022d68eabbce28940a2
parent63a471a9a8287906bc71580bbbffbc8829696e4e (diff)
Rewrote tilemap.c as a C++ class. For now kept the global
functions and just inline mapped them to the class. Will do a pass soon to actually update drivers to use the C++ methods directly. Also, the tilemap callbacks are now delegates which should make for cleaner integrating into modern devices and drivers going forward.
-rw-r--r--src/emu/machine.c4
-rw-r--r--src/emu/machine.h5
-rw-r--r--src/emu/tilemap.c2533
-rw-r--r--src/emu/tilemap.h626
-rw-r--r--src/emu/uigfx.c21
-rw-r--r--src/mame/video/jack.c2
-rw-r--r--src/mame/video/m10.c2
-rw-r--r--src/mame/video/m58.c2
-rw-r--r--src/mame/video/videopin.c2
9 files changed, 1424 insertions, 1773 deletions
diff --git a/src/emu/machine.c b/src/emu/machine.c
index 70526399393..172f15e31a5 100644
--- a/src/emu/machine.c
+++ b/src/emu/machine.c
@@ -149,7 +149,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
debug_flags(0),
memory_data(NULL),
palette_data(NULL),
- tilemap_data(NULL),
romload_data(NULL),
input_data(NULL),
input_port_data(NULL),
@@ -170,6 +169,7 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
m_input(NULL),
m_sound(NULL),
m_video(NULL),
+ m_tilemap(NULL),
m_debug_view(NULL),
m_driver_device(NULL),
m_current_phase(MACHINE_PHASE_PREINIT),
@@ -305,7 +305,7 @@ void running_machine::start()
// initialize image devices
image_init(*this);
- tilemap_init(*this);
+ m_tilemap = auto_alloc(*this, tilemap_manager(*this));
crosshair_init(*this);
network_init(*this);
diff --git a/src/emu/machine.h b/src/emu/machine.h
index 3199f78ed6b..f80d60ef84a 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -179,12 +179,12 @@ class cheat_manager;
class render_manager;
class sound_manager;
class video_manager;
+class tilemap_manager;
class debug_view_manager;
class osd_interface;
typedef struct _memory_private memory_private;
typedef struct _palette_private palette_private;
-typedef struct _tilemap_private tilemap_private;
typedef struct _romload_private romload_private;
typedef struct _input_private input_private;
typedef struct _input_port_private input_port_private;
@@ -342,6 +342,7 @@ public:
input_manager &input() const { assert(m_input != NULL); return *m_input; }
sound_manager &sound() const { assert(m_sound != NULL); return *m_sound; }
video_manager &video() const { assert(m_video != NULL); return *m_video; }
+ tilemap_manager &tilemap() const { assert(m_tilemap != NULL); return *m_tilemap; }
debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; }
driver_device *driver_data() const { return m_driver_device; }
template<class _DriverClass> _DriverClass *driver_data() const { return downcast<_DriverClass *>(m_driver_device); }
@@ -429,7 +430,6 @@ public:
// internal core information
memory_private * memory_data; // internal data from memory.c
palette_private * palette_data; // internal data from palette.c
- tilemap_private * tilemap_data; // internal data from tilemap.c
romload_private * romload_data; // internal data from romload.c
input_private * input_data; // internal data from input.c
input_port_private * input_port_data; // internal data from inptport.c
@@ -466,6 +466,7 @@ private:
input_manager * m_input; // internal data from input.c
sound_manager * m_sound; // internal data from sound.c
video_manager * m_video; // internal data from video.c
+ tilemap_manager * m_tilemap; // internal data from tilemap.c
debug_view_manager * m_debug_view; // internal data from debugvw.c
// driver state
diff --git a/src/emu/tilemap.c b/src/emu/tilemap.c
index ae841509e1c..bde68e5373c 100644
--- a/src/emu/tilemap.c
+++ b/src/emu/tilemap.c
@@ -4,8 +4,36 @@
Generic tilemap management system.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -13,1063 +41,513 @@
#include "profiler.h"
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-/* internal usage to mark tiles dirty */
-#define TILE_FLAG_DIRTY 0xff
-
-/* invalid logical index */
-#define INVALID_LOGICAL_INDEX ((tilemap_logical_index)~0)
-
-/* maximum index in each array */
-#define MAX_PEN_TO_FLAGS 256
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* logical index */
-typedef UINT32 tilemap_logical_index;
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
+//-------------------------------------------------
+// effective_rowscroll - return the effective
+// rowscroll value for a given index, taking into
+// account tilemap flip states
+//-------------------------------------------------
-/* internal set of transparency states for rendering */
-typedef enum
+inline INT32 tilemap_t::effective_rowscroll(int index, UINT32 screen_width)
{
- WHOLLY_TRANSPARENT,
- WHOLLY_OPAQUE,
- MASKED
-} trans_t;
+ // if we're flipping vertically, adjust the row number
+ if (m_attributes & TILEMAP_FLIPY)
+ index = m_scrollrows - 1 - index;
-
-/* internal blitting callbacks */
-typedef void (*blitmask_func)(void *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
-typedef void (*blitopaque_func)(void *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
-
-
-/* blitting parameters for rendering */
-typedef struct _blit_parameters blit_parameters;
-struct _blit_parameters
-{
- rectangle cliprect;
- blitmask_func draw_masked;
- blitopaque_func draw_opaque;
- UINT32 tilemap_priority_code;
- UINT8 mask;
- UINT8 value;
- UINT8 alpha;
-};
-
-
-/* core tilemap structure */
-class tilemap_t
-{
-public:
- tilemap_t(running_machine &machine)
- : m_machine(machine) { }
-
- running_machine &machine() const { return m_machine; }
-
- tilemap_t * next; /* pointer to next tilemap */
-
- /* basic tilemap metrics */
- UINT32 rows; /* number of tile rows */
- UINT32 cols; /* number of tile columns */
- UINT32 tilewidth; /* width of a single tile in pixels */
- UINT32 tileheight; /* height of a single tile in pixels */
- UINT32 width; /* width of the full tilemap in pixels */
- UINT32 height; /* height of the full tilemap in pixels */
-
- /* logical <-> memory mappings */
- tilemap_mapper_func mapper; /* callback to map a row/column to a memory index */
- tilemap_logical_index * memory_to_logical; /* map from memory index to logical index */
- tilemap_logical_index max_logical_index; /* maximum valid logical index */
- tilemap_memory_index * logical_to_memory; /* map from logical index to memory index */
- tilemap_memory_index max_memory_index; /* maximum valid memory index */
-
- /* callback to interpret video RAM for the tilemap */
- tile_get_info_func tile_get_info; /* callback to get information about a tile */
- void * tile_get_info_object;/* object passed as the first parameter to the get_info functon */
- tile_data tileinfo; /* structure to hold the data for a tile */
- void * user_data; /* user data value passed to the callback */
-
- /* global tilemap states */
- UINT8 enable; /* true if we are enabled */
- UINT8 attributes; /* global attributes (flipx/y) */
- UINT8 all_tiles_dirty; /* true if all tiles are dirty */
- UINT8 all_tiles_clean; /* true if all tiles are clean */
- UINT32 palette_offset; /* palette offset */
- UINT32 pen_data_offset; /* pen data offset */
- UINT32 gfx_used; /* bitmask of gfx items used */
- UINT32 gfx_dirtyseq[MAX_GFX_ELEMENTS]; /* dirtyseq values from last check */
-
- /* scroll information */
- UINT32 scrollrows; /* number of independently scrolled rows */
- UINT32 scrollcols; /* number of independently scrolled colums */
- INT32 * rowscroll; /* array of rowscroll values */
- INT32 * colscroll; /* array of colscroll values */
- INT32 dx; /* global horizontal scroll offset */
- INT32 dx_flipped; /* global horizontal scroll offset when flipped */
- INT32 dy; /* global vertical scroll offset */
- INT32 dy_flipped; /* global vertical scroll offset when flipped */
-
- /* pixel data */
- bitmap_ind16 pixmap; /* cached pixel data */
-
- /* transparency mapping */
- bitmap_ind8 flagsmap; /* per-pixel flags */
- UINT8 * tileflags; /* per-tile flags */
- UINT8 * pen_to_flags; /* mapping of pens to flags */
-
-private:
- running_machine & m_machine; /* pointer back to the owning machine */
-};
-
-
-struct _tilemap_private
-{
- tilemap_t * list;
- tilemap_t ** tailptr;
- int instance;
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* system management helpers */
-static tilemap_t *tilemap_create_common(running_machine &machine, void *get_info_object, tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows);
-static void tilemap_exit(running_machine &machine);
-static void tilemap_postload(tilemap_t *tmap);
-static void tilemap_dispose(tilemap_t *tmap);
-
-/* logical <-> memory index mapping */
-static void mappings_create(tilemap_t *tmap);
-static void mappings_update(tilemap_t *tmap);
-
-/* tile rendering */
-static void pixmap_update(tilemap_t *tmap);
-static void tile_update(tilemap_t *tmap, tilemap_logical_index logindex, UINT32 cached_col, UINT32 cached_row);
-static UINT8 tile_draw(tilemap_t *tmap, const UINT8 *pendata, UINT32 x0, UINT32 y0, UINT32 palette_base, UINT8 category, UINT8 group, UINT8 flags, UINT8 pen_mask);
-static UINT8 tile_apply_bitmask(tilemap_t *tmap, const UINT8 *maskdata, UINT32 x0, UINT32 y0, UINT8 category, UINT8 flags);
-
-/* drawing helpers */
-static void configure_blit_parameters(blit_parameters *blit, tilemap_t *tmap, bitmap_format dest_format, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask);
-template<class _BitmapClass>
-static void tilemap_draw_instance(_BitmapClass &dest, tilemap_t *tmap, const blit_parameters *blit, int xpos, int ypos);
-template<class _BitmapClass>
-static void tilemap_draw_roz_core(_BitmapClass &dest, tilemap_t *tmap, const blit_parameters *blit,
- UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound);
-
-/* scanline rasterizers for drawing to the pixmap */
-inline void scanline_draw_opaque_null(int count, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_masked_null(const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_opaque_ind16(UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_masked_ind16(UINT16 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_opaque_rgb32(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_masked_rgb32(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode);
-inline void scanline_draw_opaque_rgb32_alpha(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
-inline void scanline_draw_masked_rgb32_alpha(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-/*-------------------------------------------------
- effective_rowscroll - return the effective
- rowscroll value for a given index, taking into
- account tilemap flip states
--------------------------------------------------*/
-
-INLINE INT32 effective_rowscroll(tilemap_t *tmap, int index, UINT32 screen_width)
-{
+ // adjust final result based on the horizontal flip and dx values
INT32 value;
-
- /* if we're flipping vertically, adjust the row number */
- if (tmap->attributes & TILEMAP_FLIPY)
- index = tmap->scrollrows - 1 - index;
-
- /* adjust final result based on the horizontal flip and dx values */
- if (!(tmap->attributes & TILEMAP_FLIPX))
- value = tmap->dx - tmap->rowscroll[index];
+ if (!(m_attributes & TILEMAP_FLIPX))
+ value = m_dx - m_rowscroll[index];
else
- value = screen_width - tmap->width - (tmap->dx_flipped - tmap->rowscroll[index]);
+ value = screen_width - m_width - (m_dx_flipped - m_rowscroll[index]);
- /* clamp to 0..width */
+ // clamp to 0..width
if (value < 0)
- value = tmap->width - (-value) % tmap->width;
+ value = m_width - (-value) % m_width;
else
- value %= tmap->width;
+ value %= m_width;
return value;
}
-/*-------------------------------------------------
- effective_colscroll - return the effective
- colscroll value for a given index, taking into
- account tilemap flip states
--------------------------------------------------*/
+//-------------------------------------------------
+// effective_colscroll - return the effective
+// colscroll value for a given index, taking into
+// account tilemap flip states
+//-------------------------------------------------
-INLINE INT32 effective_colscroll(tilemap_t *tmap, int index, UINT32 screen_height)
+inline INT32 tilemap_t::effective_colscroll(int index, UINT32 screen_height)
{
- INT32 value;
+ // if we're flipping horizontally, adjust the column number
+ if (m_attributes & TILEMAP_FLIPX)
+ index = m_scrollcols - 1 - index;
- /* if we're flipping horizontally, adjust the column number */
- if (tmap->attributes & TILEMAP_FLIPX)
- index = tmap->scrollcols - 1 - index;
-
- /* adjust final result based on the vertical flip and dx values */
- if (!(tmap->attributes & TILEMAP_FLIPY))
- value = tmap->dy - tmap->colscroll[index];
+ // adjust final result based on the vertical flip and dx values
+ INT32 value;
+ if (!(m_attributes & TILEMAP_FLIPY))
+ value = m_dy - m_colscroll[index];
else
- value = screen_height - tmap->height - (tmap->dy_flipped - tmap->colscroll[index]);
+ value = screen_height - m_height - (m_dy_flipped - m_colscroll[index]);
- /* clamp to 0..height */
+ // clamp to 0..height
if (value < 0)
- value = tmap->height - (-value) % tmap->height;
+ value = m_height - (-value) % m_height;
else
- value %= tmap->height;
+ value %= m_height;
return value;
}
-/*-------------------------------------------------
- indexed_tilemap - return a tilemap by index
--------------------------------------------------*/
-
-INLINE tilemap_t *indexed_tilemap(running_machine &machine, int index)
-{
- tilemap_t *tmap;
-
- /* find by the tilemap index */
- for (tmap = machine.tilemap_data->list; tmap != NULL; tmap = tmap->next)
- if (index-- == 0)
- return tmap;
-
- return NULL;
-}
-
-
-/*-------------------------------------------------
- gfx_tiles_changed - return TRUE if any
- gfx_elements used by this tilemap have
- changed
--------------------------------------------------*/
+//-------------------------------------------------
+// gfx_tiles_changed - return TRUE if any
+// gfx_elements used by this tilemap have
+// changed
+//-------------------------------------------------
-INLINE int gfx_elements_changed(tilemap_t *tmap)
+inline bool tilemap_t::gfx_elements_changed()
{
- UINT32 usedmask = tmap->gfx_used;
- int isdirty = FALSE;
- int gfxnum;
+ UINT32 usedmask = m_gfx_used;
+ bool isdirty = false;
- /* iterate over all used gfx types and set the dirty flag if any of them have changed */
- for (gfxnum = 0; usedmask != 0; usedmask >>= 1, gfxnum++)
+ // iterate over all used gfx types and set the dirty flag if any of them have changed
+ for (int gfxnum = 0; usedmask != 0; usedmask >>= 1, gfxnum++)
if ((usedmask & 1) != 0)
- if (tmap->gfx_dirtyseq[gfxnum] != tmap->machine().gfx[gfxnum]->dirtyseq)
+ if (m_gfx_dirtyseq[gfxnum] != machine().gfx[gfxnum]->dirtyseq)
{
- tmap->gfx_dirtyseq[gfxnum] = tmap->machine().gfx[gfxnum]->dirtyseq;
- isdirty = TRUE;
+ m_gfx_dirtyseq[gfxnum] = machine().gfx[gfxnum]->dirtyseq;
+ isdirty = true;
}
return isdirty;
}
-/***************************************************************************
- SYSTEM-WIDE MANAGEMENT
-***************************************************************************/
+//**************************************************************************
+// SCANLINE RASTERIZERS
+//**************************************************************************
-/*-------------------------------------------------
- tilemap_init - initialize the tilemap system
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_opaque_null - draw to a NULL
+// bitmap, setting priority only
+//-------------------------------------------------
-void tilemap_init(running_machine &machine)
+inline void tilemap_t::scanline_draw_opaque_null(int count, UINT8 *pri, UINT32 pcode)
{
- if (machine.primary_screen == NULL || machine.primary_screen->width() == 0)
+ // skip entirely if not changing priority
+ if (pcode == 0xff00)
return;
- machine.primary_screen->register_screen_bitmap(machine.priority_bitmap);
- machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(tilemap_exit), &machine));
-}
-
-
-
-/***************************************************************************
- TILEMAP CREATION AND CONFIGURATION
-***************************************************************************/
-
-/*-------------------------------------------------
- tilemap_create - create a new tilemap
--------------------------------------------------*/
-
-tilemap_t *tilemap_create(running_machine &machine, tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
-{
- return tilemap_create_common(machine, (void *)&machine, tile_get_info, mapper, tilewidth, tileheight, cols, rows);
-}
-
-
-/*-------------------------------------------------
- tilemap_create - create a new tilemap that
- is owned by a device
--------------------------------------------------*/
-
-tilemap_t *tilemap_create_device(device_t *device, tile_get_info_device_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
-{
- return tilemap_create_common(device->machine(), (void *)device, (tile_get_info_func)tile_get_info, mapper, tilewidth, tileheight, cols, rows);
-}
-
-
-/*-------------------------------------------------
- tilemap_create_common - shared creation
- function
--------------------------------------------------*/
-
-static tilemap_t *tilemap_create_common(running_machine &machine, void *get_info_object, tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
-{
- tilemap_t *tmap;
- int tilemap_instance;
- int group;
-
- /* if no tilemap private data yet, allocate it */
- if (machine.tilemap_data == NULL)
- {
- machine.tilemap_data = auto_alloc_clear(machine, tilemap_private);
- machine.tilemap_data->tailptr = &machine.tilemap_data->list;
- }
- tilemap_instance = machine.tilemap_data->instance;
-
- /* allocate the tilemap itself */
- tmap = auto_alloc_clear(machine, tilemap_t(machine));
-
- /* fill in the basic metrics */
- tmap->rows = rows;
- tmap->cols = cols;
- tmap->tilewidth = tilewidth;
- tmap->tileheight = tileheight;
- tmap->width = cols * tilewidth;
- tmap->height = rows * tileheight;
-
- /* set up the logical <-> memory mappings */
- tmap->mapper = mapper;
- mappings_create(tmap);
-
- /* set up the tile map callbacks */
- tmap->tile_get_info = tile_get_info;
- tmap->tile_get_info_object = get_info_object;
-
- /* set up the default pen mask */
- tmap->tileinfo.pen_mask = 0xff;
- tmap->tileinfo.gfxnum = 0xff;
-
- /* initialize global states */
- tmap->enable = TRUE;
- tmap->all_tiles_dirty = TRUE;
-
- /* initialize scroll information */
- tmap->scrollrows = 1;
- tmap->scrollcols = 1;
- tmap->rowscroll = auto_alloc_array_clear(machine, INT32, tmap->height);
- tmap->colscroll = auto_alloc_array_clear(machine, INT32, tmap->width);
-
- /* allocate the pixel data cache */
- tmap->pixmap.allocate(tmap->width, tmap->height);
-
- /* allocate transparency mapping data */
- tmap->tileflags = auto_alloc_array(machine, UINT8, tmap->max_logical_index);
- tmap->flagsmap.allocate(tmap->width, tmap->height);
- tmap->pen_to_flags = auto_alloc_array_clear(machine, UINT8, MAX_PEN_TO_FLAGS * TILEMAP_NUM_GROUPS);
- for (group = 0; group < TILEMAP_NUM_GROUPS; group++)
- tilemap_map_pens_to_layer(tmap, group, 0, 0, TILEMAP_PIXEL_LAYER0);
-
- /* add us to the end of the list of tilemaps */
- *machine.tilemap_data->tailptr = tmap;
- machine.tilemap_data->tailptr = &tmap->next;
-
- /* save relevant state */
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->enable));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->attributes));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->palette_offset));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->pen_data_offset));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->scrollrows));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->scrollcols));
- machine.save().save_pointer("tilemap", NULL, tilemap_instance, NAME(tmap->rowscroll), rows * tileheight);
- machine.save().save_pointer("tilemap", NULL, tilemap_instance, NAME(tmap->colscroll), cols * tilewidth);
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->dx));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->dx_flipped));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->dy));
- machine.save().save_item("tilemap", NULL, tilemap_instance, NAME(tmap->dy_flipped));
- machine.tilemap_data->instance++;
-
- /* reset everything after a load */
- machine.save().register_postload(save_prepost_delegate(FUNC(tilemap_postload), tmap));
- return tmap;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_user_data - specify a parameter
- to be passed into the tile_get_info callback
--------------------------------------------------*/
-
-void tilemap_set_user_data(tilemap_t *tmap, void *user_data)
-{
- tmap->user_data = user_data;
+ // update priority across the scanline
+ for (int i = 0; i < count; i++)
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
}
-/*-------------------------------------------------
- tilemap_set_palette_offset - specify an offset
- to be added to each pixel before looking up
- the palette
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_masked_null - draw to a NULL
+// bitmap using a mask, setting priority only
+//-------------------------------------------------
-void tilemap_set_palette_offset(tilemap_t *tmap, UINT32 offset)
+inline void tilemap_t::scanline_draw_masked_null(const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode)
{
- tmap->palette_offset = offset;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_enable - set an enable flag for
- the tilemap; if 0, requests to draw the
- tilemap are ignored
--------------------------------------------------*/
+ // skip entirely if not changing priority
+ if (pcode == 0xff00)
+ return;
-void tilemap_set_enable(tilemap_t *tmap, int enable)
-{
- tmap->enable = (enable != 0);
+ // update priority across the scanline, checking the mask
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
}
-/*-------------------------------------------------
- tilemap_get_scrolldx - return the enable flag
- for the tilemap
--------------------------------------------------*/
-
-int tilemap_get_enable(tilemap_t *tmap)
-{
- return tmap->enable;
-}
-/*-------------------------------------------------
- tilemap_set_flip - set a global flip for the
- tilemap
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_opaque_ind16 - draw to a 16bpp
+// indexed bitmap
+//-------------------------------------------------
-void tilemap_set_flip(tilemap_t *tmap, UINT32 attributes)
+inline void tilemap_t::scanline_draw_opaque_ind16(UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode)
{
- /* if we're changing things, force a refresh of the mappings and mark it all dirty */
- if (tmap->attributes != attributes)
+ // special case for no palette offset
+ int pal = pcode >> 16;
+ if (pal == 0)
{
- tmap->attributes = attributes;
- mappings_update(tmap);
- }
-}
-
-
-/*-------------------------------------------------
- tilemap_set_flip_all - set a global flip for all
- the tilemaps
--------------------------------------------------*/
-
-void tilemap_set_flip_all(running_machine &machine, UINT32 attributes)
-{
- tilemap_t *tmap;
-
- if (machine.tilemap_data == NULL)
- return;
-
- for (tmap = machine.tilemap_data->list; tmap != NULL; tmap = tmap->next)
- tilemap_set_flip(tmap, attributes);
-}
-
-
+ // use memcpy which should be well-optimized for the platform
+ memcpy(dest, source, count * 2);
-/***************************************************************************
- DIRTY TILE MARKING
-***************************************************************************/
+ // skip the rest if not changing priority
+ if (pcode == 0xff00)
+ return;
-/*-------------------------------------------------
- tilemap_mark_tile_dirty - mark a single tile
- dirty based on its memory index
--------------------------------------------------*/
+ // update priority across the scanline
+ for (int i = 0; i < count; i++)
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
+ }
-void tilemap_mark_tile_dirty(tilemap_t *tmap, tilemap_memory_index memindex)
-{
- /* only mark if within range */
- if (memindex < tmap->max_memory_index)
+ // priority case
+ else if ((pcode & 0xffff) != 0xff00)
{
- tilemap_logical_index logindex = tmap->memory_to_logical[memindex];
-
- /* there may be no logical index for a given memory index */
- if (logindex != INVALID_LOGICAL_INDEX)
+ for (int i = 0; i < count; i++)
{
- tmap->tileflags[logindex] = TILE_FLAG_DIRTY;
- tmap->all_tiles_clean = FALSE;
+ dest[i] = source[i] + pal;
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
}
}
+
+ // no priority case
+ else
+ {
+ for (int i = 0; i < count; i++)
+ dest[i] = source[i] + pal;
+ }
}
-/*-------------------------------------------------
- tilemap_mark_all_tiles_dirty - mark all the
- tiles in a tilemap dirty
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_masked_ind16 - draw to a 16bpp
+// indexed bitmap using a mask
+//-------------------------------------------------
-void tilemap_mark_all_tiles_dirty(tilemap_t *tmap)
+inline void tilemap_t::scanline_draw_masked_ind16(UINT16 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode)
{
- /* mark all tiles dirty and clear the clean flag */
- tmap->all_tiles_dirty = TRUE;
- tmap->all_tiles_clean = FALSE;
-}
-
+ int pal = pcode >> 16;
-/*-------------------------------------------------
- tilemap_mark_all_tiles_dirty_all - mark all the
- tiles in all the tilemaps dirty
--------------------------------------------------*/
+ // priority case
+ if ((pcode & 0xffff) != 0xff00)
+ {
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ {
+ dest[i] = source[i] + pal;
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
+ }
+ }
-void tilemap_mark_all_tiles_dirty_all(running_machine &machine)
-{
- tilemap_t *tmap;
- for (tmap = machine.tilemap_data->list; tmap != NULL; tmap = tmap->next)
- tilemap_mark_all_tiles_dirty(tmap);
+ // no priority case
+ else
+ {
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ dest[i] = source[i] + pal;
+ }
}
-/***************************************************************************
- PEN-TO-LAYER MAPPING
-***************************************************************************/
-/*-------------------------------------------------
- tilemap_map_pens_to_layer - specify the
- mapping of one or more pens (where
- (<pen> & mask) == pen) to a layer
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_opaque_rgb32 - draw to a 32bpp
+// RGB bitmap
+//-------------------------------------------------
-void tilemap_map_pens_to_layer(tilemap_t *tmap, int group, pen_t pen, pen_t mask, UINT8 layermask)
+inline void tilemap_t::scanline_draw_opaque_rgb32(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode)
{
- UINT8 *array = tmap->pen_to_flags + group * MAX_PEN_TO_FLAGS;
- pen_t start, stop, cur;
- UINT8 changed = FALSE;
-
- assert(group < TILEMAP_NUM_GROUPS);
- assert((layermask & TILEMAP_PIXEL_CATEGORY_MASK) == 0);
-
- /* we start at the index where (pen & mask) == pen, and all other bits are 0 */
- start = pen & mask;
-
- /* we stop at the index where (pen & mask) == pen, and all other bits are 1 */
- stop = start | ~mask;
-
- /* clamp to the number of entries actually there */
- stop = MIN(stop, MAX_PEN_TO_FLAGS - 1);
+ const pen_t *clut = &pens[pcode >> 16];
- /* iterate and set */
- for (cur = start; cur <= stop; cur++)
- if ((cur & mask) == pen && array[cur] != layermask)
+ // priority case
+ if ((pcode & 0xffff) != 0xff00)
+ {
+ for (int i = 0; i < count; i++)
{
- changed = TRUE;
- array[cur] = layermask;
+ dest[i] = clut[source[i]];
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
}
+ }
- /* everything gets dirty if anything changed */
- if (changed)
- tilemap_mark_all_tiles_dirty(tmap);
-}
-
-
-/*-------------------------------------------------
- tilemap_set_transparent_pen - set a single
- transparent pen into the tilemap, mapping
- all other pens to layer 0
--------------------------------------------------*/
-
-void tilemap_set_transparent_pen(tilemap_t *tmap, pen_t pen)
-{
- /* reset the whole pen map to opaque */
- tilemap_map_pens_to_layer(tmap, 0, 0, 0, TILEMAP_PIXEL_LAYER0);
-
- /* set the single pen to transparent */
- tilemap_map_pen_to_layer(tmap, 0, pen, TILEMAP_PIXEL_TRANSPARENT);
-}
-
-
-/*-------------------------------------------------
- tilemap_set_transmask - set up the first 32
- pens using a foreground mask (mapping to
- layer 0) and a background mask (mapping to
- layer 1)
--------------------------------------------------*/
-
-void tilemap_set_transmask(tilemap_t *tmap, int group, UINT32 fgmask, UINT32 bgmask)
-{
- pen_t pen;
-
- /* iterate over all 32 pens specified */
- for (pen = 0; pen < 32; pen++)
+ // no priority case
+ else
{
- UINT8 fgbits = ((fgmask >> pen) & 1) ? TILEMAP_PIXEL_TRANSPARENT : TILEMAP_PIXEL_LAYER0;
- UINT8 bgbits = ((bgmask >> pen) & 1) ? TILEMAP_PIXEL_TRANSPARENT : TILEMAP_PIXEL_LAYER1;
- tilemap_map_pen_to_layer(tmap, group, pen, fgbits | bgbits);
+ for (int i = 0; i < count; i++)
+ dest[i] = clut[source[i]];
}
}
+//-------------------------------------------------
+// scanline_draw_masked_rgb32 - draw to a 32bpp
+// RGB bitmap using a mask
+//-------------------------------------------------
-/***************************************************************************
- TILEMAP SCROLLING
-***************************************************************************/
-
-/*-------------------------------------------------
- tilemap_set_scroll_rows - specify the number of
- independently scrollable row units; each unit
- covers height/scroll_rows pixels
--------------------------------------------------*/
-
-void tilemap_set_scroll_rows(tilemap_t *tmap, UINT32 scroll_rows)
-{
- assert(scroll_rows <= tmap->height);
- tmap->scrollrows = scroll_rows;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_scroll_cols - specify the number of
- independently scrollable column units; each
- unit covers width/scroll_cols pixels
--------------------------------------------------*/
-
-void tilemap_set_scroll_cols(tilemap_t *tmap, UINT32 scroll_cols)
-{
- assert(scroll_cols <= tmap->width);
- tmap->scrollcols = scroll_cols;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_scrolldx - specify global
- horizontal scroll offset, for non-flipped and
- flipped cases
--------------------------------------------------*/
-
-void tilemap_set_scrolldx(tilemap_t *tmap, int dx, int dx_flipped)
-{
- tmap->dx = dx;
- tmap->dx_flipped = dx_flipped;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_scrolldy - specify global
- vertical scroll offset, for non-flipped and
- flipped cases
--------------------------------------------------*/
-
-void tilemap_set_scrolldy(tilemap_t *tmap, int dy, int dy_flipped)
-{
- tmap->dy = dy;
- tmap->dy_flipped = dy_flipped;
-}
-
-
-/*-------------------------------------------------
- tilemap_get_scrolldx - return the global
- horizontal scroll offset, based on current
- flip state
--------------------------------------------------*/
-
-int tilemap_get_scrolldx(tilemap_t *tmap)
-{
- return (tmap->attributes & TILEMAP_FLIPX) ? tmap->dx_flipped : tmap->dx;
-}
-
-
-/*-------------------------------------------------
- tilemap_get_scrolldy - return the global
- vertical scroll offset, based on current
- flip state
--------------------------------------------------*/
-
-int tilemap_get_scrolldy(tilemap_t *tmap)
-{
- return (tmap->attributes & TILEMAP_FLIPY) ? tmap->dy_flipped : tmap->dy;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_scrollx - specify the scroll value
- for a row unit
--------------------------------------------------*/
-
-void tilemap_set_scrollx(tilemap_t *tmap, int which, int value)
-{
- if (which < tmap->scrollrows)
- tmap->rowscroll[which] = value;
-}
-
-
-/*-------------------------------------------------
- tilemap_set_scrolly - specify the scroll value
- for a column unit
--------------------------------------------------*/
-
-void tilemap_set_scrolly(tilemap_t *tmap, int which, int value)
-{
- if (which < tmap->scrollcols)
- tmap->colscroll[which] = value;
-}
-
-
-/*-------------------------------------------------
- tilemap_get_scrollx - return the scroll value
- for a row unit
--------------------------------------------------*/
-
-int tilemap_get_scrollx(tilemap_t *tmap, int which)
+inline void tilemap_t::scanline_draw_masked_rgb32(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode)
{
- if (which < tmap->scrollrows)
- return tmap->rowscroll[which];
- else
- return 0;
-}
-
+ const pen_t *clut = &pens[pcode >> 16];
-/*-------------------------------------------------
- tilemap_get_scrolly - return the scroll value
- for a column unit
--------------------------------------------------*/
+ // priority case
+ if ((pcode & 0xffff) != 0xff00)
+ {
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ {
+ dest[i] = clut[source[i]];
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
+ }
+ }
-int tilemap_get_scrolly(tilemap_t *tmap, int which)
-{
- if (which < tmap->scrollcols)
- return tmap->colscroll[which];
+ // no priority case
else
- return 0;
-}
-
-
-
-/***************************************************************************
- INTERNAL MAP ACCESS
-***************************************************************************/
-
-/*-------------------------------------------------
- tilemap_get_pixmap - return a pointer to the
- (updated) internal pixmap for a tilemap
--------------------------------------------------*/
-
-bitmap_ind16 &tilemap_get_pixmap(tilemap_t *tmap)
-{
- /* ensure all the tiles are up-to-date and then return the pixmap */
- pixmap_update(tmap);
- return tmap->pixmap;
+ {
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ dest[i] = clut[source[i]];
+ }
}
-/*-------------------------------------------------
- tilemap_get_flagsmap - return a pointer to the
- (updated) internal flagsmap for a tilemap
--------------------------------------------------*/
+//-------------------------------------------------
+// scanline_draw_opaque_rgb32_alpha - draw to a
+// 32bpp RGB bitmap with alpha blending
+//-------------------------------------------------
-bitmap_ind8 &tilemap_get_flagsmap(tilemap_t *tmap)
+inline void tilemap_t::scanline_draw_opaque_rgb32_alpha(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha)
{
- /* ensure all the tiles are up-to-date and then return the flagsmap */
- pixmap_update(tmap);
- return tmap->flagsmap;
-}
-
+ const pen_t *clut = &pens[pcode >> 16];
-/*-------------------------------------------------
- tilemap_get_pixmap - return a pointer to the
- (updated) internal per-tile flags for a tilemap
--------------------------------------------------*/
+ // priority case
+ if ((pcode & 0xffff) != 0xff00)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
+ }
+ }
-UINT8 *tilemap_get_tile_flags(tilemap_t *tmap)
-{
- /* ensure all the tiles are up-to-date and then return the per-tile flags */
- pixmap_update(tmap);
- return tmap->tileflags;
+ // no priority case
+ else
+ {
+ for (int i = 0; i < count; i++)
+ dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
+ }
}
+//-------------------------------------------------
+// scanline_draw_masked_rgb32_alpha - draw to a
+// 32bpp RGB bitmap using a mask and alpha
+// blending
+//-------------------------------------------------
-/***************************************************************************
- TILEMAP RENDERING
-***************************************************************************/
-
-/*-------------------------------------------------
- tilemap_draw_primask - draw a tilemap to the
- destination with clipping; pixels apply
- priority/priority_mask to the priority bitmap
--------------------------------------------------*/
-
-template<class _BitmapClass>
-void tilemap_draw_primask_common(_BitmapClass &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+inline void tilemap_t::scanline_draw_masked_rgb32_alpha(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha)
{
- UINT32 width, height;
- blit_parameters blit;
- int xpos, ypos;
-
- /* skip if disabled */
- if (!tmap->enable)
- return;
-
-g_profiler.start(PROFILER_TILEMAP_DRAW);
- /* configure the blit parameters based on the input parameters */
- configure_blit_parameters(&blit, tmap, dest.format(), cliprect, flags, priority, priority_mask);
+ const pen_t *clut = &pens[pcode >> 16];
- /* if the whole map is dirty, mark it as such */
- if (tmap->all_tiles_dirty || gfx_elements_changed(tmap))
+ // priority case
+ if ((pcode & 0xffff) != 0xff00)
{
- memset(tmap->tileflags, TILE_FLAG_DIRTY, tmap->max_logical_index);
- tmap->all_tiles_dirty = FALSE;
- tmap->gfx_used = 0;
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ {
+ dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
+ pri[i] = (pri[i] & (pcode >> 8)) | pcode;
+ }
}
- width = tmap->machine().primary_screen->width();
- height = tmap->machine().primary_screen->height();
-
- /* XY scrolling playfield */
- if (tmap->scrollrows == 1 && tmap->scrollcols == 1)
+ // no priority case
+ else
{
- int scrollx = effective_rowscroll(tmap, 0, width);
- int scrolly = effective_colscroll(tmap, 0, height);
-
- /* iterate to handle wraparound */
- for (ypos = scrolly - tmap->height; ypos <= blit.cliprect.max_y; ypos += tmap->height)
- for (xpos = scrollx - tmap->width; xpos <= blit.cliprect.max_x; xpos += tmap->width)
- tilemap_draw_instance(dest, tmap, &blit, xpos, ypos);
+ for (int i = 0; i < count; i++)
+ if ((maskptr[i] & mask) == value)
+ dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
}
+}
- /* scrolling rows + vertical scroll */
- else if (tmap->scrollcols == 1)
- {
- const rectangle original_cliprect = blit.cliprect;
- int rowheight = tmap->height / tmap->scrollrows;
- int scrolly = effective_colscroll(tmap, 0, height);
- int currow, nextrow;
-
- /* iterate over Y to handle wraparound */
- for (ypos = scrolly - tmap->height; ypos <= original_cliprect.max_y; ypos += tmap->height)
- {
- int const firstrow = MAX((original_cliprect.min_y - ypos) / rowheight, 0);
- int const lastrow = MIN((original_cliprect.max_y - ypos) / rowheight, tmap->scrollrows - 1);
-
- /* iterate over rows in the tilemap */
- for (currow = firstrow; currow <= lastrow; currow = nextrow)
- {
- int scrollx = effective_rowscroll(tmap, currow, width);
-
- /* scan forward until we find a non-matching row */
- for (nextrow = currow + 1; nextrow <= lastrow; nextrow++)
- if (effective_rowscroll(tmap, nextrow, width) != scrollx)
- break;
-
- /* skip if disabled */
- if (scrollx == TILE_LINE_DISABLED)
- continue;
-
- /* update the cliprect just for this set of rows */
- blit.cliprect.min_y = currow * rowheight + ypos;
- blit.cliprect.max_y = nextrow * rowheight - 1 + ypos;
- blit.cliprect &= original_cliprect;
-
- /* iterate over X to handle wraparound */
- for (xpos = scrollx - tmap->width; xpos <= original_cliprect.max_x; xpos += tmap->width)
- tilemap_draw_instance(dest, tmap, &blit, xpos, ypos);
- }
- }
- }
- /* scrolling columns + horizontal scroll */
- else if (tmap->scrollrows == 1)
+//**************************************************************************
+// TILEMAP CREATION AND CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// tilemap_create_common - shared creation
+// function
+//-------------------------------------------------
+
+tilemap_t::tilemap_t(tilemap_manager &manager, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, int tilewidth, int tileheight, int cols, int rows)
+ : m_next(NULL),
+ m_rows(rows),
+ m_cols(cols),
+ m_tilewidth(tilewidth),
+ m_tileheight(tileheight),
+ m_width(cols * tilewidth),
+ m_height(rows * tileheight),
+ m_mapper(mapper),
+ m_memory_to_logical(NULL),
+ m_max_logical_index(0),
+ m_logical_to_memory(NULL),
+ m_max_memory_index(0),
+ m_tile_get_info(tile_get_info),
+ m_user_data(NULL),
+ m_enable(true),
+ m_attributes(0),
+ m_all_tiles_dirty(true),
+ m_all_tiles_clean(false),
+ m_palette_offset(0),
+ m_pen_data_offset(0),
+ m_gfx_used(0),
+ m_scrollrows(1),
+ m_scrollcols(1),
+ m_rowscroll(auto_alloc_array_clear(manager.machine(), INT32, m_height)),
+ m_colscroll(auto_alloc_array_clear(manager.machine(), INT32, m_width)),
+ m_dx(0),
+ m_dx_flipped(0),
+ m_dy(0),
+ m_dy_flipped(0),
+ m_pixmap(m_width, m_height),
+ m_flagsmap(m_width, m_height),
+ m_tileflags(NULL),
+ m_manager(manager)
+{
+ // reset internal arrays
+ memset(m_gfx_dirtyseq, 0, sizeof(m_gfx_dirtyseq));
+ memset(m_pen_to_flags, 0, sizeof(m_pen_to_flags));
+
+ // create the initial mappings
+ mappings_create();
+
+ // set up the default pen mask
+ memset(&m_tileinfo, 0, sizeof(m_tileinfo));
+ m_tileinfo.pen_mask = 0xff;
+ m_tileinfo.gfxnum = 0xff;
+
+ // allocate transparency mapping data
+ m_tileflags = auto_alloc_array(machine(), UINT8, m_max_logical_index);
+ for (int group = 0; group < TILEMAP_NUM_GROUPS; group++)
+ map_pens_to_layer(group, 0, 0, TILEMAP_PIXEL_LAYER0);
+
+ // save relevant state
+ int instance = manager.alloc_instance();
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_enable));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_attributes));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_palette_offset));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_pen_data_offset));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_scrollrows));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_scrollcols));
+ machine().save().save_pointer("tilemap", NULL, instance, NAME(m_rowscroll), rows * tileheight);
+ machine().save().save_pointer("tilemap", NULL, instance, NAME(m_colscroll), cols * tilewidth);
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_dx));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_dx_flipped));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_dy));
+ machine().save().save_item("tilemap", NULL, instance, NAME(m_dy_flipped));
+
+ // reset everything after a load
+ machine().save().register_postload(save_prepost_delegate(FUNC(tilemap_t::postload), this));
+}
+
+
+//-------------------------------------------------
+// ~tilemap_t - destructor
+//-------------------------------------------------
+
+tilemap_t::~tilemap_t()
+{
+}
+
+
+//-------------------------------------------------
+// mark_tile_dirty - mark a single tile dirty
+// based on its memory index
+//-------------------------------------------------
+
+void tilemap_t::mark_tile_dirty(tilemap_memory_index memindex)
+{
+ // only mark if within range
+ if (memindex < m_max_memory_index)
{
- const rectangle original_cliprect = blit.cliprect;
- int colwidth = tmap->width / tmap->scrollcols;
- int scrollx = effective_rowscroll(tmap, 0, width);
- int curcol, nextcol;
-
- /* iterate over columns in the tilemap */
- for (curcol = 0; curcol < tmap->scrollcols; curcol = nextcol)
+ // there may be no logical index for a given memory index
+ logical_index logindex = m_memory_to_logical[memindex];
+ if (logindex != INVALID_LOGICAL_INDEX)
{
- int scrolly = effective_colscroll(tmap, curcol, height);
-
- /* scan forward until we find a non-matching column */
- for (nextcol = curcol + 1; nextcol < tmap->scrollcols; nextcol++)
- if (effective_colscroll(tmap, nextcol, height) != scrolly)
- break;
-
- /* skip if disabled */
- if (scrolly == TILE_LINE_DISABLED)
- continue;
-
- /* iterate over X to handle wraparound */
- for (xpos = scrollx - tmap->width; xpos <= original_cliprect.max_x; xpos += tmap->width)
- {
- /* update the cliprect just for this set of columns */
- blit.cliprect.min_x = curcol * colwidth + xpos;
- blit.cliprect.max_x = nextcol * colwidth - 1 + xpos;
- blit.cliprect &= original_cliprect;
-
- /* iterate over Y to handle wraparound */
- for (ypos = scrolly - tmap->height; ypos <= original_cliprect.max_y; ypos += tmap->height)
- tilemap_draw_instance(dest, tmap, &blit, xpos, ypos);
- }
+ m_tileflags[logindex] = TILE_FLAG_DIRTY;
+ m_all_tiles_clean = false;
}
}
-g_profiler.stop();
}
-void tilemap_draw_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask)
-{ tilemap_draw_primask_common(dest, cliprect, tmap, flags, priority, priority_mask); }
-void tilemap_draw_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask)
-{ tilemap_draw_primask_common(dest, cliprect, tmap, flags, priority, priority_mask); }
+//-------------------------------------------------
+// map_pens_to_layer - specify the mapping of one
+// or more pens (where (<pen> & mask) == pen) to
+// a layer
+//-------------------------------------------------
-/*-------------------------------------------------
- tilemap_draw_primask - draw a tilemap to the
- destination with clipping and arbitrary
- rotate/zoom; pixels apply priority/
- priority_mask to the priority bitmap
--------------------------------------------------*/
-
-template<class _BitmapClass>
-void tilemap_draw_roz_common(_BitmapClass &dest, const rectangle &cliprect, tilemap_t *tmap,
- UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
- int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+void tilemap_t::map_pens_to_layer(int group, pen_t pen, pen_t mask, UINT8 layermask)
{
- blit_parameters blit;
-
-/* notes:
- - startx and starty MUST be UINT32 for calculations to work correctly
- - srcbitmap->width and height are assumed to be a power of 2 to speed up wraparound
- */
+ assert(group < TILEMAP_NUM_GROUPS);
+ assert((layermask & TILEMAP_PIXEL_CATEGORY_MASK) == 0);
- /* skip if disabled */
- if (!tmap->enable)
- return;
+ // we start at the index where (pen & mask) == pen, and all other bits are 0
+ pen_t start = pen & mask;
- /* see if this is just a regular render and if so, do a regular render */
- if (incxx == (1 << 16) && incxy == 0 && incyx == 0 && incyy == (1 << 16) && wraparound)
- {
- tilemap_set_scrollx(tmap, 0, startx >> 16);
- tilemap_set_scrolly(tmap, 0, starty >> 16);
- tilemap_draw(dest, cliprect, tmap, flags, priority);
- return;
- }
+ // we stop at the index where (pen & mask) == pen, and all other bits are 1
+ pen_t stop = start | ~mask;
-g_profiler.start(PROFILER_TILEMAP_DRAW_ROZ);
- /* configure the blit parameters */
- configure_blit_parameters(&blit, tmap, dest.format(), cliprect, flags, priority, priority_mask);
+ // clamp to the number of entries actually there
+ stop = MIN(stop, MAX_PEN_TO_FLAGS - 1);
- /* get the full pixmap for the tilemap */
- tilemap_get_pixmap(tmap);
+ // iterate and set
+ UINT8 *array = m_pen_to_flags + group * MAX_PEN_TO_FLAGS;
+ bool changed = false;
+ for (pen_t cur = start; cur <= stop; cur++)
+ if ((cur & mask) == pen && array[cur] != layermask)
+ {
+ changed = true;
+ array[cur] = layermask;
+ }
- /* then do the roz copy */
- tilemap_draw_roz_core(dest, tmap, &blit, startx, starty, incxx, incxy, incyx, incyy, wraparound);
-g_profiler.stop();
+ // everything gets dirty if anything changed
+ if (changed)
+ mark_all_dirty();
}
-void tilemap_draw_roz_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap,
- UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
- int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
-{ tilemap_draw_roz_common(dest, cliprect, tmap, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
-
-void tilemap_draw_roz_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap,
- UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
- int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
-{ tilemap_draw_roz_common(dest, cliprect, tmap, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
-
-
-/***************************************************************************
- INDEXED TILEMAP HANDLING
-***************************************************************************/
-/*-------------------------------------------------
- tilemap_count - return the number of tilemaps
--------------------------------------------------*/
+//-------------------------------------------------
+// set_transparent_pen - set a single transparent
+// pen into the tilemap, mapping all other pens
+// to layer 0
+//-------------------------------------------------
-int tilemap_count(running_machine &machine)
+void tilemap_t::set_transparent_pen(pen_t pen)
{
- tilemap_t *tmap;
- int count = 0;
+ // reset the whole pen map to opaque
+ map_pens_to_layer(0, 0, 0, TILEMAP_PIXEL_LAYER0);
- if (machine.tilemap_data == NULL)
- return 0;
-
- /* find by the tilemap index */
- for (tmap = machine.tilemap_data->list; tmap != NULL; tmap = tmap->next)
- count++;
- return count;
+ // set the single pen to transparent
+ map_pen_to_layer(0, pen, TILEMAP_PIXEL_TRANSPARENT);
}
-/*-------------------------------------------------
- tilemap_size_by_index - return the size of an
- indexed tilemap
--------------------------------------------------*/
+//-------------------------------------------------
+// set_transmask - set up the first 32 pens using
+// a foreground mask (mapping to layer 0) and a
+// background mask (mapping to layer 1)
+//-------------------------------------------------
-void tilemap_size_by_index(running_machine &machine, int number, UINT32 *width, UINT32 *height)
+void tilemap_t::set_transmask(int group, UINT32 fgmask, UINT32 bgmask)
{
- tilemap_t *tmap = indexed_tilemap(machine, number);
- *width = tmap->width;
- *height = tmap->height;
-}
-
-
-/*-------------------------------------------------
- tilemap_draw_by_index - render an indexed
- tilemap with fixed characteristics (no
- priority)
--------------------------------------------------*/
-
-void tilemap_draw_by_index(running_machine &machine, bitmap_rgb32 &dest, int number, UINT32 scrollx, UINT32 scrolly)
-{
- tilemap_t *tmap = indexed_tilemap(machine, number);
- blit_parameters blit;
- int xpos,ypos;
-
- /* set up for the blit, using hard-coded parameters (no priority, etc) */
- configure_blit_parameters(&blit, tmap, dest.format(), dest.cliprect(), TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0, 0xff);
-
- /* compute the effective scroll positions */
- scrollx = tmap->width - scrollx % tmap->width;
- scrolly = tmap->height - scrolly % tmap->height;
-
- /* if the whole map is dirty, mark it as such */
- if (tmap->all_tiles_dirty || gfx_elements_changed(tmap))
+ // iterate over all 32 pens specified
+ for (pen_t pen = 0; pen < 32; pen++)
{
- memset(tmap->tileflags, TILE_FLAG_DIRTY, tmap->max_logical_index);
- tmap->all_tiles_dirty = FALSE;
- tmap->gfx_used = 0;
+ UINT8 fgbits = ((fgmask >> pen) & 1) ? TILEMAP_PIXEL_TRANSPARENT : TILEMAP_PIXEL_LAYER0;
+ UINT8 bgbits = ((bgmask >> pen) & 1) ? TILEMAP_PIXEL_TRANSPARENT : TILEMAP_PIXEL_LAYER1;
+ map_pen_to_layer(group, pen, fgbits | bgbits);
}
-
- /* iterate to handle wraparound */
- for (ypos = scrolly - tmap->height; ypos <= blit.cliprect.max_y; ypos += tmap->height)
- for (xpos = scrollx - tmap->width; xpos <= blit.cliprect.max_x; xpos += tmap->width)
- tilemap_draw_instance(dest, tmap, &blit, xpos, ypos);
}
-/***************************************************************************
- COMMON LOGICAL-TO-MEMORY MAPPERS
-***************************************************************************/
+//**************************************************************************
+// COMMON LOGICAL-TO-MEMORY MAPPERS
+//**************************************************************************
-/*-------------------------------------------------
- tilemap_scan_rows
- tilemap_scan_rows_flip_x
- tilemap_scan_rows_flip_y
- tilemap_scan_rows_flip_xy - scan in row-major
- order with optional flipping
--------------------------------------------------*/
+//-------------------------------------------------
+// tilemap_scan_rows
+// tilemap_scan_rows_flip_x
+// tilemap_scan_rows_flip_y
+// tilemap_scan_rows_flip_xy - scan in row-major
+// order with optional flipping
+//-------------------------------------------------
TILEMAP_MAPPER( tilemap_scan_rows )
{
@@ -1092,13 +570,13 @@ TILEMAP_MAPPER( tilemap_scan_rows_flip_xy )
}
-/*-------------------------------------------------
- tilemap_scan_cols
- tilemap_scan_cols_flip_x
- tilemap_scan_cols_flip_y
- tilemap_scan_cols_flip_xy - scan in column-
- major order with optional flipping
--------------------------------------------------*/
+//-------------------------------------------------
+// tilemap_scan_cols
+// tilemap_scan_cols_flip_x
+// tilemap_scan_cols_flip_y
+// tilemap_scan_cols_flip_xy - scan in column-
+// major order with optional flipping
+//-------------------------------------------------
TILEMAP_MAPPER( tilemap_scan_cols )
{
@@ -1122,294 +600,222 @@ TILEMAP_MAPPER( tilemap_scan_cols_flip_xy )
-/***************************************************************************
- SYSTEM MANAGEMENT HELPERS
-***************************************************************************/
+//-------------------------------------------------
+// postload - after loading a save state
+// invalidate everything
+//-------------------------------------------------
-/*-------------------------------------------------
- tilemap_exit - free memory allocated by the
- tilemap system
--------------------------------------------------*/
-
-static void tilemap_exit(running_machine &machine)
+void tilemap_t::postload()
{
- tilemap_private *tilemap_data = machine.tilemap_data;
-
- /* free all the tilemaps in the list */
- if (tilemap_data != NULL)
- while (tilemap_data->list != NULL)
- {
- tilemap_t *next = tilemap_data->list->next;
- tilemap_dispose(tilemap_data->list);
- tilemap_data->list = next;
- }
+ mappings_update();
}
-/*-------------------------------------------------
- tilemap_postload - after loading a save state
- invalidate everything
--------------------------------------------------*/
-
-static void tilemap_postload(tilemap_t *tmap)
-{
- mappings_update(tmap);
-}
+//**************************************************************************
+// LOGICAL <-> MEMORY INDEX MAPPING
+//**************************************************************************
-/*-------------------------------------------------
- tilemap_dispose - dispose of a tilemap
--------------------------------------------------*/
+//-------------------------------------------------
+// mappings_create - allocate memory for the
+// mapping tables and compute their extents
+//-------------------------------------------------
-static void tilemap_dispose(tilemap_t *tmap)
+void tilemap_t::mappings_create()
{
- tilemap_t **tmapptr;
+ // compute the maximum logical index
+ m_max_logical_index = m_rows * m_cols;
- /* walk the list of tilemaps; when we find ourself, remove it */
- for (tmapptr = &tmap->machine().tilemap_data->list; *tmapptr != NULL; tmapptr = &(*tmapptr)->next)
- if (*tmapptr == tmap)
+ // compute the maximum memory index
+ m_max_memory_index = 0;
+ for (UINT32 row = 0; row < m_rows; row++)
+ for (UINT32 col = 0; col < m_cols; col++)
{
- *tmapptr = tmap->next;
- break;
+ tilemap_memory_index memindex = memory_index(col, row);
+ m_max_memory_index = MAX(m_max_memory_index, memindex);
}
+ m_max_memory_index++;
- /* free allocated memory */
- auto_free(tmap->machine(), tmap->pen_to_flags);
- auto_free(tmap->machine(), tmap->tileflags);
- auto_free(tmap->machine(), tmap->colscroll);
- auto_free(tmap->machine(), tmap->rowscroll);
- auto_free(tmap->machine(), tmap->logical_to_memory);
- auto_free(tmap->machine(), tmap->memory_to_logical);
- auto_free(tmap->machine(), tmap);
-}
+ // allocate the necessary mappings
+ m_memory_to_logical = auto_alloc_array(machine(), logical_index, m_max_memory_index);
+ m_logical_to_memory = auto_alloc_array(machine(), tilemap_memory_index, m_max_logical_index);
+ // update the mappings
+ mappings_update();
+}
-/***************************************************************************
- LOGICAL <-> MEMORY INDEX MAPPING
-***************************************************************************/
+//-------------------------------------------------
+// mappings_update - update the mappings after
+// a major change (flip x/y changes)
+//-------------------------------------------------
-/*-------------------------------------------------
- mappings_create - allocate memory for the
- mapping tables and compute their extents
--------------------------------------------------*/
-
-static void mappings_create(tilemap_t *tmap)
+void tilemap_t::mappings_update()
{
- UINT32 col, row;
-
- /* compute the maximum logical index */
- tmap->max_logical_index = tmap->rows * tmap->cols;
-
- /* compute the maximum memory index */
- tmap->max_memory_index = 0;
- for (row = 0; row < tmap->rows; row++)
- for (col = 0; col < tmap->cols; col++)
- {
- tilemap_memory_index memindex = (*tmap->mapper)(col, row, tmap->cols, tmap->rows);
- tmap->max_memory_index = MAX(tmap->max_memory_index, memindex);
- }
- tmap->max_memory_index++;
+ // initialize all the mappings to invalid values
+ memset(m_memory_to_logical, 0xff, m_max_memory_index * sizeof(m_memory_to_logical[0]));
- /* allocate the necessary mappings */
- tmap->memory_to_logical = auto_alloc_array(tmap->machine(), tilemap_logical_index, tmap->max_memory_index);
- tmap->logical_to_memory = auto_alloc_array(tmap->machine(), tilemap_memory_index, tmap->max_logical_index);
+ // now iterate over all logical indexes and populate the memory index
+ for (logical_index logindex = 0; logindex < m_max_logical_index; logindex++)
+ {
+ UINT32 logical_col = logindex % m_cols;
+ UINT32 logical_row = logindex / m_cols;
+ tilemap_memory_index memindex = memory_index(logical_col, logical_row);
+
+ // apply tilemap flip to get the final location to store
+ if (m_attributes & TILEMAP_FLIPX)
+ logical_col = (m_cols - 1) - logical_col;
+ if (m_attributes & TILEMAP_FLIPY)
+ logical_row = (m_rows - 1) - logical_row;
+ UINT32 flipped_logindex = logical_row * m_cols + logical_col;
+
+ // fill in entries in both arrays
+ m_memory_to_logical[memindex] = flipped_logindex;
+ m_logical_to_memory[flipped_logindex] = memindex;
+ }
- /* update the mappings */
- mappings_update(tmap);
+ // mark the whole tilemap dirty
+ mark_all_dirty();
}
-/*-------------------------------------------------
- mappings_update - update the mappings after
- a major change (flip x/y changes)
--------------------------------------------------*/
-static void mappings_update(tilemap_t *tmap)
-{
- tilemap_logical_index logindex;
- tilemap_memory_index memindex;
+//**************************************************************************
+// TILE RENDERING
+//**************************************************************************
- /* initialize all the mappings to invalid values */
- for (memindex = 0; memindex < tmap->max_memory_index; memindex++)
- tmap->memory_to_logical[memindex] = -1;
-
- /* now iterate over all logical indexes and populate the memory index */
- for (logindex = 0; logindex < tmap->max_logical_index; logindex++)
+inline void tilemap_t::realize_all_dirty_tiles()
+{
+ // if all the tiles are marked dirty, or something in the gfx has changed,
+ // flush the dirty status to all tiles
+ if (m_all_tiles_dirty || gfx_elements_changed())
{
- UINT32 logical_col = logindex % tmap->cols;
- UINT32 logical_row = logindex / tmap->cols;
- memindex = (*tmap->mapper)(logical_col, logical_row, tmap->cols, tmap->rows);
- UINT32 flipped_logindex;
-
- /* apply tilemap flip to get the final location to store */
- if (tmap->attributes & TILEMAP_FLIPX)
- logical_col = (tmap->cols - 1) - logical_col;
- if (tmap->attributes & TILEMAP_FLIPY)
- logical_row = (tmap->rows - 1) - logical_row;
- flipped_logindex = logical_row * tmap->cols + logical_col;
-
- /* fill in entries in both arrays */
- tmap->memory_to_logical[memindex] = flipped_logindex;
- tmap->logical_to_memory[flipped_logindex] = memindex;
+ memset(m_tileflags, TILE_FLAG_DIRTY, m_max_logical_index);
+ m_all_tiles_dirty = false;
+ m_gfx_used = 0;
}
-
- /* mark the whole tilemap dirty */
- tilemap_mark_all_tiles_dirty(tmap);
}
+//-------------------------------------------------
+// pixmap_update - update the entire pixmap
+//-------------------------------------------------
-
-/***************************************************************************
- TILE RENDERING
-***************************************************************************/
-
-/*-------------------------------------------------
- pixmap_update - update the entire pixmap
--------------------------------------------------*/
-
-static void pixmap_update(tilemap_t *tmap)
+void tilemap_t::pixmap_update()
{
- int mincol, maxcol, minrow, maxrow;
- int row, col;
-
- /* if the graphics changed, we need to mark everything dirty */
- if (gfx_elements_changed(tmap))
- tilemap_mark_all_tiles_dirty(tmap);
+ // if the graphics changed, we need to mark everything dirty
+ if (gfx_elements_changed())
+ mark_all_dirty();
- /* if everything is clean, do nothing */
- if (tmap->all_tiles_clean)
+ // if everything is clean, do nothing
+ if (m_all_tiles_clean)
return;
g_profiler.start(PROFILER_TILEMAP_DRAW);
- /* compute which columns and rows to update */
- mincol = minrow = 0;
- maxcol = tmap->cols - 1;
- maxrow = tmap->rows - 1;
-
- /* if the whole map is dirty, mark it as such */
- if (tmap->all_tiles_dirty)
- {
- memset(tmap->tileflags, TILE_FLAG_DIRTY, tmap->max_logical_index);
- tmap->all_tiles_dirty = FALSE;
- tmap->gfx_used = 0;
- }
-
- /* iterate over rows */
- for (row = minrow; row <= maxrow; row++)
- {
- tilemap_logical_index logindex = row * tmap->cols;
+ // flush the dirty state to all tiles as appropriate
+ realize_all_dirty_tiles();
- /* iterate over colums */
- for (col = mincol; col <= maxcol; col++)
- if (tmap->tileflags[logindex + col] == TILE_FLAG_DIRTY)
- tile_update(tmap, logindex + col, col, row);
- }
+ // iterate over rows and columns
+ logical_index logindex = 0;
+ for (int row = 0; row < m_rows; row++)
+ for (int col = 0; col < m_cols; col++, logindex++)
+ if (m_tileflags[logindex] == TILE_FLAG_DIRTY)
+ tile_update(logindex, col, row);
- /* mark it all clean */
- if (mincol == 0 && minrow == 0 && maxcol == tmap->cols - 1 && maxcol == tmap->rows - 1)
- tmap->all_tiles_clean = TRUE;
+ // mark it all clean
+ m_all_tiles_clean = true;
g_profiler.stop();
}
-/*-------------------------------------------------
- tile_update - update a single dirty tile
--------------------------------------------------*/
+//-------------------------------------------------
+// tile_update - update a single dirty tile
+//-------------------------------------------------
-static void tile_update(tilemap_t *tmap, tilemap_logical_index logindex, UINT32 col, UINT32 row)
+void tilemap_t::tile_update(logical_index logindex, UINT32 col, UINT32 row)
{
- UINT32 x0 = tmap->tilewidth * col;
- UINT32 y0 = tmap->tileheight * row;
- tilemap_memory_index memindex;
- UINT32 flags;
-
g_profiler.start(PROFILER_TILEMAP_UPDATE);
- /* call the get info callback for the associated memory index */
- memindex = tmap->logical_to_memory[logindex];
- (*tmap->tile_get_info)(*(running_machine *)tmap->tile_get_info_object, &tmap->tileinfo, memindex, tmap->user_data);
+ // call the get info callback for the associated memory index
+ tilemap_memory_index memindex = m_logical_to_memory[logindex];
+ m_tile_get_info(&m_tileinfo, memindex, m_user_data);
- /* apply the global tilemap flip to the returned flip flags */
- flags = tmap->tileinfo.flags ^ (tmap->attributes & 0x03);
+ // apply the global tilemap flip to the returned flip flags
+ UINT32 flags = m_tileinfo.flags ^ (m_attributes & 0x03);
- /* draw the tile, using either direct or transparent */
- tmap->tileflags[logindex] = tile_draw(tmap, tmap->tileinfo.pen_data + tmap->pen_data_offset, x0, y0,
- tmap->tileinfo.palette_base, tmap->tileinfo.category, tmap->tileinfo.group, flags, tmap->tileinfo.pen_mask);
+ // draw the tile, using either direct or transparent
+ UINT32 x0 = m_tilewidth * col;
+ UINT32 y0 = m_tileheight * row;
+ m_tileflags[logindex] = tile_draw(m_tileinfo.pen_data + m_pen_data_offset, x0, y0,
+ m_tileinfo.palette_base, m_tileinfo.category, m_tileinfo.group, flags, m_tileinfo.pen_mask);
- /* if mask data is specified, apply it */
- if ((flags & (TILE_FORCE_LAYER0 | TILE_FORCE_LAYER1 | TILE_FORCE_LAYER2)) == 0 && tmap->tileinfo.mask_data != NULL)
- tmap->tileflags[logindex] = tile_apply_bitmask(tmap, tmap->tileinfo.mask_data, x0, y0, tmap->tileinfo.category, flags);
+ // if mask data is specified, apply it
+ if ((flags & (TILE_FORCE_LAYER0 | TILE_FORCE_LAYER1 | TILE_FORCE_LAYER2)) == 0 && m_tileinfo.mask_data != NULL)
+ m_tileflags[logindex] = tile_apply_bitmask(m_tileinfo.mask_data, x0, y0, m_tileinfo.category, flags);
- /* track which gfx have been used for this tilemap */
- if (tmap->tileinfo.gfxnum != 0xff && (tmap->gfx_used & (1 << tmap->tileinfo.gfxnum)) == 0)
+ // track which gfx have been used for this tilemap
+ if (m_tileinfo.gfxnum != 0xff && (m_gfx_used & (1 << m_tileinfo.gfxnum)) == 0)
{
- tmap->gfx_used |= 1 << tmap->tileinfo.gfxnum;
- tmap->gfx_dirtyseq[tmap->tileinfo.gfxnum] = tmap->machine().gfx[tmap->tileinfo.gfxnum]->dirtyseq;
+ m_gfx_used |= 1 << m_tileinfo.gfxnum;
+ m_gfx_dirtyseq[m_tileinfo.gfxnum] = machine().gfx[m_tileinfo.gfxnum]->dirtyseq;
}
g_profiler.stop();
}
-/*-------------------------------------------------
- tile_draw - draw a single tile to the
- tilemap's internal pixmap, using the pen as
- the pen_to_flags lookup value, and adding
- the palette_base
--------------------------------------------------*/
+//-------------------------------------------------
+// tile_draw - draw a single tile to the
+// tilemap's internal pixmap, using the pen as
+// the pen_to_flags lookup value, and adding
+// the palette_base
+//-------------------------------------------------
-static UINT8 tile_draw(tilemap_t *tmap, const UINT8 *pendata, UINT32 x0, UINT32 y0, UINT32 palette_base, UINT8 category, UINT8 group, UINT8 flags, UINT8 pen_mask)
+UINT8 tilemap_t::tile_draw(const UINT8 *pendata, UINT32 x0, UINT32 y0, UINT32 palette_base, UINT8 category, UINT8 group, UINT8 flags, UINT8 pen_mask)
{
- const UINT8 *penmap = tmap->pen_to_flags + group * MAX_PEN_TO_FLAGS;
- bitmap_ind8 &flagsmap = tmap->flagsmap;
- bitmap_ind16 &pixmap = tmap->pixmap;
- int height = tmap->tileheight;
- int width = tmap->tilewidth;
- UINT8 andmask = ~0, ormask = 0;
- int dx0 = 1, dy0 = 1;
- int tx, ty;
-
- /* OR in the force layer flags */
+ // OR in the force layer flags
category |= flags & (TILE_FORCE_LAYER0 | TILE_FORCE_LAYER1 | TILE_FORCE_LAYER2);
- /* if we're vertically flipped, point to the bottom row and work backwards */
+ // if we're vertically flipped, point to the bottom row and work backwards
+ int dy0 = 1;
if (flags & TILE_FLIPY)
{
- y0 += height - 1;
+ y0 += m_tileheight - 1;
dy0 = -1;
}
- /* if we're horizontally flipped, point to the rightmost column and work backwards */
+ // if we're horizontally flipped, point to the rightmost column and work backwards
+ int dx0 = 1;
if (flags & TILE_FLIPX)
{
- x0 += width - 1;
+ x0 += m_tilewidth - 1;
dx0 = -1;
}
- /* in 4bpp mode, we draw in groups of 2 pixels, so halve the width now */
+ // in 4bpp mode, we draw in groups of 2 pixels, so halve the width now
+ int width = m_tilewidth;
if (flags & TILE_4BPP)
{
assert(width % 2 == 0);
width /= 2;
}
- /* iterate over rows */
- for (ty = 0; ty < height; ty++)
+ // iterate over rows
+ const UINT8 *penmap = m_pen_to_flags + group * MAX_PEN_TO_FLAGS;
+ UINT8 andmask = ~0, ormask = 0;
+ for (int ty = 0; ty < m_tileheight; ty++)
{
- UINT16 *pixptr = &pixmap.pix16(y0, x0);
- UINT8 *flagsptr = &flagsmap.pix8(y0, x0);
- int xoffs = 0;
+ UINT16 *pixptr = &m_pixmap.pix16(y0, x0);
+ UINT8 *flagsptr = &m_flagsmap.pix8(y0, x0);
- /* pre-advance to the next row */
+ // pre-advance to the next row
y0 += dy0;
- /* 8bpp data */
+ // 8bpp data
if (!(flags & TILE_4BPP))
{
- for (tx = 0; tx < width; tx++)
+ for (int tx = 0, xoffs = 0; tx < width; tx++, xoffs += dx0)
{
UINT8 pen = (*pendata++) & pen_mask;
UINT8 map = penmap[pen];
@@ -1417,14 +823,13 @@ static UINT8 tile_draw(tilemap_t *tmap, const UINT8 *pendata, UINT32 x0, UINT32
flagsptr[xoffs] = map | category;
andmask &= map;
ormask |= map;
- xoffs += dx0;
}
}
- /* 4bpp data */
+ // 4bpp data
else
{
- for (tx = 0; tx < width; tx++)
+ for (int tx = 0, xoffs = 0; tx < width; tx++)
{
UINT8 data = *pendata++;
UINT8 pen, map;
@@ -1451,47 +856,41 @@ static UINT8 tile_draw(tilemap_t *tmap, const UINT8 *pendata, UINT32 x0, UINT32
}
-/*-------------------------------------------------
- tile_apply_bitmask - apply a bitmask to an
- already-rendered tile by modifying the
- flagsmap appropriately
--------------------------------------------------*/
+//-------------------------------------------------
+// tile_apply_bitmask - apply a bitmask to an
+// already-rendered tile by modifying the
+// flagsmap appropriately
+//-------------------------------------------------
-static UINT8 tile_apply_bitmask(tilemap_t *tmap, const UINT8 *maskdata, UINT32 x0, UINT32 y0, UINT8 category, UINT8 flags)
+UINT8 tilemap_t::tile_apply_bitmask(const UINT8 *maskdata, UINT32 x0, UINT32 y0, UINT8 category, UINT8 flags)
{
- bitmap_ind8 &flagsmap = tmap->flagsmap;
- int height = tmap->tileheight;
- int width = tmap->tilewidth;
- UINT8 andmask = ~0, ormask = 0;
- int dx0 = 1, dy0 = 1;
- int bitoffs = 0;
- int tx, ty;
-
- /* if we're vertically flipped, point to the bottom row and work backwards */
+ // if we're vertically flipped, point to the bottom row and work backwards
+ int dy0 = 1;
if (flags & TILE_FLIPY)
{
- y0 += height - 1;
+ y0 += m_tileheight - 1;
dy0 = -1;
}
- /* if we're horizontally flipped, point to the rightmost column and work backwards */
+ // if we're horizontally flipped, point to the rightmost column and work backwards
+ int dx0 = 1;
if (flags & TILE_FLIPX)
{
- x0 += width - 1;
+ x0 += m_tilewidth - 1;
dx0 = -1;
}
- /* iterate over rows */
- for (ty = 0; ty < height; ty++)
+ // iterate over rows
+ UINT8 andmask = ~0, ormask = 0;
+ int bitoffs = 0;
+ for (int ty = 0; ty < m_tileheight; ty++)
{
- UINT8 *flagsptr = &flagsmap.pix8(y0, x0);
- int xoffs = 0;
-
- /* pre-advance to the next row */
+ // pre-advance to the next row
+ UINT8 *flagsptr = &m_flagsmap.pix8(y0, x0);
y0 += dy0;
- /* anywhere the bitmask is 0 should be transparent */
- for (tx = 0; tx < width; tx++)
+ // anywhere the bitmask is 0 should be transparent
+ for (int tx = 0, xoffs = 0; tx < m_tilewidth; tx++, xoffs += dx0)
{
UINT8 map = flagsptr[xoffs];
@@ -1499,7 +898,6 @@ static UINT8 tile_apply_bitmask(tilemap_t *tmap, const UINT8 *maskdata, UINT32 x
map = flagsptr[xoffs] = TILEMAP_PIXEL_TRANSPARENT | category;
andmask &= map;
ormask |= map;
- xoffs += dx0;
bitoffs++;
}
}
@@ -1508,238 +906,398 @@ static UINT8 tile_apply_bitmask(tilemap_t *tmap, const UINT8 *maskdata, UINT32 x
-/***************************************************************************
- DRAWING HELPERS
-***************************************************************************/
+//**************************************************************************
+// DRAWING HELPERS
+//**************************************************************************
-/*-------------------------------------------------
- configure_blit_parameters - fill in the
- standard blit parameters based on the input
- data; this code is shared by normal, roz,
- and indexed drawing code
--------------------------------------------------*/
+//-------------------------------------------------
+// configure_blit_parameters - fill in the
+// standard blit parameters based on the input
+// data; this code is shared by normal, roz,
+// and indexed drawing code
+//-------------------------------------------------
-static void configure_blit_parameters(blit_parameters *blit, tilemap_t *tmap, bitmap_format dest_format, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+void tilemap_t::configure_blit_parameters(blit_parameters &blit, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask)
{
- /* start with nothing */
- memset(blit, 0, sizeof(*blit));
-
- /* set the target bitmap */
- blit->cliprect = cliprect;
+ // set the target bitmap
+ blit.cliprect = cliprect;
- /* set the priority code and alpha */
- blit->tilemap_priority_code = priority | (priority_mask << 8) | (tmap->palette_offset << 16);
- blit->alpha = (flags & TILEMAP_DRAW_ALPHA_FLAG) ? (flags >> 24) : 0xff;
+ // set the priority code and alpha
+ blit.tilemap_priority_code = priority | (priority_mask << 8) | (m_palette_offset << 16);
+ blit.alpha = (flags & TILEMAP_DRAW_ALPHA_FLAG) ? (flags >> 24) : 0xff;
- /* tile priority; unless otherwise specified, draw anything in layer 0 */
- blit->mask = TILEMAP_PIXEL_CATEGORY_MASK;
- blit->value = flags & TILEMAP_PIXEL_CATEGORY_MASK;
+ // tile priority; unless otherwise specified, draw anything in layer 0
+ blit.mask = TILEMAP_PIXEL_CATEGORY_MASK;
+ blit.value = flags & TILEMAP_PIXEL_CATEGORY_MASK;
- /* if no layers specified, draw layer 0 */
+ // if no layers specified, draw layer 0
if ((flags & (TILEMAP_DRAW_LAYER0 | TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_LAYER2)) == 0)
flags |= TILEMAP_DRAW_LAYER0;
- /* OR in the bits from the draw masks */
- blit->mask |= flags & (TILEMAP_DRAW_LAYER0 | TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_LAYER2);
- blit->value |= flags & (TILEMAP_DRAW_LAYER0 | TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_LAYER2);
+ // OR in the bits from the draw masks
+ blit.mask |= flags & (TILEMAP_DRAW_LAYER0 | TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_LAYER2);
+ blit.value |= flags & (TILEMAP_DRAW_LAYER0 | TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_LAYER2);
- /* for all-opaque rendering, don't check any of the layer bits */
+ // for all-opaque rendering, don't check any of the layer bits
if (flags & TILEMAP_DRAW_OPAQUE)
{
- blit->mask &= ~(TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1 | TILEMAP_PIXEL_LAYER2);
- blit->value &= ~(TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1 | TILEMAP_PIXEL_LAYER2);
+ blit.mask &= ~(TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1 | TILEMAP_PIXEL_LAYER2);
+ blit.value &= ~(TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1 | TILEMAP_PIXEL_LAYER2);
}
- /* don't check category if requested */
+ // don't check category if requested
if (flags & TILEMAP_DRAW_ALL_CATEGORIES)
{
- blit->mask &= ~TILEMAP_PIXEL_CATEGORY_MASK;
- blit->value &= ~TILEMAP_PIXEL_CATEGORY_MASK;
+ blit.mask &= ~TILEMAP_PIXEL_CATEGORY_MASK;
+ blit.value &= ~TILEMAP_PIXEL_CATEGORY_MASK;
}
}
-/*-------------------------------------------------
- tilemap_draw_instance - draw a single
- instance of the tilemap to the internal
- pixmap at the given xpos,ypos
--------------------------------------------------*/
+//-------------------------------------------------
+// draw_common - draw a tilemap to the
+// destination with clipping; pixels apply
+// priority/priority_mask to the priority bitmap
+//-------------------------------------------------
template<class _BitmapClass>
-static void tilemap_draw_instance(_BitmapClass &dest, tilemap_t *tmap, const blit_parameters *blit, int xpos, int ypos)
+void tilemap_t::draw_common(_BitmapClass &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask)
{
- bitmap_ind8 &priority_bitmap = tmap->machine().priority_bitmap;
- const UINT16 *source_baseaddr;
- const UINT8 *mask_baseaddr;
- typename _BitmapClass::pixel_t *dest_baseaddr = NULL;
- UINT8 *priority_baseaddr;
- int dest_rowpixels = 0;
- int mincol, maxcol;
- int x1, y1, x2, y2;
- int y, nexty;
-
- /* clip destination coordinates to the tilemap */
- /* note that x2/y2 are exclusive, not inclusive */
- x1 = MAX(xpos, blit->cliprect.min_x);
- x2 = MIN(xpos + (int)tmap->width, blit->cliprect.max_x + 1);
- y1 = MAX(ypos, blit->cliprect.min_y);
- y2 = MIN(ypos + (int)tmap->height, blit->cliprect.max_y + 1);
-
- /* if totally clipped, stop here */
+ // skip if disabled
+ if (!m_enable)
+ return;
+
+g_profiler.start(PROFILER_TILEMAP_DRAW);
+ // configure the blit parameters based on the input parameters
+ blit_parameters blit;
+ configure_blit_parameters(blit, cliprect, flags, priority, priority_mask);
+
+ // flush the dirty state to all tiles as appropriate
+ realize_all_dirty_tiles();
+
+ UINT32 width = machine().primary_screen->width();
+ UINT32 height = machine().primary_screen->height();
+
+ // XY scrolling playfield
+ if (m_scrollrows == 1 && m_scrollcols == 1)
+ {
+ // iterate to handle wraparound
+ int scrollx = effective_rowscroll(0, width);
+ int scrolly = effective_colscroll(0, height);
+ for (int ypos = scrolly - m_height; ypos <= blit.cliprect.max_y; ypos += m_height)
+ for (int xpos = scrollx - m_width; xpos <= blit.cliprect.max_x; xpos += m_width)
+ draw_instance(dest, blit, xpos, ypos);
+ }
+
+ // scrolling rows + vertical scroll
+ else if (m_scrollcols == 1)
+ {
+ const rectangle original_cliprect = blit.cliprect;
+
+ // iterate over Y to handle wraparound
+ int rowheight = m_height / m_scrollrows;
+ int scrolly = effective_colscroll(0, height);
+ for (int ypos = scrolly - m_height; ypos <= original_cliprect.max_y; ypos += m_height)
+ {
+ int const firstrow = MAX((original_cliprect.min_y - ypos) / rowheight, 0);
+ int const lastrow = MIN((original_cliprect.max_y - ypos) / rowheight, m_scrollrows - 1);
+
+ // iterate over rows in the tilemap
+ int nextrow;
+ for (int currow = firstrow; currow <= lastrow; currow = nextrow)
+ {
+ // scan forward until we find a non-matching row
+ int scrollx = effective_rowscroll(currow, width);
+ for (nextrow = currow + 1; nextrow <= lastrow; nextrow++)
+ if (effective_rowscroll(nextrow, width) != scrollx)
+ break;
+
+ // skip if disabled
+ if (scrollx == TILE_LINE_DISABLED)
+ continue;
+
+ // update the cliprect just for this set of rows
+ blit.cliprect.min_y = currow * rowheight + ypos;
+ blit.cliprect.max_y = nextrow * rowheight - 1 + ypos;
+ blit.cliprect &= original_cliprect;
+
+ // iterate over X to handle wraparound
+ for (int xpos = scrollx - m_width; xpos <= original_cliprect.max_x; xpos += m_width)
+ draw_instance(dest, blit, xpos, ypos);
+ }
+ }
+ }
+
+ // scrolling columns + horizontal scroll
+ else if (m_scrollrows == 1)
+ {
+ const rectangle original_cliprect = blit.cliprect;
+
+ // iterate over columns in the tilemap
+ int scrollx = effective_rowscroll(0, width);
+ int colwidth = m_width / m_scrollcols;
+ int nextcol;
+ for (int curcol = 0; curcol < m_scrollcols; curcol = nextcol)
+ {
+ // scan forward until we find a non-matching column
+ int scrolly = effective_colscroll(curcol, height);
+ for (nextcol = curcol + 1; nextcol < m_scrollcols; nextcol++)
+ if (effective_colscroll(nextcol, height) != scrolly)
+ break;
+
+ // skip if disabled
+ if (scrolly == TILE_LINE_DISABLED)
+ continue;
+
+ // iterate over X to handle wraparound
+ for (int xpos = scrollx - m_width; xpos <= original_cliprect.max_x; xpos += m_width)
+ {
+ // update the cliprect just for this set of columns
+ blit.cliprect.min_x = curcol * colwidth + xpos;
+ blit.cliprect.max_x = nextcol * colwidth - 1 + xpos;
+ blit.cliprect &= original_cliprect;
+
+ // iterate over Y to handle wraparound
+ for (int ypos = scrolly - m_height; ypos <= original_cliprect.max_y; ypos += m_height)
+ draw_instance(dest, blit, xpos, ypos);
+ }
+ }
+ }
+g_profiler.stop();
+}
+
+void tilemap_t::draw(bitmap_ind16 &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ draw_common(dest, cliprect, flags, priority, priority_mask); }
+
+void tilemap_t::draw(bitmap_rgb32 &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ draw_common(dest, cliprect, flags, priority, priority_mask); }
+
+
+//-------------------------------------------------
+// draw_roz - draw a tilemap to the destination
+// with clipping and arbitrary rotate/zoom; pixels
+// apply priority/priority_mask to the priority
+// bitmap
+//-------------------------------------------------
+
+template<class _BitmapClass>
+void tilemap_t::draw_roz_common(_BitmapClass &dest, const rectangle &cliprect,
+ UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
+ bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{
+// notes:
+// - startx and starty MUST be UINT32 for calculations to work correctly
+// - srcbim_width and height are assumed to be a power of 2 to speed up wraparound
+
+ // skip if disabled
+ if (!m_enable)
+ return;
+
+ // see if this is just a regular render and if so, do a regular render
+ if (incxx == (1 << 16) && incxy == 0 && incyx == 0 && incyy == (1 << 16) && wraparound)
+ {
+ set_scrollx(0, startx >> 16);
+ set_scrolly(0, starty >> 16);
+ draw(dest, cliprect, flags, priority, priority_mask);
+ return;
+ }
+
+g_profiler.start(PROFILER_TILEMAP_DRAW_ROZ);
+ // configure the blit parameters
+ blit_parameters blit;
+ configure_blit_parameters(blit, cliprect, flags, priority, priority_mask);
+
+ // get the full pixmap for the tilemap
+ pixmap();
+
+ // then do the roz copy
+ draw_roz_core(dest, blit, startx, starty, incxx, incxy, incyx, incyy, wraparound);
+g_profiler.stop();
+}
+
+void tilemap_t::draw_roz(bitmap_ind16 &dest, const rectangle &cliprect,
+ UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
+ bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ draw_roz_common(dest, cliprect, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
+
+void tilemap_t::draw_roz(bitmap_rgb32 &dest, const rectangle &cliprect,
+ UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
+ bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ draw_roz_common(dest, cliprect, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
+
+
+//-------------------------------------------------
+// draw_instance - draw a single instance of the
+// tilemap to the internal pixmap at the given
+// xpos,ypos
+//-------------------------------------------------
+
+template<class _BitmapClass>
+void tilemap_t::draw_instance(_BitmapClass &dest, const blit_parameters &blit, int xpos, int ypos)
+{
+ // clip destination coordinates to the tilemap
+ // note that x2/y2 are exclusive, not inclusive
+ int x1 = MAX(xpos, blit.cliprect.min_x);
+ int x2 = MIN(xpos + (int)m_width, blit.cliprect.max_x + 1);
+ int y1 = MAX(ypos, blit.cliprect.min_y);
+ int y2 = MIN(ypos + (int)m_height, blit.cliprect.max_y + 1);
+
+ // if totally clipped, stop here
if (x1 >= x2 || y1 >= y2)
return;
- /* look up priority and destination base addresses for y1 */
- priority_baseaddr = &priority_bitmap.pix8(y1, xpos);
+ // look up priority and destination base addresses for y1
+ bitmap_ind8 &priority_bitmap = machine().priority_bitmap;
+ UINT8 *priority_baseaddr = &priority_bitmap.pix8(y1, xpos);
+ typename _BitmapClass::pixel_t *dest_baseaddr = NULL;
+ int dest_rowpixels = 0;
if (dest.valid())
{
dest_rowpixels = dest.rowpixels();
dest_baseaddr = &dest.pix(y1, xpos);
}
- /* convert screen coordinates to source tilemap coordinates */
+ // convert screen coordinates to source tilemap coordinates
x1 -= xpos;
y1 -= ypos;
x2 -= xpos;
y2 -= ypos;
- /* get tilemap pixels */
- source_baseaddr = &tmap->pixmap.pix16(y1);
- mask_baseaddr = &tmap->flagsmap.pix8(y1);
+ // get tilemap pixels
+ const UINT16 *source_baseaddr = &m_pixmap.pix16(y1);
+ const UINT8 *mask_baseaddr = &m_flagsmap.pix8(y1);
- /* get start/stop columns, rounding outward */
- mincol = x1 / tmap->tilewidth;
- maxcol = (x2 + tmap->tilewidth - 1) / tmap->tilewidth;
+ // get start/stop columns, rounding outward
+ int mincol = x1 / m_tilewidth;
+ int maxcol = (x2 + m_tilewidth - 1) / m_tilewidth;
- /* set up row counter */
- y = y1;
- nexty = tmap->tileheight * (y1 / tmap->tileheight) + tmap->tileheight;
+ // set up row counter
+ int y = y1;
+ int nexty = m_tileheight * (y1 / m_tileheight) + m_tileheight;
nexty = MIN(nexty, y2);
- /* loop over tilemap rows */
+ // loop over tilemap rows
for (;;)
{
- int row = y / tmap->tileheight;
- trans_t prev_trans = WHOLLY_TRANSPARENT;
- trans_t cur_trans;
+ int row = y / m_tileheight;
int x_start = x1;
- int column;
- /* iterate across the applicable tilemap columns */
- for (column = mincol; column <= maxcol; column++)
+ // iterate across the applicable tilemap columns
+ trans_t prev_trans = WHOLLY_TRANSPARENT;
+ trans_t cur_trans;
+ for (int column = mincol; column <= maxcol; column++)
{
int x_end;
- /* we don't actually render the last column; it is always just used for flushing */
+ // we don't actually render the last column; it is always just used for flushing
if (column == maxcol)
cur_trans = WHOLLY_TRANSPARENT;
- /* for other columns we look up the transparency information */
+ // for other columns we look up the transparency information
else
{
- tilemap_logical_index logindex = row * tmap->cols + column;
+ logical_index logindex = row * m_cols + column;
- /* if the current tile is dirty, fix it */
- if (tmap->tileflags[logindex] == TILE_FLAG_DIRTY)
- tile_update(tmap, logindex, column, row);
+ // if the current tile is dirty, fix it
+ if (m_tileflags[logindex] == TILE_FLAG_DIRTY)
+ tile_update(logindex, column, row);
- /* if the current summary data is non-zero, we must draw masked */
- if ((tmap->tileflags[logindex] & blit->mask) != 0)
+ // if the current summary data is non-zero, we must draw masked
+ if ((m_tileflags[logindex] & blit.mask) != 0)
cur_trans = MASKED;
- /* otherwise, our transparency state is constant across the tile; fetch it */
+ // otherwise, our transparency state is constant across the tile; fetch it
else
- cur_trans = ((mask_baseaddr[column * tmap->tilewidth] & blit->mask) == blit->value) ? WHOLLY_OPAQUE : WHOLLY_TRANSPARENT;
+ cur_trans = ((mask_baseaddr[column * m_tilewidth] & blit.mask) == blit.value) ? WHOLLY_OPAQUE : WHOLLY_TRANSPARENT;
}
- /* if the transparency state is the same as last time, don't render yet */
+ // if the transparency state is the same as last time, don't render yet
if (cur_trans == prev_trans)
continue;
- /* compute the end of this run, in pixels */
- x_end = column * tmap->tilewidth;
+ // compute the end of this run, in pixels
+ x_end = column * m_tilewidth;
x_end = MAX(x_end, x1);
x_end = MIN(x_end, x2);
- /* if we're rendering something, compute the pointers */
+ // if we're rendering something, compute the pointers
if (prev_trans != WHOLLY_TRANSPARENT)
{
const UINT16 *source0 = source_baseaddr + x_start;
typename _BitmapClass::pixel_t *dest0 = dest_baseaddr + x_start;
UINT8 *pmap0 = priority_baseaddr + x_start;
- int cury;
- /* if we were opaque, use the opaque renderer */
+ // if we were opaque, use the opaque renderer
if (prev_trans == WHOLLY_OPAQUE)
{
- for (cury = y; cury < nexty; cury++)
+ for (int cury = y; cury < nexty; cury++)
{
if (dest_baseaddr == NULL)
- scanline_draw_opaque_null(x_end - x_start, pmap0, blit->tilemap_priority_code);
+ scanline_draw_opaque_null(x_end - x_start, pmap0, blit.tilemap_priority_code);
else if (sizeof(*dest0) == 2)
- scanline_draw_opaque_ind16(reinterpret_cast<UINT16 *>(dest0), source0, x_end - x_start, pmap0, blit->tilemap_priority_code);
- else if (sizeof(*dest0) == 4 && blit->alpha >= 0xff)
- scanline_draw_opaque_rgb32(reinterpret_cast<UINT32 *>(dest0), source0, x_end - x_start, tmap->machine().pens, pmap0, blit->tilemap_priority_code);
+ scanline_draw_opaque_ind16(reinterpret_cast<UINT16 *>(dest0), source0, x_end - x_start, pmap0, blit.tilemap_priority_code);
+ else if (sizeof(*dest0) == 4 && blit.alpha >= 0xff)
+ scanline_draw_opaque_rgb32(reinterpret_cast<UINT32 *>(dest0), source0, x_end - x_start, machine().pens, pmap0, blit.tilemap_priority_code);
else if (sizeof(*dest0) == 4)
- scanline_draw_opaque_rgb32_alpha(reinterpret_cast<UINT32 *>(dest0), source0, x_end - x_start, tmap->machine().pens, pmap0, blit->tilemap_priority_code, blit->alpha);
+ scanline_draw_opaque_rgb32_alpha(reinterpret_cast<UINT32 *>(dest0), source0, x_end - x_start, machine().pens, pmap0, blit.tilemap_priority_code, blit.alpha);
dest0 += dest_rowpixels;
- source0 += tmap->pixmap.rowpixels();
+ source0 += m_pixmap.rowpixels();
pmap0 += priority_bitmap.rowpixels();
}
}
- /* otherwise use the masked renderer */
+ // otherwise use the masked renderer
else
{
const UINT8 *mask0 = mask_baseaddr + x_start;
- for (cury = y; cury < nexty; cury++)
+ for (int cury = y; cury < nexty; cury++)
{
if (dest_baseaddr == NULL)
- scanline_draw_masked_null(mask0, blit->mask, blit->value, x_end - x_start, pmap0, blit->tilemap_priority_code);
+ scanline_draw_masked_null(mask0, blit.mask, blit.value, x_end - x_start, pmap0, blit.tilemap_priority_code);
else if (sizeof(*dest0) == 2)
- scanline_draw_masked_ind16(reinterpret_cast<UINT16 *>(dest0), source0, mask0, blit->mask, blit->value, x_end - x_start, pmap0, blit->tilemap_priority_code);
- else if (sizeof(*dest0) == 4 && blit->alpha >= 0xff)
- scanline_draw_masked_rgb32(reinterpret_cast<UINT32 *>(dest0), source0, mask0, blit->mask, blit->value, x_end - x_start, tmap->machine().pens, pmap0, blit->tilemap_priority_code);
+ scanline_draw_masked_ind16(reinterpret_cast<UINT16 *>(dest0), source0, mask0, blit.mask, blit.value, x_end - x_start, pmap0, blit.tilemap_priority_code);
+ else if (sizeof(*dest0) == 4 && blit.alpha >= 0xff)
+ scanline_draw_masked_rgb32(reinterpret_cast<UINT32 *>(dest0), source0, mask0, blit.mask, blit.value, x_end - x_start, machine().pens, pmap0, blit.tilemap_priority_code);
else if (sizeof(*dest0) == 4)
- scanline_draw_masked_rgb32_alpha(reinterpret_cast<UINT32 *>(dest0), source0, mask0, blit->mask, blit->value, x_end - x_start, tmap->machine().pens, pmap0, blit->tilemap_priority_code, blit->alpha);
+ scanline_draw_masked_rgb32_alpha(reinterpret_cast<UINT32 *>(dest0), source0, mask0, blit.mask, blit.value, x_end - x_start, machine().pens, pmap0, blit.tilemap_priority_code, blit.alpha);
dest0 += dest_rowpixels;
- source0 += tmap->pixmap.rowpixels();
- mask0 += tmap->flagsmap.rowpixels();
+ source0 += m_pixmap.rowpixels();
+ mask0 += m_flagsmap.rowpixels();
pmap0 += priority_bitmap.rowpixels();
}
}
}
- /* the new start is the end */
+ // the new start is the end
x_start = x_end;
prev_trans = cur_trans;
}
- /* if this was the last row, stop */
+ // if this was the last row, stop
if (nexty == y2)
break;
- /* advance to the next row on all our bitmaps */
+ // advance to the next row on all our bitmaps
priority_baseaddr += priority_bitmap.rowpixels() * (nexty - y);
- source_baseaddr += tmap->pixmap.rowpixels() * (nexty - y);
- mask_baseaddr += tmap->flagsmap.rowpixels() * (nexty - y);
+ source_baseaddr += m_pixmap.rowpixels() * (nexty - y);
+ mask_baseaddr += m_flagsmap.rowpixels() * (nexty - y);
dest_baseaddr += dest_rowpixels * (nexty - y);
- /* increment the Y counter */
+ // increment the Y counter
y = nexty;
- nexty += tmap->tileheight;
+ nexty += m_tileheight;
nexty = MIN(nexty, y2);
}
}
-/*-------------------------------------------------
- tilemap_draw_roz_core - render the tilemap's
- pixmap to the destination with rotation
- and zoom
--------------------------------------------------*/
+//-------------------------------------------------
+// tilemap_draw_roz_core - render the tilemap's
+// pixmap to the destination with rotation
+// and zoom
+//-------------------------------------------------
#define ROZ_PLOT_PIXEL(INPUT_VAL) \
do { \
@@ -1752,85 +1310,73 @@ do { \
} while (0)
template<class _BitmapClass>
-static void tilemap_draw_roz_core(_BitmapClass &destbitmap, tilemap_t *tmap, const blit_parameters *blit,
- UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound)
-{
- const pen_t *clut = &tmap->machine().pens[blit->tilemap_priority_code >> 16];
- bitmap_ind8 &priority_bitmap = tmap->machine().priority_bitmap;
- bitmap_ind16 &srcbitmap = tmap->pixmap;
- bitmap_ind8 &flagsmap = tmap->flagsmap;
- const int xmask = srcbitmap.width()-1;
- const int ymask = srcbitmap.height()-1;
- const int widthshifted = srcbitmap.width() << 16;
- const int heightshifted = srcbitmap.height() << 16;
- UINT32 priority = blit->tilemap_priority_code;
- UINT8 mask = blit->mask;
- UINT8 value = blit->value;
- UINT8 alpha = blit->alpha;
- UINT32 cx;
- UINT32 cy;
- int x;
- int sx;
- int sy;
- int ex;
- int ey;
- typename _BitmapClass::pixel_t *dest;
- UINT8 *pri;
- const UINT16 *src;
- const UINT8 *maskptr;
-
- /* pre-advance based on the cliprect */
- startx += blit->cliprect.min_x * incxx + blit->cliprect.min_y * incyx;
- starty += blit->cliprect.min_x * incxy + blit->cliprect.min_y * incyy;
-
- /* extract start/end points */
- sx = blit->cliprect.min_x;
- sy = blit->cliprect.min_y;
- ex = blit->cliprect.max_x;
- ey = blit->cliprect.max_y;
-
- /* optimized loop for the not rotated case */
+void tilemap_t::draw_roz_core(_BitmapClass &destbitmap, const blit_parameters &blit,
+ UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, bool wraparound)
+{
+ // pre-cache all the inner loop values
+ const pen_t *clut = &machine().pens[blit.tilemap_priority_code >> 16];
+ bitmap_ind8 &priority_bitmap = machine().priority_bitmap;
+ const int xmask = m_pixmap.width() - 1;
+ const int ymask = m_pixmap.height() - 1;
+ const int widthshifted = m_pixmap.width() << 16;
+ const int heightshifted = m_pixmap.height() << 16;
+ UINT32 priority = blit.tilemap_priority_code;
+ UINT8 mask = blit.mask;
+ UINT8 value = blit.value;
+ UINT8 alpha = blit.alpha;
+
+ // pre-advance based on the cliprect
+ startx += blit.cliprect.min_x * incxx + blit.cliprect.min_y * incyx;
+ starty += blit.cliprect.min_x * incxy + blit.cliprect.min_y * incyy;
+
+ // extract start/end points
+ int sx = blit.cliprect.min_x;
+ int sy = blit.cliprect.min_y;
+ int ex = blit.cliprect.max_x;
+ int ey = blit.cliprect.max_y;
+
+ // optimized loop for the not rotated case
if (incxy == 0 && incyx == 0 && !wraparound)
{
- /* skip without drawing until we are within the bitmap */
+ // skip without drawing until we are within the bitmap
while (startx >= widthshifted && sx <= ex)
{
startx += incxx;
sx++;
}
- /* early exit if we're done already */
+ // early exit if we're done already
if (sx > ex)
return;
- /* loop over rows */
+ // loop over rows
while (sy <= ey)
{
- /* only draw if Y is within range */
+ // only draw if Y is within range
if (starty < heightshifted)
{
- /* initialize X counters */
- x = sx;
- cx = startx;
- cy = starty >> 16;
-
- /* get source and priority pointers */
- pri = &priority_bitmap.pix8(sy, sx);
- src = &srcbitmap.pix16(cy);
- maskptr = &flagsmap.pix8(cy);
- dest = &destbitmap.pix(sy, sx);
-
- /* loop over columns */
+ // initialize X counters
+ int x = sx;
+ UINT32 cx = startx;
+ UINT32 cy = starty >> 16;
+
+ // get source and priority pointers
+ UINT8 *pri = &priority_bitmap.pix8(sy, sx);
+ const UINT16 *src = &m_pixmap.pix16(cy);
+ const UINT8 *maskptr = &m_flagsmap.pix8(cy);
+ typename _BitmapClass::pixel_t *dest = &destbitmap.pix(sy, sx);
+
+ // loop over columns
while (x <= ex && cx < widthshifted)
{
- /* plot if we match the mask */
+ // plot if we match the mask
if ((maskptr[cx >> 16] & mask) == value)
{
ROZ_PLOT_PIXEL(src[cx >> 16]);
*pri = (*pri & (priority >> 8)) | priority;
}
- /* advance in X */
+ // advance in X
cx += incxx;
x++;
dest++;
@@ -1838,38 +1384,38 @@ static void tilemap_draw_roz_core(_BitmapClass &destbitmap, tilemap_t *tmap, con
}
}
- /* advance in Y */
+ // advance in Y
starty += incyy;
sy++;
}
}
- /* wraparound case */
+ // wraparound case
else if (wraparound)
{
- /* loop over rows */
+ // loop over rows
while (sy <= ey)
{
- /* initialize X counters */
- x = sx;
- cx = startx;
- cy = starty;
+ // initialize X counters
+ int x = sx;
+ UINT32 cx = startx;
+ UINT32 cy = starty;
- /* get dest and priority pointers */
- dest = &destbitmap.pix(sy, sx);
- pri = &priority_bitmap.pix8(sy, sx);
+ // get dest and priority pointers
+ typename _BitmapClass::pixel_t *dest = &destbitmap.pix(sy, sx);
+ UINT8 *pri = &priority_bitmap.pix8(sy, sx);
- /* loop over columns */
+ // loop over columns
while (x <= ex)
{
- /* plot if we match the mask */
- if ((flagsmap.pix8((cy >> 16) & ymask, (cx >> 16) & xmask) & mask) == value)
+ // plot if we match the mask
+ if ((m_flagsmap.pix8((cy >> 16) & ymask, (cx >> 16) & xmask) & mask) == value)
{
- ROZ_PLOT_PIXEL(srcbitmap.pix16((cy >> 16) & ymask, (cx >> 16) & xmask));
+ ROZ_PLOT_PIXEL(m_pixmap.pix16((cy >> 16) & ymask, (cx >> 16) & xmask));
*pri = (*pri & (priority >> 8)) | priority;
}
- /* advance in X */
+ // advance in X
cx += incxx;
cy += incxy;
x++;
@@ -1877,40 +1423,40 @@ static void tilemap_draw_roz_core(_BitmapClass &destbitmap, tilemap_t *tmap, con
pri++;
}
- /* advance in Y */
+ // advance in Y
startx += incyx;
starty += incyy;
sy++;
}
}
- /* non-wraparound case */
+ // non-wraparound case
else
{
- /* loop over rows */
+ // loop over rows
while (sy <= ey)
{
- /* initialize X counters */
- x = sx;
- cx = startx;
- cy = starty;
+ // initialize X counters
+ int x = sx;
+ UINT32 cx = startx;
+ UINT32 cy = starty;
- /* get dest and priority pointers */
- dest = &destbitmap.pix(sy, sx);
- pri = &priority_bitmap.pix8(sy, sx);
+ // get dest and priority pointers
+ typename _BitmapClass::pixel_t *dest = &destbitmap.pix(sy, sx);
+ UINT8 *pri = &priority_bitmap.pix8(sy, sx);
- /* loop over columns */
+ // loop over columns
while (x <= ex)
{
- /* plot if we're within the bitmap and we match the mask */
+ // plot if we're within the bitmap and we match the mask
if (cx < widthshifted && cy < heightshifted)
- if ((flagsmap.pix8(cy >> 16, cx >> 16) & mask) == value)
+ if ((m_flagsmap.pix8(cy >> 16, cx >> 16) & mask) == value)
{
- ROZ_PLOT_PIXEL(srcbitmap.pix16(cy >> 16, cx >> 16));
+ ROZ_PLOT_PIXEL(m_pixmap.pix16(cy >> 16, cx >> 16));
*pri = (*pri & (priority >> 8)) | priority;
}
- /* advance in X */
+ // advance in X
cx += incxx;
cy += incxy;
x++;
@@ -1918,7 +1464,7 @@ static void tilemap_draw_roz_core(_BitmapClass &destbitmap, tilemap_t *tmap, con
pri++;
}
- /* advance in Y */
+ // advance in Y
startx += incyx;
starty += incyy;
sy++;
@@ -1927,238 +1473,85 @@ static void tilemap_draw_roz_core(_BitmapClass &destbitmap, tilemap_t *tmap, con
}
-/***************************************************************************
- SCANLINE RASTERIZERS
-***************************************************************************/
+//-------------------------------------------------
+// draw_debug - draw a debug version without any
+// rowscroll and with fixed parameters
+//-------------------------------------------------
-/*-------------------------------------------------
- scanline_draw_opaque_null - draw to a NULL
- bitmap, setting priority only
--------------------------------------------------*/
-
-inline void scanline_draw_opaque_null(int count, UINT8 *pri, UINT32 pcode)
+void tilemap_t::draw_debug(bitmap_rgb32 &dest, UINT32 scrollx, UINT32 scrolly)
{
- int i;
-
- /* skip entirely if not changing priority */
- if (pcode != 0xff00)
- {
- for (i = 0; i < count; i++)
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
-}
-
+ // set up for the blit, using hard-coded parameters (no priority, etc)
+ blit_parameters blit;
+ configure_blit_parameters(blit, dest.cliprect(), TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0, 0xff);
-/*-------------------------------------------------
- scanline_draw_masked_null - draw to a NULL
- bitmap using a mask, setting priority only
--------------------------------------------------*/
+ // compute the effective scroll positions
+ scrollx = m_width - scrollx % m_width;
+ scrolly = m_height - scrolly % m_height;
-inline void scanline_draw_masked_null(const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode)
-{
- int i;
+ // flush the dirty state to all tiles as appropriate
+ realize_all_dirty_tiles();
- /* skip entirely if not changing priority */
- if (pcode != 0xff00)
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
+ // iterate to handle wraparound
+ for (int ypos = scrolly - m_height; ypos <= blit.cliprect.max_y; ypos += m_height)
+ for (int xpos = scrollx - m_width; xpos <= blit.cliprect.max_x; xpos += m_width)
+ draw_instance(dest, blit, xpos, ypos);
}
-/*-------------------------------------------------
- scanline_draw_opaque_ind16 - draw to a 16bpp
- indexed bitmap
--------------------------------------------------*/
-
-inline void scanline_draw_opaque_ind16(UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode)
-{
- int pal = pcode >> 16;
- int i;
-
- /* special case for no palette offset */
- if (pal == 0)
- {
- memcpy(dest, source, count * 2);
+//**************************************************************************
+// TILEMAP MANAGER
+//**************************************************************************
- /* priority if necessary */
- if (pcode != 0xff00)
- {
- for (i = 0; i < count; i++)
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
+//-------------------------------------------------
+// tilemap_manager - constructor
+//-------------------------------------------------
- /* priority case */
- else if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- {
- dest[i] = source[i] + pal;
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- dest[i] = source[i] + pal;
- }
-}
-
-
-/*-------------------------------------------------
- scanline_draw_masked_ind16 - draw to a 16bpp
- indexed bitmap using a mask
--------------------------------------------------*/
-
-inline void scanline_draw_masked_ind16(UINT16 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode)
+tilemap_manager::tilemap_manager(running_machine &machine)
+ : m_machine(machine),
+ m_instance(0)
{
- int pal = pcode >> 16;
- int i;
-
- /* priority case */
- if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- {
- dest[i] = source[i] + pal;
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- dest[i] = source[i] + pal;
- }
+ if (machine.primary_screen == NULL || machine.primary_screen->width() == 0)
+ return;
+ machine.primary_screen->register_screen_bitmap(machine.priority_bitmap);
}
+//-------------------------------------------------
+// set_flip_all - set a global flip for all the
+// tilemaps
+//-------------------------------------------------
-/*-------------------------------------------------
- scanline_draw_opaque_rgb32 - draw to a 32bpp
- RGB bitmap
--------------------------------------------------*/
-
-inline void scanline_draw_opaque_rgb32(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode)
+tilemap_t &tilemap_manager::create(tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, int tilewidth, int tileheight, int cols, int rows)
{
- const pen_t *clut = &pens[pcode >> 16];
- int i;
-
- /* priority case */
- if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- {
- dest[i] = clut[source[i]];
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- dest[i] = clut[source[i]];
- }
+ return m_tilemap_list.append(*auto_alloc(machine(), tilemap_t(*this, tile_get_info, mapper, tilewidth, tileheight, cols, rows)));
}
-
-/*-------------------------------------------------
- scanline_draw_masked_rgb32 - draw to a 32bpp
- RGB bitmap using a mask
--------------------------------------------------*/
-
-inline void scanline_draw_masked_rgb32(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode)
+tilemap_t &tilemap_manager::create(tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
{
- const pen_t *clut = &pens[pcode >> 16];
- int i;
-
- /* priority case */
- if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- {
- dest[i] = clut[source[i]];
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- dest[i] = clut[source[i]];
- }
+ return m_tilemap_list.append(*auto_alloc(machine(), tilemap_t(*this, tilemap_get_info_delegate(tile_get_info, "", &machine()), tilemap_mapper_delegate(mapper, "", &machine()), tilewidth, tileheight, cols, rows)));
}
-/*-------------------------------------------------
- scanline_draw_opaque_rgb32_alpha - draw to a
- 32bpp RGB bitmap with alpha blending
--------------------------------------------------*/
+//-------------------------------------------------
+// set_flip_all - set a global flip for all the
+// tilemaps
+//-------------------------------------------------
-inline void scanline_draw_opaque_rgb32_alpha(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha)
+void tilemap_manager::set_flip_all(UINT32 attributes)
{
- const pen_t *clut = &pens[pcode >> 16];
- int i;
-
- /* priority case */
- if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- {
- dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
- }
+ for (tilemap_t *tmap = m_tilemap_list.first(); tmap != NULL; tmap = tmap->next())
+ tmap->set_flip(attributes);
}
-/*-------------------------------------------------
- scanline_draw_masked_rgb32_alpha - draw to a
- 32bpp RGB bitmap using a mask and alpha
- blending
--------------------------------------------------*/
+//-------------------------------------------------
+// mark_all_dirty - mark all the tiles in all the
+// tilemaps dirty
+//-------------------------------------------------
-inline void scanline_draw_masked_rgb32_alpha(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha)
+void tilemap_manager::mark_all_dirty()
{
- const pen_t *clut = &pens[pcode >> 16];
- int i;
-
- /* priority case */
- if ((pcode & 0xffff) != 0xff00)
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- {
- dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
- pri[i] = (pri[i] & (pcode >> 8)) | pcode;
- }
- }
-
- /* no priority case */
- else
- {
- for (i = 0; i < count; i++)
- if ((maskptr[i] & mask) == value)
- dest[i] = alpha_blend_r32(dest[i], clut[source[i]], alpha);
- }
+ for (tilemap_t *tmap = m_tilemap_list.first(); tmap != NULL; tmap = tmap->next())
+ tmap->mark_all_dirty();
}
diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h
index 6bf01238ab2..05c4d102108 100644
--- a/src/emu/tilemap.h
+++ b/src/emu/tilemap.h
@@ -4,8 +4,36 @@
Generic tilemap management system.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
****************************************************************************
@@ -302,258 +330,492 @@
#define __TILEMAP_H__
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/* maximum number of groups */
+// maximum number of groups
#define TILEMAP_NUM_GROUPS 256
-/* these flags control tilemap_draw() behavior */
-#define TILEMAP_DRAW_CATEGORY_MASK 0x0f /* specify the category to draw */
-#define TILEMAP_DRAW_CATEGORY(x) (x) /* specify category to draw */
-#define TILEMAP_DRAW_LAYER0 0x10 /* draw layer 0 */
-#define TILEMAP_DRAW_LAYER1 0x20 /* draw layer 1 */
-#define TILEMAP_DRAW_LAYER2 0x40 /* draw layer 2 */
-#define TILEMAP_DRAW_OPAQUE 0x80 /* draw everything, even transparent stuff */
-#define TILEMAP_DRAW_ALPHA_FLAG 0x100 /* draw with alpha blending (in the upper 8 bits) */
-#define TILEMAP_DRAW_ALPHA(x) (TILEMAP_DRAW_ALPHA_FLAG | (rgb_clamp(x) << 24))
-#define TILEMAP_DRAW_ALL_CATEGORIES 0x200 /* draw all categories */
-
-
-/* per-pixel flags in the transparency_bitmap */
-#define TILEMAP_PIXEL_CATEGORY_MASK 0x0f /* category is stored in the low 4 bits */
-#define TILEMAP_PIXEL_TRANSPARENT 0x00 /* transparent if in none of the layers below */
-#define TILEMAP_PIXEL_LAYER0 0x10 /* pixel is opaque in layer 0 */
-#define TILEMAP_PIXEL_LAYER1 0x20 /* pixel is opaque in layer 1 */
-#define TILEMAP_PIXEL_LAYER2 0x40 /* pixel is opaque in layer 2 */
+// these flags control tilemap_draw() behavior
+const UINT32 TILEMAP_DRAW_CATEGORY_MASK = 0x0f; // specify the category to draw
+const UINT32 TILEMAP_DRAW_LAYER0 = 0x10; // draw layer 0
+const UINT32 TILEMAP_DRAW_LAYER1 = 0x20; // draw layer 1
+const UINT32 TILEMAP_DRAW_LAYER2 = 0x40; // draw layer 2
+const UINT32 TILEMAP_DRAW_OPAQUE = 0x80; // draw everything, even transparent stuff
+const UINT32 TILEMAP_DRAW_ALPHA_FLAG = 0x100; // draw with alpha blending (in the upper 8 bits)
+const UINT32 TILEMAP_DRAW_ALL_CATEGORIES = 0x200; // draw all categories
+// per-pixel flags in the transparency_bitmap
+const UINT8 TILEMAP_PIXEL_CATEGORY_MASK = 0x0f; // category is stored in the low 4 bits
+const UINT8 TILEMAP_PIXEL_TRANSPARENT = 0x00; // transparent if in none of the layers below
+const UINT8 TILEMAP_PIXEL_LAYER0 = 0x10; // pixel is opaque in layer 0
+const UINT8 TILEMAP_PIXEL_LAYER1 = 0x20; // pixel is opaque in layer 1
+const UINT8 TILEMAP_PIXEL_LAYER2 = 0x40; // pixel is opaque in layer 2
-/* per-tile flags, set by get_tile_info callback */
-#define TILE_FLIPX 0x01 /* draw this tile horizontally flipped */
-#define TILE_FLIPY 0x02 /* draw this tile vertically flipped */
-#define TILE_4BPP 0x04 /* tile data is packed 4bpp */
-#define TILE_FORCE_LAYER0 TILEMAP_PIXEL_LAYER0 /* force all pixels to be layer 0 (no transparency) */
-#define TILE_FORCE_LAYER1 TILEMAP_PIXEL_LAYER1 /* force all pixels to be layer 1 (no transparency) */
-#define TILE_FORCE_LAYER2 TILEMAP_PIXEL_LAYER2 /* force all pixels to be layer 2 (no transparency) */
+// per-tile flags, set by get_tile_info callback
+const UINT8 TILE_FLIPX = 0x01; // draw this tile horizontally flipped
+const UINT8 TILE_FLIPY = 0x02; // draw this tile vertically flipped
+const UINT8 TILE_4BPP = 0x04; // tile data is packed 4bpp
+const UINT8 TILE_FORCE_LAYER0 = TILEMAP_PIXEL_LAYER0; // force all pixels to be layer 0 (no transparency)
+const UINT8 TILE_FORCE_LAYER1 = TILEMAP_PIXEL_LAYER1; // force all pixels to be layer 1 (no transparency)
+const UINT8 TILE_FORCE_LAYER2 = TILEMAP_PIXEL_LAYER2; // force all pixels to be layer 2 (no transparency)
+// tilemap global flags, used by tilemap_set_flip()
+const UINT32 TILEMAP_FLIPX = TILE_FLIPX; // draw the tilemap horizontally flipped
+const UINT32 TILEMAP_FLIPY = TILE_FLIPY; // draw the tilemap vertically flipped
-/* tilemap global flags, used by tilemap_set_flip() */
-#define TILEMAP_FLIPX TILE_FLIPX /* draw the tilemap horizontally flipped */
-#define TILEMAP_FLIPY TILE_FLIPY /* draw the tilemap vertically flipped */
+// set this value for a scroll row/column to fully disable it
+const UINT32 TILE_LINE_DISABLED = 0x80000000;
-/* set this value for a scroll row/column to fully disable it */
-#define TILE_LINE_DISABLED 0x80000000
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+// forward declarations
+class tilemap_t;
+class tilemap_manager;
-/***************************************************************************
- MACROS
-***************************************************************************/
-/* function definition for a get info callback */
-#define TILE_GET_INFO(_name) void _name(running_machine &machine, tile_data *tileinfo, tilemap_memory_index tile_index, void *param)
-#define TILE_GET_INFO_DEVICE(_name) void _name(device_t *device, tile_data *tileinfo, tilemap_memory_index tile_index, void *param)
+// global types
+typedef UINT32 tilemap_memory_index;
-/* function definition for a logical-to-memory mapper */
-#define TILEMAP_MAPPER(_name) tilemap_memory_index _name(UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows)
-/* useful macro inside of a TILE_GET_INFO callback to set tile information */
-#define SET_TILE_INFO(GFX,CODE,COLOR,FLAGS) tileinfo_set(machine, tileinfo, GFX, CODE, COLOR, FLAGS)
-#define SET_TILE_INFO_DEVICE(GFX,CODE,COLOR,FLAGS) tileinfo_set(device->machine(), tileinfo, GFX, CODE, COLOR, FLAGS)
+// tile_data is filled in by the get_tile_info callback
+struct tile_data
+{
+ const UINT8 * pen_data; // required
+ const UINT8 * mask_data; // required
+ pen_t palette_base; // defaults to 0
+ UINT8 category; // defaults to 0; range from 0..15
+ UINT8 group; // defaults to 0; range from 0..TILEMAP_NUM_GROUPS
+ UINT8 flags; // defaults to 0; one or more of TILE_* flags above
+ UINT8 pen_mask; // defaults to 0xff; mask to apply to pen_data while rendering the tile
+ UINT8 gfxnum; // defaults to 0xff; specify index of machine.gfx for auto-invalidation on dirty
+
+ void set(running_machine &machine, int _gfxnum, int rawcode, int rawcolor, int _flags)
+ {
+ const gfx_element *gfx = machine.gfx[_gfxnum];
+ int code = rawcode % gfx->total_elements;
+ pen_data = gfx_element_get_data(gfx, code);
+ palette_base = gfx->color_base + gfx->color_granularity * rawcolor;
+ flags = _flags;
+ if (gfx->flags & GFX_ELEMENT_PACKED)
+ flags |= TILE_4BPP;
+ gfxnum = _gfxnum;
+ }
+};
-/* Macros for setting tile attributes in the TILE_GET_INFO callback: */
-/* TILE_FLIP_YX assumes that flipy is in bit 1 and flipx is in bit 0 */
-/* TILE_FLIP_XY assumes that flipy is in bit 0 and flipx is in bit 1 */
-#define TILE_FLIPYX(YX) ((YX) & 3)
-#define TILE_FLIPXY(XY) ((((XY) & 2) >> 1) | (((XY) & 1) << 1))
+// modern delegates
+typedef delegate<void (tile_data *, tilemap_memory_index, void *)> tilemap_get_info_delegate;
+typedef delegate<tilemap_memory_index (UINT32, UINT32, UINT32, UINT32)> tilemap_mapper_delegate;
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+// legacy callbacks
+typedef void (*tile_get_info_func)(running_machine &machine, tile_data *tileinfo, tilemap_memory_index tile_index, void *param);
+typedef void (*tile_get_info_device_func)(device_t *device, tile_data *tileinfo, tilemap_memory_index tile_index, void *param);
+typedef tilemap_memory_index (*tilemap_mapper_func)(running_machine &machine, UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows);
-/* memory indexes are unsigned integers */
-typedef UINT32 tilemap_memory_index;
-/* opaque tilemap definition */
-class tilemap_t;
+// core tilemap structure
+class tilemap_t
+{
+ DISABLE_COPYING(tilemap_t);
+
+ friend class tilemap_manager;
+ friend class simple_list<tilemap_t>;
+ friend resource_pool_object<tilemap_t>::~resource_pool_object();
+
+ // logical index
+ typedef UINT32 logical_index;
+
+ // internal usage to mark tiles dirty
+ static const UINT8 TILE_FLAG_DIRTY = 0xff;
+
+ // invalid logical index
+ static const logical_index INVALID_LOGICAL_INDEX = (logical_index)~0;
+
+ // maximum index in each array
+ static const int MAX_PEN_TO_FLAGS = 256;
+
+ // tilemap_manager controlls our allocations
+ tilemap_t(tilemap_manager &manager, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, int tilewidth, int tileheight, int cols, int rows);
+ ~tilemap_t();
+
+public:
+ // getters
+ running_machine &machine() const;
+ tilemap_t *next() const { return m_next; }
+ UINT32 width() const { return m_width; }
+ UINT32 height() const { return m_height; }
+ bool enabled() const { return m_enable; }
+ int scrolldx() const { return (m_attributes & TILEMAP_FLIPX) ? m_dx_flipped : m_dx; }
+ int scrolldy() const { return (m_attributes & TILEMAP_FLIPY) ? m_dy_flipped : m_dy; }
+ int scrollx(int which = 0) const { return (which < m_scrollrows) ? m_rowscroll[which] : 0; }
+ int scrolly(int which = 0) const { return (which < m_scrollcols) ? m_colscroll[which] : 0; }
+ bitmap_ind16 &pixmap() { pixmap_update(); return m_pixmap; }
+ bitmap_ind8 &flagsmap() { pixmap_update(); return m_flagsmap; }
+ UINT8 *tile_flags() { pixmap_update(); return m_tileflags; }
+ tilemap_memory_index memory_index(UINT32 col, UINT32 row) { return m_mapper(col, row, m_cols, m_rows); }
+
+ // setters
+ void set_user_data(void *user_data) { m_user_data = user_data; }
+ void set_palette_offset(UINT32 offset) { m_palette_offset = offset; }
+ void set_enable(bool enable) { m_enable = enable; }
+ 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; }
+ void set_scrollx(int which, int value) { if (which < m_scrollrows) m_rowscroll[which] = value; }
+ void set_scrolly(int which, int value) { if (which < m_scrollcols) m_colscroll[which] = value; }
+ void set_scrollx(int value) { set_scrollx(0, value); }
+ void set_scrolly(int value) { set_scrolly(0, value); }
+ void set_scroll_rows(UINT32 scroll_rows) { assert(scroll_rows <= m_height); m_scrollrows = scroll_rows; }
+ void set_scroll_cols(UINT32 scroll_cols) { assert(scroll_cols <= m_width); m_scrollcols = scroll_cols; }
+ void set_flip(UINT32 attributes) { if (m_attributes != attributes) { m_attributes = attributes; mappings_update(); } }
+
+ // dirtying
+ void mark_tile_dirty(tilemap_memory_index memindex);
+ void mark_all_dirty() { m_all_tiles_dirty = true; m_all_tiles_clean = false; }
+
+ // pen mapping
+ void map_pens_to_layer(int group, pen_t pen, pen_t mask, UINT8 layermask);
+ void map_pen_to_layer(int group, pen_t pen, UINT8 layermask) { map_pens_to_layer(group, pen, ~0, layermask); }
+ void set_transparent_pen(pen_t pen);
+ void set_transmask(int group, UINT32 fgmask, UINT32 bgmask);
+
+ // drawing
+ void draw(bitmap_ind16 &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask = 0xff);
+ void draw(bitmap_rgb32 &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask = 0xff);
+ void draw_roz(bitmap_ind16 &dest, const rectangle &cliprect, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask = 0xff);
+ void draw_roz(bitmap_rgb32 &dest, const rectangle &cliprect, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask = 0xff);
+ void draw_debug(bitmap_rgb32 &dest, UINT32 scrollx, UINT32 scrolly);
+
+private:
+ // internal set of transparency states for rendering
+ enum trans_t
+ {
+ WHOLLY_TRANSPARENT,
+ WHOLLY_OPAQUE,
+ MASKED
+ };
+
+ // blitting parameters for rendering
+ struct blit_parameters
+ {
+ rectangle cliprect;
+ UINT32 tilemap_priority_code;
+ UINT8 mask;
+ UINT8 value;
+ UINT8 alpha;
+ };
+
+ // inline helpers
+ INT32 effective_rowscroll(int index, UINT32 screen_width);
+ INT32 effective_colscroll(int index, UINT32 screen_height);
+ bool gfx_elements_changed();
+
+ // inline scanline rasterizers
+ void scanline_draw_opaque_null(int count, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_masked_null(const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_opaque_ind16(UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_masked_ind16(UINT16 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_opaque_rgb32(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_masked_rgb32(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode);
+ void scanline_draw_opaque_rgb32_alpha(UINT32 *dest, const UINT16 *source, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
+ void scanline_draw_masked_rgb32_alpha(UINT32 *dest, const UINT16 *source, const UINT8 *maskptr, int mask, int value, int count, const pen_t *pens, UINT8 *pri, UINT32 pcode, UINT8 alpha);
+
+ // internal helpers
+ void postload();
+ void mappings_create();
+ void mappings_update();
+ void realize_all_dirty_tiles();
+
+ // internal drawing
+ void pixmap_update();
+ void tile_update(logical_index logindex, UINT32 col, UINT32 row);
+ UINT8 tile_draw(const UINT8 *pendata, UINT32 x0, UINT32 y0, UINT32 palette_base, UINT8 category, UINT8 group, UINT8 flags, UINT8 pen_mask);
+ UINT8 tile_apply_bitmask(const UINT8 *maskdata, UINT32 x0, UINT32 y0, UINT8 category, UINT8 flags);
+ void configure_blit_parameters(blit_parameters &blit, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask);
+ template<class _BitmapClass> void draw_common(_BitmapClass &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask);
+ template<class _BitmapClass> void draw_roz_common(_BitmapClass &dest, const rectangle &cliprect, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, bool wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask);
+ template<class _BitmapClass> void draw_instance(_BitmapClass &dest, const blit_parameters &blit, int xpos, int ypos);
+ template<class _BitmapClass> void draw_roz_core(_BitmapClass &destbitmap, const blit_parameters &blit, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, bool wraparound);
+
+ // basic tilemap metrics
+ tilemap_t * m_next; // pointer to next tilemap
+ UINT32 m_rows; // number of tile rows
+ UINT32 m_cols; // number of tile columns
+ UINT32 m_tilewidth; // width of a single tile in pixels
+ UINT32 m_tileheight; // height of a single tile in pixels
+ UINT32 m_width; // width of the full tilemap in pixels
+ UINT32 m_height; // height of the full tilemap in pixels
+
+ // logical <-> memory mappings
+ tilemap_mapper_delegate m_mapper; // callback to map a row/column to a memory index
+ logical_index * m_memory_to_logical; // map from memory index to logical index
+ logical_index m_max_logical_index; // maximum valid logical index
+ tilemap_memory_index * m_logical_to_memory; // map from logical index to memory index
+ tilemap_memory_index m_max_memory_index; // maximum valid memory index
+
+ // callback to interpret video RAM for the tilemap
+ tilemap_get_info_delegate m_tile_get_info; // callback to get information about a tile
+ tile_data m_tileinfo; // structure to hold the data for a tile
+ void * m_user_data; // user data value passed to the callback
+
+ // global tilemap states
+ bool m_enable; // true if we are enabled
+ UINT8 m_attributes; // global attributes (flipx/y)
+ bool m_all_tiles_dirty; // true if all tiles are dirty
+ bool m_all_tiles_clean; // true if all tiles are clean
+ UINT32 m_palette_offset; // palette offset
+ UINT32 m_pen_data_offset; // pen data offset
+ UINT32 m_gfx_used; // bitmask of gfx items used
+ UINT32 m_gfx_dirtyseq[MAX_GFX_ELEMENTS]; // dirtyseq values from last check
+
+ // scroll information
+ UINT32 m_scrollrows; // number of independently scrolled rows
+ UINT32 m_scrollcols; // number of independently scrolled colums
+ INT32 * m_rowscroll; // array of rowscroll values
+ INT32 * m_colscroll; // array of colscroll values
+ INT32 m_dx; // global horizontal scroll offset
+ INT32 m_dx_flipped; // global horizontal scroll offset when flipped
+ INT32 m_dy; // global vertical scroll offset
+ INT32 m_dy_flipped; // global vertical scroll offset when flipped
+
+ // pixel data
+ bitmap_ind16 m_pixmap; // cached pixel data
+
+ // transparency mapping
+ bitmap_ind8 m_flagsmap; // per-pixel flags
+ UINT8 * m_tileflags; // per-tile flags
+ UINT8 m_pen_to_flags[MAX_PEN_TO_FLAGS * TILEMAP_NUM_GROUPS]; // mapping of pens to flags
+
+private:
+ tilemap_manager & m_manager; // reference to the owning manager
+};
-/* tile_data is filled in by the get_tile_info callback */
-typedef struct _tile_data tile_data;
-struct _tile_data
+// tilemap manager
+class tilemap_manager
{
- const UINT8 * pen_data; /* required */
- const UINT8 * mask_data; /* required */
- pen_t palette_base; /* defaults to 0 */
- UINT8 category; /* defaults to 0; range from 0..15 */
- UINT8 group; /* defaults to 0; range from 0..TILEMAP_NUM_GROUPS */
- UINT8 flags; /* defaults to 0; one or more of TILE_* flags above */
- UINT8 pen_mask; /* defaults to 0xff; mask to apply to pen_data while rendering the tile */
- UINT8 gfxnum; /* defaults to 0xff; specify index of machine.gfx for auto-invalidation on dirty */
+ friend class tilemap_t;
+
+public:
+ // construction/destuction
+ tilemap_manager(running_machine &machine);
+
+ // getters
+ running_machine &machine() const { return m_machine; }
+
+ // tilemap creation
+ tilemap_t &create(tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, int tilewidth, int tileheight, int cols, int rows);
+ tilemap_t &create(tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows);
+
+ // tilemap list information
+ tilemap_t *find(int index) { return m_tilemap_list.find(index); }
+ int count() const { return m_tilemap_list.count(); }
+
+ // global operations on all tilemaps
+ void mark_all_dirty();
+ void set_flip_all(UINT32 attributes);
+
+private:
+ // allocate an instance index
+ int alloc_instance() { return ++m_instance; }
+
+ // internal state
+ running_machine & m_machine;
+ simple_list<tilemap_t> m_tilemap_list;
+ int m_instance;
};
-/* callback function to get info about a tile */
-typedef void (*tile_get_info_func)(running_machine &machine, tile_data *tileinfo, tilemap_memory_index tile_index, void *param);
-typedef void (*tile_get_info_device_func)(device_t *device, tile_data *tileinfo, tilemap_memory_index tile_index, void *param);
-/* callback function to map a column,row pair to a memory index */
-typedef tilemap_memory_index (*tilemap_mapper_func)(UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows);
+//**************************************************************************
+// MACROS
+//**************************************************************************
+// macros to help form flags for tilemap_draw
+#define TILEMAP_DRAW_CATEGORY(x) (x) // specify category to draw
+#define TILEMAP_DRAW_ALPHA(x) (TILEMAP_DRAW_ALPHA_FLAG | (rgb_clamp(x) << 24))
+// function definition for a get info callback
+#define TILE_GET_INFO(_name) void _name(running_machine &machine, tile_data *tileinfo, tilemap_memory_index tile_index, void *param)
+#define TILE_GET_INFO_DEVICE(_name) void _name(device_t *device, tile_data *tileinfo, tilemap_memory_index tile_index, void *param)
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
+// function definition for a logical-to-memory mapper
+#define TILEMAP_MAPPER(_name) tilemap_memory_index _name(running_machine &machine, UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows)
+
+// useful macro inside of a TILE_GET_INFO callback to set tile information
+#define SET_TILE_INFO(GFX,CODE,COLOR,FLAGS) tileinfo_set(machine, tileinfo, GFX, CODE, COLOR, FLAGS)
+#define SET_TILE_INFO_DEVICE(GFX,CODE,COLOR,FLAGS) tileinfo_set(device->machine(), tileinfo, GFX, CODE, COLOR, FLAGS)
+// Macros for setting tile attributes in the TILE_GET_INFO callback:
+// TILE_FLIP_YX assumes that flipy is in bit 1 and flipx is in bit 0
+// TILE_FLIP_XY assumes that flipy is in bit 0 and flipx is in bit 1
+#define TILE_FLIPYX(YX) ((YX) & 3)
+#define TILE_FLIPXY(XY) ((((XY) & 2) >> 1) | (((XY) & 1) << 1))
-/* ----- system-wide management ----- */
-/* initialize the tilemap system -- not for use by drivers */
-void tilemap_init(running_machine &machine);
+//**************************************************************************
+// FUNCTION PROTOTYPES
+//**************************************************************************
-/* ----- tilemap creation and configuration ----- */
+// ----- tilemap creation and configuration -----
-/* create a new tilemap; note that tilemaps are tracked by the core so there is no dispose */
-tilemap_t *tilemap_create(running_machine &machine, tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows);
+// create a new tilemap; note that tilemaps are tracked by the core so there is no dispose
+inline tilemap_t *tilemap_create(running_machine &machine, tile_get_info_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
+{ return &machine.tilemap().create(tilemap_get_info_delegate(tile_get_info, "", &machine), tilemap_mapper_delegate(mapper, "", &machine), tilewidth, tileheight, cols, rows); }
-/* create a new tilemap that is owned by a device */
-tilemap_t *tilemap_create_device(device_t *device, tile_get_info_device_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows);
+// create a new tilemap that is owned by a device
+inline tilemap_t *tilemap_create_device(device_t *device, tile_get_info_device_func tile_get_info, tilemap_mapper_func mapper, int tilewidth, int tileheight, int cols, int rows)
+{ return &device->machine().tilemap().create(tilemap_get_info_delegate(tile_get_info, "", device), tilemap_mapper_delegate(mapper, "", &device->machine()), tilewidth, tileheight, cols, rows); }
-/* specify a parameter to be passed into the tile_get_info callback */
-void tilemap_set_user_data(tilemap_t *tmap, void *user_data);
+// specify a parameter to be passed into the tile_get_info callback
+inline void tilemap_set_user_data(tilemap_t *tmap, void *user_data)
+{ tmap->set_user_data(user_data); }
-/* specify an offset to be added to each pixel before looking up the palette.
- * The offset only applies at final rendering time (e.g., tilemap_draw())
- * It does not apply to the cached pixmap, which is provided by tilemap_get_pixmap().
- */
-void tilemap_set_palette_offset(tilemap_t *tmap, UINT32 offset);
+// specify an offset to be added to each pixel before looking up the palette.
+inline void tilemap_set_palette_offset(tilemap_t *tmap, UINT32 offset)
+{ tmap->set_palette_offset(offset); }
-/* set an enable flag for the tilemap; if 0, requests to draw the tilemap are ignored */
-void tilemap_set_enable(tilemap_t *tmap, int enable);
+// set an enable flag for the tilemap; if 0, requests to draw the tilemap are ignored
+inline void tilemap_set_enable(tilemap_t *tmap, int enable)
+{ tmap->set_enable(enable); }
-/* return enable flag for the tilemap */
-int tilemap_get_enable(tilemap_t *tmap);
+// return enable flag for the tilemap
+inline int tilemap_get_enable(tilemap_t *tmap)
+{ return tmap->enabled(); }
-/* set a global flip for the tilemap */
-void tilemap_set_flip(tilemap_t *tmap, UINT32 attributes);
+// set a global flip for the tilemap
+inline void tilemap_set_flip(tilemap_t *tmap, UINT32 attributes)
+{ tmap->set_flip(attributes); }
-/* set a global flip for all tilemaps */
-void tilemap_set_flip_all(running_machine &machine, UINT32 attributes);
+// set a global flip for all tilemaps
+inline void tilemap_set_flip_all(running_machine &machine, UINT32 attributes)
+{ machine.tilemap().set_flip_all(attributes); }
-/* ----- dirty tile marking ----- */
+// ----- dirty tile marking -----
-/* mark a single tile dirty based on its memory index */
-void tilemap_mark_tile_dirty(tilemap_t *tmap, tilemap_memory_index memory_index);
+// mark a single tile dirty based on its memory index
+inline void tilemap_mark_tile_dirty(tilemap_t *tmap, tilemap_memory_index memory_index)
+{ tmap->mark_tile_dirty(memory_index); }
-/* mark all the tiles dirty in a tilemap */
-void tilemap_mark_all_tiles_dirty(tilemap_t *tmap);
+// mark all the tiles dirty in a tilemap
+inline void tilemap_mark_all_tiles_dirty(tilemap_t *tmap)
+{ tmap->mark_all_dirty(); }
-/* mark all the tiles dirty in all tilemaps */
-void tilemap_mark_all_tiles_dirty_all(running_machine &machine);
+// mark all the tiles dirty in all tilemaps
+inline void tilemap_mark_all_tiles_dirty_all(running_machine &machine)
+{ machine.tilemap().mark_all_dirty(); }
-/* ----- pen-to-layer mapping ----- */
+// ----- pen-to-layer mapping -----
-/* specify the mapping of one or more pens (where (<pen> & mask == pen) to a layer */
-void tilemap_map_pens_to_layer(tilemap_t *tmap, int group, pen_t pen, pen_t mask, UINT8 layermask);
+// specify the mapping of one or more pens (where (<pen> & mask == pen) to a layer
+inline void tilemap_map_pens_to_layer(tilemap_t *tmap, int group, pen_t pen, pen_t mask, UINT8 layermask)
+{ tmap->map_pens_to_layer(group, pen, mask, layermask); }
-/* set a single transparent pen into the tilemap, mapping all other pens to layer 0 */
-void tilemap_set_transparent_pen(tilemap_t *tmap, pen_t pen);
+// set a single transparent pen into the tilemap, mapping all other pens to layer 0
+inline void tilemap_set_transparent_pen(tilemap_t *tmap, pen_t pen)
+{ tmap->set_transparent_pen(pen); }
-/* set up the first 32 pens using a foreground (layer 0) mask and a background (layer 1) mask */
-void tilemap_set_transmask(tilemap_t *tmap, int group, UINT32 fgmask, UINT32 bgmask);
+// set up the first 32 pens using a foreground (layer 0) mask and a background (layer 1) mask
+inline void tilemap_set_transmask(tilemap_t *tmap, int group, UINT32 fgmask, UINT32 bgmask)
+{ tmap->set_transmask(group, fgmask, bgmask); }
-/* ----- tilemap scrolling ----- */
+// ----- tilemap scrolling -----
-/* specify the number of independently scrollable row units; each unit covers height/scroll_rows pixels */
-void tilemap_set_scroll_rows(tilemap_t *tmap, UINT32 scroll_rows);
+// specify the number of independently scrollable row units; each unit covers height/scroll_rows pixels
+inline void tilemap_set_scroll_rows(tilemap_t *tmap, UINT32 scroll_rows)
+{ tmap->set_scroll_rows(scroll_rows); }
-/* specify the number of independently scrollable column units; each unit covers width/scroll_cols pixels */
-void tilemap_set_scroll_cols(tilemap_t *tmap, UINT32 scroll_cols);
+// specify the number of independently scrollable column units; each unit covers width/scroll_cols pixels
+inline void tilemap_set_scroll_cols(tilemap_t *tmap, UINT32 scroll_cols)
+{ tmap->set_scroll_cols(scroll_cols); }
-/* specify global horizontal and vertical scroll offsets, for non-flipped and flipped cases */
-void tilemap_set_scrolldx(tilemap_t *tmap, int dx, int dx_if_flipped);
-void tilemap_set_scrolldy(tilemap_t *tmap, int dy, int dy_if_flipped);
+// specify global horizontal and vertical scroll offsets, for non-flipped and flipped cases
+inline void tilemap_set_scrolldx(tilemap_t *tmap, int dx, int dx_if_flipped)
+{ tmap->set_scrolldx(dx, dx_if_flipped); }
+inline void tilemap_set_scrolldy(tilemap_t *tmap, int dy, int dy_if_flipped)
+{ tmap->set_scrolldy(dy, dy_if_flipped); }
-/* return the global horizontal or vertical scroll offset, based on current flip state */
-int tilemap_get_scrolldx(tilemap_t *tmap);
-int tilemap_get_scrolldy(tilemap_t *tmap);
+// return the global horizontal or vertical scroll offset, based on current flip state
+inline int tilemap_get_scrolldx(tilemap_t *tmap)
+{ return tmap->scrolldx(); }
+inline int tilemap_get_scrolldy(tilemap_t *tmap)
+{ return tmap->scrolldy(); }
-/* specify the scroll value for a row/column unit */
-void tilemap_set_scrollx(tilemap_t *tmap, int row, int value);
-void tilemap_set_scrolly(tilemap_t *tmap, int col, int value);
+// specify the scroll value for a row/column unit
+inline void tilemap_set_scrollx(tilemap_t *tmap, int row, int value)
+{ tmap->set_scrollx(row, value); }
+inline void tilemap_set_scrolly(tilemap_t *tmap, int col, int value)
+{ tmap->set_scrolly(col, value); }
-/* return the scroll value for a row/column unit */
-int tilemap_get_scrollx(tilemap_t *tmap, int row);
-int tilemap_get_scrolly(tilemap_t *tmap, int col);
+// return the scroll value for a row/column unit
+inline int tilemap_get_scrollx(tilemap_t *tmap, int row)
+{ return tmap->scrollx(row); }
+inline int tilemap_get_scrolly(tilemap_t *tmap, int col)
+{ return tmap->scrolly(col); }
-/* ----- internal map access ----- */
+// ----- internal map access -----
-/* return a pointer to the (updated) internal pixmap for a tilemap */
-bitmap_ind16 &tilemap_get_pixmap(tilemap_t *tmap);
+// return a pointer to the (updated) internal pixmap for a tilemap
+inline bitmap_ind16 &tilemap_get_pixmap(tilemap_t *tmap)
+{ return tmap->pixmap(); }
-/* return a pointer to the (updated) internal flagsmap for a tilemap */
-bitmap_ind8 &tilemap_get_flagsmap(tilemap_t *tmap);
+// return a pointer to the (updated) internal flagsmap for a tilemap
+inline bitmap_ind8 &tilemap_get_flagsmap(tilemap_t *tmap)
+{ return tmap->flagsmap(); }
-/* return a pointer to the (updated) internal per-tile flags for a tilemap */
-UINT8 *tilemap_get_tile_flags(tilemap_t *tmap);
+// return a pointer to the (updated) internal per-tile flags for a tilemap
+inline UINT8 *tilemap_get_tile_flags(tilemap_t *tmap)
+{ return tmap->tile_flags(); }
-/* ----- tilemap rendering ----- */
+// ----- tilemap rendering -----
-/* draw a tilemap to the destination with clipping; pixels apply priority/priority_mask to the priority bitmap */
-void tilemap_draw_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask);
-void tilemap_draw_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask);
+// draw a tilemap to the destination with clipping; pixels apply priority/priority_mask to the priority bitmap
+inline void tilemap_draw_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ tmap->draw(dest, cliprect, flags, priority, priority_mask); }
+inline void tilemap_draw_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ tmap->draw(dest, cliprect, flags, priority, priority_mask); }
-/* draw a tilemap to the destination with clipping and arbitrary rotate/zoom; */
-/* pixels apply priority/priority_mask to the priority bitmap */
-void tilemap_draw_roz_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap,
+// draw a tilemap to the destination with clipping and arbitrary rotate/zoom;
+// pixels apply priority/priority_mask to the priority bitmap
+inline void tilemap_draw_roz_primask(bitmap_ind16 &dest, const rectangle &cliprect, tilemap_t *tmap,
UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
- int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask);
-void tilemap_draw_roz_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap,
+ int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ tmap->draw_roz(dest, cliprect, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
+inline void tilemap_draw_roz_primask(bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap,
UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
- int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask);
-
-
-
-/* ----- indexed tilemap handling ----- */
+ int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask)
+{ tmap->draw_roz(dest, cliprect, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, priority_mask); }
-/* return the number of tilemaps */
-int tilemap_count(running_machine &machine);
-/* return the size of an indexed tilemap */
-void tilemap_size_by_index(running_machine &machine, int number, UINT32 *width, UINT32 *height);
-/* render an indexed tilemap with fixed characteristics (no priority) */
-void tilemap_draw_by_index(running_machine &machine, bitmap_rgb32 &dest, int number, UINT32 scrollx, UINT32 scrolly);
+// ----- common logical-to-memory mappers -----
-
-
-/* ----- common logical-to-memory mappers ----- */
-
-/* scan in row-major order with optional flipping */
+// scan in row-major order with optional flipping
TILEMAP_MAPPER( tilemap_scan_rows );
TILEMAP_MAPPER( tilemap_scan_rows_flip_x );
TILEMAP_MAPPER( tilemap_scan_rows_flip_y );
TILEMAP_MAPPER( tilemap_scan_rows_flip_xy );
-/* scan in column-major order with optional flipping */
+// scan in column-major order with optional flipping
TILEMAP_MAPPER( tilemap_scan_cols );
TILEMAP_MAPPER( tilemap_scan_cols_flip_x );
TILEMAP_MAPPER( tilemap_scan_cols_flip_y );
@@ -561,9 +823,9 @@ TILEMAP_MAPPER( tilemap_scan_cols_flip_xy );
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
/*-------------------------------------------------
tileinfo_set - set the values of a tileinfo
@@ -571,16 +833,7 @@ TILEMAP_MAPPER( tilemap_scan_cols_flip_xy );
-------------------------------------------------*/
inline void tileinfo_set(running_machine &machine, tile_data *tileinfo, int gfxnum, int rawcode, int rawcolor, int flags)
-{
- const gfx_element *gfx = machine.gfx[gfxnum];
- int code = rawcode % gfx->total_elements;
- tileinfo->pen_data = gfx_element_get_data(gfx, code);
- tileinfo->palette_base = gfx->color_base + gfx->color_granularity * rawcolor;
- tileinfo->flags = flags;
- if (gfx->flags & GFX_ELEMENT_PACKED)
- tileinfo->flags |= TILE_4BPP;
- tileinfo->gfxnum = gfxnum;
-}
+{ tileinfo->set(machine, gfxnum, rawcode, rawcolor, flags); }
/*-------------------------------------------------
@@ -589,9 +842,7 @@ inline void tileinfo_set(running_machine &machine, tile_data *tileinfo, int gfxn
-------------------------------------------------*/
inline void tilemap_map_pen_to_layer(tilemap_t *tmap, int group, pen_t pen, UINT8 layermask)
-{
- tilemap_map_pens_to_layer(tmap, group, pen, ~0, layermask);
-}
+{ tmap->map_pen_to_layer(group, pen, layermask); }
/*-------------------------------------------------
@@ -601,9 +852,7 @@ inline void tilemap_map_pen_to_layer(tilemap_t *tmap, int group, pen_t pen, UINT
template<class _BitmapClass>
inline void tilemap_draw(_BitmapClass &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 flags, UINT8 priority)
-{
- tilemap_draw_primask(dest, cliprect, tmap, flags, priority, 0xff);
-}
+{ tmap->draw(dest, cliprect, flags, priority); }
/*-------------------------------------------------
@@ -615,10 +864,13 @@ template<class _BitmapClass>
inline void tilemap_draw_roz(_BitmapClass &dest, const rectangle &cliprect, tilemap_t *tmap,
UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy,
int wraparound, UINT32 flags, UINT8 priority)
+{ tmap->draw_roz(dest, cliprect, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority); }
+
+
+inline running_machine &tilemap_t::machine() const
{
- tilemap_draw_roz_primask(dest, cliprect, tmap, startx, starty, incxx, incxy, incyx, incyy, wraparound, flags, priority, 0xff);
+ return m_manager.machine();
}
-
-#endif /* __TILEMAP_H__ */
+#endif // __TILEMAP_H__
diff --git a/src/emu/uigfx.c b/src/emu/uigfx.c
index f1705ad960b..1717a9d137b 100644
--- a/src/emu/uigfx.c
+++ b/src/emu/uigfx.c
@@ -154,7 +154,7 @@ UINT32 ui_gfx_ui_handler(running_machine &machine, render_container *container,
ui_gfx_state *state = &ui_gfx;
/* if we have nothing, implicitly cancel */
- if (machine.total_colors() == 0 && machine.colortable == NULL && machine.gfx[0] == NULL && tilemap_count(machine) == 0)
+ if (machine.total_colors() == 0 && machine.colortable == NULL && machine.gfx[0] == NULL && machine.tilemap().count() == 0)
goto cancel;
/* if we're not paused, mark the bitmap dirty */
@@ -189,7 +189,7 @@ again:
case 2:
/* if we have tilemaps, display them */
- if (tilemap_count(machine) > 0)
+ if (machine.tilemap().count() > 0)
{
tilemap_handler(machine, container, state);
break;
@@ -854,7 +854,9 @@ static void tilemap_handler(running_machine &machine, render_container *containe
char title[100];
/* get the size of the tilemap itself */
- tilemap_size_by_index(machine, state->tilemap.which, &mapwidth, &mapheight);
+ tilemap_t *tilemap = machine.tilemap().find(state->tilemap.which);
+ mapwidth = tilemap->width();
+ mapheight = tilemap->height();
if (state->tilemap.rotate & ORIENTATION_SWAP_XY)
{ UINT32 temp = mapwidth; mapwidth = mapheight; mapheight = temp; }
@@ -906,7 +908,7 @@ static void tilemap_handler(running_machine &machine, render_container *containe
boxbounds.y1 = mapboxbounds.y1 + 0.5f * chheight;
/* figure out the title and expand the outer box to fit */
- sprintf(title, "TMAP %d/%d %dx%d OFFS %d,%d", state->tilemap.which, tilemap_count(machine) - 1, mapwidth, mapheight, state->tilemap.xoffs, state->tilemap.yoffs);
+ sprintf(title, "TMAP %d/%d %dx%d OFFS %d,%d", state->tilemap.which, machine.tilemap().count() - 1, mapwidth, mapheight, state->tilemap.xoffs, state->tilemap.yoffs);
titlewidth = ui_font->string_width(chheight, machine.render().ui_aspect(), title);
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
{
@@ -960,11 +962,13 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state *state, i
/* clamp within range */
if (state->tilemap.which < 0)
state->tilemap.which = 0;
- if (state->tilemap.which >= tilemap_count(machine))
- state->tilemap.which = tilemap_count(machine) - 1;
+ if (state->tilemap.which >= machine.tilemap().count())
+ state->tilemap.which = machine.tilemap().count() - 1;
/* cache some info in locals */
- tilemap_size_by_index(machine, state->tilemap.which, &mapwidth, &mapheight);
+ tilemap_t *tilemap = machine.tilemap().find(state->tilemap.which);
+ mapwidth = tilemap->width();
+ mapheight = tilemap->height();
/* handle zoom (minus,plus) */
if (ui_input_pressed(machine, IPT_UI_ZOOM_OUT))
@@ -1053,7 +1057,8 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state *state,
/* handle the redraw */
if (state->bitmap_dirty)
{
- tilemap_draw_by_index(machine, *state->bitmap, state->tilemap.which, state->tilemap.xoffs, state->tilemap.yoffs);
+ tilemap_t *tilemap = machine.tilemap().find(state->tilemap.which);
+ tilemap->draw_debug(*state->bitmap, state->tilemap.xoffs, state->tilemap.yoffs);
/* reset the texture to force an update */
state->texture->set_bitmap(*state->bitmap, state->bitmap->cliprect(), TEXFORMAT_RGB32);
diff --git a/src/mame/video/jack.c b/src/mame/video/jack.c
index 0d79c31d06a..e5d3ed562a7 100644
--- a/src/mame/video/jack.c
+++ b/src/mame/video/jack.c
@@ -52,7 +52,7 @@ static TILE_GET_INFO( get_bg_tile_info )
SET_TILE_INFO(0, code, color, 0);
}
-static UINT32 tilemap_scan_cols_flipy( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
+static TILEMAP_MAPPER( tilemap_scan_cols_flipy )
{
/* logical (col,row) -> memory offset */
return (col * num_rows) + (num_rows - 1 - row);
diff --git a/src/mame/video/m10.c b/src/mame/video/m10.c
index 46564237940..32bc48ae7af 100644
--- a/src/mame/video/m10.c
+++ b/src/mame/video/m10.c
@@ -42,7 +42,7 @@ static const gfx_layout charlayout =
8*8 /* every char takes 8 consecutive bytes */
};
-static UINT32 tilemap_scan( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
+static TILEMAP_MAPPER( tilemap_scan )
{
return (31 - col) * 32 + row;
}
diff --git a/src/mame/video/m58.c b/src/mame/video/m58.c
index 1135c4a7e64..b74ef896c77 100644
--- a/src/mame/video/m58.c
+++ b/src/mame/video/m58.c
@@ -159,7 +159,7 @@ static TILE_GET_INFO( yard_get_bg_tile_info )
}
-static UINT32 yard_tilemap_scan_rows( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
+static TILEMAP_MAPPER( yard_tilemap_scan_rows )
{
/* logical (col,row) -> memory offset */
if (col >= 32)
diff --git a/src/mame/video/videopin.c b/src/mame/video/videopin.c
index 2e3714a7793..6591478fcc5 100644
--- a/src/mame/video/videopin.c
+++ b/src/mame/video/videopin.c
@@ -47,7 +47,7 @@ SCREEN_UPDATE_IND16( videopin )
{
for (col = 0; col < 48; col++)
{
- UINT32 offset = get_memory_offset(col, row, 48, 32);
+ UINT32 offset = state->m_bg_tilemap->memory_index(col, row);
if (state->m_video_ram[offset] & 0x80) /* ball bit found */
{