@@ -42,13 +42,14 @@ int Transition::GetDefaultFrames(Transition::Type type)
4242 switch (type) {
4343 case TransitionFadeIn:
4444 case TransitionFadeOut:
45- return 32 ;
45+ return 35 ;
4646 case TransitionCutIn:
4747 case TransitionCutOut:
48+ return 1 ;
4849 case TransitionNone:
4950 return 0 ;
5051 default :
51- return 40 ;
52+ return 41 ;
5253 }
5354 return 0 ;
5455}
@@ -80,7 +81,8 @@ void Transition::Init(Type type, Scene *linked_scene, int duration, bool next_er
8081 transition_type = type;
8182 scene = linked_scene;
8283
83- current_frame = 0 ;
84+ // Don't skip Frame 0 (Update is called before Draw).
85+ current_frame = -1 ;
8486 flash = {};
8587 flash_power = 0 ;
8688 flash_iterations = 0 ;
@@ -173,10 +175,8 @@ void Transition::SetAttributesTransitions() {
173175 case TransitionMosaicIn:
174176 case TransitionMosaicOut:
175177 for (int i = 0 ; i < total_frames; ++i) {
176- const int initial_scale = 2 ;
177- const int excl_interval = -1 ;
178- // by default i 0..39 for scale 2..41
179- mosaic_random_offset[i] = Rand::GetRandomNumber (0 , i + initial_scale - excl_interval);
178+ // by default i 0..40 for scale 1..41
179+ mosaic_random_offset[i] = Rand::GetRandomNumber (0 , i);
180180 }
181181 break ;
182182 default :
@@ -190,7 +190,7 @@ void Transition::Draw(Bitmap& dst) {
190190 return ;
191191
192192 std::vector<int > z_pos (2 ), z_size (2 ), z_length (2 );
193- int z_min, z_max, z_percent , z_fixed_pos, z_fixed_size;
193+ int z_min, z_max, z_frame , z_fixed_pos, z_fixed_size;
194194 uint8_t m_r, m_g, m_b, m_a;
195195 uint32_t *m_pointer, blocks_to_print;
196196 int m_size;
@@ -204,19 +204,19 @@ void Transition::Draw(Bitmap& dst) {
204204 dst.BlendBlit (0 , 0 , *screen1, screen1->GetRect (), color, 255 );
205205 return ;
206206 }
207-
208- int percentage = (current_frame) * 100 / (total_frames) ;
207+
208+ int tf_off = total_frames - 1 ;
209209
210210 switch (transition_type) {
211211 case TransitionFadeIn:
212212 case TransitionFadeOut:
213213 dst.Blit (0 , 0 , *screen1, screen1->GetRect (), 255 );
214- dst.Blit (0 , 0 , *screen2, screen2->GetRect (), 255 * percentage / 100 );
214+ dst.Blit (0 , 0 , *screen2, screen2->GetRect (), 255 * (current_frame + 1 ) / (total_frames - 2 ) );
215215 break ;
216216 case TransitionRandomBlocks:
217217 case TransitionRandomBlocksDown:
218218 case TransitionRandomBlocksUp:
219- blocks_to_print = random_blocks.size () * percentage / 100 ;
219+ blocks_to_print = random_blocks.size () * (current_frame + 1 ) / tf_off ;
220220
221221 for (uint32_t i = current_blocks_print; i < blocks_to_print; i++) {
222222 random_block_transition->Blit (random_blocks[i] % (w / size_random_blocks) * size_random_blocks,
@@ -230,151 +230,152 @@ void Transition::Draw(Bitmap& dst) {
230230 break ;
231231 case TransitionBlindOpen:
232232 for (int i = 0 ; i < h / 8 ; i++) {
233- dst.Blit (0 , i * 8 , *screen1, Rect (0 , i * 8 , w, 8 - 8 * percentage / 100 ), 255 );
234- dst.Blit (0 , i * 8 + 8 - 8 * percentage / 100 , *screen2, Rect (0 , i * 8 + 8 - 8 * percentage / 100 , w, 8 * percentage / 100 ), 255 );
233+ dst.Blit (0 , i * 8 , *screen1, Rect (0 , i * 8 , w, 8 - (current_frame + 5 ) / 5 ), 255 );
234+ 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 );
235235 }
236236 break ;
237237 case TransitionBlindClose:
238238 for (int i = 0 ; i < h / 8 ; i++) {
239- dst.Blit (0 , i * 8 + 8 * percentage / 100 , *screen1, Rect (0 , i * 8 + 8 * percentage / 100 , w, 8 - 8 * percentage / 100 ), 255 );
240- dst.Blit (0 , i * 8 , *screen2, Rect (0 , i * 8 , w, 8 * percentage / 100 ), 255 );
239+ 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 );
240+ dst.Blit (0 , i * 8 , *screen2, Rect (0 , i * 8 , w, (current_frame + 5 ) / 5 ), 255 );
241241 }
242242 break ;
243243 case TransitionVerticalStripesIn:
244244 case TransitionVerticalStripesOut:
245- for (int i = 0 ; i < h / 6 + 1 - h / 6 * percentage / 100 ; i++) {
245+ for (int i = 0 ; i < tf_off - (current_frame + 1 ) ; i++) {
246246 dst.Blit (0 , i * 6 + 3 , *screen1, Rect (0 , i * 6 + 3 , w, 3 ), 255 );
247247 dst.Blit (0 , h - i * 6 , *screen1, Rect (0 , h - i * 6 , w, 3 ), 255 );
248248 }
249- for (int i = 0 ; i < h / 6 * percentage / 100 ; i++) {
249+ for (int i = 0 ; i < current_frame + 1 ; i++) {
250250 dst.Blit (0 , i * 6 , *screen2, Rect (0 , i * 6 , w, 3 ), 255 );
251251 dst.Blit (0 , h - 3 - i * 6 , *screen2, Rect (0 , h - 3 - i * 6 , w, 3 ), 255 );
252252 }
253253 break ;
254254 case TransitionHorizontalStripesIn:
255255 case TransitionHorizontalStripesOut:
256- for (int i = 0 ; i < w / 8 + 1 - w / 8 * percentage / 100 ; i++) {
256+ for (int i = 0 ; i < tf_off - (current_frame + 1 ) ; i++) {
257257 dst.Blit (i * 8 + 4 , 0 , *screen1, Rect (i * 8 + 4 , 0 , 4 , h), 255 );
258258 dst.Blit (w - i * 8 , 0 , *screen1, Rect (w - i * 8 , 0 , 4 , h), 255 );
259259 }
260- for (int i = 0 ; i < w / 8 * percentage / 100 ; i++) {
260+ for (int i = 0 ; i < current_frame + 1 ; i++) {
261261 dst.Blit (i * 8 , 0 , *screen2, Rect (i * 8 , 0 , 4 , h), 255 );
262262 dst.Blit (w - 4 - i * 8 , 0 , *screen2, Rect (w - 4 - i * 8 , 0 , 4 , h), 255 );
263263 }
264264 break ;
265265 case TransitionBorderToCenterIn:
266266 case TransitionBorderToCenterOut:
267267 dst.Blit (0 , 0 , *screen2, screen2->GetRect (), 255 );
268- 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 );
268+ 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 );
269269 break ;
270270 case TransitionCenterToBorderIn:
271271 case TransitionCenterToBorderOut:
272272 dst.Blit (0 , 0 , *screen1, screen1->GetRect (), 255 );
273- 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 );
273+ 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 );
274274 break ;
275275 case TransitionScrollUpIn:
276276 case TransitionScrollUpOut:
277- dst.Blit (0 , -h * percentage / 100 , *screen1, screen1->GetRect (), 255 );
278- dst.Blit (0 , h - h * percentage / 100 , *screen2, screen2->GetRect (), 255 );
277+ dst.Blit (0 , -h * current_frame / tf_off , *screen1, screen1->GetRect (), 255 );
278+ dst.Blit (0 , h - h * current_frame / tf_off , *screen2, screen2->GetRect (), 255 );
279279 break ;
280280 case TransitionScrollDownIn:
281281 case TransitionScrollDownOut:
282- dst.Blit (0 , h * percentage / 100 , *screen1, screen1->GetRect (), 255 );
283- dst.Blit (0 , -h + h * percentage / 100 , *screen2, screen2->GetRect (), 255 );
282+ dst.Blit (0 , h * current_frame / tf_off , *screen1, screen1->GetRect (), 255 );
283+ dst.Blit (0 , -h + h * current_frame / tf_off , *screen2, screen2->GetRect (), 255 );
284284 break ;
285285 case TransitionScrollLeftIn:
286286 case TransitionScrollLeftOut:
287- dst.Blit (-w * percentage / 100 , 0 , *screen1, screen1->GetRect (), 255 );
288- dst.Blit (w - w * percentage / 100 , 0 , *screen2, screen2->GetRect (), 255 );
287+ dst.Blit (-w * current_frame / tf_off , 0 , *screen1, screen1->GetRect (), 255 );
288+ dst.Blit (w - w * current_frame / tf_off , 0 , *screen2, screen2->GetRect (), 255 );
289289 break ;
290290 case TransitionScrollRightIn:
291291 case TransitionScrollRightOut:
292- dst.Blit (w * percentage / 100 , 0 , *screen1, screen1->GetRect (), 255 );
293- dst.Blit (-w + w * percentage / 100 , 0 , *screen2, screen2->GetRect (), 255 );
292+ dst.Blit (w * current_frame / tf_off , 0 , *screen1, screen1->GetRect (), 255 );
293+ dst.Blit (-w + w * current_frame / tf_off , 0 , *screen2, screen2->GetRect (), 255 );
294294 break ;
295295 case TransitionVerticalCombine:
296- case TransitionVerticalDivision:
297- // If TransitionVerticalCombine, invert percentage and screen:
298- if ( transition_type == TransitionVerticalCombine) { percentage = 100 - percentage; }
296+ case TransitionVerticalDivision: {
297+ // If TransitionVerticalCombine, invert current_frame and screen:
298+ int ver_cf = transition_type == TransitionVerticalCombine ? tf_off - current_frame : current_frame;
299299 screen_pointer1 = transition_type == TransitionVerticalCombine ? screen2 : screen1;
300300 screen_pointer2 = transition_type == TransitionVerticalCombine ? screen1 : screen2;
301301
302- dst.Blit (0 , -(h / 2 ) * percentage / 100 , *screen_pointer1, Rect (0 , 0 , w, h / 2 ), 255 );
303- dst.Blit (0 , h / 2 + (h / 2 ) * percentage / 100 , *screen_pointer1, Rect (0 , h / 2 , w, h / 2 ), 255 );
304- dst.Blit (0 , h / 2 - (h / 2 ) * percentage / 100 , *screen_pointer2, Rect (0 , h / 2 - (h / 2 ) * percentage / 100 , w, h * percentage / 100 ), 255 );
302+ dst.Blit (0 , -(h / 2 ) * ver_cf / tf_off , *screen_pointer1, Rect (0 , 0 , w, h / 2 ), 255 );
303+ dst.Blit (0 , h / 2 + (h / 2 ) * ver_cf / tf_off , *screen_pointer1, Rect (0 , h / 2 , w, h / 2 ), 255 );
304+ 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 );
305305 break ;
306+ }
306307 case TransitionHorizontalCombine:
307- case TransitionHorizontalDivision:
308- // If TransitionHorizontalCombine, invert percentage and screen:
309- if ( transition_type == TransitionHorizontalCombine) { percentage = 100 - percentage; }
308+ case TransitionHorizontalDivision: {
309+ // If TransitionHorizontalCombine, invert current_frame and screen:
310+ int hor_cf = transition_type == TransitionHorizontalCombine ? tf_off - current_frame : current_frame;
310311 screen_pointer1 = transition_type == TransitionHorizontalCombine ? screen2 : screen1;
311312 screen_pointer2 = transition_type == TransitionHorizontalCombine ? screen1 : screen2;
312313
313- dst.Blit (-(w / 2 ) * percentage / 100 , 0 , *screen_pointer1, Rect (0 , 0 , w / 2 , h), 255 );
314- dst.Blit (w / 2 + (w / 2 ) * percentage / 100 , 0 , *screen_pointer1, Rect (w / 2 , 0 , w / 2 , h), 255 );
315- dst.Blit (w / 2 - (w / 2 ) * percentage / 100 , 0 , *screen_pointer2, Rect (w / 2 - (w / 2 ) * percentage / 100 , 0 , w * percentage / 100 , h), 255 );
314+ dst.Blit (-(w / 2 ) * hor_cf / tf_off , 0 , *screen_pointer1, Rect (0 , 0 , w / 2 , h), 255 );
315+ dst.Blit (w / 2 + (w / 2 ) * hor_cf / tf_off , 0 , *screen_pointer1, Rect (w / 2 , 0 , w / 2 , h), 255 );
316+ 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 );
316317 break ;
318+ }
317319 case TransitionCrossCombine:
318- case TransitionCrossDivision:
319- // If TransitionCrossCombine, invert percentage and screen:
320- if ( transition_type == TransitionCrossCombine) { percentage = 100 - percentage; }
320+ case TransitionCrossDivision: {
321+ // If TransitionCrossCombine, invert current_frame and screen:
322+ int cross_cf = transition_type == TransitionCrossCombine ? tf_off - current_frame : current_frame;
321323 screen_pointer1 = transition_type == TransitionCrossCombine ? screen2 : screen1;
322324 screen_pointer2 = transition_type == TransitionCrossCombine ? screen1 : screen2;
323325
324- dst.Blit (-(w / 2 ) * percentage / 100 , -(h / 2 ) * percentage / 100 , *screen_pointer1, Rect (0 , 0 , w / 2 , h / 2 ), 255 );
325- dst.Blit (w / 2 + (w / 2 ) * percentage / 100 , -(h / 2 ) * percentage / 100 , *screen_pointer1, Rect (w / 2 , 0 , w / 2 , h / 2 ), 255 );
326- 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 );
327- dst.Blit (-(w / 2 ) * percentage / 100 , h / 2 + (h / 2 ) * percentage / 100 , *screen_pointer1, Rect (0 , h / 2 , w / 2 , h / 2 ), 255 );
328- 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 );
329- 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 );
330- dst.Blit (0 , h / 2 - (h / 2 ) * percentage / 100 , *screen_pointer2, Rect (0 , h / 2 - (h / 2 ) * percentage / 100 , w, h * percentage / 100 ), 255 );
326+ dst.Blit (-(w / 2 ) * cross_cf / tf_off , -(h / 2 ) * cross_cf / tf_off , *screen_pointer1, Rect (0 , 0 , w / 2 , h / 2 ), 255 );
327+ 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 );
328+ 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 );
329+ 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 );
330+ 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 );
331+ 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 );
332+ 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 );
331333 break ;
334+ }
332335 case TransitionZoomIn:
333- case TransitionZoomOut:
334- // If TransitionZoomOut, invert percentage and screen:
335- if ( transition_type == TransitionZoomOut) { percentage = 100 - percentage; }
336+ case TransitionZoomOut: {
337+ // If TransitionZoomOut, invert current_frame and screen:
338+ int z_cf = transition_type == TransitionZoomOut ? tf_off - current_frame : current_frame;
336339 screen_pointer1 = transition_type == TransitionZoomOut ? screen2 : screen1;
337340
338341 // X Coordinate: [0] Y Coordinate: [1]
339342 z_length[0 ] = w;
340343 z_length[1 ] = h;
341- percentage = percentage <= 97 ? percentage : 97 ;
344+ z_cf = z_cf <= total_frames - 2 ? z_cf : total_frames - 2 ;
342345
343346 for (int i = 0 ; i < 2 ; i++) {
344347 z_min = z_length[i] / 4 ;
345348 z_max = z_length[i] * 3 / 4 ;
346- z_pos[i] = std::max (z_min, std::min ((int )zoom_position[i], z_max)) * percentage / 100 ;
347- z_size[i] = z_length[i] * (100 - percentage ) / 100 ;
349+ z_pos[i] = std::max (z_min, std::min ((int )zoom_position[i], z_max)) * z_cf / tf_off ;
350+ z_size[i] = z_length[i] * (tf_off - z_cf ) / tf_off ;
348351
349- z_percent = (zoom_position[i] < z_min) ? (100 * zoom_position[i] / z_min - 100 ) :
350- (zoom_position[i] > z_max) ? (100 * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0 ;
352+ z_frame = (zoom_position[i] < z_min) ? (tf_off * zoom_position[i] / z_min - tf_off ) :
353+ (zoom_position[i] > z_max) ? (tf_off * (zoom_position[i] - z_max) / (z_length[i] - z_max)) : 0 ;
351354
352- if (z_percent != 0 && percentage > 0 ) {
353- z_fixed_pos = z_pos[i] * std::abs (z_percent ) / percentage ;
354- z_fixed_size = z_length[i] * (100 - std::abs (z_percent )) / 100 ;
355- z_pos[i] += percentage < std::abs (z_percent ) ? (z_percent > 0 ? 1 : 0 ) * (z_length[i] - z_size[i]) - z_pos[i] :
356- (z_percent > 0 ? z_length[i] - z_fixed_pos - z_fixed_size : -z_fixed_pos);
355+ if (z_frame != 0 && z_cf > 0 ) {
356+ z_fixed_pos = z_pos[i] * std::abs (z_frame ) / z_cf ;
357+ z_fixed_size = z_length[i] * (tf_off - std::abs (z_frame )) / tf_off ;
358+ z_pos[i] += z_cf < std::abs (z_frame ) ? (z_frame > 0 ? 1 : 0 ) * (z_length[i] - z_size[i]) - z_pos[i] :
359+ (z_frame > 0 ? z_length[i] - z_fixed_pos - z_fixed_size : -z_fixed_pos);
357360 }
358361 }
359362
360363 dst.StretchBlit (Rect (0 , 0 , w, h), *screen_pointer1, Rect (z_pos[0 ], z_pos[1 ], z_size[0 ], z_size[1 ]), 255 );
361364 break ;
365+ }
362366 case TransitionMosaicIn:
363367 case TransitionMosaicOut: {
364- // Goes from scale 2 to 41 (current_frame is 0 - 39)
365- // FIXME: current_frame starts at 1 (off-by-one error?)
368+ // Goes from scale 1 to 41 (current_frame is 0 - 40)
366369 // If TransitionMosaicIn, invert scale and screen:
367370 int32_t rand;
368371 if (transition_type == TransitionMosaicIn) {
369- m_size = total_frames + 1 - current_frame;
372+ m_size = total_frames - current_frame;
370373 screen_pointer1 = screen2;
371374 rand = mosaic_random_offset[total_frames - current_frame - 1 ];
372375 } else {
373- // remove when off-by-one error is fixed
374- const int off_one_fix = -1 ;
375- m_size = current_frame + 2 + off_one_fix;
376+ m_size = current_frame + 1 ;
376377 screen_pointer1 = screen1;
377- rand = mosaic_random_offset[current_frame + off_one_fix ];
378+ rand = mosaic_random_offset[current_frame];
378379 }
379380
380381 // The offset defines where at (X,Y) the pixel is picked for scaling (nearest neighbour)
@@ -399,11 +400,12 @@ void Transition::Draw(Bitmap& dst) {
399400 case TransitionWaveIn:
400401 case TransitionWaveOut:
401402 {
402- // If TransitionWaveIn, invert percentage and screen:
403- auto p = (transition_type == TransitionWaveIn) ? 100 - percentage : percentage ;
403+ // If TransitionWaveIn, invert depth, phase and screen:
404+ auto p = (transition_type == TransitionWaveIn) ? total_frames - current_frame : current_frame + 1 ;
404405 auto & screen = (transition_type == TransitionWaveIn) ? *screen2 : *screen1;
405- auto depth = p * 40 / 100 ;
406- auto phase = p * 5 * M_PI / 100.0 + M_PI;
406+ auto depth = p;
407+ auto phase = p * 5 * M_PI / tf_off + M_PI;
408+ dst.FillRect (Rect (0 , 0 , w, h), Color (0 , 0 , 0 , 255 ));
407409 dst.WaverBlit (0 , 0 , 1 , 1 , screen, screen.GetRect (), depth, phase, Opacity::Opaque ());
408410 }
409411 break ;
0 commit comments