211 lines
5.4 KiB
Rust
211 lines
5.4 KiB
Rust
use std::fmt::Write;
|
|
use std::panic::PanicHookInfo;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
use vitasdk_sys::sceGxmTerminate;
|
|
|
|
mod debug_screen;
|
|
mod gui;
|
|
|
|
// pub const CDRAM_ALIGNMENT: u32 = 0x3FFFF;
|
|
/// 256 kb
|
|
pub const CDRAM_ALIGNMENT:u32 = (256 * 1024) - 1;
|
|
/// 4 kb
|
|
pub const NOT_CDRAM_ALIGNMENT:u32 = (4 * 1024) - 1;
|
|
|
|
#[inline]
|
|
pub const fn align(data:u32, alignment:u32) -> u32 { (data + alignment) & !alignment }
|
|
|
|
// these should probably be macros?
|
|
#[inline]
|
|
pub fn abs(x:i8) -> i8 { if x > 0 { x } else { x * -1 } }
|
|
|
|
// tracing based logger
|
|
|
|
fn rainbow_color(t:f32) -> (u32, u32, u32) {
|
|
let hue = t * 360.0; // Convert time to hue (0-360 degrees)
|
|
let saturation = 1.0; // Maximum saturation
|
|
let value = 1.0; // Maximum value (brightness)
|
|
|
|
// Convert HSV to RGB
|
|
let c = value * saturation;
|
|
let x = c * (1.0 - (((hue / 60.0) % 2.0) - 1.0).abs());
|
|
let m = value - c;
|
|
let (r, g, b) = match hue {
|
|
0.0..=60.0 => (c, x, 0.0),
|
|
60.0..=120.0 => (x, c, 0.0),
|
|
120.0..=180.0 => (0.0, c, x),
|
|
180.0..=240.0 => (0.0, x, c),
|
|
240.0..=300.0 => (x, 0.0, c),
|
|
_ => (c, 0.0, x),
|
|
};
|
|
|
|
// Scale RGB values to 8-bit integers
|
|
let r = (255.0 * (r + m)) as u32;
|
|
let g = (255.0 * (g + m)) as u32;
|
|
let b = (255.0 * (b + m)) as u32;
|
|
|
|
(r, g, b)
|
|
}
|
|
|
|
fn ilerp(min:f32, max:f32, input:f32) -> f32 { (input - min) / (max - min) }
|
|
|
|
// #[tokio::main]
|
|
pub fn main() {
|
|
std::panic::set_hook(Box::new(custom_panic_hook));
|
|
|
|
println!("Panic hook set");
|
|
|
|
// SCE_GXM_ERROR_INVALID_POINTER
|
|
|
|
// const thing1: u32 = 0x80024b05;
|
|
// const thing2: u32 = 0x80024309;
|
|
|
|
// unsafe { sceClibPrintf("whar?".as_ptr() as *const i8); }
|
|
|
|
// text_screen();
|
|
|
|
// std::thread::sleep(Duration::from_secs(3));
|
|
|
|
// for _ in 0..3 {
|
|
// raw_rainbow();
|
|
// }
|
|
|
|
// std::thread::sleep(Duration::from_secs(3));
|
|
|
|
// new_text_screen();
|
|
|
|
// std::thread::sleep(Duration::from_secs(3));
|
|
|
|
// unsafe {
|
|
// cube::cube();
|
|
// cube2::cube();
|
|
// cube3::cube();
|
|
// }
|
|
|
|
std::thread::sleep(Duration::from_secs(3));
|
|
|
|
panic!("Test panic!");
|
|
|
|
// loop {
|
|
// std::thread::sleep(Duration::from_secs(10));
|
|
// }
|
|
|
|
unsafe { sceGxmTerminate() };
|
|
}
|
|
|
|
// fn new_text_screen() {
|
|
// let mut screen = gui::TextScreen::predef();
|
|
// screen.enable();
|
|
|
|
// // for i in 336..446 {
|
|
// // screen.framebuffer.set(i, 0xFF_FF_FF_FF);
|
|
// // }
|
|
|
|
// // screen.set_cursor(4, 0);
|
|
// // write!(screen, "\n").ok();
|
|
// // screen.update_screen_raw();
|
|
// write!(screen, "Goodbye Void!\n").ok();
|
|
// screen.update_screen_raw();
|
|
// thread::sleep(Duration::from_secs(3));
|
|
// write!(screen, "Goodbye Void!\n").ok();
|
|
// screen.update_screen_raw();
|
|
// thread::sleep(Duration::from_secs(3));
|
|
// write!(screen, "Goodbye Void!\n").ok();
|
|
// screen.update_screen_raw();
|
|
// thread::sleep(Duration::from_secs(3));
|
|
|
|
// screen.set_cursor(0, 3);
|
|
// for _ in 0..25 {
|
|
// write!(screen, "Goodbye Void!\n").ok();
|
|
// // screen.update_screen_raw();
|
|
// }
|
|
|
|
// thread::sleep(Duration::from_secs(3));
|
|
// screen.clear();
|
|
// screen.update_screen_raw();
|
|
|
|
// // screen.set_foreground(255,255,0);
|
|
|
|
// // for x in 0..24 {
|
|
// // for y in 0..24 {
|
|
// // mono_screen.set_cursor(24 + x, 24 + y);
|
|
// // write!((219 as char).to_string());
|
|
// // thread::sleep(Duration::from_millis(16));
|
|
// // }
|
|
// // }
|
|
// // mono_screen.set_cursor(0,1);
|
|
// // mono_screen.set_foreground(0,0,0);
|
|
|
|
// // drop(screen);
|
|
|
|
// // let mut screen = gui::TextScreen::new();
|
|
// // screen.set_display();
|
|
// // loop {
|
|
// // screen.clear();
|
|
// // screen.update_screen_raw();
|
|
// // std::thread::sleep(Duration::from_millis(100));
|
|
// // }
|
|
// }
|
|
|
|
// fn text_screen() {
|
|
// let mut screen = debug::framebuffer::DebugScreen::new();
|
|
// writeln!(screen, "crusty").ok();
|
|
// // thread::sleep(Duration::from_secs(2));
|
|
// writeln!(screen, "newline").ok();
|
|
// // thread::sleep(Duration::from_secs(2));
|
|
|
|
// let random_numbers: Vec<u8> = (0..8).map(|_i| rand::random::<u8>()).collect();
|
|
// writeln!(screen, "random numbers: {:?}", random_numbers).ok();
|
|
|
|
// // writeln!(screen, "I know where you sleep :3").ok();
|
|
// }
|
|
|
|
fn raw_rainbow() {
|
|
let mut raw_buffer = gui::framebuffer::Framebuffer::new();
|
|
raw_buffer.set_display();
|
|
|
|
for index_width in 0..raw_buffer.screen_width {
|
|
thread::sleep(Duration::from_micros(20));
|
|
|
|
let (r, g, b) = rainbow_color(ilerp(0.0, raw_buffer.screen_width as f32, index_width as f32));
|
|
|
|
for index_height in 0..raw_buffer.screen_height {
|
|
raw_buffer.set(index_width + (index_height * raw_buffer.screen_width), 0 as u32 | b << 16 | g << 8 | r); // VITA USES ABGR
|
|
}
|
|
}
|
|
}
|
|
|
|
fn custom_panic_hook(info:&PanicHookInfo<'_>) {
|
|
// The current implementation always returns `Some`.
|
|
let location = info.location().unwrap();
|
|
|
|
let msg = match info.payload().downcast_ref::<&'static str>() {
|
|
Some(s) => *s,
|
|
None => match info.payload().downcast_ref::<String>() {
|
|
Some(s) => &s[..],
|
|
None => "Box<Any>",
|
|
},
|
|
};
|
|
let name = "unknown";
|
|
|
|
let mut screen = debug_screen::framebuffer::DebugScreen::new();
|
|
|
|
println!("thread '{}' panicked at '{}', {}", name, msg, location);
|
|
writeln!(screen, "thread '{}' panicked at '{}', {}", name, msg, location).ok();
|
|
|
|
// Give 2 seconds to see the error in case capturing the stack trace fails
|
|
// (capturing the stack trace allocates memory)
|
|
thread::sleep(Duration::from_secs(2));
|
|
|
|
let _ = std::panic::catch_unwind(move || {
|
|
// The backtrace is full of "unknown" for some reason
|
|
let backtrace = std::backtrace::Backtrace::force_capture();
|
|
writeln!(screen, "{}", backtrace).ok();
|
|
});
|
|
|
|
loop {
|
|
thread::sleep(Duration::from_secs(60));
|
|
}
|
|
}
|