Skip to content

Commit baa0c34

Browse files
committed
Add graphics test command.
Shows a raw bitmap off disk in the given screen-mode using the TPA.
1 parent bf27d34 commit baa0c34

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub static OS_MENU: menu::Menu<Ctx> = menu::Menu {
3535
&fs::TYPE_ITEM,
3636
&screen::CLS_ITEM,
3737
&screen::MODE_ITEM,
38+
&screen::GFX_ITEM,
3839
&input::KBTEST_ITEM,
3940
&hardware::SHUTDOWN_ITEM,
4041
&sound::MIXER_ITEM,

src/commands/screen.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Screen-related commands for Neotron OS
22
3+
use neotron_common_bios::video::RGBColour;
4+
use pc_keyboard::DecodedKey;
5+
36
use crate::{
47
bios::{
58
video::{Format, Mode},
@@ -29,6 +32,24 @@ pub static MODE_ITEM: menu::Item<Ctx> = menu::Item {
2932
help: Some("List/change video mode"),
3033
};
3134

35+
pub static GFX_ITEM: menu::Item<Ctx> = menu::Item {
36+
item_type: menu::ItemType::Callback {
37+
function: gfx_cmd,
38+
parameters: &[
39+
menu::Parameter::Mandatory {
40+
parameter_name: "new_mode",
41+
help: Some("The new gfx mode to try"),
42+
},
43+
menu::Parameter::Optional {
44+
parameter_name: "filename",
45+
help: Some("a file to display"),
46+
},
47+
],
48+
},
49+
command: "gfx",
50+
help: Some("Test a graphics mode"),
51+
};
52+
3253
/// Called when the "cls" command is executed.
3354
fn cls_cmd(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
3455
// Reset SGR, go home, clear screen,
@@ -88,6 +109,82 @@ fn mode_cmd(_menu: &menu::Menu<Ctx>, item: &menu::Item<Ctx>, args: &[&str], _ctx
88109
}
89110
}
90111

112+
/// Called when the "gfx" command is executed
113+
fn gfx_cmd(_menu: &menu::Menu<Ctx>, item: &menu::Item<Ctx>, args: &[&str], ctx: &mut Ctx) {
114+
let Some(new_mode) = menu::argument_finder(item, args, "new_mode").unwrap() else {
115+
osprintln!("Missing arg");
116+
return;
117+
};
118+
let file_name = menu::argument_finder(item, args, "filename").unwrap();
119+
let Ok(mode_num) = new_mode.parse::<u8>() else {
120+
osprintln!("Invalid integer {:?}", new_mode);
121+
return;
122+
};
123+
let Some(mode) = Mode::try_from_u8(mode_num) else {
124+
osprintln!("Invalid mode {:?}", new_mode);
125+
return;
126+
};
127+
let api = crate::API.get();
128+
let old_mode = (api.video_get_mode)();
129+
let old_ptr = (api.video_get_framebuffer)();
130+
131+
let buffer = ctx.tpa.as_slice_u8();
132+
let buffer_ptr = buffer.as_mut_ptr() as *mut u32;
133+
if let Some(file_name) = file_name {
134+
let Ok(file) = crate::FILESYSTEM.open_file(file_name, embedded_sdmmc::Mode::ReadOnly)
135+
else {
136+
osprintln!("No such file.");
137+
return;
138+
};
139+
let _ = file.read(buffer);
140+
} else {
141+
// draw a dummy non-zero data. In Chunky1 this is a checkerboard.
142+
let line_size_words = mode.line_size_bytes() / 4;
143+
for row in 0..mode.vertical_lines() as usize {
144+
let word = if (row % 2) == 0 {
145+
0x5555_5555
146+
} else {
147+
0xAAAA_AAAA
148+
};
149+
for col in 0..line_size_words {
150+
let idx = (row * line_size_words) + col;
151+
unsafe {
152+
// Let's try stripes?
153+
buffer_ptr.add(idx).write_volatile(word);
154+
}
155+
}
156+
}
157+
}
158+
159+
if let neotron_common_bios::FfiResult::Err(e) =
160+
unsafe { (api.video_set_mode)(mode, buffer_ptr) }
161+
{
162+
osprintln!("Couldn't set mode {}: {:?}", mode_num, e);
163+
}
164+
165+
// Now wait for user input
166+
let mut r = 0u8;
167+
let mut g = 80u8;
168+
let mut b = 160u8;
169+
'wait: loop {
170+
(api.video_wait_for_line)(0);
171+
((api.video_set_palette)(0, RGBColour::from_rgb(r, g, b)));
172+
r = r.wrapping_add(1);
173+
g = g.wrapping_add(1);
174+
b = b.wrapping_add(1);
175+
176+
let keyin = crate::STD_INPUT.lock().get_raw();
177+
if let Some(DecodedKey::Unicode('Q') | DecodedKey::Unicode('q')) = keyin {
178+
break 'wait;
179+
}
180+
}
181+
182+
// Put it back as it was
183+
unsafe {
184+
(api.video_set_mode)(old_mode, old_ptr);
185+
}
186+
}
187+
91188
/// Print out all supported video modes
92189
fn print_modes() {
93190
let api = crate::API.get();

0 commit comments

Comments
 (0)