From 16ff9b8ec11cb81acbc623e960514a0d2e514221 Mon Sep 17 00:00:00 2001 From: Corwin Date: Tue, 15 Feb 2022 21:32:51 +0000 Subject: [PATCH] types for nice sprite import and usage --- agb/Cargo.lock | 134 ++++++++++++++++++++++++++++++++++++++ agb/Cargo.toml | 1 + agb/src/display/object.rs | 98 ++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) diff --git a/agb/Cargo.lock b/agb/Cargo.lock index bd85fdac..3ba21947 100644 --- a/agb/Cargo.lock +++ b/agb/Cargo.lock @@ -26,6 +26,8 @@ dependencies = [ "bitflags", "hashbrown", "modular-bitfield", + "phf", + "rustc-hash", ] [[package]] @@ -43,6 +45,7 @@ dependencies = [ "proc-macro2", "quote", "serde", + "serde_json", "syn", "toml", ] @@ -178,6 +181,12 @@ dependencies = [ "png", ] +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "libc" version = "0.2.119" @@ -261,6 +270,50 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "png" version = "0.17.5" @@ -273,6 +326,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.36" @@ -291,6 +356,58 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + [[package]] name = "serde" version = "1.0.136" @@ -311,6 +428,23 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/agb/Cargo.toml b/agb/Cargo.toml index ad0ece1a..8821c6e4 100644 --- a/agb/Cargo.toml +++ b/agb/Cargo.toml @@ -29,6 +29,7 @@ bare-metal = "1.0" hashbrown = "0.12.0" modular-bitfield = "0.11.2" rustc-hash = { version = "1.0", default-features = false } +phf = { version = "0.10", default-features = false, features = ["macros"] } [package.metadata.docs.rs] default-target = "thumbv6m-none-eabi" diff --git a/agb/src/display/object.rs b/agb/src/display/object.rs index 5be201cd..35a1bce4 100644 --- a/agb/src/display/object.rs +++ b/agb/src/display/object.rs @@ -2,7 +2,9 @@ use alloc::vec::Vec; use core::alloc::Layout; use core::cell::RefCell; use core::hash::BuildHasherDefault; +use core::ops::Deref; use core::ptr::NonNull; +use core::slice; use modular_bitfield::prelude::{B10, B2, B3, B4, B5, B8, B9}; use modular_bitfield::{bitfield, BitfieldSpecifier}; use rustc_hash::FxHasher; @@ -62,6 +64,77 @@ pub enum Size { S32x64 = 0b10_11, } + +pub struct TagMap(phf::Map<&'static str, Tag>); + +impl TagMap { + pub const fn new(map: phf::Map<&'static str, Tag>) -> Self { + Self(map) + } +} + +impl Deref for TagMap { + type Target = phf::Map<&'static str, Tag>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Clone, Copy)] +enum Direction { + Forward, + Backward, + Pingpong, +} + +impl Direction { + const fn from_usize(a: usize) -> Self { + match a { + 0 => Direction::Forward, + 1 => Direction::Backward, + 2 => Direction::Pingpong, + _ => panic!("Invalid direction, this is a bug in image converter or agb"), + } + } +} + +pub struct Tag { + sprites: *const Sprite, + len: usize, + direction: Direction, +} + +impl Tag { + pub fn get_sprites(&self) -> &'static [Sprite] { + unsafe { slice::from_raw_parts(self.sprites, self.len) } + } + + pub fn get_sprite(&self, idx: usize) -> &'static Sprite { + &self.get_sprites()[idx] + } + + pub fn get_animation_sprite(&self, idx: usize) -> &'static Sprite { + let len_sub_1 = self.len - 1; + match self.direction { + Direction::Forward => self.get_sprite(idx % self.len), + Direction::Backward => self.get_sprite(len_sub_1 - (idx % self.len)), + Direction::Pingpong => self.get_sprite( + (((idx + len_sub_1) % (len_sub_1 * 2)) as isize - len_sub_1 as isize).abs() + as usize, + ), + } + } + + pub const fn new(sprites: &'static [Sprite], from: usize, to: usize, direction: usize) -> Self { + assert!(from <= to); + Self { + sprites: &sprites[from] as *const Sprite, + len: to - from + 1, + direction: Direction::from_usize(direction), + } + } +} + impl Size { const fn number_of_tiles(self) -> usize { match self { @@ -82,6 +155,24 @@ impl Size { const fn shape_size(self) -> (u8, u8) { (self as u8 >> 2, self as u8 & 0b11) } + + pub const fn from_width_height(width: usize, height: usize) -> Self { + match (width, height) { + (8, 8) => Size::S8x8, + (16, 16) => Size::S16x16, + (32, 32) => Size::S32x32, + (64, 64) => Size::S64x64, + (16, 8) => Size::S16x8, + (32, 8) => Size::S32x8, + (32, 16) => Size::S32x16, + (64, 32) => Size::S64x32, + (8, 16) => Size::S8x16, + (8, 32) => Size::S8x32, + (16, 32) => Size::S16x32, + (32, 64) => Size::S32x64, + (_, _) => panic!("Bad width and height!"), + } + } } pub struct SpriteBorrow<'a> { @@ -328,6 +419,13 @@ impl Sprite { fn layout(&self) -> Layout { Layout::from_size_align(self.size.number_of_tiles() * BYTES_PER_TILE_4BPP, 8).unwrap() } + pub const fn new(palette: &'static Palette16, data: &'static [u8], size: Size) -> Self { + Self { + palette, + data, + size, + } + } } impl SpriteController {