1#![no_std]
6
7extern crate alloc;
8
9use alloc::{format, string::String};
10
11use pros_core::eprintln;
12#[cfg(feature = "display_panics")]
13use pros_devices::Screen;
14
15#[cfg(target_arch = "wasm32")]
16extern "C" {
17 fn sim_log_backtrace();
19}
20
21#[cfg(feature = "display_panics")]
26fn draw_error(
27 screen: &mut pros_devices::screen::Screen,
28 msg: &str,
29) -> Result<(), pros_devices::screen::ScreenError> {
30 const ERROR_BOX_MARGIN: i16 = 16;
31 const ERROR_BOX_PADDING: i16 = 16;
32 const LINE_MAX_WIDTH: usize = 52;
33
34 let error_box_rect = pros_devices::screen::Rect::new(
35 ERROR_BOX_MARGIN,
36 ERROR_BOX_MARGIN,
37 Screen::HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN,
38 Screen::VERTICAL_RESOLUTION - ERROR_BOX_MARGIN,
39 );
40
41 screen.fill(&error_box_rect, pros_devices::color::Rgb::RED)?;
42 screen.stroke(&error_box_rect, pros_devices::color::Rgb::WHITE)?;
43
44 let mut buffer = String::new();
45 let mut line: i16 = 0;
46
47 for (i, character) in msg.char_indices() {
48 if !character.is_ascii_control() {
49 buffer.push(character);
50 }
51
52 if character == '\n' || ((buffer.len() % LINE_MAX_WIDTH == 0) && (i > 0)) {
53 screen.fill(
54 &pros_devices::screen::Text::new(
55 buffer.as_str(),
56 pros_devices::screen::TextPosition::Point(
57 ERROR_BOX_MARGIN + ERROR_BOX_PADDING,
58 ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Screen::LINE_HEIGHT),
59 ),
60 pros_devices::screen::TextFormat::Small,
61 ),
62 pros_devices::color::Rgb::WHITE,
63 )?;
64
65 line += 1;
66 buffer.clear();
67 }
68 }
69
70 screen.fill(
71 &pros_devices::screen::Text::new(
72 buffer.as_str(),
73 pros_devices::screen::TextPosition::Point(
74 ERROR_BOX_MARGIN + ERROR_BOX_PADDING,
75 ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Screen::LINE_HEIGHT),
76 ),
77 pros_devices::screen::TextFormat::Small,
78 ),
79 pros_devices::color::Rgb::WHITE,
80 )?;
81
82 Ok(())
83}
84
85#[panic_handler]
86pub fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
88 let current_task = pros_core::task::current();
89
90 let task_name = current_task.name().unwrap_or_else(|_| "<unknown>".into());
91
92 let msg = format!("task '{task_name}' {info}");
95
96 eprintln!("{msg}");
97
98 unsafe {
99 #[cfg(feature = "display_panics")]
100 draw_error(&mut Screen::new(), &msg).unwrap_or_else(|err| {
101 eprintln!("Failed to draw error message to screen: {err}");
102 });
103
104 #[cfg(target_arch = "wasm32")]
105 sim_log_backtrace();
106
107 pros_sys::exit(1);
108 }
109}