mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 19:01:30 +11:00
Merge branch 'main' of https://github.com/rust-console/gba into main
This commit is contained in:
commit
f200c84ff6
|
@ -5,8 +5,9 @@ use gba::prelude::*;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||||
use core::fmt::Write;
|
#[cfg(debug_assertions)]
|
||||||
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
||||||
|
use core::fmt::Write;
|
||||||
writeln!(logger, "{info}").ok();
|
writeln!(logger, "{info}").ok();
|
||||||
}
|
}
|
||||||
loop {}
|
loop {}
|
||||||
|
@ -25,7 +26,7 @@ struct Rect {
|
||||||
h: u16,
|
h: u16,
|
||||||
}
|
}
|
||||||
impl Rect {
|
impl Rect {
|
||||||
pub fn intersect(self, other: Self) -> bool {
|
fn intersect(self, other: Self) -> bool {
|
||||||
self.x < other.x + other.w
|
self.x < other.x + other.w
|
||||||
&& self.x + self.w > other.x
|
&& self.x + self.w > other.x
|
||||||
&& self.y < other.y + other.h
|
&& self.y < other.y + other.h
|
||||||
|
@ -50,7 +51,7 @@ extern "C" fn main() -> ! {
|
||||||
creatures[0].x = 11;
|
creatures[0].x = 11;
|
||||||
creatures[0].y = 14;
|
creatures[0].y = 14;
|
||||||
//
|
//
|
||||||
creatures[1].x = 41;
|
creatures[1].x = 44;
|
||||||
creatures[1].y = 38;
|
creatures[1].y = 38;
|
||||||
creatures[2].x = 100;
|
creatures[2].x = 100;
|
||||||
creatures[2].y = 23;
|
creatures[2].y = 23;
|
||||||
|
@ -61,11 +62,16 @@ extern "C" fn main() -> ! {
|
||||||
|
|
||||||
let mut world = [[0_u8; 32]; 32];
|
let mut world = [[0_u8; 32]; 32];
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
world[0][i] = b'z';
|
world[0][i] = Cga8x8Thick::BOX_HORIZONTAL;
|
||||||
world[31][i] = b'z';
|
world[19][i] = Cga8x8Thick::BOX_HORIZONTAL;
|
||||||
world[i][0] = b'z';
|
world[i][0] = Cga8x8Thick::BOX_VERTICAL;
|
||||||
world[i][31] = b'z';
|
world[i][29] = Cga8x8Thick::BOX_VERTICAL;
|
||||||
}
|
}
|
||||||
|
world[0][0] = Cga8x8Thick::BOX_UPPER_LEFT;
|
||||||
|
world[0][29] = Cga8x8Thick::BOX_UPPER_RIGHT;
|
||||||
|
world[19][0] = Cga8x8Thick::BOX_LOWER_LEFT;
|
||||||
|
world[19][29] = Cga8x8Thick::BOX_LOWER_RIGHT;
|
||||||
|
//
|
||||||
world[1][3] = b'B';
|
world[1][3] = b'B';
|
||||||
world[2][3] = b'G';
|
world[2][3] = b'G';
|
||||||
world[3][3] = b'0';
|
world[3][3] = b'0';
|
||||||
|
@ -77,12 +83,14 @@ extern "C" fn main() -> ! {
|
||||||
|
|
||||||
TIMER0_CONTROL.write(TimerControl::new().with_enabled(true));
|
TIMER0_CONTROL.write(TimerControl::new().with_enabled(true));
|
||||||
|
|
||||||
|
// bg
|
||||||
BG_PALETTE.index(1).write(Color::MAGENTA);
|
BG_PALETTE.index(1).write(Color::MAGENTA);
|
||||||
OBJ_PALETTE.index(1).write(Color::CYAN);
|
// obj
|
||||||
OBJ_PALETTE.index(16 * 1 + 1).write(Color::GREEN);
|
let colors =
|
||||||
OBJ_PALETTE.index(16 * 2 + 1).write(Color::RED);
|
[Color::CYAN, Color::GREEN, Color::RED, Color::BLUE, Color::YELLOW];
|
||||||
OBJ_PALETTE.index(16 * 3 + 1).write(Color::BLUE);
|
for (pal, color) in colors.iter().enumerate() {
|
||||||
OBJ_PALETTE.index(16 * 4 + 1).write(Color::YELLOW);
|
obj_palbank(pal).index(1).write(*color);
|
||||||
|
}
|
||||||
|
|
||||||
Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
|
Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
|
||||||
Cga8x8Thick.bitunpack_4bpp(OBJ_TILES.as_region(), 0);
|
Cga8x8Thick.bitunpack_4bpp(OBJ_TILES.as_region(), 0);
|
||||||
|
@ -141,56 +149,56 @@ extern "C" fn main() -> ! {
|
||||||
if keys.up() {
|
if keys.up() {
|
||||||
let new_p = Position { x: player.x, y: player.y - 1 };
|
let new_p = Position { x: player.x, y: player.y - 1 };
|
||||||
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
||||||
if new_r
|
let terrain_clear = new_r
|
||||||
.iter_tiles()
|
.iter_tiles()
|
||||||
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]))
|
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
|
||||||
&& enemies.iter().all(|enemy| {
|
let enemy_clear = enemies.iter().all(|enemy| {
|
||||||
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
||||||
!new_r.intersect(enemy_r)
|
!new_r.intersect(enemy_r)
|
||||||
})
|
});
|
||||||
{
|
if terrain_clear && enemy_clear {
|
||||||
*player = new_p;
|
*player = new_p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if keys.down() {
|
if keys.down() {
|
||||||
let new_p = Position { x: player.x, y: player.y + 1 };
|
let new_p = Position { x: player.x, y: player.y + 1 };
|
||||||
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
||||||
if new_r
|
let terrain_clear = new_r
|
||||||
.iter_tiles()
|
.iter_tiles()
|
||||||
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]))
|
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
|
||||||
&& enemies.iter().all(|enemy| {
|
let enemy_clear = enemies.iter().all(|enemy| {
|
||||||
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
||||||
!new_r.intersect(enemy_r)
|
!new_r.intersect(enemy_r)
|
||||||
})
|
});
|
||||||
{
|
if terrain_clear && enemy_clear {
|
||||||
*player = new_p;
|
*player = new_p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if keys.left() {
|
if keys.left() {
|
||||||
let new_p = Position { x: player.x - 1, y: player.y };
|
let new_p = Position { x: player.x - 1, y: player.y };
|
||||||
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
||||||
if new_r
|
let terrain_clear = new_r
|
||||||
.iter_tiles()
|
.iter_tiles()
|
||||||
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]))
|
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
|
||||||
&& enemies.iter().all(|enemy| {
|
let enemy_clear = enemies.iter().all(|enemy| {
|
||||||
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
||||||
!new_r.intersect(enemy_r)
|
!new_r.intersect(enemy_r)
|
||||||
})
|
});
|
||||||
{
|
if terrain_clear && enemy_clear {
|
||||||
*player = new_p;
|
*player = new_p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if keys.right() {
|
if keys.right() {
|
||||||
let new_p = Position { x: player.x + 1, y: player.y };
|
let new_p = Position { x: player.x + 1, y: player.y };
|
||||||
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
|
||||||
if new_r
|
let terrain_clear = new_r
|
||||||
.iter_tiles()
|
.iter_tiles()
|
||||||
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]))
|
.all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
|
||||||
&& enemies.iter().all(|enemy| {
|
let enemy_clear = enemies.iter().all(|enemy| {
|
||||||
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
|
||||||
!new_r.intersect(enemy_r)
|
!new_r.intersect(enemy_r)
|
||||||
})
|
});
|
||||||
{
|
if terrain_clear && enemy_clear {
|
||||||
*player = new_p;
|
*player = new_p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use gba::prelude::*;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
||||||
writeln!(logger, "{info}").ok();
|
writeln!(logger, "{info}").ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,107 @@ use crate::{
|
||||||
video::{Tile4, Tile8},
|
video::{Tile4, Tile8},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
macro_rules! glyph {
|
||||||
|
($name:ident = $id:expr) => {
|
||||||
|
pub const $name: u8 = $id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Cga8x8Thick;
|
||||||
|
|
||||||
|
impl Cga8x8Thick {
|
||||||
|
// 0x0?
|
||||||
|
glyph!(NULL = 0x00);
|
||||||
|
glyph!(FACE = 0x01);
|
||||||
|
glyph!(FACE_INVERSE = 0x02);
|
||||||
|
glyph!(HEART = 0x03);
|
||||||
|
glyph!(DIAMOND = 0x04);
|
||||||
|
glyph!(CLUB = 0x05);
|
||||||
|
glyph!(SPADE = 0x06);
|
||||||
|
glyph!(BULLET = 0x07);
|
||||||
|
glyph!(BULLET_INVERSE = 0x08);
|
||||||
|
glyph!(CIRCLE = 0x09);
|
||||||
|
glyph!(CIRCLE_INVERSE = 0x0A);
|
||||||
|
glyph!(MALE = 0x0B);
|
||||||
|
glyph!(FEMALE = 0x0C);
|
||||||
|
glyph!(NOTE = 0x0D);
|
||||||
|
glyph!(NOTE_DOUBLE = 0x0E);
|
||||||
|
glyph!(SOLAR = 0x0F);
|
||||||
|
|
||||||
|
// 0x1?
|
||||||
|
glyph!(POINTER_RIGHT = 0x10);
|
||||||
|
glyph!(POINTER_LEFT = 0x11);
|
||||||
|
glyph!(ARROW_UP_DOWN = 0x12);
|
||||||
|
glyph!(BANG_DOUBLE = 0x13);
|
||||||
|
glyph!(PARAGRAPH = 0x14);
|
||||||
|
glyph!(SECTION = 0x15);
|
||||||
|
glyph!(UNDERLINE_THICK = 0x16);
|
||||||
|
glyph!(ARROW_UP_DOWN_UNDERLINED = 0x17);
|
||||||
|
glyph!(ARROW_UP = 0x18);
|
||||||
|
glyph!(ARROW_DOWN = 0x19);
|
||||||
|
glyph!(ARROW_RIGHT = 0x1A);
|
||||||
|
glyph!(ARROW_LEFT = 0x1B);
|
||||||
|
glyph!(RIGHT_ANGLE = 0x1C);
|
||||||
|
glyph!(ARROW_LEFT_RIGHT = 0x1D);
|
||||||
|
glyph!(POINTER_UP = 0x1E);
|
||||||
|
glyph!(POINTER_DOWN = 0x1F);
|
||||||
|
|
||||||
|
// Box drawing
|
||||||
|
glyph!(BOX_VERTICAL = 0xB3);
|
||||||
|
glyph!(BOX_HORIZONTAL = 0xC4);
|
||||||
|
glyph!(BOX_UPPER_RIGHT = 0xBF);
|
||||||
|
glyph!(BOX_UPPER_LEFT = 0xDA);
|
||||||
|
glyph!(BOX_LOWER_RIGHT = 0xD9);
|
||||||
|
glyph!(BOX_LOWER_LEFT = 0xC0);
|
||||||
|
|
||||||
|
/// Bit unpacks the data (4bpp depth) to the location given.
|
||||||
|
///
|
||||||
|
/// * `offset_and_touch_zero`: Works like the [`BitUnpackInfo`] field. By
|
||||||
|
/// default you should usually pass 0 here.
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
/// * Requires at least 256 elements of space within the region.
|
||||||
|
#[inline]
|
||||||
|
pub fn bitunpack_4bpp(
|
||||||
|
self, b: VolRegion<Tile4, Safe, Safe>, offset_and_touch_zero: u32,
|
||||||
|
) {
|
||||||
|
assert!(b.len() >= 256);
|
||||||
|
let src = CGA_8X8_THICK.as_ptr();
|
||||||
|
let dest = b.index(0).as_usize() as *mut u32;
|
||||||
|
let info = BitUnpackInfo {
|
||||||
|
src_byte_len: size_of_val(&CGA_8X8_THICK) as u16,
|
||||||
|
src_elem_width: 1,
|
||||||
|
dest_elem_width: 4,
|
||||||
|
offset_and_touch_zero,
|
||||||
|
};
|
||||||
|
unsafe { BitUnPack(src.cast(), dest, &info) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bit unpacks the data (8bpp depth) to the location given.
|
||||||
|
///
|
||||||
|
/// * `offset_and_touch_zero`: Works like the [`BitUnpackInfo`] field. By
|
||||||
|
/// default you should usually pass 0 here.
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
/// * Requires at least 256 elements of space within the region.
|
||||||
|
#[inline]
|
||||||
|
pub fn bitunpack_8bpp(
|
||||||
|
self, b: VolRegion<Tile8, Safe, Safe>, offset_and_touch_zero: u32,
|
||||||
|
) {
|
||||||
|
assert!(b.len() >= 256);
|
||||||
|
let src = CGA_8X8_THICK.as_ptr();
|
||||||
|
let dest = b.index(0).as_usize() as *mut u32;
|
||||||
|
let info = BitUnpackInfo {
|
||||||
|
src_byte_len: size_of_val(&CGA_8X8_THICK) as u16,
|
||||||
|
src_elem_width: 1,
|
||||||
|
dest_elem_width: 8,
|
||||||
|
offset_and_touch_zero,
|
||||||
|
};
|
||||||
|
unsafe { BitUnPack(src.cast(), dest, &info) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The CGA [Code Page 437][cp437] type face, with thick lines.
|
/// The CGA [Code Page 437][cp437] type face, with thick lines.
|
||||||
///
|
///
|
||||||
/// There's 256 tiles, packed down to 1bpp.
|
/// There's 256 tiles, packed down to 1bpp.
|
||||||
|
@ -126,105 +227,3 @@ pub static CGA_8X8_THICK: [u32; 512] = [
|
||||||
0x3636361E, 0x00000036, 0x060C180E, 0x0000001E, 0x3C3C0000, 0x00003C3C,
|
0x3636361E, 0x00000036, 0x060C180E, 0x0000001E, 0x3C3C0000, 0x00003C3C,
|
||||||
0x00000000, 0x00000000,
|
0x00000000, 0x00000000,
|
||||||
];
|
];
|
||||||
|
|
||||||
macro_rules! glyph_name {
|
|
||||||
($name:ident = $x:expr) => {
|
|
||||||
pub const $name: u8 = $x;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Cga8x8Thick;
|
|
||||||
impl Cga8x8Thick {
|
|
||||||
// 0x0? series
|
|
||||||
glyph_name!(NULL = 0x00);
|
|
||||||
glyph_name!(SMILEY = 0x01);
|
|
||||||
glyph_name!(SMILEY_INVERSE = 0x02);
|
|
||||||
glyph_name!(HEART = 0x03);
|
|
||||||
glyph_name!(DIAMOND = 0x04);
|
|
||||||
glyph_name!(CLUB = 0x05);
|
|
||||||
glyph_name!(SPADE = 0x06);
|
|
||||||
glyph_name!(BULLET = 0x07);
|
|
||||||
glyph_name!(BULLET_INVERSE = 0x08);
|
|
||||||
glyph_name!(BULLET_BIG = 0x09);
|
|
||||||
glyph_name!(BULLET_INVERSE_BIG = 0x0A);
|
|
||||||
glyph_name!(MALE = 0x0B);
|
|
||||||
glyph_name!(FEMALE = 0x0C);
|
|
||||||
glyph_name!(NOTE = 0x0D);
|
|
||||||
glyph_name!(DOUBLE_NOTE = 0x0E);
|
|
||||||
glyph_name!(SOLAR = 0x0F);
|
|
||||||
// 0x1? series
|
|
||||||
glyph_name!(POINTER_RIGHT = 0x10);
|
|
||||||
glyph_name!(POINTER_LEFT = 0x11);
|
|
||||||
glyph_name!(ARROW_UP_DOWN = 0x12);
|
|
||||||
glyph_name!(DOUBLE_BANG = 0x13);
|
|
||||||
glyph_name!(PARAGRAPH = 0x14);
|
|
||||||
glyph_name!(SECTION = 0x15);
|
|
||||||
glyph_name!(UNDERLINE_THICK = 0x16);
|
|
||||||
glyph_name!(ARROW_UP_DOWN_UNDERLINED = 0x17);
|
|
||||||
glyph_name!(ARROW_UP = 0x18);
|
|
||||||
glyph_name!(ARROW_DOWN = 0x19);
|
|
||||||
glyph_name!(ARROW_RIGHT = 0x1A);
|
|
||||||
glyph_name!(ARROW_LEFT = 0x1B);
|
|
||||||
glyph_name!(RIGHT_ANGLE = 0x1C);
|
|
||||||
glyph_name!(ARROW_LEFT_RIGHT = 0x1D);
|
|
||||||
glyph_name!(POINTER_UP = 0x1E);
|
|
||||||
glyph_name!(POINTER_DOWN = 0x1F);
|
|
||||||
// 0x7? series
|
|
||||||
glyph_name!(HOUSE = 0x7F);
|
|
||||||
//
|
|
||||||
glyph_name!(BOX_LIGHT_HORIZONTAL = 0xC4);
|
|
||||||
glyph_name!(BOX_LIGHT_VERTICAL = 0xB3);
|
|
||||||
glyph_name!(BOX_LIGHT_UPPER_LEFT = 0xDA);
|
|
||||||
glyph_name!(BOX_LIGHT_UPPER_RIGHT = 0xBF);
|
|
||||||
glyph_name!(BOX_LIGHT_LOWER_LEFT = 0xC0);
|
|
||||||
glyph_name!(BOX_LIGHT_LOWER_RIGHT = 0xD9);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Cga8x8Thick {
|
|
||||||
/// Bit unpacks the data (4bpp depth) to the location given.
|
|
||||||
///
|
|
||||||
/// * `offset_and_touch_zero`: Works like the [`BitUnpackInfo`] field. By
|
|
||||||
/// default you should usually pass 0 here.
|
|
||||||
///
|
|
||||||
/// ## Panics
|
|
||||||
/// * Requires at least 256 elements of space within the region.
|
|
||||||
#[inline]
|
|
||||||
pub fn bitunpack_4bpp(
|
|
||||||
self, b: VolRegion<Tile4, Safe, Safe>, offset_and_touch_zero: u32,
|
|
||||||
) {
|
|
||||||
assert!(b.len() >= 256);
|
|
||||||
let src = CGA_8X8_THICK.as_ptr();
|
|
||||||
let dest = b.index(0).as_usize() as *mut u32;
|
|
||||||
let info = BitUnpackInfo {
|
|
||||||
src_byte_len: size_of_val(&CGA_8X8_THICK) as u16,
|
|
||||||
src_elem_width: 1,
|
|
||||||
dest_elem_width: 4,
|
|
||||||
offset_and_touch_zero,
|
|
||||||
};
|
|
||||||
unsafe { BitUnPack(src.cast(), dest, &info) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bit unpacks the data (8bpp depth) to the location given.
|
|
||||||
///
|
|
||||||
/// * `offset_and_touch_zero`: Works like the [`BitUnpackInfo`] field. By
|
|
||||||
/// default you should usually pass 0 here.
|
|
||||||
///
|
|
||||||
/// ## Panics
|
|
||||||
/// * Requires at least 256 elements of space within the region.
|
|
||||||
#[inline]
|
|
||||||
pub fn bitunpack_8bpp(
|
|
||||||
self, b: VolRegion<Tile8, Safe, Safe>, offset_and_touch_zero: u32,
|
|
||||||
) {
|
|
||||||
assert!(b.len() >= 256);
|
|
||||||
let src = CGA_8X8_THICK.as_ptr();
|
|
||||||
let dest = b.index(0).as_usize() as *mut u32;
|
|
||||||
let info = BitUnpackInfo {
|
|
||||||
src_byte_len: size_of_val(&CGA_8X8_THICK) as u16,
|
|
||||||
src_elem_width: 1,
|
|
||||||
dest_elem_width: 8,
|
|
||||||
offset_and_touch_zero,
|
|
||||||
};
|
|
||||||
unsafe { BitUnPack(src.cast(), dest, &info) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
15
src/mmio.rs
15
src/mmio.rs
|
@ -201,6 +201,21 @@ def_mmio!(0x0500_0000 = BACKDROP_COLOR: VolAddress<Color, Safe, Safe>; "Color th
|
||||||
def_mmio!(0x0500_0000 = BG_PALETTE: VolBlock<Color, Safe, Safe, 256>; "Background tile palette entries.");
|
def_mmio!(0x0500_0000 = BG_PALETTE: VolBlock<Color, Safe, Safe, 256>; "Background tile palette entries.");
|
||||||
def_mmio!(0x0500_0200 = OBJ_PALETTE: VolBlock<Color, Safe, Safe, 256>; "Object tile palette entries.");
|
def_mmio!(0x0500_0200 = OBJ_PALETTE: VolBlock<Color, Safe, Safe, 256>; "Object tile palette entries.");
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
#[cfg_attr(feature="track_caller", track_caller)]
|
||||||
|
pub const fn bg_palbank(bank: usize) -> VolBlock<Color, Safe, Safe, 16> {
|
||||||
|
let u = BG_PALETTE.index(bank * 16).as_usize();
|
||||||
|
unsafe { VolBlock::new(u) }
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
#[cfg_attr(feature="track_caller", track_caller)]
|
||||||
|
pub const fn obj_palbank(bank: usize) -> VolBlock<Color, Safe, Safe, 16> {
|
||||||
|
let u = OBJ_PALETTE.index(bank * 16).as_usize();
|
||||||
|
unsafe { VolBlock::new(u) }
|
||||||
|
}
|
||||||
|
|
||||||
// Video RAM (VRAM)
|
// Video RAM (VRAM)
|
||||||
|
|
||||||
/// The VRAM byte offset per screenblock index.
|
/// The VRAM byte offset per screenblock index.
|
||||||
|
|
Loading…
Reference in a new issue