mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-13 14:55:29 +00:00
Prepare for display orientation part 1 (#2661)
This commit is contained in:
@@ -34,7 +34,7 @@ namespace lcd {
|
||||
|
||||
class ILI9341 {
|
||||
public:
|
||||
constexpr ILI9341()
|
||||
ILI9341()
|
||||
: scroll_state{0, 0, height(), 0} {
|
||||
}
|
||||
|
||||
@@ -72,12 +72,23 @@ class ILI9341 {
|
||||
draw_pixels(r, colors.data(), colors.size());
|
||||
}
|
||||
|
||||
void draw_pixels(
|
||||
const ui::Rect r,
|
||||
const std::vector<ui::Color>& colors) {
|
||||
draw_pixels(r, colors.data(), colors.size());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void read_pixels(
|
||||
const ui::Rect r,
|
||||
std::array<ui::ColorRGB888, N>& colors) {
|
||||
read_pixels(r, colors.data(), colors.size());
|
||||
}
|
||||
void read_pixels(
|
||||
const ui::Rect r,
|
||||
std::vector<ui::ColorRGB888>& colors) {
|
||||
read_pixels(r, colors.data(), colors.size());
|
||||
}
|
||||
|
||||
void draw_bitmap(
|
||||
const ui::Point p,
|
||||
@@ -138,9 +149,9 @@ class ILI9341 {
|
||||
*/
|
||||
ui::Coord scroll_area_y(const ui::Coord y) const;
|
||||
|
||||
constexpr ui::Dim width() const { return ui::screen_width; }
|
||||
constexpr ui::Dim height() const { return ui::screen_height; }
|
||||
constexpr ui::Rect screen_rect() const { return {0, 0, width(), height()}; }
|
||||
ui::Dim width() { return ui::screen_width; }
|
||||
ui::Dim height() { return ui::screen_height; }
|
||||
ui::Rect screen_rect() { return {0, 0, width(), height()}; }
|
||||
|
||||
void draw_pixels(const ui::Rect r, const ui::Color* const colors, const size_t count);
|
||||
void read_pixels(const ui::Rect r, ui::ColorRGB888* const colors, const size_t count);
|
||||
|
@@ -63,7 +63,32 @@ Optional<File::Error> PNGWriter::create(
|
||||
}
|
||||
|
||||
file.write(png_file_header);
|
||||
file.write(png_ihdr_screen_capture);
|
||||
// ihdr dynamic
|
||||
std::array<uint8_t, 25> png_ihdr_dyn;
|
||||
for (uint8_t i = 0; i < 25; i++) {
|
||||
png_ihdr_dyn[i] = png_ihdr_screen_capture[i];
|
||||
}
|
||||
// Write width (4 bytes big-endian)
|
||||
png_ihdr_dyn[8] = (width >> 24) & 0xFF;
|
||||
png_ihdr_dyn[9] = (width >> 16) & 0xFF;
|
||||
png_ihdr_dyn[10] = (width >> 8) & 0xFF;
|
||||
png_ihdr_dyn[11] = width & 0xFF;
|
||||
|
||||
// Write height (4 bytes big-endian)
|
||||
png_ihdr_dyn[12] = (height >> 24) & 0xFF;
|
||||
png_ihdr_dyn[13] = (height >> 16) & 0xFF;
|
||||
png_ihdr_dyn[14] = (height >> 8) & 0xFF;
|
||||
png_ihdr_dyn[15] = height & 0xFF;
|
||||
crc.reset();
|
||||
crc.process_bytes(png_ihdr_dyn.data(), 25);
|
||||
uint32_t crci = crc.checksum();
|
||||
|
||||
png_ihdr_dyn[21] = (crci >> 24) & 0xFF;
|
||||
png_ihdr_dyn[22] = (crci >> 16) & 0xFF;
|
||||
png_ihdr_dyn[23] = (crci >> 8) & 0xFF;
|
||||
png_ihdr_dyn[24] = crci & 0xFF;
|
||||
|
||||
file.write(png_ihdr_dyn);
|
||||
|
||||
write_chunk_header(
|
||||
2 + height * (5 + 1 + width * 3) + 4,
|
||||
@@ -108,6 +133,35 @@ void PNGWriter::write_scanline(const std::array<ui::ColorRGB888, 240>& scanline)
|
||||
scanline_count++;
|
||||
}
|
||||
|
||||
void PNGWriter::write_scanline(const std::vector<ui::ColorRGB888>& scanline) {
|
||||
constexpr uint8_t scanline_filter_type = 0;
|
||||
|
||||
// Total block length = 1 filter byte + scanline byte length
|
||||
const uint32_t deflate_block_length = 1 + static_cast<uint32_t>(scanline.size() * sizeof(ui::ColorRGB888));
|
||||
|
||||
const std::array<uint8_t, 6> deflate_and_scanline_header{
|
||||
static_cast<uint8_t>((scanline_count == (height - 1)) ? 0x01 : 0x00), // Final block?
|
||||
static_cast<uint8_t>(deflate_block_length & 0xff), // Length LSB
|
||||
static_cast<uint8_t>((deflate_block_length >> 8) & 0xff), // Length MSB
|
||||
static_cast<uint8_t>((deflate_block_length & 0xff) ^ 0xff), // ~Length LSB
|
||||
static_cast<uint8_t>(((deflate_block_length >> 8) & 0xff) ^ 0xff), // ~Length MSB
|
||||
scanline_filter_type};
|
||||
write_chunk_content(deflate_and_scanline_header);
|
||||
|
||||
adler_32.feed(scanline_filter_type);
|
||||
adler_32.feed(scanline);
|
||||
|
||||
// Chunked writing to avoid large single writes
|
||||
constexpr size_t CHUNK_SIZE = 80; // Tune for your hardware/filesystem
|
||||
|
||||
for (size_t i = 0; i < scanline.size(); i += CHUNK_SIZE) {
|
||||
size_t chunk_len = std::min(CHUNK_SIZE, scanline.size() - i);
|
||||
write_chunk_content(&scanline[i], chunk_len * sizeof(ui::ColorRGB888));
|
||||
}
|
||||
|
||||
scanline_count++;
|
||||
}
|
||||
|
||||
void PNGWriter::write_chunk_header(
|
||||
const size_t length,
|
||||
const std::array<uint8_t, 4>& type) {
|
||||
|
@@ -38,11 +38,12 @@ class PNGWriter {
|
||||
Optional<File::Error> create(const std::filesystem::path& filename);
|
||||
|
||||
void write_scanline(const std::array<ui::ColorRGB888, 240>& scanline);
|
||||
void write_scanline(const std::vector<ui::ColorRGB888>& scanline);
|
||||
|
||||
private:
|
||||
// TODO: These constants are baked in a few places, do not change blithely.
|
||||
static constexpr int width{240};
|
||||
static constexpr int height{320};
|
||||
int width{ui::screen_width};
|
||||
int height{ui::screen_height};
|
||||
|
||||
File file{};
|
||||
int scanline_count{0};
|
||||
|
@@ -28,6 +28,9 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
uint16_t screen_width = 240;
|
||||
uint16_t screen_height = 320;
|
||||
|
||||
// CGA palette
|
||||
// Index into this table should match STR_COLOR_ escape string in ui.hpp
|
||||
Color term_colors[16] = {
|
||||
|
@@ -50,8 +50,8 @@ namespace ui {
|
||||
using Coord = int16_t;
|
||||
using Dim = int16_t;
|
||||
|
||||
constexpr uint16_t screen_width = 240;
|
||||
constexpr uint16_t screen_height = 320;
|
||||
extern uint16_t screen_width;
|
||||
extern uint16_t screen_height;
|
||||
|
||||
/* Dimensions for the default font character. */
|
||||
constexpr uint16_t char_width = 8;
|
||||
|
Reference in New Issue
Block a user