summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2021-09-02 16:37:31 +0900
committer GitHub <noreply@github.com>2021-09-02 17:37:31 +1000
commitff099562655d1d98bbe98f110d3352f64d5a21f6 (patch)
tree23dbf4e498faeb13d9409f47ff73d7e85db9615c /src/mame/video
parent2c18661843fabe43131f03c14bf6ff4a3e175578 (diff)
video/toaplan_scu.cpp: Use single-pass priority drawing for sprites. (#8521)
* Use single pass pdrawgfx for sprite vs tilemap priority. * Use device-specific delegate for priority mask. * Use device_video_interface to find screen.
Diffstat (limited to 'src/mame/video')
-rw-r--r--src/mame/video/toaplan1.cpp35
-rw-r--r--src/mame/video/toaplan_scu.cpp62
-rw-r--r--src/mame/video/toaplan_scu.h15
-rw-r--r--src/mame/video/twincobr.cpp54
4 files changed, 84 insertions, 82 deletions
diff --git a/src/mame/video/toaplan1.cpp b/src/mame/video/toaplan1.cpp
index a3ce5ddc52e..47d00a00064 100644
--- a/src/mame/video/toaplan1.cpp
+++ b/src/mame/video/toaplan1.cpp
@@ -229,7 +229,6 @@ void toaplan1_state::register_common()
void toaplan1_rallybik_state::video_start()
{
- m_spritegen->alloc_sprite_bitmap(*m_screen);
m_spritegen->gfx(0)->set_colorbase(64*16);
create_tilemaps();
@@ -671,6 +670,18 @@ void toaplan1_state::log_vram()
Sprite Handlers
***************************************************************************/
+void toaplan1_rallybik_state::pri_cb(u8 priority, u32 &pri_mask)
+{
+ switch (priority)
+ {
+ case 0: pri_mask = GFX_PMASK_1|GFX_PMASK_2|GFX_PMASK_4|GFX_PMASK_8; break; // disable?
+ case 1: pri_mask = GFX_PMASK_2|GFX_PMASK_4|GFX_PMASK_8; break; // over tilemap priority ~0x4, under tilemap priority 0x5~
+ case 2: pri_mask = GFX_PMASK_4|GFX_PMASK_8; break; // over tilemap priority ~0x8, under tilemap priority 0x9~
+ case 3: pri_mask = GFX_PMASK_8; break; // over tilemap priority ~0xc, under tilemap priority 0xd~
+ }
+}
+
+
void toaplan1_state::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
u16 *source = (u16 *)m_buffered_spriteram.get();
@@ -744,26 +755,24 @@ u32 toaplan1_rallybik_state::screen_update(screen_device &screen, bitmap_rgb32 &
{
log_vram();
- m_spritegen->draw_sprites_to_tempbitmap(cliprect, m_buffered_spriteram.get(), m_spriteram.bytes());
+ screen.priority().fill(0, cliprect);
// first draw everything, including "disabled" tiles and priority 0
- m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 1);
// then draw the higher priority layers in order
for (int priority = 1; priority < 16; priority++)
{
- m_tilemap[3]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), 0);
- m_tilemap[2]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), 0);
- m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), 0);
- m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), 0);
-
- //if (pririoty==0x00) m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,0);
- if (priority==0x04) m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,1);
- if (priority==0x08) m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,2);
- if (priority==0x0c) m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,3);
-
+ // get priority mask
+ // value: 0x1 (tilemap priority 0x0~0x4), 0x2 (tilemap priority 0x5~0x8), 0x4 (tilemap priority 0x9~0xc), 0x8 (tilemap priority 0xd~)
+ int primask = 1 << (((priority - 1) >> 2));
+ m_tilemap[3]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), primask);
+ m_tilemap[2]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), primask);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), primask);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(priority), primask);
}
+ m_spritegen->draw_sprites(bitmap, cliprect, m_buffered_spriteram.get(), m_spriteram.bytes());
return 0;
}
diff --git a/src/mame/video/toaplan_scu.cpp b/src/mame/video/toaplan_scu.cpp
index a7bb72c6e3b..815e8fc99aa 100644
--- a/src/mame/video/toaplan_scu.cpp
+++ b/src/mame/video/toaplan_scu.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:Quench
/* Toaplan Sprite Controller 'SCU'
- used by video/twincobr.c (including wardner)
- and rallybik in toaplan1.c
+ used by video/twincobr.cpp (including wardner)
+ and rallybik in toaplan1.cpp
*/
@@ -32,31 +32,28 @@ GFXDECODE_END
toaplan_scu_device::toaplan_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, TOAPLAN_SCU, tag, owner, clock)
, device_gfx_interface(mconfig, *this, gfxinfo)
+ , device_video_interface(mconfig, *this)
+ , m_pri_cb(*this)
{
}
void toaplan_scu_device::device_start()
{
+ m_pri_cb.resolve();
}
void toaplan_scu_device::device_reset()
{
}
-void toaplan_scu_device::alloc_sprite_bitmap(screen_device &screen)
-{
- screen.register_screen_bitmap(m_temp_spritebitmap);
-}
-
/***************************************************************************
Sprite Handlers
***************************************************************************/
-void toaplan_scu_device::draw_sprites_to_tempbitmap(const rectangle &cliprect, u16* spriteram, u32 bytes)
+template<class BitmapClass>
+void toaplan_scu_device::draw_sprites_common(BitmapClass &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes)
{
- m_temp_spritebitmap.fill(0, cliprect);
-
- for (int offs = 0; offs < bytes / 2; offs += 4)
+ for (int offs = (bytes / 2) - 4; offs >= 0; offs -= 4)
{
const u16 attribute = spriteram[offs + 1];
const int priority = (attribute & 0x0c00) >> 10;
@@ -69,49 +66,34 @@ void toaplan_scu_device::draw_sprites_to_tempbitmap(const rectangle &cliprect, u
{
const u32 sprite = spriteram[offs] & 0x7ff;
u32 color = attribute & 0x3f;
- color |= priority << 6; // encode colour
+ u32 pri_mask = 0; // priority mask
+ if (!m_pri_cb.isnull())
+ m_pri_cb(priority, pri_mask);
int sx = spriteram[offs + 2] >> 7;
const int flipx = attribute & 0x100;
if (flipx) sx -= m_xoffs_flipped;
const int flipy = attribute & 0x200;
- gfx(0)->transpen_raw(m_temp_spritebitmap, cliprect,
+ gfx(0)->prio_transpen(bitmap, cliprect,
sprite,
- color << 4 /* << 4 because using _raw */ ,
+ color,
flipx, flipy,
- sx - m_xoffs, sy - 16, 0);
+ sx - m_xoffs, sy - 16, screen().priority(), pri_mask, 0);
}
}
-
}
-/***************************************************************************
- Draw the game screen in the given bitmap.
-***************************************************************************/
-
-void toaplan_scu_device::copy_sprites_from_tempbitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority)
+void toaplan_scu_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes)
{
- pen_t const *const pens = &palette().pen(gfx(0)->colorbase());
-
- for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
- {
- u16 const *const srcline = &m_temp_spritebitmap.pix(y);
- u32 *const dstline = &bitmap.pix(y);
+ draw_sprites_common(bitmap, cliprect, spriteram, bytes);
+}
- for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
- {
- const u16 pix = srcline[x];
-
- if ((pix >> (4 + 6)) == priority)
- {
- if (pix & 0xf)
- {
- dstline[x] = pens[pix & 0x3ff];
- }
- }
- }
- }
+void toaplan_scu_device::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes)
+{
+ draw_sprites_common(bitmap, cliprect, spriteram, bytes);
}
+
+
diff --git a/src/mame/video/toaplan_scu.h b/src/mame/video/toaplan_scu.h
index 4844f239af7..cbd9b0e9832 100644
--- a/src/mame/video/toaplan_scu.h
+++ b/src/mame/video/toaplan_scu.h
@@ -6,32 +6,35 @@
#pragma once
-
-class toaplan_scu_device : public device_t, public device_gfx_interface
+class toaplan_scu_device : public device_t, public device_gfx_interface, public device_video_interface
{
public:
toaplan_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ typedef device_delegate<void (u8 priority, u32 &pri_mask)> pri_cb_delegate;
+
// configuration
void set_xoffsets(int xoffs, int xoffs_flipped)
{
m_xoffs = xoffs;
m_xoffs_flipped = xoffs_flipped;
}
+ template <typename... T> void set_pri_callback(T &&... args) { m_pri_cb.set(std::forward<T>(args)...); }
- void draw_sprites_to_tempbitmap(const rectangle &cliprect, u16* spriteram, u32 bytes);
- void copy_sprites_from_tempbitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority);
- void alloc_sprite_bitmap(screen_device &screen);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes);
+ void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes);
protected:
virtual void device_start() override;
virtual void device_reset() override;
private:
+ template<class BitmapClass> void draw_sprites_common(BitmapClass &bitmap, const rectangle &cliprect, u16* spriteram, u32 bytes);
+
static const gfx_layout spritelayout;
DECLARE_GFXDECODE_MEMBER(gfxinfo);
- bitmap_ind16 m_temp_spritebitmap;
+ pri_cb_delegate m_pri_cb;
int m_xoffs;
int m_xoffs_flipped;
};
diff --git a/src/mame/video/twincobr.cpp b/src/mame/video/twincobr.cpp
index d6432cc3643..4159174a534 100644
--- a/src/mame/video/twincobr.cpp
+++ b/src/mame/video/twincobr.cpp
@@ -78,8 +78,6 @@ void twincobr_state::twincobr_create_tilemaps()
void twincobr_state::video_start()
{
- m_spritegen->alloc_sprite_bitmap(*m_screen);
-
/* the video RAM is accessed via ports, it's not memory mapped */
m_txvideoram_size = 0x0800;
m_bgvideoram_size = 0x2000; /* banked two times 0x1000 */
@@ -364,22 +362,21 @@ void twincobr_state::log_vram()
}
-u32 twincobr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+void twincobr_state::pri_cb(u8 priority, u32 &pri_mask)
{
- log_vram();
-
- u16 *buffered_spriteram16;
- u32 bytes;
- if (m_spriteram16 != nullptr)
- {
- buffered_spriteram16 = m_spriteram16->buffer();
- bytes = m_spriteram16->bytes();
- }
- else
+ switch (priority)
{
- buffered_spriteram16 = reinterpret_cast<u16 *>(m_spriteram8->buffer());
- bytes = m_spriteram8->bytes();
+ case 0: pri_mask = GFX_PMASK_1|GFX_PMASK_2|GFX_PMASK_4; break; // disable?
+ case 1: pri_mask = GFX_PMASK_2|GFX_PMASK_4; break; // over background, under foreground/text
+ case 2: pri_mask = GFX_PMASK_4; break; // over background/foreground, under text
+ case 3: pri_mask = 0; break; // over everything
}
+}
+
+
+u32 twincobr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ log_vram();
if (!m_display_on)
{
@@ -387,14 +384,25 @@ u32 twincobr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, c
}
else
{
- m_spritegen->draw_sprites_to_tempbitmap(cliprect, buffered_spriteram16, bytes);
-
- m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,0);
- m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,1);
- m_fg_tilemap->draw(screen, bitmap, cliprect, 0,0);
- m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,2);
- m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0);
- m_spritegen->copy_sprites_from_tempbitmap(bitmap,cliprect,3);
+ screen.priority().fill(0, cliprect);
+
+ u16 *buffered_spriteram16;
+ u32 bytes;
+ if (m_spriteram16 != nullptr)
+ {
+ buffered_spriteram16 = m_spriteram16->buffer();
+ bytes = m_spriteram16->bytes();
+ }
+ else
+ {
+ buffered_spriteram16 = reinterpret_cast<u16 *>(m_spriteram8->buffer());
+ bytes = m_spriteram8->bytes();
+ }
+
+ m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,1);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0,2);
+ m_tx_tilemap->draw(screen, bitmap, cliprect, 0,4);
+ m_spritegen->draw_sprites(bitmap, cliprect, buffered_spriteram16, bytes);
}
return 0;