|  |  | @ -15,6 +15,7 @@ void LcdBuffer_Init(struct LcdBuffer *self, const struct LcdBuf_CGROM_Entry *cgr | 
			
		
	
		
		
			
				
					
					|  |  |  |     assert(cgrom); |  |  |  |     assert(cgrom); | 
			
		
	
		
		
			
				
					
					|  |  |  |     assert(custom_symbols); |  |  |  |     assert(custom_symbols); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     memset(self, 0, sizeof(struct LcdBuffer)); | 
			
		
	
		
		
			
				
					
					|  |  |  |     LcdBuffer_Clear(self); |  |  |  |     LcdBuffer_Clear(self); | 
			
		
	
		
		
			
				
					
					|  |  |  |     self->cgrom = cgrom; |  |  |  |     self->cgrom = cgrom; | 
			
		
	
		
		
			
				
					
					|  |  |  |     self->custom_symbols = custom_symbols; |  |  |  |     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 */ |  |  |  | /** Write what needs to be written to the HW, clear all dirty marks */ | 
			
		
	
		
		
			
				
					
					|  |  |  | void LcdBuffer_Flush(struct LcdBuffer *self) |  |  |  | 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++) { |  |  |  |     for (int i = 0; i < LCDBUF_CGRAM_CAPACITY; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (self->cgram[i].refcount > 0 && self->cgram[i].dirty) { |  |  |  |         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); |  |  |  |             LcdBuffer_IO_WriteCGRAM(i, self->custom_symbols[self->cgram[i].symbol_index].data); | 
			
		
	
		
		
			
				
					
					|  |  |  |             self->cgram[i].dirty = false; |  |  |  |             self->cgram[i].dirty = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -57,7 +87,7 @@ void LcdBuffer_Flush(struct LcdBuffer *self) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!any_nonspace) { |  |  |  |         if (!any_nonspace) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             LcdBuffer_IO_Clear(); |  |  |  |             LcdBuffer_IO_Clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             goto done; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         for (int r = 0; r < LINE_NUM; r++) { |  |  |  |         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
 |  |  |  |             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 */ |  |  |  | /** Fully write everything to the display */ | 
			
		
	
		
		
			
				
					
					|  |  |  | void LcdBuffer_FlushAll(struct LcdBuffer *self) |  |  |  | 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++) { |  |  |  |     for (int i = 0; i < LCDBUF_CGRAM_CAPACITY; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (self->cgram[i].refcount > 0) { |  |  |  |         if (self->cgram[i].refcount > 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             LcdBuffer_IO_WriteCGRAM(i, self->custom_symbols[self->cgram[i].symbol_index].data); |  |  |  |             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)); |  |  |  |     memset(self->dirty_extents, 0, sizeof(self->dirty_extents)); | 
			
		
	
		
		
			
				
					
					|  |  |  |     self->full_repaint_required = false; |  |  |  |     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) {
 |  |  |  | //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++; |  |  |  |         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; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |