Struct gba::video::DisplayControl

source ·
pub struct DisplayControl(/* private fields */);

Implementations§

source§

impl DisplayControl

source

pub const fn new() -> Self

Examples found in repository?
examples/video3_test.rs (line 27)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      PIXELS.as_ptr().cast(),
      core::mem::size_of_val(PIXELS) as _,
    )
  };
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );
  loop {}
}
More examples
Hide additional examples
examples/video4_test.rs (line 30)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      INDEXES.as_ptr().cast(),
      core::mem::size_of_val(INDEXES) as _,
    )
  };
  BG_PALETTE.iter().zip(PALETTE.iter()).for_each(|(va, i)| {
    va.write(Color(*i));
  });
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_4).with_show_bg2(true),
  );
  loop {}
}
examples/mode3_realtime_example.rs (line 19)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn main() -> ! {
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );

  let mut red = 0;
  let mut green = 255;
  let mut blue = 0;

  for y in 0..160 {
    for x in 0..240 {
      let color = Color::from_rgb(red, green, blue);
      VIDEO3_VRAM.index(x, y).write(color);

      red = (red + 1) % 256;
      green = (green + 3) % 256;
      blue = (blue + 5) % 256;
    }
  }
  loop {}
}
examples/mode3_pong_example_game.rs (line 114)
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
fn main() -> ! {
    DISPCNT.write(
        DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
    );

    RUST_IRQ_HANDLER.write(Some(draw_sprites));
    DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
    IE.write(IrqBits::VBLANK);
    IME.write(true);

    let mut left_paddle = Paddle::new(10, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut right_paddle = Paddle::new(SCREEN_WIDTH as u16 - 10 - PADDLE_WIDTH, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut ball = Ball::new(SCREEN_WIDTH as u16 / 2, SCREEN_HEIGHT as u16 / 2);

    loop {
        left_paddle.update();
        right_paddle.update();
        ball.update(&left_paddle, &right_paddle);

        SPRITE_POSITIONS[0].write(left_paddle.x);
        SPRITE_POSITIONS[1].write(left_paddle.y);
        SPRITE_POSITIONS[2].write(right_paddle.x);
        SPRITE_POSITIONS[3].write(right_paddle.y);
        SPRITE_POSITIONS[4].write(ball.x);
        SPRITE_POSITIONS[5].write(ball.y);

        VBlankIntrWait();
    }
}
examples/hello.rs (line 72)
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);
    }
  }
}
examples/game.rs (line 109)
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
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;

  // indexing with `[y][x]`
  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';

  // interrupt configuration
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(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 const fn video_mode(self) -> VideoMode

source

pub const fn with_video_mode(self, val: VideoMode) -> Self

Examples found in repository?
examples/video3_test.rs (line 27)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      PIXELS.as_ptr().cast(),
      core::mem::size_of_val(PIXELS) as _,
    )
  };
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );
  loop {}
}
More examples
Hide additional examples
examples/video4_test.rs (line 30)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      INDEXES.as_ptr().cast(),
      core::mem::size_of_val(INDEXES) as _,
    )
  };
  BG_PALETTE.iter().zip(PALETTE.iter()).for_each(|(va, i)| {
    va.write(Color(*i));
  });
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_4).with_show_bg2(true),
  );
  loop {}
}
examples/mode3_realtime_example.rs (line 19)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn main() -> ! {
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );

  let mut red = 0;
  let mut green = 255;
  let mut blue = 0;

  for y in 0..160 {
    for x in 0..240 {
      let color = Color::from_rgb(red, green, blue);
      VIDEO3_VRAM.index(x, y).write(color);

      red = (red + 1) % 256;
      green = (green + 3) % 256;
      blue = (blue + 5) % 256;
    }
  }
  loop {}
}
examples/mode3_pong_example_game.rs (line 114)
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
fn main() -> ! {
    DISPCNT.write(
        DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
    );

    RUST_IRQ_HANDLER.write(Some(draw_sprites));
    DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
    IE.write(IrqBits::VBLANK);
    IME.write(true);

    let mut left_paddle = Paddle::new(10, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut right_paddle = Paddle::new(SCREEN_WIDTH as u16 - 10 - PADDLE_WIDTH, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut ball = Ball::new(SCREEN_WIDTH as u16 / 2, SCREEN_HEIGHT as u16 / 2);

    loop {
        left_paddle.update();
        right_paddle.update();
        ball.update(&left_paddle, &right_paddle);

        SPRITE_POSITIONS[0].write(left_paddle.x);
        SPRITE_POSITIONS[1].write(left_paddle.y);
        SPRITE_POSITIONS[2].write(right_paddle.x);
        SPRITE_POSITIONS[3].write(right_paddle.y);
        SPRITE_POSITIONS[4].write(ball.x);
        SPRITE_POSITIONS[5].write(ball.y);

        VBlankIntrWait();
    }
}
source

pub const fn show_frame1(self) -> bool

source

pub const fn with_show_frame1(self, b: bool) -> Self

source

pub const fn hblank_oam_free(self) -> bool

source

pub const fn with_hblank_oam_free(self, b: bool) -> Self

source

pub const fn obj_vram_1d(self) -> bool

source

pub const fn with_obj_vram_1d(self, b: bool) -> Self

source

pub const fn forced_blank(self) -> bool

source

pub const fn with_forced_blank(self, b: bool) -> Self

source

pub const fn show_bg0(self) -> bool

source

pub const fn with_show_bg0(self, b: bool) -> Self

Examples found in repository?
examples/hello.rs (line 72)
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 109)
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
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;

  // indexing with `[y][x]`
  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';

  // interrupt configuration
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(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;
      }
    }
  }
}
examples/game_vblank_draw.rs (line 135)
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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;

  // indexing with `[y][x]`
  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';

  // interrupt configuration
  RUST_IRQ_HANDLER.write(Some(irq_handler));
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(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 {
    // copy the current data into memory that the interrupt handler can see, so
    // that the handler can update all the graphics in proper timing with the
    // start of vblank.
    for (c, c_pos) in creatures.iter().zip(CREATURE_POSITIONS.iter()) {
      c_pos.0.write(c.x);
      c_pos.1.write(c.y);
    }
    // wait for vblank, graphics updates during the handler
    VBlankIntrWait();

    // 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 const fn show_bg1(self) -> bool

source

pub const fn with_show_bg1(self, b: bool) -> Self

source

pub const fn show_bg2(self) -> bool

source

pub const fn with_show_bg2(self, b: bool) -> Self

Examples found in repository?
examples/video3_test.rs (line 27)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      PIXELS.as_ptr().cast(),
      core::mem::size_of_val(PIXELS) as _,
    )
  };
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );
  loop {}
}
More examples
Hide additional examples
examples/video4_test.rs (line 30)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn main() -> ! {
  let a = TEXT_SCREENBLOCKS.get_frame(0).unwrap().as_usize();
  unsafe {
    __aeabi_memcpy(
      a as _,
      INDEXES.as_ptr().cast(),
      core::mem::size_of_val(INDEXES) as _,
    )
  };
  BG_PALETTE.iter().zip(PALETTE.iter()).for_each(|(va, i)| {
    va.write(Color(*i));
  });
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_4).with_show_bg2(true),
  );
  loop {}
}
examples/mode3_realtime_example.rs (line 19)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn main() -> ! {
  DISPCNT.write(
    DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
  );

  let mut red = 0;
  let mut green = 255;
  let mut blue = 0;

  for y in 0..160 {
    for x in 0..240 {
      let color = Color::from_rgb(red, green, blue);
      VIDEO3_VRAM.index(x, y).write(color);

      red = (red + 1) % 256;
      green = (green + 3) % 256;
      blue = (blue + 5) % 256;
    }
  }
  loop {}
}
examples/mode3_pong_example_game.rs (line 114)
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
fn main() -> ! {
    DISPCNT.write(
        DisplayControl::new().with_video_mode(VideoMode::_3).with_show_bg2(true),
    );

    RUST_IRQ_HANDLER.write(Some(draw_sprites));
    DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
    IE.write(IrqBits::VBLANK);
    IME.write(true);

    let mut left_paddle = Paddle::new(10, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut right_paddle = Paddle::new(SCREEN_WIDTH as u16 - 10 - PADDLE_WIDTH, SCREEN_HEIGHT as u16 / 2 - PADDLE_HEIGHT / 2);
    let mut ball = Ball::new(SCREEN_WIDTH as u16 / 2, SCREEN_HEIGHT as u16 / 2);

    loop {
        left_paddle.update();
        right_paddle.update();
        ball.update(&left_paddle, &right_paddle);

        SPRITE_POSITIONS[0].write(left_paddle.x);
        SPRITE_POSITIONS[1].write(left_paddle.y);
        SPRITE_POSITIONS[2].write(right_paddle.x);
        SPRITE_POSITIONS[3].write(right_paddle.y);
        SPRITE_POSITIONS[4].write(ball.x);
        SPRITE_POSITIONS[5].write(ball.y);

        VBlankIntrWait();
    }
}
source

pub const fn show_bg3(self) -> bool

source

pub const fn with_show_bg3(self, b: bool) -> Self

source

pub const fn show_obj(self) -> bool

source

pub const fn with_show_obj(self, b: bool) -> Self

Examples found in repository?
examples/game.rs (line 109)
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
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;

  // indexing with `[y][x]`
  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';

  // interrupt configuration
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(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;
      }
    }
  }
}
More examples
Hide additional examples
examples/game_vblank_draw.rs (line 135)
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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;

  // indexing with `[y][x]`
  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';

  // interrupt configuration
  RUST_IRQ_HANDLER.write(Some(irq_handler));
  DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
  IE.write(IrqBits::VBLANK);
  IME.write(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 {
    // copy the current data into memory that the interrupt handler can see, so
    // that the handler can update all the graphics in proper timing with the
    // start of vblank.
    for (c, c_pos) in creatures.iter().zip(CREATURE_POSITIONS.iter()) {
      c_pos.0.write(c.x);
      c_pos.1.write(c.y);
    }
    // wait for vblank, graphics updates during the handler
    VBlankIntrWait();

    // 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 const fn enable_win0(self) -> bool

source

pub const fn with_enable_win0(self, b: bool) -> Self

source

pub const fn enable_win1(self) -> bool

source

pub const fn with_enable_win1(self, b: bool) -> Self

source

pub const fn enable_obj_win(self) -> bool

source

pub const fn with_enable_obj_win(self, b: bool) -> Self

Trait Implementations§

source§

impl Clone for DisplayControl

source§

fn clone(&self) -> DisplayControl

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 DisplayControl

source§

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

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

impl Default for DisplayControl

source§

fn default() -> DisplayControl

Returns the “default value” for a type. Read more
source§

impl Hash for DisplayControl

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for DisplayControl

source§

fn cmp(&self, other: &DisplayControl) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for DisplayControl

source§

fn eq(&self, other: &DisplayControl) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for DisplayControl

source§

fn partial_cmp(&self, other: &DisplayControl) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl Copy for DisplayControl

source§

impl Eq for DisplayControl

source§

impl StructuralPartialEq for DisplayControl

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

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 T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
source§

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

Performs the conversion.