summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MetalliC <0vetal0@gmail.com>2019-09-09 01:34:50 +0300
committer MetalliC <0vetal0@gmail.com>2019-09-09 01:35:21 +0300
commit3f4fcc06b890e96d08f8d7f05e6ec1bc8bfd8598 (patch)
treea57412b5fb0f8866f2644d53c776c23af03c9006
parent7dedf66295f2da90ed528c40a85ceaa9e210668c (diff)
cps3.cpp: sprite list caching (fixes warzard 2p VS screen and jojo intro "enemies" text appearance)
-rw-r--r--src/mame/drivers/cps3.cpp70
-rw-r--r--src/mame/includes/cps3.h3
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<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;
-
- 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<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);