annotate interpreters/src/th06/interpolator.rs @ 787:7f9b3f5001c2

interpreters: Make Interpolator generic over N This was a workaround for Rust < 1.51 which didn’t support const generics yet, but we’ve had tat for close to five years now!
author Link Mauve <linkmauve@linkmauve.fr>
date Mon, 15 Dec 2025 11:34:58 +0100
parents 21b186be2590
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
642
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 //! Animation runner.
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 #[derive(Debug, Clone, Copy, PartialEq)]
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 pub(crate) enum Formula {
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 Linear,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 Power2,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 InvertPower2,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 }
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 impl Formula {
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 fn apply(&self, x: f32) -> f32 {
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 match self {
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 Formula::Linear => x,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 Formula::Power2 => x * x,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15 Formula::InvertPower2 => 2. * x - x * x,
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16 }
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 }
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18 }
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19
787
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
20 #[derive(Debug, Clone)]
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
21 pub(crate) struct Interpolator<T, const N: usize> {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
22 start_values: [T; N],
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
23 end_values: [T; N],
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
24 start_frame: u32,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
25 end_frame: u32,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
26 formula: Formula,
642
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 }
9e40bd5cc26d Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28
787
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
29 impl<T, const N: usize> Interpolator<T, N>
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
30 where f32: From<T>,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
31 T: From<f32>,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
32 T: std::ops::Sub<Output = T>,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
33 T: std::ops::Add<Output = T>,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
34 T: Copy,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
35 T: Default,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
36 {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
37 pub fn new(start_values: [T; N], start_frame: u32, end_values: [T; N], end_frame: u32, formula: Formula) -> Interpolator<T, N> {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
38 Interpolator {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
39 start_values,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
40 end_values,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
41 start_frame,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
42 end_frame,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
43 formula,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
44 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
45 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
46
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
47 pub fn set_start(&mut self, frame: u32, values: [T; N]) {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
48 self.start_values = values;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
49 self.start_frame = frame;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
50 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
51
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
52 pub fn set_end(&mut self, frame: u32, values: [T; N]) {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
53 self.end_values = values;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
54 self.end_frame = frame;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
55 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
56
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
57 pub fn set_end_values(&mut self, values: [T; N]) {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
58 self.end_values = values;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
59 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
60
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
61 pub fn set_end_frame(&mut self, frame: u32) {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
62 self.end_frame = frame;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
63 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
64
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
65 // XXX: Make it return [T; N] instead, we don’t want to only do f32 here.
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
66 pub fn values(&self, frame: u32) -> [f32; N] {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
67 if frame + 1 >= self.end_frame {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
68 // XXX: skip the last interpolation step.
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
69 // This bug is replicated from the original game.
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
70 //self.start_frame = self.end_frame;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
71 //self.end_values
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
72 let mut values: [f32; N] = [Default::default(); N];
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
73 for (i, value) in self.end_values.iter().enumerate() {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
74 values[i] = f32::from(*value);
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
75 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
76 values
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
77 } else {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
78 let mut coeff = (frame - self.start_frame) as f32 / (self.end_frame - self.start_frame) as f32;
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
79 coeff = self.formula.apply(coeff);
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
80 let mut values: [f32; N] = [Default::default(); N];
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
81 for (i, (start, end)) in self.start_values.iter().zip(&self.end_values).enumerate() {
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
82 values[i] = f32::from(*start + T::from(coeff * f32::from(*end - *start)));
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
83 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
84 values
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
85 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
86 }
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
87 }