From 10f3b5af62f4df160b1489ed1c7dc5a24ff9ad84 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 1 Nov 2025 01:58:59 +0900 Subject: [PATCH 1/3] seibu/sei25x_rise1x_spr.cpp: Merge SEI25X, RISE1X sprite hardware emulation into its own device seibu/r2dx_v33.cpp, seibu/raiden2.cpp: Reduce duplicates seibu/feversoc.cpp: Fix notes --- src/mame/seibu/feversoc.cpp | 66 +++----- src/mame/seibu/r2dx_v33.cpp | 18 +-- src/mame/seibu/raiden2.cpp | 38 +++-- src/mame/seibu/raiden2.h | 18 ++- src/mame/seibu/raiden2_v.cpp | 110 +------------ src/mame/seibu/sei25x_rise1x_spr.cpp | 193 ++++++++++++++++++++++ src/mame/seibu/sei25x_rise1x_spr.h | 63 ++++++++ src/mame/seibu/seibucats.cpp | 9 +- src/mame/seibu/seibuspi.cpp | 36 +++-- src/mame/seibu/seibuspi.h | 24 +-- src/mame/seibu/seibuspi_v.cpp | 234 +++++---------------------- 11 files changed, 411 insertions(+), 398 deletions(-) create mode 100644 src/mame/seibu/sei25x_rise1x_spr.cpp create mode 100644 src/mame/seibu/sei25x_rise1x_spr.h diff --git a/src/mame/seibu/feversoc.cpp b/src/mame/seibu/feversoc.cpp index 3575a0686e6db..34594d2f01635 100644 --- a/src/mame/seibu/feversoc.cpp +++ b/src/mame/seibu/feversoc.cpp @@ -75,6 +75,7 @@ U089 MAX232 Dual EIA Driver/Receiver #include "emu.h" +#include "sei25x_rise1x_spr.h" #include "seibuspi_m.h" #include "cpu/sh/sh7604.h" @@ -99,7 +100,7 @@ class feversoc_state : public driver_device m_mainram1(*this, "workram1"), m_mainram2(*this, "workram2"), m_nvram(*this, "nvram"), - m_spriteram(*this, "spriteram"), + m_spriteram(*this, "spriteram", 0x2000, ENDIANNESS_BIG), m_in(*this, {"IN1", "IN0"}), m_lamps(*this, "lamp%u", 1U), m_maincpu(*this, "maincpu"), @@ -107,8 +108,8 @@ class feversoc_state : public driver_device m_eeprom(*this, "eeprom"), m_rtc(*this, "rtc"), m_hopper(*this, "hopper"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette") + m_palette(*this, "palette"), + m_spritegen(*this, "spritegen") { } void init_feversoc() ATTR_COLD; @@ -119,6 +120,8 @@ class feversoc_state : public driver_device virtual void machine_start() override ATTR_COLD; private: + uint16_t spriteram_r(offs_t offset); + void spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint16_t in_r(offs_t offset); void output_w(uint16_t data); void output2_w(uint16_t data); @@ -131,7 +134,7 @@ class feversoc_state : public driver_device required_shared_ptr m_mainram1; required_shared_ptr m_mainram2; required_shared_ptr m_nvram; - required_shared_ptr m_spriteram; + memory_share_creator m_spriteram; required_ioport_array<2> m_in; output_finder<7> m_lamps; @@ -140,8 +143,8 @@ class feversoc_state : public driver_device required_device m_eeprom; required_device m_rtc; required_device m_hopper; - required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; }; @@ -149,42 +152,20 @@ uint32_t feversoc_state::screen_update(screen_device &screen, bitmap_ind16 &bitm { bitmap.fill(m_palette->pen(0), cliprect); //black pen - for (int offs = (0x2000 / 4) - 2; offs >= 0; offs -= 2) - { - u32 spr_offs = (m_spriteram[offs + 0] & 0x3fff); - if (spr_offs == 0) - continue; - int sy = m_spriteram[offs + 1] & 0x01ff; - int sx = (m_spriteram[offs + 1] & 0x01ff0000) >> 16; - const u32 colour = (m_spriteram[offs + 0] & 0x003f0000) >> 16; - const u8 w = ((m_spriteram[offs + 0] & 0x07000000) >> 24) + 1; - const u8 h = ((m_spriteram[offs + 0] & 0x70000000) >> 28) + 1; - // TODO: flip sprites, unused? - // flip horizontal in bit 27 - // flip vertical in bit 31 - - if (sx >= 0x180) - sx -= 0x200; - - if (sy >= 0x180) - sy -= 0x200; - - for (int dx = 0; dx < w; dx++) - { - for (int dy = 0; dy < h; dy++) - { - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, - spr_offs++, colour, - 0, 0, - (sx + dx * 16), (sy + dy * 16), - 0x3f); - } - } - } + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram, m_spriteram.bytes()); return 0; } +uint16_t feversoc_state::spriteram_r(offs_t offset) +{ + return m_spriteram[offset]; +} + +void feversoc_state::spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_spriteram[offset]); +} uint16_t feversoc_state::in_r(offs_t offset) { @@ -227,7 +208,7 @@ void feversoc_state::main_map(address_map &map) map(0x02000000, 0x0202ffff).ram().share(m_mainram1); //work ram map(0x02030000, 0x02033fff).ram().share(m_nvram); map(0x02034000, 0x0203dfff).ram().share(m_mainram2); //work ram - map(0x0203e000, 0x0203ffff).ram().share(m_spriteram); + map(0x0203e000, 0x0203ffff).rw(FUNC(feversoc_state::spriteram_r), FUNC(feversoc_state::spriteram_w)); map(0x06000000, 0x06000001).w(FUNC(feversoc_state::output_w)); map(0x06000002, 0x06000003).w(FUNC(feversoc_state::output2_w)); map(0x06000006, 0x06000007).w(FUNC(feversoc_state::irq_ack_w)); @@ -324,9 +305,14 @@ void feversoc_state::feversoc(machine_config &config) screen.set_palette(m_palette); screen.screen_vblank().set(FUNC(feversoc_state::screen_vblank)); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_feversoc); PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x1000); + SEI25X_RISE1X(config, m_spritegen, 0, m_palette, gfx_feversoc); + m_spritegen->set_screen("screen"); + m_spritegen->set_pix_raw_shift(6); + m_spritegen->set_pri_raw_shift(14); + m_spritegen->set_transpen(63); + /* sound hardware */ SPEAKER(config, "mono").front_center(); OKIM6295(config, m_oki, MASTER_CLOCK / 16, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 0.6); //pin 7 & frequency not verified (clock should be 28,6363 / n) @@ -353,7 +339,7 @@ ROM_START( feversoc ) ROM_LOAD16_BYTE( "prog0.u0139", 0x00001, 0x20000, CRC(fa699503) SHA1(96a834d4f7d5b764aa51db745afc2cd9a7c9783d) ) ROM_LOAD16_BYTE( "prog1.u0140", 0x00000, 0x20000, CRC(fd4d7943) SHA1(d7d782f878656bc79d70589f9df2cbcfff0adb5e) ) - ROM_REGION( 0x600000, "sprites", 0) /* text */ + ROM_REGION( 0x600000, "sprites", 0) /* sprites */ ROM_LOAD("obj1.u011", 0x000000, 0x200000, CRC(d8c8dde7) SHA1(3ef815fb1e21a0bd907ee835bc7a32d80f6a9d28) ) ROM_LOAD("obj2.u012", 0x200000, 0x200000, CRC(8e93bfda) SHA1(3b4740cefb164efc320fb69f58e8800d2646fea6) ) ROM_LOAD("obj3.u013", 0x400000, 0x200000, CRC(8c8c6e8b) SHA1(bed4990d6eebb7aefa200ad2bed9b7e71e6bd064) ) diff --git a/src/mame/seibu/r2dx_v33.cpp b/src/mame/seibu/r2dx_v33.cpp index 740b1a7da5784..d0371957ac043 100644 --- a/src/mame/seibu/r2dx_v33.cpp +++ b/src/mame/seibu/r2dx_v33.cpp @@ -792,14 +792,7 @@ void r2dx_v33_state::rdx_v33(machine_config &config) screen.set_visarea(0*8, 40*8-1, 0, 30*8-1); screen.set_screen_update(FUNC(r2dx_v33_state::screen_update)); - GFXDECODE(config, m_gfxdecode, m_palette, r2dx_v33_state::gfx_raiden2); - PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); - - seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); - crtc.layer_en_callback().set(FUNC(r2dx_v33_state::tilemap_enable_w)); - crtc.layer_scroll_callback().set(FUNC(r2dx_v33_state::tile_scroll_w)); - - BUFFERED_SPRITERAM16(config, m_spriteram); + base_video(config); /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -828,14 +821,7 @@ void nzeroteam_state::nzerotea(machine_config &config) screen.set_visarea(0*8, 40*8-1, 0, 32*8-1); screen.set_screen_update(FUNC(nzeroteam_state::screen_update)); - GFXDECODE(config, m_gfxdecode, m_palette, nzeroteam_state::gfx_raiden2); - PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); - - seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); - crtc.layer_en_callback().set(FUNC(nzeroteam_state::tilemap_enable_w)); - crtc.layer_scroll_callback().set(FUNC(nzeroteam_state::tile_scroll_w)); - - BUFFERED_SPRITERAM16(config, m_spriteram); + base_video(config); /* sound hardware */ SPEAKER(config, "mono").front_center(); diff --git a/src/mame/seibu/raiden2.cpp b/src/mame/seibu/raiden2.cpp index db61695f1cc3e..82cf0ac35d19c 100644 --- a/src/mame/seibu/raiden2.cpp +++ b/src/mame/seibu/raiden2.cpp @@ -1039,11 +1039,31 @@ static const gfx_layout tilelayout = GFXDECODE_START( raiden2_state::gfx_raiden2 ) GFXDECODE_ENTRY( "chars", 0, charlayout, 0x700, 0x10 ) GFXDECODE_ENTRY( "tiles", 0, tilelayout, 0x400, 0x30 ) +GFXDECODE_END + +GFXDECODE_START( raiden2_state::gfx_raiden2_spr ) GFXDECODE_ENTRY( "sprites", 0, gfx_16x16x4_packed_lsb, 0x000, 0x40 ) // really 64, but using the top bits for priority GFXDECODE_END /* MACHINE DRIVERS */ +void raiden2_state::base_video(machine_config &config) +{ + GFXDECODE(config, m_gfxdecode, m_palette, raiden2_state::gfx_raiden2); + PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); + + seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); + crtc.layer_en_callback().set(FUNC(raiden2_state::tilemap_enable_w)); + crtc.layer_scroll_callback().set(FUNC(raiden2_state::tile_scroll_w)); + + BUFFERED_SPRITERAM16(config, m_spriteram); + + SEI25X_RISE1X(config, m_spritegen, 0, m_palette, raiden2_state::gfx_raiden2_spr); + m_spritegen->set_screen("screen"); + m_spritegen->set_pix_raw_shift(4); + m_spritegen->set_pri_raw_shift(14); + m_spritegen->set_transpen(15); +} void raiden2_state::raiden2(machine_config &config) { @@ -1064,14 +1084,7 @@ void raiden2_state::raiden2(machine_config &config) screen.set_raw(XTAL(32'000'000)/4, 512, 0, 40*8, 282, 0, 30*8); /* hand-tuned to match ~55.47 */ screen.set_screen_update(FUNC(raiden2_state::screen_update)); - GFXDECODE(config, m_gfxdecode, m_palette, raiden2_state::gfx_raiden2); - PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); - - seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); - crtc.layer_en_callback().set(FUNC(raiden2_state::tilemap_enable_w)); - crtc.layer_scroll_callback().set(FUNC(raiden2_state::tile_scroll_w)); - - BUFFERED_SPRITERAM16(config, m_spriteram); + base_video(config); RAIDEN2COP(config, m_raiden2cop, 0); m_raiden2cop->videoramout_cb().set(FUNC(raiden2_state::m_videoram_private_w)); @@ -1129,14 +1142,7 @@ void raiden2_state::zeroteam(machine_config &config) screen.set_raw(XTAL(32'000'000)/4, 512, 0, 40*8, 282, 0, 32*8); /* hand-tuned to match ~55.47 */ screen.set_screen_update(FUNC(raiden2_state::screen_update)); - GFXDECODE(config, m_gfxdecode, m_palette, raiden2_state::gfx_raiden2); - PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 2048); - - seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); - crtc.layer_en_callback().set(FUNC(raiden2_state::tilemap_enable_w)); - crtc.layer_scroll_callback().set(FUNC(raiden2_state::tile_scroll_w)); - - BUFFERED_SPRITERAM16(config, m_spriteram); + base_video(config); RAIDEN2COP(config, m_raiden2cop, 0); m_raiden2cop->videoramout_cb().set(FUNC(raiden2_state::m_videoram_private_w)); diff --git a/src/mame/seibu/raiden2.h b/src/mame/seibu/raiden2.h index a63d1921a9498..61ede65688716 100644 --- a/src/mame/seibu/raiden2.h +++ b/src/mame/seibu/raiden2.h @@ -5,6 +5,7 @@ #pragma once +#include "sei25x_rise1x_spr.h" #include "seibu_crtc.h" #include "seibucop.h" @@ -29,6 +30,7 @@ class raiden2_state : public driver_device , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") , m_screen(*this, "screen") + , m_spritegen(*this, "spritegen") , m_mainbank(*this, "mainbank") , m_raiden2cop(*this, "raiden2cop") @@ -51,10 +53,10 @@ class raiden2_state : public driver_device std::fill(std::begin(m_scrollvals), std::end(m_scrollvals), 0); } - void raidendx(machine_config &config); - void xsedae(machine_config &config); - void zeroteam(machine_config &config); - void raiden2(machine_config &config); + void raidendx(machine_config &config) ATTR_COLD; + void xsedae(machine_config &config) ATTR_COLD; + void zeroteam(machine_config &config) ATTR_COLD; + void raiden2(machine_config &config) ATTR_COLD; void init_raidendx(); void init_xsedae(); @@ -76,6 +78,7 @@ class raiden2_state : public driver_device required_device m_gfxdecode; required_device m_palette; required_device m_screen; + required_device m_spritegen; optional_memory_bank m_mainbank; optional_device m_raiden2cop; @@ -100,7 +103,7 @@ class raiden2_state : public driver_device const s32 *m_cur_spri = nullptr; // cfg - bitmap_ind16 m_tile_bitmap, m_sprite_bitmap; + bitmap_ind16 m_tile_bitmap; void sprite_prot_x_w(u16 data); void sprite_prot_y_w(u16 data); @@ -127,9 +130,8 @@ class raiden2_state : public driver_device void bank_reset(int bgbank, int fgbank, int midbank, int txbank); - void draw_sprites(const rectangle &cliprect); - DECLARE_GFXDECODE_MEMBER(gfx_raiden2); + DECLARE_GFXDECODE_MEMBER(gfx_raiden2_spr); TILE_GET_INFO_MEMBER(get_back_tile_info); TILE_GET_INFO_MEMBER(get_mid_tile_info); TILE_GET_INFO_MEMBER(get_fore_tile_info); @@ -143,6 +145,8 @@ class raiden2_state : public driver_device void zeroteam_sound_map(address_map &map) ATTR_COLD; + void base_video(machine_config &config) ATTR_COLD; + private: u8 m_prg_bank; u16 m_cop_bank; diff --git a/src/mame/seibu/raiden2_v.cpp b/src/mame/seibu/raiden2_v.cpp index 55753ebb89a1e..ce7fa9b0cbec0 100644 --- a/src/mame/seibu/raiden2_v.cpp +++ b/src/mame/seibu/raiden2_v.cpp @@ -38,102 +38,6 @@ void raiden2_state::m_videoram_private_w(offs_t offset, u16 data) } -void raiden2_state::draw_sprites(const rectangle &cliprect) -{ - // causes a blank square in the corner of zero team, but otherwise the thrusters of the ship in the r2 intro are clipped, using 0x8000 as a sign bit instead of this logic works for r2, but not zero team - static constexpr s32 ZEROTEAM_MASK_X = 0x1ff; - static constexpr s32 ZEROTEAM_MASK_Y = 0x1ff; - - m_sprite_bitmap.fill(0xf, cliprect); - - gfx_element *gfx = m_gfxdecode->gfx(2); - - /* - 00 fhhh Fwww ppcc cccc h = height f=flipy w = width F = flipx p = priority c = color - 02 nnnn nnnn nnnn nnnn n = tileno - 04 xxxx xxxx xxxx xxxx x = xpos - 06 yyyy yyyy yyyy yyyy y = ypos - */ - - for (int srcindex = (m_spriteram->bytes() / 2) - 4; srcindex >= 0; srcindex -= 4) - { - u16 const *const source = &m_spriteram->buffer()[srcindex]; - u32 tile_number = source[1]; // TODO: bit 15 is unknown (but used) in zeroteam, since it's sprite tile is 0x8000. - s32 sx = source[2]; - s32 sy = source[3]; - - const u8 ytlim = ((source[0] >> 12) & 0x7) + 1; - const u8 xtlim = ((source[0] >> 8 ) & 0x7) + 1; - - const bool xflip = BIT(source[0], 15); - const bool yflip = BIT(source[0], 11); - - u32 colr = source[0] & 0x3f; - - const u32 pri = (source[0] >> 6) & 3; - - colr |= pri << (14-4); - - s32 xstep = 16; - s32 ystep = 16; - - if (xflip) - { - ystep = -16; - sy += ytlim * 16 - 16; - } - - if (yflip) - { - xstep = -16; - sx += xtlim * 16 - 16; - } - - for (int xtiles = 0; xtiles < xtlim; xtiles++) - { - for (int ytiles = 0; ytiles < ytlim; ytiles++) - { - /* note this wraparound handling could be wrong if some of the COP maths is wrong */ - - gfx->transpen_raw( - m_sprite_bitmap, - cliprect, - tile_number, - colr << 4, - yflip,xflip, - (sx+xstep*xtiles)&ZEROTEAM_MASK_X,(sy+ystep*ytiles)&ZEROTEAM_MASK_Y, 15); - - gfx->transpen_raw( - m_sprite_bitmap, - cliprect, - tile_number, - colr << 4, - yflip,xflip, - ((sx+xstep*xtiles)&ZEROTEAM_MASK_X)-0x200,(sy+ystep*ytiles)&ZEROTEAM_MASK_Y, 15); - - gfx->transpen_raw( - m_sprite_bitmap, - cliprect, - tile_number, - colr << 4, - yflip,xflip, - (sx+xstep*xtiles)&ZEROTEAM_MASK_X,((sy+ystep*ytiles)&ZEROTEAM_MASK_Y)-0x200, 15); - - gfx->transpen_raw( - m_sprite_bitmap, - cliprect, - tile_number, - colr << 4, - yflip,xflip, - ((sx+xstep*xtiles)&ZEROTEAM_MASK_X)-0x200,((sy+ystep*ytiles)&ZEROTEAM_MASK_Y)-0x200, 15); - - tile_number++; - } - } - } - -} - void raiden2_state::background_w(offs_t offset, u16 data) { if (m_back_data[offset] != data) @@ -293,7 +197,7 @@ TILE_GET_INFO_MEMBER(raiden2_state::get_text_tile_info) void raiden2_state::video_start() { m_screen->register_screen_bitmap(m_tile_bitmap); - m_screen->register_screen_bitmap(m_sprite_bitmap); + m_spritegen->alloc_sprite_bitmap(); m_back_data = make_unique_clear(0x800/2); m_fore_data = make_unique_clear(0x800/2); @@ -353,34 +257,34 @@ u32 raiden2_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co bitmap.fill(m_palette->black_pen(), cliprect); if (BIT(~m_tilemap_enable, 4)) { - draw_sprites(cliprect); + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_spriteram->buffer(), m_spriteram->bytes()); - blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[0]); + blend_layer(bitmap, cliprect, m_spritegen->get_sprite_temp_bitmap(), m_cur_spri[0]); } if (BIT(~m_tilemap_enable, 0)) tilemap_draw_and_blend(screen, bitmap, cliprect, m_background_layer); if (BIT(~m_tilemap_enable, 4)) - blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[1]); + blend_layer(bitmap, cliprect, m_spritegen->get_sprite_temp_bitmap(), m_cur_spri[1]); if (BIT(~m_tilemap_enable, 1)) tilemap_draw_and_blend(screen, bitmap, cliprect, m_midground_layer); if (BIT(~m_tilemap_enable, 4)) - blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[2]); + blend_layer(bitmap, cliprect, m_spritegen->get_sprite_temp_bitmap(), m_cur_spri[2]); if (BIT(~m_tilemap_enable, 2)) tilemap_draw_and_blend(screen, bitmap, cliprect, m_foreground_layer); if (BIT(~m_tilemap_enable, 4)) - blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[3]); + blend_layer(bitmap, cliprect, m_spritegen->get_sprite_temp_bitmap(), m_cur_spri[3]); if (BIT(~m_tilemap_enable, 3)) tilemap_draw_and_blend(screen, bitmap, cliprect, m_text_layer); if (BIT(~m_tilemap_enable, 4)) - blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[4]); + blend_layer(bitmap, cliprect, m_spritegen->get_sprite_temp_bitmap(), m_cur_spri[4]); if (machine().input().code_pressed_once(KEYCODE_Z)) if (m_raiden2cop) m_raiden2cop->dump_table(); diff --git a/src/mame/seibu/sei25x_rise1x_spr.cpp b/src/mame/seibu/sei25x_rise1x_spr.cpp new file mode 100644 index 0000000000000..ba7f5a721282a --- /dev/null +++ b/src/mame/seibu/sei25x_rise1x_spr.cpp @@ -0,0 +1,193 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina, Nicola Salmoria, Ville Linde, hap +/* + Seibu Kaihatsu SEI251/SEI252/RISE10/RISE11 Sprite generator emulation + + Used by Seibu Kaihatsu at 1993 onward, these are has encryption function. + + SEI25x and RISE1x has compatible sprite format, but RISE1x has + expanded per-line sprite limit and different encryption method. + Other chip differences are still unknown. + + Used in: + seibu/raiden2.cpp + seibu/seibuspi.cpp + seibu/seibucats.cpp + seibu/feversoc.cpp + + TODO: + - flip screen support + - Wraparound in raiden2/xsedae is correct? + - Encryption +*/ + +#include "emu.h" +#include "sei25x_rise1x_spr.h" +#include "screen.h" + + +DEFINE_DEVICE_TYPE(SEI25X_RISE1X, sei25x_rise1x_device, "sei25x_rise1x", "Seibu Kaihatsu SEI251/SEI252/RISE10/RISE11 Sprite generator") + +sei25x_rise1x_device::sei25x_rise1x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_video_interface(mconfig, *this) + , device_gfx_interface(mconfig, *this) + , m_pri_cb(*this) + , m_gfxbank_cb(*this) + , m_xoffset(0) + , m_yoffset(0) + , m_transpen(0) + , m_pix_raw_shift(4) +{ +} + +sei25x_rise1x_device::sei25x_rise1x_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sei25x_rise1x_device(mconfig, SEI25X_RISE1X, tag, owner, clock) +{ +} + +void sei25x_rise1x_device::device_start() +{ + m_pri_cb.resolve(); + m_gfxbank_cb.resolve(); +} + +void sei25x_rise1x_device::device_reset() +{ +} + +void sei25x_rise1x_device::alloc_sprite_bitmap() +{ + screen().register_screen_bitmap(m_sprite_bitmap); +} + +/* + +=============================================================== + +Common sprite format (8 byte per sprites) + +Offset Bit Description + fedc ba98 7654 3210 +00 x--- ---- ---- ---- Flip Y + -xxx ---- ---- ---- Sprite height + ---- x--- ---- ---- Flip X + ---- -xxx ---- ---- Sprite width + ---- ---- xx-- ---- Priority + ---- ---- --xx xxxx Color index +02 xxxx xxxx xxxx xxxx Tile index +04 ---x ---- ---- ---- (Optional) Extra tile bank bit + ---- ---x xxxx xxxx X position +06 ---- ---x xxxx xxxx Y position + +Unmarked bits are unused/unknown. + +=============================================================== + +*/ +template +void sei25x_rise1x_device::draw(screen_device &screen, T &bitmap, const rectangle cliprect, u16* spriteram, u16 size) +{ + if (m_sprite_bitmap.valid() && !m_pri_cb.isnull()) + fatalerror("m_sprite_bitmap && m_pri_cb is invalid\n"); + + int start, end, inc; + if (m_sprite_bitmap.valid()) + m_sprite_bitmap.fill(0xffff, cliprect); + + if (!m_pri_cb.isnull()) + { + start = 0; + end = (size / 2); + inc = 4; + } + else + { + start = (size / 2) - 4; + end = -4; + inc = -4; + } + + for (int i = start; i != end; i += inc) + { + u32 code = spriteram[i + 1]; + // TODO: it needs at spi and feversoc? + if ((code % gfx(0)->elements()) == 0) + continue; + + const bool flipy = BIT(spriteram[i + 0], 15); + const u8 sizey = BIT(spriteram[i + 0], 12, 3) + 1; + const bool flipx = BIT(spriteram[i + 0], 11); + const u8 sizex = BIT(spriteram[i + 0], 8, 3) + 1; + const u8 pri = BIT(spriteram[i + 0], 6, 2); + u32 color = BIT(spriteram[i + 0], 0, 6); + const u8 ext = BIT(spriteram[i + 2], 12); + s32 x = BIT(spriteram[i + 2], 0, 9); + s32 y = BIT(spriteram[i + 3], 0, 9); + + if (x >= 0x180) x -= 0x200; + if (y >= 0x180) y -= 0x200; + + x += m_xoffset; + y += m_yoffset; + + u32 pri_mask = 0; + + if (!m_pri_cb.isnull()) + pri_mask = m_pri_cb(pri); + else if (m_sprite_bitmap.valid()) + color |= pri << (m_pri_raw_shift - m_pix_raw_shift); // for manual mixing + + if (!m_gfxbank_cb.isnull()) + code = m_gfxbank_cb(code, ext); + + for (int ax = 0; ax < sizex; ax++) + { + const int sx = flipx ? (x + 16 * (sizex - ax - 1)) : (x + 16 * ax); + for (int ay = 0; ay < sizey; ay++) + { + const int sy = flipy ? (y + 16 * (sizey - ay - 1)) : (y + 16 * ay); + if (!m_sprite_bitmap.valid()) + { + if (!m_pri_cb.isnull()) + { + gfx(0)->prio_transpen(bitmap, cliprect, + code++, + color, + flipx, flipy, + sx, sy, + screen.priority(), pri_mask, m_transpen); + } + else + { + gfx(0)->transpen(bitmap, cliprect, + code++, + color, + flipx, flipy, + sx, sy, + m_transpen); + } + } + else + { + gfx(0)->transpen_raw(m_sprite_bitmap, cliprect, + code++, + color << m_pix_raw_shift, + flipx, flipy, + sx, sy, + m_transpen); + } + } + } + } +} + +void sei25x_rise1x_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle cliprect, u16* spriteram, u16 size) +{ + draw(screen, bitmap, cliprect, spriteram, size); +} + +void sei25x_rise1x_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/sei25x_rise1x_spr.h b/src/mame/seibu/sei25x_rise1x_spr.h new file mode 100644 index 0000000000000..0f1735a0bf8de --- /dev/null +++ b/src/mame/seibu/sei25x_rise1x_spr.h @@ -0,0 +1,63 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina, Nicola Salmoria, Ville Linde, hap +#ifndef MAME_SEIBU_SEI025X_RISE1X_SPR_H +#define MAME_SEIBU_SEI025X_RISE1X_SPR_H + +#pragma once + +class sei25x_rise1x_device : public device_t, public device_video_interface, public device_gfx_interface +{ +public: + using pri_cb_delegate = device_delegate; + using gfxbank_cb_delegate = device_delegate; + + sei25x_rise1x_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + template sei25x_rise1x_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&palette_tag, const gfx_decode_entry *gfxinfo) + : sei25x_rise1x_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_offset(s32 xoffset, s32 yoffset) + { + m_xoffset = xoffset; + m_yoffset = yoffset; + } + void set_transpen(u32 transpen) { m_transpen = transpen; } + void set_pix_raw_shift(u32 raw_shift) { m_pix_raw_shift = raw_shift; } + void set_pri_raw_shift(u32 raw_shift) { m_pri_raw_shift = raw_shift; } + + 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); + + void alloc_sprite_bitmap(); + bitmap_ind16& get_sprite_temp_bitmap() { assert(m_sprite_bitmap.valid()); return m_sprite_bitmap; } + +protected: + sei25x_rise1x_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; + +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; + + s32 m_xoffset; + s32 m_yoffset; + u32 m_transpen; + u32 m_pix_raw_shift; + u32 m_pri_raw_shift; + bitmap_ind16 m_sprite_bitmap; +}; + +DECLARE_DEVICE_TYPE(SEI25X_RISE1X, sei25x_rise1x_device) + +#endif // MAME_SEIBU_SEI025X_RISE1X_SPR_H diff --git a/src/mame/seibu/seibucats.cpp b/src/mame/seibu/seibucats.cpp index cac9bea14cfa9..b6a67d6f2651a 100644 --- a/src/mame/seibu/seibucats.cpp +++ b/src/mame/seibu/seibucats.cpp @@ -317,10 +317,15 @@ void seibucats_state::seibucats(machine_config &config) screen.set_screen_update(FUNC(seibucats_state::screen_update_sys386f)); screen.set_raw(PIXEL_CLOCK, SPI_HTOTAL, SPI_HBEND, SPI_HBSTART, SPI_VTOTAL, SPI_VBEND, SPI_VBSTART); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_seibucats); - PALETTE(config, m_palette, palette_device::BLACK, 8192); + SEI25X_RISE1X(config, m_spritegen, 0, m_palette, gfx_seibucats); + m_spritegen->set_screen("screen"); + // see above + m_spritegen->set_pix_raw_shift(6); + m_spritegen->set_pri_raw_shift(14); + m_spritegen->set_transpen(63); + /* sound hardware */ SPEAKER(config, "speaker", 2).front(); diff --git a/src/mame/seibu/seibuspi.cpp b/src/mame/seibu/seibuspi.cpp index f818a85c47194..7767af2bbcf92 100644 --- a/src/mame/seibu/seibuspi.cpp +++ b/src/mame/seibu/seibuspi.cpp @@ -1648,17 +1648,8 @@ static const gfx_layout spi_spritelayout5 = #endif static GFXDECODE_START( gfx_spi ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout, 0, 64 ) GFXDECODE_ENTRY( "tiles", 0, spi_tilelayout, 4096, 24 ) GFXDECODE_ENTRY( "chars", 0, spi_charlayout, 5632, 16 ) -#if PLANE_SPRITE - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout0, 0, 6144/2 ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout1, 0, 6144/2 ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout2, 0, 6144/2 ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout3, 0, 6144/2 ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout4, 0, 6144/2 ) - GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout5, 0, 6144/2 ) -#endif #if PLANE_TILE GFXDECODE_ENTRY( "tiles", 0, spi_tilelayout0, 0, 6144/2 ) GFXDECODE_ENTRY( "tiles", 0, spi_tilelayout1, 0, 6144/2 ) @@ -1677,6 +1668,18 @@ static GFXDECODE_START( gfx_spi ) #endif GFXDECODE_END +static GFXDECODE_START( gfx_spi_spr ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout, 0, 64 ) +#if PLANE_SPRITE + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout0, 0, 6144/2 ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout1, 0, 6144/2 ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout2, 0, 6144/2 ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout3, 0, 6144/2 ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout4, 0, 6144/2 ) + GFXDECODE_ENTRY( "sprites", 0, spi_spritelayout5, 0, 6144/2 ) +#endif +GFXDECODE_END + static const gfx_layout sys386f_spritelayout = { 16,16, @@ -1786,6 +1789,13 @@ void seibuspi_tilemap_state::base_video(machine_config &config) PALETTE(config, m_palette, palette_device::BLACK, 6144); + SEI25X_RISE1X(config, m_spritegen, 0, m_palette, gfx_spi_spr); + m_spritegen->set_screen("screen"); + m_spritegen->set_gfxbank_callback(FUNC(seibuspi_state::gfxbank_callback)); + m_spritegen->set_pix_raw_shift(6); + m_spritegen->set_pri_raw_shift(14); + m_spritegen->set_transpen(63); + seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); crtc.decrypt_key_callback().set(FUNC(seibuspi_tilemap_state::tile_decrypt_key_w)); crtc.layer_en_callback().set(FUNC(seibuspi_tilemap_state::layer_enable_w)); @@ -1973,10 +1983,14 @@ void sys386f_state::sys386f(machine_config &config) screen.set_visarea(0*8, 40*8-1, 0*8, 30*8-1); screen.set_screen_update(FUNC(sys386f_state::screen_update_sys386f)); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_sys386f); - PALETTE(config, m_palette, palette_device::BLACK, 8192); + SEI25X_RISE1X(config, m_spritegen, 0, m_palette, gfx_sys386f); + m_spritegen->set_screen("screen"); + m_spritegen->set_pix_raw_shift(8); + m_spritegen->set_pri_raw_shift(14); + m_spritegen->set_transpen(255); + /* sound hardware */ // Single PCBs only output mono sound SPEAKER(config, "mono").front_center(); diff --git a/src/mame/seibu/seibuspi.h b/src/mame/seibu/seibuspi.h index 6f02de11daf0b..55bf0ef9cbf6a 100644 --- a/src/mame/seibu/seibuspi.h +++ b/src/mame/seibu/seibuspi.h @@ -10,6 +10,8 @@ #pragma once +#include "sei25x_rise1x_spr.h" + #include "machine/7200fifo.h" #include "machine/eepromser.h" #include "machine/intelfsh.h" @@ -28,8 +30,8 @@ class seibuspi_base_state : public driver_device , m_maincpu(*this, "maincpu") , m_mainram(*this, "mainram") , m_eeprom(*this, "eeprom") - , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") + , m_spritegen(*this, "spritegen") , m_palette_ram(*this, "palette_ram", paletteram_size, ENDIANNESS_LITTLE) , m_sprite_ram(*this, "sprite_ram", spriteram_size, ENDIANNESS_LITTLE) , m_key(*this, "KEY%u", 0) @@ -37,14 +39,16 @@ class seibuspi_base_state : public driver_device , m_sprite_bpp(sprite_bpp) { } + virtual void video_start() override ATTR_COLD; + required_device m_maincpu; required_shared_ptr m_mainram; optional_device m_eeprom; - required_device m_gfxdecode; required_device m_palette; + required_device m_spritegen; memory_share_creator m_palette_ram; - memory_share_creator m_sprite_ram; + memory_share_creator m_sprite_ram; optional_ioport_array<5> m_key; optional_ioport m_special; @@ -56,8 +60,6 @@ class seibuspi_base_state : public driver_device u16 m_layer_enable = 0; u8 m_alpha_table[0x2000]{}; - virtual void video_start() override ATTR_COLD; - void palette_dma_start_w(u32 data); void sprite_dma_start_w(u16 data); void video_dma_length_w(offs_t offset, u32 data, u32 mem_mask = ~0); @@ -65,9 +67,6 @@ class seibuspi_base_state : public driver_device u8 spi_status_r(); void eeprom_w(u8 data); - void drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, u32 code, u32 color, bool flipx, bool flipy, int sx, int sy, bitmap_ind8 &primap, u8 primask); - void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap, int priority); - u32 screen_update_sys386f(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); IRQ_CALLBACK_MEMBER(irq_callback); @@ -107,6 +106,7 @@ class seibuspi_tilemap_state : public seibuspi_base_state public: seibuspi_tilemap_state(const machine_config &mconfig, device_type type, const char *tag) : seibuspi_base_state(mconfig, type, tag, 0x3000, 0x1000, 6) + , m_gfxdecode(*this, "gfxdecode") , m_tilemap_ram(*this, "tilemap_ram", 0x4000, ENDIANNESS_LITTLE) { } @@ -114,6 +114,9 @@ class seibuspi_tilemap_state : public seibuspi_base_state void init_rfjet2kc() ATTR_COLD; protected: + virtual void video_start() override ATTR_COLD; + + required_device m_gfxdecode; memory_share_creator m_tilemap_ram; tilemap_t *m_text_layer = nullptr; @@ -133,8 +136,6 @@ class seibuspi_tilemap_state : public seibuspi_base_state u32 m_fore_layer_d14 = 0; u32 m_bg_fore_layer_position = 0; - virtual void video_start() override ATTR_COLD; - void tile_decrypt_key_w(u16 data); void layer_bank_w(offs_t offset, u16 data, u16 mem_mask = ~0); void layer_enable_w(offs_t offset, u16 data, u16 mem_mask = ~0); @@ -147,7 +148,10 @@ class seibuspi_tilemap_state : public seibuspi_base_state u32 rfjet_speedup_r(); void set_layer_offsets(); + void blend_pixel(u32 &dest, u16 pen); + void blend_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri); void combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tile, int sx, int sy, int opaque, s16 *rowscroll); + u32 gfxbank_callback(u32 code, u8 ext); TILE_GET_INFO_MEMBER(get_text_tile_info); TILE_GET_INFO_MEMBER(get_back_tile_info); diff --git a/src/mame/seibu/seibuspi_v.cpp b/src/mame/seibu/seibuspi_v.cpp index b8ab8fd9f98a1..20d058abf1015 100644 --- a/src/mame/seibu/seibuspi_v.cpp +++ b/src/mame/seibu/seibuspi_v.cpp @@ -357,194 +357,47 @@ void seibuspi_base_state::sprite_dma_start_w(u16 data) if (m_video_dma_address < 0x800) logerror("sprite_dma_start_w in I/O area: %X\n", m_video_dma_address); - std::copy_n(&m_mainram[m_video_dma_address / 4], sprite_ram_size / 4, &m_sprite_ram[0]); + for (int i = 0; i < m_sprite_ram.bytes() / 4; i++) + { + m_sprite_ram[i << 1] = m_mainram[(m_video_dma_address / 4) + i] & 0xffff; + m_sprite_ram[(i << 1) | 1] = (m_mainram[(m_video_dma_address / 4) + i] >> 16) & 0xffff; + } } /*****************************************************************************/ -void seibuspi_base_state::drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, u32 code, u32 color, bool flipx, bool flipy, int sx, int sy, bitmap_ind8 &primap, u8 primask) +u32 seibuspi_tilemap_state::gfxbank_callback(u32 code, u8 ext) { - const int width = gfx->width(); - const int height = gfx->height(); - - int x1 = sx; - int x2 = sx + width - 1; - int y1 = sy; - int y2 = sy + height - 1; - - if (x1 > cliprect.max_x || x2 < cliprect.min_x) - { - return; - } - if (y1 > cliprect.max_y || y2 < cliprect.min_y) - { - return; - } - - int px = 0; - int py = 0; - int xd = 1; - int yd = 1; - - if (flipx) - { - xd = -xd; - px = width - 1; - } - if (flipy) - { - yd = -yd; - py = height - 1; - } - - // clip x - if (x1 < cliprect.min_x) - { - if (flipx) - { - px = width - (cliprect.min_x - x1) - 1; - } - else - { - px = (cliprect.min_x - x1); - } - x1 = cliprect.min_x; - } - if (x2 > cliprect.max_x) - { - x2 = cliprect.max_x; - } - - // clip y - if (y1 < cliprect.min_y) - { - if (flipy) - { - py = height - (cliprect.min_y - y1) - 1; - } - else - { - py = (cliprect.min_y - y1); - } - y1 = cliprect.min_y; - } - if (y2 > cliprect.max_y) - { - y2 = cliprect.max_y; - } - - color = gfx->colorbase() + (color % gfx->colors()) * gfx->granularity(); - const pen_t *const pens = m_palette->pens(); - const u8 *const src = gfx->get_data(code % gfx->elements()); - const u8 trans_pen = (1 << m_sprite_bpp) - 1; - - // draw - for (int y = y1; y <= y2; y++) - { - u32 *const dest = &bitmap.pix(y); - u8 *const pri = &primap.pix(y); - int src_i = (py * width) + px; - py += yd; - - for (int x = x1; x <= x2; x++) - { - const u8 pen = src[src_i]; - if (!(pri[x] & primask) && pen != trans_pen) - { - pri[x] |= primask; - const u16 global_pen = pen + color; - if (m_alpha_table[global_pen]) - dest[x] = alpha_blend_r32(dest[x], pens[global_pen], 0x7f); - else - dest[x] = pens[global_pen]; - } - src_i += xd; - } - } + return code | (((m_spritegen->gfx(0)->elements() > 0x10000) && ext) ? 0x10000 : 0); } -void seibuspi_base_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap, int priority) +inline void seibuspi_tilemap_state::blend_pixel(u32 &dest, u16 pen) { - gfx_element *gfx = m_gfxdecode->gfx(0); - const bool has_tile_high = (gfx->elements() > 0x10000); - - static const int sprite_xtable[2][8] = - { - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, - { 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 } - }; - static const int sprite_ytable[2][8] = - { - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, - { 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 } - }; + if (m_alpha_table[pen]) + dest = alpha_blend_r32(dest, m_palette->pen(pen), 0x7f); + else + dest = m_palette->pen(pen); +} - if (m_layer_enable & 0x10) +void seibuspi_tilemap_state::blend_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri) +{ + if (BIT(m_layer_enable, 4)) return; - const size_t sprite_ram_length = m_sprite_ram.length(); - for (int a = 0; a < sprite_ram_length; a += 2) + bitmap_ind16 &sprite_bitmap = m_spritegen->get_sprite_temp_bitmap(); + pri <<= 14; + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) { - /* - Word 0 - xxxxxxxx xxxxxxxx -------- -------- tile_num low - -------- -------- x------- -------- flip_y - -------- -------- -xxx---- -------- height - -------- -------- ----x--- -------- flip_x - -------- -------- -----xxx -------- width - -------- -------- -------- xx------ priority - -------- -------- -------- --xxxxxx color (highest bit not used on SYS386F) - - Word 1, unmarked bits have no function - -------x xxxxxxxx -------- -------- ypos - -------- -------- ---x---- -------- tile_num high (only on RISE10/11 chip) - -------- -------- ------xx xxxxxxxx xpos - */ - int tile_num = m_sprite_ram[a + 0] >> 16 & 0xffff; - if (tile_num == 0) - continue; - - if (has_tile_high) - tile_num |= m_sprite_ram[a + 1] << 4 & 0x10000; - - if (priority != (m_sprite_ram[a + 0] >> 6 & 0x3)) - continue; - const u8 primask = 1 << priority; - - s16 xpos = util::sext(m_sprite_ram[a + 1], 10); - s16 ypos = util::sext(m_sprite_ram[a + 1] >> 16, 9); - const int color = m_sprite_ram[a + 0] & 0x3f; - - int width = (m_sprite_ram[a + 0] >> 8 & 0x7) + 1; - int height = (m_sprite_ram[a + 0] >> 12 & 0x7) + 1; - const int flip_x = m_sprite_ram[a + 0] >> 11 & 0x1; - const int flip_y = m_sprite_ram[a + 0] >> 15 & 0x1; - int x1 = 0; - int y1 = 0; - - if (flip_x) - { - x1 = 8 - width; - width = width + x1; - } - if (flip_y) + const u16 *src = &sprite_bitmap.pix(y, cliprect.min_x); + u32 *dest = &bitmap.pix(y); + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) { - y1 = 8 - height; - height = height + y1; - } - - for (int x = x1; x < width; x++) - { - for (int y = y1; y < height; y++) + u16 pen = *src++; + if (((pen & 0xc000) == pri) && (pen != 0xffff)) { - drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y], primap, primask); - - /* xpos seems to wrap-around to 0 at 512 */ - if ((xpos + (16 * x) + 16) >= 512) - drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos - 512 + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y], primap, primask); - - tile_num++; + pen &= ~0xc000; + blend_pixel(dest[x], pen); } } } @@ -571,10 +424,7 @@ void seibuspi_tilemap_state::combine_tilemap(bitmap_rgb32 &bitmap, const rectang if (opaque || (flags[x & xscroll_mask] & (TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1))) { const u16 pen = src[x & xscroll_mask]; - if (m_alpha_table[pen]) - *dest = alpha_blend_r32(*dest, m_palette->pen(pen), 0x7f); - else - *dest = m_palette->pen(pen); + blend_pixel(*dest, pen); } dest++; } @@ -598,14 +448,15 @@ u32 seibuspi_tilemap_state::screen_update_spi(screen_device &screen, bitmap_rgb3 fore_rowscroll = nullptr; } - screen.priority().fill(0, cliprect); + if (BIT(~m_layer_enable, 4)) + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_sprite_ram, m_sprite_ram.bytes()); if (m_layer_enable & 1) bitmap.fill(0, cliprect); else combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0], m_scrollram[1], 1, back_rowscroll); - draw_sprites(bitmap, cliprect, screen.priority(), 0); + blend_sprite(bitmap, cliprect, 0); // if fore layer is enabled, draw priority 0 sprites behind back layer if ((m_layer_enable & 0x15) == 0) @@ -613,21 +464,21 @@ u32 seibuspi_tilemap_state::screen_update_spi(screen_device &screen, bitmap_rgb3 // if fore layer is enabled, draw priority 1 sprites behind middle layer if (~m_layer_enable & 4) - draw_sprites(bitmap, cliprect, screen.priority(), 1); + blend_sprite(bitmap, cliprect, 1); if (~m_layer_enable & 2) combine_tilemap(bitmap, cliprect, m_midl_layer, m_scrollram[2], m_scrollram[3], 0, midl_rowscroll); // if fore layer is disabled, draw priority 1 sprites above middle layer if (m_layer_enable & 4) - draw_sprites(bitmap, cliprect, screen.priority(), 1); + blend_sprite(bitmap, cliprect, 1); - draw_sprites(bitmap, cliprect, screen.priority(), 2); + blend_sprite(bitmap, cliprect, 2); if (~m_layer_enable & 4) combine_tilemap(bitmap, cliprect, m_fore_layer, m_scrollram[4], m_scrollram[5], 0, fore_rowscroll); - draw_sprites(bitmap, cliprect, screen.priority(), 3); + blend_sprite(bitmap, cliprect, 3); if (~m_layer_enable & 8) combine_tilemap(bitmap, cliprect, m_text_layer, 0, 0, 0, nullptr); @@ -637,13 +488,9 @@ u32 seibuspi_tilemap_state::screen_update_spi(screen_device &screen, bitmap_rgb3 u32 seibuspi_base_state::screen_update_sys386f(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - screen.priority().fill(0, cliprect); bitmap.fill(0, cliprect); - draw_sprites(bitmap, cliprect, screen.priority(), 0); - draw_sprites(bitmap, cliprect, screen.priority(), 1); - draw_sprites(bitmap, cliprect, screen.priority(), 2); - draw_sprites(bitmap, cliprect, screen.priority(), 3); + m_spritegen->draw_sprites(screen, bitmap, cliprect, m_sprite_ram, m_sprite_ram.bytes()); return 0; } @@ -659,7 +506,7 @@ TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_text_tile_info) tile &= 0xfff; - tileinfo.set(2, tile, color, 0); + tileinfo.set(1, tile, color, 0); } TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_back_tile_info) @@ -671,7 +518,7 @@ TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_back_tile_info) tile &= 0x1fff; tile |= m_back_layer_d14; - tileinfo.set(1, tile, color, 0); + tileinfo.set(0, tile, color, 0); } TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_midl_tile_info) @@ -684,7 +531,7 @@ TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_midl_tile_info) tile |= 0x2000; tile |= m_midl_layer_d14; - tileinfo.set(1, tile, color + 16, 0); + tileinfo.set(0, tile, color + 16, 0); } TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_fore_tile_info) @@ -698,13 +545,13 @@ TILE_GET_INFO_MEMBER(seibuspi_tilemap_state::get_fore_tile_info) tile |= m_fore_layer_d13; tile |= m_fore_layer_d14; - tileinfo.set(1, tile, color + 8, 0); + tileinfo.set(0, tile, color + 8, 0); } void seibuspi_base_state::video_start() { - m_gfxdecode->gfx(0)->set_granularity(1 << m_sprite_bpp); + m_spritegen->gfx(0)->set_granularity(1 << m_sprite_bpp); save_item(NAME(m_video_dma_length)); save_item(NAME(m_video_dma_address)); @@ -715,6 +562,7 @@ void seibuspi_tilemap_state::video_start() { seibuspi_base_state::video_start(); + m_spritegen->alloc_sprite_bitmap(); m_video_dma_length = 0; m_video_dma_address = 0; m_layer_enable = 0; From 22159d64191d16cd992b9189c007facd0eb3ae68 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 1 Nov 2025 02:00:27 +0900 Subject: [PATCH 2/3] seibu/sei25x_rise1x_spr.cpp: Fix notes --- src/mame/seibu/sei25x_rise1x_spr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mame/seibu/sei25x_rise1x_spr.cpp b/src/mame/seibu/sei25x_rise1x_spr.cpp index ba7f5a721282a..1465330989e91 100644 --- a/src/mame/seibu/sei25x_rise1x_spr.cpp +++ b/src/mame/seibu/sei25x_rise1x_spr.cpp @@ -11,6 +11,7 @@ Used in: seibu/raiden2.cpp + seibu/r2dx_v33.cpp seibu/seibuspi.cpp seibu/seibucats.cpp seibu/feversoc.cpp From c463c667fd79effda60bd617c1f3c6969237a6fb Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 1 Nov 2025 06:31:59 +0900 Subject: [PATCH 3/3] sribu/sei25x_rise1x_spr.cpp: Fix include guard --- src/mame/seibu/sei25x_rise1x_spr.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mame/seibu/sei25x_rise1x_spr.h b/src/mame/seibu/sei25x_rise1x_spr.h index 0f1735a0bf8de..855887734b2fc 100644 --- a/src/mame/seibu/sei25x_rise1x_spr.h +++ b/src/mame/seibu/sei25x_rise1x_spr.h @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina, Nicola Salmoria, Ville Linde, hap -#ifndef MAME_SEIBU_SEI025X_RISE1X_SPR_H -#define MAME_SEIBU_SEI025X_RISE1X_SPR_H +#ifndef MAME_SEIBU_SEI25X_RISE1X_SPR_H +#define MAME_SEIBU_SEI25X_RISE1X_SPR_H #pragma once @@ -60,4 +60,4 @@ class sei25x_rise1x_device : public device_t, public device_video_interface, pub DECLARE_DEVICE_TYPE(SEI25X_RISE1X, sei25x_rise1x_device) -#endif // MAME_SEIBU_SEI025X_RISE1X_SPR_H +#endif // MAME_SEIBU_SEI25X_RISE1X_SPR_H