1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use super::*;

/// "Background 0 Control" (Text mode only).
#[cfg(feature = "unsafe_addresses")]
pub const BG0CNT: SimpleVolAddr<BackgroundControlValue> =
  unsafe { SimpleVolAddr::new(0x0400_0008) };

/// "Background 1 Control" (Text mode only).
#[cfg(feature = "unsafe_addresses")]
pub const BG1CNT: SimpleVolAddr<BackgroundControlValue> =
  unsafe { SimpleVolAddr::new(0x0400_000A) };

/// "Background 2 Control" (Text/Affine mode only).
#[cfg(feature = "unsafe_addresses")]
pub const BG2CNT: SimpleVolAddr<BackgroundControlValue> =
  unsafe { SimpleVolAddr::new(0x0400_000C) };

/// "Background 3 Control" (Text/Affine mode only).
#[cfg(feature = "unsafe_addresses")]
pub const BG3CNT: SimpleVolAddr<BackgroundControlValue> =
  unsafe { SimpleVolAddr::new(0x0400_000E) };

/// Lets you adjust how each background layer is displayed.
///
/// The effects of setting a `BackgroundControlValue` only apply in
/// [`VideoMode`] 0, 1, and 2, and also the specific layer must be present in
/// that video mode (eg: changing the BG0 control while in VideoMode2 has no
/// effect).
///
/// * `priority`: Determines the "z-order" of the background layers. When
///   drawing a background pixel, the background layer with the **lowest**
///   priority value non-transparent pixel gets its pixel drawn. If two BG
///   layers have the same priority value set then the lower numbered background
///   wins. Also note that the OBJ layer is part of this same calculation.
/// * `char_base_block`: This determines the character base block for all tile
///   ID offsets used by this background layer's tile map.
/// * `mosaic`: If this background layer should have the "mosaic" effect
///   enabled.
/// * `bpp8`: If the background should use use 8 bits per pixel (otherwise it
///   uses 4 bits per pixel).
/// * `screen_base_block`: Determines the tile map to use for arranging this
///   background's tiles.
/// * `affine_wrap`: This causes the display area overflow to wrap when the
///   layer is in affine mode, otherwise the display area is transparent. Has no
///   effect on text mode backgrounds.
/// * `screen_size`: This value affects the size of the background, but the
///   details depend on if the background is in text mode or affine mode.
///
/// | Screen Size | Text Mode (px) | Affine Mode (px) |
/// |:-:|:-:|:-:|
/// | 0 | 256^2 | 128^2 |
/// | 1 | 512x256 (wide) | 256^2 |
/// | 2 | 256x512 (tall) | 512^2 |
/// | 3 | 512^2 | 1024^2 |
#[repr(transparent)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct BackgroundControlValue(u16);

#[rustfmt::skip]
#[allow(missing_docs)]
impl BackgroundControlValue {
  pub_const_fn_new_zero!();
  unsigned_bits_u16!(0..=1, priority, with_priority, set_priority);
  unsigned_bits_u16!(2..=3, char_base_block, with_char_base_block, set_char_base_block);
  bool_bit_u16!(6, mosaic, with_mosaic, set_mosaic);
  bool_bit_u16!(7, bpp8, with_bpp8, set_bpp8);
  unsigned_bits_u16!(8..=12, screen_base_block, with_screen_base_block, set_screen_base_block);
  bool_bit_u16!(13, affine_wrap, with_affine_wrap, set_affine_wrap);
  unsigned_bits_u16!(14..=15, screen_size, with_screen_size, set_screen_size);
}