about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-05-18 10:23:54 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-05-18 10:23:54 -0700
commitfd57c48c60851cd39a7105e3805c57d78cf2ea98 (patch)
treefb692b64462e45fdf3ac4f6c04fe7b72b4e94c0e
parent2952a2996060070c529d9b9692f6a6c4b6009d22 (diff)
downloadmu-fd57c48c60851cd39a7105e3805c57d78cf2ea98.tar.gz
start double-buffering
Amazing how much difference it makes even when the implementation is so
naive and slow.
-rw-r--r--313index-bounds-check.subx8
-rw-r--r--500fake-screen.mu39
-rw-r--r--hest-life.mu9
3 files changed, 48 insertions, 8 deletions
diff --git a/313index-bounds-check.subx b/313index-bounds-check.subx
index 4bc8e12e..b6a64876 100644
--- a/313index-bounds-check.subx
+++ b/313index-bounds-check.subx
@@ -33,9 +33,7 @@ __check-mu-array-bounds:  # index: int, elem-size: int, arr-size: int, function-
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " is too large for array '" 3 0)  # 3=cyan
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0x18) 3 0)  # 3=cyan
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "'" 3 0)  # 3=cyan
-    {
-      eb/jump loop/disp8
-    }
+    (abort "")
     # never gets here
 $__check-mu-array-bounds:end:
     # . restore registers
@@ -53,9 +51,7 @@ __check-mu-array-bounds:overflow:
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 ": offset to array '" 3 0)  # 3=cyan
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0x18) 3 0)  # 3=cyan
     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "' overflowed 32 bits" 3 0)  # 3=cyan
-    {
-      eb/jump loop/disp8
-    }
+    (abort "")
     # never gets here
 
 __mu-abort-null-index-base-address:
diff --git a/500fake-screen.mu b/500fake-screen.mu
index fc907885..607f1ce8 100644
--- a/500fake-screen.mu
+++ b/500fake-screen.mu
@@ -516,3 +516,42 @@ fn pixel-index _screen: (addr screen), x: int, y: int -> _/ecx: int {
   result <- add x
   return result
 }
+
+# double-buffering primitive
+# 'screen' must be a fake screen. 'target-screen' is usually real.
+# Both screens must have the same size.
+fn copy-pixels _screen: (addr screen), target-screen: (addr screen) {
+  var screen/esi: (addr screen) <- copy _screen
+  var pixels-ah/eax: (addr handle array byte) <- get screen, pixels
+  var _pixels/eax: (addr array byte) <- lookup *pixels-ah
+  var pixels/edi: (addr array byte) <- copy _pixels
+  var width-a/edx: (addr int) <- get screen, width
+  var width/edx: int <- copy *width-a
+  width <- shift-left 3/log2-font-width
+  var height-a/ebx: (addr int) <- get screen, height
+  var height/ebx: int <- copy *height-a
+  height <- shift-left 4/log2-font-height
+  var i/esi: int <- copy 0
+  var y/ecx: int <- copy 0
+  {
+    # screen top left pixels x y width height
+    compare y, height
+    break-if->=
+    var x/eax: int <- copy 0
+    {
+      compare x, width
+      break-if->=
+      {
+        var color-addr/ebx: (addr byte) <- index pixels, i
+        var color/ebx: byte <- copy-byte *color-addr
+        var color2/ebx: int <- copy color
+        pixel target-screen, x, y, color2
+      }
+      x <- increment
+      i <- increment
+      loop
+    }
+    y <- increment
+    loop
+  }
+}
diff --git a/hest-life.mu b/hest-life.mu
index ceb16a8b..2cefd9bf 100644
--- a/hest-life.mu
+++ b/hest-life.mu
@@ -16,7 +16,11 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
   var env-storage: environment
   var env/esi: (addr environment) <- address env-storage
   initialize-environment env
-  render screen, env
+  var second-buffer: screen
+  var second-screen/edi: (addr screen) <- address second-buffer
+  initialize-screen second-screen, 0x80, 0x30, 1/include-pixels
+  render second-screen, env
+  copy-pixels second-screen, screen
   {
     edit keyboard, env
     var play?/eax: (addr boolean) <- get env, play?
@@ -24,7 +28,8 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
     {
       break-if-=
       step env
-      render screen, env
+      render second-screen, env
+      copy-pixels second-screen, screen
     }
     linger env
     loop