From e07372084f12981644ca96dd052c24fd8b837bff Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 7 Oct 2022 20:52:05 -0600 Subject: [PATCH] move video module into a folder/mod.rs --- src/{video.rs => video/mod.rs} | 85 +++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) rename src/{video.rs => video/mod.rs} (65%) diff --git a/src/video.rs b/src/video/mod.rs similarity index 65% rename from src/video.rs rename to src/video/mod.rs index 0081cc8..33a2eb3 100644 --- a/src/video.rs +++ b/src/video/mod.rs @@ -1,6 +1,76 @@ +//! Module to control the GBA's screen. +//! +//! # Video Basics +//! +//! To configure the screen's display, you should first decide on the +//! [`DisplayControl`] value that you want to set to the +//! [`DISPCNT`](crate::mmio::DISPCNT) register. This configures several things, +//! but most importantly it determines the [`VideoMode`] for the display to use. +//! +//! The GBA has four Background layers. Depending on the current video mode, +//! different background layers will be available for use with either "text", +//! "affine", or "bitmap" mode. +//! +//! In addition to the background layers, there's also an "OBJ" layer. This +//! allows the display of a number of "objects", which can move independently of +//! any background. Generally, one or more objects will be used to display the +//! "sprites" within a game. Because there isn't an exact 1:1 mapping between +//! sprites and objects, these docs will attempt to only talk about objects. +//! +//! ## Color And Bit Depth +//! +//! [Color] values on the GBA are 5-bits-per-channel RGB values. They're always +//! stored packed and aligned to 2, so think of them as being like a `u16`. +//! +//! Because of the GBA's limited memory, image data will rarely be stored with +//! one full color value per pixel. Instead they'll be stored as +//! 4-bits-per-pixel (4bpp) or 8-bits-per-pixel (8bpp). In both cases, each +//! pixel is an index into the PALRAM (either the [`BG_PALETTE`] or +//! [`OBJ_PALETTE`]), which stores the color to draw. This is known as "indexed" +//! or "paletted" color. +//! +//! Each palette has 256 slots. The palettes are always indexed with 8 bits +//! total, but how those bits are determined depends on the bit depth of the +//! image: +//! * 8bpp images index into the full range of the palette directly. +//! * 4bpp images are always associated with a "palbank". The palbank acts as +//! the upper 4 bits of the index, selecting which block of 16 palette entries +//! the image will be able to use. Then each 4-bit pixel within the image +//! indexes into that palbank. +//! * In both 8bpp and 4bpp modes, if a pixel's value is 0 then that pixel is +//! transparent. +//! +//! ## Priority +//! +//! When more than one thing would be drawn to the same pixel, there's a +//! priority system that determines which pixel is actually drawn. +//! * Priority values are always 2-bit, the range `0..=3`. The priority acts +//! like the sorting index, or you could also think of it as the distance from +//! the viewer. Things with a *lower* priority number are *closer* to the +//! viewer, and so they'll be what's drawn. +//! * Objects always draw over top a same-priority background. +//! * Lower indexed objects get drawn when two objects have the same priority. +//! * Lower numbered backgrounds get drawn when two backgrounds have the same +//! priority. +//! +//! There's also one hardware bug that can occur: when there's two objects and +//! their the priority and index wouldn't sort them the same (eg: a lower index +//! number object has a higher priority number), if a background is *also* +//! between the two objects, then the object that's supposed to be behind the +//! background will instead appear through the background where the two objects +//! overlap. This might never happen to you, but if it does, the "fix" is to +//! sort your object entries so that any lower priority objects are also the +//! lower index objects. + use crate::macros::{ pub_const_fn_new_zeroed, u16_bool_field, u16_enum_field, u16_int_field, }; +#[allow(unused_imports)] +use crate::prelude::*; + +pub mod affine_backgrounds; +pub mod bitmap_backgrounds; +pub mod tiled_backgrounds; /// An RGB555 color value (packed into `u16`). #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -158,10 +228,21 @@ pub type Tile4 = [u32; 8]; /// Data for an 8-bit-per-pixel tile. pub type Tile8 = [u32; 16]; +/// An entry within a tile mode tilemap. +/// +/// * `tile_id` is the index of the tile, offset from the `charblock` that the +/// background is using. This is a 10-bit value, so indexes are in the range +/// `0..=1023`. You *cannot* index past the end of background VRAM into object +/// VRAM (it just won't draw properly), but you *can* index past the end of +/// one charblock into the next charblock. +/// * `hflip` If you want the tile horizontally flipped. +/// * `vflip` If you want the tile vertically flipped. +/// * `palbank` sets the palbank for this tile. If the background is in 8bpp +/// mode this has no effect. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] -pub struct TextEntry(u16); -impl TextEntry { +pub struct TileEntry(u16); +impl TileEntry { pub_const_fn_new_zeroed!(); u16_int_field!(0 - 9, tile_id, with_tile_id); u16_bool_field!(10, hflip, with_hflip);