about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-22 20:57:29 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-22 20:57:29 -0800
commit1b09418c60cd48d021f95a8c3f248a33421d776f (patch)
tree22ce69760518152efcaf7f0950bc751facc95336
parenta51bc7a1e0c287d9a0be9c43cd3967dcfb6107f8 (diff)
downloadmu-1b09418c60cd48d021f95a8c3f248a33421d776f.tar.gz
7542 - baremetal: support cursor on a grapheme
So far we've drawn a space implicitly at the cursor. Now I allow drawing
an arbitrary grapheme when drawing the cursor. But the caller has to
specify what to draw. (The alternative would be for layer 103 to
track every single grapheme on screen along with its color and any other
future attributes, just to be able to paint and unpaint the background
for a single character.)

I've modified existing helpers for drawing multiple graphemes to always
clear the final cursor position after they finish drawing. That seems
reasonable for terminal-like applications. Applications that need to
control the screen in a more random-access manner will need to track the
grapheme at the cursor for themselves.
-rw-r--r--baremetal/103grapheme.subx6
-rw-r--r--baremetal/400.mu2
-rw-r--r--baremetal/500text-screen.mu13
-rw-r--r--baremetal/501draw-text.mu33
4 files changed, 36 insertions, 18 deletions
diff --git a/baremetal/103grapheme.subx b/baremetal/103grapheme.subx
index 97a44315..b4750989 100644
--- a/baremetal/103grapheme.subx
+++ b/baremetal/103grapheme.subx
@@ -104,14 +104,16 @@ $cursor-position-on-real-screen:end:
     5d/pop-to-ebp
     c3/return
 
-set-cursor-position-on-real-screen:  # x: int, y: int
+# Caller is responsible for tracking what was on the screen at this position
+# before, and making sure the cursor continues to show the same grapheme.
+set-cursor-position-on-real-screen:  # x: int, y: int, g: grapheme
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
     50/push-eax
     #
-    (draw-grapheme-on-real-screen 0x20 *(ebp+8) *(ebp+0xc) 0 7)
+    (draw-grapheme-on-real-screen *(ebp+0x10) *(ebp+8) *(ebp+0xc) 0 7)
     # TODO: support fake screen; we currently assume 'screen' is always 0 (real)
     8b/-> *(ebp+8) 0/r32/eax
     89/<- *Real-screen-cursor-x 0/r32/eax
diff --git a/baremetal/400.mu b/baremetal/400.mu
index 8db62837..7ebd90ae 100644
--- a/baremetal/400.mu
+++ b/baremetal/400.mu
@@ -2,7 +2,7 @@
 sig pixel-on-real-screen x: int, y: int, color: int
 sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int
 sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
-sig set-cursor-position-on-real-screen x: int, y: int
+sig set-cursor-position-on-real-screen x: int, y: int, g: grapheme
 
 # keyboard
 sig read-key kbd: (addr keyboard) -> _/eax: byte
diff --git a/baremetal/500text-screen.mu b/baremetal/500text-screen.mu
index b387496f..fbc2ef43 100644
--- a/baremetal/500text-screen.mu
+++ b/baremetal/500text-screen.mu
@@ -112,11 +112,11 @@ fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
   return *cursor-x-addr, *cursor-y-addr
 }
 
-fn set-cursor-position screen: (addr screen), x: int, y: int {
+fn set-cursor-position screen: (addr screen), x: int, y: int, g: grapheme {
   {
     compare screen, 0
     break-if-!=
-    set-cursor-position-on-real-screen x, y
+    set-cursor-position-on-real-screen x, y, g
     return
   }
   # fake screen
@@ -157,6 +157,11 @@ fn set-cursor-position screen: (addr screen), x: int, y: int {
   dest <- get screen-addr, cursor-y
   src <- copy y
   copy-to *dest, src
+  #
+  var cursor-x/eax: int <- copy 0
+  var cursor-y/ecx: int <- copy 0
+  cursor-x, cursor-y <- cursor-position screen-addr
+  draw-grapheme screen-addr, g, cursor-x, cursor-y, 0  # cursor color not tracked for fake screen
 }
 
 fn clear-screen screen: (addr screen) {
@@ -168,7 +173,7 @@ fn clear-screen screen: (addr screen) {
   }
   # fake screen
   var space/edi: grapheme <- copy 0x20
-  set-cursor-position screen, 0, 0
+  set-cursor-position screen, 0, 0, space
   var screen-addr/esi: (addr screen) <- copy screen
   var y/eax: int <- copy 1
   var height/ecx: (addr int) <- get screen-addr, height
@@ -187,7 +192,7 @@ fn clear-screen screen: (addr screen) {
     y <- increment
     loop
   }
-  set-cursor-position screen, 0, 0
+  set-cursor-position screen, 0, 0, space
 }
 
 # there's no grapheme that guarantees to cover every pixel, so we'll bump down
diff --git a/baremetal/501draw-text.mu b/baremetal/501draw-text.mu
index 0bb95dee..d7455829 100644
--- a/baremetal/501draw-text.mu
+++ b/baremetal/501draw-text.mu
@@ -10,7 +10,8 @@ fn cursor-left screen: (addr screen) {
     return
   }
   cursor-x <- decrement
-  set-cursor-position screen, cursor-x, cursor-y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, cursor-x, cursor-y, space
 }
 
 fn cursor-right screen: (addr screen) {
@@ -27,7 +28,8 @@ fn cursor-right screen: (addr screen) {
     return
   }
   cursor-x <- increment
-  set-cursor-position screen, cursor-x, cursor-y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, cursor-x, cursor-y, space
 }
 
 fn cursor-up screen: (addr screen) {
@@ -40,7 +42,8 @@ fn cursor-up screen: (addr screen) {
     return
   }
   cursor-y <- decrement
-  set-cursor-position screen, cursor-x, cursor-y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, cursor-x, cursor-y, space
 }
 
 fn cursor-down screen: (addr screen) {
@@ -57,7 +60,8 @@ fn cursor-down screen: (addr screen) {
     return
   }
   cursor-y <- increment
-  set-cursor-position screen, cursor-x, cursor-y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, cursor-x, cursor-y, space
 }
 
 fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
@@ -101,7 +105,8 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
     xcurr <- increment
     loop
   }
-  set-cursor-position screen, xcurr, y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, xcurr, y, space  # we'll assume it's ok to clear the next grapheme
   return xcurr
 }
 
@@ -162,7 +167,8 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
     }
     loop
   }
-  set-cursor-position screen, xcurr, ycurr
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, xcurr, ycurr, space  # we'll assume it's ok to clear the next grapheme
   return xcurr, ycurr
 }
 
@@ -177,7 +183,8 @@ fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: in
     cursor-x <- copy xmin
     cursor-y <- increment
   }
-  set-cursor-position screen, cursor-x, cursor-y
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, cursor-x, cursor-y, space  # we'll assume it's ok to clear the grapheme at the cursor
 }
 
 fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int -> _/eax: int, _/ecx: int {
@@ -255,7 +262,8 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin:
     }
     loop
   }
-  set-cursor-position screen, xcurr, ycurr
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, xcurr, ycurr, space  # we'll assume it's ok to clear the next grapheme
   return xcurr, ycurr
 }
 
@@ -334,7 +342,8 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm
     }
     loop
   }
-  set-cursor-position screen, xcurr, ycurr
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, xcurr, ycurr, space  # we'll assume it's ok to clear the next grapheme
   return xcurr, ycurr
 }
 
@@ -404,7 +413,8 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y:
     ycurr <- increment
     loop
   }
-  set-cursor-position screen, x, ycurr
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, x, ycurr, space  # we'll assume it's ok to clear the next grapheme
   return ycurr
 }
 
@@ -464,7 +474,8 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b
     }
     loop
   }
-  set-cursor-position screen, xcurr, ycurr
+  var space/esi: grapheme <- copy 0x20
+  set-cursor-position screen, xcurr, ycurr, space  # we'll assume it's ok to clear the next grapheme
   return xcurr, ycurr
 }