/* * Copyright (C) 2023 Kyle Reed * Copyright (C) 2023 Mark Thompson * * 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. */ #include "ui_ss_viewer.hpp" using namespace portapack; namespace fs = std::filesystem; namespace ui { const std::filesystem::path splash_dot_bmp{u"/splash.bmp"}; ScreenshotViewer::ScreenshotViewer( NavigationView& nav, const std::filesystem::path& path) : nav_{nav}, path_{path} { set_focusable(true); } bool ScreenshotViewer::on_key(KeyEvent) { nav_.pop(); return true; } void ScreenshotViewer::paint(Painter& painter) { File file{}; painter.fill_rectangle({0, 0, screen_width, screen_height}, Color::black()); auto show_invalid = [&]() { painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, "Not a valid screenshot."); }; auto error = file.open(path_); if (error) { painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, error->what()); return; } // Screenshots from PNGWriter are all this size. if (file.size() != 232383) { show_invalid(); return; } constexpr size_t read_chunk = 80; // NB: must be a factor of pixel_width. constexpr size_t buffer_size = sizeof(ColorRGB888) * read_chunk; uint8_t buffer[buffer_size]; std::array pixel_data; // Seek past all the headers. file.seek(43); for (auto line = 0u; line < screen_height; ++line) { // Seek past the per-line header. file.seek(file.tell() + 6); // Per comment in PNGWriter, read in chunks of 80. // NB: Reading in one large chunk caused corruption so there's // likely a bug lurking in the SD Card/FatFs layer. for (auto offset = 0u; offset < screen_width; offset += read_chunk) { auto read = file.read(buffer, buffer_size); if (!read || *read != buffer_size) { show_invalid(); return; } auto c8 = (ColorRGB888*)buffer; for (auto i = 0u; i < read_chunk; ++i) { pixel_data[i + offset] = Color(c8->r, c8->g, c8->b); ++c8; } } display.draw_pixels({0, (int)line, screen_width, 1}, pixel_data); } } SplashViewer::SplashViewer( NavigationView& nav, const std::filesystem::path& path) : nav_{nav}, path_{path} { valid_image = false; set_focusable(true); } bool SplashViewer::on_key(const KeyEvent key) { if (valid_image && key == KeyEvent::Right) { delete_file(splash_dot_bmp); copy_file(path_, splash_dot_bmp); } nav_.pop(); return true; } void SplashViewer::paint(Painter& painter) { painter.fill_rectangle({0, 0, screen_width, screen_height}, Color::black()); if (!portapack::display.draw_bmp_from_sdcard_file({0, 0}, path_)) { painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, "Not a valid splash image."); return; } // Show option to set splash screen if it's not already the splash screen if (!path_iequal(path_, splash_dot_bmp)) { painter.draw_string({0, 0}, *Theme::getInstance()->bg_darkest, "*RIGHT BUTTON UPDATES SPLASH*"); valid_image = true; } } } // namespace ui