Mercurial > touhou
annotate src/th06/interpolator.rs @ 678:1d81a449c436
Implement ECL instructions DelayAttack and NoDelayAttack.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 15 Aug 2019 21:35:22 +0200 |
parents | 9e40bd5cc26d |
children | 6020e33d4fc4 |
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 |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
20 macro_rules! generate_interpolator { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
21 ($name:ident, $n:tt) => { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
22 #[derive(Debug, Clone)] |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
23 pub(crate) struct $name<T> { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
24 start_values: [T; $n], |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
25 end_values: [T; $n], |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
26 start_frame: u16, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
27 end_frame: u16, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
28 formula: Formula, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
29 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
30 |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
31 impl<T> $name<T> |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
32 where f32: From<T>, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
33 T: From<f32>, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
34 T: std::ops::Sub<Output = T>, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
35 T: std::ops::Add<Output = T>, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
36 T: Copy, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
37 T: Default, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
38 { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
39 pub fn new(start_values: [T; $n], start_frame: u16, end_values: [T; $n], end_frame: u16, formula: Formula) -> $name<T> { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
40 $name { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
41 start_values, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
42 end_values, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
43 start_frame, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
44 end_frame, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
45 formula, |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
46 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
47 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
48 |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
49 // XXX: Make it return [T; $n] instead, we don’t want to only do f32 here. |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
50 pub fn values(&self, frame: u16) -> [f32; $n] { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
51 if frame + 1 >= self.end_frame { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
52 // XXX: skip the last interpolation step. |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
53 // This bug is replicated from the original game. |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
54 //self.start_frame = self.end_frame; |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
55 //self.end_values |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
56 let mut values: [f32; $n] = [Default::default(); $n]; |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
57 for (i, value) in self.end_values.iter().enumerate() { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
58 values[i] = f32::from(*value); |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
59 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
60 values |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
61 } else { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
62 let mut coeff = (frame - self.start_frame) as f32 / (self.end_frame - self.start_frame) as f32; |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
63 coeff = self.formula.apply(coeff); |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
64 let mut values: [f32; $n] = [Default::default(); $n]; |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
65 for (i, (start, end)) in self.start_values.iter().zip(&self.end_values).enumerate() { |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
66 values[i] = f32::from(*start + T::from(coeff * f32::from(*end - *start))); |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
67 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
68 values |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
69 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
70 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
71 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
72 }; |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
73 } |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
74 |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
75 generate_interpolator!(Interpolator1, 1); |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
76 generate_interpolator!(Interpolator2, 2); |
9e40bd5cc26d
Move interpolators in another module.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
77 generate_interpolator!(Interpolator3, 3); |