gba-lsdpack-player/src/main.rs

138 lines
4 KiB
Rust
Raw Normal View History

// from https://github.com/rust-console/gba/blob/main/examples/hello.rs
#![no_std]
#![no_main]
2023-12-09 09:34:16 +00:00
#![feature(ascii_char)]
#![feature(panic_info_message)]
// rustc is simply wrong about core::fmt::Write being unused,
// it's used in the panic handler.
#![allow(unused_imports)]
mod halfwidth;
use core::fmt::Write;
2023-12-09 09:34:16 +00:00
use gba::prelude::*;
2023-12-09 09:34:16 +00:00
#[allow(unused_must_use)]
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
2023-12-09 09:34:16 +00:00
let mut text_painter = halfwidth::TextPainter::new();
text_painter.setup_display();
text_painter.write_str("panic at ");
if let Some(location) = info.location() {
write!(&mut text_painter, "{}:{}", location.file(), location.line());
} else {
text_painter.write_str("unknown location");
};
if let Some(msg) = info.message() {
write!(&mut text_painter, ":\n");
core::fmt::write(&mut text_painter, *msg);
}
if let Some(s) = info.payload().downcast_ref::<&str>() {
text_painter.write_str("\n");
text_painter.write_str(s);
}
#[cfg(debug_assertions)]
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
2023-12-09 09:34:16 +00:00
for _ in 0..4 {
VBlankIntrWait();
}
if let Some(args) = info.message() {
logger.write_fmt(*args);
} else {
writeln!(logger, "{info}");
}
}
loop {
VBlankIntrWait();
}
}
#[link_section = ".ewram"]
static FRAME_KEYS: GbaCell<KeyInput> = GbaCell::new(KeyInput::new());
#[link_section = ".iwram"]
extern "C" fn irq_handler(_: IrqBits) {
// We'll read the keys during vblank and store it for later.
FRAME_KEYS.write(KEYINPUT.read());
}
#[no_mangle]
extern "C" fn main() -> ! {
RUST_IRQ_HANDLER.write(Some(irq_handler));
DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
IE.write(IrqBits::VBLANK);
IME.write(true);
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) {
writeln!(logger, "hello!").ok();
let fx_u: Fixed<u32, 8> = Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_raw(12);
writeln!(logger, "fixed unsigned: {fx_u:?}").ok();
let fx_i1: Fixed<i32, 8> =
Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_raw(15);
writeln!(logger, "fixed signed positive: {fx_i1:?}").ok();
let fx_i2: Fixed<i32, 8> = Fixed::<i32, 8>::wrapping_from(0)
- Fixed::<i32, 8>::wrapping_from(3)
- Fixed::<i32, 8>::from_raw(17);
writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
}
{
// get our tile data into memory.
Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
}
{
// set up the tilemap
let tsb = TEXT_SCREENBLOCKS.get_frame(31).unwrap();
for y in 0..16 {
let row = tsb.get_row(y).unwrap();
for (x, addr) in row.iter().enumerate().take(16) {
let te = TextEntry::new().with_tile((y * 16 + x) as u16);
addr.write(te);
}
}
}
{
// Set BG0 to use the tilemap we just made, and set it to be shown.
BG0CNT.write(BackgroundControl::new().with_screenblock(31));
DISPCNT.write(DisplayControl::new().with_show_bg0(true));
}
let mut x_off = 0_u32;
let mut y_off = 0_u32;
let mut backdrop_color = Color(0);
loop {
VBlankIntrWait();
// show current frame
BACKDROP_COLOR.write(backdrop_color);
BG0HOFS.write(x_off as u16);
BG0VOFS.write(y_off as u16);
// prep next frame
let k = FRAME_KEYS.read();
backdrop_color = Color(k.to_u16());
if k.up() {
y_off = y_off.wrapping_add(1);
}
if k.down() {
y_off = y_off.wrapping_sub(1);
}
if k.left() {
x_off = x_off.wrapping_add(1);
}
if k.right() {
x_off = x_off.wrapping_sub(1);
}
2023-12-09 09:34:16 +00:00
if k.start() {
panic!("pressed start")
}
}
}