From 9f26def26885841cbab99ad08a806c200cae5245 Mon Sep 17 00:00:00 2001 From: mamehaze <140764005+mamehaze@users.noreply.github.com> Date: Sun, 7 Jan 2024 14:34:35 +0000 Subject: [PATCH] pkspirit.cpp - doesn't use tilemaps, uses a spritelist. remove tilemaps, hook up preliminary list (#11896) --------- Co-authored-by: David Haywood --- src/mame/taito/pkspirit.cpp | 227 +++++++++++++++++++++++++----------- 1 file changed, 162 insertions(+), 65 deletions(-) diff --git a/src/mame/taito/pkspirit.cpp b/src/mame/taito/pkspirit.cpp index e45a4890171..2dc11c65e5c 100644 --- a/src/mame/taito/pkspirit.cpp +++ b/src/mame/taito/pkspirit.cpp @@ -52,7 +52,6 @@ Video PCB: #include "emupal.h" #include "screen.h" #include "speaker.h" -#include "tilemap.h" namespace { @@ -66,8 +65,9 @@ public: , m_mainio(*this, "mainio") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") - , m_bg_videoram(*this, "bg_videoram") - , m_fg_videoram(*this, "fg_videoram") + , m_vidram(*this, "vidram") + , m_sprram(*this, "sprram") + , m_mainram(*this, "mainram") , m_audiobank(*this, "audiobank") , m_opto(*this, "opto%u", 1U) { } @@ -83,64 +83,145 @@ private: required_device m_mainio; required_device m_gfxdecode; required_device m_palette; + required_shared_ptr m_vidram; + required_shared_ptr m_sprram; + required_shared_ptr m_mainram; - required_shared_ptr m_bg_videoram; - required_shared_ptr m_fg_videoram; required_memory_bank m_audiobank; required_device_array m_opto; - tilemap_t *m_bg_tilemap = nullptr; - tilemap_t *m_fg_tilemap = nullptr; + void vidram_w(offs_t offset, u16 data, u16 mem_mask); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void bg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void fg_videoram_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); - void main_map(address_map &map); void sound_map(address_map &map); }; -void pkspirit_state::bg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_bg_videoram[offset]); - m_bg_tilemap->mark_tile_dirty(offset); -} - -TILE_GET_INFO_MEMBER(pkspirit_state::get_bg_tile_info) -{ - int tileno = m_bg_videoram[tile_index]; - tileinfo.set(0, tileno, 0x8 + 0x6, 0); -} - -void pkspirit_state::fg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_fg_videoram[offset]); - m_fg_tilemap->mark_tile_dirty(offset); -} - -TILE_GET_INFO_MEMBER(pkspirit_state::get_fg_tile_info) -{ - int tileno = m_fg_videoram[tile_index]; - tileinfo.set(0, tileno, 0x8 + 0x6, 0); -} - void pkspirit_state::video_start() { - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pkspirit_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32); - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pkspirit_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32); - m_fg_tilemap->set_transparent_pen(0); } uint32_t pkspirit_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + bitmap.fill(0, cliprect); + + uint16_t *spriteram_start = m_mainram + 0xff2 / 2; + //uint16_t* spriteram_start = m_sprram; // once DMA is handled in the TMP68303 this should be used instead + + for (int i = 0; i < 0x800 / 2; i += 4) + { + // somewhat illogical, but the full tilemap sprites need to be drawn first, in reverse order + // followed by the regular sprites, again in reverse order. + // (or there is some priority control) + int reali = ((0x3fc - i) + 0x8) & 0x3ff; + + uint16_t sp0 = spriteram_start[reali + 0]; + uint16_t sp1 = spriteram_start[reali + 1]; + //uint16_t sp2 = spriteram_start[preali + 2]; + uint16_t sp3 = spriteram_start[reali + 3]; + + int xpos = sp1 & 0x3ff; + int ypos = sp0 & 0x1ff; + + ypos = 0x1ff - ypos; + + int sizex; + int sizey; + int xshift; + + int base = (sp3 & 0x7ffe); + + int pal = (sp1 & 0xfc00) >> 10; + + if (sp0 & 0x8000) // large tilemap sprites + { + sizex = 0x40; + sizey = 0x40; + xshift = 0x40; + } + else + { + xshift = 0; + sizex = 1; + sizey = 1; + + // TODO work out which bits are controlling this + // 0x2000 might be priority? + switch (sp0 & 0x7e00) + { + case 0x0200: // sprites that aren't in use? + { + sizex = 1; + sizey = 1; + break; + } + case 0x0600: // Values on Double Up screen + { + sizex = 1; + sizey = 2; + break; + } + case 0x0e00: // HOLD text + { + sizex = 2; + sizey = 2; + break; + } + case 0x1600: // Game Over + { + sizex = 4; + sizey = 2; + break; + } + case 0x1a00: // TAITO logo on title + { + sizex = 4; + sizey = 4; + break; + } + + case 0x3800: // Reel on bonus type 2(?) (not sure this is visible) + { + sizex = 4; + sizey = 2; + break; + } + case 0x3a00: // Reel on bonus type 2 + { + sizex = 4; + sizey = 4; // there is still a slight glitch with this reel if 4 is used, maybe priority? + break; + } + } + } + + //if (sp0 != 0x0000) + // printf("sp%03x : %04x %04x %04x %04x\n", i, sp0, sp1, sp2, sp3); + + if (sp0 != 0x0000) + { + int count = 0; + for (int y = 0; y < sizey; y++) + { + int ydraw = y * 16 + ypos - 31; + + for (int x = 0; x < sizex; x++) + { + int xdraw = x * 16 + xpos - xshift; + + uint16_t tile = m_vidram[base + count]; + m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, tile, pal, 0, 0, xdraw, ydraw, 0); + + count++; + } + } + } + + } + return 0; } @@ -149,30 +230,34 @@ void pkspirit_state::machine_start() m_audiobank->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); } +void pkspirit_state::vidram_w(offs_t offset, u16 data, u16 mem_mask) +{ + COMBINE_DATA(&m_vidram[offset]); + m_gfxdecode->gfx(1)->mark_dirty(offset / 16); +} void pkspirit_state::main_map(address_map &map) // TODO: verify everything { map(0x000000, 0x01ffff).rom().region("maincpu", 0); map(0x100000, 0x10001f).rw(m_mainio, FUNC(te7750_device::read), FUNC(te7750_device::write)).umask16(0x00ff); map(0x200000, 0x200001).portr("DSW"); - map(0x300000, 0x30ffff).ram(); // main RAM? + map(0x300000, 0x30ffff).ram().share("mainram"); map(0x800001, 0x800001).w("ciu", FUNC(pc060ha_device::master_port_w)); map(0x800003, 0x800003).rw("ciu", FUNC(pc060ha_device::master_comm_r), FUNC(pc060ha_device::master_comm_w)); //map(0x900000, 0x900001).w // ? - map(0xa00000, 0xa0003f).ram(); + map(0xa00000, 0xa0003f).ram(); // is this still palette? (for the uploaded tiles?) map(0xa04000, 0xa057ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); - map(0xb00000, 0xb00fff).ram().w(FUNC(pkspirit_state::fg_videoram_w)).share(m_fg_videoram); // GFX chips RAM? - map(0xb01000, 0xb01fff).ram(); // GFX chips RAM? - map(0xb02000, 0xb02fff).ram().w(FUNC(pkspirit_state::bg_videoram_w)).share(m_bg_videoram); // GFX chips RAM? - map(0xb03000, 0xb03fff).ram(); // GFX chips RAM ? - map(0xb04000, 0xb04fff).ram(); // maybe sprite data, arranged as strips of 4 horizontal tiles - map(0xb05000, 0xb0ffff).ram(); // GFX chips RAM ? + map(0xb00000, 0xb0ffff).ram().w(FUNC(pkspirit_state::vidram_w)).share("vidram"); // it uploads a 2bpp tileset at c000-cfff, why? it's just another copy of the basic font + + map(0xb10000, 0xb107ff).ram().share("sprram"); // spritelist should be copied here map(0xb10800, 0xb1087f).ram(); // control registers for one of the custom GFX chips? map(0xb20000, 0xb2001f).ram(); // control registers for one of the custom GFX chips? } + + void pkspirit_state::sound_map(address_map &map) // TODO: verify everything { map(0x0000, 0x3fff).rom().region("audiocpu", 0); @@ -233,18 +318,18 @@ static INPUT_PORTS_START( pkspirit ) PORT_DIPNAME( 0x0001, 0x0001, "Credit Type" ) PORT_DIPLOCATION("SW1:1") PORT_DIPSETTING( 0x0001, "A" ) PORT_DIPSETTING( 0x0000, "B" ) - PORT_DIPNAME( 0x0002, 0x0002, "Back Bar" ) PORT_DIPLOCATION("SW1:2") - PORT_DIPSETTING( 0x0002, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPNAME( 0x0002, 0x0002, "Background Style" ) PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x0002, "Green" ) + PORT_DIPSETTING( 0x0000, "Blue" ) PORT_DIPNAME( 0x0004, 0x0004, "Card Speed" ) PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING( 0x0004, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPSETTING( 0x0004, "Fast" ) + PORT_DIPSETTING( 0x0000, "Slow" ) PORT_DIPNAME( 0x0008, 0x0008, "Card Deal Type" ) PORT_DIPLOCATION("SW1:4") - PORT_DIPSETTING( 0x0008, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPSETTING( 0x0008, "Slide" ) + PORT_DIPSETTING( 0x0000, "Appear" ) PORT_DIPNAME( 0x0010, 0x0010, "Double Up Type" ) PORT_DIPLOCATION("SW1:5") - PORT_DIPSETTING( 0x0010, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPSETTING( 0x0010, "Without Reel" ) + PORT_DIPSETTING( 0x0000, "With Reel" ) PORT_DIPNAME( 0x0020, 0x0020, "Max Bet" ) PORT_DIPLOCATION("SW1:6") PORT_DIPSETTING( 0x0000, "5" ) PORT_DIPSETTING( 0x0020, "10" ) @@ -252,8 +337,8 @@ static INPUT_PORTS_START( pkspirit ) PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0080, 0x0080, "Card Type" ) PORT_DIPLOCATION("SW1:8") - PORT_DIPSETTING( 0x0080, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPSETTING( 0x0080, "Standard Deck" ) + PORT_DIPSETTING( 0x0000, "Taito Deck" ) PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW2:1,2") PORT_DIPSETTING( 0x0300, DEF_STR( 1C_1C ) ) @@ -268,9 +353,9 @@ static INPUT_PORTS_START( pkspirit ) PORT_DIPNAME( 0x1000, 0x1000, "Hopper" ) PORT_DIPLOCATION("SW2:5") PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x1000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, "Double Up Open Pattern" ) PORT_DIPLOCATION("SW2:6") // TODO: improve machine translation - PORT_DIPSETTING( 0x2000, "A" ) - PORT_DIPSETTING( 0x0000, "B" ) + PORT_DIPNAME( 0x2000, 0x2000, "Double Up Reveal Order" ) PORT_DIPLOCATION("SW2:6") + PORT_DIPSETTING( 0x2000, "Show Chosen Card First" ) + PORT_DIPSETTING( 0x0000, "Show Chosen Card Last" ) PORT_DIPNAME( 0x4000, 0x4000, "Bell" ) PORT_DIPLOCATION("SW2:7") PORT_DIPSETTING( 0x4000, DEF_STR( On ) ) PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) @@ -292,12 +377,24 @@ const gfx_layout gfx_16x16x5_planar = 16*16 }; +const gfx_layout gfx_ram = +{ + 16,16, + RGN_FRAC(1,1), + 2, + { 0,1 }, + { STEP8(0,2), STEP8(128,2) }, + { STEP8(0,16), STEP8(256,16) }, + 32*16 +}; static GFXDECODE_START( gfx_pkspirit ) // TODO: wrong, needs adjustments GFXDECODE_ENTRY( "tiles", 0, gfx_16x16x5_planar, 0, 256) + GFXDECODE_RAM( "vidram", 0, gfx_ram, 0, 256 ) GFXDECODE_END + void pkspirit_state::pkspirit(machine_config &config) { // basic machine hardware @@ -324,7 +421,7 @@ void pkspirit_state::pkspirit(machine_config &config) screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); screen.set_size(64*8, 64*8); - screen.set_visarea(0*8, 64*8-1, 0*8, 56*8-1); + screen.set_visarea(0*8, 64*8-1, 0*8, 52*8-1); // uncertain height screen.set_palette("palette"); screen.set_screen_update(FUNC(pkspirit_state::screen_update)); screen.screen_vblank().set_inputline(m_maincpu, 1);