From 9438e996d7e86a286ba0f808c8af7f231c1b4638 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 12 Nov 2024 18:27:33 +0100 Subject: [PATCH] Fixed math.mul16_last_upper(). Added math.lerpw() a LERP routine for words (to complement the existing math.lerp() for bytes) Described the LERP routines in the library chapter in the docs. --- compiler/res/prog8lib/math.p8 | 15 ++++++++++++-- compiler/res/prog8lib/virtual/math.p8 | 11 ++++++++++ docs/source/libraries.rst | 19 ++++++++++++++++++ examples/test.p8 | 29 +++++++++------------------ 4 files changed, 53 insertions(+), 21 deletions(-) diff --git a/compiler/res/prog8lib/math.p8 b/compiler/res/prog8lib/math.p8 index dac342d52..768b9cddf 100644 --- a/compiler/res/prog8lib/math.p8 +++ b/compiler/res/prog8lib/math.p8 @@ -175,8 +175,8 @@ _sinecosR8 .char trunc(127.0 * sin(range(180+45) * rad(360.0/180.0))) ; as soon as a negative word value (or 2) was used in the multiplication, these upper 16 bits are not valid!! ; Suggestion (if you are on the Commander X16): use verafx.muls() to get a hardware accelerated 32 bit signed multplication. %asm {{ - lda multiply_words.result+2 - ldy multiply_words.result+3 + lda prog8_math.multiply_words.result+2 + ldy prog8_math.multiply_words.result+3 rts }} } @@ -651,4 +651,15 @@ log2_tab ; guarantees v = v1 when t = 255 return v0 + msb(t as uword * (v1 - v0) + 255) } + + sub lerpw(uword v0, uword v1, uword t) -> uword { + ; Linear interpolation (LERP) on word values + ; returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 65535] + ; guarantees v = v1 when t = 65535 + t *= v1-v0 + cx16.r0 = math.mul16_last_upper() + if t!=0 + cx16.r0++ + return v0 + cx16.r0 + } } diff --git a/compiler/res/prog8lib/virtual/math.p8 b/compiler/res/prog8lib/virtual/math.p8 index a9e12d57b..2a18c7b99 100644 --- a/compiler/res/prog8lib/virtual/math.p8 +++ b/compiler/res/prog8lib/virtual/math.p8 @@ -406,4 +406,15 @@ math { ; guarantees v = v1 when t = 255 return v0 + msb(t as uword * (v1 - v0) + 255) } + + sub lerpw(uword v0, uword v1, uword t) -> uword { + ; Linear interpolation (LERP) on word values + ; returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 65535] + ; guarantees v = v1 when t = 65535 + t *= v1-v0 + cx16.r0 = math.mul16_last_upper() + if t!=0 + cx16.r0++ + return v0 + cx16.r0 + } } diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index b5943cb9d..f561ccf30 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -677,6 +677,14 @@ Provides definitions for the ROM/Kernal subroutines and utility routines dealing Warning: this routine may stop working on the Commander X16 when a new ROM version is released, because it uses an internal BASIC routine. Then it will require a fix. +``lerp(v0, v1, t)`` + Linear interpolation (LERP). Precise method, which guarantees v = v1 when t = 1. + Returns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0] + +``lerp_fast(v0, v1, t)``` + Linear interpolation (LERP). Imprecise (but faster) method, which does not guarantee v = v1 when t = 1 + Teturns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0] + graphics -------- @@ -823,6 +831,17 @@ but perhaps the provided ones can be of service too. Call the start() routine first, feed it bytes with the update() routine, finalize with calling the end() routine. The 32 bits result is stored in cx16.r14 (low word) and cx16.r15 (high word). +``lerp(v0, v1, t)`` + Linear interpolation routine for unsigned byte values. + Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 255] + Guarantees v = v1 when t = 255. + +``lerpw(v0, v1, t)`` + Linear interpolation routine for unsigned word values. + Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 65535] + Guarantees v = v1 when t = 65535. + + cx16logo -------- Just a fun module that contains the Commander X16 logo in PETSCII graphics diff --git a/examples/test.p8 b/examples/test.p8 index 57d845db2..6e6ec6451 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,28 +1,19 @@ +%import math %import textio %option no_sysinit %zeropage basicsafe main { sub start() { - defer initial() - if allocate() { - txt.print("1") - defer deallocate() - txt.print("2") - return + uword v0 = 4000 + uword v1 = 60000 + + for cx16.r1 in 65400 to 65535 { + txt.print_uw(cx16.r1) + txt.spc() + txt.spc() + txt.print_uw(math.lerpw(v0, v1, cx16.r1)) + txt.nl() } - txt.print("3") - } - - sub allocate() -> bool { - txt.print("allocate\n") - return true - } - - sub initial() { - txt.print("initial\n") - } - sub deallocate() { - txt.print("deallocate\n") } }