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.
This commit is contained in:
cam900 2023-12-08 02:47:20 +09:00 committed by GitHub
parent 55bc72ec97
commit 0a0ddfb6af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 599 additions and 660 deletions

View File

@ -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<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<sei0211_device> m_spritegen;
required_device<ticket_dispenser_device> m_ticket;
required_device<lh5045_device> m_rtc;
@ -102,7 +105,7 @@ private:
template <uint8_t Which> 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();

View File

@ -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 )

View File

@ -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<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<cpu_device> m_audiocpu;
optional_device<sei0210_device> m_spritegen;
required_device<seibu_sound_device> m_seibu_sound;
required_device<ym3812_device> m_ymsnd;
@ -61,14 +61,40 @@ 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);
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);
void bloodbro_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);
@ -76,19 +102,9 @@ private:
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);
void bloodbro_map(address_map &map);
void common_map(address_map &map);
void skysmash_map(address_map &map);
void weststry_map(address_map &map);
void weststry_sound_map(address_map &map);
};

View File

@ -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;
}

View File

@ -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) )

View File

@ -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<seibu_sound_device> m_seibu_sound;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<sei0211_device> m_spritegen;
required_shared_ptr<uint16_t> m_back_data;
required_shared_ptr<uint16_t> 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);
};

View File

@ -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; ax<dx; ax++)
for (ay=0; ay<dy; ay++) {
if (!fx && !fy)
{
m_gfxdecode->gfx(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;
}

View File

@ -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<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<sei0210_device> m_spritegen;
required_device<screen_device> m_screen;
required_device<seibu_crtc_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 )

View File

@ -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 */

View File

@ -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<u16[]> m_paletteram;
u16 m_layer_disable;
std::unique_ptr<u16[]> 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<okim6295_device> m_oki;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<sei0211_device> m_spritegen;
required_device<seibu_crtc_device> m_crtc;
optional_device<raiden2cop_device> m_raiden2cop;
};

View File

@ -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<u16[]>(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;
return m_sprite_pri_mask[pri];
}
u8 cur_pri = 0;
int pri_mask = 0;
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];
}
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);
}
}
}
}
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 (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 & 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 (!(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();

View File

@ -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<class T>
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);
}

View File

@ -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<u32 (u8 pri, u8 ext)> pri_cb_delegate;
typedef device_delegate<u32 (u32 code, u8 ext, u8 y)> gfxbank_cb_delegate;
sei0210_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
template <typename T> 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<T>(palette_tag));
}
// configuration
template <typename... T> void set_pri_callback(T &&... args) { m_pri_cb.set(std::forward<T>(args)...); }
template <typename... T> void set_gfxbank_callback(T &&... args) { m_gfxbank_cb.set(std::forward<T>(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<class T>
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 <typename T> 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<T>(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

View File

@ -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<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<sei0210_device> m_spritegen;
required_shared_ptr<uint16_t> m_sc0_vram;
required_shared_ptr<uint16_t> 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; ax<dx; ax++)
for (ay=0; ay<dy; ay++) {
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);
}
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();