13 static const size_t Columns = 80;
14 static const size_t Rows = 25;
15 static const size_t CellCount = Columns * Rows;
17 bool initialise(
void* pixels,
size_t bytes, uint32_t width, uint32_t height, uint32_t pitch,
19 if (!pixels || (
reinterpret_cast<uintptr_t
>(pixels) & 3) || width < 640 || height < 400 ||
20 static_cast<uint64_t
>(width) * 4 > pitch || (pitch & 3) || format > 1 ||
21 static_cast<uint64_t
>(pitch) * height > bytes) {
24 m_Pixels =
static_cast<volatile uint32_t*
>(pixels);
29 m_Scale = width / 640 < height / 400 ? width / 640 : height / 400;
30 m_Left = (width - 640 * m_Scale) / 2;
31 m_Top = (height - 400 * m_Scale) / 2;
33 for (
size_t y = 0; y < height; ++y) {
34 for (
size_t x = 0; x < width; ++x) {
35 m_Pixels[y * m_Stride + x] = 0;
45 const uint16_t* cells()
const {
49 void moveCursor(
size_t x,
size_t y) {
50 m_Cursor = x < Columns && y < Rows ? y * Columns + x : CellCount;
61 for (
size_t y = 0; y < m_Height; ++y) {
62 for (
size_t x = 0; x < m_Width; ++x) {
63 m_Pixels[y * m_Stride + x] = 0;
78 for (
size_t i = 0; i < CellCount; ++i) {
79 uint16_t cell = m_Cells[i];
80 if (!m_FirstFrame && cell == m_Rendered[i] && i != m_Cursor && i != m_PreviousCursor) {
83 const uint8_t* glyph = font_data + ((cell & 0xff) * FONT_HEIGHT);
84 uint32_t foreground = colour((cell >> 8) & 15);
85 uint32_t background = colour((cell >> 12) & 15);
86 size_t left = m_Left + (i % Columns) * FONT_WIDTH * m_Scale;
87 size_t top = m_Top + (i / Columns) * FONT_HEIGHT * m_Scale;
88 for (
size_t y = 0; y < FONT_HEIGHT * m_Scale; ++y) {
89 uint8_t bits = glyph[y / m_Scale];
90 bool cursor = i == m_Cursor && y >= 14 * m_Scale;
91 for (
size_t x = 0; x < FONT_WIDTH * m_Scale; ++x) {
92 bool set = (bits & (1U << (FONT_WIDTH - 1 - (x / m_Scale)))) != 0;
93 m_Pixels[(top + y) * m_Stride + left + x] = (set != cursor) ? foreground : background;
98 m_PreviousCursor = m_Cursor;
103 uint32_t colour(
size_t index)
const {
104 static const uint32_t palette[16] = {0x000000, 0x0000aa, 0x00aa00, 0x00aaaa, 0xaa0000, 0xaa00aa,
105 0xaa5500, 0xaaaaaa, 0x555555, 0x5555ff, 0x55ff55, 0x55ffff,
106 0xff5555, 0xff55ff, 0xffff55, 0xffffff};
107 uint32_t value = palette[index];
108 return m_Format == 1 ? value : ((value & 0xff) << 16) | (value & 0xff00) | (value >> 16);
111 volatile uint32_t* m_Pixels =
nullptr;
118 uint32_t m_Format = 0;
119 uint16_t m_Cells[CellCount] = {};
120 uint16_t m_Rendered[CellCount] = {};
121 size_t m_Cursor = CellCount;
122 size_t m_PreviousCursor = CellCount;
123 bool m_FirstFrame =
true;