Skip to content

Commit 0d0b20c

Browse files
committed
Added a mandelbrot set.
1 parent 3d5850c commit 0d0b20c

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub static OS_MENU: menu::Menu<Ctx> = menu::Menu {
2222
&screen::CLEAR_ITEM,
2323
&screen::BENCH_ITEM,
2424
&screen::FILL_ITEM,
25+
&screen::MANDEL_ITEM,
2526
&input::KBTEST_ITEM,
2627
],
2728
entry: None,

src/commands/screen.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use neotron_common_bios::video::{Attr, TextBackgroundColour, TextForegroundColour};
44

5-
use crate::{println, Ctx, API, VGA_CONSOLE};
5+
use crate::{print, println, Ctx, API, VGA_CONSOLE};
66

77
pub static CLEAR_ITEM: menu::Item<Ctx> = menu::Item {
88
item_type: menu::ItemType::Callback {
@@ -31,6 +31,15 @@ pub static BENCH_ITEM: menu::Item<Ctx> = menu::Item {
3131
help: Some("Time how long to put 1,000,000 characters on the screen, with scrolling."),
3232
};
3333

34+
pub static MANDEL_ITEM: menu::Item<Ctx> = menu::Item {
35+
item_type: menu::ItemType::Callback {
36+
function: mandel,
37+
parameters: &[],
38+
},
39+
command: "screen_mandel",
40+
help: Some("Calculate the Mandelbrot set"),
41+
};
42+
3443
/// Called when the "clear" command is executed.
3544
fn clear(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
3645
if let Some(ref mut console) = unsafe { &mut VGA_CONSOLE } {
@@ -99,3 +108,40 @@ fn bench(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx:
99108
);
100109
}
101110
}
111+
112+
/// Called when the "mandel" command is executed.
113+
fn mandel(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
114+
fn mandelbrot(cx: f64, cy: f64, max_loops: u32) -> u32 {
115+
let mut x = cx;
116+
let mut y = cy;
117+
for i in 1..max_loops {
118+
let x_squared = x * x;
119+
let y_squared = y * y;
120+
if x_squared + y_squared > 4.0 {
121+
return i;
122+
}
123+
let x1 = x_squared - y_squared + cx;
124+
let y1 = (2.0 * x * y) + cy;
125+
x = x1;
126+
y = y1;
127+
}
128+
0
129+
}
130+
131+
let api = API.get();
132+
let mode = (api.video_get_mode)();
133+
let (Some(width), Some(height)) = (mode.text_width(), mode.text_height()) else {
134+
println!("Unable to get screen size");
135+
return;
136+
};
137+
138+
let glyphs = b" .,'~!^:;[/<&?oxOX# ";
139+
for y_pos in 0..height - 2 {
140+
let y = (f64::from(y_pos) * 4.0 / f64::from(height)) - 2.0;
141+
for x_pos in 0..width {
142+
let x = (f64::from(x_pos) * 4.0 / f64::from(width)) - 2.0;
143+
let result = mandelbrot(x, y, 20);
144+
print!("{}", glyphs[result as usize] as char);
145+
}
146+
}
147+
}

0 commit comments

Comments
 (0)