diff --git a/embed/extmod/modtrezorui/display-unix.h b/embed/extmod/modtrezorui/display-unix.h index 587bff4a10..a2df8cbee7 100644 --- a/embed/extmod/modtrezorui/display-unix.h +++ b/embed/extmod/modtrezorui/display-unix.h @@ -25,17 +25,21 @@ #define EMULATOR_BORDER 16 #if TREZOR_MODEL == T + #define WINDOW_WIDTH 400 #define WINDOW_HEIGHT 600 #define TOUCH_OFFSET_X 80 #define TOUCH_OFFSET_Y 110 + #elif TREZOR_MODEL == 1 + #define WINDOW_WIDTH 200 #define WINDOW_HEIGHT 340 #define TOUCH_OFFSET_X 36 #define TOUCH_OFFSET_Y 92 + #else -#error Unknown TREZOR model +#error Unknown TREZOR Model #endif static SDL_Renderer *RENDERER; diff --git a/embed/extmod/modtrezorui/display.c b/embed/extmod/modtrezorui/display.c index afafdc1093..2a3ee99b09 100644 --- a/embed/extmod/modtrezorui/display.c +++ b/embed/extmod/modtrezorui/display.c @@ -281,6 +281,76 @@ void display_icon(int x, int y, int w, int h, const void *data, int datalen, uin sinf_inflate(data, datalen, inflate_callback_icon, userdata); } +#include "loader.h" + +static void inflate_callback_loader(uint8_t byte, uint32_t pos, void *userdata) +{ + uint8_t *out = (uint8_t *)userdata; + out[pos] = byte; +} + +void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor) +{ + uint16_t colortable[16], iconcolortable[16]; + set_color_table(colortable, fgcolor, bgcolor); + if (icon) { + set_color_table(iconcolortable, iconfgcolor, bgcolor); + } + if ((DISPLAY_RESY / 2 - img_loader_size + yoffset < 0) || + (DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset >= DISPLAY_RESY)) { + return; + } + display_set_window(DISPLAY_RESX / 2 - img_loader_size, DISPLAY_RESY / 2 - img_loader_size + yoffset, DISPLAY_RESX / 2 + img_loader_size - 1, DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset); + if (icon && memcmp(icon, "TOIg", 4) == 0 && LOADER_ICON_SIZE == *(uint16_t *)(icon + 4) && LOADER_ICON_SIZE == *(uint16_t *)(icon + 6) && iconlen == 12 + *(uint32_t *)(icon + 8)) { + uint8_t icondata[LOADER_ICON_SIZE * LOADER_ICON_SIZE / 2]; + sinf_inflate(icon + 12, iconlen - 12, inflate_callback_loader, icondata); + icon = icondata; + } else { + icon = NULL; + } + for (int y = 0; y < img_loader_size * 2; y++) { + for (int x = 0; x < img_loader_size * 2; x++) { + int mx = x, my = y; + uint16_t a; + if ((mx >= img_loader_size) && (my >= img_loader_size)) { + mx = img_loader_size * 2 - 1 - x; + my = img_loader_size * 2 - 1 - y; + a = 499 - (img_loader[my][mx] >> 8); + } else + if (mx >= img_loader_size) { + mx = img_loader_size * 2 - 1 - x; + a = img_loader[my][mx] >> 8; + } else + if (my >= img_loader_size) { + my = img_loader_size * 2 - 1 - y; + a = 500 + (img_loader[my][mx] >> 8); + } else { + a = 999 - (img_loader[my][mx] >> 8); + } + // inside of circle - draw glyph + #define LOADER_ICON_CORNER_CUT 2 + if (icon && mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) && mx >= img_loader_size - (LOADER_ICON_SIZE / 2) && my >= img_loader_size - (LOADER_ICON_SIZE / 2)) { + int i = (x - (img_loader_size - (LOADER_ICON_SIZE / 2))) + (y - (img_loader_size - (LOADER_ICON_SIZE / 2))) * LOADER_ICON_SIZE; + uint8_t c; + if (i % 2) { + c = icon[i / 2] & 0x0F; + } else { + c = (icon[i / 2] & 0xF0) >> 4; + } + PIXELDATA(iconcolortable[c]); + } else { + uint8_t c; + if (progress > a) { + c = (img_loader[my][mx] & 0x00F0) >> 4; + } else { + c = img_loader[my][mx] & 0x000F; + } + PIXELDATA(colortable[c]); + } + } + } +} + static const uint8_t *get_glyph(int font, uint8_t c) { if (c >= ' ' && c <= '~') { @@ -538,76 +608,6 @@ void display_qrcode(int x, int y, const char *data, int datalen, uint8_t scale) } } -#include "loader.h" - -static void inflate_callback_loader(uint8_t byte, uint32_t pos, void *userdata) -{ - uint8_t *out = (uint8_t *)userdata; - out[pos] = byte; -} - -void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor) -{ - uint16_t colortable[16], iconcolortable[16]; - set_color_table(colortable, fgcolor, bgcolor); - if (icon) { - set_color_table(iconcolortable, iconfgcolor, bgcolor); - } - if ((DISPLAY_RESY / 2 - img_loader_size + yoffset < 0) || - (DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset >= DISPLAY_RESY)) { - return; - } - display_set_window(DISPLAY_RESX / 2 - img_loader_size, DISPLAY_RESY / 2 - img_loader_size + yoffset, DISPLAY_RESX / 2 + img_loader_size - 1, DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset); - if (icon && memcmp(icon, "TOIg", 4) == 0 && LOADER_ICON_SIZE == *(uint16_t *)(icon + 4) && LOADER_ICON_SIZE == *(uint16_t *)(icon + 6) && iconlen == 12 + *(uint32_t *)(icon + 8)) { - uint8_t icondata[LOADER_ICON_SIZE * LOADER_ICON_SIZE / 2]; - sinf_inflate(icon + 12, iconlen - 12, inflate_callback_loader, icondata); - icon = icondata; - } else { - icon = NULL; - } - for (int y = 0; y < img_loader_size * 2; y++) { - for (int x = 0; x < img_loader_size * 2; x++) { - int mx = x, my = y; - uint16_t a; - if ((mx >= img_loader_size) && (my >= img_loader_size)) { - mx = img_loader_size * 2 - 1 - x; - my = img_loader_size * 2 - 1 - y; - a = 499 - (img_loader[my][mx] >> 8); - } else - if (mx >= img_loader_size) { - mx = img_loader_size * 2 - 1 - x; - a = img_loader[my][mx] >> 8; - } else - if (my >= img_loader_size) { - my = img_loader_size * 2 - 1 - y; - a = 500 + (img_loader[my][mx] >> 8); - } else { - a = 999 - (img_loader[my][mx] >> 8); - } - // inside of circle - draw glyph - #define LOADER_ICON_CORNER_CUT 2 - if (icon && mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) && mx >= img_loader_size - (LOADER_ICON_SIZE / 2) && my >= img_loader_size - (LOADER_ICON_SIZE / 2)) { - int i = (x - (img_loader_size - (LOADER_ICON_SIZE / 2))) + (y - (img_loader_size - (LOADER_ICON_SIZE / 2))) * LOADER_ICON_SIZE; - uint8_t c; - if (i % 2) { - c = icon[i / 2] & 0x0F; - } else { - c = (icon[i / 2] & 0xF0) >> 4; - } - PIXELDATA(iconcolortable[c]); - } else { - uint8_t c; - if (progress > a) { - c = (img_loader[my][mx] & 0x00F0) >> 4; - } else { - c = img_loader[my][mx] & 0x000F; - } - PIXELDATA(colortable[c]); - } - } - } -} - void display_offset(int set_xy[2], int *get_x, int *get_y) { if (set_xy) { @@ -621,7 +621,13 @@ void display_offset(int set_xy[2], int *get_x, int *get_y) int display_orientation(int degrees) { if (degrees != DISPLAY_ORIENTATION) { +#if TREZOR_MODEL == T if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) { +#elif TREZOR_MODEL == 1 + if (degrees == 0 || degrees == 180) { +#else +#error Unknown TREZOR model +#endif DISPLAY_ORIENTATION = degrees; display_set_orientation(degrees); } diff --git a/embed/extmod/modtrezorui/display.h b/embed/extmod/modtrezorui/display.h index 2feb7fcfb8..d11c7e1210 100644 --- a/embed/extmod/modtrezorui/display.h +++ b/embed/extmod/modtrezorui/display.h @@ -22,37 +22,47 @@ #include -// ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution -#define MAX_DISPLAY_RESX 240 -#define MAX_DISPLAY_RESY 320 -// X and Y display resolution used -#define DISPLAY_RESX 240 -#define DISPLAY_RESY 240 +#if TREZOR_MODEL == T -#define FONT_BPP 4 -#define FONT_SIZE 20 +// ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution +#define MAX_DISPLAY_RESX 240 +#define MAX_DISPLAY_RESY 320 +#define DISPLAY_RESX 240 +#define DISPLAY_RESY 240 + +#elif TREZOR_MODEL == 1 + +#define MAX_DISPLAY_RESX 128 +#define MAX_DISPLAY_RESY 64 +#define DISPLAY_RESX 128 +#define DISPLAY_RESY 64 + +#else +#error Unknown TREZOR Model +#endif + +#define FONT_BPP 4 +#define FONT_SIZE 20 +#define AVATAR_IMAGE_SIZE 144 +#define LOADER_ICON_SIZE 64 + +#define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3) +#define COLOR_WHITE 0xFFFF +#define COLOR_BLACK 0x0000 #ifdef TREZOR_FONT_NORMAL_ENABLE -#define FONT_NORMAL (-1) +#define FONT_NORMAL (-1) #endif #ifdef TREZOR_FONT_BOLD_ENABLE -#define FONT_BOLD (-2) +#define FONT_BOLD (-2) #endif #ifdef TREZOR_FONT_MONO_ENABLE -#define FONT_MONO (-3) +#define FONT_MONO (-3) #endif #ifdef TREZOR_FONT_MONO_BOLD_ENABLE -#define FONT_MONO_BOLD (-4) +#define FONT_MONO_BOLD (-4) #endif -#define AVATAR_IMAGE_SIZE 144 -#define LOADER_ICON_SIZE 64 - -#define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3) - -#define COLOR_WHITE RGB16(0xFF, 0xFF, 0xFF) -#define COLOR_BLACK RGB16(0x00, 0x00, 0x00) - // provided by port void display_init(void); @@ -69,6 +79,7 @@ void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint void display_image(int x, int y, int w, int h, const void *data, int datalen); void display_avatar(int x, int y, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor); void display_icon(int x, int y, int w, int h, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor); +void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor); #ifndef TREZOR_PRINT_DISABLE void display_print_color(uint16_t fgcolor, uint16_t bgcolor); @@ -82,7 +93,6 @@ void display_text_right(int x, int y, const char *text, int textlen, int font, u int display_text_width(const char *text, int textlen, int font); void display_qrcode(int x, int y, const char *data, int datalen, uint8_t scale); -void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor); void display_offset(int set_xy[2], int *get_x, int *get_y); int display_orientation(int degrees); diff --git a/embed/extmod/modtrezorui/modtrezorui-display.h b/embed/extmod/modtrezorui/modtrezorui-display.h index 7a1db59198..b571320f49 100644 --- a/embed/extmod/modtrezorui/modtrezorui-display.h +++ b/embed/extmod/modtrezorui/modtrezorui-display.h @@ -174,7 +174,49 @@ STATIC mp_obj_t mod_trezorui_Display_icon(size_t n_args, const mp_obj_t *args) { display_icon(x, y, w, h, data + 12, icon.len - 12, fgcolor, bgcolor); return mp_const_none; } + STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6, mod_trezorui_Display_icon); +/// def loader(self, progress: int, yoffset: int, fgcolor: int, bgcolor: int, icon: bytes = None, iconfgcolor: int = None) -> None: +/// ''' +/// Renders a rotating loader graphic. +/// Progress determines its position (0-1000), fgcolor is used as foreground color, bgcolor as background. +/// When icon and iconfgcolor are provided, an icon is drawn in the middle using the color specified in iconfgcolor. +/// Icon needs to be of exactly LOADER_ICON_SIZE x LOADER_ICON_SIZE pixels size. +/// ''' +STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args, const mp_obj_t *args) { + mp_int_t progress = mp_obj_get_int(args[1]); + mp_int_t yoffset = mp_obj_get_int(args[2]); + mp_int_t fgcolor = mp_obj_get_int(args[3]); + mp_int_t bgcolor = mp_obj_get_int(args[4]); + if (n_args > 5) { // icon provided + mp_buffer_info_t icon; + mp_get_buffer_raise(args[5], &icon, MP_BUFFER_READ); + const uint8_t *data = icon.buf; + if (icon.len < 8 || memcmp(data, "TOIg", 4) != 0) { + mp_raise_ValueError("Invalid image format"); + } + mp_int_t w = *(uint16_t *)(data + 4); + mp_int_t h = *(uint16_t *)(data + 6); + mp_int_t datalen = *(uint32_t *)(data + 8); + if (w != LOADER_ICON_SIZE || h != LOADER_ICON_SIZE) { + mp_raise_ValueError("Invalid icon size"); + } + if (datalen != icon.len - 12) { + mp_raise_ValueError("Invalid size of data"); + } + uint16_t iconfgcolor; + if (n_args > 6) { // icon color provided + iconfgcolor = mp_obj_get_int(args[6]); + } else { + iconfgcolor = ~bgcolor; // invert + } + display_loader(progress, yoffset, fgcolor, bgcolor, icon.buf, icon.len, iconfgcolor); + } else { + display_loader(progress, yoffset, fgcolor, bgcolor, NULL, 0, 0); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 5, 7, mod_trezorui_Display_loader); /// def print(self, text: str) -> None: /// ''' @@ -302,48 +344,6 @@ STATIC mp_obj_t mod_trezorui_Display_qrcode(size_t n_args, const mp_obj_t *args) } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_qrcode_obj, 5, 5, mod_trezorui_Display_qrcode); -/// def loader(self, progress: int, yoffset: int, fgcolor: int, bgcolor: int, icon: bytes = None, iconfgcolor: int = None) -> None: -/// ''' -/// Renders a rotating loader graphic. -/// Progress determines its position (0-1000), fgcolor is used as foreground color, bgcolor as background. -/// When icon and iconfgcolor are provided, an icon is drawn in the middle using the color specified in iconfgcolor. -/// Icon needs to be of exactly LOADER_ICON_SIZE x LOADER_ICON_SIZE pixels size. -/// ''' -STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args, const mp_obj_t *args) { - mp_int_t progress = mp_obj_get_int(args[1]); - mp_int_t yoffset = mp_obj_get_int(args[2]); - mp_int_t fgcolor = mp_obj_get_int(args[3]); - mp_int_t bgcolor = mp_obj_get_int(args[4]); - if (n_args > 5) { // icon provided - mp_buffer_info_t icon; - mp_get_buffer_raise(args[5], &icon, MP_BUFFER_READ); - const uint8_t *data = icon.buf; - if (icon.len < 8 || memcmp(data, "TOIg", 4) != 0) { - mp_raise_ValueError("Invalid image format"); - } - mp_int_t w = *(uint16_t *)(data + 4); - mp_int_t h = *(uint16_t *)(data + 6); - mp_int_t datalen = *(uint32_t *)(data + 8); - if (w != LOADER_ICON_SIZE || h != LOADER_ICON_SIZE) { - mp_raise_ValueError("Invalid icon size"); - } - if (datalen != icon.len - 12) { - mp_raise_ValueError("Invalid size of data"); - } - uint16_t iconfgcolor; - if (n_args > 6) { // icon color provided - iconfgcolor = mp_obj_get_int(args[6]); - } else { - iconfgcolor = ~bgcolor; // invert - } - display_loader(progress, yoffset, fgcolor, bgcolor, icon.buf, icon.len, iconfgcolor); - } else { - display_loader(progress, yoffset, fgcolor, bgcolor, NULL, 0, 0); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 5, 7, mod_trezorui_Display_loader); - /// def orientation(self, degrees: int = None) -> int: /// ''' /// Sets display orientation to 0, 90, 180 or 270 degrees. @@ -438,13 +438,13 @@ STATIC const mp_rom_map_elem_t mod_trezorui_Display_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_image), MP_ROM_PTR(&mod_trezorui_Display_image_obj) }, { MP_ROM_QSTR(MP_QSTR_avatar), MP_ROM_PTR(&mod_trezorui_Display_avatar_obj) }, { MP_ROM_QSTR(MP_QSTR_icon), MP_ROM_PTR(&mod_trezorui_Display_icon_obj) }, + { MP_ROM_QSTR(MP_QSTR_loader), MP_ROM_PTR(&mod_trezorui_Display_loader_obj) }, { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mod_trezorui_Display_print_obj) }, { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&mod_trezorui_Display_text_obj) }, { MP_ROM_QSTR(MP_QSTR_text_center), MP_ROM_PTR(&mod_trezorui_Display_text_center_obj) }, { MP_ROM_QSTR(MP_QSTR_text_right), MP_ROM_PTR(&mod_trezorui_Display_text_right_obj) }, { MP_ROM_QSTR(MP_QSTR_text_width), MP_ROM_PTR(&mod_trezorui_Display_text_width_obj) }, { MP_ROM_QSTR(MP_QSTR_qrcode), MP_ROM_PTR(&mod_trezorui_Display_qrcode_obj) }, - { MP_ROM_QSTR(MP_QSTR_loader), MP_ROM_PTR(&mod_trezorui_Display_loader_obj) }, { MP_ROM_QSTR(MP_QSTR_orientation), MP_ROM_PTR(&mod_trezorui_Display_orientation_obj) }, { MP_ROM_QSTR(MP_QSTR_backlight), MP_ROM_PTR(&mod_trezorui_Display_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_offset), MP_ROM_PTR(&mod_trezorui_Display_offset_obj) },