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.
This commit is contained in:
Kartik Agaram 2021-01-13 00:02:35 -08:00
parent 4413168269
commit 422ebaf88c
4 changed files with 47 additions and 24 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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
}

View File

@ -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
}