width-aware drawing primitives
No support yet for drawing wide graphemes.
This commit is contained in:
parent
bc859a7ca4
commit
8e182e394e
103
103grapheme.subx
103
103grapheme.subx
|
@ -10,24 +10,23 @@
|
||||||
# Therefore 'x' here is in [0, 128), and 'y' is in [0, 48)
|
# Therefore 'x' here is in [0, 128), and 'y' is in [0, 48)
|
||||||
# Doesn't update the cursor; where the cursor should go after printing the
|
# Doesn't update the cursor; where the cursor should go after printing the
|
||||||
# current grapheme is a higher-level concern.
|
# current grapheme is a higher-level concern.
|
||||||
draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, background-color: int
|
draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
#
|
#
|
||||||
(draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30)
|
(draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) # => eax
|
||||||
$draw-grapheme-on-real-screen:end:
|
$draw-grapheme-on-real-screen:end:
|
||||||
# . epilogue
|
# . epilogue
|
||||||
89/<- %esp 5/r32/ebp
|
89/<- %esp 5/r32/ebp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int
|
draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
|
||||||
51/push-ecx
|
51/push-ecx
|
||||||
52/push-edx
|
52/push-edx
|
||||||
# if screen-width*screen-height > len(screen-data) abort
|
# if screen-width*screen-height > len(screen-data) abort
|
||||||
|
@ -49,12 +48,11 @@ draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
05/add-to-eax 4/imm32
|
05/add-to-eax 4/imm32
|
||||||
#
|
#
|
||||||
(draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24))
|
(draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) # => eax
|
||||||
$draw-grapheme-on-screen-array:end:
|
$draw-grapheme-on-screen-array:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
59/pop-to-ecx
|
59/pop-to-ecx
|
||||||
58/pop-to-eax
|
|
||||||
# . epilogue
|
# . epilogue
|
||||||
89/<- %esp 5/r32/ebp
|
89/<- %esp 5/r32/ebp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
|
@ -67,15 +65,12 @@ $draw-grapheme-on-screen-array:abort:
|
||||||
(abort "draw-grapheme-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?")
|
(abort "draw-grapheme-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?")
|
||||||
|
|
||||||
# 'buffer' here is not a valid Mu type: a naked address without a length.
|
# 'buffer' here is not a valid Mu type: a naked address without a length.
|
||||||
draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int
|
# returns number of 8x16 units printed to screen (1 or 2).
|
||||||
|
draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
|
||||||
51/push-ecx
|
|
||||||
52/push-edx
|
|
||||||
53/push-ebx
|
|
||||||
56/push-esi
|
56/push-esi
|
||||||
# switch screen-width and screen-height from grapheme to pixel units
|
# switch screen-width and screen-height from grapheme to pixel units
|
||||||
c1 4/subop/shift-left *(ebp+20) 3/imm8/log2-font-width
|
c1 4/subop/shift-left *(ebp+20) 3/imm8/log2-font-width
|
||||||
|
@ -88,7 +83,64 @@ draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y:
|
||||||
# var letter-bitmap/esi = font[g]
|
# var letter-bitmap/esi = font[g]
|
||||||
69/multiply %esi 0x21/imm32/glyph-size 6/r32/esi
|
69/multiply %esi 0x21/imm32/glyph-size 6/r32/esi
|
||||||
81 0/subop/add %esi Font/imm32
|
81 0/subop/add %esi Font/imm32
|
||||||
|
# dispatch based on letter-bitmap->size
|
||||||
|
b8/copy-to-eax 0/imm32
|
||||||
|
8a/byte-> *esi 0/r32/AL
|
||||||
46/increment-esi # skip size
|
46/increment-esi # skip size
|
||||||
|
3d/compare-eax-and 8/imm32
|
||||||
|
{
|
||||||
|
75/jump-if-!= break/disp8
|
||||||
|
(draw-narrow-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24))
|
||||||
|
b8/copy-to-eax 1/imm32
|
||||||
|
eb/jump $draw-grapheme-on-screen-buffer:end/disp8
|
||||||
|
}
|
||||||
|
(draw-wide-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24))
|
||||||
|
b8/copy-to-eax 2/imm32
|
||||||
|
$draw-grapheme-on-screen-buffer:end:
|
||||||
|
# . restore registers
|
||||||
|
5e/pop-to-esi
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
|
wide-grapheme?: # g: grapheme -> _/eax: boolean
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
# eax = g
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
# if (g >= 128) return # characters beyond ASCII currently not supported
|
||||||
|
3d/compare-eax-and 0x80/imm32
|
||||||
|
0f 8d/jump-if->= $wide-grapheme?:end/disp32
|
||||||
|
# var letter-bitmap/eax = font[g]
|
||||||
|
69/multiply %eax 0x21/imm32/glyph-size 0/r32/eax
|
||||||
|
05/add-to-eax Font/imm32
|
||||||
|
# dispatch based on letter-bitmap->size
|
||||||
|
8a/byte-> *eax 0/r32/AL
|
||||||
|
25/and-eax-with 0xff/imm32
|
||||||
|
3d/compare-eax-and 8/imm32
|
||||||
|
0f 95/set-if-!= %eax
|
||||||
|
$wide-grapheme?:end:
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
|
# buffer: naked address to raw screen RAM without a length
|
||||||
|
# letter-bitmap: naked address to 8-pixel wide font glyph
|
||||||
|
draw-narrow-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
# . save registers
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
52/push-edx
|
||||||
|
53/push-ebx
|
||||||
|
56/push-esi
|
||||||
|
# esi = letter-bitmap
|
||||||
|
8b/-> *(ebp+0xc) 6/r32/esi
|
||||||
# var ycurr/edx: int = y*16
|
# var ycurr/edx: int = y*16
|
||||||
8b/-> *(ebp+0x14) 2/r32/edx
|
8b/-> *(ebp+0x14) 2/r32/edx
|
||||||
c1 4/subop/shift-left %edx 4/imm8
|
c1 4/subop/shift-left %edx 4/imm8
|
||||||
|
@ -139,7 +191,32 @@ $draw-grapheme-on-screen-buffer:continue:
|
||||||
#
|
#
|
||||||
e9/jump loop/disp32
|
e9/jump loop/disp32
|
||||||
}
|
}
|
||||||
$draw-grapheme-on-screen-buffer:end:
|
$draw-narrow-grapheme-on-screen-buffer:end:
|
||||||
|
# . restore registers
|
||||||
|
5e/pop-to-esi
|
||||||
|
5b/pop-to-ebx
|
||||||
|
5a/pop-to-edx
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
|
# buffer: naked address to raw screen RAM without a length
|
||||||
|
# letter-bitmap: naked address to 16-pixel wide font glyph
|
||||||
|
draw-wide-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
# . save registers
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
52/push-edx
|
||||||
|
53/push-ebx
|
||||||
|
56/push-esi
|
||||||
|
# HERE
|
||||||
|
$draw-wide-grapheme-on-screen-buffer:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5e/pop-to-esi
|
5e/pop-to-esi
|
||||||
5b/pop-to-ebx
|
5b/pop-to-ebx
|
||||||
|
@ -198,7 +275,7 @@ draw-cursor-on-real-screen: # g: grapheme
|
||||||
51/push-ecx
|
51/push-ecx
|
||||||
#
|
#
|
||||||
(cursor-position-on-real-screen) # => eax, ecx
|
(cursor-position-on-real-screen) # => eax, ecx
|
||||||
(draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7)
|
(draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) # => eax
|
||||||
$draw-cursor-on-real-screen:end:
|
$draw-cursor-on-real-screen:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
59/pop-to-ecx
|
59/pop-to-ecx
|
||||||
|
|
5
400.mu
5
400.mu
|
@ -1,7 +1,8 @@
|
||||||
# screen
|
# screen
|
||||||
sig pixel-on-real-screen x: int, y: int, color: int
|
sig pixel-on-real-screen x: int, y: int, color: int
|
||||||
sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int
|
sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax: int
|
||||||
sig draw-grapheme-on-screen-array screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int
|
sig draw-grapheme-on-screen-array screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int
|
||||||
|
sig wide-grapheme? g: grapheme -> _/eax: boolean
|
||||||
sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
|
sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
|
||||||
sig set-cursor-position-on-real-screen x: int, y: int
|
sig set-cursor-position-on-real-screen x: int, y: int
|
||||||
sig draw-cursor-on-real-screen g: grapheme
|
sig draw-cursor-on-real-screen g: grapheme
|
||||||
|
|
|
@ -48,8 +48,6 @@ fn initialize-screen _screen: (addr screen), width: int, height: int, pixel-grap
|
||||||
capacity <- multiply height
|
capacity <- multiply height
|
||||||
#
|
#
|
||||||
populate data-ah, capacity
|
populate data-ah, capacity
|
||||||
# save sentinel index
|
|
||||||
capacity <- decrement
|
|
||||||
}
|
}
|
||||||
# if necessary, populate screen->pixels
|
# if necessary, populate screen->pixels
|
||||||
{
|
{
|
||||||
|
@ -62,8 +60,6 @@ fn initialize-screen _screen: (addr screen), width: int, height: int, pixel-grap
|
||||||
capacity <- shift-left 4/log2-font-height
|
capacity <- shift-left 4/log2-font-height
|
||||||
#
|
#
|
||||||
populate pixels-ah, capacity
|
populate pixels-ah, capacity
|
||||||
# save sentinel index
|
|
||||||
capacity <- decrement
|
|
||||||
}
|
}
|
||||||
# screen->cursor-x = 0
|
# screen->cursor-x = 0
|
||||||
dest <- get screen, cursor-x
|
dest <- get screen, cursor-x
|
||||||
|
@ -92,15 +88,29 @@ fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int {
|
||||||
}
|
}
|
||||||
|
|
||||||
# testable screen primitive
|
# testable screen primitive
|
||||||
fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int {
|
# return number of 8x16 units drawn
|
||||||
|
fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
||||||
var screen/esi: (addr screen) <- copy _screen
|
var screen/esi: (addr screen) <- copy _screen
|
||||||
{
|
{
|
||||||
compare screen, 0
|
compare screen, 0
|
||||||
break-if-!=
|
break-if-!=
|
||||||
draw-grapheme-on-real-screen g, x, y, color, background-color
|
var result/eax: int <- draw-grapheme-on-real-screen g, x, y, color, background-color
|
||||||
return
|
return result
|
||||||
}
|
}
|
||||||
# fake screen
|
# fake screen
|
||||||
|
var wide?/eax: boolean <- wide-grapheme? g
|
||||||
|
compare wide?, 0/false
|
||||||
|
{
|
||||||
|
break-if-=
|
||||||
|
draw-wide-grapheme-on-fake-screen screen, g, x, y, color, background-color
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
draw-narrow-grapheme-on-fake-screen screen, g, x, y, color, background-color
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-narrow-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int {
|
||||||
|
var screen/esi: (addr screen) <- copy _screen
|
||||||
# ignore if out of bounds
|
# ignore if out of bounds
|
||||||
{
|
{
|
||||||
compare x, 0
|
compare x, 0
|
||||||
|
@ -108,10 +118,13 @@ fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var xmax/eax: (addr int) <- get screen, width
|
var xmax-addr/eax: (addr int) <- get screen, width
|
||||||
var xcurr/ecx: int <- copy x
|
var xmax/eax: int <- copy *xmax-addr
|
||||||
compare xcurr, *xmax
|
compare x, xmax
|
||||||
break-if-<
|
break-if-<
|
||||||
|
{
|
||||||
|
loop
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -120,9 +133,9 @@ fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var ymax/eax: (addr int) <- get screen, height
|
var ymax-addr/eax: (addr int) <- get screen, height
|
||||||
var ycurr/ecx: int <- copy y
|
var ymax/eax: int <- copy *ymax-addr
|
||||||
compare ycurr, *ymax
|
compare y, ymax
|
||||||
break-if-<
|
break-if-<
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -141,12 +154,75 @@ fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int
|
||||||
dest-color <- get dest-cell, background-color
|
dest-color <- get dest-cell, background-color
|
||||||
src-color <- copy background-color
|
src-color <- copy background-color
|
||||||
copy-to *dest-color, src-color
|
copy-to *dest-color, src-color
|
||||||
|
var dest/eax: (addr boolean) <- get dest-cell, unused?
|
||||||
|
copy-to *dest, 0/false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-wide-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int {
|
||||||
|
var screen/esi: (addr screen) <- copy _screen
|
||||||
|
# ignore if out of bounds
|
||||||
|
{
|
||||||
|
compare x, 0
|
||||||
|
break-if->=
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var xmax-addr/eax: (addr int) <- get screen, width
|
||||||
|
var xmax/eax: int <- copy *xmax-addr
|
||||||
|
xmax <- decrement # wide graphemes need an extra unit
|
||||||
|
compare x, xmax
|
||||||
|
break-if-<
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{
|
||||||
|
compare y, 0
|
||||||
|
break-if->=
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var ymax-addr/eax: (addr int) <- get screen, height
|
||||||
|
var ymax/eax: int <- copy *ymax-addr
|
||||||
|
compare y, ymax
|
||||||
|
break-if-<
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#
|
||||||
|
var index/ecx: int <- screen-cell-index screen, x, y
|
||||||
|
{
|
||||||
|
var data-ah/eax: (addr handle array screen-cell) <- get screen, data
|
||||||
|
var data/eax: (addr array screen-cell) <- lookup *data-ah
|
||||||
|
var offset/ecx: (offset screen-cell) <- compute-offset data, index
|
||||||
|
var dest-cell/ecx: (addr screen-cell) <- index data, offset
|
||||||
|
var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data
|
||||||
|
var g2/edx: grapheme <- copy g
|
||||||
|
copy-to *dest-grapheme, g2
|
||||||
|
var dest-color/eax: (addr int) <- get dest-cell, color
|
||||||
|
var src-color/edx: int <- copy color
|
||||||
|
copy-to *dest-color, src-color
|
||||||
|
dest-color <- get dest-cell, background-color
|
||||||
|
src-color <- copy background-color
|
||||||
|
copy-to *dest-color, src-color
|
||||||
|
var dest/eax: (addr boolean) <- get dest-cell, unused?
|
||||||
|
copy-to *dest, 0/false
|
||||||
|
}
|
||||||
|
# set next screen-cell to unused
|
||||||
|
index <- increment
|
||||||
|
{
|
||||||
|
var data-ah/eax: (addr handle array screen-cell) <- get screen, data
|
||||||
|
var data/eax: (addr array screen-cell) <- lookup *data-ah
|
||||||
|
var offset/ecx: (offset screen-cell) <- compute-offset data, index
|
||||||
|
var dest-cell/ecx: (addr screen-cell) <- index data, offset
|
||||||
|
var dest/eax: (addr boolean) <- get dest-cell, unused?
|
||||||
|
copy-to *dest, 1/true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# we can't really render non-ASCII yet, but when we do we'll be ready
|
# we can't really render non-ASCII yet, but when we do we'll be ready
|
||||||
fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int {
|
# return number of 8x16 units drawn
|
||||||
|
fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
||||||
var g/eax: grapheme <- copy c
|
var g/eax: grapheme <- copy c
|
||||||
draw-grapheme screen, g, x, y, color, background-color
|
var result/eax: int <- draw-grapheme screen, g, x, y, color, background-color
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
# fake screens only
|
# fake screens only
|
||||||
|
@ -233,7 +309,7 @@ fn draw-cursor screen: (addr screen), g: grapheme {
|
||||||
var cursor-x/eax: int <- copy 0
|
var cursor-x/eax: int <- copy 0
|
||||||
var cursor-y/ecx: int <- copy 0
|
var cursor-y/ecx: int <- copy 0
|
||||||
cursor-x, cursor-y <- cursor-position screen
|
cursor-x, cursor-y <- cursor-position screen
|
||||||
draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg
|
var dummy/eax: int <- draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear-screen _screen: (addr screen) {
|
fn clear-screen _screen: (addr screen) {
|
||||||
|
@ -256,7 +332,7 @@ fn clear-screen _screen: (addr screen) {
|
||||||
{
|
{
|
||||||
compare x, *width
|
compare x, *width
|
||||||
break-if->=
|
break-if->=
|
||||||
draw-code-point screen, 0/nul, x, y, 0/fg=black, 0/bg=black
|
var dummy/eax: int <- draw-code-point screen, 0/nul, x, y, 0/fg=black, 0/bg=black
|
||||||
x <- increment
|
x <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
@ -358,7 +434,7 @@ fn clear-rect _screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int
|
||||||
{
|
{
|
||||||
compare x, xmax
|
compare x, xmax
|
||||||
break-if->=
|
break-if->=
|
||||||
draw-code-point screen, 0x20/space, x, y, 0/fg, background-color
|
var dummy/eax: int <- draw-code-point screen, 0x20/space, x, y, 0/fg, background-color
|
||||||
x <- increment
|
x <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
@ -618,9 +694,9 @@ fn convert-graphemes-to-pixels _screen: (addr screen) {
|
||||||
var fg: int
|
var fg: int
|
||||||
copy-to fg, tmp
|
copy-to fg, tmp
|
||||||
var bg/eax: int <- screen-background-color-at screen, x, y
|
var bg/eax: int <- screen-background-color-at screen, x, y
|
||||||
draw-grapheme-on-screen-array data, g, x, y, fg, bg, *width-a, *height-a
|
var offset/eax: int <- draw-grapheme-on-screen-array data, g, x, y, fg, bg, *width-a, *height-a
|
||||||
|
x <- add offset
|
||||||
}
|
}
|
||||||
x <- increment
|
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
y <- increment
|
y <- increment
|
||||||
|
|
|
@ -85,14 +85,21 @@ fn draw-grapheme-at-cursor-over-full-screen screen: (addr screen), g: grapheme,
|
||||||
var cursor-x/eax: int <- copy 0
|
var cursor-x/eax: int <- copy 0
|
||||||
var cursor-y/ecx: int <- copy 0
|
var cursor-y/ecx: int <- copy 0
|
||||||
cursor-x, cursor-y <- cursor-position screen
|
cursor-x, cursor-y <- cursor-position screen
|
||||||
draw-grapheme screen, g, cursor-x, cursor-y, color, background-color
|
var _offset/eax: int <- draw-grapheme screen, g, cursor-x, cursor-y, color, background-color
|
||||||
|
var offset/edx: int <- copy _offset
|
||||||
var width/eax: int <- copy 0
|
var width/eax: int <- copy 0
|
||||||
var dummy/ecx: int <- copy 0
|
var dummy/ecx: int <- copy 0
|
||||||
width, dummy <- screen-size screen
|
width, dummy <- screen-size screen
|
||||||
move-cursor-rightward-and-downward screen, 0 width
|
move-cursor-rightward-and-downward screen, 0 width
|
||||||
|
offset <- decrement
|
||||||
|
compare offset, 0
|
||||||
|
{
|
||||||
|
break-if-=
|
||||||
|
# should never move downward here
|
||||||
|
move-cursor-rightward-and-downward screen, 0 width
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# we can't really render non-ASCII yet, but when we do we'll be ready
|
|
||||||
fn draw-code-point-at-cursor-over-full-screen screen: (addr screen), c: code-point, color: int, background-color: int {
|
fn draw-code-point-at-cursor-over-full-screen screen: (addr screen), c: code-point, color: int, background-color: int {
|
||||||
var g/eax: grapheme <- copy c
|
var g/eax: grapheme <- copy c
|
||||||
draw-grapheme-at-cursor-over-full-screen screen, g, color, background-color
|
draw-grapheme-at-cursor-over-full-screen screen, g, color, background-color
|
||||||
|
@ -118,8 +125,8 @@ fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: i
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
compare g, 0xffffffff/end-of-file
|
compare g, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-grapheme screen, g, xcurr, y, color, background-color
|
var offset/eax: int <- draw-grapheme screen, g, xcurr, y, color, background-color
|
||||||
xcurr <- increment
|
xcurr <- add offset
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
set-cursor-position screen, xcurr, y
|
set-cursor-position screen, xcurr, y
|
||||||
|
@ -151,17 +158,17 @@ fn draw-text-rightward-from-cursor-over-full-screen screen: (addr screen), text:
|
||||||
|
|
||||||
fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
|
fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
|
||||||
compare g, 0xa/newline
|
compare g, 0xa/newline
|
||||||
var x/eax: int <- copy x
|
var x/ecx: int <- copy x
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
# minimum effort to clear cursor
|
# minimum effort to clear cursor
|
||||||
draw-code-point screen, 0x20/space, x, y, color, background-color
|
var dummy/eax: int <- draw-code-point screen, 0x20/space, x, y, color, background-color
|
||||||
x <- copy xmin
|
x <- copy xmin
|
||||||
increment y
|
increment y
|
||||||
return x, y
|
return x, y
|
||||||
}
|
}
|
||||||
draw-grapheme screen, g, x, y, color, background-color
|
var offset/eax: int <- draw-grapheme screen, g, x, y, color, background-color
|
||||||
x <- increment
|
x <- add offset
|
||||||
compare x, xmax
|
compare x, xmax
|
||||||
{
|
{
|
||||||
break-if-<
|
break-if-<
|
||||||
|
@ -294,8 +301,8 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin:
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
compare g, 0xffffffff/end-of-file
|
compare g, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
||||||
xcurr <- increment
|
xcurr <- add offset
|
||||||
compare xcurr, xmax
|
compare xcurr, xmax
|
||||||
{
|
{
|
||||||
break-if-<
|
break-if-<
|
||||||
|
@ -348,8 +355,8 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
compare g, 0xffffffff/end-of-file
|
compare g, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
||||||
xcurr <- increment
|
xcurr <- add offset
|
||||||
compare xcurr, xmax
|
compare xcurr, xmax
|
||||||
{
|
{
|
||||||
break-if-<
|
break-if-<
|
||||||
|
@ -408,13 +415,14 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y:
|
||||||
# draw a single-line stream vertically from x, y to ymax
|
# draw a single-line stream vertically from x, y to ymax
|
||||||
# return the next 'y' coordinate
|
# return the next 'y' coordinate
|
||||||
# if there isn't enough space, truncate
|
# if there isn't enough space, truncate
|
||||||
|
# TODO: should we track horizontal width?
|
||||||
fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
|
fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
|
||||||
var ycurr/ecx: int <- copy y
|
var ycurr/ecx: int <- copy y
|
||||||
{
|
{
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
compare g, 0xffffffff/end-of-file
|
compare g, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-grapheme screen, g, x, ycurr, color, background-color
|
var dummy/eax: int <- draw-grapheme screen, g, x, ycurr, color, background-color
|
||||||
ycurr <- increment
|
ycurr <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
@ -447,6 +455,7 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b
|
||||||
# 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.
|
||||||
# if there isn't enough space, truncate
|
# if there isn't enough space, truncate
|
||||||
|
# TODO: should we track horizontal width? just always offset by 2 for now
|
||||||
fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
|
fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
|
||||||
var xcurr/edx: int <- copy x
|
var xcurr/edx: int <- copy x
|
||||||
var ycurr/ecx: int <- copy y
|
var ycurr/ecx: int <- copy y
|
||||||
|
@ -454,12 +463,12 @@ fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr str
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
compare g, 0xffffffff/end-of-file
|
compare g, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color
|
||||||
ycurr <- increment
|
ycurr <- increment
|
||||||
compare ycurr, ymax
|
compare ycurr, ymax
|
||||||
{
|
{
|
||||||
break-if-<
|
break-if-<
|
||||||
xcurr <- increment
|
xcurr <- add 2
|
||||||
ycurr <- copy ymin
|
ycurr <- copy ymin
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
|
|
|
@ -337,7 +337,7 @@ fn test-draw-single-grapheme {
|
||||||
var _screen: screen
|
var _screen: screen
|
||||||
var screen/esi: (addr screen) <- address _screen
|
var screen/esi: (addr screen) <- address _screen
|
||||||
initialize-screen screen, 5, 4, 0/no-pixel-graphics
|
initialize-screen screen, 5, 4, 0/no-pixel-graphics
|
||||||
draw-code-point screen, 0x61/a, 0/x, 0/y, 1/fg, 2/bg
|
var dummy/eax: int <- draw-code-point screen, 0x61/a, 0/x, 0/y, 1/fg, 2/bg
|
||||||
check-screen-row screen, 0/y, "a", "F - test-draw-single-grapheme" # top-left corner of the screen
|
check-screen-row screen, 0/y, "a", "F - test-draw-single-grapheme" # top-left corner of the screen
|
||||||
check-screen-row-in-color screen, 1/fg, 0/y, "a", "F - test-draw-single-grapheme-fg"
|
check-screen-row-in-color screen, 1/fg, 0/y, "a", "F - test-draw-single-grapheme-fg"
|
||||||
check-screen-row-in-background-color screen, 2/bg, 0/y, "a", "F - test-draw-single-grapheme-bg"
|
check-screen-row-in-background-color screen, 2/bg, 0/y, "a", "F - test-draw-single-grapheme-bg"
|
||||||
|
|
|
@ -10,5 +10,5 @@
|
||||||
# Expected output: letter 'A' in green near the top-left corner of screen
|
# Expected output: letter 'A' in green near the top-left corner of screen
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
|
var dummy/eax: int <- draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue