|
2 | 2 |
|
3 | 3 | use neotron_common_bios::video::{Attr, TextBackgroundColour, TextForegroundColour}; |
4 | 4 |
|
5 | | -use crate::{println, Ctx, API, VGA_CONSOLE}; |
| 5 | +use crate::{print, println, Ctx, API, VGA_CONSOLE}; |
6 | 6 |
|
7 | 7 | pub static CLEAR_ITEM: menu::Item<Ctx> = menu::Item { |
8 | 8 | item_type: menu::ItemType::Callback { |
@@ -31,6 +31,15 @@ pub static BENCH_ITEM: menu::Item<Ctx> = menu::Item { |
31 | 31 | help: Some("Time how long to put 1,000,000 characters on the screen, with scrolling."), |
32 | 32 | }; |
33 | 33 |
|
| 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 | + |
34 | 43 | /// Called when the "clear" command is executed. |
35 | 44 | fn clear(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) { |
36 | 45 | 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: |
99 | 108 | ); |
100 | 109 | } |
101 | 110 | } |
| 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