7507 - baremetal: drawing text down then right
This commit is contained in:
parent
8a81faecbe
commit
4413168269
|
@ -8,6 +8,7 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
||||||
52/push-edx
|
52/push-edx
|
||||||
53/push-ebx
|
53/push-ebx
|
||||||
56/push-esi
|
56/push-esi
|
||||||
|
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
|
||||||
# var letter-bitmap/esi = font[g]
|
# var letter-bitmap/esi = font[g]
|
||||||
8b/-> *(ebp+0xc) 6/r32/esi
|
8b/-> *(ebp+0xc) 6/r32/esi
|
||||||
c1 4/subop/shift-left %esi 4/imm8
|
c1 4/subop/shift-left %esi 4/imm8
|
||||||
|
@ -57,6 +58,12 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
||||||
#
|
#
|
||||||
eb/jump loop/disp8
|
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:
|
$draw-grapheme:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5e/pop-to-esi
|
5e/pop-to-esi
|
||||||
|
@ -68,3 +75,24 @@ $draw-grapheme:end:
|
||||||
89/<- %esp 5/r32/ebp
|
89/<- %esp 5/r32/ebp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
|
cursor-position: # screen: (addr screen) -> _/eax: int, _/ecx: int
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
|
||||||
|
8b/-> *Default-next-x 0/r32/eax
|
||||||
|
8b/-> *Default-next-y 1/r32/ecx
|
||||||
|
$cursor-position:end:
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
|
== data
|
||||||
|
|
||||||
|
Default-next-x:
|
||||||
|
0/imm32
|
||||||
|
|
||||||
|
Default-next-y:
|
||||||
|
0/imm32
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
sig pixel screen: (addr screen), x: int, y: int, color: int
|
sig pixel screen: (addr screen), x: int, y: int, color: int
|
||||||
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
||||||
sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
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 clear-stream f: (addr stream _)
|
sig clear-stream f: (addr stream _)
|
||||||
sig rewind-stream f: (addr stream _)
|
sig rewind-stream f: (addr stream _)
|
||||||
sig write f: (addr stream byte), s: (addr array byte)
|
sig write f: (addr stream byte), s: (addr array byte)
|
||||||
|
|
|
@ -35,6 +35,14 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
|
||||||
return xcurr
|
return xcurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int -> _/eax: int {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- cursor-position screen
|
||||||
|
var result/eax: int <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
# draw text in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary
|
# draw text in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary
|
||||||
# return the next (x, y) coordinate in raster order where drawing stopped
|
# return the next (x, y) coordinate in raster order where drawing stopped
|
||||||
# that way the caller can draw more if given the same min and max bounding-box.
|
# that way the caller can draw more if given the same min and max bounding-box.
|
||||||
|
@ -86,3 +94,164 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
|
||||||
}
|
}
|
||||||
return xcurr, ycurr
|
return xcurr, ycurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, 0, 0, 0x400, 0x300, x, y, color # 1024, 768
|
||||||
|
return cursor-x, cursor-y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-wrapping-right-then-down-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int -> _/eax: int, _/ecx: int {
|
||||||
|
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
|
||||||
|
#? }
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int -> _/eax: int, _/ecx: int {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- draw-text-wrapping-right-then-down-from-cursor screen, text, 0, 0, 0x400, 0x300, color # 1024, 768
|
||||||
|
return cursor-x, cursor-y
|
||||||
|
}
|
||||||
|
|
||||||
|
## Text direction: down then right
|
||||||
|
|
||||||
|
# draw a single line of text vertically from x, y to ymax
|
||||||
|
# return the next 'y' coordinate
|
||||||
|
# if there isn't enough space, return 0 without modifying the screen
|
||||||
|
fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int -> _/eax: int {
|
||||||
|
var stream-storage: (stream byte 0x100)
|
||||||
|
var stream/esi: (addr stream byte) <- address stream-storage
|
||||||
|
write stream, text
|
||||||
|
# check if we have enough space
|
||||||
|
var ycurr/ecx: int <- copy y
|
||||||
|
{
|
||||||
|
compare ycurr, ymax
|
||||||
|
break-if->
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
compare ycurr, ymax
|
||||||
|
{
|
||||||
|
break-if-<=
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
# we do; actually draw
|
||||||
|
rewind-stream stream
|
||||||
|
ycurr <- copy y
|
||||||
|
{
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
draw-grapheme screen, g, x, ycurr, color
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
return ycurr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int -> _/eax: int {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- cursor-position screen
|
||||||
|
var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
# draw text down and right in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary
|
||||||
|
# return the next (x, y) coordinate in raster order where drawing stopped
|
||||||
|
# that way the caller can draw more if given the same min and max bounding-box.
|
||||||
|
# if there isn't enough space, return 0 without modifying the screen
|
||||||
|
fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int -> _/eax: int, _/ecx: int {
|
||||||
|
var stream-storage: (stream byte 0x100)
|
||||||
|
var stream/esi: (addr stream byte) <- address stream-storage
|
||||||
|
write stream, text
|
||||||
|
# check if we have enough space
|
||||||
|
var xcurr/edx: int <- copy x
|
||||||
|
var ycurr/ecx: int <- copy y
|
||||||
|
{
|
||||||
|
compare xcurr, xmax
|
||||||
|
break-if->=
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
compare ycurr, ymax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
xcurr <- add 8 # font-width
|
||||||
|
ycurr <- copy ymin
|
||||||
|
}
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
compare xcurr, xmax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
# we do; actually draw
|
||||||
|
rewind-stream stream
|
||||||
|
xcurr <- copy x
|
||||||
|
ycurr <- copy y
|
||||||
|
{
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
draw-grapheme screen, g, xcurr, ycurr, color
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
compare ycurr, ymax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
xcurr <- add 8 # font-width
|
||||||
|
ycurr <- copy ymin
|
||||||
|
}
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
return xcurr, ycurr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-wrapping-down-then-right-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int -> _/eax: int, _/ecx: int {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, 0, 0, 0x400, 0x300, x, y, color # 1024, 768
|
||||||
|
return cursor-x, cursor-y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-wrapping-down-then-right-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int -> _/eax: int, _/ecx: int {
|
||||||
|
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
|
||||||
|
#? }
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int -> _/eax: int, _/ecx: int {
|
||||||
|
var cursor-x/eax: int <- copy 0
|
||||||
|
var cursor-y/ecx: int <- copy 0
|
||||||
|
cursor-x, cursor-y <- draw-text-wrapping-down-then-right-from-cursor screen, text, 0, 0, 0x400, 0x300, color # 1024, 768
|
||||||
|
return cursor-x, cursor-y
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Drawing ASCII text incrementally within a bounding box.
|
# Drawing ASCII text incrementally.
|
||||||
#
|
#
|
||||||
# To build a disk image:
|
# To build a disk image:
|
||||||
# ./translate_mu_baremetal baremetal/ex6.mu # emits disk.img
|
# ./translate_mu_baremetal baremetal/ex6.mu # emits disk.img
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
# Expected output: a box and text that doesn't overflow it
|
# Expected output: a box and text that doesn't overflow it
|
||||||
|
|
||||||
fn main {
|
fn main {
|
||||||
|
# drawing text within a bounding box
|
||||||
draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4
|
draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4
|
||||||
var x/eax: int <- copy 0x20
|
var x/eax: int <- copy 0x20
|
||||||
var y/ecx: int <- copy 0x20
|
var y/ecx: int <- copy 0x20
|
||||||
|
@ -17,4 +18,8 @@ fn main {
|
||||||
x, y <- draw-text-wrapping-right-then-down 0, "from ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
x, y <- draw-text-wrapping-right-then-down 0, "from ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
||||||
x, y <- draw-text-wrapping-right-then-down 0, "baremetal ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
x, y <- draw-text-wrapping-right-then-down 0, "baremetal ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
||||||
x, y <- draw-text-wrapping-right-then-down 0, "Mu!", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
x, y <- draw-text-wrapping-right-then-down 0, "Mu!", 0x10, 0x20, 0x78, 0x50, x, y, 0xa
|
||||||
|
|
||||||
|
# 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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue