about summary refs log tree commit diff stats
path: root/405screen.mu
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-06 22:45:43 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-06 22:45:43 -0700
commit9f293fef05217b9d7aabe7f697022145ada5bf47 (patch)
tree78a8e9f711e37a9c7247a5581926e6bb84d824bf /405screen.mu
parent05b9b2ab9c89652b845e0f89bd87b2d56b961822 (diff)
downloadmu-9f293fef05217b9d7aabe7f697022145ada5bf47.tar.gz
6741 - fake screen now scrolls correctly
Diffstat (limited to '405screen.mu')
-rw-r--r--405screen.mu83
1 files changed, 73 insertions, 10 deletions
diff --git a/405screen.mu b/405screen.mu
index ffa9fbb4..f7e04c53 100644
--- a/405screen.mu
+++ b/405screen.mu
@@ -10,9 +10,9 @@ type screen {
   num-rows: int
   num-cols: int
   data: (handle array screen-cell)
-  top-index: int
-  cursor-row: int
-  cursor-col: int
+  top-index: int  # 0-indexed
+  cursor-row: int  # 1-indexed
+  cursor-col: int  # 1-indexed
   cursor-hide?: boolean
   curr-attributes: screen-cell
 }
@@ -217,22 +217,52 @@ $print-grapheme:body: {
     var screen-addr/esi: (addr screen) <- copy screen
     var cursor-col-addr/edx: (addr int) <- get screen-addr, cursor-col
     # adjust cursor if necessary
+    # to avoid premature scrolling it's important to do this lazily, at the last possible time
     {
-      var num-cols-addr/eax: (addr int) <- get screen-addr, num-cols
-      var num-cols/eax: int <- copy *num-cols-addr
+      # next row
+      var num-cols-addr/ecx: (addr int) <- get screen-addr, num-cols
+      var num-cols/ecx: int <- copy *num-cols-addr
       compare *cursor-col-addr, num-cols
       break-if-<=
       copy-to *cursor-col-addr, 1
-      var cursor-row-addr/eax: (addr int) <- get screen-addr, cursor-row
+      var cursor-row-addr/ebx: (addr int) <- get screen-addr, cursor-row
       increment *cursor-row-addr
+      # scroll
+      var num-rows-addr/eax: (addr int) <- get screen-addr, num-rows
+      var num-rows/eax: int <- copy *num-rows-addr
+      compare *cursor-row-addr, num-rows
+      break-if-<=
+      copy-to *cursor-row-addr, num-rows
+      # if (top-index > data size) top-index = 0, otherwise top-index += num-cols
+      $print-grapheme:perform-scroll: {
+        var top-index-addr/ebx: (addr int) <- get screen-addr, top-index
+        var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
+        var data/eax: (addr array screen-cell) <- lookup *data-ah
+        var max-index/edi: int <- length data
+        compare *top-index-addr, max-index
+        {
+          break-if->=
+          add-to *top-index-addr, num-cols
+          break $print-grapheme:perform-scroll
+        }
+        {
+          break-if-<
+          copy-to *top-index-addr, 0
+        }
+      }
     }
     var idx/ecx: int <- current-screen-cell-index screen-addr
+#?     print-string-to-real-screen "printing grapheme at screen index "
+#?     print-int32-hex-to-real-screen idx
+#?     print-string-to-real-screen ": "
     var data-ah/eax: (addr handle array screen-cell) <- get screen-addr, data
     var data/eax: (addr array screen-cell) <- lookup *data-ah
     var offset/ecx: (offset screen-cell) <- compute-offset data, idx
     var cell/eax: (addr screen-cell) <- index data, offset
     var dest/eax: (addr grapheme) <- get cell, data
     var c2/ecx: grapheme <- copy c
+#?     print-grapheme-to-real-screen c2
+#?     print-string-to-real-screen "\n"
     copy-to *dest, c2
     increment *cursor-col-addr
   }
@@ -255,6 +285,17 @@ fn screen-cell-index screen-on-stack: (addr screen), row: int, col: int -> resul
   result <- multiply num-cols
   result <- add col
   result <- subtract 1
+  # result = (result + top-index) % data length
+  var top-index-addr/eax: (addr int) <- get screen, top-index
+  result <- add *top-index-addr
+  var data-ah/eax: (addr handle array screen-cell) <- get screen, data
+  var data/eax: (addr array screen-cell) <- lookup *data-ah
+  var max-index/eax: int <- length data
+  compare result, max-index
+  {
+    break-if-<
+    result <- subtract max-index
+  }
 }
 
 fn screen-grapheme-at screen-on-stack: (addr screen), row: int, col: int -> result/eax: grapheme {
@@ -641,7 +682,29 @@ fn test-print-string-overflows-to-next-row {
   check-screen-row screen, 2, "efg", "F - test-print-string-overflows-to-next-row"
 }
 
-fn main -> exit-status/ebx: int {
-  run-tests
-  exit-status <- copy 0
-}
+fn test-check-screen-scrolls-on-overflow {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 4
+  # single character starting at bottom right
+  move-cursor screen, 5, 4
+  var c/eax: grapheme <- copy 0x61  # 'a'
+  print-grapheme screen, c
+  check-screen-row-from screen, 5, 4, "a", "F - test-check-screen-scrolls-on-overflow/baseline"  # bottom-right corner of the screen
+  # multiple characters starting at bottom right
+  move-cursor screen, 5, 4
+  print-string screen, "ab"
+  # screen scrolled up one row
+#?   check-screen-row screen, 1, "    ", "F - test-check-screen-scrolls-on-overflow/x1"
+#?   check-screen-row screen, 2, "    ", "F - test-check-screen-scrolls-on-overflow/x2"
+#?   check-screen-row screen, 3, "    ", "F - test-check-screen-scrolls-on-overflow/x3"
+#?   check-screen-row screen, 4, "   a", "F - test-check-screen-scrolls-on-overflow/x4"
+#?   check-screen-row screen, 5, "b   ", "F - test-check-screen-scrolls-on-overflow/x5"
+  check-screen-row-from screen, 4, 4, "a", "F - test-check-screen-scrolls-on-overflow/1"
+  check-screen-row-from screen, 5, 1, "b", "F - test-check-screen-scrolls-on-overflow/2"
+}
+
+#? fn main -> exit-status/ebx: int {
+#?   run-tests
+#?   exit-status <- copy 0
+#? }