diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 7157060ee..f2558eeb3 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -21,7 +21,7 @@ */ // Bitmaps generated with: -// Gimp :( > indexed colors, then "xxd -i *.bmp" +// Gimp image > indexed colors (16), then "xxd -i *.bmp" //BUG: No audio in about when shown second time //BUG: Description doesn't show up first time going to system>module info (UI drawn on top) diff --git a/firmware/application/splash.hpp b/firmware/application/splash.hpp index 4891e7a90..0c9fe567e 100644 --- a/firmware/application/splash.hpp +++ b/firmware/application/splash.hpp @@ -1,3 +1,25 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + const unsigned char splash_bmp[] = { 0x42, 0x4d, 0x28, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x1b, 0x01, diff --git a/firmware/application/ui_alphanum.cpp b/firmware/application/ui_alphanum.cpp index b44dab7f1..c4155ff97 100644 --- a/firmware/application/ui_alphanum.cpp +++ b/firmware/application/ui_alphanum.cpp @@ -106,12 +106,12 @@ AlphanumView::AlphanumView( } }; - /*add_child(&raw_char); + add_child(&raw_char); raw_char.set_value(0x30); - raw_char.on_select = [this, &nav, txt, max_len](Button&) { + raw_char.on_select = [this, &nav, txt, max_len](NumberField&) { char_add(raw_char.value()); update_text(); - };*/ + }; add_child(&button_done); button_done.on_select = [this, &nav, txt, max_len](Button&) { diff --git a/firmware/application/ui_alphanum.hpp b/firmware/application/ui_alphanum.hpp index 108927503..24aed4d01 100644 --- a/firmware/application/ui_alphanum.hpp +++ b/firmware/application/ui_alphanum.hpp @@ -73,13 +73,13 @@ private: "UC" }; - /*NumberField raw_char { - { 16, 270, 16, 16 }, + NumberField raw_char { + { 16, 270 }, 3, { 1, 255 }, 1, '0' - };*/ + }; Button button_done { { 88, 270, 64, 24 }, diff --git a/firmware/application/ui_lcr.cpp b/firmware/application/ui_lcr.cpp index e1aac9bb4..3b71d75b7 100644 --- a/firmware/application/ui_lcr.cpp +++ b/firmware/application/ui_lcr.cpp @@ -123,7 +123,11 @@ void LCRView::generate_message() { // Alt format for (dp = 0; dp < strlen(lcr_message); dp++) { pp = pm; - cur_byte = alt_lookup[(uint8_t)lcr_message[dp] & 0x7F]; + // Do not apply LUT on checksum (last byte) ? + if (dp != strlen(lcr_message) - 1) + cur_byte = alt_lookup[(uint8_t)lcr_message[dp] & 0x7F]; + else + cur_byte = lcr_message[dp]; for (cp = 0; cp < 8; cp++) { if ((cur_byte >> cp) & 1) pp++; } diff --git a/firmware/application/ui_lcr.hpp b/firmware/application/ui_lcr.hpp index 5fe698a7f..ffc879694 100644 --- a/firmware/application/ui_lcr.hpp +++ b/firmware/application/ui_lcr.hpp @@ -92,7 +92,7 @@ private: // 9: 85 ? const char alt_lookup[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, // 0 + 0, 0, 0, 0x5F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 0xF8, 0, 0x99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 !"#$%&'()*+,-./ 0xF5, 0, 0x94, 0x55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, // 30 0123456789:;<=>? diff --git a/firmware/common/lcd_ili9341.cpp b/firmware/common/lcd_ili9341.cpp index 5dca2d3a6..8826d717f 100644 --- a/firmware/common/lcd_ili9341.cpp +++ b/firmware/common/lcd_ili9341.cpp @@ -289,58 +289,45 @@ void ILI9341::render_box(const ui::Point p, const ui::Size s, const ui::Color* l io.lcd_write_pixels(line_buffer, s.w * s.h); } +// RLE_4 BMP loader (delta not implemented) void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool transparency) { - uint32_t pixel_data, pal_data; - uint8_t pal, by, c, count, transp_idx = 0, color_r, color_g, color_b; - ui::Color linebuffer[240]; + const bmp_t * bmp_header = (const bmp_t *)bitmap; + uint32_t data_idx; + uint8_t by, c, count, transp_idx = 0; + ui::Color line_buffer[240]; ui::Coord px = 0, py; ui::Color palette[16]; - uint32_t bmpwidth, bmpheight; - // RLE_4 BMP loader with no delta :( - - if (bitmap[0x1E] != 2) return; // Bad compression type - - bmpwidth = static_cast( - (bitmap[0x12]) | - (bitmap[0x13] << 8) | - (bitmap[0x14] << 16)| - (bitmap[0x15] << 24) ); - bmpheight = static_cast( - (bitmap[0x16]) | - (bitmap[0x17] << 8) | - (bitmap[0x18] << 16)| - (bitmap[0x19] << 24) ); + // Abort if bad depth or no RLE + if ((bmp_header->bpp != 4) || + (bmp_header->compression != 2)) return; - pal_data = bitmap[0x0E] + 0x0E; - - pixel_data = bitmap[0x0A]; - pal = 0; - for (c = 0; c < (16*4); c+=4) { - color_r = bitmap[c+2+pal_data]; - color_g = bitmap[c+1+pal_data]; - color_b = bitmap[c+pal_data]; - palette[pal] = ui::Color(color_r, color_g, color_b); - if ((color_r == 0xFF) && (color_g == 0x00) && (color_b == 0xFF)) transp_idx = pal; - pal++; + data_idx = bmp_header->image_data; + + // Convert palette and find pure magenta index (alpha color key) + for (c = 0; c < 16; c++) { + palette[c] = ui::Color(bmp_header->palette[c].R, bmp_header->palette[c].G, bmp_header->palette[c].B); + if ((bmp_header->palette[c].R == 0xFF) && + (bmp_header->palette[c].G == 0x00) && + (bmp_header->palette[c].B == 0xFF)) transp_idx = c; } if (!transparency) { - py = bmpheight + 16; // +1 ? + py = bmp_header->height + 16; do { - by = bitmap[pixel_data++]; + by = bitmap[data_idx++]; if (by) { - count = by; - by = bitmap[pixel_data++]; - for (c = 0; c < count; c+=2) { - linebuffer[px++] = palette[by >> 4]; - if (px < bmpwidth) linebuffer[px++] = palette[by & 15]; + count = by >> 1; + by = bitmap[data_idx++]; + for (c = 0; c < count; c++) { + line_buffer[px++] = palette[by >> 4]; + if (px < bmp_header->width) line_buffer[px++] = palette[by & 15]; } - if (pixel_data & 1) pixel_data++; + if (data_idx & 1) data_idx++; } else { - by = bitmap[pixel_data++]; + by = bitmap[data_idx++]; if (by == 0) { - render_line({p.x, p.y + py}, bmpwidth, linebuffer); + render_line({p.x, p.y + py}, bmp_header->width, line_buffer); py--; px = 0; } else if (by == 1) { @@ -348,34 +335,34 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran } else if (by == 2) { // Delta } else { - count = by; - for (c = 0; c < count; c+=2) { - by = bitmap[pixel_data++]; - linebuffer[px++] = palette[by >> 4]; - if (px < bmpwidth) linebuffer[px++] = palette[by & 15]; + count = by >> 1; + for (c = 0; c < count; c++) { + by = bitmap[data_idx++]; + line_buffer[px++] = palette[by >> 4]; + if (px < bmp_header->width) line_buffer[px++] = palette[by & 15]; } - if (pixel_data & 1) pixel_data++; + if (data_idx & 1) data_idx++; } } } while (1); } else { - py = bmpheight; // +1 ? + py = bmp_header->height; do { - by = bitmap[pixel_data++]; + by = bitmap[data_idx++]; if (by) { - count = by; - by = bitmap[pixel_data++]; - for (c = 0; c < count; c+=2) { + count = by >> 1; + by = bitmap[data_idx++]; + for (c = 0; c < count; c++) { if ((by >> 4) != transp_idx) draw_pixel({static_cast(p.x + px), static_cast(p.y + py)}, palette[by >> 4]); px++; - if (px < bmpwidth) { + if (px < bmp_header->width) { if ((by & 15) != transp_idx) draw_pixel({static_cast(p.x + px), static_cast(p.y + py)}, palette[by & 15]); } px++; } - if (pixel_data & 1) pixel_data++; + if (data_idx & 1) data_idx++; } else { - by = bitmap[pixel_data++]; + by = bitmap[data_idx++]; if (by == 0) { py--; px = 0; @@ -384,17 +371,17 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran } else if (by == 2) { // Delta } else { - count = by; - for (c = 0; c < count; c+=2) { - by = bitmap[pixel_data++]; + count = by >> 1; + for (c = 0; c < count; c++) { + by = bitmap[data_idx++]; if ((by >> 4) != transp_idx) draw_pixel({static_cast(p.x + px), static_cast(p.y + py)}, palette[by >> 4]); px++; - if (px < bmpwidth) { + if (px < bmp_header->width) { if ((by & 15) != transp_idx) draw_pixel({static_cast(p.x + px), static_cast(p.y + py)}, palette[by & 15]); } px++; } - if (pixel_data & 1) pixel_data++; + if (data_idx & 1) data_idx++; } } } while (1); diff --git a/firmware/common/lcd_ili9341.hpp b/firmware/common/lcd_ili9341.hpp index a3d29f212..534d6da2c 100644 --- a/firmware/common/lcd_ili9341.hpp +++ b/firmware/common/lcd_ili9341.hpp @@ -109,6 +109,33 @@ private: uint16_t height; uint16_t current_position; }; + + #pragma pack(push, 1) + struct bmp_t { + uint16_t signature; + uint32_t size; + uint16_t reserved_1; + uint16_t reserved_2; + uint32_t image_data; + uint32_t BIH_size; + uint32_t width; + uint32_t height; + uint16_t planes; + uint16_t bpp; + uint32_t compression; + uint32_t data_size; + uint32_t h_res; + uint32_t v_res; + uint32_t colors_count; + uint32_t icolors_count; + struct palette { + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t A; + } palette[16]; + }; + #pragma pack(pop) scroll_t scroll_state; diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index d25b2cdad..f02f3826e 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -820,7 +820,6 @@ bool ImageButton::on_touch(const TouchEvent event) { set_dirty(); return true; - case TouchEvent::Type::End: set_highlighted(false); set_dirty(); @@ -1040,12 +1039,12 @@ void NumberField::paint(Painter& painter) { } bool NumberField::on_key(const KeyEvent key) { - /*if( key == KeyEvent::Select ) { + if( key == KeyEvent::Select ) { if( on_select ) { on_select(*this); return true; } - }*/ + } return false; } diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index 7d3f6aaa8..2c66df8d3 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -403,6 +403,7 @@ private: class NumberField : public Widget { public: + std::function on_select; std::function on_change; using range_t = std::pair; diff --git a/firmware/portapack-h1-firmware.bin b/firmware/portapack-h1-firmware.bin index 11aba67d4..6ae7006c5 100644 Binary files a/firmware/portapack-h1-firmware.bin and b/firmware/portapack-h1-firmware.bin differ