AmendHub

Download:

jcs

/

subtext

/

amendments

/

29

console: Implement scrolling, speed up redrawing

No need to pass hints anymore, just do less math in the loop scanning
for dirty cells

jcs made amendment 29 over 2 years ago
--- console.c Mon Dec 13 09:14:36 2021 +++ console.c Mon Dec 13 21:42:20 2021 @@ -33,7 +33,8 @@ struct node_funcs console_node_funcs = { console_close }; -void console_redraw(struct console *console, short numhints, short *hints); +void console_redraw(struct console *console, short force); +short console_bound(struct console *console); void console_parse_csi(struct console *console); struct console * @@ -50,9 +51,8 @@ console_init(struct console **cur_console) memset(console->chars, ' ', sizeof(console->chars)); console->ncolumns = 80; console->nlines = 24; - console->attrs[0] |= (ATTR_CURSOR | ATTR_DIRTY); - width = FONT_WIDTH * (console->ncolumns + 2); + width = (FONT_WIDTH * console->ncolumns) + (FONT_WIDTH * 2); height = (FONT_HEIGHT * console->nlines) + (FONT_WIDTH * 2); bounds.left = (screenBits.bounds.right - width) / 2; @@ -110,27 +110,21 @@ console_idle(struct console *console) { struct session *session = console->session; short n, len, cursor, iac = 0; - short hints[100]; - short nhints = 0; if (session->obuflen == 0) return; + /* uncursor */ cursor = (console->cursor_line * console->ncolumns) + console->cursor_column; - console->attrs[cursor] |= ATTR_DIRTY; + if (cursor >= sizeof(console->attrs)) + panic("console_idle: cursor out of bounds!"); console->attrs[cursor] &= ~ATTR_CURSOR; - hints[nhints++] = cursor; + console->attrs[cursor] |= ATTR_DIRTY; for (n = 0; n < session->obuflen; n++) { - if (console->cursor_column >= console->ncolumns && - session->obuf[n] != '\n') { - console->cursor_column = 0; - console->cursor_line++; - } - if (console->in_csi) { - if (session->obuf[n] == '\e' || + if (session->obuf[n] == '\33' || console->csilen >= nitems(console->csi) - 1) { console_parse_csi(console); console->in_csi = 0; @@ -151,6 +145,8 @@ console_idle(struct console *console) break; case '\n': console->cursor_line++; + console->cursor_column = 0; /* \r should do this, but JIC */ + console_bound(console); break; case '\33': /* \e */ if (session->obuflen <= n + 1) { @@ -166,15 +162,12 @@ console_idle(struct console *console) } /* escape but not CSI, fall through */ default: + console_bound(console); cursor = (console->cursor_line * console->ncolumns) + console->cursor_column; console->chars[cursor] = session->obuf[n]; console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; console->cursor_column++; - if (nhints != -1 && nhints < nitems(hints) - 1) - hints[nhints++] = cursor; - else - nhints = -1; break; } } @@ -183,14 +176,8 @@ console_idle(struct console *console) session->obuflen = 0; output_done: - cursor = (console->cursor_line * console->ncolumns) + - console->cursor_column; - console->attrs[cursor] |= (ATTR_DIRTY | ATTR_CURSOR); - if (nhints != -1 && nhints < nitems(hints) - 1) - hints[nhints++] = cursor; - else if (nhints == -1) - nhints = 0; - console_redraw(console, nhints, hints); + console_bound(console); + console_redraw(console, 0); } void @@ -215,7 +202,7 @@ console_update(struct console *console, EventRecord *e switch (what) { case -1: case updateEvt: - console_redraw(console, -1, NULL); + console_redraw(console, 1); //browser_update_menu(browser); UpdtControl(console->win, console->win->visRgn); @@ -261,66 +248,115 @@ console_input(struct session *session) return 0; } -void -console_redraw(struct console *console, short nhints, short *hints) +short +console_bound(struct console *console) { - Rect cursor; - short n, nsize, cell, line = 0, column = 0; + unsigned short shift_lines, shift_cols, chars_left, pxout; + RgnHandle rgn; + Rect r; + short ret = 0; +#ifdef SMOOTH_SCROLLING + Rect r2; + short n; +#endif - if (nhints > 0) - nsize = nhints; - else { - nsize = nitems(console->chars); - SetCursor(*(GetCursor(watchCursor))); + while (console->cursor_column >= console->ncolumns) { + console->cursor_line++; + console->cursor_column -= console->ncolumns; } - for (n = 0; n < nsize; n++) { - if (nhints > 0) { - cell = hints[n]; - } else { - if (nhints == 0 && !(console->attrs[n] & ATTR_DIRTY)) - continue; - - /* - * speed hack: if doing a whole-window update, no need to - * redraw blank space - */ - if (nhints == -1 && console->chars[n] == ' ' && - !(console->attrs[n] & ATTR_CURSOR)) - continue; + if (console->cursor_line >= console->nlines) { + shift_lines = console->cursor_line - console->nlines + 1; + shift_cols = shift_lines * console->ncolumns; + chars_left = (console->nlines * console->ncolumns) - shift_cols; + pxout = shift_lines * FONT_HEIGHT; - cell = n; + rgn = NewRgn(); + r.left = console->win->portRect.left + FONT_WIDTH; + r.top = console->win->portRect.top + FONT_WIDTH; + r.right = r.left + (console->ncolumns * FONT_WIDTH); + r.bottom = r.top + ((console->nlines) * FONT_HEIGHT); +#ifdef SMOOTH_SCROLLING + for (n = 0; n < pxout; n++) { + ScrollRect(&r, 0, -1, rgn); + r2 = r; + r2.top = r.bottom - 1; + r2.bottom = r.top + 1; + FillRect(&r2, white); } +#else + ScrollRect(&r, 0, -pxout, rgn); + r.top = r.bottom - 1; + r.bottom = r.top + pxout; + FillRect(&r, white); +#endif + DisposeRgn(rgn); + + BlockMove(console->chars + shift_cols, console->chars, chars_left); + BlockMove(console->attrs + shift_cols, console->attrs, chars_left); + memset(console->chars + chars_left, ' ', shift_cols); + memset(console->attrs + chars_left, console->cur_attr, shift_cols); - line = cell / console->ncolumns; - column = cell - (line * console->ncolumns); + console->cursor_line = console->nlines - 1; + ret = 1; + } + + return ret; +} - cursor.left = FONT_WIDTH + ((console->win->portRect.left + - column) * FONT_WIDTH); - cursor.top = FONT_WIDTH + ((console->win->portRect.top + line) * - FONT_HEIGHT); +void +console_redraw(struct console *console, short force) +{ + Rect cursor; + short n, nsize, cell, cbold = -1; + + /* recursor */ + console->attrs[(console->cursor_line * console->ncolumns) + + console->cursor_column] |= (ATTR_CURSOR | ATTR_DIRTY); + + nsize = console->ncolumns * console->nlines; + SetCursor(*(GetCursor(watchCursor))); + + cursor.left = console->win->portRect.left + FONT_WIDTH; + cursor.top = console->win->portRect.top + FONT_WIDTH; + for (cell = 0; cell < nsize; cell++) { + if (cell) { + if (cell % console->ncolumns == 0) { + cursor.left = console->win->portRect.left + FONT_WIDTH; + cursor.top += FONT_HEIGHT; + } else { + cursor.left += FONT_WIDTH; + } + } + + if (!force && !(console->attrs[cell] & ATTR_DIRTY)) + continue; + cursor.right = cursor.left + FONT_WIDTH; cursor.bottom = cursor.top + FONT_HEIGHT; - FillRect(&cursor, white); - - MoveTo(cursor.left, cursor.top + FONT_HEIGHT - 2); - if (console->attrs[cell] & ATTR_BOLD) - TextFace(thePort->txFace | bold); - else - TextFace(thePort->txFace & ~bold); + MoveTo(cursor.left, cursor.top + FONT_HEIGHT - 2); + + if (cbold != (console->attrs[cell] & ATTR_BOLD)) { + if (console->attrs[cell] & ATTR_BOLD) + TextFace(thePort->txFace | bold); + else + TextFace(thePort->txFace & ~bold); + + cbold = console->attrs[cell] & ATTR_BOLD; + } + DrawChar(console->chars[cell]); - console->attrs[n] &= ~ATTR_DIRTY; + console->attrs[cell] &= ~ATTR_DIRTY; if (console->attrs[cell] & ATTR_CURSOR) InvertRect(&cursor); } - + ValidRect(&console->win->portRect); - if (nhints <= 0) - SetCursor(&arrow); + SetCursor(&arrow); } void @@ -672,11 +708,9 @@ console_parse_csi(struct console *console) } if (serviced) { - cursor = (console->cursor_line * console->ncolumns) + - console->cursor_column; - console->attrs[cursor] |= (ATTR_CURSOR | ATTR_DIRTY); console->csilen = 0; console->csi[0] = '\0'; console->in_csi = 0; + console_bound(console); } } --- console.h Mon Dec 6 17:32:18 2021 +++ console.h Mon Dec 13 13:43:42 2021 @@ -24,6 +24,8 @@ struct console { struct console **cur_console; WindowPtr win; ControlHandle scroller; + short nlines; + short ncolumns; char chars[80 * 24]; char attrs[80 * 24]; char cur_attr; @@ -32,8 +34,6 @@ struct console { #define ATTR_UNDERLINE (1 << 2) #define ATTR_CURSOR (1 << 6) #define ATTR_DIRTY (1 << 7) - short nlines; - short ncolumns; short cursor_line; short cursor_column; short in_csi;