Struct agb::input::ButtonController

source ·
pub struct ButtonController { /* private fields */ }
Expand description

Helper to make it easy to get the current state of the GBA’s buttons.

Example

use agb::input::{ButtonController, Tri};

let mut input = ButtonController::new();

loop {
    input.update(); // call update every loop

    match input.x_tri() {
        Tri::Negative => { /* left is being pressed */ }
        Tri::Positive => { /* right is being pressed */ }
        Tri::Zero => { /* Neither left nor right (or both) are pressed */ }
    }
}

Implementations§

source§

impl ButtonController

source

pub fn new() -> Self

Create a new ButtonController. This is the preferred way to create it.

Examples found in repository?
examples/sprites.rs (line 24)
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
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
fn all_sprites(gfx: &OamManaged, rotation_speed: Num<i32, 16>) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    let mut rotation: Num<i32, 16> = num!(0.);

    let rotation_matrix = AffineMatrix::from_rotation(rotation);
    let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

    for y in 0..9 {
        for x in 0..14 {
            let mut obj = gfx.object_sprite(&SPRITES[0]);
            obj.set_affine_matrix(matrix.clone());
            obj.show_affine(object::AffineMode::Affine);
            obj.set_position((x * 16 + 8, y * 16 + 8).into());
            objs.push(obj);
        }
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();
        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        rotation += rotation_speed;
        let rotation_matrix = AffineMatrix::from_rotation(rotation);

        let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

        for obj in objs.iter_mut() {
            obj.set_affine_matrix(matrix.clone());
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            image %= SPRITES.len();
            for (i, obj) in objs.iter_mut().enumerate() {
                let this_image = (image + i) % SPRITES.len();
                obj.set_sprite(gfx.sprite(&SPRITES[this_image]));
            }
        }
        gfx.commit();
    }
}

fn all_tags(gfx: &OamManaged) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    for (i, v) in TAG_MAP.values().enumerate() {
        let x = (i % 7) as i32;
        let y = (i / 7) as i32;
        let sprite = v.sprite(0);
        let (size_x, size_y) = sprite.size().to_width_height();
        let (size_x, size_y) = (size_x as i32, size_y as i32);
        let mut obj = gfx.object_sprite(sprite);
        obj.show();
        obj.set_position((x * 32 + 16 - size_x / 2, y * 32 + 16 - size_y / 2).into());
        objs.push((obj, v));
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();

        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            for (obj, tag) in objs.iter_mut() {
                obj.set_sprite(gfx.sprite(tag.animation_sprite(image)));
            }
            gfx.commit();
        }
    }
}
More examples
Hide additional examples
examples/object_text_render.rs (line 57)
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
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
fn main(mut gba: agb::Gba) -> ! {
    let (mut unmanaged, _sprites) = gba.display.object.get_unmanaged();

    let mut palette = [0x0; 16];
    palette[1] = 0xFF_FF;
    palette[2] = 0x00_FF;
    let palette = Palette16::new(palette);
    let palette = PaletteVram::new(&palette).unwrap();

    let timer = gba.timers.timers();
    let mut timer: agb::timer::Timer = timer.timer2;

    timer.set_enabled(true);
    timer.set_divider(agb::timer::Divider::Divider256);

    let mut wr = ObjectTextRender::new(&FONT, Size::S16x16, palette);
    let start = timer.value();

    let player_name = "You";
    let _ = writeln!(
            wr,
            "Woah!{change2} {player_name}! {change1}Hey there! I have a bunch of text I want to show you. However, you will find that the amount of text I can display is limited. Who'd have thought! Good thing that my text system supports scrolling! It only took around 20 jank versions to get here!",
            change2 = ChangeColour::new(2),
            change1 = ChangeColour::new(1),
        );
    let end = timer.value();

    agb::println!(
        "Write took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let vblank = agb::interrupt::VBlank::get();
    let mut input = agb::input::ButtonController::new();

    let start = timer.value();

    wr.layout((WIDTH, 40).into(), TextAlignment::Justify, 2);
    let end = timer.value();

    agb::println!(
        "Layout took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let mut line_done = false;
    let mut frame = 0;

    loop {
        vblank.wait_for_vblank();
        input.update();
        let oam = &mut unmanaged.iter();
        wr.commit(oam);

        let start = timer.value();
        if frame % 4 == 0 {
            line_done = !wr.next_letter_group();
        }
        if line_done && input.is_just_pressed(Button::A) {
            line_done = false;
            wr.pop_line();
        }
        wr.update((0, HEIGHT - 40).into());
        let end = timer.value();

        frame += 1;

        agb::println!(
            "Took {} cycles, line done {}",
            256 * (end.wrapping_sub(start) as u32),
            line_done
        );
    }
}
source

pub fn update(&mut self)

Updates the state of the button controller. You should call this every frame (either at the start or the end) to ensure that you have the latest state of each button press. Calls to any method won’t change until you call this.

Examples found in repository?
examples/multiple_video.rs (line 35)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
fn bitmap3_mode(
    bitmap: &mut display::bitmap3::Bitmap3,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    let mut pos = Vector2D {
        x: display::WIDTH / 2,
        y: display::HEIGHT / 2,
    };

    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        pos.x += input.x_tri() as i32;
        pos.y += input.y_tri() as i32;

        pos.x = pos.x.clamp(0, display::WIDTH - 1);
        pos.y = pos.y.clamp(0, display::HEIGHT - 1);
        bitmap.draw_point(pos.x, pos.y, 0x001F);
    }
}

fn bitmap4_mode(
    bitmap: &mut display::bitmap4::Bitmap4,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    bitmap.set_palette_entry(1, 0x001F);
    bitmap.set_palette_entry(2, 0x03E0);

    bitmap.draw_point_page(
        display::WIDTH / 2,
        display::HEIGHT / 2,
        1,
        display::bitmap4::Page::Front,
    );
    bitmap.draw_point_page(
        display::WIDTH / 2 + 5,
        display::HEIGHT / 2,
        2,
        display::bitmap4::Page::Back,
    );

    let mut count = 0;
    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        count += 1;
        if count % 6 == 0 {
            bitmap.flip_page();
        }
    }
}
More examples
Hide additional examples
examples/sprites.rs (line 49)
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
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
fn all_sprites(gfx: &OamManaged, rotation_speed: Num<i32, 16>) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    let mut rotation: Num<i32, 16> = num!(0.);

    let rotation_matrix = AffineMatrix::from_rotation(rotation);
    let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

    for y in 0..9 {
        for x in 0..14 {
            let mut obj = gfx.object_sprite(&SPRITES[0]);
            obj.set_affine_matrix(matrix.clone());
            obj.show_affine(object::AffineMode::Affine);
            obj.set_position((x * 16 + 8, y * 16 + 8).into());
            objs.push(obj);
        }
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();
        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        rotation += rotation_speed;
        let rotation_matrix = AffineMatrix::from_rotation(rotation);

        let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

        for obj in objs.iter_mut() {
            obj.set_affine_matrix(matrix.clone());
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            image %= SPRITES.len();
            for (i, obj) in objs.iter_mut().enumerate() {
                let this_image = (image + i) % SPRITES.len();
                obj.set_sprite(gfx.sprite(&SPRITES[this_image]));
            }
        }
        gfx.commit();
    }
}

fn all_tags(gfx: &OamManaged) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    for (i, v) in TAG_MAP.values().enumerate() {
        let x = (i % 7) as i32;
        let y = (i / 7) as i32;
        let sprite = v.sprite(0);
        let (size_x, size_y) = sprite.size().to_width_height();
        let (size_x, size_y) = (size_x as i32, size_y as i32);
        let mut obj = gfx.object_sprite(sprite);
        obj.show();
        obj.set_position((x * 32 + 16 - size_x / 2, y * 32 + 16 - size_y / 2).into());
        objs.push((obj, v));
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();

        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            for (obj, tag) in objs.iter_mut() {
                obj.set_sprite(gfx.sprite(tag.animation_sprite(image)));
            }
            gfx.commit();
        }
    }
}
examples/object_text_render.rs (line 74)
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
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
fn main(mut gba: agb::Gba) -> ! {
    let (mut unmanaged, _sprites) = gba.display.object.get_unmanaged();

    let mut palette = [0x0; 16];
    palette[1] = 0xFF_FF;
    palette[2] = 0x00_FF;
    let palette = Palette16::new(palette);
    let palette = PaletteVram::new(&palette).unwrap();

    let timer = gba.timers.timers();
    let mut timer: agb::timer::Timer = timer.timer2;

    timer.set_enabled(true);
    timer.set_divider(agb::timer::Divider::Divider256);

    let mut wr = ObjectTextRender::new(&FONT, Size::S16x16, palette);
    let start = timer.value();

    let player_name = "You";
    let _ = writeln!(
            wr,
            "Woah!{change2} {player_name}! {change1}Hey there! I have a bunch of text I want to show you. However, you will find that the amount of text I can display is limited. Who'd have thought! Good thing that my text system supports scrolling! It only took around 20 jank versions to get here!",
            change2 = ChangeColour::new(2),
            change1 = ChangeColour::new(1),
        );
    let end = timer.value();

    agb::println!(
        "Write took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let vblank = agb::interrupt::VBlank::get();
    let mut input = agb::input::ButtonController::new();

    let start = timer.value();

    wr.layout((WIDTH, 40).into(), TextAlignment::Justify, 2);
    let end = timer.value();

    agb::println!(
        "Layout took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let mut line_done = false;
    let mut frame = 0;

    loop {
        vblank.wait_for_vblank();
        input.update();
        let oam = &mut unmanaged.iter();
        wr.commit(oam);

        let start = timer.value();
        if frame % 4 == 0 {
            line_done = !wr.next_letter_group();
        }
        if line_done && input.is_just_pressed(Button::A) {
            line_done = false;
            wr.pop_line();
        }
        wr.update((0, HEIGHT - 40).into());
        let end = timer.value();

        frame += 1;

        agb::println!(
            "Took {} cycles, line done {}",
            256 * (end.wrapping_sub(start) as u32),
            line_done
        );
    }
}
source

pub fn x_tri(&self) -> Tri

Returns Tri::Positive if right is pressed, Tri::Negative if left is pressed and Tri::Zero if neither or both are pressed. This is the normal behaviour you’ll want if you’re using orthogonal inputs.

Examples found in repository?
examples/multiple_video.rs (line 40)
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
fn bitmap3_mode(
    bitmap: &mut display::bitmap3::Bitmap3,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    let mut pos = Vector2D {
        x: display::WIDTH / 2,
        y: display::HEIGHT / 2,
    };

    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        pos.x += input.x_tri() as i32;
        pos.y += input.y_tri() as i32;

        pos.x = pos.x.clamp(0, display::WIDTH - 1);
        pos.y = pos.y.clamp(0, display::HEIGHT - 1);
        bitmap.draw_point(pos.x, pos.y, 0x001F);
    }
}
source

pub fn y_tri(&self) -> Tri

Returns Tri::Positive if down is pressed, Tri::Negative if up is pressed and Tri::Zero if neither or both are pressed. This is the normal behaviour you’ll want if you’re using orthogonal inputs.

Examples found in repository?
examples/multiple_video.rs (line 41)
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
fn bitmap3_mode(
    bitmap: &mut display::bitmap3::Bitmap3,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    let mut pos = Vector2D {
        x: display::WIDTH / 2,
        y: display::HEIGHT / 2,
    };

    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        pos.x += input.x_tri() as i32;
        pos.y += input.y_tri() as i32;

        pos.x = pos.x.clamp(0, display::WIDTH - 1);
        pos.y = pos.y.clamp(0, display::HEIGHT - 1);
        bitmap.draw_point(pos.x, pos.y, 0x001F);
    }
}
source

pub fn vector<T>(&self) -> Vector2D<T>
where T: From<i32> + FixedWidthUnsignedInteger,

Returns true if all the buttons specified in keys are pressed.

source

pub fn just_pressed_x_tri(&self) -> Tri

Returns Tri::Positive if left was just pressed, Tri::Negative if right was just pressed and Tri::Zero if neither or both are just pressed.

Also returns Tri::Zero after the call to update() if the button is still held.

source

pub fn just_pressed_y_tri(&self) -> Tri

Returns Tri::Positive if down was just pressed, Tri::Negative if up was just pressed and Tri::Zero if neither or both are just pressed.

Also returns Tri::Zero after the call to update() if the button is still held.

source

pub fn just_pressed_vector<T>(&self) -> Vector2D<T>
where T: From<i32> + FixedWidthUnsignedInteger,

Returns a vector which represents the direction the button was just pressed in.

source

pub fn is_pressed(&self, keys: Button) -> bool

Returns true if the provided keys are all pressed, and false if not.

source

pub fn is_released(&self, keys: Button) -> bool

Returns true if all the buttons specified in keys are not pressed. Equivalent to !is_pressed(keys).

source

pub fn is_just_pressed(&self, keys: Button) -> bool

Returns true if all the buttons specified in keys went from not pressed to pressed in the last frame. Very useful for menu navigation or selection if you want the players actions to only happen for one frame.

Example
use agb::input::{Button, ButtonController};

let mut button_controller = ButtonController::new();

loop {
    button_controller.update();

    if button_controller.is_just_pressed(Button::A) {
        // A button was just pressed, maybe select the currently selected item
    }
}
Examples found in repository?
examples/multiple_video.rs (line 36)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
fn bitmap3_mode(
    bitmap: &mut display::bitmap3::Bitmap3,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    let mut pos = Vector2D {
        x: display::WIDTH / 2,
        y: display::HEIGHT / 2,
    };

    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        pos.x += input.x_tri() as i32;
        pos.y += input.y_tri() as i32;

        pos.x = pos.x.clamp(0, display::WIDTH - 1);
        pos.y = pos.y.clamp(0, display::HEIGHT - 1);
        bitmap.draw_point(pos.x, pos.y, 0x001F);
    }
}

fn bitmap4_mode(
    bitmap: &mut display::bitmap4::Bitmap4,
    vblank: &agb::interrupt::VBlank,
    input: &mut agb::input::ButtonController,
) {
    bitmap.set_palette_entry(1, 0x001F);
    bitmap.set_palette_entry(2, 0x03E0);

    bitmap.draw_point_page(
        display::WIDTH / 2,
        display::HEIGHT / 2,
        1,
        display::bitmap4::Page::Front,
    );
    bitmap.draw_point_page(
        display::WIDTH / 2 + 5,
        display::HEIGHT / 2,
        2,
        display::bitmap4::Page::Back,
    );

    let mut count = 0;
    loop {
        vblank.wait_for_vblank();

        input.update();
        if input.is_just_pressed(agb::input::Button::B) {
            break;
        }

        count += 1;
        if count % 6 == 0 {
            bitmap.flip_page();
        }
    }
}
More examples
Hide additional examples
examples/sprites.rs (line 51)
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
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
fn all_sprites(gfx: &OamManaged, rotation_speed: Num<i32, 16>) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    let mut rotation: Num<i32, 16> = num!(0.);

    let rotation_matrix = AffineMatrix::from_rotation(rotation);
    let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

    for y in 0..9 {
        for x in 0..14 {
            let mut obj = gfx.object_sprite(&SPRITES[0]);
            obj.set_affine_matrix(matrix.clone());
            obj.show_affine(object::AffineMode::Affine);
            obj.set_position((x * 16 + 8, y * 16 + 8).into());
            objs.push(obj);
        }
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();
        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        rotation += rotation_speed;
        let rotation_matrix = AffineMatrix::from_rotation(rotation);

        let matrix = object::AffineMatrixInstance::new(rotation_matrix.to_object_wrapping());

        for obj in objs.iter_mut() {
            obj.set_affine_matrix(matrix.clone());
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            image %= SPRITES.len();
            for (i, obj) in objs.iter_mut().enumerate() {
                let this_image = (image + i) % SPRITES.len();
                obj.set_sprite(gfx.sprite(&SPRITES[this_image]));
            }
        }
        gfx.commit();
    }
}

fn all_tags(gfx: &OamManaged) {
    let mut input = agb::input::ButtonController::new();
    let mut objs = Vec::new();

    for (i, v) in TAG_MAP.values().enumerate() {
        let x = (i % 7) as i32;
        let y = (i / 7) as i32;
        let sprite = v.sprite(0);
        let (size_x, size_y) = sprite.size().to_width_height();
        let (size_x, size_y) = (size_x as i32, size_y as i32);
        let mut obj = gfx.object_sprite(sprite);
        obj.show();
        obj.set_position((x * 32 + 16 - size_x / 2, y * 32 + 16 - size_y / 2).into());
        objs.push((obj, v));
    }

    let mut count = 0;
    let mut image = 0;

    let vblank = agb::interrupt::VBlank::get();

    loop {
        vblank.wait_for_vblank();

        input.update();

        if input.is_just_pressed(agb::input::Button::A) {
            break;
        }

        count += 1;

        if count % 5 == 0 {
            image += 1;
            for (obj, tag) in objs.iter_mut() {
                obj.set_sprite(gfx.sprite(tag.animation_sprite(image)));
            }
            gfx.commit();
        }
    }
}
examples/object_text_render.rs (line 82)
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
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
fn main(mut gba: agb::Gba) -> ! {
    let (mut unmanaged, _sprites) = gba.display.object.get_unmanaged();

    let mut palette = [0x0; 16];
    palette[1] = 0xFF_FF;
    palette[2] = 0x00_FF;
    let palette = Palette16::new(palette);
    let palette = PaletteVram::new(&palette).unwrap();

    let timer = gba.timers.timers();
    let mut timer: agb::timer::Timer = timer.timer2;

    timer.set_enabled(true);
    timer.set_divider(agb::timer::Divider::Divider256);

    let mut wr = ObjectTextRender::new(&FONT, Size::S16x16, palette);
    let start = timer.value();

    let player_name = "You";
    let _ = writeln!(
            wr,
            "Woah!{change2} {player_name}! {change1}Hey there! I have a bunch of text I want to show you. However, you will find that the amount of text I can display is limited. Who'd have thought! Good thing that my text system supports scrolling! It only took around 20 jank versions to get here!",
            change2 = ChangeColour::new(2),
            change1 = ChangeColour::new(1),
        );
    let end = timer.value();

    agb::println!(
        "Write took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let vblank = agb::interrupt::VBlank::get();
    let mut input = agb::input::ButtonController::new();

    let start = timer.value();

    wr.layout((WIDTH, 40).into(), TextAlignment::Justify, 2);
    let end = timer.value();

    agb::println!(
        "Layout took {} cycles",
        256 * (end.wrapping_sub(start) as u32)
    );

    let mut line_done = false;
    let mut frame = 0;

    loop {
        vblank.wait_for_vblank();
        input.update();
        let oam = &mut unmanaged.iter();
        wr.commit(oam);

        let start = timer.value();
        if frame % 4 == 0 {
            line_done = !wr.next_letter_group();
        }
        if line_done && input.is_just_pressed(Button::A) {
            line_done = false;
            wr.pop_line();
        }
        wr.update((0, HEIGHT - 40).into());
        let end = timer.value();

        frame += 1;

        agb::println!(
            "Took {} cycles, line done {}",
            256 * (end.wrapping_sub(start) as u32),
            line_done
        );
    }
}
source

pub fn is_just_released(&self, keys: Button) -> bool

Returns true if all the buttons specified in keys went from pressed to not pressed in the last frame. Very useful for menu navigation or selection if you want players actions to only happen for one frame.

Trait Implementations§

source§

impl Default for ButtonController

source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl RefUnwindSafe for ButtonController

§

impl Send for ButtonController

§

impl Sync for ButtonController

§

impl Unpin for ButtonController

§

impl UnwindSafe for ButtonController

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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.
§

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

Performs the conversion.