mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
adding rect and fillrect to gfx2
This commit is contained in:
parent
cdcda27d07
commit
dd82e550d5
@ -110,6 +110,8 @@ graphics {
|
||||
|
||||
sub circle(uword xcenter, ubyte ycenter, ubyte radius) {
|
||||
; Midpoint algorithm
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp ploty
|
||||
ubyte @zp xx = radius
|
||||
ubyte @zp yy = 0
|
||||
@ -148,8 +150,10 @@ graphics {
|
||||
|
||||
sub disc(uword xcenter, ubyte ycenter, ubyte radius) {
|
||||
; Midpoint algorithm, filled
|
||||
ubyte xx = radius
|
||||
ubyte yy = 0
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp xx = radius
|
||||
ubyte @zp yy = 0
|
||||
byte decisionOver2 = 1-xx as byte
|
||||
|
||||
while xx>=yy {
|
||||
|
@ -98,7 +98,31 @@ gfx2 {
|
||||
position(0, 0)
|
||||
}
|
||||
|
||||
sub horizontal_line(uword x, uword y, ubyte length, ubyte color) {
|
||||
sub rect(uword x, uword y, uword width, uword height, ubyte color) {
|
||||
if width==0 or height==0
|
||||
return
|
||||
horizontal_line(x, y, width, color)
|
||||
if height==1
|
||||
return
|
||||
horizontal_line(x, y+height-1, width, color)
|
||||
vertical_line(x, y+1, height-2, color)
|
||||
if width==1
|
||||
return
|
||||
vertical_line(x+width-1, y+1, height-2, color)
|
||||
}
|
||||
|
||||
sub fillrect(uword x, uword y, uword width, uword height, ubyte color) {
|
||||
if width==0
|
||||
return
|
||||
repeat height {
|
||||
horizontal_line(x, y, width, color)
|
||||
y++
|
||||
}
|
||||
}
|
||||
|
||||
sub horizontal_line(uword x, uword y, uword length, ubyte color) {
|
||||
if length==0
|
||||
return
|
||||
when active_mode {
|
||||
1 -> {
|
||||
; 8bpp mode
|
||||
@ -117,8 +141,108 @@ gfx2 {
|
||||
}
|
||||
}
|
||||
|
||||
sub circle(uword xcenter, uword ycenter, ubyte radius, ubyte color) {
|
||||
sub vertical_line(uword x, uword y, uword height, ubyte color) {
|
||||
; TODO optimize this to use vera special increment mode
|
||||
repeat height {
|
||||
plot(x, y, color)
|
||||
y++
|
||||
}
|
||||
}
|
||||
|
||||
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
|
||||
; Bresenham algorithm.
|
||||
; This code special-cases various quadrant loops to allow simple ++ and -- operations.
|
||||
; TODO rewrite this in optimized assembly
|
||||
if y1>y2 {
|
||||
; make sure dy is always positive to have only 4 instead of 8 special cases
|
||||
swap(x1, x2)
|
||||
swap(y1, y2)
|
||||
}
|
||||
word @zp dx = x2-x1 as word
|
||||
word @zp dy = y2-y1 as word
|
||||
|
||||
if dx==0 {
|
||||
vertical_line(x1, y1, abs(dy)+1 as uword, 255)
|
||||
return
|
||||
}
|
||||
if dy==0 {
|
||||
if x1>x2
|
||||
x1=x2
|
||||
horizontal_line(x1, y1, abs(dx)+1 as uword, 255)
|
||||
return
|
||||
}
|
||||
|
||||
word @zp d = 0
|
||||
ubyte positive_ix = true
|
||||
if dx < 0 {
|
||||
dx = -dx
|
||||
positive_ix = false
|
||||
}
|
||||
dx *= 2
|
||||
dy *= 2
|
||||
cx16.r14 = x1 ; internal plot X
|
||||
|
||||
if dx >= dy {
|
||||
if positive_ix {
|
||||
repeat {
|
||||
plot(cx16.r14, y1, color)
|
||||
if cx16.r14==x2
|
||||
return
|
||||
cx16.r14++
|
||||
d += dy
|
||||
if d > dx {
|
||||
y1++
|
||||
d -= dx
|
||||
}
|
||||
}
|
||||
} else {
|
||||
repeat {
|
||||
plot(cx16.r14, y1, color)
|
||||
if cx16.r14==x2
|
||||
return
|
||||
cx16.r14--
|
||||
d += dy
|
||||
if d > dx {
|
||||
y1++
|
||||
d -= dx
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if positive_ix {
|
||||
repeat {
|
||||
plot(cx16.r14, y1, color)
|
||||
if y1 == y2
|
||||
return
|
||||
y1++
|
||||
d += dx
|
||||
if d > dy {
|
||||
cx16.r14++
|
||||
d -= dy
|
||||
}
|
||||
}
|
||||
} else {
|
||||
repeat {
|
||||
plot(cx16.r14, y1, color)
|
||||
if y1 == y2
|
||||
return
|
||||
y1++
|
||||
d += dx
|
||||
if d > dy {
|
||||
cx16.r14--
|
||||
d -= dy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, ubyte color) {
|
||||
; Midpoint algorithm.
|
||||
if radius==0
|
||||
return
|
||||
|
||||
ubyte @zp xx = radius
|
||||
ubyte @zp yy = 0
|
||||
word @zp decisionOver2 = (1 as word)-xx
|
||||
@ -157,28 +281,29 @@ gfx2 {
|
||||
}
|
||||
}
|
||||
|
||||
sub disc(uword xcenter, uword ycenter, ubyte radius, ubyte color) {
|
||||
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, ubyte color) {
|
||||
; Midpoint algorithm, filled
|
||||
ubyte @zp xx = radius
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp yy = 0
|
||||
word @zp decisionOver2 = (1 as word)-xx
|
||||
word @zp decisionOver2 = (1 as word)-radius
|
||||
|
||||
while xx>=yy {
|
||||
horizontal_line(xcenter-xx, ycenter+yy, xx*2+1, color)
|
||||
horizontal_line(xcenter-xx, ycenter-yy, xx*2+1, color)
|
||||
horizontal_line(xcenter-yy, ycenter+xx, yy*2+1, color)
|
||||
horizontal_line(xcenter-yy, ycenter-xx, yy*2+1, color)
|
||||
while radius>=yy {
|
||||
horizontal_line(xcenter-radius, ycenter+yy, radius*2+1, color)
|
||||
horizontal_line(xcenter-radius, ycenter-yy, radius*2+1, color)
|
||||
horizontal_line(xcenter-yy, ycenter+radius, yy*2+1, color)
|
||||
horizontal_line(xcenter-yy, ycenter-radius, yy*2+1, color)
|
||||
yy++
|
||||
if decisionOver2<=0
|
||||
decisionOver2 += (yy as word)*2+1
|
||||
else {
|
||||
xx--
|
||||
decisionOver2 += (yy as word -xx)*2+1
|
||||
radius--
|
||||
decisionOver2 += (yy as word -radius)*2+1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub plot(uword x, uword y, ubyte color) {
|
||||
sub plot(uword @zp x, uword y, ubyte color) {
|
||||
ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1]
|
||||
uword addr
|
||||
ubyte value
|
||||
@ -204,7 +329,7 @@ gfx2 {
|
||||
color = cx16.VERA_DATA0
|
||||
}
|
||||
|
||||
sub position(uword x, uword y) {
|
||||
sub position(uword @zp x, uword y) {
|
||||
when active_mode {
|
||||
0 -> {
|
||||
cx16.r0 = y*(320/8) + x/8
|
||||
@ -280,7 +405,7 @@ gfx2 {
|
||||
}
|
||||
}
|
||||
|
||||
sub text(uword x, uword y, ubyte color, uword sctextptr) {
|
||||
sub text(uword @zp x, uword y, ubyte color, uword sctextptr) {
|
||||
; -- Write some text at the given pixel position. The text string must be in screencode encoding (not petscii!).
|
||||
; You must also have called text_charset() first to select and prepare the character set to use.
|
||||
; NOTE: in monochrome (1bpp) screen modes, x position is currently constrained to mulitples of 8 !
|
||||
|
@ -44,6 +44,8 @@ graphics {
|
||||
;cx16.GRAPH_draw_oval(false) ; currently this call is not implemented on cx16, does a BRK
|
||||
|
||||
; Midpoint algorithm
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp xx = radius
|
||||
ubyte @zp yy = 0
|
||||
byte @zp decisionOver2 = 1-xx as byte
|
||||
@ -94,8 +96,10 @@ graphics {
|
||||
; cx16.r3 = radius*2
|
||||
; cx16.GRAPH_draw_oval(true) ; currently this call is not implemented on cx16, does a BRK
|
||||
|
||||
ubyte xx = radius
|
||||
ubyte yy = 0
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp xx = radius
|
||||
ubyte @zp yy = 0
|
||||
byte decisionOver2 = 1-xx as byte
|
||||
|
||||
while xx>=yy {
|
||||
|
@ -94,7 +94,7 @@ Full-screen multicolor bitmap graphics routines, available on the Cx16 machine o
|
||||
- clearing screen, switching screen mode
|
||||
- drawing pixels
|
||||
- drawing text inside the bitmap
|
||||
- **TODO:** lines, circles, discs.
|
||||
- lines, rectangles, circles, discs.
|
||||
|
||||
|
||||
palette (cx16 only)
|
||||
|
@ -2,6 +2,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- implement gfx2's rect, fillrect, horizontal_line and vertical_line in graphics modules as well.
|
||||
- detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
|
||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||
|
@ -13,10 +13,6 @@ main {
|
||||
for mode in modes {
|
||||
gfx2.screen_mode(mode)
|
||||
draw()
|
||||
ubyte tp
|
||||
for tp in 0 to 15 {
|
||||
gfx2.text(19+tp,20+tp*11, 5, @"ScreenCODE text! 1234![]<>#$%&*()")
|
||||
}
|
||||
cx16.wait(200)
|
||||
}
|
||||
|
||||
@ -25,6 +21,45 @@ main {
|
||||
}
|
||||
|
||||
sub draw() {
|
||||
|
||||
gfx2.rect(10,10, 1, 1, 255)
|
||||
gfx2.rect(20,10, 2, 1, 255)
|
||||
gfx2.rect(30,10, 3, 1, 255)
|
||||
gfx2.rect(40,10, 1, 2, 255)
|
||||
gfx2.rect(50,10, 1, 3, 255)
|
||||
gfx2.rect(60,10, 2, 2, 255)
|
||||
gfx2.rect(70,10, 3, 3, 255)
|
||||
gfx2.rect(80,10, 4, 4, 255)
|
||||
gfx2.rect(90,10, 5, 5, 255)
|
||||
gfx2.rect(100,10, 8, 8, 255)
|
||||
gfx2.rect(110,10, 20, 5, 255)
|
||||
gfx2.rect(80, 80, 200, 140, 255)
|
||||
|
||||
gfx2.fillrect(10,40, 1, 1, 5)
|
||||
gfx2.fillrect(20,40, 2, 1, 5)
|
||||
gfx2.fillrect(30,40, 3, 1, 5)
|
||||
gfx2.fillrect(40,40, 1, 2, 5)
|
||||
gfx2.fillrect(50,40, 1, 3, 5)
|
||||
gfx2.fillrect(60,40, 2, 2, 5)
|
||||
gfx2.fillrect(70,40, 3, 3, 5)
|
||||
gfx2.fillrect(80,40, 4, 4, 5)
|
||||
gfx2.fillrect(90,40, 5, 5, 5)
|
||||
gfx2.fillrect(100,40, 8, 8, 5)
|
||||
gfx2.fillrect(110,40, 20, 5, 5)
|
||||
gfx2.fillrect(82, 82, 200-4, 140-4, 5)
|
||||
|
||||
ubyte i
|
||||
for i in 0 to 255 step 4 {
|
||||
uword x1 = ((gfx2.width-256)/2 as uword) + sin8u(i)
|
||||
uword y1 = (gfx2.height-128)/2 + cos8u(i)/2
|
||||
uword x2 = ((gfx2.width-64)/2 as uword) + sin8u(i)/4
|
||||
uword y2 = (gfx2.height-64)/2 + cos8u(i)/4
|
||||
gfx2.line(x1, y1, x2, y2, i)
|
||||
}
|
||||
|
||||
cx16.wait(60)
|
||||
gfx2.clear_screen()
|
||||
|
||||
ubyte radius
|
||||
|
||||
for radius in 110 downto 8 step -4 {
|
||||
@ -32,10 +67,11 @@ main {
|
||||
}
|
||||
|
||||
gfx2.disc(gfx2.width/2, gfx2.height/2, 108, 255)
|
||||
|
||||
ubyte tp
|
||||
for tp in 0 to 15 {
|
||||
gfx2.text(19+tp,20+tp*11, 5, @"ScreenCODE text! 1234![]<>#$%&*()")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gfx3 {
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,15 @@ main {
|
||||
|
||||
|
||||
sub start () {
|
||||
uword length
|
||||
|
||||
if length>256 {
|
||||
repeat length-1
|
||||
gfx2.next_pixel(color)
|
||||
} else {
|
||||
repeat (length-1) as ubyte ; TODO lsb(length-1) doesn't work!?!?!?
|
||||
gfx2.next_pixel(color)
|
||||
}
|
||||
|
||||
test_stack.test()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user