From 7e38d26c337f18cc8e04b4419952bd2cb38b9e7e Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 9 Oct 2024 20:53:19 +0200 Subject: [PATCH] added several color fade functions to the palette module (cx16) --- compiler/res/prog8lib/cx16/palette.p8 | 84 +++++++++++++++++++ .../compiler/astprocessing/AstChecker.kt | 5 ++ docs/source/todo.rst | 2 - examples/test.p8 | 53 +++++++----- 4 files changed, 119 insertions(+), 25 deletions(-) diff --git a/compiler/res/prog8lib/cx16/palette.p8 b/compiler/res/prog8lib/cx16/palette.p8 index c3fba336d..b33b36af6 100644 --- a/compiler/res/prog8lib/cx16/palette.p8 +++ b/compiler/res/prog8lib/cx16/palette.p8 @@ -106,6 +106,90 @@ palette { } } + sub fade_step_multi(ubyte startindex, ubyte endindex, uword target_rgb) -> bool { + ; Perform one color fade step for multiple consecutive palette entries. + ; startindex = palette index of first color to fade + ; endindex = palette index of last color to fade + ; target_rgb = $RGB color value to fade towards + ; Returns true if one or more colors were changed, false if no fade steps were done anymore. + ; So you usually keep calling this until it returns false. + bool changed = false + while startindex <= endindex { + if fade_step(startindex, target_rgb) + changed=true + startindex++ + if_z + break + } + return changed + } + + sub fade_step_colors(ubyte startindex, ubyte endindex, uword target_colors) -> bool { + ; Perform one color fade step for multiple consecutive palette entries, to different target colors. + ; startindex = palette index of first color to fade + ; endindex = palette index of last color to fade + ; target_colors = address of uword $RGB array of colors to fade towards + ; Returns true if one or more colors were changed, false if no fade steps were done anymore. + ; So you usually keep calling this until it returns false. + bool changed = false + ubyte target_index = 0 + while startindex <= endindex { + if fade_step(startindex, peekw(target_colors+target_index)) + changed=true + target_index += 2 + startindex++ + if_z + break + } + return changed + } + + sub fade_step(ubyte index, uword target_rgb) -> bool { + ; Perform one color fade step for a single palette entry. + ; index = palette index of the color to fade + ; target_rgb = $RGB color value to fade towards + ; Returns true if the color was changed, false if no fade step was done anymore. + ; So you usually keep calling this until it returns false. + uword color = palette.get_color(index) + cx16.r0L = msb(color) ; r + cx16.r1L = lsb(color) >> 4 ; g + cx16.r2L = lsb(color) & 15 ; b + cx16.r0H = msb(target_rgb) & 15 ; r2 + cx16.r1H = lsb(target_rgb) >> 4 ; g2 + cx16.r2H = lsb(target_rgb) & 15 ; b2 + + ubyte changed + + ; use cmp() + status bits branches, to avoid multiple compares that could be done just once + cmp(cx16.r0L, cx16.r0H) + if_ne { + if_cc + cx16.r0L++ + else + cx16.r0L-- + changed++ + } + cmp(cx16.r1L, cx16.r1H) + if_ne { + if_cc + cx16.r1L++ + else + cx16.r1L-- + changed++ + } + cmp(cx16.r2L, cx16.r2H) + if_ne { + if_cc + cx16.r2L++ + else + cx16.r2L-- + changed++ + } + + palette.set_color(index, mkword(cx16.r0L, cx16.r1L<<4 | cx16.r2L)) + return changed!=0 + } + sub set_c64pepto() { ; set first 16 colors to the "Pepto" PAL commodore-64 palette http://www.pepto.de/projects/colorvic/ uword[] colors = [ diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 3f0d8bfc9..0a74a4939 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1008,6 +1008,11 @@ internal class AstChecker(private val program: Program, errors.err("array literal for iteration must contain constants. Try using a separate array variable instead?", array.position) } + if(array.parent is Assignment) { + val assignTarget = (array.parent as Assignment).target + if(!assignTarget.inferType(program).isArray) + errors.err("cannot assign array to a non-array variable", assignTarget.position) + } super.visit(array) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 4e686fab9..270b321a4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,8 +1,6 @@ TODO ==== -Put palette fade to white / black in. - Regenerate skeleton doc files. Improve register load order in subroutine call args assignments: diff --git a/examples/test.p8 b/examples/test.p8 index 45293072b..10a85aec4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,30 +1,37 @@ +%import palette %import textio -%import string -%zeropage basicsafe +%option no_sysinit main { sub start() { - str name1 = "irmen" - str name2 = "other" - bool[2] flags = [true, false] + repeat 4 { + for cx16.r0L in 0 to 15 { + txt.color2(cx16.r0L, cx16.r0L) + txt.spc() + txt.spc() + txt.spc() + txt.spc() + } + txt.nl() + } + bool changed + uword[] colors = [ + $f00, $800, $200, $000, + $f0f, $80f, $20f, $00f + ] + do { + sys.waitvsync() + sys.waitvsync() + changed = palette.fade_step_colors(0, 8, colors) + } until not changed - txt.print(name1) - txt.nl() - name1 = name2 - txt.print(name1) - txt.nl() - flags = [false, true] - - ubyte[10] array - ubyte[10] array2 - - void string.copy(name2, name1) - array = array2 - name2 = "zzz" - array = [1,2,3,4,5,6,7,8,9,10] - ;; array = cx16.r0 - ;; array = name1 - ;; name1 = array - ;; name1 = cx16.r0 + sys.wait(60) + changed = false + do { + sys.waitvsync() + sys.waitvsync() + changed = palette.fade_step_multi(0, 8, $fff) + } until not changed + sys.wait(60) } }