From 17169320b45bd2eed49ed7a8f0921b29bfbd0159 Mon Sep 17 00:00:00 2001 From: Misa Date: Sun, 21 Mar 2021 12:49:14 -0700 Subject: [PATCH] Fix text box deltaframe flashing on deltaframes after fully opaque So #434 didn't end up solving the deltaframe flashing fully, only reduced the chances that it could happen. I've had the Level Complete image flash a few times when the Game Saved text box pops up. This seems to be because the Level Complete image is based off of the text box being at y-position 12, and the Game Saved text box is also at y-position 12. Level Complete only gets drawn if the text box additionally has a red channel value of 165, and the Game Saved text box has a red channel value of 174. However, there is a check that the text box be fully opaque first before drawing special images. So what went wrong? Well, after thinking about it for a while, I realized that even though there is indeed an opaqueness check, the alpha of the text box updates BEFORE it gets drawn. And during the deltaframes immediately after it gets updated, the text box is considered fully opaque. It's completely possible for the linear interpolation to end up with a red channel value of 165 during these deltaframes, while the text box is opaque as well. As always, it helps if you have a high refresh rate, and run the game under 40% slowdown. Anyways, so what's the final fix for this issue? Well, use the text box 'target' RGB values instead - its tr/tg/tb attributes instead of its r/g/b attributes. They are not subject to interpolation and so are completely reliable. The opaqueness check should still be kept, though, because the target values don't account for opaqueness. And this way, we get no more deltaframe flashes during text box fades. An even better fix would be to not use magic RGB values to draw special images... but that'd be something to do later. --- desktop_version/src/Graphics.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 8a1bb266..5784da61 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -835,6 +835,7 @@ void Graphics::drawgui(void) { int text_yoff; int yp; + bool opaque; if (flipmode) { text_yoff = textbox[i].line.size() * 8; @@ -854,7 +855,7 @@ void Graphics::drawgui(void) float tl_lerp = lerp(textbox[i].prev_tl, textbox[i].tl); textbox[i].setcol(textbox[i].tr * tl_lerp, textbox[i].tg * tl_lerp, textbox[i].tb * tl_lerp); - if (textbox[i].r == 0 && textbox[i].g == 0 && textbox[i].b == 0) + if (textbox[i].tr == 0 && textbox[i].tg == 0 && textbox[i].tb == 0) { for (size_t j = 0; j < textbox[i].line.size(); j++) { @@ -888,11 +889,14 @@ void Graphics::drawgui(void) } } - // Only draw special images when fully opaque - // This prevents flashes of special images during delta frames - bool drawspecial = textbox[i].tl >= 1.0; + opaque = textbox[i].tl >= 1.0; - if (textbox[i].yp == 12 && textbox[i].r == 165 && drawspecial) + if (!opaque) + { + continue; + } + + if (textbox[i].yp == 12 && textbox[i].tr == 165) { if (flipmode) { @@ -903,7 +907,7 @@ void Graphics::drawgui(void) drawimage(0, 0, 12, true); } } - else if (textbox[i].yp == 12 && textbox[i].g == 165 && drawspecial) + else if (textbox[i].yp == 12 && textbox[i].tg == 165) { if (flipmode) { @@ -914,27 +918,27 @@ void Graphics::drawgui(void) drawimage(4, 0, 12, true); } } - if (textbox[i].r == 175 && textbox[i].g == 175 && drawspecial) + if (textbox[i].tr == 175 && textbox[i].tg == 175) { //purple guy drawsprite(80 - 6, crew_yp, crew_sprite, 220- help.glow/4 - int(fRandom()*20), 120- help.glow/4, 210 - help.glow/4); } - else if (textbox[i].r == 175 && textbox[i].b == 175 && drawspecial) + else if (textbox[i].tr == 175 && textbox[i].tb == 175) { //red guy drawsprite(80 - 6, crew_yp, crew_sprite, 255 - help.glow/8, 70 - help.glow/4, 70 - help.glow / 4); } - else if (textbox[i].r == 175 && drawspecial) + else if (textbox[i].tr == 175) { //green guy drawsprite(80 - 6, crew_yp, crew_sprite, 120 - help.glow / 4 - int(fRandom() * 20), 220 - help.glow / 4, 120 - help.glow / 4); } - else if (textbox[i].g == 175 && drawspecial) + else if (textbox[i].tg == 175) { //yellow guy drawsprite(80 - 6, crew_yp, crew_sprite, 220- help.glow/4 - int(fRandom()*20), 210 - help.glow/4, 120- help.glow/4); } - else if (textbox[i].b == 175 && drawspecial) + else if (textbox[i].tb == 175) { //blue guy drawsprite(80 - 6, crew_yp, crew_sprite, 75, 75, 255- help.glow/4 - int(fRandom()*20));