diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index a9a819a07..f5d73cc9b 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -2,10 +2,12 @@ ; Bitmap pixel graphics module for the CommanderX16 ; Custom routines to use the full-screen 640x480 and 320x240 screen modes. -; This only works on the Cx16. No text layer is currently shown, text can be drawn as part of the bitmap itself. -; Note: for compatible graphics code that words on C64 too, use the "graphics" module instead. -; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module. - +; These modes are not supported by the documented GRAPH_xxxx kernel routines. +; No text layer is currently shown, text can be drawn as part of the bitmap itself. +; Note: for similar graphics routines that also work on the C-64, use the "graphics" module instead. +; Note: for color palette manipulation, use the "palette" module or write Vera registers yourself. +; +; ; SCREEN MODE LIST: ; mode 0 = reset back to default text mode ; mode 1 = bitmap 320 x 240 monochrome @@ -13,7 +15,7 @@ ; mode 3 = bitmap 320 x 240 x 16c (unsupported TODO not yet implemented) ; mode 4 = bitmap 320 x 240 x 256c ; mode 5 = bitmap 640 x 480 monochrome -; mode 6 = bitmap 640 x 480 x 4c (unsupported TODO not yet implemented) +; mode 6 = bitmap 640 x 480 x 4c (unsupported TODO being implemented) ; mode 7 = bitmap 640 x 480 x 16c (unsupported due to lack of VRAM) ; mode 8 = bitmap 640 x 480 x 256c (unsupported due to lack of VRAM) @@ -239,34 +241,51 @@ _done 6 -> { ; highres 4c ; TODO also mostly usable for lores 4c? + color &= 3 + ubyte[4] colorbits + ubyte ii + for ii in 3 downto 0 { + colorbits[ii] = color + color <<= 2 + } + void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte) + %asm {{ + lda cx16.VERA_ADDR_H + and #%00000111 ; no auto advance + sta cx16.VERA_ADDR_H + stz cx16.VERA_CTRL ; setup vera addr 0 + lda cx16.r1 + and #1 + sta cx16.VERA_ADDR_H + lda cx16.r0 + sta cx16.VERA_ADDR_L + lda cx16.r0+1 + sta cx16.VERA_ADDR_M + phx + ldx x + }} - for x in x to x+length-1 - plot(x, y, color) + repeat length { + %asm {{ + txa + and #3 + tay + lda cx16.VERA_DATA0 + and gfx2.plot.mask4c,y + ora colorbits,y + sta cx16.VERA_DATA0 + cpy #%00000011 ; next vera byte? + bne + + inc cx16.VERA_ADDR_L + bne + + inc cx16.VERA_ADDR_M ++ inx ; next pixel + }} + } - ; 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++ -; } + %asm {{ + plx + }} } } } @@ -380,12 +399,12 @@ _done 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) + + ; TODO optimize the loop in pure assembly color &= 3 color <<= gfx2.plot.shift4c[lsb(x) & 3] ubyte mask = gfx2.plot.mask4c[lsb(x) & 3] - repeat height { - ; TODO optimize the vera memory manipulation in pure assembly ubyte value = cx16.vpeek(lsb(cx16.r1), cx16.r0) & mask | color cx16.vpoke(lsb(cx16.r1), cx16.r0, value) cx16.r0 += 640/4 @@ -818,7 +837,7 @@ _done } sub addr_mul_24_for_highres_4c(uword yy, uword xx) { - ; TODO asmsub, 24 bits calc + ; TODO asmsub, actually do 24 bits calc ; 24 bits result is in r0 and r1L (highest byte) cx16.r0 = xx/4 + yy*(640/4) cx16.r1 = 0 diff --git a/examples/cx16/amiga.p8 b/examples/cx16/amiga.p8 index 1c53955f0..063d5a3a6 100644 --- a/examples/cx16/amiga.p8 +++ b/examples/cx16/amiga.p8 @@ -5,12 +5,10 @@ ; Mockup of a classic Amiga Workbench screen. -; TODO make everything 4 colors - main { sub start() { - gfx2.screen_mode(6) ; select 640*480 mode + gfx2.screen_mode(6) ; select 640*480 mode, 4 colors uword[4] amigacolors = [$aaa, $000, $fff, $68c] ; gray, black, white, lightblue palette.set_rgb(amigacolors, len(amigacolors)) @@ -110,21 +108,23 @@ main { widget { - sub highlightedrect(uword x, uword y, uword width, uword height, ubyte active) { + sub highlightedrect(uword x, uword y, uword width, uword height, ubyte fill, 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, 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) + if fill { + 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) { const ubyte width = 56 const ubyte height = 28 - highlightedrect(x, y, width, height, false) + highlightedrect(x, y, width, height, false, false) uword middlex = x+width/2+1 ubyte halfstring = string.length(caption) * 4 gfx2.text(middlex-halfstring,y+height+1,1,caption) @@ -139,7 +139,7 @@ widget { 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-64, height, active) + widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, true, 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) @@ -150,7 +150,7 @@ widget { sub window_flipsize_icon(uword x, uword y, ubyte active) { const uword width = 22 const uword height = 11 - highlightedrect(x, y, width, height, active) + highlightedrect(x, y, width, height, true, 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, 7, 4, 1) @@ -160,7 +160,7 @@ widget { sub window_order_icon(uword x, uword y, ubyte active) { const uword width = 22 const uword height = 11 - highlightedrect(x, y, width, height, active) + highlightedrect(x, y, width, height, true, active) 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 @@ -170,7 +170,7 @@ widget { sub window_close_icon(uword x, uword y, ubyte active) { const uword width = 20 const uword height = 11 - highlightedrect(x, y, width, height, active) + highlightedrect(x, y, width, height, true, active) 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) @@ -191,7 +191,6 @@ widget { } 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 @@ -204,5 +203,7 @@ widget { 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) + highlightedrect(x+width-13, y+12, 10, height-23, false, false) + ; TODO scroll icons } } diff --git a/examples/cx16/highresbitmap-4c.p8 b/examples/cx16/highresbitmap-4c.p8 index b2b8f5950..90e307e9a 100644 --- a/examples/cx16/highresbitmap-4c.p8 +++ b/examples/cx16/highresbitmap-4c.p8 @@ -11,8 +11,8 @@ main { gfx2.screen_mode(6) testrect() - ; testhorizontal() - ;testvertical() + testhorizontal() + testvertical() sys.wait(9900) gfx2.screen_mode(0) diff --git a/examples/test.p8 b/examples/test.p8 index 3faf7792f..779e45156 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -14,6 +14,9 @@ main { cx16.vpoke(1, mkword(hh, ll), lsb(screencolorRGB)) + cx16.vpoke(lsb(cx16.r1), cx16.r0, cbits4) ; TODO r0 is alreay in r0, avoid bogus assignment here + cbits4 &= gfx2.plot.mask4c[lower2_x_bits] ; TODO why lda..and instead of and mask,y? + cbits4 |= colorbits[lower2_x_bits] ; TODO why lda..ora instead of ora mask,y? ; ubyte value ; ubyte bb1