From 422ebaf88c5a04900beb0a68162213ebc94e37c2 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 13 Jan 2021 00:02:35 -0800 Subject: [PATCH] 7508 This is the right way to be direction-independent. Don't save the cursor when drawing a single grapheme. Where the next char goes is just a property of the direction-oriented primitives. --- baremetal/103grapheme.subx | 25 +++++++++++++++++++------ baremetal/400.mu | 1 + baremetal/501draw-text.mu | 38 ++++++++++++++++++++------------------ baremetal/ex6.mu | 7 +++++++ 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/baremetal/103grapheme.subx b/baremetal/103grapheme.subx index 053cd497..a536bfed 100644 --- a/baremetal/103grapheme.subx +++ b/baremetal/103grapheme.subx @@ -58,12 +58,6 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int # eb/jump loop/disp8 } - # Save default coordinates for a future call to draw-grapheme - 8b/-> *(ebp+0x10) 0/r32/eax - 81 0/subop/add %eax 8/imm32 - 89/<- *Default-next-x 0/r32/eax - 8b/-> *(ebp+0x14) 0/r32/eax - 89/<- *Default-next-y 0/r32/eax $draw-grapheme:end: # . restore registers 5e/pop-to-esi @@ -89,6 +83,25 @@ $cursor-position:end: 5d/pop-to-ebp c3/return +set-cursor-position: # screen: (addr screen), x: int, y: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + # TODO: support fake screen; we currently assume 'screen' is always 0 (real) + 8b/-> *(ebp+0xc) 0/r32/eax + 89/<- *Default-next-x 0/r32/eax + 8b/-> *(ebp+0x10) 0/r32/eax + 89/<- *Default-next-y 0/r32/eax +$set-cursor-position:end: + # . restore registers + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + == data Default-next-x: diff --git a/baremetal/400.mu b/baremetal/400.mu index c32497b8..dd494ecf 100644 --- a/baremetal/400.mu +++ b/baremetal/400.mu @@ -2,6 +2,7 @@ sig pixel screen: (addr screen), x: int, y: int, color: int sig read-key kbd: (addr keyboard) -> _/eax: byte sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int sig cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int +sig set-cursor-position screen: (addr screen), x: int, y: int sig clear-stream f: (addr stream _) sig rewind-stream f: (addr stream _) sig write f: (addr stream byte), s: (addr array byte) diff --git a/baremetal/501draw-text.mu b/baremetal/501draw-text.mu index 63e41728..5ddb4bf5 100644 --- a/baremetal/501draw-text.mu +++ b/baremetal/501draw-text.mu @@ -32,6 +32,7 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x xcurr <- add 8 # font-width loop } + set-cursor-position screen, xcurr, y return xcurr } @@ -92,6 +93,7 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b } loop } + set-cursor-position screen, xcurr, ycurr return xcurr, ycurr } @@ -106,16 +108,14 @@ fn draw-text-wrapping-right-then-down-from-cursor screen: (addr screen), text: ( var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen - # we could wrap around if we're too far to the right, but that feels like it - # makes assumptions about text direction -#? var end-x/edx: int <- copy cursor-x -#? end-x <- add 8 # font-width -#? compare end-x, xmax -#? { -#? break-if-< -#? cursor-x <- copy xmin -#? cursor-y <- add 0x10 # font-height -#? } + var end-x/edx: int <- copy cursor-x + end-x <- add 8 # font-width + compare end-x, xmax + { + break-if-< + cursor-x <- copy xmin + cursor-y <- add 0x10 # font-height + } cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color return cursor-x, cursor-y } @@ -163,6 +163,7 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: ycurr <- add 0x10 # font-height loop } + set-cursor-position screen, x, ycurr return ycurr } @@ -223,6 +224,7 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b } loop } + set-cursor-position screen, xcurr, ycurr return xcurr, ycurr } @@ -237,14 +239,14 @@ fn draw-text-wrapping-down-then-right-from-cursor screen: (addr screen), text: ( var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen -#? var end-y/edx: int <- copy cursor-y -#? end-y <- add 0x10 # font-height -#? compare end-y, ymax -#? { -#? break-if-< -#? cursor-x <- add 8 # font-width -#? cursor-y <- copy ymin -#? } + var end-y/edx: int <- copy cursor-y + end-y <- add 0x10 # font-height + compare end-y, ymax + { + break-if-< + cursor-x <- add 8 # font-width + cursor-y <- copy ymin + } cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color return cursor-x, cursor-y } diff --git a/baremetal/ex6.mu b/baremetal/ex6.mu index 00fefe60..587720d5 100644 --- a/baremetal/ex6.mu +++ b/baremetal/ex6.mu @@ -22,4 +22,11 @@ fn main { # drawing at the cursor in multiple directions x, y <- draw-text-wrapping-down-then-right-from-cursor-over-full-screen 0, "abc", 0xa x, y <- draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "def", 0xa + + # test drawing near the edge + x <- draw-text-rightward 0, "R", 0x3f8, 0x400, 0x100, 0xa + x, y <- draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "wrapped from R", 0xa + + x <- draw-text-downward 0, "D", 0x100, 0x2f0, 0x300, 0xa + x, y <- draw-text-wrapping-down-then-right-from-cursor-over-full-screen 0, "wrapped from D", 0xa }