Partial redrawing

This commit is contained in:
Shylie 2024-04-15 17:59:59 -04:00
parent 46bc24be3b
commit 98097d7540
2 changed files with 48 additions and 20 deletions

View File

@ -69,27 +69,35 @@ namespace
} }
} }
void print_cell(tcell cell) void print_cell(tcell cell, const tcell* last = nullptr)
{ {
printf(FG(%d, %d, %d), (cell.foreground & 0xFF0000) >> 16, (cell.foreground & 0xFF00) >> 8, cell.foreground & 0xFF); if (!last || cell.foreground != last->foreground)
printf(BG(%d, %d, %d), (cell.background & 0xFF0000) >> 16, (cell.background & 0xFF00) >> 8, cell.background & 0xFF);
print_cell_impl(cell);
}
void print_cell(tcell cell, tcell last)
{
if (cell.foreground != last.foreground)
{ {
printf(FG(%d, %d, %d), (cell.foreground & 0xFF0000) >> 16, (cell.foreground & 0xFF00) >> 8, cell.foreground & 0xFF); printf(FG(%d, %d, %d), (cell.foreground & 0xFF0000) >> 16, (cell.foreground & 0xFF00) >> 8, cell.foreground & 0xFF);
} }
if (cell.background != last.background) if (!last || cell.background != last->background)
{ {
printf(BG(%d, %d, %d), (cell.background & 0xFF0000) >> 16, (cell.background & 0xFF00) >> 8, cell.background & 0xFF); printf(BG(%d, %d, %d), (cell.background & 0xFF0000) >> 16, (cell.background & 0xFF00) >> 8, cell.background & 0xFF);
} }
print_cell_impl(cell); print_cell_impl(cell);
} }
bool operator==(const tcell& a, const tcell& b)
{
return
a.background == b.background &&
a.foreground == b.foreground &&
a.codepoint == b.codepoint;
}
bool operator!=(const tcell& a, const tcell& b)
{
return
a.background != b.background ||
a.foreground != b.foreground ||
a.codepoint != b.codepoint;
}
} }
terml::terml() : terml::terml() :
@ -112,25 +120,39 @@ terml::~terml()
const tcell& terml::get(unsigned int x, unsigned int y) const const tcell& terml::get(unsigned int x, unsigned int y) const
{ {
return cells[x + y * width]; return cells[x + y * width].cell;
} }
void terml::set(unsigned int x, unsigned int y, tcell cell) void terml::set(unsigned int x, unsigned int y, tcell cell)
{ {
cells[x + y * width] = cell; cells[x + y * width].dirty = (cell != cells[x + y * width].cell);
cells[x + y * width].cell = cell;
} }
void terml::flush() const void terml::flush() const
{
const tcell* last = nullptr;
if (cells[0].dirty)
{ {
printf(CUP(1, 1)); printf(CUP(1, 1));
print_cell(cells[0]); print_cell(cells[0].cell);
cells[0].dirty = false;
last = &cells[0].cell;
}
for (int i = 1; i < width * height; i++) for (int i = 1; i < width * height; i++)
{ {
const unsigned int x = i % width; const unsigned int x = i % width;
const unsigned int y = i / width; const unsigned int y = i / width;
if (cells[i].dirty)
{
printf(CUP(%d, %d), y + 1, x + 1); printf(CUP(%d, %d), y + 1, x + 1);
print_cell(cells[i], cells[i - 1]); print_cell(cells[i].cell, last);
cells[i].dirty = false;
last = &cells[i].cell;
}
} }
fflush(stdout); fflush(stdout);
@ -245,8 +267,8 @@ void terml::setup_buffer()
height = new_height; height = new_height;
if (cells) { delete[] cells; } if (cells) { delete[] cells; }
cells = new tcell[width * height]; cells = new tcelld[width * height];
memset(cells, 0, sizeof(tcell) * width * height); memset(cells, 0, sizeof(tcelld) * width * height);
if (resize) if (resize)
{ {

View File

@ -26,6 +26,12 @@
#define FG(r, g, b) CSI "38;2;" STRINGIFY(r) ";" STRINGIFY(g) ";" STRINGIFY(b) "m" #define FG(r, g, b) CSI "38;2;" STRINGIFY(r) ";" STRINGIFY(g) ";" STRINGIFY(b) "m"
#define BG(r, g, b) CSI "48;2;" STRINGIFY(r) ";" STRINGIFY(g) ";" STRINGIFY(b) "m" #define BG(r, g, b) CSI "48;2;" STRINGIFY(r) ";" STRINGIFY(g) ";" STRINGIFY(b) "m"
struct tcelld
{
tcell cell;
bool dirty;
};
class terml class terml
{ {
public: public:
@ -69,7 +75,7 @@ protected:
void key_event(char code) const; void key_event(char code) const;
private: private:
tcell* cells; tcelld* cells;
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
terml_main_callback main; terml_main_callback main;