Skip to content

Commit

Permalink
Fixed math.mul16_last_upper().
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
irmen committed Nov 12, 2024
1 parent 3b4a5e2 commit 9438e99
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 21 deletions.
15 changes: 13 additions & 2 deletions compiler/res/prog8lib/math.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
}}
}
Expand Down Expand Up @@ -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
}
}
11 changes: 11 additions & 0 deletions compiler/res/prog8lib/virtual/math.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
19 changes: 19 additions & 0 deletions docs/source/libraries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------
Expand Down Expand Up @@ -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
Expand Down
29 changes: 10 additions & 19 deletions examples/test.p8
Original file line number Diff line number Diff line change
@@ -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
}
txt.print("3")
}

sub allocate() -> bool {
txt.print("allocate\n")
return true
}
uword v0 = 4000
uword v1 = 60000

sub initial() {
txt.print("initial\n")
}
sub deallocate() {
txt.print("deallocate\n")
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()
}
}
}

0 comments on commit 9438e99

Please sign in to comment.