From 6f8fb72e3511bc4a1d55e347ae6d9a61241b6a34 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 24 Feb 2020 21:52:34 +0900 Subject: taito_f2.cpp : Fix sprite vs tilemap priority (#6351) * taito_f2.cpp : Fix sprite vs tilemap priority * taito_f2.cpp : Reduce minor spacing --- src/mame/includes/taito_f2.h | 6 +- src/mame/video/taito_f2.cpp | 223 ++++++++++++++++++++----------------------- 2 files changed, 106 insertions(+), 123 deletions(-) diff --git a/src/mame/includes/taito_f2.h b/src/mame/includes/taito_f2.h index 750f9d2bec6..d46fe276ee8 100644 --- a/src/mame/includes/taito_f2.h +++ b/src/mame/includes/taito_f2.h @@ -109,7 +109,7 @@ protected: bool flipx, flipy; int x, y; int zoomx, zoomy; - u32 primask; + u64 primask; }; /* memory pointers */ optional_shared_ptr m_sprite_extension; @@ -243,13 +243,13 @@ protected: INTERRUPT_GEN_MEMBER(megab_interrupt); TIMER_DEVICE_CALLBACK_MEMBER(cchip_irq_clear_cb); void core_vh_start(int sprite_type, int hide, int flip_hide); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u32 *primasks, int uses_tc360_mixer); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u64 *primasks, int uses_tc360_mixer); void update_spritebanks(); void handle_sprite_buffering(); void update_sprites_active_area(); void draw_roz_layer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u8 priority, u8 priority_mask = 0xff); void taito_f2_tc360_spritemixdraw(screen_device &screen, bitmap_ind16 &dest_bmp, const rectangle &clip, gfx_element *gfx, - u32 code, u32 color, int flipx, int flipy, int sx, int sy, int scalex, int scaley); + u32 code, u32 color, int flipx, int flipy, int sx, int sy, int scalex, int scaley, u64 primask = 0, bool use_mixer = false); void cameltry_map(address_map &map); void cameltrya_map(address_map &map); diff --git a/src/mame/video/taito_f2.cpp b/src/mame/video/taito_f2.cpp index b47500f899d..4ece4e7b83f 100644 --- a/src/mame/video/taito_f2.cpp +++ b/src/mame/video/taito_f2.cpp @@ -283,7 +283,7 @@ void taitof2_state::koshien_spritebank_w(u16 data) } void taitof2_state::taito_f2_tc360_spritemixdraw(screen_device &screen, bitmap_ind16 &dest_bmp, const rectangle &clip, gfx_element *gfx, - u32 code, u32 color, int flipx, int flipy, int sx, int sy, int scalex, int scaley) + u32 code, u32 color, int flipx, int flipy, int sx, int sy, int scalex, int scaley, u64 primask, bool use_mixer) { const u16 pal_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors()); const u8 *source_base = gfx->get_data(code % gfx->elements()); @@ -353,77 +353,96 @@ void taitof2_state::taito_f2_tc360_spritemixdraw(screen_device &screen, bitmap_i if (ex > sx) { /* skip if inner loop doesn't draw anything */ - for (int y = sy; y < ey; y++) + if (use_mixer) { - const u8 *source = source_base + (y_index >> 16) * gfx->rowbytes(); - u16 *dest = &dest_bmp.pix16(y); - u8 *pri = &priority_bitmap.pix8(y); - - int x_index = x_index_base; - for (int x = sx; x < ex; x++) + for (int y = sy; y < ey; y++) { - const u8 c = source[x_index >> 16]; - if (c && (pri[x] & 0x80) == 0) + const u8 *source = source_base + (y_index >> 16) * gfx->rowbytes(); + u16 *dest = &dest_bmp.pix16(y); + u8 *pri = &priority_bitmap.pix8(y); + + int x_index = x_index_base; + for (int x = sx; x < ex; x++) { - u8 tilemap_priority = 0, sprite_priority = 0; - - // Get tilemap priority (0 - 0xf) for this destination pixel - if (pri[x] & 0x10) tilemap_priority = m_tilepri[4]; - else if (pri[x] & 0x8) tilemap_priority = m_tilepri[3]; - else if (pri[x] & 0x4) tilemap_priority = m_tilepri[2]; - else if (pri[x] & 0x2) tilemap_priority = m_tilepri[1]; - else if (pri[x] & 0x1) tilemap_priority = m_tilepri[0]; - - // Get sprite priority (0 - 0xf) for this source pixel - if ((color & 0xc0) == 0xc0) - sprite_priority = m_spritepri[3]; - else if ((color & 0xc0) == 0x80) - sprite_priority = m_spritepri[2]; - else if ((color & 0xc0) == 0x40) - sprite_priority = m_spritepri[1]; - else if ((color & 0xc0) == 0x00) - sprite_priority = m_spritepri[0]; - - // Blend mode 1 - Sprite under tilemap, use sprite palette with tilemap data - if ((m_spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority - 1)) + const u8 c = source[x_index >> 16]; + if (c && (pri[x] & 0x80) == 0) { - dest[x] = ((pal_base + c) & 0xfff0) | (dest[x] & 0xf); - } - // Blend mode 1 - Sprite over tilemap, use sprite data with tilemap palette - else if ((m_spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority + 1)) - { - if (dest[x] & 0xf) - dest[x] = (dest[x] & 0xfff0) | ((pal_base + c) & 0xf); + u8 tilemap_priority = 0, sprite_priority = 0; + + // Get tilemap priority (0 - 0xf) for this destination pixel + if (pri[x] & 0x10) tilemap_priority = m_tilepri[4]; + else if (pri[x] & 0x8) tilemap_priority = m_tilepri[3]; + else if (pri[x] & 0x4) tilemap_priority = m_tilepri[2]; + else if (pri[x] & 0x2) tilemap_priority = m_tilepri[1]; + else if (pri[x] & 0x1) tilemap_priority = m_tilepri[0]; + + // Get sprite priority (0 - 0xf) for this source pixel + sprite_priority = m_spritepri[primask & 0x03]; + + // Blend mode 1 - Sprite under tilemap, use sprite palette with tilemap data + if ((m_spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority - 1)) + { + dest[x] = ((pal_base + c) & 0xfff0) | (dest[x] & 0xf); + } + // Blend mode 1 - Sprite over tilemap, use sprite data with tilemap palette + else if ((m_spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority + 1)) + { + if (dest[x] & 0xf) + dest[x] = (dest[x] & 0xfff0) | ((pal_base + c) & 0xf); + else + dest[x] = pal_base + c; + } + // Blend mode 2 - Sprite under tilemap, use sprite data with tilemap palette + else if ((m_spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority - 1)) + { + dest[x] = (dest[x] & 0xffef); + } + // Blend mode 2 - Sprite over tilemap, alternate sprite palette, confirmed in Pulirula level 2 + else if ((m_spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority + 1)) + { + dest[x] = ((pal_base + c) & 0xffef); // Pulirula level 2, Liquid Kids attract mode + } + // No blending else - dest[x] = pal_base + c; - } - // Blend mode 2 - Sprite under tilemap, use sprite data with tilemap palette - else if ((m_spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority - 1)) - { - dest[x] = (dest[x] & 0xffef); - } - // Blend mode 2 - Sprite over tilemap, alternate sprite palette, confirmed in Pulirula level 2 - else if ((m_spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority + 1)) - { - dest[x] = ((pal_base + c) & 0xffef); // Pulirula level 2, Liquid Kids attract mode + { + if (sprite_priority > tilemap_priority) // Ninja Kids confirms tilemap takes priority in equal value case + dest[x] = pal_base + c; + } + pri[x] |= 0x80; } - // No blending - else + x_index += dx; + } + y_index += dy; + } + } + else // without blending + { + for (int y = sy; y < ey; y++) + { + const u8 *source = source_base + (y_index >> 16) * gfx->rowbytes(); + u16 *dest = &dest_bmp.pix16(y); + u8 *pri = &priority_bitmap.pix8(y); + + int x_index = x_index_base; + for (int x = sx; x < ex; x++) + { + const u8 c = source[x_index >> 16]; + if (c && (pri[x] & 0x80) == 0) { - if (sprite_priority > tilemap_priority) // Ninja Kids confirms tilemap takes priority in equal value case + if (((1 << (pri[x] & 0x3f)) & primask) == 0) dest[x] = pal_base + c; + pri[x] |= 0x80; } - pri[x] |= 0x80; + x_index += dx; } - x_index += dx; + y_index += dy; } - y_index += dy; } } } } -void taitof2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u32 *primasks, int uses_tc360_mixer) +void taitof2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u64 *primasks, int uses_tc360_mixer) { /* Sprite format: @@ -755,7 +774,9 @@ void taitof2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co if (primasks || uses_tc360_mixer) { - if (primasks) + if (uses_tc360_mixer) + sprite_ptr->primask = (color & 0xc0) >> 6; + else if (primasks) sprite_ptr->primask = primasks[(color & 0xc0) >> 6]; sprite_ptr++; @@ -778,21 +799,12 @@ void taitof2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co { sprite_ptr--; - if (!uses_tc360_mixer) - m_gfxdecode->gfx(0)->prio_zoom_transpen(bitmap,cliprect, - sprite_ptr->code, - sprite_ptr->color, - sprite_ptr->flipx,sprite_ptr->flipy, - sprite_ptr->x,sprite_ptr->y, - sprite_ptr->zoomx,sprite_ptr->zoomy, - screen.priority(),sprite_ptr->primask,0); - else - taito_f2_tc360_spritemixdraw(screen,bitmap,cliprect,m_gfxdecode->gfx(0), - sprite_ptr->code, - sprite_ptr->color, - sprite_ptr->flipx,sprite_ptr->flipy, - sprite_ptr->x,sprite_ptr->y, - sprite_ptr->zoomx,sprite_ptr->zoomy); + taito_f2_tc360_spritemixdraw(screen,bitmap,cliprect,m_gfxdecode->gfx(0), + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx,sprite_ptr->flipy, + sprite_ptr->x,sprite_ptr->y, + sprite_ptr->zoomx,sprite_ptr->zoomy,sprite_ptr->primask,uses_tc360_mixer); } } @@ -1140,14 +1152,8 @@ u32 taitof2_state::screen_update_thundfox(screen_device &screen, bitmap_ind16 &b screen.priority().fill(0, cliprect); bitmap.fill(0, cliprect); /* wrong color? */ - /* - TODO: This isn't the correct way to handle the priority. At the moment of - writing, pdrawgfx() doesn't support 6 layers, so I have to cheat, assuming - that the two FG layers are always on top of sprites. - */ - drawn[0] = drawn[1] = 0; - while (drawn[0] < 2 && drawn[1] < 2) + while (drawn[0] < 3 && drawn[1] < 3) { int pick; @@ -1160,48 +1166,33 @@ u32 taitof2_state::screen_update_thundfox(screen_device &screen, bitmap_ind16 &b pick = 1; } - m_tc0100scn[pick]->tilemap_draw(screen, bitmap, cliprect, layer[pick][drawn[pick]], 0, 1 << (drawn[pick] + 2 * pick)); + m_tc0100scn[pick]->tilemap_draw(screen, bitmap, cliprect, layer[pick][drawn[pick]], 0, 1 << (drawn[pick] + 3 * pick)); drawn[pick]++; } - while (drawn[0] < 2) + while (drawn[0] < 3) { m_tc0100scn[0]->tilemap_draw(screen, bitmap, cliprect, layer[0][drawn[0]], 0, 1 << drawn[0]); drawn[0]++; } - while (drawn[1] < 2) + while (drawn[1] < 3) { - m_tc0100scn[1]->tilemap_draw(screen, bitmap, cliprect, layer[1][drawn[1]], 0, 1 << (drawn[1] + 2)); + m_tc0100scn[1]->tilemap_draw(screen, bitmap, cliprect, layer[1][drawn[1]], 0, 1 << (drawn[1] + 3)); drawn[1]++; } - u32 primasks[4] = {0,0,0,0}; + u64 primasks[4] = {0,0,0,0}; for (int i = 0; i < 4; i++) { - if (spritepri[i] < tilepri[0][0]) primasks[i] |= 0xaaaa; - if (spritepri[i] < tilepri[0][1]) primasks[i] |= 0xcccc; - if (spritepri[i] < tilepri[1][0]) primasks[i] |= 0xf0f0; - if (spritepri[i] < tilepri[1][1]) primasks[i] |= 0xff00; + if (spritepri[i] < tilepri[0][0]) primasks[i] |= 0xaaaaaaaaaaaaaaaaU; + if (spritepri[i] < tilepri[0][1]) primasks[i] |= 0xccccccccccccccccU; + if (spritepri[i] < tilepri[0][2]) primasks[i] |= 0xf0f0f0f0f0f0f0f0U; + if (spritepri[i] < tilepri[1][0]) primasks[i] |= 0xff00ff00ff00ff00U; + if (spritepri[i] < tilepri[1][1]) primasks[i] |= 0xffff0000ffff0000U; + if (spritepri[i] < tilepri[1][2]) primasks[i] |= 0xffffffff00000000U; } draw_sprites(screen, bitmap,cliprect,primasks,0); - - /* - TODO: This isn't the correct way to handle the priority. At the moment of - writing, pdrawgfx() doesn't support 6 layers, so I have to cheat, assuming - that the two FG layers are always on top of sprites. - */ - - if (tilepri[0][2] < tilepri[1][2]) - { - m_tc0100scn[0]->tilemap_draw(screen, bitmap, cliprect, layer[0][2], 0, 0); - m_tc0100scn[1]->tilemap_draw(screen, bitmap, cliprect, layer[1][2], 0, 0); - } - else - { - m_tc0100scn[1]->tilemap_draw(screen, bitmap, cliprect, layer[1][2], 0, 0); - m_tc0100scn[0]->tilemap_draw(screen, bitmap, cliprect, layer[0][2], 0, 0); - } return 0; } @@ -1305,8 +1296,6 @@ u32 taitof2_state::screen_update_deadconx(screen_device &screen, bitmap_ind16 &b tilepri[1] = m_tc0360pri->read(5) & 0x0f; /* bg1 */ tilepri[2] = m_tc0360pri->read(5) >> 4; /* bg2 */ tilepri[3] = m_tc0360pri->read(4) & 0x0f; /* bg3 */ - -/* we actually assume text layer is on top of everything anyway, but FWIW... */ tilepri[layer[4]] = m_tc0360pri->read(9) >> 4; /* fg (text layer) */ spritepri[0] = m_tc0360pri->read(6) & 0x0f; @@ -1321,25 +1310,19 @@ u32 taitof2_state::screen_update_deadconx(screen_device &screen, bitmap_ind16 &b m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8); + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 16); - u32 primasks[4] = {0,0,0,0}; + u64 primasks[4] = {0,0,0,0}; for (int i = 0; i < 4; i++) { - if (spritepri[i] < tilepri[(layer[0])]) primasks[i] |= 0xaaaa; - if (spritepri[i] < tilepri[(layer[1])]) primasks[i] |= 0xcccc; - if (spritepri[i] < tilepri[(layer[2])]) primasks[i] |= 0xf0f0; - if (spritepri[i] < tilepri[(layer[3])]) primasks[i] |= 0xff00; + if (spritepri[i] < tilepri[(layer[0])]) primasks[i] |= 0xaaaaaaaaaaaaaaaaU; + if (spritepri[i] < tilepri[(layer[1])]) primasks[i] |= 0xccccccccccccccccU; + if (spritepri[i] < tilepri[(layer[2])]) primasks[i] |= 0xf0f0f0f0f0f0f0f0U; + if (spritepri[i] < tilepri[(layer[3])]) primasks[i] |= 0xff00ff00ff00ff00U; + if (spritepri[i] < tilepri[(layer[4])]) primasks[i] |= 0xffff0000ffff0000U; } draw_sprites(screen, bitmap, cliprect, primasks, 0); - - /* - TODO: This isn't the correct way to handle the priority. At the moment of - writing, pdrawgfx() doesn't support 5 layers, so I have to cheat, assuming - that the FG layer is always on top of sprites. - */ - - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); return 0; } -- cgit v1.2.3