mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 06:18:07 +00:00
feat(core): implement loaders for T2B1
[no changelog]
This commit is contained in:
parent
52cd43bf29
commit
9aa8662ba9
@ -3,7 +3,6 @@ use crate::ui::{
|
||||
display::Color,
|
||||
geometry::{Offset, Point, Rect},
|
||||
};
|
||||
use core::slice::from_raw_parts;
|
||||
|
||||
#[cfg(feature = "dma2d")]
|
||||
use crate::trezorhal::{
|
||||
@ -16,9 +15,6 @@ use crate::ui::{
|
||||
display::toif::Icon,
|
||||
};
|
||||
|
||||
pub const LOADER_MIN: u16 = 0;
|
||||
pub const LOADER_MAX: u16 = 1000;
|
||||
|
||||
const LOADER_SIZE: i32 = (LOADER_OUTER * 2.0) as i32;
|
||||
|
||||
const OUTER: f32 = constant::LOADER_OUTER;
|
||||
@ -32,7 +28,7 @@ const INNER_OUTER_ANTI: i32 = ((INNER + 2.5) * (INNER + 2.5)) as i32;
|
||||
const OUTER_OUT_ANTI: i32 = ((OUTER - 1.5) * (OUTER - 1.5)) as i32;
|
||||
const OUTER_MAX: i32 = ((OUTER - 0.5) * (OUTER - 0.5)) as i32;
|
||||
|
||||
pub fn loader_uncompress(
|
||||
pub fn loader_circular_uncompress(
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
@ -47,7 +43,7 @@ pub fn loader_uncompress(
|
||||
if toif_size.x <= ICON_MAX_SIZE && toif_size.y <= ICON_MAX_SIZE {
|
||||
let mut icon_data = [0_u8; ((ICON_MAX_SIZE * ICON_MAX_SIZE) / 2) as usize];
|
||||
icon.toif.uncompress(&mut icon_data);
|
||||
let i = Some((icon, color, toif_size));
|
||||
let i = Some((icon_data.as_ref(), color, toif_size));
|
||||
loader_rust(y_offset, fg_color, bg_color, progress, indeterminate, i);
|
||||
} else {
|
||||
loader_rust(y_offset, fg_color, bg_color, progress, indeterminate, None);
|
||||
@ -57,29 +53,24 @@ pub fn loader_uncompress(
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn loader_uncompress_r(
|
||||
y_offset: cty::int32_t,
|
||||
fg_color: cty::uint16_t,
|
||||
bg_color: cty::uint16_t,
|
||||
icon_color: cty::uint16_t,
|
||||
progress: cty::int32_t,
|
||||
indeterminate: cty::int32_t,
|
||||
icon_data: cty::uintptr_t,
|
||||
icon_data_size: cty::uint32_t,
|
||||
pub fn loader_circular(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
let fg = Color::from_u16(fg_color);
|
||||
let bg = Color::from_u16(bg_color);
|
||||
let ic_color = Color::from_u16(icon_color);
|
||||
loader_circular_uncompress(y_offset, fg_color, bg_color, progress, false, icon);
|
||||
}
|
||||
|
||||
let i = if icon_data != 0 {
|
||||
let data_slice = unsafe { from_raw_parts(icon_data as _, icon_data_size as _) };
|
||||
Some((Icon::new(data_slice), ic_color))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
loader_uncompress(y_offset as _, fg, bg, progress as _, indeterminate != 0, i);
|
||||
pub fn loader_circular_indeterminate(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
loader_circular_uncompress(y_offset, fg_color, bg_color, progress, true, icon);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -189,7 +180,7 @@ pub fn loader_rust(
|
||||
bg_color: Color,
|
||||
progress: u16,
|
||||
indeterminate: bool,
|
||||
icon: Option<(Icon, Color, Offset)>,
|
||||
icon: Option<(&[u8], Color, Offset)>,
|
||||
) {
|
||||
let center = screen().center() + Offset::new(0, y_offset);
|
||||
let r = Rect::from_center_and_size(center, Offset::uniform(LOADER_OUTER as i16 * 2));
|
||||
@ -205,14 +196,14 @@ pub fn loader_rust(
|
||||
let mut icon_area = Rect::zero();
|
||||
let mut icon_area_clamped = Rect::zero();
|
||||
let mut icon_width = 0;
|
||||
let mut icon_data = None;
|
||||
let mut icon_data = [].as_ref();
|
||||
|
||||
if let Some((data, color, size)) = icon {
|
||||
if size.x <= ICON_MAX_SIZE && size.y <= ICON_MAX_SIZE {
|
||||
icon_width = size.x;
|
||||
icon_area = Rect::from_center_and_size(center, size);
|
||||
icon_area_clamped = icon_area.clamp(constant::screen());
|
||||
icon_data = Some(data);
|
||||
icon_data = data;
|
||||
use_icon = true;
|
||||
icon_colortable = display::get_color_table(color, bg_color);
|
||||
}
|
||||
@ -238,8 +229,7 @@ pub fn loader_rust(
|
||||
let x_i = x_c - icon_area.x0;
|
||||
let y_i = y_c - icon_area.y0;
|
||||
|
||||
let data = unwrap!(icon_data).zdata()
|
||||
[(((x_i & 0xFE) + (y_i * icon_width)) / 2) as usize];
|
||||
let data = icon_data[(((x_i & 0xFE) + (y_i * icon_width)) / 2) as usize];
|
||||
if (x_i & 0x01) == 0 {
|
||||
underlying_color = icon_colortable[(data & 0xF) as usize];
|
||||
} else {
|
||||
@ -270,7 +260,7 @@ pub fn loader_rust(
|
||||
bg_color: Color,
|
||||
progress: u16,
|
||||
indeterminate: bool,
|
||||
icon: Option<(Icon, Color, Offset)>,
|
||||
icon: Option<(&[u8], Color, Offset)>,
|
||||
) {
|
||||
let center = screen().center() + Offset::new(0, y_offset);
|
||||
let r = Rect::from_center_and_size(center, Offset::uniform(LOADER_OUTER as i16 * 2));
|
||||
@ -285,16 +275,16 @@ pub fn loader_rust(
|
||||
let mut icon_width = 0;
|
||||
let mut icon_offset = 0;
|
||||
let mut icon_color = Color::from_u16(0);
|
||||
let mut icon_data = None;
|
||||
let mut icon_data = [].as_ref();
|
||||
|
||||
if let Some((icon, color, size)) = icon {
|
||||
if let Some((data, color, size)) = icon {
|
||||
if size.x <= ICON_MAX_SIZE && size.y <= ICON_MAX_SIZE {
|
||||
icon_width = size.x;
|
||||
icon_area = Rect::from_center_and_size(center, size);
|
||||
icon_area_clamped = icon_area.clamp(constant::screen());
|
||||
icon_offset = (icon_area_clamped.x0 - r.x0) / 2;
|
||||
icon_color = color;
|
||||
icon_data = Some(icon);
|
||||
icon_data = data;
|
||||
use_icon = true;
|
||||
}
|
||||
}
|
||||
@ -338,7 +328,7 @@ pub fn loader_rust(
|
||||
|
||||
icon_buffer_used.buffer[icon_offset as usize..(icon_offset + icon_width / 2) as usize]
|
||||
.copy_from_slice(
|
||||
&unwrap!(icon_data).toif.zdata()[(y_i * (icon_width / 2)) as usize
|
||||
&icon_data[(y_i * (icon_width / 2)) as usize
|
||||
..((y_i + 1) * (icon_width / 2)) as usize],
|
||||
);
|
||||
icon_buffer = icon_buffer_used;
|
||||
@ -371,23 +361,3 @@ pub fn loader_rust(
|
||||
|
||||
dma2d_wait_for_transfer();
|
||||
}
|
||||
|
||||
pub fn loader(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
loader_uncompress(y_offset, fg_color, bg_color, progress, false, icon);
|
||||
}
|
||||
|
||||
pub fn loader_indeterminate(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
loader_uncompress(y_offset, fg_color, bg_color, progress, true, icon);
|
||||
}
|
68
core/embed/rust/src/ui/display/loader/mod.rs
Normal file
68
core/embed/rust/src/ui/display/loader/mod.rs
Normal file
@ -0,0 +1,68 @@
|
||||
mod circular;
|
||||
mod rectangular;
|
||||
mod starry;
|
||||
|
||||
use crate::ui::display::{Color, Icon};
|
||||
use core::slice::from_raw_parts;
|
||||
|
||||
#[cfg(feature = "model_tt")]
|
||||
use crate::ui::display::loader::circular::{
|
||||
loader_circular as determinate, loader_circular_indeterminate as indeterminate,
|
||||
};
|
||||
#[cfg(not(feature = "model_tt"))]
|
||||
use crate::ui::display::loader::rectangular::loader_rectangular as determinate;
|
||||
#[cfg(not(feature = "model_tt"))]
|
||||
use crate::ui::display::loader::starry::loader_starry_indeterminate as indeterminate;
|
||||
|
||||
pub const LOADER_MIN: u16 = 0;
|
||||
pub const LOADER_MAX: u16 = 1000;
|
||||
|
||||
pub fn loader(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
determinate(progress, y_offset, fg_color, bg_color, icon);
|
||||
}
|
||||
|
||||
pub fn loader_indeterminate(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
indeterminate(progress, y_offset, fg_color, bg_color, icon);
|
||||
}
|
||||
|
||||
//TODO: remove when loader is no longer called from C
|
||||
#[no_mangle]
|
||||
pub extern "C" fn loader_uncompress_r(
|
||||
y_offset: cty::int32_t,
|
||||
fg_color: cty::uint16_t,
|
||||
bg_color: cty::uint16_t,
|
||||
icon_color: cty::uint16_t,
|
||||
progress: cty::int32_t,
|
||||
indeterminate: cty::int32_t,
|
||||
icon_data: cty::uintptr_t,
|
||||
icon_data_size: cty::uint32_t,
|
||||
) {
|
||||
let fg = Color::from_u16(fg_color);
|
||||
let bg = Color::from_u16(bg_color);
|
||||
let ic_color = Color::from_u16(icon_color);
|
||||
|
||||
let i = if icon_data != 0 {
|
||||
let data_slice = unsafe { from_raw_parts(icon_data as _, icon_data_size as _) };
|
||||
Some((Icon::new(data_slice), ic_color))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if indeterminate == 0 {
|
||||
loader(progress as _, y_offset as _, fg, bg, i);
|
||||
} else {
|
||||
loader_indeterminate(progress as _, y_offset as _, fg, bg, i);
|
||||
}
|
||||
}
|
25
core/embed/rust/src/ui/display/loader/rectangular.rs
Normal file
25
core/embed/rust/src/ui/display/loader/rectangular.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::ui::{
|
||||
constant::{screen, LOADER_INNER},
|
||||
display,
|
||||
display::{Color, Icon},
|
||||
geometry::{Offset, Rect},
|
||||
};
|
||||
|
||||
pub fn loader_rectangular(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
let area = Rect::from_center_and_size(screen().center(), Offset::uniform(LOADER_INNER as _))
|
||||
.translate(Offset::y(y_offset));
|
||||
|
||||
display::rect_rounded2_partial(
|
||||
area,
|
||||
fg_color,
|
||||
bg_color,
|
||||
(100 * progress as u32 / 1000) as i16,
|
||||
icon,
|
||||
);
|
||||
}
|
67
core/embed/rust/src/ui/display/loader/starry.rs
Normal file
67
core/embed/rust/src/ui/display/loader/starry.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use crate::ui::{
|
||||
constant::{screen, LOADER_OUTER},
|
||||
display::{rect_fill, rect_fill_rounded, rect_fill_rounded1, Color, Icon},
|
||||
geometry::{Offset, Point, Rect, CENTER},
|
||||
};
|
||||
use core::f32::consts::SQRT_2;
|
||||
|
||||
const SIZE_SMALL: i16 = 2;
|
||||
const SIZE_MEDIUM: i16 = 4;
|
||||
const SIZE_LARGE: i16 = 6;
|
||||
const RADIUS: i16 = 13;
|
||||
const DIAGONAL: i16 = ((RADIUS as f32 * SQRT_2) / 2_f32) as i16;
|
||||
|
||||
fn star_small(center: Point, fg: Color, _bg: Color) {
|
||||
let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_SMALL));
|
||||
rect_fill(r, fg);
|
||||
}
|
||||
|
||||
fn star_medium(center: Point, fg: Color, bg: Color) {
|
||||
let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_MEDIUM));
|
||||
rect_fill_rounded1(r, fg, bg);
|
||||
}
|
||||
|
||||
fn star_large(center: Point, fg: Color, bg: Color) {
|
||||
let r = Rect::from_center_and_size(center, Offset::uniform(SIZE_LARGE));
|
||||
rect_fill_rounded(r, fg, bg, 2);
|
||||
}
|
||||
|
||||
pub fn loader_starry_indeterminate(
|
||||
progress: u16,
|
||||
y_offset: i16,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
) {
|
||||
let area = Rect::from_center_and_size(screen().center(), Offset::uniform(LOADER_OUTER as _))
|
||||
.translate(Offset::y(y_offset));
|
||||
|
||||
rect_fill(area, bg_color);
|
||||
|
||||
let coords = [
|
||||
Point::new(area.center().x, area.center().y - RADIUS),
|
||||
Point::new(area.center().x + DIAGONAL, area.center().y - DIAGONAL),
|
||||
Point::new(area.center().x + RADIUS, area.center().y),
|
||||
Point::new(area.center().x + DIAGONAL, area.center().y + DIAGONAL),
|
||||
Point::new(area.center().x, area.center().y + RADIUS),
|
||||
Point::new(area.center().x - DIAGONAL, area.center().y + DIAGONAL),
|
||||
Point::new(area.center().x - RADIUS, area.center().y),
|
||||
Point::new(area.center().x - DIAGONAL, area.center().y - DIAGONAL),
|
||||
];
|
||||
|
||||
let big_idx = (progress / 125) as usize % 8;
|
||||
|
||||
for (i, c) in coords.iter().enumerate() {
|
||||
if i == big_idx {
|
||||
star_large(*c, fg_color, bg_color);
|
||||
} else if (big_idx + 1) % 8 == i || (big_idx - 1) % 8 == i {
|
||||
star_medium(*c, fg_color, bg_color);
|
||||
} else {
|
||||
star_small(*c, fg_color, bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((icon, color)) = icon {
|
||||
icon.draw(area.center(), CENTER, color, bg_color);
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
#[cfg(any(feature = "model_tt", feature = "model_tr"))]
|
||||
pub mod loader;
|
||||
#[cfg(feature = "jpeg")]
|
||||
pub mod tjpgd;
|
||||
|
@ -5,9 +5,9 @@ pub const HEIGHT: i16 = 128;
|
||||
pub const LINE_SPACE: i16 = 1;
|
||||
pub const FONT_BPP: i16 = 1;
|
||||
|
||||
pub const LOADER_OUTER: f32 = 20_f32;
|
||||
pub const LOADER_INNER: f32 = 14_f32;
|
||||
pub const LOADER_ICON_MAX_SIZE: i16 = 24;
|
||||
pub const LOADER_OUTER: f32 = 32_f32;
|
||||
pub const LOADER_INNER: f32 = 18_f32;
|
||||
pub const LOADER_ICON_MAX_SIZE: i16 = 8;
|
||||
|
||||
pub const fn size() -> Offset {
|
||||
Offset::new(WIDTH, HEIGHT)
|
||||
|
Loading…
Reference in New Issue
Block a user