Commits

Trammell Hudson committed 5fc9fd0 Draft

Character rotation and scaling works

Comments (0)

Files changed (3)

 */
 };
 
+static vector_rot_t rot = {
+	.scale = 100,
+	.cx = 128,
+	.cy = 148,
+};
+
 
 static void
 draw_text(void)
 {
 	const uint8_t height = 24;
 
-	uint8_t y = 256-height;
+	int8_t y = 128 - 24;
 	for (uint8_t row = 0 ; row < MAX_ROWS ; row++)
 	{
-		uint8_t x = 0;
+		int8_t x = -128;
 		for (uint8_t col = 0 ; col < MAX_COLS ; col++)
 		{
-			x += draw_char_small(x, y, text[row][col]) + 3;
+			draw_char_rot(&rot, x, y, text[row][col]);
+			x += 20;
 		}
 
 		y -= height;
 	clock_init();
 
 	uint8_t col = 0;
+	uint16_t theta = 0;
+	uint8_t size = 0;
 
 	while (1)
 	{
-		draw_text();
+		vector_rot_init(&rot, (theta++) >> 1);
+		if (size >= 128)
+			rot.scale = (32+64) - (size - 128)/2;
+		else
+			rot.scale = 32 + size/2;
+
+		size = (size + 3);
+
+		draw_char_rot(&rot, -50, -10, 'A');
+		draw_char_rot(&rot, -30, -10, 'L');
+		draw_char_rot(&rot, -10, -10, 'E');
+		draw_char_rot(&rot, +20, -10, 'R');
+		draw_char_rot(&rot, +40, -10, 'T');
+		draw_char_rot(&rot, +60, -10, '!');
+
+		draw_char_med(30, 60, '#');
+		draw_char_med(50, 60, 'F');
+		draw_char_med(70, 60, 'u');
+		draw_char_med(90, 60, 't');
+		draw_char_med(110, 60, 'u');
+		draw_char_med(132, 60, 'r');
+		draw_char_med(152, 60, 'e');
+
+		draw_char_med(100, 30, 'C');
+		draw_char_med(120, 30, 'r');
+		draw_char_med(140, 30, 'e');
+		draw_char_med(160, 30, 'w');
+		draw_char_med(180, 30, '*');
+
+		line(0, 0, 254, 0);
+		line(254, 0, 254, 254);
+		line(254, 254, 0, 254);
+		line(0, 254, 0, 0);
+
+		//draw_text();
 		int c = usb_serial_getchar();
 		if (c == -1)
 			continue;
 #include "bits.h"
 #include "hershey.h"
 #include "asteroids-font.h"
+#include "vector.h"
 #include "sin_table.h"
 
 
 }
 
 
+
+void
+vector_rot_init(
+	vector_rot_t * r,
+	uint8_t theta
+)
+{
+	r->sin_t = sin_lookup(theta);
+	r->cos_t = cos_lookup(theta);
+}
+
+
+uint8_t
+vector_rot_x(
+	const vector_rot_t * r,
+	int8_t x,
+	int8_t y
+)
+{
+	int32_t x2 = x;
+	int32_t y2 = y;
+
+	int32_t w = (r->scale * (x2 * r->cos_t + y2 * r->sin_t)) / (32 * 256);
+	
+	return w + r->cx;
+}
+
+uint8_t
+vector_rot_y(
+	const vector_rot_t * r,
+	int8_t x,
+	int8_t y
+)
+{
+	int32_t x2 = x;
+	int32_t y2 = y;
+	int32_t z = (r->scale * (y2 * r->cos_t - x2 * r->sin_t)) / (32 * 256);
+	return z + r->cy;
+}
+	
+
 static inline int8_t
 scaling(
 	int8_t d,
 }
 
 
+
 static inline uint8_t
 _draw_char(
 	const uint8_t x,
 {
 	return _draw_char(x, y, c, 0);
 }
+
+
+void
+draw_char_rot(
+	const vector_rot_t * const r,
+	const int8_t x,
+	const int8_t y,
+	char c
+)
+{
+	// we never use the original points since the lines always
+	// start pen-up
+	uint8_t ox = 0; // vector_rot_x(r, x, y);
+	uint8_t oy = 0; // vector_rot_y(r, x, y);
+	uint8_t pen_down = 0;
+
+	if (c < 0x20)
+		return;
+
+	if ('a' <= c && c <= 'z')
+		c += 'A' - 'a';
+
+	const asteroids_char_t * const p = &asteroids_font[c - 0x20];
+	for (uint8_t i = 0 ; i < 8 ; i++)
+	{
+		const uint8_t xy = pgm_read_byte(&p->points[i]);
+		if (xy == 0xFF)
+			break;
+		if (xy == 0xFE)
+		{
+			pen_down = 0;
+			continue;
+		}
+
+		const int8_t px = ((xy >> 4) & 0xF) * 2;
+		const int8_t py = ((xy >> 0) & 0xF) * 2;
+
+		const int8_t nx = x + px;
+		const int8_t ny = y + py;
+		const uint8_t rx = vector_rot_x(r, nx, ny);
+		const uint8_t ry = vector_rot_y(r, nx, ny);
+
+		if (pen_down)
+			line(ox, oy, rx, ry);
+
+		pen_down = 1;
+		ox = rx;
+		oy = ry;
+	}
+}
+
 #include <stdint.h>
 
 
-static inline void
-vector_x(
-	uint8_t x
-)
-{
-	PORTB = x;
-}
-
-static  inline void
-vector_y(
-	uint8_t y
-)
-{
-	PORTD = y;
-}
-
-
-static inline void
-vector_init(void)
-{
-	DDRD = 0xFF;
-	DDRB = 0xFF;
-	vector_x(128);
-	vector_y(128);
-}
-
-
 void
 line_vert(
 	uint8_t x0,
 );
 
 
+typedef struct
+{
+	// center of rotation
+	uint8_t cx;
+	uint8_t cy;
+
+	// scale of vector, divided by 16
+	int8_t scale;
+
+	// precomputed sin/cos
+	int8_t sin_t;
+	int8_t cos_t;
+} vector_rot_t;
+
+
+void
+vector_rot_init(
+	vector_rot_t * r,
+	uint8_t angle
+);
+
+
+uint8_t
+vector_rot_x(
+	const vector_rot_t * r,
+	int8_t x,
+	int8_t y
+);
+
+
+uint8_t
+vector_rot_y(
+	const vector_rot_t * r,
+	int8_t x,
+	int8_t y
+);
+
+
 uint8_t
 draw_char_big(
 	uint8_t x,
 );
 
 
+void
+draw_char_rot(
+	const vector_rot_t * const r,
+	int8_t x,
+	int8_t y,
+	char val
+);
+
 #endif