You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
3.6 KiB
Rust

#[derive(PartialEq, Copy, Clone)]
enum PomState {
STOPPED,
RUNNING,
PAUSED
}
const POM_DURATION : u16 = 1500;
const POM_CURRENT_INDEX : u32 = 68;
const POM_LIGHT_COUNT : u32 = 9;
const POM_COMPLETE_INDEX : u32 = POM_CURRENT_INDEX + POM_LIGHT_COUNT + 1;
static mut current_pom_state : PomState = PomState::STOPPED;
static mut pom_visible : bool = false;
static mut poms_completed : u32 = 0;
static mut pom_current_secs : u16 = 0;
static mut pom_second_start : u32 = 0;
static mut blink_on : bool = false;
static mut last_pos : u32 = 0;
extern "C" {
pub static complete_hsv : [u32; 3usize];
pub static current_hsv : [u32; 3usize];
pub static hidden_hsv : [u32; 3usize];
pub static blank_hsv : [u32; 3usize];
fn timer_read32() -> u32;
fn timer_elapsed32(prev : u32) -> u32;
fn hsv_matrix_set_color(i : u32, color : *const [u32; 3usize]);
}
#[no_mangle]
pub unsafe extern "C" fn new_pom() {
let previous_pom_state = current_pom_state;
match previous_pom_state {
PomState::RUNNING => {
current_pom_state = PomState::PAUSED;
},
PomState::PAUSED => {
current_pom_state = PomState::RUNNING;
},
PomState::STOPPED => {
current_pom_state = PomState::RUNNING;
pom_current_secs = 0;
pom_second_start = 0;
}
}
}
#[no_mangle]
pub unsafe extern "C" fn cancel_pom() {
current_pom_state = PomState::STOPPED;
pom_current_secs = 0;
pom_second_start = 0;
}
#[no_mangle]
pub unsafe extern "C" fn delete_pom() {
cancel_pom();
poms_completed = 0;
}
#[no_mangle]
pub unsafe extern "C" fn show_pom() {
pom_visible = !pom_visible;
}
#[no_mangle]
pub unsafe extern "C" fn tick_pom() {
if current_pom_state == PomState::RUNNING {
count_pom();
}
if current_pom_state != PomState::STOPPED || poms_completed > 0 {
draw_pom();
}
}
unsafe fn count_pom() {
if pom_second_start == 0 {
pom_second_start = timer_read32();
}
if timer_elapsed32(pom_second_start) > 1000 {
pom_second_start = 0;
pom_current_secs += 1;
}
if pom_current_secs >= POM_DURATION {
poms_completed += 1;
current_pom_state = PomState::STOPPED;
pom_current_secs = 0;
pom_second_start = 0;
}
}
unsafe fn draw_pom() {
let current_pos = POM_CURRENT_INDEX + ((pom_current_secs as f32 / POM_DURATION as f32) * POM_LIGHT_COUNT as f32) as u32;
let completed_pos = POM_COMPLETE_INDEX + poms_completed - 1;
// Clear row
if pom_visible {
if current_pom_state != PomState::STOPPED {
let mut i = POM_CURRENT_INDEX;
while i < POM_CURRENT_INDEX + POM_LIGHT_COUNT {
hsv_matrix_set_color(i, &blank_hsv);
i += 1;
}
}
let mut i = POM_COMPLETE_INDEX;
while i < POM_COMPLETE_INDEX + 3 {
hsv_matrix_set_color(i, &blank_hsv);
i += 1;
}
}
// Draw completed
if pom_visible {
let mut i = POM_COMPLETE_INDEX;
while i < POM_COMPLETE_INDEX + poms_completed {
hsv_matrix_set_color(i, &complete_hsv);
i += 1;
}
} else if poms_completed > 0 && poms_completed <= 3 {
hsv_matrix_set_color(completed_pos, &hidden_hsv);
}
if current_pom_state == PomState::STOPPED {
return;
}
if last_pos != current_pos {
last_pos = current_pos;
blink_on = true;
} else if pom_second_start == 0 {
blink_on = !blink_on;
}
// Current solid
if pom_visible {
let mut i = POM_CURRENT_INDEX;
while i < current_pos {
hsv_matrix_set_color(i, &current_hsv);
i += 1;
}
}
// Current blinking
if blink_on {
if pom_visible {
hsv_matrix_set_color(current_pos, &current_hsv);
} else {
hsv_matrix_set_color(current_pos, &hidden_hsv);
}
}
}