module main;
import std;
import libc;
Clock last_frame;
char* fb = null;
fn char* get_framebuffer() @export("get_framebuffer")
{
if (!fb) fb = (char*)libc::calloc(WIDTH * HEIGHT * 4, 1);
return fb;
}
Vec2 pos = { 400.0f, 300.0f };
Vec2 vel = { 220.0f, 180.0f };
const int WIDTH = 800;
const int HEIGHT = 600;
const int RADIUS = 50;
const float DT_CAP = 0.1f;
typedef Color = char[<4>];
struct Circle
{
Vec2 origin;
float radius;
}
fn bool Circle.contains(Circle self, Vec2 p) @inline => self.origin.distance_sq(p) <= self.radius * self.radius;
fn void update_and_render() @export("update_and_render")
{
if (!fb) return;
Clock now = clock::now();
float dt = (float)(now - last_frame).to_sec();
last_frame = now;
if (dt > DT_CAP) dt = DT_CAP;
pos += vel * dt;
Vec2 min_p = { (float)RADIUS, (float)RADIUS };
Vec2 max_p = { (float)WIDTH - RADIUS, (float)HEIGHT - RADIUS };
bool[<2>] hit = pos.comp_lt(min_p) | pos.comp_gt(max_p);
if (hit.x) vel.x = -vel.x;
if (hit.y) vel.y = -vel.y;
pos = pos.clamp(min_p, max_p);
fb[:WIDTH * HEIGHT * 4] = 0;
Circle dot = { .origin = pos, .radius = (float)RADIUS };
Color color = { 255, 0, 0, 255 };
int y_min = math::max(0, (int)pos.y - RADIUS);
int y_max = math::min(HEIGHT - 1, (int)pos.y + RADIUS);
int x_min = math::max(0, (int)pos.x - RADIUS);
int x_max = math::min(WIDTH - 1, (int)pos.x + RADIUS);
for (int py = y_min; py <= y_max; py++)
{
for (int px = x_min; px <= x_max; px++)
{
if (dot.contains({ (float)px, (float)py }))
{
fb[(py * WIDTH + px) * 4:4] = color[..];
}
}
}
}
fn void main()
{
io::printn("Initialized...");
}