cps3.cpp: sprite list caching (fixes warzard 2p VS screen and jojo intro "enemies" text appearance)

This commit is contained in:
MetalliC 2019-09-09 01:34:50 +03:00
parent 7dedf66295
commit 3f4fcc06b8
2 changed files with 50 additions and 21 deletions

View File

@ -19,10 +19,6 @@ Tilemap Global X/Y flip not emulated
Street Fighter 3 2nd Impact uses Y-flipped tilemaps during flashing.
Warzard uses X-flipped tilemaps during special effects.
Sprite-list caching (presumable)
Warzard 2p mode, at next screen after characters select,
if holding player's button to speed up sequence - player's sprites will be distorted.
Whole screen flip not emulated
Miscellaneous TO-DOs:
@ -986,6 +982,9 @@ void cps3_state::video_start()
m_char_ram = make_unique_clear<u32[]>(0x800000/4);
m_mame_colours = make_unique_clear<u32[]>(0x20000);
m_ss_ram = make_unique_clear<u8[]>(0x8000);
m_spritelist = make_unique_clear<u32[]>(0x80000/4);
m_spritelist[0] = 0x80000000;
/* create the char set (gfx will then be updated dynamically from RAM) */
m_gfxdecode->set_gfx(0, std::make_unique<gfx_element>(m_palette, cps3_tiles8x8_layout, &m_ss_ram[0x4000], 0, m_palette->entries() / 16, 0));
@ -1007,6 +1006,7 @@ void cps3_state::video_start()
save_pointer(NAME(m_char_ram), 0x800000/4);
save_pointer(NAME(m_mame_colours), 0x20000);
save_pointer(NAME(m_ss_ram), 0x8000);
save_pointer(NAME(m_spritelist), 0x80000/4);
}
static inline int to_s10(int data)
@ -1153,23 +1153,24 @@ u32 cps3_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
//logerror("Spritelist start:\n");
for (int i = 0x00000 / 4; i < 0x2000 / 4; i += 4)
{
if (m_spriteram[i + 0] & 0x80000000)
if (m_spritelist[i + 0] & 0x80000000)
break;
u8 const gscroll = (m_spriteram[i + 0] & 0x70000000) >> 28;
u32 const length = (m_spriteram[i + 0] & 0x01ff0000) >> 16; // how many entries in the sprite table
u32 start = (m_spriteram[i + 0] & 0x00007ff0) >> 4;
u8 const gscroll = (m_spritelist[i + 0] & 0x70000000) >> 28;
u32 const length = (m_spritelist[i + 0] & 0x01ff0000) >> 16; // how many entries in the sprite table
u32 start = (m_spritelist[i + 0] & 0x00007ff0) >> 4;
int const xpos = (m_spriteram[i + 1] & 0x03ff0000) >> 16;
int const ypos = m_spriteram[i + 1] & 0x000003ff;
int const xpos = (m_spritelist[i + 1] & 0x03ff0000) >> 16;
int const ypos = m_spritelist[i + 1] & 0x000003ff;
bool const whichbpp = (m_spriteram[i + 2] & 0x40000000) >> 30; // not 100% sure if this is right, jojo title / characters
bool const whichpal = (m_spriteram[i + 2] & 0x20000000) >> 29;
u8 const global_xflip = (m_spriteram[i + 2] & 0x10000000) >> 28;
u8 const global_yflip = (m_spriteram[i + 2] & 0x08000000) >> 27;
bool const global_alpha = (m_spriteram[i + 2] & 0x04000000) >> 26; // alpha / shadow? set on sfiii2 shadows, and big black image in jojo intro
bool const global_bpp = (m_spriteram[i + 2] & 0x02000000) >> 25;
u32 const global_pal = (m_spriteram[i + 2] & 0x01ff0000) >> 16;
bool const whichbpp = (m_spritelist[i + 2] & 0x40000000) >> 30; // not 100% sure if this is right, jojo title / characters
bool const whichpal = (m_spritelist[i + 2] & 0x20000000) >> 29;
u8 const global_xflip = (m_spritelist[i + 2] & 0x10000000) >> 28;
u8 const global_yflip = (m_spritelist[i + 2] & 0x08000000) >> 27;
bool const global_alpha = (m_spritelist[i + 2] & 0x04000000) >> 26; // alpha / shadow? set on sfiii2 shadows, and big black image in jojo intro
bool const global_bpp = (m_spritelist[i + 2] & 0x02000000) >> 25;
u32 const global_pal = (m_spritelist[i + 2] & 0x01ff0000) >> 16;
//int const tilemapnum = (m_spritelist[i + 2] & 0x00000030) >> 4; // jojo and jojoba only
int const gscrollx = (m_ppu_gscroll[gscroll] & 0x03ff0000) >> 16;
int const gscrolly = (m_ppu_gscroll[gscroll] & 0x000003ff) >> 0;
@ -1177,9 +1178,9 @@ u32 cps3_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
for (int j = 0; j < (length) * 4; j += 4)
{
u32 const value1 = (m_spriteram[start + j + 0]);
u32 const value2 = (m_spriteram[start + j + 1]);
u32 const value3 = (m_spriteram[start + j + 2]);
u32 const value1 = (m_spritelist[start + j + 0]);
u32 const value2 = (m_spritelist[start + j + 1]);
u32 const value3 = (m_spritelist[start + j + 2]);
static const int tilestable[4] = { 8,1,2,4 };
@ -1408,6 +1409,27 @@ WRITE32_MEMBER(cps3_state::cram_data_w)
m_gfxdecode->gfx(1)->mark_dirty(fulloffset/0x40);
}
WRITE16_MEMBER(cps3_state::spritedma_w)
{
u16 prev = m_spritelist_dma;
COMBINE_DATA(&m_spritelist_dma);
// display list caching (into PPU on-chip RAM ?)
if ((m_spritelist_dma & 8) && !(prev & 8)) // 0->1
{
for (int i = 0; i < 0x2000/4; i += 4)
{
std::copy(&m_spriteram[i], &m_spriteram[i + 4], &m_spritelist[i]); // copy main list record
u32 dat = m_spriteram[i];
if (dat & 0x80000000)
break;
u32 offs = (dat & 0x00007fff) << 2;
u32 length = (dat & 0x01ff0000) >> 16;
std::copy(&m_spriteram[offs], &m_spriteram[offs + length*4], &m_spritelist[offs]); // copy sublist
}
}
}
/* FLASH ROM ACCESS */
READ32_MEMBER(cps3_state::gfxflash_r)
@ -1780,6 +1802,8 @@ WRITE8_MEMBER(cps3_state::ssregs_w)
case 0x12:
m_ss_pal_base = data;
break;
case 0x14:
break;
default:
logerror("SS regs write %02X data %02X\n", offset, data);
break;
@ -2132,7 +2156,7 @@ void cps3_state::cps3_map(address_map &map)
map(0x040c0040, 0x040c004b).writeonly().share("tmap40_regs");
map(0x040c0050, 0x040c005b).writeonly().share("tmap50_regs");
map(0x040c0060, 0x040c007f).writeonly().share("ppu_crtc_zoom");
map(0x040c0080, 0x040c0083).nopw().umask32(0x0000ffff); // sprite-related, triggered after sprite list upload
map(0x040c0080, 0x040c0083).w(FUNC(cps3_state::spritedma_w)).umask32(0x0000ffff);
map(0x040c0084, 0x040c0087).w(FUNC(cps3_state::cram_bank_w));
map(0x040c0088, 0x040c008b).w(FUNC(cps3_state::cram_gfxflash_bank_w));
map(0x040c0094, 0x040c009b).w(FUNC(cps3_state::characterdma_w));
@ -2279,6 +2303,7 @@ void cps3_state::machine_start()
save_item(NAME(m_ss_hscroll));
save_item(NAME(m_ss_vscroll));
save_item(NAME(m_ss_pal_base));
save_item(NAME(m_spritelist_dma));
save_pointer(NAME(m_eeprom), 0x80/4);
}
@ -2288,6 +2313,7 @@ void cps3_state::machine_reset()
{
m_current_table_address = -1;
m_dma_status = 0;
m_spritelist_dma = 0;
// copy data from flashroms back into user regions + decrypt into regions we execute/draw from.
copy_from_nvram();

View File

@ -110,6 +110,7 @@ private:
std::unique_ptr<u32[]> m_char_ram;
std::unique_ptr<u32[]> m_eeprom;
std::unique_ptr<u8[]> m_ss_ram;
std::unique_ptr<u32[]> m_spritelist;
u32 m_ppu_gscroll[0x20/4];
s16 m_ss_hscroll;
s16 m_ss_vscroll;
@ -123,6 +124,7 @@ private:
u32 m_key2;
int m_altEncryption;
u16 m_dma_status;
u16 m_spritelist_dma;
u32 m_cram_bank;
u16 m_current_eeprom_read;
u32 m_paldma_source;
@ -163,6 +165,7 @@ private:
DECLARE_READ16_MEMBER(colourram_r);
DECLARE_WRITE16_MEMBER(colourram_w);
DECLARE_WRITE16_MEMBER(outport_w);
DECLARE_WRITE16_MEMBER(spritedma_w);
SH2_DMA_KLUDGE_CB(dma_callback);
void draw_fg_layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);