Monorepo for Aesthetic.Computer aesthetic.computer
at main 174 lines 5.8 kB view raw
1#include <gb/gb.h> 2#include <stdio.h> 3#include <gbdk/console.h> 4#include <string.h> 5 6// Sine table: 256 entries, values from -64 to +64 7const int8_t sine_table[256] = { 8 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 9 48, 51, 54, 57, 59, 62, 65, 67, 70, 73, 75, 78, 80, 82, 85, 87, 10 89, 91, 94, 96, 98, 100, 102, 103, 105, 107, 108, 110, 112, 113, 114, 116, 11 117, 118, 119, 120, 121, 122, 123, 124, 124, 125, 126, 126, 127, 127, 127, 127, 12 127, 127, 127, 127, 127, 126, 126, 125, 124, 124, 123, 122, 121, 120, 119, 118, 13 117, 116, 114, 113, 112, 110, 108, 107, 105, 103, 102, 100, 98, 96, 94, 91, 14 89, 87, 85, 82, 80, 78, 75, 73, 70, 67, 65, 62, 59, 57, 54, 51, 15 48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 16 0, -3, -6, -9, -12, -15, -18, -21, -24, -27, -30, -33, -36, -39, -42, -45, 17 -48, -51, -54, -57, -59, -62, -65, -67, -70, -73, -75, -78, -80, -82, -85, -87, 18 -89, -91, -94, -96, -98, -100, -102, -103, -105, -107, -108, -110, -112, -113, -114, -116, 19 -117, -118, -119, -120, -121, -122, -123, -124, -124, -125, -126, -126, -127, -127, -127, -127, 20 -127, -127, -127, -127, -127, -126, -126, -125, -124, -124, -123, -122, -121, -120, -119, -118, 21 -117, -116, -114, -113, -112, -110, -108, -107, -105, -103, -102, -100, -98, -96, -94, -91, 22 -89, -87, -85, -82, -80, -78, -75, -73, -70, -67, -65, -62, -59, -57, -54, -51, 23 -48, -45, -42, -39, -36, -33, -30, -27, -24, -21, -18, -15, -12, -9, -6, -3 24}; 25 26int8_t sin_lookup(uint8_t angle) { 27 return sine_table[angle]; 28} 29 30int8_t cos_lookup(uint8_t angle) { 31 return sine_table[(angle + 64) & 0xFF]; 32} 33 34// Buffer for tile data manipulation 35uint8_t tile_buffer[16]; 36uint8_t next_tile_id = 128; // Start at 128 to avoid printf's font tiles (0-127) 37 38// Plot a pixel in the background by modifying tile data 39void plot_pixel(uint8_t x, uint8_t y) { 40 uint8_t tile_x, tile_y; 41 uint8_t pixel_x, pixel_y; 42 uint8_t tile_num; 43 uint8_t row_offset; 44 uint8_t bit_mask; 45 46 // Convert screen coordinates to tile coordinates 47 tile_x = x / 8; 48 tile_y = y / 8; 49 50 // Get pixel position within the tile (0-7) 51 pixel_x = x % 8; 52 pixel_y = y % 8; 53 54 // Get the tile number from the background map 55 get_bkg_tiles(tile_x, tile_y, 1, 1, &tile_num); 56 57 // If tile is 0 (empty), allocate a new tile 58 if(tile_num == 0) { 59 // Make sure we don't run out of tiles (max 256) 60 if(next_tile_id >= 255) return; 61 62 tile_num = next_tile_id; 63 next_tile_id++; 64 set_bkg_tiles(tile_x, tile_y, 1, 1, &tile_num); 65 66 // Clear the tile buffer 67 memset(tile_buffer, 0, 16); 68 } else { 69 // Read existing tile data 70 get_bkg_data(tile_num, 1, tile_buffer); 71 } 72 73 // Set the pixel in the tile data 74 // Each row is 2 bytes (low bit plane, high bit plane) 75 row_offset = pixel_y * 2; 76 bit_mask = 0x80 >> pixel_x; // Bit 7 is leftmost pixel 77 78 // Set both bit planes to make pixel black (color 3) 79 tile_buffer[row_offset] |= bit_mask; // Low bit plane 80 tile_buffer[row_offset + 1] |= bit_mask; // High bit plane 81 82 // Write the modified tile back to VRAM 83 set_bkg_data(tile_num, 1, tile_buffer); 84} 85 86void main(void) { 87 uint16_t angle = 0; // Angle in degrees: 0-359 88 int16_t turtle_x_fixed = 80 << 8; 89 int16_t turtle_y_fixed = 72 << 8; 90 int16_t dx, dy; 91 uint16_t step = 0; 92 uint8_t delay_counter = 0; 93 uint8_t pixel_x, pixel_y; 94 int16_t radius_fixed = 25 << 8; // 25 pixel radius 95 96 // Display must be off to initialize 97 DISPLAY_OFF; 98 99 // Initialize background (all tiles start at 0 = blank) 100 uint8_t i, j; 101 uint8_t blank = 0; 102 for(i = 0; i < 18; i++) { 103 for(j = 0; j < 20; j++) { 104 set_bkg_tiles(j, i, 1, 1, &blank); 105 } 106 } 107 108 SHOW_BKG; 109 DISPLAY_ON; 110 111 // Print status in top-left (uses tiles 0-127 for font) 112 gotoxy(0, 0); 113 printf("TURTLE CIRCLE"); 114 115 // Move turtle to starting position (right side of circle at 0°) 116 turtle_x_fixed += radius_fixed; 117 118 while(1) { 119 wait_vbl_done(); 120 121 delay_counter++; 122 if(delay_counter >= 2) { 123 delay_counter = 0; 124 125 if(step < 360) { 126 // Use polar coordinates: calculate position directly from angle 127 // x = center_x + radius * cos(angle) 128 // y = center_y + radius * sin(angle) 129 130 // Convert angle (0-36000 hundredths) to lookup table (0-255) 131 angle_byte = (uint8_t)((angle_degrees * 256UL) / 36000UL); 132 133 // Get cos/sin from lookup table (values are -127 to +127) 134 int16_t cos_val = cos_lookup(angle_byte); 135 int16_t sin_val = sin_lookup(angle_byte); 136 137 // Calculate position: center + (radius * cos/sin) / 127 138 // radius_fixed is already in 8.8 format (25 << 8) 139 // cos/sin are scaled to 127, so multiply then divide by 127 140 int16_t x_offset = (radius_fixed * cos_val) / 127; 141 int16_t y_offset = (radius_fixed * sin_val) / 127; 142 143 // turtle positions start at center (80, 72) in 8.8 fixed point 144 int16_t x_pos = (80 << 8) + x_offset; 145 int16_t y_pos = (72 << 8) + y_offset; 146 147 // Convert to screen pixels 148 int16_t x_int = x_pos >> 8; 149 int16_t y_int = y_pos >> 8; 150 151 // Only plot if on screen 152 if(x_int >= 0 && x_int < 160 && y_int >= 0 && y_int < 144) { 153 pixel_x = (uint8_t)x_int; 154 pixel_y = (uint8_t)y_int; 155 plot_pixel(pixel_x, pixel_y); 156 } 157 158 // Turn: increment angle by 1 degree 159 angle_degrees += 100; 160 if(angle_degrees >= 36000) angle_degrees -= 36000; 161 162 step++; 163 164 // Update step counter and angle debug more frequently 165 if(step % 5 == 0) { 166 gotoxy(0, 1); 167 printf("S:%d A:%d.%02d ", step, angle_degrees/100, angle_degrees%100); 168 gotoxy(0, 2); 169 printf("X:%d Y:%d ", x_int, y_int); 170 } 171 } 172 } 173 } 174}