From 02def869af45f3d89f658dd9b180a1f1c6093c95 Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Fri, 24 Oct 2025 12:37:56 -0400 Subject: [PATCH] sinclair/specnext_sprites.cpp: Detected sprites collision --- src/mame/sinclair/specnext_sprites.cpp | 46 ++++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/mame/sinclair/specnext_sprites.cpp b/src/mame/sinclair/specnext_sprites.cpp index c9173a97ac40b..c1192927c3dbf 100644 --- a/src/mame/sinclair/specnext_sprites.cpp +++ b/src/mame/sinclair/specnext_sprites.cpp @@ -78,8 +78,8 @@ void specnext_sprites_device::draw(screen_device &screen, bitmap_rgb32 &bitmap, for (auto i = 0; i < m_sprites_cache.size(); i++ ) { - const u8 x = m_zero_on_top ? i : (m_sprites_cache.size() - 1) - i; - const sprite_data &spr = m_sprites_cache[x]; + const u8 n = m_zero_on_top ? i : (m_sprites_cache.size() - 1) - i; + const sprite_data &spr = m_sprites_cache[n]; gfx((spr.rotate << 1) | spr.h)->prio_zoom_transpen(bitmap, clipped , spr.pattern >> (1 - spr.h), spr.paloff @@ -207,20 +207,46 @@ u8 specnext_sprites_device::status_r() bool collision = 0; for (auto s1 = begin(m_sprites_cache); !collision && s1 != end(m_sprites_cache); ++s1) { + const u8 t_pen1 = m_transp_colour & (s1->h ? 0x0f : 0xff); const u16 x1 = s1->x & 0x1ff; - const u16 w1 = 16 << ((s1->rotate & 1) ? s1->yscale : s1->xscale); const u16 y1 = s1->y & 0x1ff; - const u16 h1 = 16 << ((s1->rotate & 1) ? s1->xscale : s1->yscale); + const rectangle rec1 = { + x1, x1 + (16 << ((s1->rotate & 1) ? s1->yscale : s1->xscale)) - 1, + y1, y1 + (16 << ((s1->rotate & 1) ? s1->xscale : s1->yscale)) - 1 + }; for (auto s2 = s1 + 1; !collision && s2 != end(m_sprites_cache); ++s2) { const u16 x2 = s2->x & 0x1ff; - const u16 w2 = 16 << ((s2->rotate & 1) ? s2->yscale : s2->xscale); const u16 y2 = s2->y & 0x1ff; - const u16 h2 = 16 << ((s2->rotate & 1) ? s2->xscale : s2->yscale); - bool c = (x1 < x2 + w2) && (x2 < x1 + w1) && (y1 < y2 + h2) && (y2 < y1 + h1); - if (c) - ; // TODO detect if pixel(s) are not transparent - collision |= c; + rectangle over = rec1 & rectangle { + x2, x2 + (16 << ((s2->rotate & 1) ? s2->yscale : s2->xscale)) - 1, + y2, y2 + (16 << ((s2->rotate & 1) ? s2->xscale : s2->yscale)) - 1 + }; + if (!over.empty()) // sprites overlapped + { + const u8 t_pen2 = m_transp_colour & (s2->h ? 0x0f : 0xff); + bitmap_ind16 b1 = bitmap_ind16(16 << 3, 1); + bitmap_ind16 b2 = bitmap_ind16(16 << 3, 1); + for (u16 y = over.top(); y <= over.bottom(); ++y) // draw one line of the time in the overlap area + { + gfx((s1->rotate << 1) | s1->h)->zoom_opaque(b1, { 0, over.width() - 1, 0, 0 } + , s1->pattern >> (1 - s1->h), 0 + , s1->xmirror, s1->ymirror + , x1 - over.left(), y1 - y + , 0x10000 << s1->xscale, 0x10000 << s1->yscale); + gfx((s2->rotate << 1) | s2->h)->zoom_opaque(b2, { 0, over.width() - 1, 0, 0 } + , s2->pattern >> (1 - s2->h), 0 + , s2->xmirror, s2->ymirror + , x2 - over.left(), y2 - y + , 0x10000 << s2->xscale, 0x10000 << s2->yscale); + + for (u8 x = 0; !collision && (x < over.width()); ++x) + collision = (b1.pix(0, x) & 0xff) != t_pen1 && (b2.pix(0, x) & 0xff) != t_pen2; + + if (collision) + break; + } + } } }