Skip to content

Commit

Permalink
clothed functions (#197)
Browse files Browse the repository at this point in the history
* clothed functions

* remove the asm_runtime module as a public module

* partly fix the examples.

* add RUST_IRQ_HANDLER to the prelude

* make the crate work right with both a32 and t32 building.

* fix incorrect mgba logging activation.

* it all builds but there's bugs in here.

* we had the wrong number of copies.

* we can delete the old stuff we don't even want all that general memcpy stuff, we want precise functions.

* try putting the irq handler in iwram to speed it up

* get the correct runtime handler code from the 0.12 branch; the bug was that we need to go back to IRQ mode (not SVC mode) when finishing up the IRQ handler (which should have been obvious).

* skip flipping dy when bouncing off of a paddle in the pong demo.

* remove excess imports

* remove unsafe code usage from examples by providing safe wrappers for those operations in the lib.

* make the pointer type match the usage.

* i'm just going with not having the crate provide special division support for now, compiler-builtins still provides it.

* fix the pointer type.

* improve the unimplemented message.

* sort our crate declarations
  • Loading branch information
Lokathor authored Sep 2, 2024
1 parent e6abe9f commit fa14304
Show file tree
Hide file tree
Showing 12 changed files with 452 additions and 1,104 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ fixed = ["dep:fixed"]
[dependencies]
voladdress = "1.3.0"
bitfrob = "1"
bracer = "0.1.2"
bracer = "0.3.1"
critical-section = { version = "1.1.2", features = [
"restore-state-bool",
], optional = true }
fixed = { version = "1.28.0", optional = true }
bytemuck = "1.17.1"

[profile.dev]
opt-level = 3
Expand Down
6 changes: 3 additions & 3 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ extern "C" fn main() -> ! {
writeln!(logger, "hello!").ok();

let fx_u: Fixed<u32, 8> =
Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_raw(12);
Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_bits(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);
Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_bits(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);
- Fixed::<i32, 8>::from_bits(17);
writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
}

Expand Down
239 changes: 128 additions & 111 deletions examples/mode3_pong_example_game.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* Made by Evan Goemer
* Discord: @evangoemer
*/
/*
* Made by Evan Goemer
* Discord: @evangoemer
*/

#![no_std]
#![no_main]

use gba::{prelude::*, mem_fns::__aeabi_memset};
use gba::{mem::set_u32x80_unchecked, prelude::*};

Check warning on line 9 in examples/mode3_pong_example_game.rs

View workflow job for this annotation

GitHub Actions / build (nightly)

unused import: `mem::set_u32x80_unchecked`

const SCREEN_WIDTH: u16 = 240;
const SCREEN_HEIGHT: u16 = 160;
Expand All @@ -16,91 +16,87 @@ const PADDLE_HEIGHT: u16 = 20;
const BALL_SIZE: u16 = 2;

struct Paddle {
x: u16,
y: u16,
x: u16,
y: u16,
}

struct Ball {
x: u16,
y: u16,
dx: i16,
dy: i16,
x: u16,
y: u16,
dx: i16,
dy: i16,
}

impl Paddle {
fn new(x: u16, y: u16) -> Self {
Self {
x,
y,
}
fn new(x: u16, y: u16) -> Self {
Self { x, y }
}

fn update(&mut self) {
let keys = KEYINPUT.read();
if keys.up() && self.y > 1 {
self.y -= 1;
}

fn update(&mut self) {
let keys = KEYINPUT.read();
if keys.up() && self.y > 1 {
self.y -= 1;
}

if keys.down() && self.y + PADDLE_HEIGHT + 1 < SCREEN_HEIGHT {
self.y += 1;
}
if keys.down() && self.y + PADDLE_HEIGHT + 1 < SCREEN_HEIGHT {
self.y += 1;
}
}
}

impl Ball {
fn new(x: u16, y: u16) -> Self {
Self { x, y, dx: 1, dy: 1 }
fn new(x: u16, y: u16) -> Self {
Self { x, y, dx: 1, dy: 1 }
}

fn update(&mut self, paddle1: &Paddle, paddle2: &Paddle) {
if self.y <= 0 || self.y + BALL_SIZE >= SCREEN_HEIGHT {
self.dy = -self.dy;
}

if self.x + BALL_SIZE >= paddle1.x
&& self.x <= paddle1.x + PADDLE_WIDTH
&& self.y + BALL_SIZE >= paddle1.y
&& self.y <= paddle1.y + PADDLE_HEIGHT
{
self.dx = -self.dx;
self.dy = self.dy;
}

if self.x + BALL_SIZE >= paddle2.x
&& self.x <= paddle2.x + PADDLE_WIDTH
&& self.y + BALL_SIZE >= paddle2.y
&& self.y <= paddle2.y + PADDLE_HEIGHT
{
self.dx = -self.dx;
self.dy = self.dy;
}

fn update(&mut self, paddle1: &Paddle, paddle2: &Paddle) {
if self.y <= 0 || self.y + BALL_SIZE >= SCREEN_HEIGHT {
self.dy = -self.dy;
}

if self.x + BALL_SIZE >= paddle1.x
&& self.x <= paddle1.x + PADDLE_WIDTH
&& self.y + BALL_SIZE >= paddle1.y
&& self.y <= paddle1.y + PADDLE_HEIGHT
{
self.dx = -self.dx;
self.dy = -self.dy;
}

if self.x + BALL_SIZE >= paddle2.x
&& self.x <= paddle2.x + PADDLE_WIDTH
&& self.y + BALL_SIZE >= paddle2.y
&& self.y <= paddle2.y + PADDLE_HEIGHT
{
self.dx = -self.dx;
self.dy = -self.dy;
}


if self.x + BALL_SIZE <= 1 + BALL_SIZE {
self.x = SCREEN_WIDTH / 2 - BALL_SIZE / 2;
self.y = SCREEN_HEIGHT / 2 - BALL_SIZE / 2;
self.dx = 1;
self.dy = 1;
}

if self.x >= SCREEN_WIDTH - BALL_SIZE - 1 {
self.x = SCREEN_WIDTH / 2 - BALL_SIZE / 2;
self.y = SCREEN_HEIGHT / 2 - BALL_SIZE / 2;
self.dx = -1;
self.dy = 1;
}
self.x = (self.x as i16 + self.dx) as u16;
self.y = (self.y as i16 + self.dy) as u16;
if self.x + BALL_SIZE <= 1 + BALL_SIZE {
self.x = SCREEN_WIDTH / 2 - BALL_SIZE / 2;
self.y = SCREEN_HEIGHT / 2 - BALL_SIZE / 2;
self.dx = 1;
self.dy = 1;
}

if self.x >= SCREEN_WIDTH - BALL_SIZE - 1 {
self.x = SCREEN_WIDTH / 2 - BALL_SIZE / 2;
self.y = SCREEN_HEIGHT / 2 - BALL_SIZE / 2;
self.dx = -1;
self.dy = 1;
}
self.x = (self.x as i16 + self.dx) as u16;
self.y = (self.y as i16 + self.dy) as u16;
}
}

static SPRITE_POSITIONS: [GbaCell<u16>; 6] = [
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
GbaCell::new(0),
];

#[panic_handler]
Expand All @@ -110,50 +106,71 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {

#[no_mangle]
fn main() -> ! {
DISPCNT.write(
DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
);

RUST_IRQ_HANDLER.write(Some(draw_sprites));
DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
IE.write(IrqBits::VBLANK);
IME.write(true);

let mut left_paddle = Paddle::new(10, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
let mut right_paddle = Paddle::new(SCREEN_WIDTH as u16 - 10 - PADDLE_WIDTH, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
let mut ball = Ball::new(SCREEN_WIDTH as u16 / 2, SCREEN_HEIGHT as u16 / 2);

loop {
left_paddle.update();
right_paddle.update();
ball.update(&left_paddle, &right_paddle);

SPRITE_POSITIONS[0].write(left_paddle.x);
SPRITE_POSITIONS[1].write(left_paddle.y);
SPRITE_POSITIONS[2].write(right_paddle.x);
SPRITE_POSITIONS[3].write(right_paddle.y);
SPRITE_POSITIONS[4].write(ball.x);
SPRITE_POSITIONS[5].write(ball.y);

VBlankIntrWait();
}
DISPCNT.write(
DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
);

RUST_IRQ_HANDLER.write(Some(draw_sprites));
DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
IE.write(IrqBits::VBLANK);
IME.write(true);

let mut left_paddle =
Paddle::new(10, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
let mut right_paddle = Paddle::new(
SCREEN_WIDTH as u16 - 10 - PADDLE_WIDTH,
SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2,
);
let mut ball = Ball::new(SCREEN_WIDTH as u16 / 2, SCREEN_HEIGHT as u16 / 2);

loop {
left_paddle.update();
right_paddle.update();
ball.update(&left_paddle, &right_paddle);

SPRITE_POSITIONS[0].write(left_paddle.x);
SPRITE_POSITIONS[1].write(left_paddle.y);
SPRITE_POSITIONS[2].write(right_paddle.x);
SPRITE_POSITIONS[3].write(right_paddle.y);
SPRITE_POSITIONS[4].write(ball.x);
SPRITE_POSITIONS[5].write(ball.y);

VBlankIntrWait();
}
}

#[link_section = ".iwram.draw_sprites"]
extern "C" fn draw_sprites(_bits: IrqBits) {
unsafe {
let p = VIDEO3_VRAM.as_usize() as *mut u8;
__aeabi_memset(p, 240*160*2, 0)
}

draw_rect(SPRITE_POSITIONS[0].read(), SPRITE_POSITIONS[1].read(), PADDLE_WIDTH, PADDLE_HEIGHT, Color::WHITE);
draw_rect(SPRITE_POSITIONS[2].read(), SPRITE_POSITIONS[3].read(), PADDLE_WIDTH, PADDLE_HEIGHT, Color::WHITE);
draw_rect(SPRITE_POSITIONS[4].read(), SPRITE_POSITIONS[5].read(), BALL_SIZE, BALL_SIZE, Color::WHITE);
video3_clear_to(Color::BLACK);

draw_rect(
SPRITE_POSITIONS[0].read(),
SPRITE_POSITIONS[1].read(),
PADDLE_WIDTH,
PADDLE_HEIGHT,
Color::WHITE,
);
draw_rect(
SPRITE_POSITIONS[2].read(),
SPRITE_POSITIONS[3].read(),
PADDLE_WIDTH,
PADDLE_HEIGHT,
Color::WHITE,
);
draw_rect(
SPRITE_POSITIONS[4].read(),
SPRITE_POSITIONS[5].read(),
BALL_SIZE,
BALL_SIZE,
Color::WHITE,
);
}

#[link_section = ".iwram.draw_rect"]
fn draw_rect(x: u16, y: u16, width: u16, height: u16, color: Color) {
for i in 0..width {
for j in 0..height {
VIDEO3_VRAM.index((x + i) as usize, (y + j) as usize).write(color);
}
for i in 0..width {
for j in 0..height {
VIDEO3_VRAM.index((x + i) as usize, (y + j) as usize).write(color);
}
}
}
15 changes: 4 additions & 11 deletions examples/video3_test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![no_std]
#![no_main]

use gba::{mem_fns::__aeabi_memcpy, prelude::*};
use gba::prelude::*;

#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
Expand All @@ -15,21 +15,14 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {

#[no_mangle]
fn main() -> ! {
let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
unsafe {
__aeabi_memcpy(
a as _,
PIXELS.as_ptr().cast(),
core::mem::size_of_val(PIXELS) as _,
)
};
video3_set_bitmap(&BITMAP);
DISPCNT.write(
DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
);
loop {}
}

pub const PIXELS: &[u16] = &[
pub static BITMAP: Video3Bitmap = Video3Bitmap::new_from_u16([
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
Expand Down Expand Up @@ -4297,4 +4290,4 @@ pub const PIXELS: &[u16] = &[
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE, 0x77DE,
];
]);
Loading

0 comments on commit fa14304

Please sign in to comment.