diff options
Diffstat (limited to 'src/devices/video/sprite.h')
-rw-r--r-- | src/devices/video/sprite.h | 80 |
1 files changed, 37 insertions, 43 deletions
diff --git a/src/devices/video/sprite.h b/src/devices/video/sprite.h index 2ef3234b9d9..3674ec343dd 100644 --- a/src/devices/video/sprite.h +++ b/src/devices/video/sprite.h @@ -11,23 +11,8 @@ #pragma once - -// ======================> sparse_dirty_rect - -// class representing a single dirty region -class sparse_dirty_rect : public rectangle -{ - friend class simple_list<sparse_dirty_rect>; - -public: - sparse_dirty_rect(): m_next(nullptr) { } - // getters - const sparse_dirty_rect *next() const { return m_next; } - -private: - // internal state - sparse_dirty_rect * m_next; -}; +#include <utility> +#include <vector> // ======================> sparse_dirty_bitmap @@ -49,16 +34,27 @@ public: void clean(int32_t left, int32_t right, int32_t top, int32_t bottom); void clean_all() { clean(0, m_width - 1, 0, m_height - 1); } - // convert to rect list - sparse_dirty_rect *first_dirty_rect() { rectangle fullrect(0, m_width - 1, 0, m_height - 1); return first_dirty_rect(fullrect); } - sparse_dirty_rect *first_dirty_rect(const rectangle &cliprect); + // operate on rect list + template <typename T> + void iterate_dirty_rects(T &&action) + { + iterate_dirty_rects(rectangle(0, m_width - 1, 0, m_height - 1), std::forward<T>(action)); + } + template <typename T> + void iterate_dirty_rects(const rectangle &cliprect, T &&action) + { + calculate_rect_list(cliprect); + for (const rectangle &rect : m_rect_list) + action(rect); + } // dynamic resizing void resize(int width, int height); private: - // invalidate cached rect list + // invalidate or update cached rect list void invalidate_rect_list() { m_rect_list_bounds.set(0, -1, 0, -1); } + void calculate_rect_list(const rectangle &cliprect); // internal state int m_width; @@ -66,14 +62,13 @@ private: int m_granularity; bitmap_ind8 m_bitmap; rectangle m_rect_list_bounds; - fixed_allocator<sparse_dirty_rect> m_rect_allocator; - simple_list<sparse_dirty_rect> m_rect_list; + std::vector<rectangle> m_rect_list; }; // ======================> sprite_device -template<typename _SpriteRAMType, class _BitmapType> +template<typename SpriteRAMType, class BitmapType> class sprite_device : public device_t { // constants @@ -96,16 +91,16 @@ public: // getters int32_t xorigin() const { return m_xorigin; } int32_t yorigin() const { return m_yorigin; } - _BitmapType &bitmap() { return m_bitmap; } - sparse_dirty_rect *first_dirty_rect() { return m_dirty.first_dirty_rect(); } - sparse_dirty_rect *first_dirty_rect(const rectangle &cliprect) { return m_dirty.first_dirty_rect(cliprect); } - _SpriteRAMType *spriteram() const { return m_spriteram; } + BitmapType &bitmap() { return m_bitmap; } + template <typename T> void iterate_dirty_rects(T &&action) { m_dirty.iterate_dirty_rects(std::forward<T>(action)); } + template <typename T> void iterate_dirty_rects(const rectangle &cliprect, T &&action) { m_dirty.iterate_dirty_rects(cliprect, std::forward<T>(action)); } + SpriteRAMType *spriteram() const { return m_spriteram; } uint32_t spriteram_bytes() const { return m_spriteram_bytes; } - uint32_t spriteram_elements() const { return m_spriteram_bytes / sizeof(_SpriteRAMType); } - _SpriteRAMType *buffer() { return &m_buffer[0]; } + uint32_t spriteram_elements() const { return m_spriteram_bytes / sizeof(SpriteRAMType); } + SpriteRAMType *buffer() { return &m_buffer[0]; } // configuration - void set_spriteram(_SpriteRAMType *base, uint32_t bytes) { assert(base != nullptr && bytes != 0); m_spriteram = base; m_spriteram_bytes = bytes; m_buffer.resize(m_spriteram_bytes / sizeof(_SpriteRAMType)); } + void set_spriteram(SpriteRAMType *base, uint32_t bytes) { assert(base != nullptr && bytes != 0); m_spriteram = base; m_spriteram_bytes = bytes; m_buffer.resize(m_spriteram_bytes / sizeof(SpriteRAMType)); } void set_origin(int32_t xorigin = 0, int32_t yorigin = 0) { m_xorigin = xorigin; m_yorigin = yorigin; } void set_xorigin(int32_t xorigin) { m_xorigin = xorigin; } void set_yorigin(int32_t yorigin) { m_yorigin = yorigin; } @@ -117,8 +112,7 @@ public: void clear() { clear(m_bitmap.cliprect()); } void clear(const rectangle &cliprect) { - for (const sparse_dirty_rect *rect = m_dirty.first_dirty_rect(cliprect); rect != nullptr; rect = rect->next()) - m_bitmap.fill(~0, *rect); + m_dirty.iterate_dirty_rects(cliprect, [this] (const rectangle &rect) { m_bitmap.fill(~0, rect); }); m_dirty.clean(cliprect); } @@ -146,7 +140,7 @@ public: clear(cliprect); // wrap the bitmap, adjusting for x/y origins - _BitmapType wrapped(&m_bitmap.pix(0) - m_xorigin - m_yorigin * m_bitmap.rowpixels(), m_xorigin + cliprect.right() + 1, m_yorigin + cliprect.bottom() + 1, m_bitmap.rowpixels()); + BitmapType wrapped(&m_bitmap.pix(0) - m_xorigin - m_yorigin * m_bitmap.rowpixels(), m_xorigin + cliprect.right() + 1, m_yorigin + cliprect.bottom() + 1, m_bitmap.rowpixels()); // compute adjusted cliprect in source space rectangle adjusted = cliprect; @@ -164,7 +158,7 @@ protected: memory_share *spriteram = owner()->memshare(tag()); if (spriteram != nullptr) { - set_spriteram(reinterpret_cast<_SpriteRAMType *>(spriteram->ptr()), spriteram->bytes()); + set_spriteram(reinterpret_cast<SpriteRAMType *>(spriteram->ptr()), spriteram->bytes()); // save states save_item(NAME(m_buffer)); @@ -172,7 +166,7 @@ protected: } // subclass overrides - virtual void draw(_BitmapType &bitmap, const rectangle &cliprect) = 0; + virtual void draw(BitmapType &bitmap, const rectangle &cliprect) = 0; // subclass helpers void mark_dirty(const rectangle &rect) { mark_dirty(rect.left(), rect.right(), rect.top(), rect.bottom()); } @@ -180,17 +174,17 @@ protected: private: // configuration - int32_t m_xorigin; // X origin for drawing - int32_t m_yorigin; // Y origin for drawing + int32_t m_xorigin; // X origin for drawing + int32_t m_yorigin; // Y origin for drawing // memory pointers and buffers - _SpriteRAMType * m_spriteram; // pointer to spriteram pointer - int32_t m_spriteram_bytes; // size of sprite RAM in bytes - std::vector<_SpriteRAMType> m_buffer; // buffered spriteram for those that use it + SpriteRAMType * m_spriteram; // pointer to spriteram pointer + int32_t m_spriteram_bytes; // size of sprite RAM in bytes + std::vector<SpriteRAMType> m_buffer; // buffered spriteram for those that use it // bitmaps - _BitmapType m_bitmap; // live bitmap - sparse_dirty_bitmap m_dirty; // dirty bitmap + BitmapType m_bitmap; // live bitmap + sparse_dirty_bitmap m_dirty; // dirty bitmap }; typedef sprite_device<uint8_t, bitmap_ind16> sprite8_device_ind16; |