diff --git a/src/mame/drivers/dec8.cpp b/src/mame/drivers/dec8.cpp index 1b1a1c7ddc1..e2cbc84a3c0 100644 --- a/src/mame/drivers/dec8.cpp +++ b/src/mame/drivers/dec8.cpp @@ -1958,8 +1958,6 @@ void dec8_state::lastmisn(machine_config &config) BUFFERED_SPRITERAM8(config, m_spriteram); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); @@ -2020,8 +2018,6 @@ void dec8_state::shackled(machine_config &config) BUFFERED_SPRITERAM8(config, m_spriteram); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); @@ -2074,8 +2070,7 @@ void dec8_state::gondo(machine_config &config) BUFFERED_SPRITERAM8(config, m_spriteram); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); + m_spritegen_krn->set_colpri_callback(FUNC(dec8_state::gondo_colpri_cb), this); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); @@ -2132,8 +2127,6 @@ void dec8_state::garyoret(machine_config &config) BUFFERED_SPRITERAM8(config, m_spriteram); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); @@ -2194,8 +2187,6 @@ void dec8_state::ghostb(machine_config &config) m_tilegen[0]->set_gfxdecode_tag(m_gfxdecode); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); @@ -2255,8 +2246,6 @@ void dec8_state::csilver(machine_config &config) BUFFERED_SPRITERAM8(config, m_spriteram); DECO_KARNOVSPRITES(config, m_spritegen_krn, 0); - m_spritegen_krn->set_gfx_region(1); - m_spritegen_krn->set_gfxdecode_tag(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(58); diff --git a/src/mame/drivers/karnov.cpp b/src/mame/drivers/karnov.cpp index cb058bed589..d2d5b176264 100644 --- a/src/mame/drivers/karnov.cpp +++ b/src/mame/drivers/karnov.cpp @@ -793,8 +793,6 @@ void karnov_state::karnov(machine_config &config) m_palette->set_init("palette", FUNC(deco_rmc3_device::palette_init_proms)); DECO_KARNOVSPRITES(config, m_spritegen, 0); - m_spritegen->set_gfx_region(2); - m_spritegen->set_gfxdecode_tag(m_gfxdecode); MCFG_VIDEO_START_OVERRIDE(karnov_state,karnov) @@ -870,8 +868,6 @@ void karnov_state::wndrplnt(machine_config &config) m_palette->set_init("palette", FUNC(deco_rmc3_device::palette_init_proms)); DECO_KARNOVSPRITES(config, m_spritegen, 0); - m_spritegen->set_gfx_region(2); - m_spritegen->set_gfxdecode_tag(m_gfxdecode); MCFG_VIDEO_START_OVERRIDE(karnov_state,wndrplnt) diff --git a/src/mame/includes/dec8.h b/src/mame/includes/dec8.h index bdb74019a18..b35d71c8dfe 100644 --- a/src/mame/includes/dec8.h +++ b/src/mame/includes/dec8.h @@ -201,6 +201,7 @@ private: DECLARE_WRITE8_MEMBER(oscar_coin_clear_w); DECLARE_WRITE_LINE_MEMBER(shackled_coin_irq); void srdarwin_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap); + void gondo_colpri_cb(u32 &colour, u32 &pri_mask); DECLARE_WRITE_LINE_MEMBER(csilver_adpcm_int); void set_screen_raw_params_data_east(machine_config &config); diff --git a/src/mame/video/dec8.cpp b/src/mame/video/dec8.cpp index a8780dc3b23..a2395a25866 100644 --- a/src/mame/video/dec8.cpp +++ b/src/mame/video/dec8.cpp @@ -254,7 +254,7 @@ VIDEO_START_MEMBER(dec8_state,cobracom) uint32_t dec8_state::screen_update_ghostb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { m_tilegen[0]->deco_bac06_pf_draw(bitmap,cliprect,TILEMAP_DRAW_OPAQUE, 0x00, 0x00, 0x00, 0x00); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 0); + m_spritegen_krn->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(1), m_buffered_spriteram16.get(), 0x400); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; } @@ -293,7 +293,7 @@ uint32_t dec8_state::screen_update_oscar(screen_device &screen, bitmap_ind16 &bi m_spritegen_mxc->set_flip_screen(flip); m_fix_tilemap->set_flip(flip ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); - // we mimic the priority scheme in dec0.c, this was originally a bit different, so this could be wrong + // we mimic the priority scheme in dec0.cpp, this was originally a bit different, so this could be wrong m_tilegen[0]->deco_bac06_pf_draw(bitmap,cliprect,TILEMAP_DRAW_OPAQUE, 0x00, 0x00, 0x00, 0x00); m_spritegen_mxc->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x00, 0x00, 0x0f); m_tilegen[0]->deco_bac06_pf_draw(bitmap,cliprect,0, 0x08,0x08,0x08,0x08); @@ -332,7 +332,7 @@ uint32_t dec8_state::screen_update_lastmisn(screen_device &screen, bitmap_ind16 m_bg_tilemap->set_scrolly(0, ((m_scroll2[2] << 8)+ m_scroll2[3])); m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 0); + m_spritegen_krn->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(1), m_buffered_spriteram16.get(), 0x400); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; } @@ -345,7 +345,7 @@ uint32_t dec8_state::screen_update_shackled(screen_device &screen, bitmap_ind16 m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 0); m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 0); m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 0); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 0); + m_spritegen_krn->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(1), m_buffered_spriteram16.get(), 0x400); m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 0); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; @@ -464,15 +464,22 @@ VIDEO_START_MEMBER(dec8_state,srdarwin) /******************************************************************************/ +void dec8_state::gondo_colpri_cb(u32 &colour, u32 &pri_mask) +{ + pri_mask = 0; // above foreground, background + if (colour & 8) + pri_mask |= GFX_PMASK_2; // behind foreground, above background +} + uint32_t dec8_state::screen_update_gondo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + screen.priority().fill(0, cliprect); m_bg_tilemap->set_scrollx(0, ((m_scroll2[0] << 8) + m_scroll2[1])); m_bg_tilemap->set_scrolly(0, ((m_scroll2[2] << 8) + m_scroll2[3])); - m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 2); - m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 1); + m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 1); + m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 2); + m_spritegen_krn->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(1), m_buffered_spriteram16.get(), 0x400); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; } @@ -483,7 +490,7 @@ uint32_t dec8_state::screen_update_garyoret(screen_device &screen, bitmap_ind16 m_bg_tilemap->set_scrolly(0, ((m_scroll2[2] << 8) + m_scroll2[3])); m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - m_spritegen_krn->draw_sprites(bitmap, cliprect, m_buffered_spriteram16.get(), 0x400, 0); + m_spritegen_krn->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(1), m_buffered_spriteram16.get(), 0x400); m_bg_tilemap->draw(screen, bitmap, cliprect, 1, 0); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; diff --git a/src/mame/video/deckarn.cpp b/src/mame/video/deckarn.cpp index 91186d1f57b..16c8c608767 100644 --- a/src/mame/video/deckarn.cpp +++ b/src/mame/video/deckarn.cpp @@ -8,16 +8,15 @@ DEFINE_DEVICE_TYPE(DECO_KARNOVSPRITES, deco_karnovsprites_device, "deco_karnovsprites", "DECO Karnov Sprites") -deco_karnovsprites_device::deco_karnovsprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +deco_karnovsprites_device::deco_karnovsprites_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, DECO_KARNOVSPRITES, tag, owner, clock) - , m_gfxregion(0) - , m_gfxdecode(*this, finder_base::DUMMY_TAG) { } void deco_karnovsprites_device::device_start() { m_flip_screen = false; + m_colpri_cb.bind_relative_to(*owner()); save_item(NAME(m_flip_screen)); } @@ -26,37 +25,40 @@ void deco_karnovsprites_device::device_reset() { } -void deco_karnovsprites_device::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t* spriteram, int size, int priority ) +void deco_karnovsprites_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, u16* spriteram, int size) { - int offs; + const bool priority = !m_colpri_cb.isnull(); + int start, end, inc; + if (priority) { start = size - 4; end = -4; inc = -4; } + else { start = 0; end = size; inc = +4; } - for (offs = 0; offs < size; offs += 4) + for (int offs = start; offs != end; offs += inc) { - int x, y, sprite, sprite2, colour, fx, fy, extra; + int sprite2; + u32 pri_mask = 0; - y = spriteram[offs]; - if (!(y & 0x8000)) + const u16 data0 = spriteram[offs]; + if (!(data0 & 0x8000)) continue; - y = y & 0x1ff; - sprite = spriteram[offs + 3]; - colour = sprite >> 12; + int y = data0 & 0x1ff; + const u16 data3 = spriteram[offs + 3]; + u32 colour = data3 >> 12; + if (priority) + m_colpri_cb(colour, pri_mask); - if (priority == 1 && (colour & 8)) continue; - if (priority == 2 && !(colour & 8)) continue; + u32 sprite = data3 & 0xfff; + int x = spriteram[offs + 2] & 0x1ff; - sprite = sprite & 0xfff; - x = spriteram[offs + 2] & 0x1ff; - - fx = spriteram[offs + 1]; + const u16 data1 = spriteram[offs + 1]; /* the 8-bit implementation had this. illustrated by enemy projectile explosions in Shackled being left on screen. */ - if ((fx & 0x1) == 0) continue; + if ((data1 & 0x1) == 0) continue; - extra = (fx & 0x10) ? 1 : 0; - fy = fx & 0x2; - fx = fx & 0x4; + const bool extra = (data1 & 0x10) ? 1 : 0; + int fy = data1 & 0x2; + int fx = data1 & 0x4; if (extra) { @@ -87,14 +89,29 @@ void deco_karnovsprites_device::draw_sprites( bitmap_ind16 &bitmap, const rectan else sprite2 = sprite + 1; - m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect, - sprite, - colour,fx,fy,x,y,0); + if (priority) + { + gfx->prio_transpen(bitmap,cliprect, + sprite, + colour,fx,fy,x,y,screen.priority(),pri_mask,0); - /* 1 more sprite drawn underneath */ - if (extra) - m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect, - sprite2, - colour,fx,fy,x,y+16,0); + /* 1 more sprite drawn underneath */ + if (extra) + gfx->prio_transpen(bitmap,cliprect, + sprite2, + colour,fx,fy,x,y+16,screen.priority(),pri_mask,0); + } + else + { + gfx->transpen(bitmap,cliprect, + sprite, + colour,fx,fy,x,y,0); + + /* 1 more sprite drawn underneath */ + if (extra) + gfx->transpen(bitmap,cliprect, + sprite2, + colour,fx,fy,x,y+16,0); + } } } diff --git a/src/mame/video/deckarn.h b/src/mame/video/deckarn.h index 919b2489d58..7c176a024ca 100644 --- a/src/mame/video/deckarn.h +++ b/src/mame/video/deckarn.h @@ -5,27 +5,26 @@ #pragma once +#include "screen.h" + +typedef device_delegate deckarn_colpri_cb_delegate; class deco_karnovsprites_device : public device_t { public: - deco_karnovsprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - void set_gfxregion(int region) { m_gfxregion = region; } - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t* spriteram, int size, int priority); + deco_karnovsprites_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, u16* spriteram, int size); void set_flip_screen(bool flip) { m_flip_screen = flip; } - // configuration - template void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward(tag)); } - void set_gfx_region(int region) { m_gfxregion = region; } + template void set_colpri_callback(T &&... args) { m_colpri_cb = deckarn_colpri_cb_delegate(std::forward(args)...); } protected: virtual void device_start() override; virtual void device_reset() override; - uint8_t m_gfxregion; - bool m_flip_screen; private: - required_device m_gfxdecode; + deckarn_colpri_cb_delegate m_colpri_cb; + bool m_flip_screen; }; DECLARE_DEVICE_TYPE(DECO_KARNOVSPRITES, deco_karnovsprites_device) diff --git a/src/mame/video/karnov.cpp b/src/mame/video/karnov.cpp index 730e87ffbb8..bcc5b1591d8 100644 --- a/src/mame/video/karnov.cpp +++ b/src/mame/video/karnov.cpp @@ -22,7 +22,7 @@ uint32_t karnov_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap m_bg_tilemap->set_scrollx(m_scroll[0]); m_bg_tilemap->set_scrolly(m_scroll[1]); m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); - m_spritegen->draw_sprites(bitmap, cliprect, m_spriteram->buffer(), 0x800, 0); + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_gfxdecode->gfx(2), m_spriteram->buffer(), 0x800); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; }