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.
This commit is contained in:
Irmen de Jong 2024-11-12 18:27:33 +01:00
parent 3b4a5e27f7
commit 9438e996d7
4 changed files with 53 additions and 21 deletions

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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")
}
}