pkspirit.cpp - doesn't use tilemaps, uses a spritelist. remove tilemaps, hook up preliminary list (#11896)

---------
Co-authored-by: David Haywood <hazemamewip@hotmail.com>
This commit is contained in:
mamehaze 2024-01-07 14:34:35 +00:00 committed by GitHub
parent 56128b30da
commit 9f26def268
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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<te7750_device> m_mainio;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_shared_ptr<u16> m_vidram;
required_shared_ptr<u16> m_sprram;
required_shared_ptr<u16> m_mainram;
required_shared_ptr<uint16_t> m_bg_videoram;
required_shared_ptr<uint16_t> m_fg_videoram;
required_memory_bank m_audiobank;
required_device_array<taitoio_opto_device, 2> 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);