diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index 5b6bc684e..a9a819a07 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -212,7 +212,7 @@ _done x++ } } - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; vera auto-increment off again + cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off again } 4 -> { ; lores 256c @@ -239,28 +239,34 @@ _done 6 -> { ; highres 4c ; TODO also mostly usable for lores 4c? - color &=3 - ubyte[4] colorbits - ubyte[4] masks - ubyte mask = %11111100 - ubyte ii - for ii in 3 downto 0 { - colorbits[ii] = color - masks[ii] = mask - color <<= 2 - mask <<=2 - } - void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte) - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance - repeat length { - ; TODO optimize the vera memory manipulation in pure assembly - ubyte lower_x_bits = lsb(x) & 3 - ubyte cbits4 = cx16.vpeek(lsb(cx16.r1), cx16.r0) & masks[lower_x_bits] | colorbits[lower_x_bits] - cx16.vpoke(lsb(cx16.r1), cx16.r0, cbits4) - if lower_x_bits==%00000011 - cx16.r0++ ; next x byte - x++ - } + + for x in x to x+length-1 + plot(x, y, color) + + ; TODO this optimized loop sometimes misses the last pixel ???? +; color &= 3 +; ubyte[4] colorbits +; ubyte[4] masks +; ubyte mask = %11111100 +; ubyte ii +; for ii in 3 downto 0 { +; colorbits[ii] = color +; masks[ii] = mask +; color <<= 2 +; mask <<=2 +; } + +; cx16.VERA_ADDR_H &= %00000111 ; no auto advance +; void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte) +; repeat length { +; ; TODO optimize the vera memory manipulation in pure assembly +; ubyte lower_x_bits = lsb(x) & 3 +; ubyte cbits4 = cx16.vpeek(lsb(cx16.r1), cx16.r0) & masks[lower_x_bits] | colorbits[lower_x_bits] +; cx16.vpoke(lsb(cx16.r1), cx16.r0, cbits4) +; if lower_x_bits==%00000011 +; cx16.r0++ ; next x byte +; x++ +; } } } } @@ -271,7 +277,7 @@ _done 1, 5 -> { ; monochrome, either resolution ; note for the 1 bpp modes we can't use vera's auto increment mode because we have to 'or' the pixel data in place. - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance + cx16.VERA_ADDR_H &= %00000111 ; no auto advance cx16.r15 = gfx2.plot.bits[x as ubyte & 7] ; bitmask if active_mode>=5 cx16.r14 = 640/8 @@ -357,7 +363,7 @@ _done 4 -> { ; lores 256c ; set vera auto-increment to 320 pixel increment (=next line) - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | (14<<4) + cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | (14<<4) %asm {{ ldy height beq + @@ -371,7 +377,7 @@ _done 6 -> { ; highres 4c ; note for this mode we can't use vera's auto increment mode because we have to 'or' the pixel data in place. - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance + cx16.VERA_ADDR_H &= %00000111 ; no auto advance ; TODO also mostly usable for lores 4c? void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte) color &= 3 @@ -575,7 +581,7 @@ _done void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte) cx16.vpoke(lsb(cx16.r1), cx16.r0, color) ; activate vera auto-increment mode so next_pixel() can be used after this - cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000 + cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | %00010000 color = cx16.VERA_DATA0 } 5 -> { @@ -604,6 +610,7 @@ _done color &= 3 color <<= shift4c[lsb(x) & 3] ; TODO optimize the vera memory manipulation in pure assembly + cx16.VERA_ADDR_H &= %00000111 ; no auto advance value = cx16.vpeek(lsb(cx16.r1), cx16.r0) & mask4c[lsb(x) & 3] | color cx16.vpoke(lsb(cx16.r1), cx16.r0, value) } diff --git a/examples/cx16/amiga.p8 b/examples/cx16/amiga.p8 index 5ad9d5ea4..1c53955f0 100644 --- a/examples/cx16/amiga.p8 +++ b/examples/cx16/amiga.p8 @@ -10,15 +10,18 @@ main { sub start() { - gfx2.screen_mode(5) ; select 640*480 mode - palette.set_monochrome($0aaa, $0000) ; TODO fix setting the palette... the isNoClobberRisk() for lsb/msb broke it + gfx2.screen_mode(6) ; select 640*480 mode + uword[4] amigacolors = [$aaa, $000, $fff, $68c] ; gray, black, white, lightblue + palette.set_rgb(amigacolors, len(amigacolors)) cx16.VERA_DC_VSCALE = 64 ; have the vertical resolution so it is 640*240 - more or less Amiga's default non interlaced mode cx16.mouse_config(1, 1) ; enable mouse TODO make it an Amiga mouse pointer if possible gfx2.text_charset(3) - gfx2.monochrome_stipple(true) - gfx2.fillrect(0,11,gfx2.width,gfx2.height/2-11,1) - gfx2.monochrome_stipple(false) + if gfx2.active_mode==5 { + gfx2.monochrome_stipple(true) + gfx2.fillrect(0,11,gfx2.width,gfx2.height/2-11,1) + gfx2.monochrome_stipple(false) + } screen_titlebar() window_workbench() @@ -31,7 +34,7 @@ main { } sub screen_titlebar() { - ; TODO white box + gfx2.fillrect(0, 0, gfx2.width, 10, 2) gfx2.text(8,1, 1, @"AmigaOS 3.1 2,002,448 graphics mem 16,504,384 other mem") gfx2.horizontal_line(0, 10, gfx2.width, 1) widget.window_order_icon(gfx2.width-widget.window_order_icon.width, 0, false) @@ -44,11 +47,11 @@ main { const uword width = 600 const uword height = 220 - widget.window_titlebar(win_x, win_y, width, @"Workbench", true) - gfx2.fillrect(win_x+3, win_y+11, width-4, height-11-2,0) ; clear window pane - widget.window_leftborder(win_x, win_y, height, true) + widget.window_titlebar(win_x, win_y, width, @"Workbench", false) + ; gfx2.fillrect(win_x+3, win_y+11, width-4, height-11-2,0) ; clear window pane + widget.window_leftborder(win_x, win_y, height, false) widget.window_bottomborder(win_x, win_y, width, height) - widget.window_rightborder(win_x, win_y, width, height, true) + widget.window_rightborder(win_x, win_y, width, height, false) vector_v(win_x+width - 380, win_y+height-20) vector_v(win_x+width - 380 -14, win_y+height-20) @@ -73,7 +76,7 @@ main { const uword win_y = 40 widget.window_titlebar(win_x, win_y, width, @"System", false) - gfx2.fillrect(win_x+3, win_y+11, width-4, height-11-2,0) ; clear window pane + gfx2.fillrect(win_x+3, win_y+11, width-4, height-11-2, 0) ; clear window pane widget.window_leftborder(win_x, win_y, height, false) widget.window_bottomborder(win_x, win_y, width, height) widget.window_rightborder(win_x, win_y, width, height, false) @@ -91,11 +94,11 @@ main { const uword width = 500 const uword height = 65 - widget.window_titlebar(win_x, win_y, width, @"AmigaShell", false) + widget.window_titlebar(win_x, win_y, width, @"AmigaShell", true) gfx2.fillrect(win_x+3, win_y+11, width-4, height-11-2,0) ; clear window pane - widget.window_leftborder(win_x, win_y, height, false) + widget.window_leftborder(win_x, win_y, height, true) widget.window_bottomborder(win_x, win_y, width, height) - widget.window_rightborder(win_x, win_y, width, height, false) + widget.window_rightborder(win_x, win_y, width, height, true) gfx2.text(win_x+5, win_y+12, 1, @"New Shell process 3") gfx2.text(win_x+5, win_y+12+8, 1, @"3.Workbench3.1:>") @@ -108,12 +111,14 @@ main { widget { sub highlightedrect(uword x, uword y, uword width, uword height, ubyte active) { - ; TODO white - gfx2.horizontal_line(x, y, width, 1) - gfx2.vertical_line(x, y+1, height-1, 1) - ; TODO black + gfx2.horizontal_line(x, y, width, 2) + gfx2.vertical_line(x, y+1, height-1, 2) gfx2.vertical_line(x+width-1, y+1, height-1, 1) gfx2.horizontal_line(x+1, y+height-1, width-2, 1) + if active + gfx2.fillrect(x+1,y+1,width-2,height-2, 3) + else + gfx2.fillrect(x+1,y+1,width-2,height-2, 0) } sub icon(uword x, uword y, uword caption) { @@ -134,8 +139,8 @@ widget { sub window_titlebar(uword x, uword y, uword width, uword titlestr, ubyte active) { const ubyte height = 11 - gfx2.fillrect(x,y,width,height-1,0) - widget.highlightedrect(x+widget.window_close_icon.width, y, width-62, height, active) + widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, active) + gfx2.plot(x+widget.window_close_icon.width, y+height-1, 1) ; correct bottom left corner gfx2.text(x+32, y+1, 1, titlestr) widget.window_close_icon(x, y, active) widget.window_order_icon(x+width-22, y, active) @@ -146,51 +151,58 @@ widget { const uword width = 22 const uword height = 11 highlightedrect(x, y, width, height, active) + gfx2.plot(x, y+height-1, 1) ; correct bottom left corner gfx2.rect(x+5, y+2, width-9, height-4, 1) - gfx2.rect(x+5, y+2, width-15, height-7, 1) + gfx2.rect(x+5, y+2, 7, 4, 1) + gfx2.fillrect(x+6, y+3, 5, 2, 2) } sub window_order_icon(uword x, uword y, ubyte active) { - ; TODO background filled box const uword width = 22 const uword height = 11 highlightedrect(x, y, width, height, active) - gfx2.fillrect(x+4, y+2, 10, 5, 1) ; grey back - ; TODO black border - gfx2.fillrect(x+8, y+4, 10, 5, 1) ; white front - ; TODO black border + gfx2.plot(x, y+height-1, 1) ; correct bottom left corner + gfx2.rect(x+4, y+2, 10, 5, 1) ; back + gfx2.fillrect(x+9, y+5, 8, 3, 2) ; white front + gfx2.rect(x+8, y+4, 10, 5, 1) ; front } sub window_close_icon(uword x, uword y, ubyte active) { - ; TODO background filled box const uword width = 20 const uword height = 11 highlightedrect(x, y, width, height, active) - gfx2.fillrect(x+7, y+3, 5, 5, 1) - ; TODO black border + gfx2.plot(x, y+height-1, 1) ; correct bottom left corner + gfx2.rect(x+7, y+3, 5, 5, 1) + gfx2.fillrect(x+8, y+4, 3, 3, 2) } sub window_leftborder(uword x, uword y, uword height, ubyte active) { - gfx2.vertical_line(x, y, height, 1) - gfx2.vertical_line(x+1, y+11, height-11, 1) + gfx2.vertical_line(x, y, height, 2) + ubyte color = 0 + if active + color = 3 + gfx2.vertical_line(x+1, y+11, height-11, color) gfx2.vertical_line(x+2, y+11, height-11, 1) } sub window_bottomborder(uword x, uword y, uword width, uword height) { - gfx2.horizontal_line(x+3, y+height-2, width-3, 1) + gfx2.horizontal_line(x+3, y+height-2, width-3, 2) gfx2.horizontal_line(x, y+height-1, width, 1) } sub window_rightborder(uword x, uword y, uword width, uword height, ubyte active) { ; TODO scrollbar and scroll icons - gfx2.vertical_line(x+width-1-16, y+11, height-13,1) + gfx2.vertical_line(x+width-1-16, y+11, height-13,2) gfx2.vertical_line(x+width-1, y+11, height-11,1) + ubyte color = 0 + if active + color = 3 + gfx2.fillrect(x+width-1-15, y+11, 15, height-12, color) - gfx2.fillrect(x+width-1-15, y+height-10, 15, 9, 0) - gfx2.horizontal_line(x+width-1-13, y+height-3, 11,1) - gfx2.vertical_line(x+width-1-3, y+height-3-5, 5,1) + gfx2.horizontal_line(x+width-1-13, y+height-3, 11, 1) + gfx2.vertical_line(x+width-1-3, y+height-3-5, 5, 1) gfx2.line(x+width-1-13,y+height-3, x+width-1-3, y+height-3-5, 1) - gfx2.horizontal_line(x+width-1-16, y+height-10, 16,1) + gfx2.horizontal_line(x+width-1-16, y+height-10, 16, 2) } } diff --git a/examples/cx16/highresbitmap-4c.p8 b/examples/cx16/highresbitmap-4c.p8 index 017454d28..b2b8f5950 100644 --- a/examples/cx16/highresbitmap-4c.p8 +++ b/examples/cx16/highresbitmap-4c.p8 @@ -1,5 +1,6 @@ %target cx16 %import gfx2 +%import string %import textio %zeropage basicsafe @@ -7,34 +8,199 @@ main { sub start () { gfx2.text_charset(3) + gfx2.screen_mode(6) - test() + testrect() + ; testhorizontal() + ;testvertical() + sys.wait(9900) gfx2.screen_mode(0) txt.print("done!\n") } - sub test() { - gfx2.screen_mode(6) + sub testrect() { + uword siz + for siz in 10 to 40 step 3 { + widget.highlightedrect(100-siz, 100-siz, 100+siz*2, 10+siz*2, 1) + } + } + sub testhorizontal() { + uword width + uword yy = 100 + for width in 40 to 60 { + gfx2.horizontal_line(100, yy, width, 1) + uword xx + yy+=2 + for xx in 100 to 99+width { + gfx2.plot(xx, yy, 2) + } + yy += 4 + } + + + } + + sub testvertical() { + uword height + uword xx = 100 + for height in 40 to 60 { + gfx2.vertical_line(xx, 100, height, 1) + uword yy + xx+=2 + for yy in 100 to 99+height { + gfx2.plot(xx, yy, 2) + } + xx += 4 + } + + + } + + sub testplot() { + uword xx = 100 + uword yy = 100 ubyte color - uword yy -; for color in 3 downto 0 { -; for yy in 100 to 120 { -; uword xx -; for xx in 10 to 500 { -; gfx2.plot(xx, yy, color) -; } -; } -; } - - for color in 3 downto 0 { - for yy in 130 to 150 { - gfx2.horizontal_line(10, yy, 400, color) + repeat 6 { + for color in 0 to 3 { + for xx in 200 to 600 step 3 { + gfx2.plot(xx, yy, color) + } + yy += 5 } } - sys.wait(5*60) + xx = 50 + repeat 6 { + for color in 0 to 3 { + for yy in 100 to 400 step 3 { + gfx2.plot(xx, yy, color) + } + xx += 5 + } + } + + yy = 101 + repeat 6 { + for color in 0 to 3 { + gfx2.horizontal_line(200, yy, 400, color) + yy += 5 + } + } + + xx = 51 + repeat 6 { + for color in 0 to 3 { + gfx2.vertical_line(xx, 100, 300, color) + xx += 5 + } + } + } +} + +widget { + + sub highlightedrect(uword x, uword y, uword width, uword height, ubyte active) { + gfx2.horizontal_line(x, y, width, 2) + gfx2.vertical_line(x, y+1, height-1, 2) + gfx2.vertical_line(x+width-1, y+1, height-1, 3) + gfx2.horizontal_line(x+1, y+height-1, width-2, 2) ; TODO SOMETIMES MISSES THE LAST PIXEL +; if active +; gfx2.fillrect(x+1,y+1,width-2,height-2, 3) +; else +; gfx2.fillrect(x+1,y+1,width-2,height-2, 0) + } + + sub horizontal_line(uword x, uword y, uword length, ubyte color) { + if length==0 + return + + uword xx + for xx in x to x+length-1 { + gfx2.plot(xx, y, color) + } + } + + sub icon(uword x, uword y, uword caption) { + const ubyte width = 56 + const ubyte height = 28 + highlightedrect(x, y, width, height, false) + uword middlex = x+width/2+1 + ubyte halfstring = string.length(caption) * 4 + gfx2.text(middlex-halfstring,y+height+1,1,caption) + + gfx2.monochrome_stipple(true) + gfx2.disc(x+width/4+4, y+height/2, height/2-4, 1) + gfx2.monochrome_stipple(false) + gfx2.circle(x+width/4+4, y+height/2, height/2-4, 1) + gfx2.fillrect(x+20,y+12,width/2,height/2-4,1) + } + + + sub window_titlebar(uword x, uword y, uword width, uword titlestr, ubyte active) { + const ubyte height = 11 + widget.highlightedrect(x+widget.window_close_icon.width, y, width-62, height, active) + gfx2.text(x+32, y+1, 1, titlestr) + widget.window_close_icon(x, y, active) + widget.window_order_icon(x+width-22, y, active) + widget.window_flipsize_icon(x+width-44, y, active) + } + + sub window_flipsize_icon(uword x, uword y, ubyte active) { + const uword width = 22 + const uword height = 11 + highlightedrect(x, y, width, height, active) + gfx2.rect(x+5, y+2, width-9, height-4, 1) + gfx2.rect(x+5, y+2, 7, 4, 1) + gfx2.fillrect(x+6, y+3, 5, 2, 2) + } + + sub window_order_icon(uword x, uword y, ubyte active) { + const uword width = 22 + const uword height = 11 + highlightedrect(x, y, width, height, active) + gfx2.rect(x+4, y+2, 10, 5, 1) ; back + gfx2.fillrect(x+9, y+5, 8, 3, 2) ; white front + gfx2.rect(x+8, y+4, 10, 5, 1) ; front + } + + sub window_close_icon(uword x, uword y, ubyte active) { + const uword width = 20 + const uword height = 11 + highlightedrect(x, y, width, height, active) + gfx2.rect(x+7, y+3, 5, 5, 1) + gfx2.fillrect(x+8, y+4, 3, 3, 2) + } + + sub window_leftborder(uword x, uword y, uword height, ubyte active) { + gfx2.vertical_line(x, y, height, 2) + ubyte color = 0 + if active + color = 3 + gfx2.vertical_line(x+1, y+11, height-11, color) + gfx2.vertical_line(x+2, y+11, height-11, 1) + } + + sub window_bottomborder(uword x, uword y, uword width, uword height) { + gfx2.horizontal_line(x+3, y+height-2, width-3, 2) + gfx2.horizontal_line(x, y+height-1, width, 1) + } + + sub window_rightborder(uword x, uword y, uword width, uword height, ubyte active) { + ; TODO scrollbar and scroll icons + gfx2.vertical_line(x+width-1-16, y+11, height-13,2) + gfx2.vertical_line(x+width-1, y+11, height-11,1) + ubyte color = 0 + if active + color = 3 + gfx2.fillrect(x+width-1-15, y+11, 15, height-12, color) + + gfx2.horizontal_line(x+width-1-13, y+height-3, 11, 1) + gfx2.vertical_line(x+width-1-3, y+height-3-5, 5, 1) + gfx2.line(x+width-1-13,y+height-3, x+width-1-3, y+height-3-5, 1) + gfx2.horizontal_line(x+width-1-16, y+height-10, 16, 2) + } }