From 0a0ddfb6aff95bf8312d421ac863a42bee8d7b74 Mon Sep 17 00:00:00 2001 From: cam900 Date: Fri, 8 Dec 2023 02:47:20 +0900 Subject: seibu/sei021x_sei0220_spr.cpp: Encapsulated SEI0210/SEI0211/SEI0220 sprite chip emulation. (#11802) * seibu/banprestoms.cpp, seibu/sengokumj.cpp: Use single-pass sprite drawing. * seibu/bloodbro.cpp: Split driver state classes for different hardware configurations. * seibu/dcon.cpp: Fixed sprite coordinate format. --- src/mame/seibu/banprestoms.cpp | 82 ++++-------- src/mame/seibu/bloodbro.cpp | 124 +++++++++--------- src/mame/seibu/bloodbro.h | 52 +++++--- src/mame/seibu/bloodbro_v.cpp | 76 ++--------- src/mame/seibu/dcon.cpp | 39 +++--- src/mame/seibu/dcon.h | 6 +- src/mame/seibu/dcon_v.cpp | 151 +++------------------- src/mame/seibu/goodejan.cpp | 114 ++++------------- src/mame/seibu/legionna.cpp | 27 +++- src/mame/seibu/legionna.h | 13 +- src/mame/seibu/legionna_v.cpp | 226 ++++++++------------------------- src/mame/seibu/sei021x_sei0220_spr.cpp | 193 ++++++++++++++++++++++++++++ src/mame/seibu/sei021x_sei0220_spr.h | 80 ++++++++++++ src/mame/seibu/sengokmj.cpp | 78 +++++------- 14 files changed, 600 insertions(+), 661 deletions(-) create mode 100644 src/mame/seibu/sei021x_sei0220_spr.cpp create mode 100644 src/mame/seibu/sei021x_sei0220_spr.h diff --git a/src/mame/seibu/banprestoms.cpp b/src/mame/seibu/banprestoms.cpp index cdc3a77139e..5b806b7b659 100644 --- a/src/mame/seibu/banprestoms.cpp +++ b/src/mame/seibu/banprestoms.cpp @@ -38,6 +38,7 @@ TODO: #include "emu.h" +#include "sei021x_sei0220_spr.h" #include "seibu_crtc.h" #include "cpu/m68000/m68000.h" @@ -62,6 +63,7 @@ public: , m_maincpu(*this, "maincpu") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") + , m_spritegen(*this, "spritegen") , m_ticket(*this, "ticket") , m_rtc(*this, "rtc") , m_vram(*this, "vram%u", 0U) @@ -81,6 +83,7 @@ private: required_device m_maincpu; required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; required_device m_ticket; required_device m_rtc; @@ -102,7 +105,7 @@ private: template TILE_GET_INFO_MEMBER(tile_info); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri); + uint32_t pri_cb(uint8_t pri, uint8_t ext); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void prg_map(address_map &map); @@ -154,62 +157,24 @@ TILE_GET_INFO_MEMBER(banprestoms_state::tile_info) { int tile = m_vram[Which][tile_index] & 0xfff; int color = (m_vram[Which][tile_index] >> 12) & 0x0f; - tileinfo.set(Which + 1, tile, color, 0); + tileinfo.set(Which, tile, color, 0); } -void banprestoms_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri) +uint32_t banprestoms_state::pri_cb(uint8_t pri, uint8_t ext) { - for (int offs = 0x400 - 4; offs >= 0; offs -= 4) + switch (pri) { - if ((m_spriteram[offs] & 0x8000) != 0x8000) continue; - int sprite = m_spriteram[offs + 1]; - if ((sprite >> 14) != pri) continue; - sprite &= 0x1fff; - - int y = m_spriteram[offs + 3]; - int x = m_spriteram[offs + 2]; - - int color = m_spriteram[offs] & 0x3f; - int fx = m_spriteram[offs] & 0x4000; - int fy = m_spriteram[offs] & 0x2000; - int dy = ((m_spriteram[offs] & 0x0380) >> 7) + 1; - int dx = ((m_spriteram[offs] & 0x1c00) >> 10) + 1; - - // co-ordinates don't have a sign bit, there must be wrapping logic - // co-ordinate masking might need to be applied during drawing instead - x &= 0x1ff; - if (x >= 0x180) - x -= 0x200; - - y &= 0x1ff; - if (y >= 0x180) - y -= 0x200; - - for (int ax = 0; ax < dx; ax++) - { - for (int ay = 0; ay < dy; ay++) - { - if (!fy) - { - if (!fx) - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, sprite++, color, fx, fy, x + ax * 16, y + ay * 16, 15); - else - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, sprite++, color, fx, fy, x + (dx - 1 - ax) * 16, y + ay * 16, 15); - } - else - { - if (!fx) - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, sprite++, color, fx, fy, x + ax * 16, y + (dy - 1 - ay) * 16, 15); - else - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, sprite++, color, fx, fy, x + (dx - 1 - ax) * 16, y + (dy - 1 - ay) * 16, 15); - } - } - } + case 0: return GFX_PMASK_8; + case 1: return GFX_PMASK_8 | GFX_PMASK_4; + case 2: return GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2; + case 3: + default: return 0; } } uint32_t banprestoms_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + screen.priority().fill(0, cliprect); bitmap.fill(m_palette->pen(0x7ff), cliprect); //black pen m_tilemap[0]->set_scrollx(0, m_scrollram[0]); @@ -221,14 +186,11 @@ uint32_t banprestoms_state::screen_update(screen_device &screen, bitmap_ind16 &b m_tilemap[3]->set_scrollx(0, 128); m_tilemap[3]->set_scrolly(0, -16); - if (!(m_layer_en & 0x0001)) { m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); } - if (!(m_layer_en & 0x0010)) { draw_sprites(bitmap, cliprect, 2); } - if (!(m_layer_en & 0x0002)) { m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); } - if (!(m_layer_en & 0x0010)) { draw_sprites(bitmap, cliprect, 1); } - if (!(m_layer_en & 0x0004)) { m_tilemap[2]->draw(screen, bitmap, cliprect, 0, 0); } - if (!(m_layer_en & 0x0010)) { draw_sprites(bitmap, cliprect, 0); } - if (!(m_layer_en & 0x0008)) { m_tilemap[3]->draw(screen, bitmap, cliprect, 0, 0); } - if (!(m_layer_en & 0x0010)) { draw_sprites(bitmap, cliprect, 3); } + if (BIT(~m_layer_en, 0)) { m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 1); } + if (BIT(~m_layer_en, 1)) { m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 2); } + if (BIT(~m_layer_en, 2)) { m_tilemap[2]->draw(screen, bitmap, cliprect, 0, 4); } + if (BIT(~m_layer_en, 3)) { m_tilemap[3]->draw(screen, bitmap, cliprect, 0, 8); } + if (BIT(~m_layer_en, 4)) { m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); } return 0; } @@ -430,13 +392,16 @@ static const gfx_layout charlayout = }; static GFXDECODE_START( gfx_banprestoms ) - GFXDECODE_ENTRY( "spr_gfx",0, tilelayout, 0x000, 0x40 ) GFXDECODE_ENTRY( "bg_gfx", 0, tilelayout, 0x100, 0x10 ) // TODO, doesn't seem to be used by the dumped games GFXDECODE_ENTRY( "md_gfx", 0, tilelayout, 0x100, 0x10 ) // TODO, doesn't seem to be used by the dumped games GFXDECODE_ENTRY( "fg_gfx", 0, tilelayout, 0x100, 0x10 ) GFXDECODE_ENTRY( "tx_gfx", 0, charlayout, 0x200, 0x10 ) GFXDECODE_END +static GFXDECODE_START( gfx_banprestoms_spr ) + GFXDECODE_ENTRY( "spr_gfx",0, tilelayout, 0x000, 0x40 ) +GFXDECODE_END + void banprestoms_state::banprestoms(machine_config &config) { @@ -467,6 +432,9 @@ void banprestoms_state::banprestoms(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_banprestoms); PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x400); // TODO: copied from other drivers using the same CRTC + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_banprestoms_spr); + m_spritegen->set_pri_callback(FUNC(banprestoms_state::pri_cb)); + // sound hardware SPEAKER(config, "mono").front_center(); diff --git a/src/mame/seibu/bloodbro.cpp b/src/mame/seibu/bloodbro.cpp index 22a3ae308d9..6e92ad5b723 100644 --- a/src/mame/seibu/bloodbro.cpp +++ b/src/mame/seibu/bloodbro.cpp @@ -184,7 +184,7 @@ void bloodbro_state::skysmash_map(address_map &map) map(0xc0000, 0xc004f).rw("crtc", FUNC(seibu_crtc_device::read_alt), FUNC(seibu_crtc_device::write_alt)); } -void bloodbro_state::weststry_soundlatch_w(offs_t offset, u8 data) +void weststry_state::weststry_soundlatch_w(offs_t offset, u8 data) { m_seibu_sound->main_w(offset, data); @@ -192,33 +192,33 @@ void bloodbro_state::weststry_soundlatch_w(offs_t offset, u8 data) m_audiocpu->set_input_line(0, ASSERT_LINE); } -void bloodbro_state::weststry_map(address_map &map) +void weststry_state::weststry_map(address_map &map) { map(0x000000, 0x07ffff).rom(); map(0x080000, 0x08ffff).ram(); // old VRAM areas still used, but bootleg code copies them to higher addresses map(0x0c1000, 0x0c1001).portr("DSW"); map(0x0c1002, 0x0c1003).portr("IN0"); map(0x0c1004, 0x0c1005).portr("IN1"); - map(0x0c1000, 0x0c1003).w(FUNC(bloodbro_state::weststry_soundlatch_w)).umask16(0xff00); - map(0x0c1004, 0x0c100b).w(FUNC(bloodbro_state::weststry_layer_scroll_w)); + map(0x0c1000, 0x0c1003).w(FUNC(weststry_state::weststry_soundlatch_w)).umask16(0xff00); + map(0x0c1004, 0x0c100b).w(FUNC(weststry_state::weststry_layer_scroll_w)); map(0x0e0002, 0x0e0003).nopr(); // remnant of old code map(0x122800, 0x122bff).ram(); // cleared at startup - map(0x122c00, 0x122fff).ram().w(FUNC(bloodbro_state::fgvideoram_w)).share("fgvideoram"); - map(0x123000, 0x1233ff).ram().w(FUNC(bloodbro_state::bgvideoram_w)).share("bgvideoram"); + map(0x122c00, 0x122fff).ram().w(FUNC(weststry_state::fgvideoram_w)).share("fgvideoram"); + map(0x123000, 0x1233ff).ram().w(FUNC(weststry_state::bgvideoram_w)).share("bgvideoram"); map(0x123400, 0x1237ff).ram(); // cleared at startup - map(0x123800, 0x123fff).ram().w(FUNC(bloodbro_state::txvideoram_w)).share("txvideoram"); + map(0x123800, 0x123fff).ram().w(FUNC(weststry_state::txvideoram_w)).share("txvideoram"); map(0x124000, 0x124005).ram(); map(0x124006, 0x1247fd).ram().share("spriteram"); map(0x128000, 0x1287ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); } -void bloodbro_state::weststry_opl_irq_w(int state) +void weststry_state::weststry_opl_irq_w(int state) { m_weststry_opl_irq = state; weststry_soundnmi_update(); } -void bloodbro_state::weststry_opl_w(offs_t offset, uint8_t data) +void weststry_state::weststry_opl_w(offs_t offset, uint8_t data) { // NMI cannot be accepted between address and data writes, or else registers get corrupted m_weststry_soundnmi_mask = BIT(offset, 0); @@ -226,22 +226,22 @@ void bloodbro_state::weststry_opl_w(offs_t offset, uint8_t data) weststry_soundnmi_update(); } -void bloodbro_state::weststry_soundnmi_ack_w(uint8_t data) +void weststry_state::weststry_soundnmi_ack_w(uint8_t data) { m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); weststry_soundnmi_update(); } -void bloodbro_state::weststry_soundnmi_update() +void weststry_state::weststry_soundnmi_update() { if (m_weststry_opl_irq && m_weststry_soundnmi_mask) m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } -void bloodbro_state::weststry_sound_map(address_map &map) +void weststry_state::weststry_sound_map(address_map &map) { seibu_sound_map(map); - map(0x4002, 0x4002).w(FUNC(bloodbro_state::weststry_soundnmi_ack_w)); + map(0x4002, 0x4002).w(FUNC(weststry_state::weststry_soundnmi_ack_w)); } /* Input Ports */ @@ -492,17 +492,20 @@ static const gfx_layout weststry_spritelayout = /* Graphics Decode Info */ static GFXDECODE_START( gfx_bloodbro ) - GFXDECODE_ENTRY( "gfx1", 0x00000, textlayout, 0x70*16, 0x10 ) /* Text */ - GFXDECODE_ENTRY( "gfx2", 0x00000, spritelayout, 0x40*16, 0x10 ) /* Background */ - GFXDECODE_ENTRY( "gfx2", 0x00000, spritelayout, 0x50*16, 0x10 ) /* Foreground */ - GFXDECODE_ENTRY( "gfx3", 0x00000, spritelayout, 0x00*16, 0x10 ) /* Sprites */ + GFXDECODE_ENTRY( "txtiles", 0x00000, textlayout, 0x70*16, 0x10 ) /* Text */ + GFXDECODE_ENTRY( "bgtiles", 0x00000, spritelayout, 0x40*16, 0x10 ) /* Background */ + GFXDECODE_ENTRY( "bgtiles", 0x00000, spritelayout, 0x50*16, 0x10 ) /* Foreground */ +GFXDECODE_END + +static GFXDECODE_START( gfx_bloodbro_spr ) + GFXDECODE_ENTRY( "sprites", 0x00000, spritelayout, 0x00*16, 0x10 ) /* Sprites */ GFXDECODE_END static GFXDECODE_START( gfx_weststry ) - GFXDECODE_ENTRY( "gfx1", 0x00000, weststry_textlayout, 0x10*16, 0x10 ) - GFXDECODE_ENTRY( "gfx2", 0x00000, weststry_spritelayout, 0x30*16, 0x10 ) - GFXDECODE_ENTRY( "gfx2", 0x00000, weststry_spritelayout, 0x20*16, 0x10 ) - GFXDECODE_ENTRY( "gfx3", 0x00000, weststry_spritelayout, 0x00*16, 0x10 ) + GFXDECODE_ENTRY( "txtiles", 0x00000, weststry_textlayout, 0x10*16, 0x10 ) + GFXDECODE_ENTRY( "bgtiles", 0x00000, weststry_spritelayout, 0x30*16, 0x10 ) + GFXDECODE_ENTRY( "bgtiles", 0x00000, weststry_spritelayout, 0x20*16, 0x10 ) + GFXDECODE_ENTRY( "sprites", 0x00000, weststry_spritelayout, 0x00*16, 0x10 ) GFXDECODE_END void bloodbro_state::layer_en_w(uint16_t data) @@ -515,7 +518,7 @@ void bloodbro_state::layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_m COMBINE_DATA(&m_scrollram[offset]); } -void bloodbro_state::weststry_layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void weststry_state::weststry_layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&m_scrollram[offset]); } @@ -549,6 +552,10 @@ void bloodbro_state::bloodbro(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_bloodbro); PALETTE(config, m_palette).set_format(palette_device::xBGR_444, 2048); + SEI0210(config, m_spritegen, XTAL(12'000'000), m_palette, gfx_bloodbro_spr); + m_spritegen->set_alt_format(true); + m_spritegen->set_pri_callback(FUNC(bloodbro_state::pri_cb)); + // sound hardware SPEAKER(config, "mono").front_center(); @@ -567,15 +574,15 @@ void bloodbro_state::bloodbro(machine_config &config) m_seibu_sound->ym_write_callback().set(m_ymsnd, FUNC(ym3812_device::write)); } -void bloodbro_state::weststry(machine_config &config) +void weststry_state::weststry(machine_config &config) { bloodbro(config); - m_maincpu->set_addrmap(AS_PROGRAM, &bloodbro_state::weststry_map); - m_maincpu->set_vblank_int("screen", FUNC(bloodbro_state::irq6_line_hold)); + m_maincpu->set_addrmap(AS_PROGRAM, &weststry_state::weststry_map); + m_maincpu->set_vblank_int("screen", FUNC(weststry_state::irq6_line_hold)); m_audiocpu->set_clock(XTAL(20'000'000)/4); /* 5MHz - verified on PCB */ - m_audiocpu->set_addrmap(AS_PROGRAM, &bloodbro_state::weststry_sound_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &weststry_state::weststry_sound_map); m_audiocpu->remove_irq_acknowledge_callback(); m_gfxdecode->set_info(gfx_weststry); @@ -583,7 +590,8 @@ void bloodbro_state::weststry(machine_config &config) // Bootleg video hardware is non-Seibu m_screen->set_refresh_hz(59); /* verified on PCB */ - m_screen->set_screen_update(FUNC(bloodbro_state::screen_update_weststry)); + m_screen->set_screen_update(FUNC(weststry_state::screen_update_weststry)); + config.device_remove("spritegen"); config.device_remove("crtc"); // Bootleg sound hardware is close copy of Seibu, but uses different interrupts @@ -592,10 +600,10 @@ void bloodbro_state::weststry(machine_config &config) oki.add_route(ALL_OUTPUTS, "mono", 1.0); YM3812(config.replace(), m_ymsnd, XTAL(20'000'000)/4); /* ~4.9MHz - see notes at top */ - m_ymsnd->irq_handler().set(FUNC(bloodbro_state::weststry_opl_irq_w)); + m_ymsnd->irq_handler().set(FUNC(weststry_state::weststry_opl_irq_w)); m_ymsnd->add_route(ALL_OUTPUTS, "mono", 1.0); - m_seibu_sound->ym_write_callback().set(FUNC(bloodbro_state::weststry_opl_w)); + m_seibu_sound->ym_write_callback().set(FUNC(weststry_state::weststry_opl_w)); } void bloodbro_state::skysmash(machine_config &config) @@ -604,8 +612,6 @@ void bloodbro_state::skysmash(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &bloodbro_state::skysmash_map); m_maincpu->set_vblank_int("screen", FUNC(bloodbro_state::irq2_line_hold)); - - m_screen->set_screen_update(FUNC(bloodbro_state::screen_update_skysmash)); } @@ -623,14 +629,14 @@ ROM_START( bloodbro ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "blood_bros_bk__=c=1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ - ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "blood_bros_obj__=c=1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -652,14 +658,14 @@ ROM_START( bloodbroj ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "blood_bros_bk__=c=1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ - ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "blood_bros_obj__=c=1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -681,14 +687,14 @@ ROM_START( bloodbroja ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "blood_bros_bk__=c=1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ - ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "blood_bros_obj__=c=1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -710,14 +716,14 @@ ROM_START( bloodbrou ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "blood_bros_bk__=c=1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ - ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "blood_bros_obj__=c=1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -739,14 +745,14 @@ ROM_START( bloodbrok ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "blood_bros_bk__=c=1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ - ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "blood_bros_obj__=c=1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -768,7 +774,7 @@ ROM_START( weststry ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) // first half of these is blank + ROM_REGION( 0x20000, "txtiles", 0 ) // first half of these is blank ROM_LOAD( "ws09.bin", 0x00000, 0x08000, CRC(f05b2b3e) SHA1(6570d795d68655ace9668f32dc0bf5c2d2372411) ) /* characters */ ROM_CONTINUE( 0x00000, 0x08000 ) ROM_LOAD( "ws11.bin", 0x08000, 0x08000, CRC(2b10e3d2) SHA1(0f5045615b44e2300745fd3afac7f1441352cca5) ) @@ -778,7 +784,7 @@ ROM_START( weststry ) ROM_LOAD( "ws12.bin", 0x18000, 0x08000, CRC(af993578) SHA1(b250b562deeab3bb2c79002e5e1f0b6e17986848) ) ROM_CONTINUE( 0x18000, 0x08000 ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "ws01.bin", 0x20000, 0x20000, CRC(32bda4bc) SHA1(ed0c0740c7af513b341b2b7ff3e0bf6045e930e9) ) /* Foreground */ ROM_LOAD( "ws03.bin", 0x60000, 0x20000, CRC(046b51f8) SHA1(25af752caebdec762582fc0130cf14546110bb54) ) ROM_LOAD( "ws02.bin", 0xa0000, 0x20000, CRC(ed9d682e) SHA1(0f79ea09a7af367d175081f72f2bc94f6caad463) ) @@ -788,7 +794,7 @@ ROM_START( weststry ) ROM_LOAD( "ws06.bin", 0x80000, 0x20000, CRC(459d075e) SHA1(24cd0bffe7c5bbccf653ced0b73579059603d187) ) ROM_LOAD( "ws08.bin", 0xc0000, 0x20000, CRC(4d6783b3) SHA1(9870fe9570afeff179b6080581fd6bb187898ff0) ) - ROM_REGION( 0x100000, "gfx3", ROMREGION_INVERT ) + ROM_REGION( 0x100000, "sprites", ROMREGION_INVERT ) ROM_LOAD( "ws25.bin", 0x00000, 0x20000, CRC(8092e8e9) SHA1(eabe58ac0f88234b0dddf361f56aad509a83012e) ) /* sprites */ ROM_LOAD( "ws26.bin", 0x20000, 0x20000, CRC(f6a1f42c) SHA1(6d5503e1a9b00104970292d22301ed28893c5223) ) ROM_LOAD( "ws23.bin", 0x40000, 0x20000, CRC(43d58e24) SHA1(99e255faa9716d9102a1223419084fc209ab4024) ) @@ -814,7 +820,7 @@ ROM_START( weststrya ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) // first half of these is blank + ROM_REGION( 0x20000, "txtiles", 0 ) // first half of these is blank ROM_LOAD( "ws09.bin", 0x00000, 0x08000, CRC(f05b2b3e) SHA1(6570d795d68655ace9668f32dc0bf5c2d2372411) ) /* characters */ ROM_CONTINUE( 0x00000, 0x08000 ) ROM_LOAD( "ws11.bin", 0x08000, 0x08000, CRC(2b10e3d2) SHA1(0f5045615b44e2300745fd3afac7f1441352cca5) ) @@ -824,7 +830,7 @@ ROM_START( weststrya ) ROM_LOAD( "ws12.bin", 0x18000, 0x08000, CRC(af993578) SHA1(b250b562deeab3bb2c79002e5e1f0b6e17986848) ) ROM_CONTINUE( 0x18000, 0x08000 ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "ws01.bin", 0x20000, 0x20000, CRC(32bda4bc) SHA1(ed0c0740c7af513b341b2b7ff3e0bf6045e930e9) ) /* Foreground */ ROM_LOAD( "ws03.bin", 0x60000, 0x20000, CRC(046b51f8) SHA1(25af752caebdec762582fc0130cf14546110bb54) ) ROM_LOAD( "ws02.bin", 0xa0000, 0x20000, CRC(ed9d682e) SHA1(0f79ea09a7af367d175081f72f2bc94f6caad463) ) @@ -834,7 +840,7 @@ ROM_START( weststrya ) ROM_LOAD( "ws06.bin", 0x80000, 0x20000, CRC(459d075e) SHA1(24cd0bffe7c5bbccf653ced0b73579059603d187) ) ROM_LOAD( "ws08.bin", 0xc0000, 0x20000, CRC(4d6783b3) SHA1(9870fe9570afeff179b6080581fd6bb187898ff0) ) - ROM_REGION( 0x100000, "gfx3", ROMREGION_INVERT ) + ROM_REGION( 0x100000, "sprites", ROMREGION_INVERT ) ROM_LOAD( "ws25.bin", 0x00000, 0x20000, CRC(8092e8e9) SHA1(eabe58ac0f88234b0dddf361f56aad509a83012e) ) /* sprites */ ROM_LOAD( "ws26.bin", 0x20000, 0x20000, CRC(f6a1f42c) SHA1(6d5503e1a9b00104970292d22301ed28893c5223) ) ROM_LOAD( "ws23.bin", 0x40000, 0x20000, CRC(43d58e24) SHA1(99e255faa9716d9102a1223419084fc209ab4024) ) @@ -860,14 +866,14 @@ ROM_START( skysmash ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_REGION( 0x20000, "txtiles", 0 ) ROM_LOAD( "rom3", 0x00000, 0x10000, CRC(fbb241be) SHA1(cd94c328891538bbd8c062d90a47ddf3d7d05bb0) ) /* characters */ ROM_LOAD( "rom4", 0x10000, 0x10000, CRC(ad3cde81) SHA1(2bd0c707e5b67d3699a743d989cb5384cbe37ff7) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "bgtiles", 0 ) ROM_LOAD( "rom9", 0x00000, 0x100000, CRC(b0a5eecf) SHA1(9e8191c7ae4a32dc16aebc37fa942afc531eddd4) ) /* Background + Foreground */ - ROM_REGION( 0x80000, "gfx3", 0 ) + ROM_REGION( 0x80000, "sprites", 0 ) ROM_LOAD( "rom10", 0x00000, 0x080000, CRC(1bbcda5d) SHA1(63915221f70a7dfda6a4d8ac7f5c663c9316610a) ) /* sprites */ ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ @@ -878,14 +884,14 @@ ROM_START( skysmash ) ROM_END -void bloodbro_state::init_weststry() +void weststry_state::init_weststry() { // Patch out jp nz,$3000; no code known to exist at that address memory_region *z80_rom = memregion("audiocpu"); z80_rom->as_u8(0x160e) = 0x00; z80_rom->as_u8(0x1610) = 0x00; - uint8_t *sprites = memregion("gfx3")->base(); + uint8_t *sprites = memregion("sprites")->base(); for (int i = 0; i < 0x40000; i++) { /* sprite roms ws25 and ws26 have 2 bits swapped @@ -908,6 +914,6 @@ GAME( 1990, bloodbroj, bloodbro, bloodbro, bloodbro, bloodbro_state, empty_init GAME( 1990, bloodbroja, bloodbro, bloodbro, bloodbro, bloodbro_state, empty_init, ROT0, "TAD Corporation", "Blood Bros. (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) GAME( 1990, bloodbrou, bloodbro, bloodbro, bloodbro, bloodbro_state, empty_init, ROT0, "TAD Corporation (Fabtek license)", "Blood Bros. (US)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) GAME( 1990, bloodbrok, bloodbro, bloodbro, bloodbro, bloodbro_state, empty_init, ROT0, "TAD Corporation", "Blood Bros. (Korea)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, weststry, bloodbro, weststry, weststry, bloodbro_state, init_weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, weststrya, bloodbro, weststry, weststry, bloodbro_state, init_weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, weststry, bloodbro, weststry, weststry, weststry_state, init_weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, weststrya, bloodbro, weststry, weststry, weststry_state, init_weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) GAME( 1990, skysmash, 0, skysmash, skysmash, bloodbro_state, empty_init, ROT270, "Nihon System", "Sky Smasher", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/seibu/bloodbro.h b/src/mame/seibu/bloodbro.h index 6347130671c..e721c111486 100644 --- a/src/mame/seibu/bloodbro.h +++ b/src/mame/seibu/bloodbro.h @@ -5,6 +5,8 @@ #pragma once +#include "sei021x_sei0220_spr.h" + #include "seibusound.h" #include "sound/ymopl.h" @@ -19,10 +21,11 @@ public: bloodbro_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette"), - m_audiocpu(*this, "audiocpu"), + m_spritegen(*this, "spritegen"), m_seibu_sound(*this, "seibu_sound"), m_ymsnd(*this, "ymsnd"), m_spriteram(*this, "spriteram"), @@ -31,21 +34,18 @@ public: m_txvideoram(*this, "txvideoram") { } - void init_weststry(); - void bloodbro(machine_config &config); void skysmash(machine_config &config); - void weststry(machine_config &config); protected: virtual void video_start() override; -private: required_device m_maincpu; + required_device m_audiocpu; required_device m_gfxdecode; required_device m_screen; required_device m_palette; - required_device m_audiocpu; + optional_device m_spritegen; required_device m_seibu_sound; required_device m_ymsnd; @@ -61,34 +61,50 @@ private: tilemap_t *m_fg_tilemap = nullptr; tilemap_t *m_tx_tilemap = nullptr; - bool m_weststry_opl_irq = false; - bool m_weststry_soundnmi_mask = false; - void bgvideoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void fgvideoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void txvideoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void layer_en_w(uint16_t data); void layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void weststry_layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void weststry_soundlatch_w(offs_t offset, u8 data); - void weststry_opl_irq_w(int state); - void weststry_opl_w(offs_t offset, uint8_t data); - void weststry_soundnmi_ack_w(uint8_t data); - void weststry_soundnmi_update(); TILE_GET_INFO_MEMBER(get_bg_tile_info); TILE_GET_INFO_MEMBER(get_fg_tile_info); TILE_GET_INFO_MEMBER(get_tx_tile_info); uint32_t screen_update_bloodbro(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_weststry(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_skysmash(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void bloodbro_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void weststry_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t pri_cb(uint8_t pri, uint8_t ext); void bloodbro_map(address_map &map); void common_map(address_map &map); void skysmash_map(address_map &map); +}; + +class weststry_state : public bloodbro_state +{ +public: + weststry_state(const machine_config &mconfig, device_type type, const char *tag) : + bloodbro_state(mconfig, type, tag) + { } + + void init_weststry(); + + void weststry(machine_config &config); + +private: + bool m_weststry_opl_irq = false; + bool m_weststry_soundnmi_mask = false; + + void weststry_layer_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void weststry_soundlatch_w(offs_t offset, u8 data); + void weststry_opl_irq_w(int state); + void weststry_opl_w(offs_t offset, uint8_t data); + void weststry_soundnmi_ack_w(uint8_t data); + void weststry_soundnmi_update(); + + uint32_t screen_update_weststry(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void weststry_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void weststry_map(address_map &map); void weststry_sound_map(address_map &map); }; diff --git a/src/mame/seibu/bloodbro_v.cpp b/src/mame/seibu/bloodbro_v.cpp index 3413fe6c08b..8d9aea01fb8 100644 --- a/src/mame/seibu/bloodbro_v.cpp +++ b/src/mame/seibu/bloodbro_v.cpp @@ -145,44 +145,9 @@ void bloodbro_state::txvideoram_w(offs_t offset, uint16_t data, uint16_t mem_mas -------X XXXXXXXX -------- YYYYYYYY */ -void bloodbro_state::bloodbro_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t bloodbro_state::pri_cb(uint8_t pri, uint8_t ext) { - uint16_t *spriteram16 = m_spriteram; - int offs; - for (offs = 0;offs < m_spriteram.bytes()/2;offs += 4) - { - int sx,sy,x,y,width,height,attributes,tile_number,color,flipx,flipy,pri_mask; - - attributes = spriteram16[offs+0]; - if (attributes & 0x8000) continue; /* disabled */ - - width = ((attributes>>7)&7); - height = ((attributes>>4)&7); - pri_mask = (attributes & 0x0800) ? 0x02 : 0; - tile_number = spriteram16[offs+1]&0x1fff; - sx = spriteram16[offs+2]&0x1ff; - sy = spriteram16[offs+3]&0x1ff; - if (sx >= 256) sx -= 512; - if (sy >= 256) sy -= 512; - - flipx = attributes & 0x2000; - flipy = attributes & 0x4000; /* ?? */ - color = attributes & 0xf; - - for (x = 0;x <= width;x++) - { - for (y = 0;y <= height;y++) - { - m_gfxdecode->gfx(3)->prio_transpen(bitmap,cliprect, - tile_number++, - color, - flipx,flipy, - flipx ? (sx + 16*(width-x)) : (sx + 16*x),flipy ? (sy + 16*(height-y)) : (sy + 16*y), - screen.priority(), - pri_mask,15); - } - } - } + return pri ? 0x02 : 0; } /* SPRITE INFO (8 bytes) @@ -193,7 +158,7 @@ void bloodbro_state::bloodbro_draw_sprites(screen_device &screen, bitmap_ind16 & -------X XXXXXXXX */ -void bloodbro_state::weststry_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +void weststry_state::weststry_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint16_t *spriteram16 = m_spriteram; int offs; @@ -238,18 +203,19 @@ uint32_t bloodbro_state::screen_update_bloodbro(screen_device &screen, bitmap_in screen.priority().fill(0, cliprect); - if(!(m_layer_en & 1)) + if(BIT(~m_layer_en, 0)) m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0); - if(!(m_layer_en & 2)) + if(BIT(~m_layer_en, 1)) m_fg_tilemap->draw(screen, bitmap, cliprect, 0,1); - if(!(m_layer_en & 0x10)) - bloodbro_draw_sprites(screen, bitmap,cliprect); - if(!(m_layer_en & 8)) + if(BIT(~m_layer_en, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); + if(BIT(~m_layer_en, 3)) m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0); + return 0; } -uint32_t bloodbro_state::screen_update_weststry(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t weststry_state::screen_update_weststry(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // The bootleg video hardware probably also allows BG scrolling, but weststry doesn't use it m_fg_tilemap->set_scrollx(0, (int8_t)m_scrollram[1] - 13); @@ -263,25 +229,3 @@ uint32_t bloodbro_state::screen_update_weststry(screen_device &screen, bitmap_in m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0); return 0; } - - -uint32_t bloodbro_state::screen_update_skysmash(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg_tilemap->set_scrollx(0,m_scrollram[0]); - m_bg_tilemap->set_scrolly(0,m_scrollram[1]); - m_fg_tilemap->set_scrollx(0,m_scrollram[2]); - m_fg_tilemap->set_scrolly(0,m_scrollram[3]); - - screen.priority().fill(0, cliprect); - - if(!(m_layer_en & 1)) - m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0); - if(!(m_layer_en & 2)) - m_fg_tilemap->draw(screen, bitmap, cliprect, 0,1); - if(!(m_layer_en & 0x10)) - bloodbro_draw_sprites(screen, bitmap,cliprect); - if(!(m_layer_en & 8)) - m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0); - - return 0; -} diff --git a/src/mame/seibu/dcon.cpp b/src/mame/seibu/dcon.cpp index 84dad3e00c8..0b7a0e564ee 100644 --- a/src/mame/seibu/dcon.cpp +++ b/src/mame/seibu/dcon.cpp @@ -256,11 +256,14 @@ static const gfx_layout dcon_tilelayout = }; static GFXDECODE_START( gfx_dcon ) - GFXDECODE_ENTRY( "gfx1", 0, dcon_charlayout, 1024+768, 16 ) - GFXDECODE_ENTRY( "gfx2", 0, dcon_tilelayout, 1024+0, 16 ) - GFXDECODE_ENTRY( "gfx3", 0, dcon_tilelayout, 1024+512, 16 ) - GFXDECODE_ENTRY( "gfx4", 0, dcon_tilelayout, 1024+256, 16 ) - GFXDECODE_ENTRY( "gfx5", 0, dcon_tilelayout, 0, 64 ) + GFXDECODE_ENTRY( "txtiles", 0, dcon_charlayout, 1024+768, 16 ) + GFXDECODE_ENTRY( "bgtiles", 0, dcon_tilelayout, 1024+0, 16 ) + GFXDECODE_ENTRY( "fgtiles", 0, dcon_tilelayout, 1024+512, 16 ) + GFXDECODE_ENTRY( "mgtiles", 0, dcon_tilelayout, 1024+256, 16 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_dcon_spr ) + GFXDECODE_ENTRY( "sprites", 0, dcon_tilelayout, 0, 64 ) GFXDECODE_END void dcon_state::layer_en_w(uint16_t data) @@ -302,6 +305,9 @@ void dcon_state::dcon(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_dcon); PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_dcon_spr); + m_spritegen->set_pri_callback(FUNC(dcon_state::pri_cb)); + /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -347,6 +353,9 @@ void dcon_state::sdgndmps(machine_config &config) /* PCB number is PB91008 */ GFXDECODE(config, m_gfxdecode, m_palette, gfx_dcon); PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_dcon_spr); + m_spritegen->set_pri_callback(FUNC(dcon_state::pri_cb)); + /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -380,20 +389,20 @@ ROM_START( dcon ) ROM_CONTINUE( 0x010000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "txtiles", 0 ) ROM_LOAD( "fix0", 0x000000, 0x10000, CRC(ab30061f) SHA1(14dba37fef7bd13c827fd542b24cc593dcdc9f99) ) /* chars */ ROM_LOAD( "fix1", 0x010000, 0x10000, CRC(a0582115) SHA1(498d6e4f631a5dfe54d5c2813c47d40c466b694d) ) - ROM_REGION( 0x080000, "gfx2", 0 ) + ROM_REGION( 0x080000, "bgtiles", 0 ) ROM_LOAD( "bg1", 0x000000, 0x80000, CRC(eac43283) SHA1(f5d384c98751002416013a9a920e2ab2cea61cb1) ) /* tiles */ - ROM_REGION( 0x080000, "gfx3", 0 ) + ROM_REGION( 0x080000, "fgtiles", 0 ) ROM_LOAD( "bg3", 0x000000, 0x80000, CRC(1408a1e0) SHA1(d96fb8a60af02df313ffc9e0284611d7ca50540d) ) /* tiles */ - ROM_REGION( 0x080000, "gfx4", 0 ) + ROM_REGION( 0x080000, "mgtiles", 0 ) ROM_LOAD( "bg2", 0x000000, 0x80000, CRC(01864eb6) SHA1(78f755d7462a787bd1a378184e8fce8fa889f258) ) /* tiles */ - ROM_REGION( 0x200000, "gfx5", 0 ) + ROM_REGION( 0x200000, "sprites", 0 ) ROM_LOAD( "obj0", 0x000000, 0x80000, CRC(c3af37db) SHA1(7d6ee07b6302aaec8d792faf78a37898a2ac3c4e) ) /* sprites */ ROM_LOAD( "obj1", 0x080000, 0x80000, CRC(be1f53ba) SHA1(061b80487e6c4040618af6ed9c5315fba44f5d0c) ) ROM_LOAD( "obj2", 0x100000, 0x80000, CRC(24e0b51c) SHA1(434b4d58f785eefb5380c08a0704c8dea6609268) ) @@ -415,20 +424,20 @@ ROM_START( sdgndmps ) ROM_CONTINUE( 0x10000, 0x08000 ) ROM_COPY( "audiocpu", 0x000000, 0x18000, 0x08000 ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "txtiles", 0 ) ROM_LOAD( "911-a08.66", 0x000000, 0x10000, CRC(e7e04823) SHA1(d9b1ace5cd8218d5a4767cf5adbc267dce7c0668) ) /* chars */ ROM_LOAD( "911-a07.73", 0x010000, 0x10000, CRC(6f40d4a9) SHA1(8abadb2dc07ac22081b2970358e9f92b90b174b0) ) - ROM_REGION( 0x080000, "gfx2", 0 ) + ROM_REGION( 0x080000, "bgtiles", 0 ) ROM_LOAD( "911-a12.63", 0x000000, 0x080000, CRC(8976bbb6) SHA1(6f510d6506e54ddec7119d85dcc0a169d4901983) ) - ROM_REGION( 0x080000, "gfx3", 0 ) + ROM_REGION( 0x080000, "fgtiles", 0 ) ROM_LOAD( "911-a11.65", 0x000000, 0x080000, CRC(3f3b7810) SHA1(0761c5fb0802fdd2ee7523f1f4e5cfb2c7a6fce6) ) - ROM_REGION( 0x100000, "gfx4", 0 ) + ROM_REGION( 0x100000, "mgtiles", 0 ) ROM_LOAD( "911-a13.64", 0x000000, 0x100000, CRC(f38a584a) SHA1(16dd8e7086949d14e9185c37313290024d6dafdc) ) - ROM_REGION( 0x200000, "gfx5", 0 ) + ROM_REGION( 0x200000, "sprites", 0 ) ROM_LOAD( "911-a10.73", 0x000000, 0x100000, CRC(80e341fb) SHA1(619e71aefd0b13a01a6a2ed5d8613fe56242d209) ) /* sprites */ ROM_LOAD( "911-a09.74", 0x100000, 0x100000, CRC(98f34519) SHA1(20319d546df104485ee553ce0e58364f927d1135) ) diff --git a/src/mame/seibu/dcon.h b/src/mame/seibu/dcon.h index 987c85ec509..c1ed2d69b8f 100644 --- a/src/mame/seibu/dcon.h +++ b/src/mame/seibu/dcon.h @@ -5,6 +5,8 @@ #pragma once +#include "sei021x_sei0220_spr.h" + #include "seibusound.h" #include "emupal.h" @@ -19,6 +21,7 @@ public: m_seibu_sound(*this, "seibu_sound"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), + m_spritegen(*this, "spritegen"), m_back_data(*this, "back_data"), m_fore_data(*this, "fore_data"), m_mid_data(*this, "mid_data"), @@ -34,6 +37,7 @@ private: required_device m_seibu_sound; required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; required_shared_ptr m_back_data; required_shared_ptr m_fore_data; @@ -70,7 +74,7 @@ private: uint32_t screen_update_dcon(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_sdgndmps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect); + uint32_t pri_cb(uint8_t pri, uint8_t ext); void dcon_map(address_map &map); void sdgndmps_map(address_map &map); }; diff --git a/src/mame/seibu/dcon_v.cpp b/src/mame/seibu/dcon_v.cpp index fa6a75857ea..3eebe0a1998 100644 --- a/src/mame/seibu/dcon_v.cpp +++ b/src/mame/seibu/dcon_v.cpp @@ -116,128 +116,15 @@ void dcon_state::video_start() save_item(NAME(m_layer_en)); } -void dcon_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect) +uint32_t dcon_state::pri_cb(uint8_t pri, uint8_t ext) { - uint16_t *spriteram16 = m_spriteram; - int offs,fx,fy,x,y,color,sprite; - int dx,dy,ax,ay,inc,pri_mask = 0; - - for (offs = 0;offs < 0x400;offs += 4) + switch(pri) { - if ((spriteram16[offs+0]&0x8000)!=0x8000) continue; - sprite = spriteram16[offs+1]; - - switch((sprite>>14) & 3) - { - case 0: pri_mask = 0xf0; // above foreground layer - break; - case 1: pri_mask = 0xfc; // above midground layer - break; - case 2: pri_mask = 0xfe; // above background layer - break; - case 3: pri_mask = 0; // above text layer - break; - } - - sprite &= 0x3fff; - - y = spriteram16[offs+3]; - x = spriteram16[offs+2]; - - if (x&0x8000) x=0-(0x200-(x&0x1ff)); - else x&=0x1ff; - if (y&0x8000) y=0-(0x200-(y&0x1ff)); - else y&=0x1ff; - - color = spriteram16[offs+0]&0x3f; - fx = spriteram16[offs+0]&0x4000; - fy = spriteram16[offs+0]&0x2000; - dy=((spriteram16[offs+0]&0x0380)>>7)+1; - dx=((spriteram16[offs+0]&0x1c00)>>10)+1; - - inc = 0; - - for (ax=0; axgfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+ay*16, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+ay*16 + 512, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+ay*16 - 512, - screen.priority(),pri_mask,15); - } - else if (fx && !fy) - { - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+ay*16, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+ay*16 + 512, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+ay*16 - 512, - screen.priority(),pri_mask,15); - } - else if (!fx && fy) - { - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+(dy-1-ay)*16, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+(dy-1-ay)*16 + 512, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+ax*16,y+(dy-1-ay)*16 - 512, - screen.priority(),pri_mask,15); - } - else - { - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+(dy-1-ay)*16, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+(dy-1-ay)*16 + 512, - screen.priority(),pri_mask,15); - - // wrap around y - m_gfxdecode->gfx(4)->prio_transpen(bitmap,cliprect, - sprite + inc, - color,fx,fy,x+(dx-1-ax)*16,y+(dy-1-ay)*16 - 512, - screen.priority(),pri_mask,15); - } - - inc++; - } + case 0: return 0xf0; // above foreground layer + case 1: return 0xfc; // above midground layer + case 2: return 0xfe; // above background layer + case 3: + default: return 0; // above text layer } } @@ -253,22 +140,22 @@ uint32_t dcon_state::screen_update_dcon(screen_device &screen, bitmap_ind16 &bit m_foreground_layer->set_scrollx(0, m_scroll_ram[4] ); m_foreground_layer->set_scrolly(0, m_scroll_ram[5] ); - if (!(m_layer_en & 1)) + if (BIT(~m_layer_en, 0)) m_background_layer->draw(screen, bitmap, cliprect, 0,0); else bitmap.fill(15, cliprect); /* Should always be black, not pen 15 */ - if (!(m_layer_en & 2)) + if (BIT(~m_layer_en, 1)) m_midground_layer->draw(screen, bitmap, cliprect, 0,1); - if (!(m_layer_en & 4)) + if (BIT(~m_layer_en, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0,2); - if (!(m_layer_en & 8)) + if (BIT(~m_layer_en, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0,4); - if (!(m_layer_en & 0x10)) - draw_sprites(screen, bitmap,cliprect); + if (BIT(~m_layer_en, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); return 0; } @@ -294,22 +181,22 @@ uint32_t dcon_state::screen_update_sdgndmps(screen_device &screen, bitmap_ind16 m_text_layer->set_scrollx(0, /*m_scroll_ram[6] + */ 128 ); m_text_layer->set_scrolly(0, /*m_scroll_ram[7] + */ 0 ); - if (!(m_layer_en & 1)) + if (BIT(~m_layer_en, 0)) m_background_layer->draw(screen, bitmap, cliprect, 0,0); else bitmap.fill(15, cliprect); /* Should always be black, not pen 15 */ - if (!(m_layer_en & 2)) + if (BIT(~m_layer_en, 1)) m_midground_layer->draw(screen, bitmap, cliprect, 0,1); - if (!(m_layer_en & 4)) + if (BIT(~m_layer_en, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0,2); - if (!(m_layer_en & 8)) + if (BIT(~m_layer_en, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0,4); - if (!(m_layer_en & 0x10)) - draw_sprites(screen, bitmap,cliprect); + if (BIT(~m_layer_en, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); return 0; } diff --git a/src/mame/seibu/goodejan.cpp b/src/mame/seibu/goodejan.cpp index 39ffa347253..dcbd6b218d7 100644 --- a/src/mame/seibu/goodejan.cpp +++ b/src/mame/seibu/goodejan.cpp @@ -72,6 +72,7 @@ Secret menu hack [totmejan only] (I couldn't find official way to enter, so it's #include "emu.h" +#include "sei021x_sei0220_spr.h" #include "seibu_crtc.h" #include "seibusound.h" @@ -96,6 +97,7 @@ public: , m_maincpu(*this, "maincpu") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") + , m_spritegen(*this, "spritegen") , m_screen(*this, "screen") , m_crtc(*this, "crtc") , m_sc0_vram(*this, "sc0_vram") @@ -116,6 +118,7 @@ private: required_device m_maincpu; required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; required_device m_screen; required_device m_crtc; @@ -154,9 +157,8 @@ private: void vblank_irq(int state); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, bool coordinate_format); + uint32_t pri_cb(uint8_t pri, uint8_t ext); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_totmejan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void common_io_map(address_map &map); void goodejan_io_map(address_map &map); @@ -248,87 +250,39 @@ TILE_GET_INFO_MEMBER( goodejan_state::seibucrtc_sc0_tile_info ) u32 tile = m_sc0_vram[tile_index] & 0xfff; u32 color = (m_sc0_vram[tile_index] >> 12) & 0x0f; tile += (m_seibucrtc_sc0bank << 12); - tileinfo.set(1, tile, color, 0); + tileinfo.set(0, tile, color, 0); } TILE_GET_INFO_MEMBER( goodejan_state::seibucrtc_sc2_tile_info ) { u32 tile = m_sc2_vram[tile_index] & 0xfff; u32 color = (m_sc2_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(2, tile, color, 0); + tileinfo.set(1, tile, color, 0); } TILE_GET_INFO_MEMBER( goodejan_state::seibucrtc_sc1_tile_info ) { u32 tile = m_sc1_vram[tile_index] & 0xfff; u32 color = (m_sc1_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(3, tile, color, 0); + tileinfo.set(2, tile, color, 0); } TILE_GET_INFO_MEMBER( goodejan_state::seibucrtc_sc3_tile_info ) { u32 tile = m_sc3_vram[tile_index] & 0xfff; u32 color = (m_sc3_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(4, tile, color, 0); + tileinfo.set(3, tile, color, 0); } -void goodejan_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, bool coordinate_format) +uint32_t goodejan_state::pri_cb(uint8_t pri, uint8_t ext) { - constexpr u32 pri_mask[4] = { - GFX_PMASK_8, - GFX_PMASK_8 | GFX_PMASK_4, - GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2, - 0 - }; - for (int offs = 0; offs < 0x400; offs += 4) + switch (pri) { - if ((m_spriteram16[offs + 0] & 0x8000) != 0x8000) continue; - u32 sprite = m_spriteram16[offs + 1]; - u32 pri = pri_mask[(sprite >> 14) & 3]; - sprite &= 0x1fff; - - int y = m_spriteram16[offs + 3]; - int x = m_spriteram16[offs + 2]; - - if (!coordinate_format) // SEI0210 - { - if (x & 0x8000) x = 0 - (0x200 - (x & 0x1ff)); - else x &= 0x1ff; - if (y & 0x8000) y = 0 - (0x200 - (y & 0x1ff)); - else y &= 0x1ff; - } - else // SEI0211 - { - x &= 0x1ff; - if (x >= 0x180) x -= 0x200; - y &= 0x1ff; - if (y >= 0x180) y -= 0x200; - } - - u32 color = m_spriteram16[offs + 0] & 0x3f; - bool fx = m_spriteram16[offs + 0] & 0x4000; - bool fy = m_spriteram16[offs + 0] & 0x2000; - u32 dy = ((m_spriteram16[offs + 0] & 0x0380) >> 7) + 1; - u32 dx = ((m_spriteram16[offs + 0] & 0x1c00) >> 10) + 1; - - for (int ax = 0; ax < dx; ax++) - for (int ay = 0; ay < dy; ay++) { - if (!fx) - m_gfxdecode->gfx(0)->prio_transpen(bitmap, cliprect, - sprite++, - color, - fx, fy, - x + ax * 16, y + ay * 16, - screen.priority(), pri, 15); - else - m_gfxdecode->gfx(0)->prio_transpen(bitmap, cliprect, - sprite++, - color, - fx, fy, - x + (dx - 1 - ax) * 16, - y + ay * 16, - screen.priority(), pri, 15); - } + case 0: return GFX_PMASK_8; + case 1: return GFX_PMASK_8 | GFX_PMASK_4; + case 2: return GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2; + case 3: + default: return 0; } } @@ -367,28 +321,7 @@ uint32_t goodejan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm if(SEIBU_CRTC_ENABLE_SC2) { m_sc2_tilemap->draw(screen, bitmap, cliprect, 0, 2); } if(SEIBU_CRTC_ENABLE_SC1) { m_sc1_tilemap->draw(screen, bitmap, cliprect, 0, 4); } if(SEIBU_CRTC_ENABLE_SC3) { m_sc3_tilemap->draw(screen, bitmap, cliprect, 0, 8); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(screen, bitmap, cliprect, true); } - - return 0; -} - -uint32_t goodejan_state::screen_update_totmejan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - screen.priority().fill(0, cliprect); - bitmap.fill(m_palette->pen(0x7ff), cliprect); //black pen - - m_sc0_tilemap->set_scrollx(0, (SEIBU_CRTC_SC0_SX) & 0x1ff ); - m_sc0_tilemap->set_scrolly(0, (SEIBU_CRTC_SC0_SY) & 0x1ff ); - m_sc2_tilemap->set_scrollx(0, (SEIBU_CRTC_SC2_SX) & 0x1ff ); - m_sc2_tilemap->set_scrolly(0, (SEIBU_CRTC_SC2_SY) & 0x1ff ); - m_sc1_tilemap->set_scrollx(0, (SEIBU_CRTC_SC1_SX) & 0x1ff ); - m_sc1_tilemap->set_scrolly(0, (SEIBU_CRTC_SC1_SY) & 0x1ff ); - - if(SEIBU_CRTC_ENABLE_SC0) { m_sc0_tilemap->draw(screen, bitmap, cliprect, 0, 1); } - if(SEIBU_CRTC_ENABLE_SC2) { m_sc2_tilemap->draw(screen, bitmap, cliprect, 0, 2); } - if(SEIBU_CRTC_ENABLE_SC1) { m_sc1_tilemap->draw(screen, bitmap, cliprect, 0, 4); } - if(SEIBU_CRTC_ENABLE_SC3) { m_sc3_tilemap->draw(screen, bitmap, cliprect, 0, 8); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(screen, bitmap, cliprect, false); } + if(SEIBU_CRTC_ENABLE_SPR) { m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram16, m_spriteram16.bytes()); } return 0; } @@ -609,13 +542,16 @@ static const gfx_layout charlayout = }; static GFXDECODE_START( gfx_goodejan ) - GFXDECODE_ENTRY( "spr_gfx", 0,tilelayout, 0x200, 0x40 ) /* Sprites */ GFXDECODE_ENTRY( "bg_gfx", 0, tilelayout, 0x000, 0x30 ) /* Tiles */ - GFXDECODE_ENTRY( "md_gfx", 0, tilelayout, 0x300, 0x10 ) /* Text */ + GFXDECODE_ENTRY( "md_gfx", 0, tilelayout, 0x300, 0x10 ) /* Tiles */ GFXDECODE_ENTRY( "fg_gfx", 0, tilelayout, 0x600, 0x10 ) /* Tiles */ GFXDECODE_ENTRY( "tx_gfx", 0, charlayout, 0x100, 0x10 ) /* Text */ GFXDECODE_END +static GFXDECODE_START( gfx_goodejan_spr ) + GFXDECODE_ENTRY( "spr_gfx", 0, tilelayout, 0x200, 0x40 ) /* Sprites */ +GFXDECODE_END + void goodejan_state::vblank_irq(int state) { if (state) @@ -664,6 +600,9 @@ void goodejan_state::goodejan(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_goodejan); PALETTE(config, m_palette).set_format(palette_device::xBGR_444, 0x800); + SEI0211(config, m_spritegen, GOODEJAN_MHZ3, m_palette, gfx_goodejan_spr); + m_spritegen->set_pri_callback(FUNC(goodejan_state::pri_cb)); + /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -686,7 +625,10 @@ void goodejan_state::totmejan(machine_config &config) { goodejan(config); m_maincpu->set_addrmap(AS_IO, &goodejan_state::totmejan_io_map); - m_screen->set_screen_update(FUNC(goodejan_state::screen_update_totmejan)); + + SEI0210(config.replace(), m_spritegen, XTAL(12'000'000), m_palette, gfx_goodejan_spr); + m_spritegen->set_pri_callback(FUNC(goodejan_state::pri_cb)); + } ROM_START( totmejan ) diff --git a/src/mame/seibu/legionna.cpp b/src/mame/seibu/legionna.cpp index c341d3fef46..6ec1981dc1c 100644 --- a/src/mame/seibu/legionna.cpp +++ b/src/mame/seibu/legionna.cpp @@ -1159,15 +1159,17 @@ static const gfx_layout tilelayout = 16*16*4 }; -static GFXDECODE_START( gfx_legionna ) // Background and Midground has shared ROM +static GFXDECODE_START( gfx_legionna_spr ) GFXDECODE_ENTRY( "sprite", 0, tilelayout, 64*16, 64 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_legionna ) // Background and Midground has shared ROM GFXDECODE_ENTRY( "char", 0, charlayout, 48*16, 16 ) GFXDECODE_ENTRY( "back", 0, tilelayout, 0, 32 ) GFXDECODE_ENTRY( "fore", 0, tilelayout, 32*16, 16 ) GFXDECODE_END static GFXDECODE_START( gfx_heatbrl ) // Midground has independent ROM - GFXDECODE_ENTRY( "sprite", 0, tilelayout, 64*16, 64 ) GFXDECODE_ENTRY( "char", 0, charlayout, 48*16, 16 ) GFXDECODE_ENTRY( "back", 0, tilelayout, 0*16, 16 ) GFXDECODE_ENTRY( "fore", 0, tilelayout, 32*16, 16 ) @@ -1209,6 +1211,9 @@ void legionna_state::legionna(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_legionna); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(12'000'000), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::pri_cb)); + MCFG_VIDEO_START_OVERRIDE(legionna_state,legionna) /* sound hardware */ @@ -1262,6 +1267,9 @@ void legionna_state::heatbrl(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_heatbrl); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(12'000'000), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::pri_cb)); + MCFG_VIDEO_START_OVERRIDE(legionna_state,heatbrl) /* sound hardware */ @@ -1318,6 +1326,10 @@ void legionna_state::godzilla(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_legionna); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::pri_cb)); + m_spritegen->set_gfxbank_callback(FUNC(legionna_state::godzilla_tile_cb)); + MCFG_VIDEO_START_OVERRIDE(legionna_state,godzilla) /* sound hardware */ @@ -1372,6 +1384,10 @@ void legionna_state::denjinmk(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_heatbrl); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::pri_cb)); + m_spritegen->set_gfxbank_callback(FUNC(legionna_state::godzilla_tile_cb)); + MCFG_VIDEO_START_OVERRIDE(legionna_state,denjinmk) /* sound hardware */ @@ -1426,6 +1442,10 @@ void legionna_state::grainbow(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_legionna); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::grainbow_pri_cb)); + m_spritegen->set_offset(16, 16); + MCFG_VIDEO_START_OVERRIDE(legionna_state,grainbow) /* sound hardware */ @@ -1484,6 +1504,9 @@ void legionna_state::cupsoc(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_legionna); PALETTE(config, m_palette, palette_device::BLACK).set_format(palette_device::xBGR_555, 128*16); + SEI0211(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_legionna_spr); + m_spritegen->set_pri_callback(FUNC(legionna_state::pri_cb)); + MCFG_VIDEO_START_OVERRIDE(legionna_state,cupsoc) /* sound hardware */ diff --git a/src/mame/seibu/legionna.h b/src/mame/seibu/legionna.h index 14439ff5d80..e866d98defe 100644 --- a/src/mame/seibu/legionna.h +++ b/src/mame/seibu/legionna.h @@ -5,6 +5,7 @@ #pragma once +#include "sei021x_sei0220_spr.h" #include "seibu_crtc.h" #include "seibucop.h" @@ -35,6 +36,7 @@ public: , m_oki(*this, "oki") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") + , m_spritegen(*this, "spritegen") , m_crtc(*this, "crtc") , m_raiden2cop(*this, "raiden2cop") { @@ -88,9 +90,11 @@ private: u32 screen_update_heatbrl(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); u32 screen_update_godzilla(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); u32 screen_update_grainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect); + u32 pri_cb(u8 pri, u8 ext); + u32 grainbow_pri_cb(u8 pri, u8 ext); + u32 godzilla_tile_cb(u32 code, u8 ext, u8 y); void descramble_legionnaire_gfx(u8* src); - void common_video_start(bool split, bool has_extended_banking, bool has_extended_priority); + void common_video_start(bool split); void common_video_allocate_ptr(); void cupsoc_map(address_map &map); @@ -113,14 +117,10 @@ private: std::unique_ptr m_paletteram; u16 m_layer_disable; std::unique_ptr m_layer_config; - int m_sprite_xoffs = 0; - int m_sprite_yoffs = 0; tilemap_t *m_background_layer = nullptr; tilemap_t *m_foreground_layer = nullptr; tilemap_t *m_midground_layer = nullptr; tilemap_t *m_text_layer = nullptr; - bool m_has_extended_banking = false; - bool m_has_extended_priority = false; u16 m_sprite_pri_mask[4]{}; u16 m_back_gfx_bank; u16 m_fore_gfx_bank; @@ -133,6 +133,7 @@ private: required_device m_oki; required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; required_device m_crtc; optional_device m_raiden2cop; }; diff --git a/src/mame/seibu/legionna_v.cpp b/src/mame/seibu/legionna_v.cpp index 6b1492de526..98dfbc1569f 100644 --- a/src/mame/seibu/legionna_v.cpp +++ b/src/mame/seibu/legionna_v.cpp @@ -145,31 +145,31 @@ void legionna_state::text_w(offs_t offset, u16 data, u16 mem_mask) TILE_GET_INFO_MEMBER(legionna_state::get_back_tile_info) { const u16 tile = m_back_data[tile_index]; - tileinfo.set(2, (tile & 0xfff) | m_back_gfx_bank, (tile >> 12) & 0xf, 0); + tileinfo.set(1, (tile & 0xfff) | m_back_gfx_bank, (tile >> 12) & 0xf, 0); } TILE_GET_INFO_MEMBER(legionna_state::get_mid_tile_info_split) { const u16 tile = m_mid_data[tile_index]; - tileinfo.set(4, (tile & 0xfff) | m_mid_gfx_bank, (tile >> 12) & 0xf, 0); + tileinfo.set(3, (tile & 0xfff) | m_mid_gfx_bank, (tile >> 12) & 0xf, 0); } TILE_GET_INFO_MEMBER(legionna_state::get_mid_tile_info_share_bgrom) { const u16 tile = m_mid_data[tile_index]; - tileinfo.set(2, (tile & 0xfff) | 0x1000, ((tile >> 12) & 0xf) | 0x10, 0); + tileinfo.set(1, (tile & 0xfff) | 0x1000, ((tile >> 12) & 0xf) | 0x10, 0); } TILE_GET_INFO_MEMBER(legionna_state::get_fore_tile_info) { const u16 tile = m_fore_data[tile_index]; - tileinfo.set(3, (tile & 0xfff) | m_fore_gfx_bank, (tile >> 12) & 0xf, 0); + tileinfo.set(2, (tile & 0xfff) | m_fore_gfx_bank, (tile >> 12) & 0xf, 0); } TILE_GET_INFO_MEMBER(legionna_state::get_text_tile_info) { const u16 tile = m_textram[tile_index]; - tileinfo.set(1, tile & 0xfff, (tile >> 12) & 0xf, 0); + tileinfo.set(0, tile & 0xfff, (tile >> 12) & 0xf, 0); } void legionna_state::common_video_allocate_ptr() @@ -182,9 +182,6 @@ void legionna_state::common_video_allocate_ptr() m_paletteram = make_unique_clear(0x1000/2); m_palette->basemem().set(m_paletteram.get(), 0x1000/2 * sizeof(u16), 16, ENDIANNESS_BIG, 2); - m_sprite_xoffs = 0; - m_sprite_yoffs = 0; - save_pointer(NAME(m_back_data), 0x800/2); save_pointer(NAME(m_fore_data), 0x800/2); save_pointer(NAME(m_mid_data), 0x800/2); @@ -200,7 +197,7 @@ void legionna_state::common_video_allocate_ptr() save_item(NAME(m_layer_disable)); } -void legionna_state::common_video_start(bool split, bool has_extended_banking, bool has_extended_priority) +void legionna_state::common_video_start(bool split) { common_video_allocate_ptr(); @@ -216,9 +213,6 @@ void legionna_state::common_video_start(bool split, bool has_extended_banking, b m_foreground_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(legionna_state::get_fore_tile_info)), TILEMAP_SCAN_ROWS,16,16,32,32); m_text_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(legionna_state::get_text_tile_info)), TILEMAP_SCAN_ROWS, 8, 8,64,32); - m_has_extended_banking = has_extended_banking; - m_has_extended_priority = has_extended_priority; - m_background_layer->set_transparent_pen(15); m_midground_layer->set_transparent_pen(15); m_foreground_layer->set_transparent_pen(15); @@ -227,7 +221,7 @@ void legionna_state::common_video_start(bool split, bool has_extended_banking, b VIDEO_START_MEMBER(legionna_state,legionna) { - common_video_start(false, false, false); + common_video_start(false); m_sprite_pri_mask[0] = 0x0000; m_sprite_pri_mask[1] = 0xfff0; @@ -237,7 +231,7 @@ VIDEO_START_MEMBER(legionna_state,legionna) VIDEO_START_MEMBER(legionna_state,heatbrl) { - common_video_start(true, false, false); + common_video_start(true); m_sprite_pri_mask[0] = 0xfff0; m_sprite_pri_mask[1] = 0xfffc; @@ -248,7 +242,7 @@ VIDEO_START_MEMBER(legionna_state,heatbrl) VIDEO_START_MEMBER(legionna_state,godzilla) { - common_video_start(false, true, false); + common_video_start(false); m_sprite_pri_mask[0] = 0xfff0; m_sprite_pri_mask[1] = 0xfffc; @@ -259,7 +253,7 @@ VIDEO_START_MEMBER(legionna_state,godzilla) VIDEO_START_MEMBER(legionna_state,denjinmk) { - common_video_start(true, true, false); + common_video_start(true); m_sprite_pri_mask[0] = 0xfff0; // normal sprites m_sprite_pri_mask[1] = 0xfffc; // luna park horse rides @@ -271,7 +265,7 @@ VIDEO_START_MEMBER(legionna_state,denjinmk) VIDEO_START_MEMBER(legionna_state,cupsoc) { - common_video_start(false, false, false); + common_video_start(false); m_sprite_pri_mask[0] = 0xfff0; // title screen "Seibu Cup Soccer" elements m_sprite_pri_mask[1] = 0xfffc; // ? @@ -281,8 +275,8 @@ VIDEO_START_MEMBER(legionna_state,cupsoc) VIDEO_START_MEMBER(legionna_state,grainbow) { - common_video_start(false, false, true); - m_sprite_xoffs = m_sprite_yoffs = 16; + common_video_start(false); + m_sprite_pri_mask[0] = 0xfff0; // m_sprite_pri_mask[1] = 0xfffc; // level 2 and 3 m_sprite_pri_mask[2] = 0xfffe; // swamp monster mask effect @@ -317,127 +311,26 @@ VIDEO_START_MEMBER(legionna_state,grainbow) *************************************************************************/ -void legionna_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect) +u32 legionna_state::pri_cb(u8 pri, u8 ext) { - for (int offs = 0; offs < 0x400; offs += 4) - { - const u16 data = m_spriteram[offs]; - if (!(data & 0x8000)) continue; - - u8 cur_pri = 0; - int pri_mask = 0; - - if (m_has_extended_priority) - { - // SD Gundam uses this arrangement, with bit 14 seemingly unused - // side effect of using the COP sprite DMA? - cur_pri = (m_spriteram[offs+1] & 0x8000) >> 14; - - if (data & 0x0040) - cur_pri |= 1; - } - else - cur_pri = (m_spriteram[offs+1] & 0xc000) >> 14; - - pri_mask = m_sprite_pri_mask[cur_pri]; - - u32 sprite = m_spriteram[offs+1]; - - sprite &= 0x3fff; - - if (m_has_extended_banking) - { - if (data & 0x0040) - { - sprite |= 0x4000;//tile banking,used in Denjin Makai - } - if (m_spriteram[offs+3] & 0x8000) - { - sprite |= 0x8000;//tile banking?,used in Denjin Makai - } - } - - int y = m_spriteram[offs+3]; - int x = m_spriteram[offs+2]; - - /* heated barrel hardware seems to need 0x1ff with 0x100 sign bit for sprite wrap, - this doesn't work on denjin makai as the visible area is larger */ - if (cliprect.max_x<(320-1)) - { - x &= 0x1ff; - y &= 0x1ff; - - if (x & 0x100) x -= 0x200; - if (y & 0x100) y -= 0x200; - } - else - { - x &= 0xfff; - y &= 0xfff; - - if (x & 0x800) x -= 0x1000; - if (y & 0x800) y -= 0x1000; - - } - - - const u32 color = (data & 0x003f); - const u8 fx = (data & 0x4000) >> 14; - const u8 fy = (data & 0x2000) >> 13; - const u8 dy = ((data & 0x0380) >> 7) + 1; - const u8 dx = ((data & 0x1c00) >> 10) + 1; - - if (!fx) - { - if (!fy) - { - for (int ax = 0; ax < dx; ax++) - for (int ay = 0; ay < dy; ay++) - { - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - sprite++, - color,fx,fy,(x+ax*16)+m_sprite_xoffs,y+ay*16+m_sprite_yoffs, - screen.priority(),pri_mask, 15); - } - } - else - { - for (int ax = 0; ax < dx; ax++) - for (int ay = 0; ay < dy; ay++) - { - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - sprite++, - color,fx,fy,(x+ax*16)+m_sprite_xoffs,y+(dy-ay-1)*16+m_sprite_yoffs, - screen.priority(),pri_mask,15); - } - } - } - else - { - if (!fy) - { - for (int ax = 0; ax < dx; ax++) - for (int ay = 0; ay < dy; ay++) - { - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - sprite++, - color,fx,fy,(x+(dx-ax-1)*16)+m_sprite_xoffs,y+ay*16+m_sprite_yoffs, - screen.priority(),pri_mask,15); - } - } - else - { - for (int ax = 0; ax < dx; ax++) - for (int ay = 0; ay < dy; ay++) - { - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - sprite++, - color,fx,fy,(x+(dx-ax-1)*16)+m_sprite_xoffs,y+(dy-ay-1)*16+m_sprite_yoffs, - screen.priority(),pri_mask, 15); - } - } - } - } + return m_sprite_pri_mask[pri]; +} + +u32 legionna_state::grainbow_pri_cb(u8 pri, u8 ext) +{ + // SD Gundam uses this arrangement, with bit 14 seemingly unused + // side effect of using the COP sprite DMA? + pri = (pri & 2) | (ext & 1); + return m_sprite_pri_mask[pri]; +} + +u32 legionna_state::godzilla_tile_cb(u32 code, u8 ext, u8 y) +{ + if (ext) + code |= 0x4000; //tile banking,used in Denjin Makai + if (y) + code |= 0x8000; //tile banking?,used in Denjin Makai + return code; } u32 legionna_state::screen_update_legionna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -446,13 +339,13 @@ u32 legionna_state::screen_update_legionna(screen_device &screen, bitmap_ind16 & screen.priority().fill(0, cliprect); bitmap.fill(m_palette->black_pen(), cliprect); /* wrong color? */ - if (!(m_layer_disable & 0x0001)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 0); - if (!(m_layer_disable & 0x0002)) m_background_layer->draw(screen, bitmap, cliprect, 0, 1); - if (!(m_layer_disable & 0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); - if (!(m_layer_disable & 0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); + if (BIT(~m_layer_disable, 0)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 0); + if (BIT(~m_layer_disable, 1)) m_background_layer->draw(screen, bitmap, cliprect, 0, 1); + if (BIT(~m_layer_disable, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); + if (BIT(~m_layer_disable, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - if (!(m_layer_disable & 0x0010)) - draw_sprites(screen,bitmap,cliprect); + if (BIT(~m_layer_disable, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); //if (machine().input().code_pressed_once(KEYCODE_Z)) // if (m_raiden2cop) m_raiden2cop->dump_table(); @@ -467,13 +360,13 @@ u32 legionna_state::screen_update_heatbrl(screen_device &screen, bitmap_ind16 &b bitmap.fill(m_palette->black_pen(), cliprect); /* wrong color? */ // TODO: priority order is different than anything else? - if (!(m_layer_disable & 0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 0); - if (!(m_layer_disable & 0x0002)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); - if (!(m_layer_disable & 0x0001)) m_background_layer->draw(screen, bitmap, cliprect, 0, 2); - if (!(m_layer_disable & 0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); + if (BIT(~m_layer_disable, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 0); + if (BIT(~m_layer_disable, 1)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); + if (BIT(~m_layer_disable, 0)) m_background_layer->draw(screen, bitmap, cliprect, 0, 2); + if (BIT(~m_layer_disable, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - if (!(m_layer_disable & 0x0010)) - draw_sprites(screen,bitmap,cliprect); + if (BIT(~m_layer_disable, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); //if (machine().input().code_pressed_once(KEYCODE_Z)) // if (m_raiden2cop) m_raiden2cop->dump_table(); @@ -488,13 +381,13 @@ u32 legionna_state::screen_update_godzilla(screen_device &screen, bitmap_ind16 & // matches PCB recording for Denjin Makai, settable thru CRTC? bitmap.fill(0xff, cliprect); - if (!(m_layer_disable & 0x0001)) m_background_layer->draw(screen, bitmap, cliprect, 0, 0); - if (!(m_layer_disable & 0x0002)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); - if (!(m_layer_disable & 0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); - if (!(m_layer_disable & 0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); + if (BIT(~m_layer_disable, 0)) m_background_layer->draw(screen, bitmap, cliprect, 0, 0); + if (BIT(~m_layer_disable, 1)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); + if (BIT(~m_layer_disable, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); + if (BIT(~m_layer_disable, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - if (!(m_layer_disable & 0x0010)) - draw_sprites(screen,bitmap,cliprect); + if (BIT(~m_layer_disable, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); //if (machine().input().code_pressed_once(KEYCODE_Z)) // if (m_raiden2cop) m_raiden2cop->dump_table(); @@ -508,20 +401,13 @@ u32 legionna_state::screen_update_grainbow(screen_device &screen, bitmap_ind16 & bitmap.fill(m_palette->black_pen(), cliprect); screen.priority().fill(0, cliprect); - if (!(m_layer_disable & 1)) - m_background_layer->draw(screen, bitmap, cliprect, 0,0); - - if (!(m_layer_disable & 2)) - m_midground_layer->draw(screen, bitmap, cliprect, 0,1); - - if (!(m_layer_disable & 4)) - m_foreground_layer->draw(screen, bitmap, cliprect, 0,2); - - if (!(m_layer_disable & 8)) - m_text_layer->draw(screen, bitmap, cliprect, 0,4); + if (BIT(~m_layer_disable, 0)) m_background_layer->draw(screen, bitmap, cliprect, 0, 0); + if (BIT(~m_layer_disable, 1)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); + if (BIT(~m_layer_disable, 2)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); + if (BIT(~m_layer_disable, 3)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - if (!(m_layer_disable & 0x0010)) - draw_sprites(screen,bitmap,cliprect); + if (BIT(~m_layer_disable, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); //if (machine().input().code_pressed_once(KEYCODE_Z)) // if (m_raiden2cop) m_raiden2cop->dump_table(); diff --git a/src/mame/seibu/sei021x_sei0220_spr.cpp b/src/mame/seibu/sei021x_sei0220_spr.cpp new file mode 100644 index 00000000000..eb024f90c39 --- /dev/null +++ b/src/mame/seibu/sei021x_sei0220_spr.cpp @@ -0,0 +1,193 @@ +// license:BSD-3-Clause +// copyright-holders:David Graves, Angelo Salese, David Haywood, Tomasz Slanina, Carlos A. Lozano, Bryan McPhail, Pierpaolo Prazzoli +/* + Seibu Kaihatsu SEI0210/SEI0211/SEI0220(BP) Sprite generator emulation + + Used by Seibu Kaihatsu at 1990 to 1994, SEI0210/SEI0211 is paired with + SEI0220(BP). + + SEI0210 and SEI0211 is similar, but coordinate format is different. + Another difference between these chips are still unknown. + + Used in: + banprestoms.cpp + bloodbro.cpp* + dcon.cpp + goodejan.cpp + legionna.cpp + sengokmj.cpp + + * Using alternative sprite format. + + TODO: + - flip screen support +*/ + +#include "emu.h" +#include "sei021x_sei0220_spr.h" +#include "screen.h" + + +DEFINE_DEVICE_TYPE(SEI0210, sei0210_device, "sei0210", "Seibu Kaihatsu SEI0210 Sprite generator") +DEFINE_DEVICE_TYPE(SEI0211, sei0211_device, "sei0211", "Seibu Kaihatsu SEI0211 Sprite generator") + +sei0210_device::sei0210_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_gfx_interface(mconfig, *this) + , m_pri_cb(*this) + , m_gfxbank_cb(*this) + , m_alt_format(false) + , m_xoffset(0) + , m_yoffset(0) +{ +} + +sei0210_device::sei0210_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sei0210_device(mconfig, SEI0210, tag, owner, clock) +{ +} + +sei0211_device::sei0211_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sei0210_device(mconfig, SEI0211, tag, owner, clock) +{ +} + +void sei0210_device::device_start() +{ + m_pri_cb.resolve(); + m_gfxbank_cb.resolve(); +} + +void sei0210_device::device_reset() +{ +} + +/* + +=============================================================== + +Common sprite format (8 byte per sprites) + +Offset Bit Description + fedc ba98 7654 3210 +00 x--- ---- ---- ---- Enable this sprite + -x-- ---- ---- ---- Flip X + --x- ---- ---- ---- Flip Y + ---x xx-- ---- ---- Sprite width + ---- --xx x--- ---- Sprite height + ---- ---- -x-- ---- (Optional) Extra bit + ---- ---- --xx xxxx Color index +02 xx-- ---- ---- ---- Priority + --xx xxxx xxxx xxxx Tile index +04 x--- ---- ---- ---- (Optional) X sign bit + ---- ---x xxxx xxxx X position +06 x--- ---- ---- ---- (Optional) Y sign bit or Extra bit + ---- ---x xxxx xxxx Y position + +Unmarked bits are unused/unknown. + +=============================================================== + +Blood Bros. sprite format (8 byte per sprites) + +Offset Bit Description + fedc ba98 7654 3210 +00 x--- ---- ---- ---- Disable this sprite + -x-- ---- ---- ---- Flip Y + --x- ---- ---- ---- Flip X + ---- x--- ---- ---- Priority + ---- --xx x--- ---- Sprite width + ---- ---- -xxx ---- Sprite height + ---- ---- ---- xxxx Color index +02 ---x xxxx xxxx xxxx Tile index +04 x--- ---- ---- ---- (Optional) X sign bit + ---- ---x xxxx xxxx X position +06 x--- ---- ---- ---- (Optional) Y sign bit + ---- ---x xxxx xxxx Y position + +Unmarked bits are unused/unknown. + +=============================================================== + +*/ +template +void sei0210_device::draw(screen_device &screen, T &bitmap, const rectangle cliprect, u16* spriteram, u16 size) +{ + for (int i = 0; i < (size / 2); i += 4) + { + bool flipx, flipy; + u8 pri = 0, ext = 0; + u8 sizex, sizey; + u32 color, code; + s32 x, y; + if (m_alt_format) + { + if (BIT(spriteram[i], 15)) + continue; + + flipy = BIT(spriteram[i + 0], 14); + flipx = BIT(spriteram[i + 0], 13); + pri = BIT(spriteram[i + 0], 11); + sizex = BIT(spriteram[i + 0], 7, 3) + 1; + sizey = BIT(spriteram[i + 0], 4, 3) + 1; + color = BIT(spriteram[i + 0], 0, 4); + code = BIT(spriteram[i + 1], 0, 13); + x = BIT(spriteram[i + 2], 0, 9); + y = BIT(spriteram[i + 3], 0, 9); + + if (x >= 0x180) x -= 0x200; + if (y >= 0x180) y -= 0x200; + } + else + { + if (BIT(~spriteram[i], 15)) + continue; + + flipx = BIT(spriteram[i + 0], 14); + flipy = BIT(spriteram[i + 0], 13); + sizex = BIT(spriteram[i + 0], 10, 3) + 1; + sizey = BIT(spriteram[i + 0], 7, 3) + 1; + ext = BIT(spriteram[i + 0], 6); + color = BIT(spriteram[i + 0], 0, 6); + pri = BIT(spriteram[i + 1], 14, 2); + code = BIT(spriteram[i + 1], 0, 14); + x = get_coordinate(spriteram[i + 2]); + y = get_coordinate(spriteram[i + 3]); + } + + x += m_xoffset; + y += m_yoffset; + + u32 pri_mask = 0; + + if (!m_pri_cb.isnull()) + pri_mask = m_pri_cb(pri, ext); + + if (!m_gfxbank_cb.isnull()) + code = m_gfxbank_cb(code, ext, BIT(spriteram[i + 3], 15)); + + for (int ax = 0; ax < sizex; ax++) + { + for (int ay = 0; ay < sizey; ay++) + { + gfx(0)->prio_transpen(bitmap, cliprect, + code++, + color, + flipx, flipy, + flipx ? (x + 16 * (sizex - ax - 1)) : (x + 16 * ax), + flipy ? (y + 16 * (sizey - ay - 1)) : (y + 16 * ay), + screen.priority(), pri_mask, 15); + } + } + } +} + +void sei0210_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle cliprect, u16* spriteram, u16 size) +{ + draw(screen, bitmap, cliprect, spriteram, size); +} + +void sei0210_device::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle cliprect, u16* spriteram, u16 size) +{ + draw(screen, bitmap, cliprect, spriteram, size); +} diff --git a/src/mame/seibu/sei021x_sei0220_spr.h b/src/mame/seibu/sei021x_sei0220_spr.h new file mode 100644 index 00000000000..3f50bde0432 --- /dev/null +++ b/src/mame/seibu/sei021x_sei0220_spr.h @@ -0,0 +1,80 @@ +// license:BSD-3-Clause +// copyright-holders:David Graves, Angelo Salese, David Haywood, Tomasz Slanina, Carlos A. Lozano, Bryan McPhail, Pierpaolo Prazzoli +#ifndef MAME_VIDEO_SEI021X_SEI0220_SPR_H +#define MAME_VIDEO_SEI021X_SEI0220_SPR_H + +#pragma once + +class sei0210_device : public device_t, public device_gfx_interface +{ +public: + typedef device_delegate pri_cb_delegate; + typedef device_delegate gfxbank_cb_delegate; + + sei0210_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + template sei0210_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&palette_tag, const gfx_decode_entry *gfxinfo) + : sei0210_device(mconfig, tag, owner, clock) + { + set_info(gfxinfo); + set_palette(std::forward(palette_tag)); + } + + // configuration + template void set_pri_callback(T &&... args) { m_pri_cb.set(std::forward(args)...); } + template void set_gfxbank_callback(T &&... args) { m_gfxbank_cb.set(std::forward(args)...); } + void set_alt_format(bool alt_format) { m_alt_format = alt_format; } + void set_offset(s32 xoffset, s32 yoffset) + { + m_xoffset = xoffset; + m_yoffset = yoffset; + } + + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle cliprect, u16* spriteram, u16 size); + void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle cliprect, u16* spriteram, u16 size); + +protected: + sei0210_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + virtual void device_start() override; + virtual void device_reset() override; + + virtual s32 get_coordinate(s32 coordinate) + { + return (coordinate & 0x1ff) - ((coordinate & 0x8000) ? 0x200 : 0); + } + +private: + template + void draw(screen_device &screen, T &bitmap, const rectangle cliprect, u16* spriteram, u16 size); + + pri_cb_delegate m_pri_cb; + gfxbank_cb_delegate m_gfxbank_cb; + + bool m_alt_format; + s32 m_xoffset; + s32 m_yoffset; +}; + +class sei0211_device : public sei0210_device +{ +public: + sei0211_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + template sei0211_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&palette_tag, const gfx_decode_entry *gfxinfo) + : sei0211_device(mconfig, tag, owner, clock) + { + set_info(gfxinfo); + set_palette(std::forward(palette_tag)); + } + +protected: + virtual s32 get_coordinate(s32 coordinate) override + { + coordinate &= 0x1ff; + return (coordinate >= 0x180) ? (coordinate - 0x200) : coordinate; + } +}; + +DECLARE_DEVICE_TYPE(SEI0210, sei0210_device) +DECLARE_DEVICE_TYPE(SEI0211, sei0211_device) + +#endif // MAME_VIDEO_SEI021X_SEI0220_SPR_H diff --git a/src/mame/seibu/sengokmj.cpp b/src/mame/seibu/sengokmj.cpp index f955cd5e0f2..cd0449efb7b 100644 --- a/src/mame/seibu/sengokmj.cpp +++ b/src/mame/seibu/sengokmj.cpp @@ -55,6 +55,8 @@ RSSENGO2.72 chr. #include "emu.h" +#include "sei021x_sei0220_spr.h" + #include "seibusound.h" #include "cpu/nec/nec.h" @@ -78,6 +80,7 @@ public: m_maincpu(*this, "maincpu"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), + m_spritegen(*this, "spritegen"), m_sc0_vram(*this, "sc0_vram"), m_sc1_vram(*this, "sc1_vram"), m_sc2_vram(*this, "sc2_vram"), @@ -95,6 +98,7 @@ private: required_device m_maincpu; required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; required_shared_ptr m_sc0_vram; required_shared_ptr m_sc1_vram; @@ -130,7 +134,7 @@ private: void vblank_irq(int state); - void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri); + uint32_t pri_cb(uint8_t pri, uint8_t ext); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void sengokmj_io_map(address_map &map); @@ -245,67 +249,39 @@ TILE_GET_INFO_MEMBER( sengokmj_state::seibucrtc_sc0_tile_info ) int tile = m_sc0_vram[tile_index] & 0xfff; int color = (m_sc0_vram[tile_index] >> 12) & 0x0f; // tile+=(m_seibucrtc_sc0bank<<12); - tileinfo.set(1, tile, color, 0); + tileinfo.set(0, tile, color, 0); } TILE_GET_INFO_MEMBER( sengokmj_state::seibucrtc_sc2_tile_info ) { int tile = m_sc2_vram[tile_index] & 0xfff; int color = (m_sc2_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(2, tile, color, 0); + tileinfo.set(1, tile, color, 0); } TILE_GET_INFO_MEMBER( sengokmj_state::seibucrtc_sc1_tile_info ) { int tile = m_sc1_vram[tile_index] & 0xfff; int color = (m_sc1_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(3, tile, color, 0); + tileinfo.set(2, tile, color, 0); } TILE_GET_INFO_MEMBER( sengokmj_state::seibucrtc_sc3_tile_info ) { int tile = m_sc3_vram[tile_index] & 0xfff; int color = (m_sc3_vram[tile_index] >> 12) & 0x0f; - tileinfo.set(4, tile, color, 0); + tileinfo.set(3, tile, color, 0); } -void sengokmj_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri) +uint32_t sengokmj_state::pri_cb(uint8_t pri, uint8_t ext) { - int offs,fx,fy,x,y,color,sprite; - int dx,dy,ax,ay; - - for (offs = 0x400-4;offs >= 0;offs -= 4) + switch (pri) { - if ((m_spriteram16[offs+0]&0x8000)!=0x8000) continue; - sprite = m_spriteram16[offs+1]; - if ((sprite>>14)!=pri) continue; - sprite &= 0x1fff; - - y = m_spriteram16[offs+3]; - x = m_spriteram16[offs+2]; - - if (x&0x8000) x=0-(0x200-(x&0x1ff)); - else x&=0x1ff; - if (y&0x8000) y=0-(0x200-(y&0x1ff)); - else y&=0x1ff; - - color = m_spriteram16[offs+0]&0x3f; - fx = m_spriteram16[offs+0]&0x4000; - fy = m_spriteram16[offs+0]&0x2000; - dy=((m_spriteram16[offs+0]&0x0380)>>7)+1; - dx=((m_spriteram16[offs+0]&0x1c00)>>10)+1; - - for (ax=0; axgfx(0)->transpen(bitmap,cliprect, - sprite++, - color,fx,fy,x+ax*16,y+ay*16,15); - else - m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, - sprite++, - color,fx,fy,x+(dx-1-ax)*16,y+ay*16,15); - } + case 0: return GFX_PMASK_8; + case 1: return GFX_PMASK_8 | GFX_PMASK_4; + case 2: return GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2; + case 3: + default: return 0; } } @@ -326,6 +302,7 @@ void sengokmj_state::video_start() uint32_t sengokmj_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + screen.priority().fill(0, cliprect); bitmap.fill(m_palette->pen(0x7ff), cliprect); //black pen /* TODO: offsetted? */ @@ -338,14 +315,11 @@ uint32_t sengokmj_state::screen_update(screen_device &screen, bitmap_ind16 &bitm m_sc3_tilemap->set_scrollx(0, (128) & 0x1ff ); m_sc3_tilemap->set_scrolly(0, (0) & 0x1ff ); - if(SEIBU_CRTC_ENABLE_SC0) { m_sc0_tilemap->draw(screen, bitmap, cliprect, 0,0); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(bitmap,cliprect, 2); } - if(SEIBU_CRTC_ENABLE_SC2) { m_sc2_tilemap->draw(screen, bitmap, cliprect, 0,0); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(bitmap,cliprect, 1); } - if(SEIBU_CRTC_ENABLE_SC1) { m_sc1_tilemap->draw(screen, bitmap, cliprect, 0,0); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(bitmap,cliprect, 0); } - if(SEIBU_CRTC_ENABLE_SC3) { m_sc3_tilemap->draw(screen, bitmap, cliprect, 0,0); } - if(SEIBU_CRTC_ENABLE_SPR) { draw_sprites(bitmap,cliprect, 3); } + if(SEIBU_CRTC_ENABLE_SC0) { m_sc0_tilemap->draw(screen, bitmap, cliprect, 0, 1); } + if(SEIBU_CRTC_ENABLE_SC2) { m_sc2_tilemap->draw(screen, bitmap, cliprect, 0, 2); } + if(SEIBU_CRTC_ENABLE_SC1) { m_sc1_tilemap->draw(screen, bitmap, cliprect, 0, 4); } + if(SEIBU_CRTC_ENABLE_SC3) { m_sc3_tilemap->draw(screen, bitmap, cliprect, 0, 8); } + if(SEIBU_CRTC_ENABLE_SPR) { m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram16, m_spriteram16.bytes()); } return 0; } @@ -558,13 +532,16 @@ static const gfx_layout charlayout = }; static GFXDECODE_START( gfx_sengokmj ) - GFXDECODE_ENTRY( "spr_gfx",0, tilelayout, 0x000, 0x40 ) /* Sprites */ GFXDECODE_ENTRY( "bg_gfx", 0, tilelayout, 0x400, 0x10 ) /* Tiles */ GFXDECODE_ENTRY( "md_gfx", 0, tilelayout, 0x500, 0x10 ) /* Tiles */ GFXDECODE_ENTRY( "fg_gfx", 0, tilelayout, 0x600, 0x10 ) /* Tiles */ GFXDECODE_ENTRY( "tx_gfx", 0, charlayout, 0x700, 0x10 ) /* Text */ GFXDECODE_END +static GFXDECODE_START( gfx_sengokmj_spr ) + GFXDECODE_ENTRY( "spr_gfx",0, tilelayout, 0x000, 0x40 ) /* Sprites */ +GFXDECODE_END + void sengokmj_state::vblank_irq(int state) { if (state) @@ -612,6 +589,9 @@ void sengokmj_state::sengokmj(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_sengokmj); PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x800); + SEI0210(config, m_spritegen, XTAL(14'318'181), m_palette, gfx_sengokmj_spr); + m_spritegen->set_pri_callback(FUNC(sengokmj_state::pri_cb)); + /* sound hardware */ SPEAKER(config, "mono").front_center(); -- cgit v1.2.3