From 3d6955e3d1b997014dc930607912b9516cb7ea6f Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 20 Nov 2023 01:39:14 +0900 Subject: seibu/dynduke_v.cpp: Use single-pass sprite drawing. (#11758) Manage sprite/tilemap priorities using priority masks. --- src/mame/seibu/dynduke.h | 20 +++++------ src/mame/seibu/dynduke_v.cpp | 79 +++++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/mame/seibu/dynduke.h b/src/mame/seibu/dynduke.h index e0cd9535a02..edb527dd3f4 100644 --- a/src/mame/seibu/dynduke.h +++ b/src/mame/seibu/dynduke.h @@ -49,14 +49,14 @@ private: tilemap_t *m_bg_layer = nullptr; tilemap_t *m_fg_layer = nullptr; tilemap_t *m_tx_layer = nullptr; - int m_back_bankbase = 0; - int m_fore_bankbase = 0; - int m_back_enable = 0; - int m_fore_enable = 0; - int m_sprite_enable = 0; - int m_txt_enable = 0; - int m_old_back = 0; - int m_old_fore = 0; + uint32_t m_back_bankbase = 0; + uint32_t m_fore_bankbase = 0; + bool m_back_enable = false; + bool m_fore_enable = false; + bool m_sprite_enable = false; + bool m_txt_enable = false; + uint32_t m_old_back = 0; + uint32_t m_old_fore = 0; void background_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void foreground_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); @@ -71,8 +71,8 @@ private: virtual void video_start() override; uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri); - void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri ); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, uint32_t pri_mask); void vblank_irq(int state); void master_map(address_map &map); diff --git a/src/mame/seibu/dynduke_v.cpp b/src/mame/seibu/dynduke_v.cpp index de460585157..81fd3589c35 100644 --- a/src/mame/seibu/dynduke_v.cpp +++ b/src/mame/seibu/dynduke_v.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "dynduke.h" +#include "screen.h" /******************************************************************************/ @@ -87,8 +88,8 @@ void dynduke_state::gfxbank_w(offs_t offset, uint16_t data, uint16_t mem_mask) { if (ACCESSING_BITS_0_7) { - if (data&0x01) m_back_bankbase=0x1000; else m_back_bankbase=0; - if (data&0x10) m_fore_bankbase=0x1000; else m_fore_bankbase=0; + m_back_bankbase = BIT(data, 0) ? 0x1000 : 0; + m_fore_bankbase = BIT(data, 4) ? 0x1000 : 0; if (m_back_bankbase!=m_old_back) m_bg_layer->mark_all_dirty(); @@ -114,53 +115,60 @@ void dynduke_state::control_w(offs_t offset, uint16_t data, uint16_t mem_mask) // bit 0x02 is used on the map screen (fore disable?) // bit 0x01 set when inserting coin.. bg disable? - if (data&0x1) m_back_enable = 0; else m_back_enable = 1; - if (data&0x2) m_fore_enable=0; else m_fore_enable=1; - if (data&0x4) m_txt_enable = 0; else m_txt_enable = 1; - if (data&0x8) m_sprite_enable=0; else m_sprite_enable=1; + m_back_enable = BIT(~data, 0); + m_fore_enable = BIT(~data, 1); + m_txt_enable = BIT(~data, 2); + m_sprite_enable = BIT(~data, 3); - flip_screen_set(data & 0x40); + flip_screen_set(BIT(data, 6)); } } -void dynduke_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri) +void dynduke_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t *buffered_spriteram16 = m_spriteram->buffer(); - int offs,fx,fy,x,y,color,sprite; + uint16_t const *const buffered_spriteram16 = m_spriteram->buffer(); if (!m_sprite_enable) return; - for (offs = 0x800-4;offs >= 0;offs -= 4) + constexpr uint32_t pri_mask[4] = { + GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2, // Untested: does anything use it? Could be behind background + GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2, + GFX_PMASK_8 | GFX_PMASK_4, + GFX_PMASK_8, + }; + + for (int offs = 0;offs < 0x800;offs += 4) { /* Don't draw empty sprite table entries */ if ((buffered_spriteram16[offs+3] >> 8)!=0xf) continue; - if (((buffered_spriteram16[offs+2]>>13)&3)!=pri) continue; + uint32_t pri = pri_mask[((buffered_spriteram16[offs+2]>>13)&3)]; - fx= buffered_spriteram16[offs+0]&0x2000; - fy= buffered_spriteram16[offs+0]&0x4000; - y = buffered_spriteram16[offs+0] & 0xff; - x = buffered_spriteram16[offs+2] & 0xff; + bool fx = BIT(buffered_spriteram16[offs+0], 13); + bool fy = BIT(buffered_spriteram16[offs+0], 14); + int32_t y = buffered_spriteram16[offs+0] & 0xff; + int32_t x = buffered_spriteram16[offs+2] & 0xff; if (buffered_spriteram16[offs+2]&0x100) x=0-(0x100-x); - color = (buffered_spriteram16[offs+0]>>8)&0x1f; - sprite = buffered_spriteram16[offs+1]; + uint32_t const color = (buffered_spriteram16[offs+0]>>8)&0x1f; + uint32_t sprite = buffered_spriteram16[offs+1]; sprite &= 0x3fff; if (flip_screen()) { x=240-x; y=240-y; - if (fx) fx=0; else fx=1; - if (fy) fy=0; else fy=1; + fx=!fx; + fy=!fy; } - m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, + m_gfxdecode->gfx(3)->prio_transpen(bitmap,cliprect, sprite, - color,fx,fy,x,y,15); + color,fx,fy,x,y, + screen.priority(),pri,15); } } -void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri ) +void dynduke_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, uint32_t pri_mask) { /* The transparency / palette handling on the background layer is very strange */ bitmap_ind16 &bm = m_bg_layer->pixmap(); @@ -180,16 +188,17 @@ void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &clipr scrollx = 256 - scrollx; } - for (int y=0;y<256;y++) + for (int y=cliprect.top();y<=cliprect.bottom();y++) { - int realy = (y + scrolly) & 0x1ff; + int const realy = (y + scrolly) & 0x1ff; uint16_t const *const src = &bm.pix(realy); uint16_t *const dst = &bitmap.pix(y); + uint8_t *const pdst = &screen.priority().pix(y); - for (int x=0;x<256;x++) + for (int x=cliprect.left();x<=cliprect.right();x++) { - int realx = (x + scrollx) & 0x1ff; + int const realx = (x + scrollx) & 0x1ff; uint16_t srcdat = src[realx]; /* 0x01 - data bits @@ -208,6 +217,7 @@ void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &clipr srcdat = (srcdat & 0x000f) | ((srcdat & 0xffc0) >> 2); dst[x] = srcdat; + pdst[x] |= pri_mask; } @@ -223,16 +233,11 @@ uint32_t dynduke_state::screen_update(screen_device &screen, bitmap_ind16 &bitma m_fg_layer->enable(m_fore_enable); m_tx_layer->enable(m_txt_enable); - - draw_background(bitmap, cliprect,0x00); - draw_sprites(bitmap,cliprect,0); // Untested: does anything use it? Could be behind background - draw_sprites(bitmap,cliprect,1); - draw_background(bitmap, cliprect,0x20); - - draw_sprites(bitmap,cliprect,2); - m_fg_layer->draw(screen, bitmap, cliprect, 0,0); - draw_sprites(bitmap,cliprect,3); - m_tx_layer->draw(screen, bitmap, cliprect, 0,0); + draw_background(screen, bitmap, cliprect, 0x00, 1); + draw_background(screen, bitmap, cliprect, 0x20, 2); + m_fg_layer->draw(screen, bitmap, cliprect, 0,4); + m_tx_layer->draw(screen, bitmap, cliprect, 0,8); + draw_sprites(screen, bitmap, cliprect); return 0; } -- cgit v1.2.3