mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 08:41:34 +11:00
add some sprite allocation
This commit is contained in:
parent
93d994360e
commit
6a2c9d8826
|
@ -1,7 +1,11 @@
|
||||||
|
use core::alloc::Layout;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
use hashbrown::{hash_map::Entry, HashMap};
|
use hashbrown::{hash_map::Entry, HashMap};
|
||||||
|
|
||||||
|
const BYTES_PER_TILE_4BPP: usize = 32;
|
||||||
|
|
||||||
use super::palette16::Palette16;
|
use super::palette16::Palette16;
|
||||||
use super::{palette16, Priority, DISPLAY_CONTROL};
|
use super::{palette16, Priority, DISPLAY_CONTROL};
|
||||||
use crate::agb_alloc::block_allocator::BlockAllocator;
|
use crate::agb_alloc::block_allocator::BlockAllocator;
|
||||||
|
@ -27,6 +31,45 @@ const TILE_SPRITE: MemoryMapped1DArray<u32, { 1024 * 8 }> =
|
||||||
pub struct Sprite {
|
pub struct Sprite {
|
||||||
palette: &'static Palette16,
|
palette: &'static Palette16,
|
||||||
data: &'static [u8],
|
data: &'static [u8],
|
||||||
|
size: Size,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Size {
|
||||||
|
// stored as attr0 attr1
|
||||||
|
S8x8 = 0b00_00,
|
||||||
|
S16x16 = 0b00_01,
|
||||||
|
S32x32 = 0b00_10,
|
||||||
|
S64x64 = 0b00_11,
|
||||||
|
|
||||||
|
S16x8 = 0b01_00,
|
||||||
|
S32x8 = 0b01_01,
|
||||||
|
S32x16 = 0b01_10,
|
||||||
|
S64x32 = 0b01_11,
|
||||||
|
|
||||||
|
S8x16 = 0b10_00,
|
||||||
|
S8x32 = 0b10_01,
|
||||||
|
S16x32 = 0b10_10,
|
||||||
|
S32x64 = 0b10_11,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Size {
|
||||||
|
fn number_of_tiles(self) -> usize {
|
||||||
|
match self {
|
||||||
|
S8x8 => 1,
|
||||||
|
S16x16 => 4,
|
||||||
|
S32x32 => 16,
|
||||||
|
S64x64 => 64,
|
||||||
|
S16x8 => 2,
|
||||||
|
S32x8 => 4,
|
||||||
|
S32x16 => 8,
|
||||||
|
S64x32 => 32,
|
||||||
|
S8x16 => 2,
|
||||||
|
S8x32 => 4,
|
||||||
|
S16x32 => 8,
|
||||||
|
S32x64 => 32,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SpriteBorrow<'a> {
|
struct SpriteBorrow<'a> {
|
||||||
|
@ -39,6 +82,15 @@ struct Storage {
|
||||||
count: u16,
|
count: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storage {
|
||||||
|
fn from_ptr(d: NonNull<u8>) -> Self {
|
||||||
|
Self {
|
||||||
|
location: (((d.as_ptr() as usize) - 0x06010000) / BYTES_PER_TILE_4BPP) as u16,
|
||||||
|
count: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Object<'a> {
|
pub struct Object<'a> {
|
||||||
sprite: SpriteBorrow<'a>,
|
sprite: SpriteBorrow<'a>,
|
||||||
}
|
}
|
||||||
|
@ -59,6 +111,15 @@ pub struct ObjectController {}
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
struct SpriteId(usize);
|
struct SpriteId(usize);
|
||||||
|
|
||||||
|
impl SpriteId {
|
||||||
|
fn get_sprite(self) -> &'static Sprite {
|
||||||
|
// # Safety
|
||||||
|
// This must be constructed using the get_id of a sprite, so
|
||||||
|
// they are always valid and always static
|
||||||
|
unsafe { (self.0 as *const Sprite).as_ref().unwrap_unchecked() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The palette id is a thin wrapper around the pointer to the palette in rom
|
/// The palette id is a thin wrapper around the pointer to the palette in rom
|
||||||
/// and is therefore a unique reference to a palette
|
/// and is therefore a unique reference to a palette
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -68,6 +129,9 @@ impl Sprite {
|
||||||
fn get_id(&'static self) -> SpriteId {
|
fn get_id(&'static self) -> SpriteId {
|
||||||
SpriteId(self as *const _ as usize)
|
SpriteId(self as *const _ as usize)
|
||||||
}
|
}
|
||||||
|
const fn layout(&self) -> Layout {
|
||||||
|
Layout::from_size_align(self.size.number_of_tiles() * BYTES_PER_TILE_4BPP, 8).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpriteController {
|
impl SpriteController {
|
||||||
|
@ -81,8 +145,18 @@ impl SpriteController {
|
||||||
controller: &self.inner,
|
controller: &self.inner,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// allocate a new sprite
|
// layout is non zero sized, so this is safe to call
|
||||||
|
|
||||||
|
let dest = unsafe { SPRITE_ALLOCATOR.alloc(sprite.layout())? };
|
||||||
|
inner.sprite.insert(id, Storage::from_ptr(dest));
|
||||||
|
|
||||||
|
// need to consider palette
|
||||||
todo!();
|
todo!();
|
||||||
|
|
||||||
|
Some(SpriteBorrow {
|
||||||
|
id,
|
||||||
|
controller: &self.inner,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue