22
33use 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
77pub static CLEAR_ITEM : menu:: Item < Ctx > = menu:: Item {
88 item_type : menu:: ItemType :: Callback {
@@ -22,6 +22,24 @@ pub static FILL_ITEM: menu::Item<Ctx> = menu::Item {
2222 help : Some ( "Fill the screen with characters" ) ,
2323} ;
2424
25+ pub static BENCH_ITEM : menu:: Item < Ctx > = menu:: Item {
26+ item_type : menu:: ItemType :: Callback {
27+ function : bench,
28+ parameters : & [ ] ,
29+ } ,
30+ command : "screen_bench" ,
31+ help : Some ( "Time how long to put 1,000,000 characters on the screen, with scrolling." ) ,
32+ } ;
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+
2543/// Called when the "clear" command is executed.
2644fn clear ( _menu : & menu:: Menu < Ctx > , _item : & menu:: Item < Ctx > , _args : & [ & str ] , _ctx : & mut Ctx ) {
2745 if let Some ( ref mut console) = unsafe { & mut VGA_CONSOLE } {
@@ -69,3 +87,61 @@ fn fill(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx:
6987 console. set_attr ( attr) ;
7088 }
7189}
90+
91+ /// Called when the "bench" command is executed.
92+ fn bench ( _menu : & menu:: Menu < Ctx > , _item : & menu:: Item < Ctx > , _args : & [ & str ] , _ctx : & mut Ctx ) {
93+ const NUM_CHARS : u64 = 1_000_000 ;
94+ if let Some ( ref mut console) = unsafe { & mut VGA_CONSOLE } {
95+ let api = API . get ( ) ;
96+ let start = ( api. time_ticks_get ) ( ) ;
97+ console. clear ( ) ;
98+ let glyphs = & [ b'x' ] ;
99+ for _idx in 0 ..NUM_CHARS {
100+ console. write_bstr ( glyphs) ;
101+ }
102+ let end = ( api. time_ticks_get ) ( ) ;
103+ let delta = end. 0 - start. 0 ;
104+ let chars_per_second = ( NUM_CHARS * ( api. time_ticks_per_second ) ( ) . 0 ) / delta;
105+ println ! (
106+ "{} chars in {} ticks, or {} chars per second" ,
107+ NUM_CHARS , delta, chars_per_second
108+ ) ;
109+ }
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