Skip to content

Commit

Permalink
3860 - stop buffering the screen in termbox
Browse files Browse the repository at this point in the history
To achieve this we have to switch to a model of the screen in termbox that
is closer to the underlying terminal.

Before:
  a screen is a grid of characters
  writing out of bounds does nothing

After:
  a screen is a scrolling raster of characters
  writing out of bounds wraps to next line and scrolls if necessary

To move to the new model, it was essential that I migrate my fake screen
at the same time to mimic it. This is why the first attempt (commit 3824)
failed (commit 3858). This is also why this commit can't be split into
smaller pieces.

The fake screen now 'scrolls' by rotating screen lines from top to bottom.
There's still no notion of a scrollback buffer.

The newer model is richer; it permits repl-like apps that upstream termbox
can't do easily. It also permits us to simply use `printf` or `cout` to
write to the screen, and everything mostly works as you would expect. Exceptions:

  a) '\n' won't do what you expect. You need to explicitly print both '\n'
  and '\r'.

  b) backspace won't do what you expect. It only moves the cursor back,
  without erasing the previous character. It does not wrap.

  Both behaviors exactly mimic my existing terminal's emulation of vt100.

The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints
didn't matter before, but they're bugs now. To help track them down, use
the `save-top-idx`, `assert-no-scroll` pair of helpers.

  An important trick is to wrap the cursor before rather after printing
  a character. Otherwise we end up scrolling every time we print to the
  bottom-right character. This means that the cursor position can be invalid
  at the start of a print, and we need to handle that.

In the process we also lose the ability to hide and show the screen. We
have to show the prints happening. Seems apt for a "white-box" platform
like Mu.
  • Loading branch information
akkartik committed May 18, 2017
1 parent 7f67383 commit ee1a18f
Show file tree
Hide file tree
Showing 24 changed files with 277 additions and 395 deletions.
74 changes: 15 additions & 59 deletions 080display.cc
Expand Up @@ -7,7 +7,6 @@
:(before "End Globals")
int Display_row = 0;
int Display_column = 0;
bool Autodisplay = true;

:(before "End Includes")
#define CHECK_SCREEN \
Expand Down Expand Up @@ -38,6 +37,7 @@ case OPEN_CONSOLE: {
:(before "End Primitive Recipe Implementations")
case OPEN_CONSOLE: {
tb_init();
std::setvbuf(stdout, NULL, _IONBF, 0); // disable buffering in cout
Display_row = Display_column = 0;
int width = tb_width();
int height = tb_height();
Expand Down Expand Up @@ -128,29 +128,24 @@ case PRINT_CHARACTER_TO_DISPLAY: {
if (bg_color == 0) bg_color = TB_BLACK;
}
tb_change_cell(Display_column, Display_row, c, color, bg_color);
if (c == '\n' || c == '\r') {
if (Display_row < height-1) {
Display_column = 0;
++Display_row;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
// track row and column, mimicking what happens on screen
if (c == '\n') {
if (Display_row < height-1) ++Display_row; // otherwise we scroll and Display_row remains unchanged
}
if (c == '\b') {
if (Display_column > 0) {
tb_change_cell(Display_column-1, Display_row, ' ', color, bg_color);
--Display_column;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
else if (c == '\r') {
Display_column = 0;
}
if (Display_column < width-1) {
else if (c == '\b') {
if (Display_column > 0) --Display_column;
}
else {
++Display_column;
tb_set_cursor(Display_column, Display_row);
if (Display_column >= width) {
Display_column = 0;
if (Display_row < height-1) ++Display_row;
}
}
if (Autodisplay) tb_present();
tb_set_cursor(Display_column, Display_row);
break;
}

Expand Down Expand Up @@ -197,7 +192,6 @@ case MOVE_CURSOR_ON_DISPLAY: {
Display_row = ingredients.at(0).at(0);
Display_column = ingredients.at(1).at(0);
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
break;
}

Expand All @@ -217,7 +211,6 @@ case MOVE_CURSOR_DOWN_ON_DISPLAY: {
if (Display_row < height-1) {
++Display_row;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
}
Expand All @@ -236,7 +229,6 @@ case MOVE_CURSOR_UP_ON_DISPLAY: {
if (Display_row > 0) {
--Display_row;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
}
Expand All @@ -257,7 +249,6 @@ case MOVE_CURSOR_RIGHT_ON_DISPLAY: {
if (Display_column < width-1) {
++Display_column;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
}
Expand All @@ -276,7 +267,6 @@ case MOVE_CURSOR_LEFT_ON_DISPLAY: {
if (Display_column > 0) {
--Display_column;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}
break;
}
Expand All @@ -292,7 +282,6 @@ void move_cursor_to_start_of_next_line_on_display() {
else Display_row = 0;
Display_column = 0;
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
}

:(before "End Primitive Recipe Declarations")
Expand Down Expand Up @@ -327,37 +316,6 @@ case DISPLAY_HEIGHT: {
break;
}

:(before "End Primitive Recipe Declarations")
HIDE_DISPLAY,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "hide-display", HIDE_DISPLAY);
:(before "End Primitive Recipe Checks")
case HIDE_DISPLAY: {
break;
}
:(before "End Primitive Recipe Implementations")
case HIDE_DISPLAY: {
CHECK_SCREEN;
Autodisplay = false;
break;
}

:(before "End Primitive Recipe Declarations")
SHOW_DISPLAY,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "show-display", SHOW_DISPLAY);
:(before "End Primitive Recipe Checks")
case SHOW_DISPLAY: {
break;
}
:(before "End Primitive Recipe Implementations")
case SHOW_DISPLAY: {
CHECK_SCREEN;
Autodisplay = true;
tb_present();
break;
}

//:: Keyboard/mouse management

:(before "End Primitive Recipe Declarations")
Expand Down Expand Up @@ -481,7 +439,6 @@ case CLEAR_LINE_ON_DISPLAY: {
tb_change_cell(x, Display_row, ' ', TB_WHITE, TB_BLACK);
}
tb_set_cursor(Display_column, Display_row);
if (Autodisplay) tb_present();
break;
}

Expand All @@ -507,6 +464,5 @@ case CLEAR_DISPLAY_FROM: {
tb_change_cell(column, row, ' ', TB_WHITE, TB_BLACK);
}
}
if (Autodisplay) tb_present();
break;
}

0 comments on commit ee1a18f

Please sign in to comment.