From c12ae4b5d9350e9efda946622cc09e8f7f288c8c Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 14 Sep 2023 12:44:26 +0100 Subject: [PATCH 1/2] add safety comments to public unsafe functions --- agb/src/lib.rs | 4 ++++ agb/src/sync/mod.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/agb/src/lib.rs b/agb/src/lib.rs index 73963fcc..7cbe83d6 100644 --- a/agb/src/lib.rs +++ b/agb/src/lib.rs @@ -231,6 +231,10 @@ pub struct Gba { impl Gba { #[doc(hidden)] #[must_use] + /// # Safety + /// + /// May only be called a single time. It is not needed to call this due to + /// it being called internally by the [`entry`] macro. pub unsafe fn new_in_entry() -> Self { Self::single_new() } diff --git a/agb/src/sync/mod.rs b/agb/src/sync/mod.rs index 17dad495..826a8326 100644 --- a/agb/src/sync/mod.rs +++ b/agb/src/sync/mod.rs @@ -33,6 +33,8 @@ pub fn memory_write_hint(val: *mut T) { /// This seems to be a problem caused by Rust issue #62256: /// /// +/// # Safety +/// /// **WARNING FOR ANYONE WHO FINDS THIS**: This implementation will *only* be /// correct on the GBA, and should not be used on any other platform. The GBA /// is very old, and has no atomics to begin with - only a main thread and From 473181718be08ddbc7730f85265d8eec6086f385 Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 14 Sep 2023 13:28:00 +0100 Subject: [PATCH 2/2] remove outer loop --- agb/examples/object_text_render.rs | 106 ++++++++++++++--------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/agb/examples/object_text_render.rs b/agb/examples/object_text_render.rs index d5323724..f3df935a 100644 --- a/agb/examples/object_text_render.rs +++ b/agb/examples/object_text_render.rs @@ -24,76 +24,74 @@ fn entry(gba: agb::Gba) -> ! { fn main(mut gba: agb::Gba) -> ! { let (mut unmanaged, _sprites) = gba.display.object.get_unmanaged(); - loop { - let mut palette = [0x0; 16]; - palette[1] = 0xFF_FF; - palette[2] = 0x00_FF; - let palette = Palette16::new(palette); - let palette = PaletteVram::new(&palette).unwrap(); + let mut palette = [0x0; 16]; + palette[1] = 0xFF_FF; + palette[2] = 0x00_FF; + let palette = Palette16::new(palette); + let palette = PaletteVram::new(&palette).unwrap(); - let timer = gba.timers.timers(); - let mut timer: agb::timer::Timer = timer.timer2; + let timer = gba.timers.timers(); + let mut timer: agb::timer::Timer = timer.timer2; - timer.set_enabled(true); - timer.set_divider(agb::timer::Divider::Divider256); + timer.set_enabled(true); + timer.set_divider(agb::timer::Divider::Divider256); - let mut wr = ObjectTextRender::new(&FONT, Size::S16x16, palette); - let start = timer.value(); + let mut wr = ObjectTextRender::new(&FONT, Size::S16x16, palette); + let start = timer.value(); - let player_name = "You"; - let _ = writeln!( + let player_name = "You"; + let _ = writeln!( wr, "Woah!{change2} {player_name}! {change1}Hey there! I have a bunch of text I want to show you. However, you will find that the amount of text I can display is limited. Who'd have thought! Good thing that my text system supports scrolling! It only took around 20 jank versions to get here!", change2 = ChangeColour::new(2), change1 = ChangeColour::new(1), ); - let end = timer.value(); + let end = timer.value(); - agb::println!( - "Write took {} cycles", - 256 * (end.wrapping_sub(start) as u32) - ); + agb::println!( + "Write took {} cycles", + 256 * (end.wrapping_sub(start) as u32) + ); - let vblank = agb::interrupt::VBlank::get(); - let mut input = agb::input::ButtonController::new(); + let vblank = agb::interrupt::VBlank::get(); + let mut input = agb::input::ButtonController::new(); + + let start = timer.value(); + + wr.layout((WIDTH, 40).into(), TextAlignment::Justify, 2); + let end = timer.value(); + + agb::println!( + "Layout took {} cycles", + 256 * (end.wrapping_sub(start) as u32) + ); + + let mut line_done = false; + let mut frame = 0; + + loop { + vblank.wait_for_vblank(); + input.update(); + let oam = &mut unmanaged.iter(); + wr.commit(oam); let start = timer.value(); - - wr.layout((WIDTH, 40).into(), TextAlignment::Justify, 2); + if frame % 4 == 0 { + line_done = !wr.next_letter_group(); + } + if line_done && input.is_just_pressed(Button::A) { + line_done = false; + wr.pop_line(); + } + wr.update((0, HEIGHT - 40).into()); let end = timer.value(); + frame += 1; + agb::println!( - "Layout took {} cycles", - 256 * (end.wrapping_sub(start) as u32) + "Took {} cycles, line done {}", + 256 * (end.wrapping_sub(start) as u32), + line_done ); - - let mut line_done = false; - let mut frame = 0; - - loop { - vblank.wait_for_vblank(); - input.update(); - let oam = &mut unmanaged.iter(); - wr.commit(oam); - - let start = timer.value(); - if frame % 4 == 0 { - line_done = !wr.next_letter_group(); - } - if line_done && input.is_just_pressed(Button::A) { - line_done = false; - wr.pop_line(); - } - wr.update((0, HEIGHT - 40).into()); - let end = timer.value(); - - frame += 1; - - agb::println!( - "Took {} cycles, line done {}", - 256 * (end.wrapping_sub(start) as u32), - line_done - ); - } } }