From 3f4fcc06b890e96d08f8d7f05e6ec1bc8bfd8598 Mon Sep 17 00:00:00 2001 From: MetalliC <0vetal0@gmail.com> Date: Mon, 9 Sep 2019 01:34:50 +0300 Subject: cps3.cpp: sprite list caching (fixes warzard 2p VS screen and jojo intro "enemies" text appearance) --- src/mame/drivers/cps3.cpp | 70 ++++++++++++++++++++++++++++++++--------------- src/mame/includes/cps3.h | 3 ++ 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/mame/drivers/cps3.cpp b/src/mame/drivers/cps3.cpp index 801750b1a2d..7633764b6a5 100644 --- a/src/mame/drivers/cps3.cpp +++ b/src/mame/drivers/cps3.cpp @@ -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(0x800000/4); m_mame_colours = make_unique_clear(0x20000); m_ss_ram = make_unique_clear(0x8000); + m_spritelist = make_unique_clear(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(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; - - 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; + int const xpos = (m_spritelist[i + 1] & 0x03ff0000) >> 16; + int const ypos = m_spritelist[i + 1] & 0x000003ff; + + 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(); diff --git a/src/mame/includes/cps3.h b/src/mame/includes/cps3.h index 77ed603030e..b68937159c3 100644 --- a/src/mame/includes/cps3.h +++ b/src/mame/includes/cps3.h @@ -110,6 +110,7 @@ private: std::unique_ptr m_char_ram; std::unique_ptr m_eeprom; std::unique_ptr m_ss_ram; + std::unique_ptr 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); -- cgit v1.2.3