Player icon indicating copy to clipboard operation
Player copied to clipboard

Mosaic transition fails when the map's background is undefined

Open Lt-knb opened this issue 7 months ago • 3 comments

In RPG_RT, when a map has no background, it looks black, and Mosaic behaves as if it really has a black background. In EasyRPG, it doesn't, so it looks very wrong. In Yume Nikki, 23 maps are affected. To easily reproduce it, go to sleep, then go to Neon World (Map20) and press 9

Lt-knb avatar Jun 03 '25 08:06 Lt-knb

Btw thanks for making these detailed issues which try to explain the reason why something is broken. Safes us time figuring it out

Ghabry avatar Jun 03 '25 11:06 Ghabry

This is btw a long-standing bug but telling us where it happens exactly helped me finding the problematic line of code:

When the background is undefined we overdraw it with zero-bytes.

This also affects the alpha-channel (0 = fully transparent). For the screen output this alpha channel is ignored (a screen has no alpha so the byte is just ignored). Though the Mosaic code respects that alpha channel so it blits "nothing". Just forcing a fully opaque fixes the transition.

index a804bd241..14526334e 100644
--- a/src/transition.cpp
+++ b/src/transition.cpp
@@ -362,7 +362,7 @@ void Transition::Draw(Bitmap& dst) {
                                        m_pointer = static_cast<uint32_t *>(screen_pointer1->pixels()) + j * w + i;
                                        m_pointer += ((i == 0 ? 1 : 0) + (j == 0 ? w : 0)) * (m_size - 1);
                                        dst.pixel_format.uint32_to_rgba(*m_pointer, m_r, m_g, m_b, m_a);
-                                       dst.FillRect(Rect(i - ((m_size - w % m_size) % m_size) / 2, j - ((m_size - h % m_size) % m_size) / 2, m_size, m_size), Color(m_r, m_g, m_b, m_a));
+                                       dst.FillRect(Rect(i - ((m_size - w % m_size) % m_size) / 2, j - ((m_size - h % m_size) % m_size) / 2, m_size, m_size), Color(m_r, m_g, m_b, 255));
                                }
                else
                        dst.Blit(0, 0, *screen_pointer1, screen_pointer1->GetRect(), 255);

Bonus: Without the background overdraw you get this funny effect:

Image

Ghabry avatar Jun 04 '25 15:06 Ghabry

Btw thanks for making these detailed issues which try to explain the reason why something is broken. Safes us time figuring it out

Least I can do, I'm glad it's helping.

Nice, that was easy like the sound fade timing. Looking forward to trying out the PR

Lt-knb avatar Jun 05 '25 03:06 Lt-knb