#include "math.h" #define HEIGHT 600 #define WIDTH 800 #define SQ_SIZE 100 typedef struct { double x, y; } Vec2d; typedef struct { unsigned char r, g, b, a; } Color; Color gradient[SQ_SIZE*SQ_SIZE] = {0}; Color buffer[WIDTH*HEIGHT] = {0}; Vec2d pos = {0}; double time = 0; Color* get_buffer_ptr() { return buffer; } int get_buffer_len() { return WIDTH*HEIGHT; } void compute_gradient(Color* output_buffer, int width, int height) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { output_buffer[y*width+x] = (Color){ .r = (x * 255) / (width - 1), .g = (y * 255) / (height - 1), .b = 0, .a = 255 }; } } } void init() { compute_gradient(gradient, SQ_SIZE, SQ_SIZE); } void render_frame(double dt) { time += dt; double x = 0.5 + cos(2.0 * PI / 10.0 * time) * 0.5; double y = 0.5 + sin(2.0 * PI / 10.0 * time) * 0.5; pos.x = x * (WIDTH - SQ_SIZE); pos.y = y * (HEIGHT - SQ_SIZE); // Clear the framebuffer before drawing the next frame. __builtin_memset(buffer, 0, sizeof(buffer)); // Clamp coordinates before indexing the framebuffer to avoid a bad // coordinate from turning into an out-of-bounds write. int pos_x = (int)pos.x; int pos_y = (int)pos.y; if (pos_x < 0) pos_x = 0; if (pos_y < 0) pos_y = 0; if (pos_x > WIDTH - SQ_SIZE) pos_x = WIDTH - SQ_SIZE; if (pos_y > HEIGHT - SQ_SIZE) pos_y = HEIGHT - SQ_SIZE; for (int y = pos_y; y < pos_y + SQ_SIZE; ++y) { for (int x = pos_x; x < pos_x + SQ_SIZE; ++x) { // Sample point from gradient int local_x = x - pos_x; int local_y = y - pos_y; Color c = gradient[local_y * SQ_SIZE + local_x]; buffer[y * WIDTH + x] = c; } } }