@@ -32,16 +32,10 @@ pub static MODE_ITEM: menu::Item<Ctx> = menu::Item {
3232pub static GFX_ITEM : menu:: Item < Ctx > = menu:: Item {
3333 item_type : menu:: ItemType :: Callback {
3434 function : gfx_cmd,
35- parameters : & [
36- menu:: Parameter :: Mandatory {
37- parameter_name : "new_mode" ,
38- help : Some ( "The new gfx mode to try" ) ,
39- } ,
40- menu:: Parameter :: Optional {
41- parameter_name : "filename" ,
42- help : Some ( "a file to display" ) ,
43- } ,
44- ] ,
35+ parameters : & [ menu:: Parameter :: Mandatory {
36+ parameter_name : "new_mode" ,
37+ help : Some ( "The new gfx mode to try" ) ,
38+ } ] ,
4539 } ,
4640 command : "gfx" ,
4741 help : Some ( "Test a graphics mode" ) ,
@@ -107,12 +101,13 @@ fn mode_cmd(_menu: &menu::Menu<Ctx>, item: &menu::Item<Ctx>, args: &[&str], _ctx
107101}
108102
109103/// Called when the "gfx" command is executed
104+ ///
105+ /// Performs a selection of graphical tests
110106fn gfx_cmd ( _menu : & menu:: Menu < Ctx > , item : & menu:: Item < Ctx > , args : & [ & str ] , ctx : & mut Ctx ) {
111107 let Some ( new_mode) = menu:: argument_finder ( item, args, "new_mode" ) . unwrap ( ) else {
112108 osprintln ! ( "Missing arg" ) ;
113109 return ;
114110 } ;
115- let file_name = menu:: argument_finder ( item, args, "filename" ) . unwrap ( ) ;
116111 let Ok ( mode_num) = new_mode. parse :: < u8 > ( ) else {
117112 osprintln ! ( "Invalid integer {:?}" , new_mode) ;
118113 return ;
@@ -126,58 +121,164 @@ fn gfx_cmd(_menu: &menu::Menu<Ctx>, item: &menu::Item<Ctx>, args: &[&str], ctx:
126121 let old_ptr = ( api. video_get_framebuffer ) ( ) ;
127122
128123 let buffer = ctx. tpa . as_slice_u8 ( ) ;
129- let buffer_ptr = buffer. as_mut_ptr ( ) as * mut u32 ;
130- if let Some ( file_name) = file_name {
131- let Ok ( file) = crate :: FILESYSTEM . open_file ( file_name, embedded_sdmmc:: Mode :: ReadOnly )
132- else {
133- osprintln ! ( "No such file." ) ;
134- return ;
135- } ;
136- let _ = file. read ( buffer) ;
137- } else {
138- let ( odd_pattern, even_pattern) = match mode. format ( ) {
139- // This is alternating hearts and diamonds
140- Format :: Text8x16 | Format :: Text8x8 => (
141- u32:: from_le_bytes ( * b"\x03 \x0F \x04 \x70 " ) ,
142- u32:: from_le_bytes ( * b"\x04 \x70 \x03 \x0F " ) ,
143- ) ,
144- // Can't do a checkerboard here - so stripes will do
145- Format :: Chunky32 => ( 0x0000_0000 , 0x0000_0001 ) ,
146- // These should produce black/white checkerboard, in the default
147- // palette
148- Format :: Chunky16 => ( 0x0000_FFFF , 0xFFFF_0000 ) ,
149- Format :: Chunky8 => ( 0x000F_000F , 0x0F00_0F00 ) ,
150- Format :: Chunky4 => ( 0x0F0F_0F0F , 0xF0F0_F0F0 ) ,
151- Format :: Chunky2 => ( 0x3333_3333 , 0xCCCC_CCCC ) ,
152- Format :: Chunky1 => ( 0x5555_5555 , 0xAAAA_AAAA ) ,
153- _ => todo ! ( ) ,
154- } ;
155- // draw a dummy non-zero data. In Chunky1 this is a checkerboard.
156- let line_size_words = mode. line_size_bytes ( ) / 4 ;
157- for row in 0 ..mode. vertical_lines ( ) as usize {
158- let word = if ( row % 2 ) == 0 {
159- even_pattern
160- } else {
161- odd_pattern
162- } ;
163- for col in 0 ..line_size_words {
164- let idx = ( row * line_size_words) + col;
165- unsafe {
166- buffer_ptr. add ( idx) . write_volatile ( word) ;
167- }
168- }
169- }
124+ if mode. frame_size_bytes ( ) > buffer. len ( ) {
125+ osprintln ! ( "Not enough space in TPA" ) ;
126+ return ;
170127 }
128+ let buffer_ptr = buffer. as_mut_ptr ( ) as * mut u32 ;
171129
172130 if let neotron_common_bios:: FfiResult :: Err ( e) =
173131 unsafe { ( api. video_set_mode ) ( mode, buffer_ptr) }
174132 {
175133 osprintln ! ( "Couldn't set mode {}: {:?}" , mode_num, e) ;
176134 }
177135
178- // Now wait for user input
179- while crate :: STD_INPUT . lock ( ) . get_raw ( ) . is_none ( ) {
180- // spin
136+ let gen_value = |x : u16 , y : u16 , colour : u32 | -> u64 {
137+ ( x as u64 ) << 48 | ( y as u64 ) << 32 | ( colour & 0xFFFFFF ) as u64
138+ } ;
139+
140+ // plots a vertical colour stripe pattern.
141+ let vertical = |handle| -> Result < ( ) , neotron_api:: Error > {
142+ for y in 0 ..mode. vertical_lines ( ) {
143+ let mut colour = 0u32 ;
144+ for x in 0 ..mode. horizontal_pixels ( ) {
145+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
146+ handle,
147+ crate :: program:: GFX_COMMAND_CHUNKY_PLOT ,
148+ gen_value ( x, y, colour) ,
149+ )
150+ . into ( ) ;
151+ result?;
152+ colour = colour. wrapping_add ( 1 ) & 0xFFFFFF ;
153+ }
154+ }
155+
156+ // Now wait for user input
157+ while crate :: STD_INPUT . lock ( ) . get_raw ( ) . is_none ( ) {
158+ // spin
159+ }
160+
161+ Ok ( ( ) )
162+ } ;
163+
164+ // plots a horizontal colour stripe pattern.
165+ let horizontal = |handle| -> Result < ( ) , neotron_api:: Error > {
166+ let mut colour = 0u32 ;
167+ for y in 0 ..mode. vertical_lines ( ) {
168+ for x in 0 ..mode. horizontal_pixels ( ) {
169+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
170+ handle,
171+ crate :: program:: GFX_COMMAND_CHUNKY_PLOT ,
172+ gen_value ( x, y, colour) ,
173+ )
174+ . into ( ) ;
175+ result?;
176+ }
177+ colour = colour. wrapping_add ( 1 ) & 0xFFFFFF ;
178+ }
179+
180+ // Now wait for user input
181+ while crate :: STD_INPUT . lock ( ) . get_raw ( ) . is_none ( ) {
182+ // spin
183+ }
184+
185+ Ok ( ( ) )
186+ } ;
187+
188+ // plots a rolling stripe pattern.
189+ let rolling = |handle| -> Result < ( ) , neotron_api:: Error > {
190+ for y in 0 ..mode. vertical_lines ( ) {
191+ let mut colour = y as u32 ;
192+ for x in 0 ..mode. horizontal_pixels ( ) {
193+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
194+ handle,
195+ crate :: program:: GFX_COMMAND_CHUNKY_PLOT ,
196+ gen_value ( x, y, colour) ,
197+ )
198+ . into ( ) ;
199+ result?;
200+ colour = colour. wrapping_add ( 1 ) & 0xFFFFFF ;
201+ }
202+ }
203+
204+ // Now wait for user input
205+ while crate :: STD_INPUT . lock ( ) . get_raw ( ) . is_none ( ) {
206+ // spin
207+ }
208+
209+ Ok ( ( ) )
210+ } ;
211+
212+ // plots a grid
213+ let grid = |handle| -> Result < ( ) , neotron_api:: Error > {
214+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
215+ handle,
216+ crate :: program:: GFX_COMMAND_CLEAR_SCREEN ,
217+ 0 ,
218+ )
219+ . into ( ) ;
220+ result?;
221+
222+ let width = mode. horizontal_pixels ( ) / 10 ;
223+ let height = mode. vertical_lines ( ) / 10 ;
224+
225+ for y in 0 ..mode. vertical_lines ( ) {
226+ if ( y % height) == 0 || ( y == mode. vertical_lines ( ) - 1 ) {
227+ // solid line
228+ for x in 0 ..mode. horizontal_pixels ( ) {
229+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
230+ handle,
231+ crate :: program:: GFX_COMMAND_CHUNKY_PLOT ,
232+ gen_value ( x, y, 15 ) ,
233+ )
234+ . into ( ) ;
235+ result?;
236+ }
237+ } else {
238+ // stripes
239+ for x in 0 ..mode. horizontal_pixels ( ) {
240+ let colour = if ( x % width) == 0 || ( x == mode. horizontal_pixels ( ) - 1 ) {
241+ 15
242+ } else {
243+ 0
244+ } ;
245+ let result: Result < _ , _ > = ( crate :: program:: CALLBACK_TABLE . ioctl ) (
246+ handle,
247+ crate :: program:: GFX_COMMAND_CHUNKY_PLOT ,
248+ gen_value ( x, y, colour) ,
249+ )
250+ . into ( ) ;
251+ result?;
252+ }
253+ }
254+ }
255+
256+ // Now wait for user input
257+ while crate :: STD_INPUT . lock ( ) . get_raw ( ) . is_none ( ) {
258+ // spin
259+ }
260+
261+ Ok ( ( ) )
262+ } ;
263+
264+ let handle: Result < _ , _ > =
265+ ( crate :: program:: CALLBACK_TABLE . open ) ( "GFX:" . into ( ) , neotron_api:: file:: Flags :: WRITE )
266+ . into ( ) ;
267+ if let Ok ( handle) = handle {
268+ if let Err ( e) = vertical ( handle) {
269+ osprintln ! ( "Draw failure on vertical: {:?}" , e) ;
270+ }
271+ if let Err ( e) = horizontal ( handle) {
272+ osprintln ! ( "Draw failure on horizontal: {:?}" , e) ;
273+ }
274+ if let Err ( e) = rolling ( handle) {
275+ osprintln ! ( "Draw failure on rolling: {:?}" , e) ;
276+ }
277+ if let Err ( e) = grid ( handle) {
278+ osprintln ! ( "Draw failure on grid: {:?}" , e) ;
279+ }
280+ // close the handle
281+ let _ = ( crate :: program:: CALLBACK_TABLE . close ) ( handle) ;
181282 }
182283
183284 // Put it back as it was
0 commit comments