comparison src/th06/anm0_vm.rs @ 642:9e40bd5cc26d

Move interpolators in another module.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 07 Jul 2019 12:19:50 +0200
parents a58103f2f264
children 01849ffd0180
comparison
equal deleted inserted replaced
641:a58103f2f264 642:9e40bd5cc26d
4 Script, 4 Script,
5 Anm0, 5 Anm0,
6 Call, 6 Call,
7 Instruction, 7 Instruction,
8 }; 8 };
9 use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula};
9 use std::cell::RefCell; 10 use std::cell::RefCell;
10 use std::rc::Rc; 11 use std::rc::Rc;
11
12 #[derive(Debug, Clone, Copy, PartialEq)]
13 enum Formula {
14 Linear,
15 Power2,
16 InvertPower2,
17 }
18
19 impl Formula {
20 fn apply(&self, x: f32) -> f32 {
21 match self {
22 Formula::Linear => x,
23 Formula::Power2 => x * x,
24 Formula::InvertPower2 => 2. * x - x * x,
25 }
26 }
27 }
28
29 macro_rules! generate_interpolator {
30 ($name:ident, $n:tt) => {
31 #[derive(Debug, Clone)]
32 struct $name<T> {
33 start_values: [T; $n],
34 end_values: [T; $n],
35 start_frame: u16,
36 end_frame: u16,
37 formula: Formula,
38 }
39
40 impl<T> $name<T>
41 where f32: From<T>,
42 T: From<f32>,
43 T: std::ops::Sub<Output = T>,
44 T: std::ops::Add<Output = T>,
45 T: Copy,
46 T: Default,
47 {
48 pub fn new(start_values: [T; $n], start_frame: u16, end_values: [T; $n], end_frame: u16, formula: Formula) -> $name<T> {
49 $name {
50 start_values,
51 end_values,
52 start_frame,
53 end_frame,
54 formula,
55 }
56 }
57
58 // XXX: Make it return [T; $n] instead, we don’t want to only do f32 here.
59 pub fn values(&self, frame: u16) -> [f32; $n] {
60 if frame + 1 >= self.end_frame {
61 // XXX: skip the last interpolation step.
62 // This bug is replicated from the original game.
63 //self.start_frame = self.end_frame;
64 //self.end_values
65 let mut values: [f32; $n] = [Default::default(); $n];
66 for (i, value) in self.end_values.iter().enumerate() {
67 values[i] = f32::from(*value);
68 }
69 values
70 } else {
71 let mut coeff = (frame - self.start_frame) as f32 / (self.end_frame - self.start_frame) as f32;
72 coeff = self.formula.apply(coeff);
73 let mut values: [f32; $n] = [Default::default(); $n];
74 for (i, (start, end)) in self.start_values.iter().zip(&self.end_values).enumerate() {
75 values[i] = f32::from(*start + T::from(coeff * f32::from(*end - *start)));
76 }
77 values
78 }
79 }
80 }
81 };
82 }
83
84 generate_interpolator!(Interpolator1, 1);
85 generate_interpolator!(Interpolator2, 2);
86 generate_interpolator!(Interpolator3, 3);
87 12
88 /// Base visual element. 13 /// Base visual element.
89 #[derive(Debug, Clone, Default)] 14 #[derive(Debug, Clone, Default)]
90 pub struct Sprite { 15 pub struct Sprite {
91 blendfunc: u32, 16 blendfunc: u32,