Skip to main content

features/
features.rs

1use std::env;
2
3use boppo_core::color;
4use boppo_websocket::{
5    Button, ButtonEvent, ButtonEvents,
6    audio::{SoundBuilder, play, play_with_controller, stop_all_sounds},
7    commands::execute_command,
8    connect_and_setup_globals,
9};
10
11#[tokio::main]
12async fn main() {
13    if env::args().len() != 3 {
14        panic!("usage: features <hostname> <password>");
15    }
16    let url = env::args().nth(1).unwrap();
17    let password = env::args().nth(2).unwrap();
18    println!("Connecting to {url:?} ...");
19    connect_and_setup_globals(&url, &password)
20        .await
21        .expect("failed to connect");
22    println!("Connected!");
23
24    const FLASH_BUTTON: Button = Button::B0;
25    const PRESS_LIGHT_BUTTON: Button = Button::B1;
26    const SFX_SIMPLE_BUTTON: Button = Button::B5;
27    const SFX_WAIT_BUTTON: Button = Button::B6;
28    const SFX_ERROR_BUTTON: Button = Button::B7;
29    const STOP_ALL_SOUNDS_BUTTON: Button = Button::B8;
30    const SLEEP_BUTTON: Button = Button::B9;
31
32    const PAUSE_BUTTON: Button = Button::B2;
33    const SPEED_CHANGE_BUTTON: Button = Button::B3;
34    const VOLUME_CHANGE_BUTTON: Button = Button::B4;
35
36    SFX_SIMPLE_BUTTON.set_color(color::ORANGE);
37    SFX_WAIT_BUTTON.set_color(color::ORANGE);
38    SFX_ERROR_BUTTON.set_color(color::RED);
39    PAUSE_BUTTON.set_color(color::GREEN);
40    SPEED_CHANGE_BUTTON.set_color(color::PURPLE);
41    VOLUME_CHANGE_BUTTON.set_color(color::YELLOW);
42    STOP_ALL_SOUNDS_BUTTON.set_color(color::WHITE);
43    SLEEP_BUTTON.set_color(color::GREY);
44
45    tokio::spawn(async move {
46        let mut button_events = ButtonEvents::subscribe();
47        let music_controller =
48            play_with_controller(SoundBuilder::file("music/Being_Me.mp3").repeat_forever())
49                .await
50                .unwrap();
51
52        music_controller.set_paused(true);
53
54        let mut paused = true;
55        let mut volume = 1.0;
56        let mut speed = 1.0;
57
58        loop {
59            let event = button_events.next().await;
60            print_event(event);
61            let button = event.button();
62            if event.is_released() && button != PRESS_LIGHT_BUTTON {
63                continue;
64            }
65            match button {
66                PRESS_LIGHT_BUTTON => {
67                    let color = if event.is_pressed() {
68                        color::RED
69                    } else {
70                        color::OFF
71                    };
72                    PRESS_LIGHT_BUTTON.set_color(color);
73                }
74                SFX_SIMPLE_BUTTON => {
75                    play("/effects/success.qoa").await.ok();
76                }
77                SFX_ERROR_BUTTON => {
78                    play("/effects/MISSING_SOUND_FOR_ERROR.qoa").await.ok();
79                }
80                SFX_WAIT_BUTTON => {
81                    let controller = play_with_controller("music/add_music_instructions.mp3")
82                        .await
83                        .unwrap();
84                    SFX_WAIT_BUTTON.set_color(color::BLUE);
85                    tokio::spawn(async move {
86                        controller.wait_until_finished().await;
87                        SFX_WAIT_BUTTON.set_color(color::ORANGE);
88                    });
89                }
90                PAUSE_BUTTON => {
91                    paused = !paused;
92                    let color = if paused { color::GREEN } else { color::RED };
93                    PAUSE_BUTTON.set_color(color);
94                    music_controller.set_paused(paused);
95                }
96                VOLUME_CHANGE_BUTTON => {
97                    volume = match volume {
98                        1.0 => 0.5,
99                        _ => 1.0,
100                    };
101                    music_controller.set_volume(volume);
102                }
103                SPEED_CHANGE_BUTTON => {
104                    speed = match speed {
105                        1.0 => 2.0,
106                        2.0 => 0.5,
107                        _ => 1.0,
108                    };
109                    music_controller.set_speed(speed);
110                }
111                STOP_ALL_SOUNDS_BUTTON => {
112                    stop_all_sounds().await.ok();
113                }
114                SLEEP_BUTTON => {
115                    execute_command("sleep").await.ok();
116                }
117                _ => {}
118            }
119        }
120    });
121
122    loop {
123        FLASH_BUTTON.set_color(color::RED);
124        tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
125        FLASH_BUTTON.set_color(color::OFF);
126        tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
127    }
128}
129
130fn print_event(event: ButtonEvent) {
131    let action = if event.is_pressed() {
132        "pressed"
133    } else {
134        "released"
135    };
136    println!("tablet event: button {} {action}", event.button().index());
137}