:: commit 5d22de7733bd3e91259f287898cc60491185fd17

mintsuki <mintsuki@protonmail.com> — 2021-07-31 18:52

parents: 7fdacf3163

term: Misc improvements

diff --git a/stage23/drivers/vga_textmode.h b/stage23/drivers/vga_textmode.h
index 31c0ce7a..cd78d435 100644
--- a/stage23/drivers/vga_textmode.h
+++ b/stage23/drivers/vga_textmode.h
@@ -15,6 +15,7 @@ void text_set_text_fg(int fg);
 void text_set_text_bg(int bg);
 bool text_scroll_disable(void);
 void text_scroll_enable(void);
+void text_move_character(int new_x, int new_y, int old_x, int old_y);
 
 void text_double_buffer(bool state);
 void text_double_buffer_flush(void);
diff --git a/stage23/drivers/vga_textmode.s2.c b/stage23/drivers/vga_textmode.s2.c
index 18048f76..80d4970c 100644
--- a/stage23/drivers/vga_textmode.s2.c
+++ b/stage23/drivers/vga_textmode.s2.c
@@ -174,6 +174,13 @@ void text_get_cursor_pos(int *x, int *y) {
     *y = cursor_offset / VD_COLS;
 }
 
+void text_move_character(int new_x, int new_y, int old_x, int old_y) {
+    current_buffer[new_y * VD_COLS + new_x * 2] = current_buffer[old_y * VD_COLS + old_x * 2];
+    if (current_buffer == front_buffer) {
+        video_mem[new_y * VD_COLS + new_x * 2] = current_buffer[old_y * VD_COLS + old_x * 2];
+    }
+}
+
 void text_set_cursor_pos(int x, int y) {
     clear_cursor();
     if (x < 0) {
diff --git a/stage23/lib/gterm.c b/stage23/lib/gterm.c
index 6aca3a82..8fc89138 100644
--- a/stage23/lib/gterm.c
+++ b/stage23/lib/gterm.c
@@ -376,6 +376,15 @@ void gterm_get_cursor_pos(int *x, int *y) {
     *y = cursor_y;
 }
 
+void gterm_move_character(int new_x, int new_y, int old_x, int old_y) {
+    if (!double_buffer_enabled) {
+        gterm_plot_char(&grid[old_x + old_y * cols],
+                        frame_width + new_x * VGA_FONT_WIDTH,
+                        frame_height + new_y * VGA_FONT_HEIGHT);
+    }
+    grid[new_x + new_y * cols] = grid[old_x + old_y * cols];
+}
+
 static int text_fg = 9, text_bg = 8;
 
 void gterm_set_text_fg(int fg) {
diff --git a/stage23/lib/gterm.h b/stage23/lib/gterm.h
index 43ce6607..9e923799 100644
--- a/stage23/lib/gterm.h
+++ b/stage23/lib/gterm.h
@@ -20,6 +20,7 @@ void gterm_set_text_fg(int fg);
 void gterm_set_text_bg(int bg);
 bool gterm_scroll_disable(void);
 void gterm_scroll_enable(void);
+void gterm_move_character(int new_x, int new_y, int old_x, int old_y);
 
 void gterm_double_buffer_flush(void);
 void gterm_double_buffer(bool state);
diff --git a/stage23/lib/term.c b/stage23/lib/term.c
index 4c3e9822..82323055 100644
--- a/stage23/lib/term.c
+++ b/stage23/lib/term.c
@@ -29,6 +29,7 @@ void term_vbe(int width, int height) {
     set_text_bg    = gterm_set_text_bg;
     scroll_disable = gterm_scroll_disable;
     scroll_enable  = gterm_scroll_enable;
+    term_move_character = gterm_move_character;
 
     term_double_buffer       = gterm_double_buffer;
     term_double_buffer_flush = gterm_double_buffer_flush;
diff --git a/stage23/lib/term.h b/stage23/lib/term.h
index c2bb1988..4596ffce 100644
--- a/stage23/lib/term.h
+++ b/stage23/lib/term.h
@@ -15,6 +15,7 @@ extern void (*set_text_fg)(int fg);
 extern void (*set_text_bg)(int bg);
 extern bool (*scroll_disable)(void);
 extern void (*scroll_enable)(void);
+extern void (*term_move_character)(int new_x, int new_y, int old_x, int old_y);
 
 extern void (*term_double_buffer)(bool status);
 extern void (*term_double_buffer_flush)(void);
diff --git a/stage23/lib/term.s2.c b/stage23/lib/term.s2.c
index 9ba2ebf7..81a44ec5 100644
--- a/stage23/lib/term.s2.c
+++ b/stage23/lib/term.s2.c
@@ -27,6 +27,7 @@ void (*set_text_fg)(int fg);
 void (*set_text_bg)(int bg);
 bool (*scroll_disable)(void);
 void (*scroll_enable)(void);
+void (*term_move_character)(int new_x, int new_y, int old_x, int old_y);
 
 void (*term_double_buffer)(bool status);
 void (*term_double_buffer_flush)(void);
@@ -49,6 +50,7 @@ void term_textmode(void) {
     set_text_bg    = text_set_text_bg;
     scroll_disable = text_scroll_disable;
     scroll_enable  = text_scroll_enable;
+    term_move_character = text_move_character;
 
     term_double_buffer       = text_double_buffer;
     term_double_buffer_flush = text_double_buffer_flush;
@@ -88,12 +90,13 @@ static int get_cursor_pos_y(void) {
 static bool control_sequence = false;
 static bool escape = false;
 static bool rrr = false;
-static int esc_values[MAX_ESC_VALUES];
-static int esc_values_i = 0;
+static bool dec_private = false;
+static int32_t esc_values[MAX_ESC_VALUES];
+static size_t esc_values_i = 0;
 static int saved_cursor_x = 0, saved_cursor_y = 0;
 
 static void sgr(void) {
-    int i = 0;
+    size_t i = 0;
 
     if (!esc_values_i)
         goto def;
@@ -115,10 +118,30 @@ def:
             set_text_bg(esc_values[i] - 40);
             continue;
         }
+
+        if (esc_values[i] == 39) {
+            set_text_fg(9);
+            continue;
+        }
+
+        if (esc_values[i] == 49) {
+            set_text_bg(8);
+            continue;
+        }
     }
 }
 
+static void dec_private_parse(uint8_t c) {
+    (void)c;
+    dec_private = false;
+}
+
 static void control_sequence_parse(uint8_t c) {
+    if (c == '?') {
+        dec_private = true;
+        return;
+    }
+
     if (c >= '0' && c <= '9') {
         rrr = true;
         esc_values[esc_values_i] *= 10;
@@ -137,9 +160,20 @@ static void control_sequence_parse(uint8_t c) {
         }
     }
 
-    // default rest to 1
+    int esc_default;
+    switch (c) {
+        case 'J': esc_default = 0; break;
+        case 'K': esc_default = 0; break;
+        default:  esc_default = 1; break;
+    }
+
     for (int i = esc_values_i; i < MAX_ESC_VALUES; i++)
-        esc_values[i] = 1;
+        esc_values[i] = esc_default;
+
+    if (dec_private == true) {
+        dec_private_parse(c);
+        goto cleanup;
+    }
 
     switch (c) {
         case 'A':
@@ -197,6 +231,43 @@ static void control_sequence_parse(uint8_t c) {
             break;
         case 'J':
             switch (esc_values[0]) {
+                case 0: {
+                    int x, y;
+                    get_cursor_pos(&x, &y);
+                    int rows_remaining = term_rows - (y + 1);
+                    int cols_diff = term_cols - (x + 1);
+                    size_t to_clear = rows_remaining * term_cols + cols_diff;
+                    bool r = scroll_disable();
+                    for (size_t i = 0; i < to_clear; i++) {
+                        raw_putchar(' ');
+                    }
+                    set_cursor_pos(x, y);
+                    if (r)
+                        scroll_enable();
+                    break;
+                }
+                case 1: {
+                    int x, y;
+                    get_cursor_pos(&x, &y);
+                    bool r = scroll_disable();
+                    set_cursor_pos(0, 0);
+                    bool b = false;
+                    for (int yc = 0; yc < term_rows; yc++) {
+                        for (int xc = 0; xc < term_cols; xc++) {
+                            raw_putchar(' ');
+                            if (xc == x && yc == y) {
+                                raw_putchar('\b');
+                                b = true;
+                                break;
+                            }
+                        }
+                        if (b == true)
+                            break;
+                    }
+                    if (r)
+                        scroll_enable();
+                    break;
+                }
                 case 2:
                     clear(false);
                     break;
@@ -204,6 +275,20 @@ static void control_sequence_parse(uint8_t c) {
                     break;
             }
             break;
+        case 'P': {
+            bool r = scroll_disable();
+            int x, y;
+            get_cursor_pos(&x, &y);
+            for (int i = x + esc_values[0]; i < term_cols; i++)
+                term_move_character(i - esc_values[0], y, i, y);
+            set_cursor_pos(term_cols - esc_values[0], y);
+            for (int i = 0; i < esc_values[0]; i++)
+                raw_putchar(' ');
+            set_cursor_pos(x, y);
+            if (r)
+                scroll_enable();
+            break;
+        }
         case 'm':
             sgr();
             break;
@@ -213,25 +298,40 @@ static void control_sequence_parse(uint8_t c) {
         case 'u':
             set_cursor_pos(saved_cursor_x, saved_cursor_y);
             break;
-        case 'K':
+        case 'K': {
+            bool r = scroll_disable();
+            int x, y;
+            get_cursor_pos(&x, &y);
             switch (esc_values[0]) {
+                case 0: {
+                    for (int i = x; i < term_cols; i++)
+                        raw_putchar(' ');
+                    set_cursor_pos(x, y);
+                    break;
+                }
+                case 1: {
+                    set_cursor_pos(0, y);
+                    for (int i = 0; i < x; i++)
+                        raw_putchar(' ');
+                    break;
+                }
                 case 2: {
-                    int x, y;
-                    get_cursor_pos(&x, &y);
                     set_cursor_pos(0, y);
-                    bool r = scroll_disable();
                     for (int i = 0; i < term_cols; i++)
                         raw_putchar(' ');
-                    if (r)
-                        scroll_enable();
                     set_cursor_pos(x, y);
                     break;
                 }
             }
+            if (r)
+                scroll_enable();
+            break;
+        }
         default:
             break;
     }
 
+cleanup:
     control_sequence = false;
     escape = false;
 }
@@ -277,6 +377,8 @@ static void term_putchar(uint8_t c) {
                 break;
             set_cursor_pos((get_cursor_pos_x() / TERM_TABSIZE + 1) * TERM_TABSIZE, get_cursor_pos_y());
             break;
+        case '\a':
+            break;
         default:
             raw_putchar(c);
             break;
tab: 248 wrap: offon