1use fltk::{app, frame, prelude::*, utils, window::Window};
2
3const WIDTH: i32 = 600;
4const HEIGHT: i32 = 400;
5const CIRCLE_RADIUS: i16 = 64;
6
7struct World {
8 circle_x: i16,
9 circle_y: i16,
10 velocity_x: i16,
11 velocity_y: i16,
12}
13
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 let app = app::App::default();
16 let mut win = Window::default()
17 .with_size(WIDTH, HEIGHT)
18 .with_label("Framebuffer");
19 let mut frame = frame::Frame::default_fill();
20 win.end();
21 win.make_resizable(true);
22 win.show();
23
24 let mut framebuf: Vec<u8> = vec![0; (WIDTH * HEIGHT * 4) as usize];
25 let mut world = World::new();
26
27 unsafe {
28 utils::blit_rgba_nocopy(&mut frame, &framebuf);
29 }
30
31 app::add_idle(move |_| {
32 world.update();
33 world.draw(&mut framebuf);
34 win.redraw();
36 app::sleep(0.016);
38 });
39
40 app.run()?;
41 Ok(())
42}
43
44impl World {
45 fn new() -> Self {
46 Self {
47 circle_x: 300,
48 circle_y: 200,
49 velocity_x: 5,
50 velocity_y: 5,
51 }
52 }
53
54 fn update(&mut self) {
55 if self.circle_x - CIRCLE_RADIUS <= 0 || self.circle_x + CIRCLE_RADIUS > WIDTH as i16 {
56 self.velocity_x *= -1;
57 }
58 if self.circle_y - CIRCLE_RADIUS <= 0 || self.circle_y + CIRCLE_RADIUS > HEIGHT as i16 {
59 self.velocity_y *= -1;
60 }
61
62 self.circle_x += self.velocity_x;
63 self.circle_y += self.velocity_y;
64 }
65
66 fn draw(&self, frame: &mut [u8]) {
67 for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
68 let x = (i % WIDTH as usize) as i16;
69 let y = (i / WIDTH as usize) as i16;
70 let d = {
71 let xd = x as i32 - self.circle_x as i32;
72 let yd = y as i32 - self.circle_y as i32;
73 ((xd.pow(2) + yd.pow(2)) as f64).sqrt().powi(2)
74 };
75 let inside_the_circle = d < (CIRCLE_RADIUS as f64).powi(2);
76
77 let rgba = if inside_the_circle {
78 [0xac, 0x00, 0xe6, 0xff]
79 } else {
80 [0x26, 0x00, 0x33, 0xff]
81 };
82
83 pixel.copy_from_slice(&rgba);
84 }
85 }
86}