mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 08:41:34 +11:00
hopefully enough to actually maybe display something?
This commit is contained in:
parent
5ea6eb0f1d
commit
effaac3885
|
@ -1,13 +1,18 @@
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::memory_mapped::MemoryMapped1DArray;
|
use crate::memory_mapped::{MemoryMapped, MemoryMapped1DArray};
|
||||||
|
|
||||||
|
use super::{set_graphics_mode, set_graphics_settings, DisplayMode, GraphicsSettings};
|
||||||
|
|
||||||
const TILE_BACKGROUND: MemoryMapped1DArray<u32, { 2048 * 8 }> =
|
const TILE_BACKGROUND: MemoryMapped1DArray<u32, { 2048 * 8 }> =
|
||||||
unsafe { MemoryMapped1DArray::new(0x06000000) };
|
unsafe { MemoryMapped1DArray::new(0x06000000) };
|
||||||
|
|
||||||
|
const PALETTE_BACKGROUND: MemoryMapped1DArray<u16, 256> =
|
||||||
|
unsafe { MemoryMapped1DArray::new(0x0500_0000) };
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
enum TileFormat {
|
pub enum TileFormat {
|
||||||
FourBpp,
|
FourBpp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,19 +25,19 @@ impl TileFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TileSet<'a> {
|
pub struct TileSet<'a> {
|
||||||
tiles: &'a [u8],
|
tiles: &'a [u8],
|
||||||
format: TileFormat,
|
format: TileFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
struct TileSetReference {
|
pub struct TileSetReference {
|
||||||
id: u16,
|
id: u16,
|
||||||
generation: u32,
|
generation: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Debug)]
|
||||||
struct TileIndex(u16);
|
pub struct TileIndex(u16);
|
||||||
|
|
||||||
enum ArenaStorageItem<T> {
|
enum ArenaStorageItem<T> {
|
||||||
EndOfFreeList,
|
EndOfFreeList,
|
||||||
|
@ -40,7 +45,7 @@ enum ArenaStorageItem<T> {
|
||||||
Data(T, u32),
|
Data(T, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VRamManager<'a> {
|
pub struct VRamManager<'a> {
|
||||||
tilesets: Vec<ArenaStorageItem<TileSet<'a>>>,
|
tilesets: Vec<ArenaStorageItem<TileSet<'a>>>,
|
||||||
generation: u32,
|
generation: u32,
|
||||||
free_pointer: Option<usize>,
|
free_pointer: Option<usize>,
|
||||||
|
@ -89,19 +94,16 @@ impl<'a> VRamManager<'a> {
|
||||||
self.tilesets.len() - 1
|
self.tilesets.len() - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
TileSetReference {
|
TileSetReference::new(index as u16, generation)
|
||||||
id: index as u16,
|
|
||||||
generation,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_tileset(&mut self, tile_set_ref: TileSetReference) {
|
pub fn remove_tileset(&mut self, tile_set_ref: TileSetReference) {
|
||||||
let tileset = self.tilesets[tile_set_ref.id as usize];
|
let tileset = &self.tilesets[tile_set_ref.id as usize];
|
||||||
|
|
||||||
match tileset {
|
match tileset {
|
||||||
ArenaStorageItem::Data(_, generation) => {
|
ArenaStorageItem::Data(_, generation) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generation, tile_set_ref.generation,
|
*generation, tile_set_ref.generation,
|
||||||
"Tileset generation must be the same when removing"
|
"Tileset generation must be the same when removing"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -136,10 +138,10 @@ impl<'a> VRamManager<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let tile_slice = if let ArenaStorageItem::Data(data, generation) =
|
let tile_slice = if let ArenaStorageItem::Data(data, generation) =
|
||||||
self.tilesets[tile_set_ref.id as usize]
|
&self.tilesets[tile_set_ref.id as usize]
|
||||||
{
|
{
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generation, tile_set_ref.generation,
|
*generation, tile_set_ref.generation,
|
||||||
"Stale tile data requested"
|
"Stale tile data requested"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -178,6 +180,123 @@ impl<'a> VRamManager<'a> {
|
||||||
|
|
||||||
self.vram_free_pointer = Some(index);
|
self.vram_free_pointer = Some(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copies raw palettes to the background palette without any checks.
|
||||||
|
pub fn set_background_palette_raw(&mut self, palette: &[u16]) {
|
||||||
|
for (index, &colour) in palette.iter().enumerate() {
|
||||||
|
PALETTE_BACKGROUND.set(index, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Tile(u16);
|
||||||
|
|
||||||
|
impl Tile {
|
||||||
|
pub fn new(tid: TileIndex, hflip: bool, vflip: bool, palette_id: u16) -> Self {
|
||||||
|
Self(tid.0 | ((hflip as u16) << 10) | ((vflip as u16) << 11) | (palette_id << 12))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RegularMap {
|
||||||
|
background_id: u8,
|
||||||
|
|
||||||
|
screenblock: u8,
|
||||||
|
x_scroll: u16,
|
||||||
|
y_scroll: u16,
|
||||||
|
priority: u8,
|
||||||
|
|
||||||
|
tiles: [Tile; 32 * 32],
|
||||||
|
tiles_dirty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegularMap {
|
||||||
|
fn new(background_id: u8, screenblock: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
background_id,
|
||||||
|
|
||||||
|
screenblock,
|
||||||
|
x_scroll: 0,
|
||||||
|
y_scroll: 0,
|
||||||
|
priority: 0,
|
||||||
|
|
||||||
|
tiles: [Tile(0); 32 * 32],
|
||||||
|
tiles_dirty: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_tile(&mut self, x: u16, y: u16, tile: Tile) {
|
||||||
|
self.tiles[(x + y * 32) as usize] = tile;
|
||||||
|
self.tiles_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit(&mut self) {
|
||||||
|
let new_bg_control_value = (self.priority as u16) | ((self.screenblock as u16) << 8);
|
||||||
|
|
||||||
|
self.bg_control_register().set(new_bg_control_value);
|
||||||
|
self.bg_h_offset().set(self.x_scroll);
|
||||||
|
self.bg_v_offset().set(self.y_scroll);
|
||||||
|
|
||||||
|
if !self.tiles_dirty {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let screenblock_memory = self.screenblock_memory();
|
||||||
|
for (i, tile) in self.tiles.iter().enumerate() {
|
||||||
|
screenblock_memory.set(i, tile.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bg_control_register(&self) -> MemoryMapped<u16> {
|
||||||
|
unsafe { MemoryMapped::new(0x0400_0008 + 2 * self.background_id as usize) }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bg_h_offset(&self) -> MemoryMapped<u16> {
|
||||||
|
unsafe { MemoryMapped::new(0x0400_0010 + 4 * self.background_id as usize) }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bg_v_offset(&self) -> MemoryMapped<u16> {
|
||||||
|
unsafe { MemoryMapped::new(0x0400_0012 + 4 * self.background_id as usize) }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn screenblock_memory(&self) -> MemoryMapped1DArray<u16, { 32 * 32 }> {
|
||||||
|
unsafe { MemoryMapped1DArray::new(0x0600_0000 + 0x1000 * self.screenblock as usize) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Tiled0<'a> {
|
||||||
|
num_regular: u8,
|
||||||
|
next_screenblock: u8,
|
||||||
|
|
||||||
|
pub vram: VRamManager<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tiled0<'_> {
|
||||||
|
pub(crate) unsafe fn new() -> Self {
|
||||||
|
set_graphics_settings(GraphicsSettings::empty() | GraphicsSettings::SPRITE1_D);
|
||||||
|
set_graphics_mode(DisplayMode::Tiled0);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
num_regular: 0,
|
||||||
|
next_screenblock: 16,
|
||||||
|
|
||||||
|
vram: VRamManager::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn background(&mut self) -> RegularMap {
|
||||||
|
if self.num_regular == 4 {
|
||||||
|
panic!("Can only create 4 backgrounds");
|
||||||
|
}
|
||||||
|
|
||||||
|
let bg = RegularMap::new(self.num_regular, self.next_screenblock);
|
||||||
|
|
||||||
|
self.num_regular += 1;
|
||||||
|
self.next_screenblock += 1;
|
||||||
|
|
||||||
|
bg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileSetReference {
|
impl TileSetReference {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::display::background::BackgroundDistributor;
|
/*use crate::display::background::BackgroundDistributor;
|
||||||
|
|
||||||
crate::include_gfx!("gfx/agb_logo.toml");
|
crate::include_gfx!("gfx/agb_logo.toml");
|
||||||
|
|
||||||
|
@ -31,4 +31,4 @@ mod tests {
|
||||||
|
|
||||||
crate::test_runner::assert_image_output("gfx/test_logo.png");
|
crate::test_runner::assert_image_output("gfx/test_logo.png");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{background::BackgroundDistributor, bitmap3::Bitmap3, bitmap4::Bitmap4};
|
use super::{bitmap3::Bitmap3, bitmap4::Bitmap4};
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Video {}
|
pub struct Video {}
|
||||||
|
@ -14,7 +14,7 @@ impl Video {
|
||||||
unsafe { Bitmap4::new() }
|
unsafe { Bitmap4::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tiled0(&mut self) -> BackgroundDistributor {
|
// pub fn tiled0(&mut self) -> BackgroundDistributor {
|
||||||
unsafe { BackgroundDistributor::new() }
|
// unsafe { BackgroundDistributor::new() }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue