diff --git a/examples/cx16/colorbars.p8 b/examples/cx16/colorbars.p8 index d78eb727e..2cc974416 100644 --- a/examples/cx16/colorbars.p8 +++ b/examples/cx16/colorbars.p8 @@ -14,10 +14,11 @@ main { ubyte yy for yy in 0 to 239 - gfx2.horizontal_line(0, yy, 320, yy & 63) + gfx2.horizontal_line(0, yy, 320, yy & 31) repeat { - colors.random_bar() + colors.random_half_bar() + colors.mirror_bar() colors.set_palette() repeat 20 sys.waitvsync() @@ -30,96 +31,85 @@ main { } colors { - ubyte cr - ubyte cg - ubyte cb - ubyte[48+16] reds - ubyte[48+16] greens - ubyte[48+16] blues + ubyte target_red + ubyte target_green + ubyte target_blue + ubyte[32] reds + ubyte[32] greens + ubyte[32] blues ubyte bar_size sub random_rgb12() { do { uword rr = rndw() - cr = msb(rr) & 15 - cg = lsb(rr) - cb = cg & 15 - cg >>= 4 - } until cr+cg+cb >= 12 + target_red = msb(rr) & 15 + target_green = lsb(rr) + target_blue = target_green & 15 + target_green >>= 4 + } until target_red+target_green+target_blue >= 12 } - sub random_bar() { - ; fade black -> color then fade color -> white - random_rgb12() - ubyte r=0 - ubyte g=0 - ubyte b=0 - ubyte different - bar_size = 0 + sub mirror_bar() { + ; mirror the top half bar into the bottom half + ubyte ix=14 + ubyte mix=16 + do { + reds[mix] = reds[ix] + greens[mix] = greens[ix] + blues[mix] = blues[ix] + mix++ + ix-- + } until ix==255 + reds[mix] = 0 + greens[mix] = 0 + blues[mix] = 0 + } - repeat { - different = false - if r != cr { - different = true - r++ + sub random_half_bar() { + ; fade black -> color then fade color -> white + ; gradient calculations in 8.8 bits fixed-point + ; could theoretically be 4.12 bits for even more fractional accuracy + random_rgb12() + uword r = $000 + uword g = $000 + uword b = $000 + uword dr = target_red + uword dg = target_green + uword db = target_blue + ubyte ix = 1 + + ; gradient from black to halfway color + reds[0] = 0 + greens[0] = 0 + blues[0] = 0 + dr <<= 5 + dg <<= 5 + db <<= 5 + continue_gradient() + + ; gradient from halfway color to white + dr = (($f00 - r) >> 3) - 1 + dg = (($f00 - g) >> 3) - 1 + db = (($f00 - b) >> 3) - 1 + continue_gradient() + return + + sub continue_gradient() { + repeat 8 { + reds[ix] = msb(r) + greens[ix] = msb(g) + blues[ix] = msb(b) + r += dr + g += dg + b += db + ix++ } - if g != cg { - different = true - g++ - } - if b != cb { - different = true - b++ - } - if not different - break - reds[bar_size] = r - greens[bar_size] = g - blues[bar_size] = b - bar_size++ - } - repeat { - different = false - if r != 15 { - different = true - r++ - } - if g != 15 { - different = true - g++ - } - if b != 15 { - different = true - b++ - } - if not different - break - reds[bar_size] = r - greens[bar_size] = g - blues[bar_size] = b - bar_size++ - } - ; mirror bottom half from top half - ubyte mi = bar_size-1 - repeat mi { - reds[bar_size] = reds[mi] - greens[bar_size] = greens[mi] - blues[bar_size] = blues[mi] - bar_size++ - mi-- - } - ; make rest of bar black (bars are not always the same length using the simplistic algorithm above...) - while bar_size != 48+16 { - reds[bar_size] = $0 - greens[bar_size] = $0 - blues[bar_size] = $0 - bar_size++ } } sub set_palette() { ubyte ix - for ix in 0 to 48+15 { + for ix in 0 to 31 { uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] ) palette.set_color(ix, color) }