From 88346c2d936ba965b109c631dae9b0d012b3411c Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Fri, 17 Oct 2025 23:12:18 +0200 Subject: [PATCH 01/15] Mosaic: Fix random offset range Fix part of #3446 --- src/transition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transition.cpp b/src/transition.cpp index 9dafb0ba8f..4eaa0cd891 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -176,7 +176,7 @@ void Transition::SetAttributesTransitions() { const int initial_scale = 2; const int excl_interval = -1; // by default i 0..39 for scale 2..41 - mosaic_random_offset[i] = Rand::GetRandomNumber(0, i + initial_scale - excl_interval); + mosaic_random_offset[i] = Rand::GetRandomNumber(0, i + initial_scale + excl_interval); } break; default: From f04e4ce0c32385d1514002008229c883e8557566 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Fri, 17 Oct 2025 23:20:57 +0200 Subject: [PATCH 02/15] Wave: Fix trailing artifacts Fix part of #3446 --- src/transition.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transition.cpp b/src/transition.cpp index 4eaa0cd891..84b1671b93 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -404,6 +404,7 @@ void Transition::Draw(Bitmap& dst) { auto& screen = (transition_type == TransitionWaveIn) ? *screen2 : *screen1; auto depth = p * 40 / 100; auto phase = p * 5 * M_PI / 100.0 + M_PI; + dst.FillRect(Rect(0, 0, w, h), Color(0, 0, 0, 255)); dst.WaverBlit(0, 0, 1, 1, screen, screen.GetRect(), depth, phase, Opacity::Opaque()); } break; From 91853fb8d4a534caa1d6996daa6e1e5a7ccbb7e5 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Sun, 19 Oct 2025 03:48:54 +0200 Subject: [PATCH 03/15] Wave: Make depth and phase frame-based to fix integer truncation --- src/transition.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 84b1671b93..2753ffb2fb 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -399,11 +399,11 @@ void Transition::Draw(Bitmap& dst) { case TransitionWaveIn: case TransitionWaveOut: { - // If TransitionWaveIn, invert percentage and screen: - auto p = (transition_type == TransitionWaveIn) ? 100 - percentage : percentage; + // If TransitionWaveIn, invert depth, phase and screen: + auto p = (transition_type == TransitionWaveIn) ? total_frames - current_frame : current_frame; auto& screen = (transition_type == TransitionWaveIn) ? *screen2 : *screen1; - auto depth = p * 40 / 100; - auto phase = p * 5 * M_PI / 100.0 + M_PI; + auto depth = p; + auto phase = p * 5 * M_PI / total_frames + M_PI; dst.FillRect(Rect(0, 0, w, h), Color(0, 0, 0, 255)); dst.WaverBlit(0, 0, 1, 1, screen, screen.GetRect(), depth, phase, Opacity::Opaque()); } From 5cf7b0b916155e356bc22aaf0b562bc938571875 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Mon, 20 Oct 2025 06:23:59 +0200 Subject: [PATCH 04/15] Make Stripes and Scroll frame-based to fix truncation. Part of #3446 --- src/transition.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 2753ffb2fb..3afbbd6d1f 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -242,22 +242,22 @@ void Transition::Draw(Bitmap& dst) { break; case TransitionVerticalStripesIn: case TransitionVerticalStripesOut: - for (int i = 0; i < h / 6 + 1 - h / 6 * percentage / 100; i++) { + for (int i = 0; i < total_frames - current_frame; i++) { dst.Blit(0, i * 6 + 3, *screen1, Rect(0, i * 6 + 3, w, 3), 255); dst.Blit(0, h - i * 6, *screen1, Rect(0, h - i * 6, w, 3), 255); } - for (int i = 0; i < h / 6 * percentage / 100; i++) { + for (int i = 0; i < current_frame; i++) { dst.Blit(0, i * 6, *screen2, Rect(0, i * 6, w, 3), 255); dst.Blit(0, h - 3 - i * 6, *screen2, Rect(0, h - 3 - i * 6, w, 3), 255); } break; case TransitionHorizontalStripesIn: case TransitionHorizontalStripesOut: - for (int i = 0; i < w / 8 + 1 - w / 8 * percentage / 100; i++) { + for (int i = 0; i < total_frames - current_frame; i++) { dst.Blit(i * 8 + 4, 0, *screen1, Rect(i * 8 + 4, 0, 4, h), 255); dst.Blit(w - i * 8, 0, *screen1, Rect(w - i * 8, 0, 4, h), 255); } - for (int i = 0; i < w / 8 * percentage / 100; i++) { + for (int i = 0; i < current_frame; i++) { dst.Blit(i * 8, 0, *screen2, Rect(i * 8, 0, 4, h), 255); dst.Blit(w - 4 - i * 8, 0, *screen2, Rect(w - 4 - i * 8, 0, 4, h), 255); } @@ -274,23 +274,23 @@ void Transition::Draw(Bitmap& dst) { break; case TransitionScrollUpIn: case TransitionScrollUpOut: - dst.Blit(0, -h * percentage / 100, *screen1, screen1->GetRect(), 255); - dst.Blit(0, h - h * percentage / 100, *screen2, screen2->GetRect(), 255); + dst.Blit(0, -h * current_frame / total_frames, *screen1, screen1->GetRect(), 255); + dst.Blit(0, h - h * current_frame / total_frames, *screen2, screen2->GetRect(), 255); break; case TransitionScrollDownIn: case TransitionScrollDownOut: - dst.Blit(0, h * percentage / 100, *screen1, screen1->GetRect(), 255); - dst.Blit(0, -h + h * percentage / 100, *screen2, screen2->GetRect(), 255); + dst.Blit(0, h * current_frame / total_frames, *screen1, screen1->GetRect(), 255); + dst.Blit(0, -h + h * current_frame / total_frames, *screen2, screen2->GetRect(), 255); break; case TransitionScrollLeftIn: case TransitionScrollLeftOut: - dst.Blit(-w * percentage / 100, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(w - w * percentage / 100, 0, *screen2, screen2->GetRect(), 255); + dst.Blit(-w * current_frame / total_frames, 0, *screen1, screen1->GetRect(), 255); + dst.Blit(w - w * current_frame / total_frames, 0, *screen2, screen2->GetRect(), 255); break; case TransitionScrollRightIn: case TransitionScrollRightOut: - dst.Blit(w * percentage / 100, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(-w + w * percentage / 100, 0, *screen2, screen2->GetRect(), 255); + dst.Blit(w * current_frame / total_frames, 0, *screen1, screen1->GetRect(), 255); + dst.Blit(-w + w * current_frame / total_frames, 0, *screen2, screen2->GetRect(), 255); break; case TransitionVerticalCombine: case TransitionVerticalDivision: From 938c992c58619a6da0b626f7b365afcc94269af8 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:01:53 +0200 Subject: [PATCH 05/15] Blind: Make frame-based and apply offset to fix starting frame and percentage truncation --- src/transition.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 3afbbd6d1f..802863f4de 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -230,14 +230,14 @@ void Transition::Draw(Bitmap& dst) { break; case TransitionBlindOpen: for (int i = 0; i < h / 8; i++) { - dst.Blit(0, i * 8, *screen1, Rect(0, i * 8, w, 8 - 8 * percentage / 100), 255); - dst.Blit(0, i * 8 + 8 - 8 * percentage / 100, *screen2, Rect(0, i * 8 + 8 - 8 * percentage / 100, w, 8 * percentage / 100), 255); + dst.Blit(0, i * 8, *screen1, Rect(0, i * 8, w, 8 - (current_frame + 4) / 5), 255); + dst.Blit(0, i * 8 + 8 - (current_frame + 4) / 5, *screen2, Rect(0, i * 8 + 8 - (current_frame + 4) / 5, w, (current_frame + 4) / 5), 255); } break; case TransitionBlindClose: for (int i = 0; i < h / 8; i++) { - dst.Blit(0, i * 8 + 8 * percentage / 100, *screen1, Rect(0, i * 8 + 8 * percentage / 100, w, 8 - 8 * percentage / 100), 255); - dst.Blit(0, i * 8, *screen2, Rect(0, i * 8, w, 8 * percentage / 100), 255); + dst.Blit(0, i * 8 + (current_frame + 4) / 5, *screen1, Rect(0, i * 8 + (current_frame + 4) / 5, w, 8 - (current_frame + 4) / 5), 255); + dst.Blit(0, i * 8, *screen2, Rect(0, i * 8, w, (current_frame + 4) / 5), 255); } break; case TransitionVerticalStripesIn: From f255944b9c995a231aa50cebf70b66819030e1c8 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Fri, 24 Oct 2025 03:55:15 +0200 Subject: [PATCH 06/15] Make BorderToCenter and CenterToBorder frame-based to fix truncation. Part of #3446 --- src/transition.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 802863f4de..55d43aa6cf 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -265,12 +265,12 @@ void Transition::Draw(Bitmap& dst) { case TransitionBorderToCenterIn: case TransitionBorderToCenterOut: dst.Blit(0, 0, *screen2, screen2->GetRect(), 255); - dst.Blit((w / 2) * percentage / 100, (h / 2) * percentage / 100, *screen1, Rect((w / 2) * percentage / 100, (h / 2) * percentage / 100, w - w * percentage / 100, h - h * percentage / 100), 255); + dst.Blit((w / 2) * current_frame / total_frames, (h / 2) * current_frame / total_frames, *screen1, Rect((w / 2) * current_frame / total_frames, (h / 2) * current_frame / total_frames, w - w * current_frame / total_frames, h - h * current_frame / total_frames), 255); break; case TransitionCenterToBorderIn: case TransitionCenterToBorderOut: dst.Blit(0, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(w / 2 - (w / 2) * percentage / 100, h / 2 - (h / 2) * percentage / 100, *screen2, Rect(w / 2 - (w / 2) * percentage / 100, h / 2 - (h / 2) * percentage / 100, w * percentage / 100, h * percentage / 100), 255); + dst.Blit(w / 2 - (w / 2) * current_frame / total_frames, h / 2 - (h / 2) * current_frame / total_frames, *screen2, Rect(w / 2 - (w / 2) * current_frame / total_frames, h / 2 - (h / 2) * current_frame / total_frames, w * current_frame / total_frames, h * current_frame / total_frames), 255); break; case TransitionScrollUpIn: case TransitionScrollUpOut: From 0d9be495036e82412669f593a0a2230c00a34b47 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Sun, 26 Oct 2025 02:45:17 +0100 Subject: [PATCH 07/15] Make Combine/Division frame-based to fix truncation. Part of #3446 --- src/transition.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 55d43aa6cf..92177c8e62 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -293,27 +293,29 @@ void Transition::Draw(Bitmap& dst) { dst.Blit(-w + w * current_frame / total_frames, 0, *screen2, screen2->GetRect(), 255); break; case TransitionVerticalCombine: - case TransitionVerticalDivision: - // If TransitionVerticalCombine, invert percentage and screen: - if (transition_type == TransitionVerticalCombine) { percentage = 100 - percentage; } + case TransitionVerticalDivision: { + // If TransitionVerticalCombine, invert current_frame and screen: + int ver_cf = transition_type == TransitionVerticalCombine ? total_frames - current_frame : current_frame; screen_pointer1 = transition_type == TransitionVerticalCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionVerticalCombine ? screen1 : screen2; - dst.Blit(0, -(h / 2) * percentage / 100, *screen_pointer1, Rect(0, 0, w, h / 2), 255); - dst.Blit(0, h / 2 + (h / 2) * percentage / 100, *screen_pointer1, Rect(0, h / 2, w, h / 2), 255); - dst.Blit(0, h / 2 - (h / 2) * percentage / 100, *screen_pointer2, Rect(0, h / 2 - (h / 2) * percentage / 100, w, h * percentage / 100), 255); + dst.Blit(0, -(h / 2) * ver_cf / total_frames, *screen_pointer1, Rect(0, 0, w, h / 2), 255); + dst.Blit(0, h / 2 + (h / 2) * ver_cf / total_frames, *screen_pointer1, Rect(0, h / 2, w, h / 2), 255); + dst.Blit(0, h / 2 - (h / 2) * ver_cf / total_frames, *screen_pointer2, Rect(0, h / 2 - (h / 2) * ver_cf / total_frames, w, h * ver_cf / total_frames), 255); break; + } case TransitionHorizontalCombine: - case TransitionHorizontalDivision: - // If TransitionHorizontalCombine, invert percentage and screen: - if (transition_type == TransitionHorizontalCombine) { percentage = 100 - percentage; } + case TransitionHorizontalDivision: { + // If TransitionHorizontalCombine, invert current_frame and screen: + int hor_cf = transition_type == TransitionHorizontalCombine ? total_frames - current_frame : current_frame; screen_pointer1 = transition_type == TransitionHorizontalCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionHorizontalCombine ? screen1 : screen2; - dst.Blit(-(w / 2) * percentage / 100, 0, *screen_pointer1, Rect(0, 0, w / 2, h), 255); - dst.Blit(w / 2 + (w / 2) * percentage / 100, 0, *screen_pointer1, Rect(w / 2, 0, w / 2, h), 255); - dst.Blit(w / 2 - (w / 2) * percentage / 100, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * percentage / 100, 0, w * percentage / 100, h), 255); + dst.Blit(-(w / 2) * hor_cf / total_frames, 0, *screen_pointer1, Rect(0, 0, w / 2, h), 255); + dst.Blit(w / 2 + (w / 2) * hor_cf / total_frames, 0, *screen_pointer1, Rect(w / 2, 0, w / 2, h), 255); + dst.Blit(w / 2 - (w / 2) * hor_cf / total_frames, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * hor_cf / total_frames, 0, w * hor_cf / total_frames, h), 255); break; + } case TransitionCrossCombine: case TransitionCrossDivision: // If TransitionCrossCombine, invert percentage and screen: From 40b5ecb7ff04a4333beb02cfea9e798fc75ceb3e Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Sun, 26 Oct 2025 20:50:53 +0100 Subject: [PATCH 08/15] Make CrossCombine/Division frame-based to fix truncation. Part of #3446 --- src/transition.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 92177c8e62..d04c2f116c 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -317,20 +317,21 @@ void Transition::Draw(Bitmap& dst) { break; } case TransitionCrossCombine: - case TransitionCrossDivision: - // If TransitionCrossCombine, invert percentage and screen: - if (transition_type == TransitionCrossCombine) { percentage = 100 - percentage; } + case TransitionCrossDivision: { + // If TransitionCrossCombine, invert current_frame and screen: + int cross_cf = transition_type == TransitionCrossCombine ? total_frames - current_frame : current_frame; screen_pointer1 = transition_type == TransitionCrossCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionCrossCombine ? screen1 : screen2; - dst.Blit(-(w / 2) * percentage / 100, -(h / 2) * percentage / 100, *screen_pointer1, Rect(0, 0, w / 2, h / 2), 255); - dst.Blit(w / 2 + (w / 2) * percentage / 100, -(h / 2) * percentage / 100, *screen_pointer1, Rect(w / 2, 0, w / 2, h / 2), 255); - dst.Blit(w / 2 + (w / 2) * percentage / 100, h / 2 + (h / 2) * percentage / 100, *screen_pointer1, Rect(w / 2, h / 2, w / 2, h / 2), 255); - dst.Blit(-(w / 2) * percentage / 100, h / 2 + (h / 2) * percentage / 100, *screen_pointer1, Rect(0, h / 2, w / 2, h / 2), 255); - dst.Blit(w / 2 - (w / 2) * percentage / 100, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * percentage / 100, 0, w * percentage / 100, h / 2 - (h / 2) * percentage / 100), 255); - dst.Blit(w / 2 - (w / 2) * percentage / 100, h / 2 + (h / 2) * percentage / 100, *screen_pointer2, Rect(w / 2 - (w / 2) * percentage / 100, h / 2 + (h / 2) * percentage / 100, w * percentage / 100, h / 2 + (h / 2) * percentage / 100), 255); - dst.Blit(0, h / 2 - (h / 2) * percentage / 100, *screen_pointer2, Rect(0, h / 2 - (h / 2) * percentage / 100, w, h * percentage / 100), 255); + dst.Blit(-(w / 2) * cross_cf / total_frames, -(h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(0, 0, w / 2, h / 2), 255); + dst.Blit(w / 2 + (w / 2) * cross_cf / total_frames, -(h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(w / 2, 0, w / 2, h / 2), 255); + dst.Blit(w / 2 + (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(w / 2, h / 2, w / 2, h / 2), 255); + dst.Blit(-(w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(0, h / 2, w / 2, h / 2), 255); + dst.Blit(w / 2 - (w / 2) * cross_cf / total_frames, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / total_frames, 0, w * cross_cf / total_frames, h / 2 - (h / 2) * cross_cf / total_frames), 255); + dst.Blit(w / 2 - (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, w * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames), 255); + dst.Blit(0, h / 2 - (h / 2) * cross_cf / total_frames, *screen_pointer2, Rect(0, h / 2 - (h / 2) * cross_cf / total_frames, w, h * cross_cf / total_frames), 255); break; + } case TransitionZoomIn: case TransitionZoomOut: // If TransitionZoomOut, invert percentage and screen: From 36fe20c9ab9b9d36637025e14b87597497913ec5 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Mon, 27 Oct 2025 01:25:26 +0100 Subject: [PATCH 09/15] Make Zoom frame-based to fix percentage truncation. Part of #3446 --- src/transition.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index d04c2f116c..c43a7864c7 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -190,7 +190,7 @@ void Transition::Draw(Bitmap& dst) { return; std::vector z_pos(2), z_size(2), z_length(2); - int z_min, z_max, z_percent, z_fixed_pos, z_fixed_size; + int z_min, z_max, z_frame, z_fixed_pos, z_fixed_size; uint8_t m_r, m_g, m_b, m_a; uint32_t *m_pointer, blocks_to_print; int m_size; @@ -333,35 +333,36 @@ void Transition::Draw(Bitmap& dst) { break; } case TransitionZoomIn: - case TransitionZoomOut: - // If TransitionZoomOut, invert percentage and screen: - if (transition_type == TransitionZoomOut) { percentage = 100 - percentage; } + case TransitionZoomOut: { + // If TransitionZoomOut, invert current_frame and screen: + int z_cf = transition_type == TransitionZoomOut ? total_frames - current_frame : current_frame; screen_pointer1 = transition_type == TransitionZoomOut ? screen2 : screen1; // X Coordinate: [0] Y Coordinate: [1] z_length[0] = w; z_length[1] = h; - percentage = percentage <= 97 ? percentage : 97; + z_cf = z_cf <= total_frames - 1 ? z_cf : total_frames - 1; for (int i = 0; i < 2; i++) { z_min = z_length[i] / 4; z_max = z_length[i] * 3 / 4; - z_pos[i] = std::max(z_min, std::min((int)zoom_position[i], z_max)) * percentage / 100; - z_size[i] = z_length[i] * (100 - percentage) / 100; + z_pos[i] = std::max(z_min, std::min((int)zoom_position[i], z_max)) * z_cf / total_frames; + z_size[i] = z_length[i] * (total_frames - z_cf) / total_frames; - z_percent = (zoom_position[i] < z_min) ? (100 * zoom_position[i] / z_min - 100) : - (zoom_position[i] > z_max) ? (100 * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0; + z_frame = (zoom_position[i] < z_min) ? (total_frames * zoom_position[i] / z_min - total_frames) : + (zoom_position[i] > z_max) ? (total_frames * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0; - if (z_percent != 0 && percentage > 0) { - z_fixed_pos = z_pos[i] * std::abs(z_percent) / percentage; - z_fixed_size = z_length[i] * (100 - std::abs(z_percent)) / 100; - z_pos[i] += percentage < std::abs(z_percent) ? (z_percent > 0 ? 1 : 0) * (z_length[i] - z_size[i]) - z_pos[i] : - (z_percent > 0 ? z_length[i] - z_fixed_pos - z_fixed_size : -z_fixed_pos); + if (z_frame != 0 && z_cf > 0) { + z_fixed_pos = z_pos[i] * std::abs(z_frame) / z_cf; + z_fixed_size = z_length[i] * (total_frames - std::abs(z_frame)) / total_frames; + z_pos[i] += z_cf < std::abs(z_frame) ? (z_frame > 0 ? 1 : 0) * (z_length[i] - z_size[i]) - z_pos[i] : + (z_frame > 0 ? z_length[i] - z_fixed_pos - z_fixed_size : -z_fixed_pos); } } dst.StretchBlit(Rect(0, 0, w, h), *screen_pointer1, Rect(z_pos[0], z_pos[1], z_size[0], z_size[1]), 255); break; + } case TransitionMosaicIn: case TransitionMosaicOut: { // Goes from scale 2 to 41 (current_frame is 0 - 39) From 5d8891f13fdab4cae28657990b70519b0b71a8de Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Mon, 27 Oct 2025 03:43:44 +0100 Subject: [PATCH 10/15] Make Fade and RandomBlocks frame-based to fix truncation and remove percentage. Part of #3446 --- src/transition.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index c43a7864c7..cad307bf0d 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -205,18 +205,16 @@ void Transition::Draw(Bitmap& dst) { return; } - int percentage = (current_frame) * 100 / (total_frames); - switch (transition_type) { case TransitionFadeIn: case TransitionFadeOut: dst.Blit(0, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * percentage / 100); + dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * current_frame / total_frames); break; case TransitionRandomBlocks: case TransitionRandomBlocksDown: case TransitionRandomBlocksUp: - blocks_to_print = random_blocks.size() * percentage / 100; + blocks_to_print = random_blocks.size() * current_frame / total_frames; for (uint32_t i = current_blocks_print; i < blocks_to_print; i++) { random_block_transition->Blit(random_blocks[i] % (w / size_random_blocks) * size_random_blocks, From b54ef62b1322993628ad262849f6f75db3091c22 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Wed, 29 Oct 2025 19:55:52 +0100 Subject: [PATCH 11/15] Change Cut Duration It's one frame in RPG_RT. Part of #3446 --- src/transition.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transition.cpp b/src/transition.cpp index cad307bf0d..6467466999 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -45,6 +45,7 @@ int Transition::GetDefaultFrames(Transition::Type type) return 32; case TransitionCutIn: case TransitionCutOut: + return 1; case TransitionNone: return 0; default: From c9f39afbddb8e4e755da3bf6bc429268f826a99e Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Wed, 29 Oct 2025 22:36:40 +0100 Subject: [PATCH 12/15] Render Frame 0 (no offsets yet) First step to fix the off-by-one error. Fix #3446 --- src/transition.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/transition.cpp b/src/transition.cpp index 6467466999..10c739eae6 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -81,7 +81,8 @@ void Transition::Init(Type type, Scene *linked_scene, int duration, bool next_er transition_type = type; scene = linked_scene; - current_frame = 0; + // Don't skip Frame 0 (Update is called before Draw). + current_frame = -1; flash = {}; flash_power = 0; flash_iterations = 0; From eb0da53ae830823dad2b8ac2c2f92b86520517f1 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Thu, 30 Oct 2025 00:34:58 +0100 Subject: [PATCH 13/15] Change Fade and Default Duration (no offsets yet) First step to fix the frame count. Part of #3446 --- src/transition.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 10c739eae6..56a7f5d59c 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -42,14 +42,14 @@ int Transition::GetDefaultFrames(Transition::Type type) switch (type) { case TransitionFadeIn: case TransitionFadeOut: - return 32; + return 35; case TransitionCutIn: case TransitionCutOut: return 1; case TransitionNone: return 0; default: - return 40; + return 41; } return 0; } From 20aaf5b00eb56f0cca40c6091674870389edeff7 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Sun, 2 Nov 2025 22:29:02 +0100 Subject: [PATCH 14/15] Apply offsets Fix the off-by-one error and frame count. Fix #3446 --- src/transition.cpp | 109 ++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/src/transition.cpp b/src/transition.cpp index 56a7f5d59c..8947222bc7 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -175,10 +175,8 @@ void Transition::SetAttributesTransitions() { case TransitionMosaicIn: case TransitionMosaicOut: for (int i = 0; i < total_frames; ++i) { - const int initial_scale = 2; - const int excl_interval = -1; - // by default i 0..39 for scale 2..41 - mosaic_random_offset[i] = Rand::GetRandomNumber(0, i + initial_scale + excl_interval); + // by default i 0..40 for scale 1..41 + mosaic_random_offset[i] = Rand::GetRandomNumber(0, i); } break; default: @@ -206,17 +204,19 @@ void Transition::Draw(Bitmap& dst) { dst.BlendBlit(0, 0, *screen1, screen1->GetRect(), color, 255); return; } + + int tf_off = total_frames - 1; switch (transition_type) { case TransitionFadeIn: case TransitionFadeOut: dst.Blit(0, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * current_frame / total_frames); + dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * (current_frame + 1) / (total_frames - 2); break; case TransitionRandomBlocks: case TransitionRandomBlocksDown: case TransitionRandomBlocksUp: - blocks_to_print = random_blocks.size() * current_frame / total_frames; + blocks_to_print = random_blocks.size() * (current_frame + 1) / tf_off; for (uint32_t i = current_blocks_print; i < blocks_to_print; i++) { random_block_transition->Blit(random_blocks[i] % (w / size_random_blocks) * size_random_blocks, @@ -230,34 +230,34 @@ void Transition::Draw(Bitmap& dst) { break; case TransitionBlindOpen: for (int i = 0; i < h / 8; i++) { - dst.Blit(0, i * 8, *screen1, Rect(0, i * 8, w, 8 - (current_frame + 4) / 5), 255); - dst.Blit(0, i * 8 + 8 - (current_frame + 4) / 5, *screen2, Rect(0, i * 8 + 8 - (current_frame + 4) / 5, w, (current_frame + 4) / 5), 255); + dst.Blit(0, i * 8, *screen1, Rect(0, i * 8, w, 8 - (current_frame + 5) / 5), 255); + dst.Blit(0, i * 8 + 8 - (current_frame + 5) / 5, *screen2, Rect(0, i * 8 + 8 - (current_frame + 5) / 5, w, (current_frame + 5) / 5), 255); } break; case TransitionBlindClose: for (int i = 0; i < h / 8; i++) { - dst.Blit(0, i * 8 + (current_frame + 4) / 5, *screen1, Rect(0, i * 8 + (current_frame + 4) / 5, w, 8 - (current_frame + 4) / 5), 255); - dst.Blit(0, i * 8, *screen2, Rect(0, i * 8, w, (current_frame + 4) / 5), 255); + dst.Blit(0, i * 8 + (current_frame + 5) / 5, *screen1, Rect(0, i * 8 + (current_frame + 5) / 5, w, 8 - (current_frame + 5) / 5), 255); + dst.Blit(0, i * 8, *screen2, Rect(0, i * 8, w, (current_frame + 5) / 5), 255); } break; case TransitionVerticalStripesIn: case TransitionVerticalStripesOut: - for (int i = 0; i < total_frames - current_frame; i++) { + for (int i = 0; i < tf_off - (current_frame + 1); i++) { dst.Blit(0, i * 6 + 3, *screen1, Rect(0, i * 6 + 3, w, 3), 255); dst.Blit(0, h - i * 6, *screen1, Rect(0, h - i * 6, w, 3), 255); } - for (int i = 0; i < current_frame; i++) { + for (int i = 0; i < current_frame + 1; i++) { dst.Blit(0, i * 6, *screen2, Rect(0, i * 6, w, 3), 255); dst.Blit(0, h - 3 - i * 6, *screen2, Rect(0, h - 3 - i * 6, w, 3), 255); } break; case TransitionHorizontalStripesIn: case TransitionHorizontalStripesOut: - for (int i = 0; i < total_frames - current_frame; i++) { + for (int i = 0; i < tf_off - (current_frame + 1); i++) { dst.Blit(i * 8 + 4, 0, *screen1, Rect(i * 8 + 4, 0, 4, h), 255); dst.Blit(w - i * 8, 0, *screen1, Rect(w - i * 8, 0, 4, h), 255); } - for (int i = 0; i < current_frame; i++) { + for (int i = 0; i < current_frame + 1; i++) { dst.Blit(i * 8, 0, *screen2, Rect(i * 8, 0, 4, h), 255); dst.Blit(w - 4 - i * 8, 0, *screen2, Rect(w - 4 - i * 8, 0, 4, h), 255); } @@ -265,96 +265,96 @@ void Transition::Draw(Bitmap& dst) { case TransitionBorderToCenterIn: case TransitionBorderToCenterOut: dst.Blit(0, 0, *screen2, screen2->GetRect(), 255); - dst.Blit((w / 2) * current_frame / total_frames, (h / 2) * current_frame / total_frames, *screen1, Rect((w / 2) * current_frame / total_frames, (h / 2) * current_frame / total_frames, w - w * current_frame / total_frames, h - h * current_frame / total_frames), 255); + dst.Blit((w / 2) * current_frame / tf_off, (h / 2) * current_frame / tf_off, *screen1, Rect((w / 2) * current_frame / tf_off, (h / 2) * current_frame / tf_off, w - w * current_frame / tf_off, h - h * current_frame / tf_off), 255); break; case TransitionCenterToBorderIn: case TransitionCenterToBorderOut: dst.Blit(0, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(w / 2 - (w / 2) * current_frame / total_frames, h / 2 - (h / 2) * current_frame / total_frames, *screen2, Rect(w / 2 - (w / 2) * current_frame / total_frames, h / 2 - (h / 2) * current_frame / total_frames, w * current_frame / total_frames, h * current_frame / total_frames), 255); + dst.Blit(w / 2 - (w / 2) * current_frame / tf_off, h / 2 - (h / 2) * current_frame / tf_off, *screen2, Rect(w / 2 - (w / 2) * current_frame / tf_off, h / 2 - (h / 2) * current_frame / tf_off, w * current_frame / tf_off, h * current_frame / tf_off), 255); break; case TransitionScrollUpIn: case TransitionScrollUpOut: - dst.Blit(0, -h * current_frame / total_frames, *screen1, screen1->GetRect(), 255); - dst.Blit(0, h - h * current_frame / total_frames, *screen2, screen2->GetRect(), 255); + dst.Blit(0, -h * current_frame / tf_off, *screen1, screen1->GetRect(), 255); + dst.Blit(0, h - h * current_frame / tf_off, *screen2, screen2->GetRect(), 255); break; case TransitionScrollDownIn: case TransitionScrollDownOut: - dst.Blit(0, h * current_frame / total_frames, *screen1, screen1->GetRect(), 255); - dst.Blit(0, -h + h * current_frame / total_frames, *screen2, screen2->GetRect(), 255); + dst.Blit(0, h * current_frame / tf_off, *screen1, screen1->GetRect(), 255); + dst.Blit(0, -h + h * current_frame / tf_off, *screen2, screen2->GetRect(), 255); break; case TransitionScrollLeftIn: case TransitionScrollLeftOut: - dst.Blit(-w * current_frame / total_frames, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(w - w * current_frame / total_frames, 0, *screen2, screen2->GetRect(), 255); + dst.Blit(-w * current_frame / tf_off, 0, *screen1, screen1->GetRect(), 255); + dst.Blit(w - w * current_frame / tf_off, 0, *screen2, screen2->GetRect(), 255); break; case TransitionScrollRightIn: case TransitionScrollRightOut: - dst.Blit(w * current_frame / total_frames, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(-w + w * current_frame / total_frames, 0, *screen2, screen2->GetRect(), 255); + dst.Blit(w * current_frame / tf_off, 0, *screen1, screen1->GetRect(), 255); + dst.Blit(-w + w * current_frame / tf_off, 0, *screen2, screen2->GetRect(), 255); break; case TransitionVerticalCombine: case TransitionVerticalDivision: { // If TransitionVerticalCombine, invert current_frame and screen: - int ver_cf = transition_type == TransitionVerticalCombine ? total_frames - current_frame : current_frame; + int ver_cf = transition_type == TransitionVerticalCombine ? tf_off - current_frame : current_frame; screen_pointer1 = transition_type == TransitionVerticalCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionVerticalCombine ? screen1 : screen2; - dst.Blit(0, -(h / 2) * ver_cf / total_frames, *screen_pointer1, Rect(0, 0, w, h / 2), 255); - dst.Blit(0, h / 2 + (h / 2) * ver_cf / total_frames, *screen_pointer1, Rect(0, h / 2, w, h / 2), 255); - dst.Blit(0, h / 2 - (h / 2) * ver_cf / total_frames, *screen_pointer2, Rect(0, h / 2 - (h / 2) * ver_cf / total_frames, w, h * ver_cf / total_frames), 255); + dst.Blit(0, -(h / 2) * ver_cf / tf_off, *screen_pointer1, Rect(0, 0, w, h / 2), 255); + dst.Blit(0, h / 2 + (h / 2) * ver_cf / tf_off, *screen_pointer1, Rect(0, h / 2, w, h / 2), 255); + dst.Blit(0, h / 2 - (h / 2) * ver_cf / tf_off, *screen_pointer2, Rect(0, h / 2 - (h / 2) * ver_cf / tf_off, w, h * ver_cf / tf_off), 255); break; } case TransitionHorizontalCombine: case TransitionHorizontalDivision: { // If TransitionHorizontalCombine, invert current_frame and screen: - int hor_cf = transition_type == TransitionHorizontalCombine ? total_frames - current_frame : current_frame; + int hor_cf = transition_type == TransitionHorizontalCombine ? tf_off - current_frame : current_frame; screen_pointer1 = transition_type == TransitionHorizontalCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionHorizontalCombine ? screen1 : screen2; - dst.Blit(-(w / 2) * hor_cf / total_frames, 0, *screen_pointer1, Rect(0, 0, w / 2, h), 255); - dst.Blit(w / 2 + (w / 2) * hor_cf / total_frames, 0, *screen_pointer1, Rect(w / 2, 0, w / 2, h), 255); - dst.Blit(w / 2 - (w / 2) * hor_cf / total_frames, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * hor_cf / total_frames, 0, w * hor_cf / total_frames, h), 255); + dst.Blit(-(w / 2) * hor_cf / tf_off, 0, *screen_pointer1, Rect(0, 0, w / 2, h), 255); + dst.Blit(w / 2 + (w / 2) * hor_cf / tf_off, 0, *screen_pointer1, Rect(w / 2, 0, w / 2, h), 255); + dst.Blit(w / 2 - (w / 2) * hor_cf / tf_off, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * hor_cf / tf_off, 0, w * hor_cf / tf_off, h), 255); break; } case TransitionCrossCombine: case TransitionCrossDivision: { // If TransitionCrossCombine, invert current_frame and screen: - int cross_cf = transition_type == TransitionCrossCombine ? total_frames - current_frame : current_frame; + int cross_cf = transition_type == TransitionCrossCombine ? tf_off - current_frame : current_frame; screen_pointer1 = transition_type == TransitionCrossCombine ? screen2 : screen1; screen_pointer2 = transition_type == TransitionCrossCombine ? screen1 : screen2; - dst.Blit(-(w / 2) * cross_cf / total_frames, -(h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(0, 0, w / 2, h / 2), 255); - dst.Blit(w / 2 + (w / 2) * cross_cf / total_frames, -(h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(w / 2, 0, w / 2, h / 2), 255); - dst.Blit(w / 2 + (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(w / 2, h / 2, w / 2, h / 2), 255); - dst.Blit(-(w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer1, Rect(0, h / 2, w / 2, h / 2), 255); - dst.Blit(w / 2 - (w / 2) * cross_cf / total_frames, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / total_frames, 0, w * cross_cf / total_frames, h / 2 - (h / 2) * cross_cf / total_frames), 255); - dst.Blit(w / 2 - (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames, w * cross_cf / total_frames, h / 2 + (h / 2) * cross_cf / total_frames), 255); - dst.Blit(0, h / 2 - (h / 2) * cross_cf / total_frames, *screen_pointer2, Rect(0, h / 2 - (h / 2) * cross_cf / total_frames, w, h * cross_cf / total_frames), 255); + dst.Blit(-(w / 2) * cross_cf / tf_off, -(h / 2) * cross_cf / tf_off, *screen_pointer1, Rect(0, 0, w / 2, h / 2), 255); + dst.Blit(w / 2 + (w / 2) * cross_cf / tf_off, -(h / 2) * cross_cf / tf_off, *screen_pointer1, Rect(w / 2, 0, w / 2, h / 2), 255); + dst.Blit(w / 2 + (w / 2) * cross_cf / tf_off, h / 2 + (h / 2) * cross_cf / tf_off, *screen_pointer1, Rect(w / 2, h / 2, w / 2, h / 2), 255); + dst.Blit(-(w / 2) * cross_cf / tf_off, h / 2 + (h / 2) * cross_cf / tf_off, *screen_pointer1, Rect(0, h / 2, w / 2, h / 2), 255); + dst.Blit(w / 2 - (w / 2) * cross_cf / tf_off, 0, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / tf_off, 0, w * cross_cf / tf_off, h / 2 - (h / 2) * cross_cf / tf_off), 255); + dst.Blit(w / 2 - (w / 2) * cross_cf / tf_off, h / 2 + (h / 2) * cross_cf / tf_off, *screen_pointer2, Rect(w / 2 - (w / 2) * cross_cf / tf_off, h / 2 + (h / 2) * cross_cf / tf_off, w * cross_cf / tf_off, h / 2 + (h / 2) * cross_cf / tf_off), 255); + dst.Blit(0, h / 2 - (h / 2) * cross_cf / tf_off, *screen_pointer2, Rect(0, h / 2 - (h / 2) * cross_cf / tf_off, w, h * cross_cf / tf_off), 255); break; } case TransitionZoomIn: case TransitionZoomOut: { // If TransitionZoomOut, invert current_frame and screen: - int z_cf = transition_type == TransitionZoomOut ? total_frames - current_frame : current_frame; + int z_cf = transition_type == TransitionZoomOut ? tf_off - current_frame : current_frame; screen_pointer1 = transition_type == TransitionZoomOut ? screen2 : screen1; // X Coordinate: [0] Y Coordinate: [1] z_length[0] = w; z_length[1] = h; - z_cf = z_cf <= total_frames - 1 ? z_cf : total_frames - 1; + z_cf = z_cf <= total_frames - 2 ? z_cf : total_frames - 2; for (int i = 0; i < 2; i++) { z_min = z_length[i] / 4; z_max = z_length[i] * 3 / 4; - z_pos[i] = std::max(z_min, std::min((int)zoom_position[i], z_max)) * z_cf / total_frames; - z_size[i] = z_length[i] * (total_frames - z_cf) / total_frames; + z_pos[i] = std::max(z_min, std::min((int)zoom_position[i], z_max)) * z_cf / tf_off; + z_size[i] = z_length[i] * (tf_off - z_cf) / tf_off; - z_frame = (zoom_position[i] < z_min) ? (total_frames * zoom_position[i] / z_min - total_frames) : - (zoom_position[i] > z_max) ? (total_frames * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0; + z_frame = (zoom_position[i] < z_min) ? (tf_off * zoom_position[i] / z_min - tf_off) : + (zoom_position[i] > z_max) ? (tf_off * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0; if (z_frame != 0 && z_cf > 0) { z_fixed_pos = z_pos[i] * std::abs(z_frame) / z_cf; - z_fixed_size = z_length[i] * (total_frames - std::abs(z_frame)) / total_frames; + z_fixed_size = z_length[i] * (tf_off - std::abs(z_frame)) / tf_off; z_pos[i] += z_cf < std::abs(z_frame) ? (z_frame > 0 ? 1 : 0) * (z_length[i] - z_size[i]) - z_pos[i] : (z_frame > 0 ? z_length[i] - z_fixed_pos - z_fixed_size : -z_fixed_pos); } @@ -365,20 +365,17 @@ void Transition::Draw(Bitmap& dst) { } case TransitionMosaicIn: case TransitionMosaicOut: { - // Goes from scale 2 to 41 (current_frame is 0 - 39) - // FIXME: current_frame starts at 1 (off-by-one error?) + // Goes from scale 1 to 41 (current_frame is 0 - 40) // If TransitionMosaicIn, invert scale and screen: int32_t rand; if (transition_type == TransitionMosaicIn) { - m_size = total_frames + 1 - current_frame; + m_size = total_frames - current_frame; screen_pointer1 = screen2; rand = mosaic_random_offset[total_frames - current_frame - 1]; } else { - // remove when off-by-one error is fixed - const int off_one_fix = -1; - m_size = current_frame + 2 + off_one_fix; + m_size = current_frame + 1; screen_pointer1 = screen1; - rand = mosaic_random_offset[current_frame + off_one_fix]; + rand = mosaic_random_offset[current_frame]; } // The offset defines where at (X,Y) the pixel is picked for scaling (nearest neighbour) @@ -404,10 +401,10 @@ void Transition::Draw(Bitmap& dst) { case TransitionWaveOut: { // If TransitionWaveIn, invert depth, phase and screen: - auto p = (transition_type == TransitionWaveIn) ? total_frames - current_frame : current_frame; + auto p = (transition_type == TransitionWaveIn) ? total_frames - current_frame : current_frame + 1; auto& screen = (transition_type == TransitionWaveIn) ? *screen2 : *screen1; auto depth = p; - auto phase = p * 5 * M_PI / total_frames + M_PI; + auto phase = p * 5 * M_PI / tf_off + M_PI; dst.FillRect(Rect(0, 0, w, h), Color(0, 0, 0, 255)); dst.WaverBlit(0, 0, 1, 1, screen, screen.GetRect(), depth, phase, Opacity::Opaque()); } From e827009e57006381979680d558d5652ceaed7177 Mon Sep 17 00:00:00 2001 From: Lt-knb <87249079+Lt-knb@users.noreply.github.com> Date: Sun, 2 Nov 2025 23:40:58 +0100 Subject: [PATCH 15/15] Make the compiler shut up --- src/transition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transition.cpp b/src/transition.cpp index 8947222bc7..2af6f93f45 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -211,7 +211,7 @@ void Transition::Draw(Bitmap& dst) { case TransitionFadeIn: case TransitionFadeOut: dst.Blit(0, 0, *screen1, screen1->GetRect(), 255); - dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * (current_frame + 1) / (total_frames - 2); + dst.Blit(0, 0, *screen2, screen2->GetRect(), 255 * (current_frame + 1) / (total_frames - 2)); break; case TransitionRandomBlocks: case TransitionRandomBlocksDown: