pub struct Cga8x8Thick;

Implementations§

source§

impl Cga8x8Thick

source

pub const NULL: u8 = 0u8

source

pub const FACE: u8 = 1u8

source

pub const FACE_INVERSE: u8 = 2u8

source

pub const HEART: u8 = 3u8

source

pub const DIAMOND: u8 = 4u8

source

pub const CLUB: u8 = 5u8

source

pub const SPADE: u8 = 6u8

source

pub const BULLET: u8 = 7u8

source

pub const BULLET_INVERSE: u8 = 8u8

source

pub const CIRCLE: u8 = 9u8

source

pub const CIRCLE_INVERSE: u8 = 10u8

source

pub const MALE: u8 = 11u8

source

pub const FEMALE: u8 = 12u8

source

pub const NOTE: u8 = 13u8

source

pub const NOTE_DOUBLE: u8 = 14u8

source

pub const SOLAR: u8 = 15u8

source

pub const POINTER_RIGHT: u8 = 16u8

source

pub const POINTER_LEFT: u8 = 17u8

source

pub const ARROW_UP_DOWN: u8 = 18u8

source

pub const BANG_DOUBLE: u8 = 19u8

source

pub const PARAGRAPH: u8 = 20u8

source

pub const SECTION: u8 = 21u8

source

pub const UNDERLINE_THICK: u8 = 22u8

source

pub const ARROW_UP_DOWN_UNDERLINED: u8 = 23u8

source

pub const ARROW_UP: u8 = 24u8

source

pub const ARROW_DOWN: u8 = 25u8

source

pub const ARROW_RIGHT: u8 = 26u8

source

pub const ARROW_LEFT: u8 = 27u8

source

pub const RIGHT_ANGLE: u8 = 28u8

source

pub const ARROW_LEFT_RIGHT: u8 = 29u8

source

pub const POINTER_UP: u8 = 30u8

source

pub const POINTER_DOWN: u8 = 31u8

source

pub const BOX_VERTICAL: u8 = 179u8

source

pub const BOX_HORIZONTAL: u8 = 196u8

source

pub const BOX_UPPER_RIGHT: u8 = 191u8

source

pub const BOX_UPPER_LEFT: u8 = 218u8

source

pub const BOX_LOWER_RIGHT: u8 = 217u8

source

pub const BOX_LOWER_LEFT: u8 = 192u8

source

pub fn bitunpack_4bpp( self, b: VolRegion<Tile4, Safe, Safe>, offset_and_touch_zero: u32 )

Bit unpacks the data (4bpp depth) to the location given.

  • offset_and_touch_zero: Works like the BitUnpackInfo field. By default you should usually pass 0 here.
Panics
  • Requires at least 256 elements of space within the region.
Examples found in repository?
examples/hello.rs (line 54)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
extern "C" fn main() -> ! {
  RUST_IRQ_HANDLER.write(Some(irq_handler));
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(true);

  if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) {
    writeln!(logger, "hello!").ok();

    let fx_u: Fixed<u32, 8> =
      Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_raw(12);
    writeln!(logger, "fixed unsigned: {fx_u:?}").ok();

    let fx_i1: Fixed<i32, 8> =
      Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_raw(15);
    writeln!(logger, "fixed signed positive: {fx_i1:?}").ok();

    let fx_i2: Fixed<i32, 8> = Fixed::<i32, 8>::wrapping_from(0)
      - Fixed::<i32, 8>::wrapping_from(3)
      - Fixed::<i32, 8>::from_raw(17);
    writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
  }

  {
    // get our tile data into memory.
    Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
  }

  {
    // set up the tilemap
    let tsb = TEXT_SCREENBLOCKS.get_frame(31).unwrap();
    for y in 0..16 {
      let row = tsb.get_row(y).unwrap();
      for (x, addr) in row.iter().enumerate().take(16) {
        let te = TextEntry::new().with_tile((y * 16 + x) as u16);
        addr.write(te);
      }
    }
  }

  {
    // Set BG0 to use the tilemap we just made, and set it to be shown.
    BG0CNT.write(BackgroundControl::new().with_screenblock(31));
    DISPCNT.write(DisplayControl::new().with_show_bg0(true));
  }

  let mut x_off = 0_u32;
  let mut y_off = 0_u32;
  let mut backdrop_color = Color(0);
  loop {
    VBlankIntrWait();
    // show current frame
    BACKDROP_COLOR.write(backdrop_color);
    BG0HOFS.write(x_off as u16);
    BG0VOFS.write(y_off as u16);

    // prep next frame
    let k = FRAME_KEYS.read();
    backdrop_color = Color(k.to_u16());
    if k.up() {
      y_off = y_off.wrapping_add(1);
    }
    if k.down() {
      y_off = y_off.wrapping_sub(1);
    }
    if k.left() {
      x_off = x_off.wrapping_add(1);
    }
    if k.right() {
      x_off = x_off.wrapping_sub(1);
    }
  }
}
More examples
Hide additional examples
examples/game.rs (line 95)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
extern "C" fn main() -> ! {
  // game simulation setup
  let mut creatures = [Position::default(); 5];
  creatures[0].x = 11;
  creatures[0].y = 14;
  //
  creatures[1].x = 44;
  creatures[1].y = 38;
  creatures[2].x = 100;
  creatures[2].y = 23;
  creatures[3].x = 14;
  creatures[3].y = 101;
  creatures[4].x = 72;
  creatures[4].y = 59;

  let mut world = [[0_u8; 32]; 32];
  for i in 0..32 {
    world[0][i] = Cga8x8Thick::BOX_HORIZONTAL;
    world[19][i] = Cga8x8Thick::BOX_HORIZONTAL;
    world[i][0] = Cga8x8Thick::BOX_VERTICAL;
    world[i][29] = Cga8x8Thick::BOX_VERTICAL;
  }
  world[0][0] = Cga8x8Thick::BOX_UPPER_LEFT;
  world[0][29] = Cga8x8Thick::BOX_UPPER_RIGHT;
  world[19][0] = Cga8x8Thick::BOX_LOWER_LEFT;
  world[19][29] = Cga8x8Thick::BOX_LOWER_RIGHT;
  //
  world[1][3] = b'B';
  world[2][3] = b'G';
  world[3][3] = b'0';

  // hardware configuration
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(true);

  TIMER0_CONTROL.write(TimerControl::new().with_enabled(true));

  // bg
  BG_PALETTE.index(1).write(Color::MAGENTA);
  // obj
  let colors =
    [Color::CYAN, Color::GREEN, Color::RED, Color::BLUE, Color::YELLOW];
  for (pal, color) in colors.iter().enumerate() {
    obj_palbank(pal).index(1).write(*color);
  }

  Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
  Cga8x8Thick.bitunpack_4bpp(OBJ_TILES.as_region(), 0);

  BG0CNT.write(BackgroundControl::new().with_screenblock(8));
  let screenblock = TEXT_SCREENBLOCKS.get_frame(8).unwrap();
  for y in 0..32 {
    let row = screenblock.get_row(y).unwrap();
    for (x, addr) in row.iter().enumerate() {
      let te = TextEntry::new().with_tile(world[y][x] as u16);
      addr.write(te);
    }
  }

  let no_display = ObjAttr0::new().with_style(ObjDisplayStyle::NotDisplayed);
  OBJ_ATTR0.iter().skip(creatures.len()).for_each(|va| va.write(no_display));

  DISPCNT.write(DisplayControl::new().with_show_obj(true).with_show_bg0(true));

  let mut l_was_pressed = false;
  let mut r_was_pressed = false;

  loop {
    // wait for vblank
    VBlankIntrWait();

    // update graphics MMIO
    for (i, (creature_pos, attr_addr)) in
      creatures.iter().zip(OBJ_ATTR_ALL.iter()).enumerate()
    {
      let mut obj = ObjAttr::new();
      obj.set_x(creature_pos.x);
      obj.set_y(creature_pos.y);
      obj.set_tile_id(1);
      obj.set_palbank(i as u16);
      attr_addr.write(obj);
    }

    // handle input
    let keys = KEYINPUT.read();
    if keys.l() && !l_was_pressed {
      creatures.rotate_left(1);
    }
    if keys.r() && !r_was_pressed {
      creatures.rotate_right(1);
    }
    l_was_pressed = keys.l();
    r_was_pressed = keys.r();

    // the way we handle movement here is per-direction. If you're against a
    // wall and you press a diagonal then one axis will progress while the other
    // will be halted by the wall. This makes the player slide along the wall
    // when bumping into walls.
    let (player, enemies) = match &mut creatures {
      [player, enemies @ ..] => (player, enemies),
    };
    if keys.up() {
      let new_p = Position { x: player.x, y: player.y - 1 };
      let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
      let terrain_clear = new_r
        .iter_tiles()
        .all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
      let enemy_clear = enemies.iter().all(|enemy| {
        let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
        !new_r.intersect(enemy_r)
      });
      if terrain_clear && enemy_clear {
        *player = new_p;
      }
    }
    if keys.down() {
      let new_p = Position { x: player.x, y: player.y + 1 };
      let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
      let terrain_clear = new_r
        .iter_tiles()
        .all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
      let enemy_clear = enemies.iter().all(|enemy| {
        let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
        !new_r.intersect(enemy_r)
      });
      if terrain_clear && enemy_clear {
        *player = new_p;
      }
    }
    if keys.left() {
      let new_p = Position { x: player.x - 1, y: player.y };
      let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
      let terrain_clear = new_r
        .iter_tiles()
        .all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
      let enemy_clear = enemies.iter().all(|enemy| {
        let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
        !new_r.intersect(enemy_r)
      });
      if terrain_clear && enemy_clear {
        *player = new_p;
      }
    }
    if keys.right() {
      let new_p = Position { x: player.x + 1, y: player.y };
      let new_r = Rect { x: new_p.x, y: new_p.y, w: 8, h: 8 };
      let terrain_clear = new_r
        .iter_tiles()
        .all(|(tx, ty)| allows_movement(world[ty as usize][tx as usize]));
      let enemy_clear = enemies.iter().all(|enemy| {
        let enemy_r = Rect { x: enemy.x, y: enemy.y, w: 8, h: 8 };
        !new_r.intersect(enemy_r)
      });
      if terrain_clear && enemy_clear {
        *player = new_p;
      }
    }
  }
}
source

pub fn bitunpack_8bpp( self, b: VolRegion<Tile8, Safe, Safe>, offset_and_touch_zero: u32 )

Bit unpacks the data (8bpp depth) to the location given.

  • offset_and_touch_zero: Works like the BitUnpackInfo field. By default you should usually pass 0 here.
Panics
  • Requires at least 256 elements of space within the region.

Trait Implementations§

source§

impl Clone for Cga8x8Thick

source§

fn clone(&self) -> Cga8x8Thick

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Cga8x8Thick

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Cga8x8Thick

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.