|
|
|
@ -15,6 +15,7 @@ void LcdBuffer_Init(struct LcdBuffer *self, const struct LcdBuf_CGROM_Entry *cgr |
|
|
|
|
assert(cgrom); |
|
|
|
|
assert(custom_symbols); |
|
|
|
|
|
|
|
|
|
memset(self, 0, sizeof(struct LcdBuffer)); |
|
|
|
|
LcdBuffer_Clear(self); |
|
|
|
|
self->cgrom = cgrom; |
|
|
|
|
self->custom_symbols = custom_symbols; |
|
|
|
@ -36,8 +37,37 @@ void LcdBuffer_Clear(struct LcdBuffer *self) |
|
|
|
|
/** Write what needs to be written to the HW, clear all dirty marks */ |
|
|
|
|
void LcdBuffer_Flush(struct LcdBuffer *self) |
|
|
|
|
{ |
|
|
|
|
bool any_flush = self->full_repaint_required || self->cursor_dirty; |
|
|
|
|
uint8_t flush_cgram_mask = 0; |
|
|
|
|
|
|
|
|
|
// Check if any flushing is required
|
|
|
|
|
for (int i = 0; i < LCDBUF_CGRAM_CAPACITY; i++) { |
|
|
|
|
if (self->cgram[i].refcount > 0 && self->cgram[i].dirty) { |
|
|
|
|
any_flush = true; |
|
|
|
|
flush_cgram_mask |= 1 << i; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!any_flush) { |
|
|
|
|
// check if we have dirty areas
|
|
|
|
|
for (int e = 0; e < LCDBUF_DIRTY_LIST_LEN; e++) { |
|
|
|
|
struct LcdBuf_DirtyExtent *ext = &self->dirty_extents[e]; |
|
|
|
|
if (ext->count) { |
|
|
|
|
any_flush = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!any_flush) { |
|
|
|
|
// really nothing to do
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LcdBuffer_IO_SetCursorStyle(0); // hide cursor for the time of this function
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < LCDBUF_CGRAM_CAPACITY; i++) { |
|
|
|
|
if (flush_cgram_mask & (1 << i)) { |
|
|
|
|
LcdBuffer_IO_WriteCGRAM(i, self->custom_symbols[self->cgram[i].symbol_index].data); |
|
|
|
|
self->cgram[i].dirty = false; |
|
|
|
|
} |
|
|
|
@ -57,7 +87,7 @@ void LcdBuffer_Flush(struct LcdBuffer *self) |
|
|
|
|
|
|
|
|
|
if (!any_nonspace) { |
|
|
|
|
LcdBuffer_IO_Clear(); |
|
|
|
|
return; |
|
|
|
|
goto done; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int r = 0; r < LINE_NUM; r++) { |
|
|
|
@ -74,11 +104,21 @@ void LcdBuffer_Flush(struct LcdBuffer *self) |
|
|
|
|
ext->count = 0; // mark the slot as free
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
done: |
|
|
|
|
// Restore the visible cursor
|
|
|
|
|
if (self->cursor_style != 0) { |
|
|
|
|
LcdBuffer_IO_SetCursorPos(self->cursor_row, self->cursor_col); |
|
|
|
|
LcdBuffer_IO_SetCursorStyle(self->cursor_style); // hide cursor for the time of this function
|
|
|
|
|
} |
|
|
|
|
self->cursor_dirty = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Fully write everything to the display */ |
|
|
|
|
void LcdBuffer_FlushAll(struct LcdBuffer *self) |
|
|
|
|
{ |
|
|
|
|
LcdBuffer_IO_SetCursorStyle(0); // hide cursor for the time of this function
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < LCDBUF_CGRAM_CAPACITY; i++) { |
|
|
|
|
if (self->cgram[i].refcount > 0) { |
|
|
|
|
LcdBuffer_IO_WriteCGRAM(i, self->custom_symbols[self->cgram[i].symbol_index].data); |
|
|
|
@ -92,6 +132,14 @@ void LcdBuffer_FlushAll(struct LcdBuffer *self) |
|
|
|
|
|
|
|
|
|
memset(self->dirty_extents, 0, sizeof(self->dirty_extents)); |
|
|
|
|
self->full_repaint_required = false; |
|
|
|
|
|
|
|
|
|
// Restore the visible cursor
|
|
|
|
|
if (self->cursor_style != 0) { |
|
|
|
|
LcdBuffer_IO_SetCursorPos(self->cursor_row, self->cursor_col); |
|
|
|
|
LcdBuffer_IO_SetCursorStyle(self->cursor_style); // hide cursor for the time of this function
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self->cursor_dirty = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//static void show_dirty_slots(const struct LcdBuffer *self) {
|
|
|
|
@ -289,3 +337,14 @@ void LcdBuffer_Write(struct LcdBuffer *self, lcdbuf_pos_t row, lcdbuf_pos_t col, |
|
|
|
|
col++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void LcdBuffer_SetCursor(struct LcdBuffer *self, lcdbuf_pos_t row, lcdbuf_pos_t col, uint8_t cursor_style) |
|
|
|
|
{ |
|
|
|
|
if ((self->cursor_style != cursor_style) || (self->cursor_row != row) || (self->cursor_col != col)) { |
|
|
|
|
self->cursor_style = cursor_style; |
|
|
|
|
self->cursor_row = row; |
|
|
|
|
self->cursor_col = col; |
|
|
|
|
self->cursor_dirty = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|