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
|
||||
53/push-ebx
|
||||
56/push-esi
|
||||
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
|
||||
# var letter-bitmap/esi = font[g]
|
||||
8b/-> *(ebp+0xc) 6/r32/esi
|
||||
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
|
||||
}
|
||||
# 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
|
||||
|
@ -68,3 +75,24 @@ $draw-grapheme:end:
|
|||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
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 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 clear-stream f: (addr stream _)
|
||||
sig rewind-stream f: (addr stream _)
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
# 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.
|
||||
|
@ -86,3 +94,164 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
|
|||
}
|
||||
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:
|
||||
# ./translate_mu_baremetal baremetal/ex6.mu # emits disk.img
|
||||
|
@ -10,6 +10,7 @@
|
|||
# Expected output: a box and text that doesn't overflow it
|
||||
|
||||
fn main {
|
||||
# drawing text within a bounding box
|
||||
draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4
|
||||
var x/eax: 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, "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
|
||||
|
||||
# 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