changeset 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
files src/th06/anm0_vm.rs src/th06/interpolator.rs src/th06/mod.rs
diffstat 3 files changed, 79 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/src/th06/anm0_vm.rs
+++ b/src/th06/anm0_vm.rs
@@ -6,85 +6,10 @@ use crate::th06::anm0::{
     Call,
     Instruction,
 };
+use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula};
 use std::cell::RefCell;
 use std::rc::Rc;
 
-#[derive(Debug, Clone, Copy, PartialEq)]
-enum Formula {
-    Linear,
-    Power2,
-    InvertPower2,
-}
-
-impl Formula {
-    fn apply(&self, x: f32) -> f32 {
-        match self {
-            Formula::Linear => x,
-            Formula::Power2 => x * x,
-            Formula::InvertPower2 => 2. * x - x * x,
-        }
-    }
-}
-
-macro_rules! generate_interpolator {
-    ($name:ident, $n:tt) => {
-        #[derive(Debug, Clone)]
-        struct $name<T> {
-            start_values: [T; $n],
-            end_values: [T; $n],
-            start_frame: u16,
-            end_frame: u16,
-            formula: Formula,
-        }
-
-        impl<T> $name<T>
-        where f32: From<T>,
-              T: From<f32>,
-              T: std::ops::Sub<Output = T>,
-              T: std::ops::Add<Output = T>,
-              T: Copy,
-              T: Default,
-        {
-            pub fn new(start_values: [T; $n], start_frame: u16, end_values: [T; $n], end_frame: u16, formula: Formula) -> $name<T> {
-                $name {
-                    start_values,
-                    end_values,
-                    start_frame,
-                    end_frame,
-                    formula,
-                }
-            }
-
-            // XXX: Make it return [T; $n] instead, we don’t want to only do f32 here.
-            pub fn values(&self, frame: u16) -> [f32; $n] {
-                if frame + 1 >= self.end_frame {
-                    // XXX: skip the last interpolation step.
-                    // This bug is replicated from the original game.
-                    //self.start_frame = self.end_frame;
-                    //self.end_values
-                    let mut values: [f32; $n] = [Default::default(); $n];
-                    for (i, value) in self.end_values.iter().enumerate() {
-                        values[i] = f32::from(*value);
-                    }
-                    values
-                } else {
-                    let mut coeff = (frame - self.start_frame) as f32 / (self.end_frame - self.start_frame) as f32;
-                    coeff = self.formula.apply(coeff);
-                    let mut values: [f32; $n] = [Default::default(); $n];
-                    for (i, (start, end)) in self.start_values.iter().zip(&self.end_values).enumerate() {
-                        values[i] = f32::from(*start + T::from(coeff * f32::from(*end - *start)));
-                    }
-                    values
-                }
-            }
-        }
-    };
-}
-
-generate_interpolator!(Interpolator1, 1);
-generate_interpolator!(Interpolator2, 2);
-generate_interpolator!(Interpolator3, 3);
-
 /// Base visual element.
 #[derive(Debug, Clone, Default)]
 pub struct Sprite {
new file mode 100644
--- /dev/null
+++ b/src/th06/interpolator.rs
@@ -0,0 +1,77 @@
+//! Animation runner.
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub(crate) enum Formula {
+    Linear,
+    Power2,
+    InvertPower2,
+}
+
+impl Formula {
+    fn apply(&self, x: f32) -> f32 {
+        match self {
+            Formula::Linear => x,
+            Formula::Power2 => x * x,
+            Formula::InvertPower2 => 2. * x - x * x,
+        }
+    }
+}
+
+macro_rules! generate_interpolator {
+    ($name:ident, $n:tt) => {
+        #[derive(Debug, Clone)]
+        pub(crate) struct $name<T> {
+            start_values: [T; $n],
+            end_values: [T; $n],
+            start_frame: u16,
+            end_frame: u16,
+            formula: Formula,
+        }
+
+        impl<T> $name<T>
+        where f32: From<T>,
+              T: From<f32>,
+              T: std::ops::Sub<Output = T>,
+              T: std::ops::Add<Output = T>,
+              T: Copy,
+              T: Default,
+        {
+            pub fn new(start_values: [T; $n], start_frame: u16, end_values: [T; $n], end_frame: u16, formula: Formula) -> $name<T> {
+                $name {
+                    start_values,
+                    end_values,
+                    start_frame,
+                    end_frame,
+                    formula,
+                }
+            }
+
+            // XXX: Make it return [T; $n] instead, we don’t want to only do f32 here.
+            pub fn values(&self, frame: u16) -> [f32; $n] {
+                if frame + 1 >= self.end_frame {
+                    // XXX: skip the last interpolation step.
+                    // This bug is replicated from the original game.
+                    //self.start_frame = self.end_frame;
+                    //self.end_values
+                    let mut values: [f32; $n] = [Default::default(); $n];
+                    for (i, value) in self.end_values.iter().enumerate() {
+                        values[i] = f32::from(*value);
+                    }
+                    values
+                } else {
+                    let mut coeff = (frame - self.start_frame) as f32 / (self.end_frame - self.start_frame) as f32;
+                    coeff = self.formula.apply(coeff);
+                    let mut values: [f32; $n] = [Default::default(); $n];
+                    for (i, (start, end)) in self.start_values.iter().zip(&self.end_values).enumerate() {
+                        values[i] = f32::from(*start + T::from(coeff * f32::from(*end - *start)));
+                    }
+                    values
+                }
+            }
+        }
+    };
+}
+
+generate_interpolator!(Interpolator1, 1);
+generate_interpolator!(Interpolator2, 2);
+generate_interpolator!(Interpolator3, 3);
--- a/src/th06/mod.rs
+++ b/src/th06/mod.rs
@@ -3,3 +3,4 @@
 pub mod pbg3;
 pub mod anm0;
 pub mod anm0_vm;
+pub mod interpolator;