Commits

Trammell Hudson committed 1ac9015

Second animation looks better; use animation framework

Comments (0)

Files changed (1)

fireworks/fireworks.c

 
 
 typedef struct {
-	uint8_t value;
+	uint32_t ms;
+	color24_t color;
 	int32_t scale;
 	int32_t x;
 	int32_t y;
+} frame_t;
+
+typedef struct {
+	uint8_t value;
+	uint8_t first;
+	frame_t start;
+	frame_t end;
+	frame_t last;
 } digit_t;
 
 static digit_t last_sec, last_min, last_hour;
+static digit_t cur_sec, cur_min, cur_hour;
 
 void
 init(void)
 
 // Draw a zooming upwards digit
 static void
-draw_time(
-	digit_t * last,
-	uint8_t value,
+animate(
+	digit_t * d,
 	uint32_t ms
 )
 {
-	int32_t scale = (ms * (10 << VSCREEN_SHIFT)) / 1000;
-	int32_t y = (ms * VSCREEN_HEIGHT) / 1000 - scale * 2;
-	int32_t x = (ms * (20 << VSCREEN_SHIFT)) / 1000;
-	const char * s = digit_strings[value];
+	int32_t mult = ms - d->start.ms;
+	int32_t den = d->end.ms - d->start.ms;
+	if (mult < 0)
+		mult = 0;
+	if (mult > den)
+		mult = den;
+
+	int32_t scale = ((d->end.scale - d->start.scale) * mult) / den + d->start.scale;
+	int32_t x = ((d->end.x - d->start.x) * mult) / den + d->start.x;
+	int32_t y = ((d->end.y - d->start.y) * mult) / den + d->start.y;
+
+	const char * s = digit_strings[d->value];
 	color24_t color = {
-		(256 * ms) / 1000,
-		(256 * ms) / 1000,
-		(256 * ms) / 1000
+		((d->end.color.red - d->start.color.red) * mult) / den + d->start.color.red,
+		((d->end.color.green - d->start.color.green) * mult) / den + d->start.color.green,
+		((d->end.color.blue - d->start.color.blue) * mult) / den + d->start.color.blue,
 	};
 
-	if (last->value != -1)
+	if (!d->first)
 	{
 		// Erase the previous drawing
 		draw_digit_string(
 			COLOR_BLACK,
 			-16384,
-			last->scale,
-			digit_strings[last->value],
-			last->y,
-			last->x
+			d->last.scale,
+			digit_strings[d->value],
+			d->last.y,
+			d->last.x
 		);
 	}
 
-	last->value = value;
-	last->x = x;
-	last->y = y;
-	last->scale = scale;
-
+	d->first = 0;
+	d->last.x = x;
+	d->last.y = y;
+	d->last.scale = scale;
+	d->last.color = color;
 
 	draw_digit_string(
 		color,
 	const uint8_t min = cur_ms % 60; cur_ms /= 60;
 	const uint8_t hour = cur_ms %= 24;
 
-	draw_time(&last_sec, sec, ms);
+	if (cur_sec.value != sec)
+	{
+		//  new second time!
+		last_sec.value = cur_sec.value;
+		last_sec.first = 1;
+		last_sec.start.ms = ms;
+		last_sec.end.ms = ms + 800;
+		last_sec.start.color = cur_sec.last.color;
+		last_sec.end.color = COLOR_BLACK;
+		last_sec.start.scale = cur_sec.last.scale;
+		last_sec.end.scale = 50 << VSCREEN_SHIFT;
+		last_sec.start.x = cur_sec.last.x;
+		last_sec.start.y = cur_sec.last.y;
+		last_sec.end.x = cur_sec.end.x - (50 << VSCREEN_SHIFT);
+		last_sec.end.y = cur_sec.end.y - (50 << VSCREEN_SHIFT);
 
+		cur_sec.value = sec;
+		cur_sec.first = 1;
+		cur_sec.start.scale = 0;
+		cur_sec.start.x = 0;
+		cur_sec.start.y = 0;
+		cur_sec.start.color = COLOR_BLACK;
+		cur_sec.end.color = COLOR_WHITE;
+
+		cur_sec.start.ms = ms;
+		cur_sec.end.ms = ms + 900;
+
+		cur_sec.end.scale = (10 << VSCREEN_SHIFT);
+		cur_sec.end.y = VSCREEN_HEIGHT - (20 << VSCREEN_SHIFT);
+		cur_sec.end.x = 20 << VSCREEN_SHIFT;
+	}
+	
+	animate(&last_sec, ms);
+	animate(&cur_sec, ms);
+
+	if (cur_min.value != min)
+	{
+		// new minute time!
+		last_min.value = cur_min.value;
+		last_min.first = 1;
+		last_min.start.ms = ms;
+		last_min.end.ms = ms + 800;
+		last_min.start.color = cur_min.last.color;
+		last_min.end.color = COLOR_BLACK;
+		last_min.start.scale = cur_min.last.scale;
+		last_min.end.scale = 50 << VSCREEN_SHIFT;
+		last_min.start.x = cur_min.last.x;
+		last_min.start.y = cur_min.last.y;
+		last_min.end.x = cur_min.end.x - (50 << VSCREEN_SHIFT);
+		last_min.end.y = cur_min.end.y - (50 << VSCREEN_SHIFT);
+
+		cur_min.value = min;
+		cur_min.first = 1;
+		cur_min.start.scale = 0;
+		cur_min.start.x = 0;
+		cur_min.start.y = 0;
+		cur_min.start.color = COLOR_BLACK;
+		cur_min.end.color = COLOR_WHITE;
+
+		cur_min.start.ms = ms;
+		cur_min.end.ms = ms + 900;
+
+		cur_min.end.scale = (10 << VSCREEN_SHIFT);
+		cur_min.end.y = VSCREEN_HEIGHT - (20 << VSCREEN_SHIFT);
+		cur_min.end.x = -10 << VSCREEN_SHIFT;
+	}
+
+	animate(&last_min, ms);
+	animate(&cur_min, ms);
 
 /*
 	draw_digit_string(