changeset 661:598f3125cbac

Implement enough instructions to execute sub 0 from stage 1.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 10 Aug 2019 21:04:54 +0200
parents 31fc0d881105
children 107bb5ca5cc8
files examples/eclrenderer.rs src/th06/anm0_vm.rs src/th06/ecl.rs src/th06/ecl_vm.rs src/th06/enemy.rs
diffstat 5 files changed, 58 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/examples/eclrenderer.rs
+++ b/examples/eclrenderer.rs
@@ -165,7 +165,7 @@ fn main() {
             }
         }
 
-        if frame == 60 {
+        if ecl_runner.running == false {
             break;
         }
         frame += 1;
@@ -214,11 +214,11 @@ fn main() {
     }
 }
 
-fn fill_vertices_ptr(sprites: Vec<Rc<RefCell<Sprite>>>, vertices: *mut Vertex) {
+fn fill_vertices_ptr(sprites: Vec<(f32, f32, f32, Rc<RefCell<Sprite>>)>, vertices: *mut Vertex) {
     let mut fake_vertices = unsafe { std::mem::transmute::<*mut Vertex, &mut [FakeVertex; 4]>(vertices) };
-    for sprite in sprites {
+    for (x, y, z, sprite) in sprites {
         let sprite = sprite.borrow();
-        sprite.fill_vertices(&mut fake_vertices);
+        sprite.fill_vertices(&mut fake_vertices, x, y, z);
     }
 }
 
--- a/src/th06/anm0_vm.rs
+++ b/src/th06/anm0_vm.rs
@@ -87,7 +87,7 @@ impl Sprite {
     }
 
     /// TODO
-    pub fn fill_vertices(&self, vertices: &mut [Vertex; 4]) {
+    pub fn fill_vertices(&self, vertices: &mut [Vertex; 4], x: f32, y: f32, z: f32) {
         let mut mat = Mat4::new([[-0.5, 0.5, 0.5, -0.5],
                                  [-0.5, -0.5, 0.5, 0.5],
                                  [0., 0., 0., 0.],
@@ -127,6 +127,8 @@ impl Sprite {
             mat.translate_2d(width / 2., height / 2.);
         }
 
+        mat.translate([x, y, z]);
+
         let mat = mat.borrow_inner();
         vertices[0].pos[0] = mat[0][0] as i16;
         vertices[0].pos[1] = mat[1][0] as i16;
--- a/src/th06/ecl.rs
+++ b/src/th06/ecl.rs
@@ -226,7 +226,7 @@ declare_sub_instructions!{
     100 => fn SetDeathAnim(sprite_index: i32),
     101 => fn SetBossMode(value: i32),
     102 => fn CreateSquares(UNK1: i32, UNK2: f32, UNK3: f32, UNK4: f32, UNK5: f32),
-    103 => fn SetEnemyHitbox(width: f32, height: f32, depth: f32),
+    103 => fn SetHitbox(width: f32, height: f32, depth: f32),
     104 => fn SetCollidable(collidable: i32),
     105 => fn SetDamageable(damageable: i32),
     106 => fn PlaySound(index: i32),
--- a/src/th06/ecl_vm.rs
+++ b/src/th06/ecl_vm.rs
@@ -14,7 +14,8 @@ pub struct EclRunner {
     enemy: Rc<RefCell<Enemy>>,
     ecl: Option<Ecl>,
     sub: u8,
-    running: bool,
+    /// XXX
+    pub running: bool,
     /// XXX
     pub frame: i32,
     ip: i32,
@@ -31,6 +32,7 @@ impl EclRunner {
             // XXX: no clone.
             ecl: Some(ecl.clone()),
             sub,
+            running: true,
             ..Default::default()
         }
     }
@@ -143,6 +145,7 @@ impl EclRunner {
     }
 
     fn run_instruction(&mut self, instruction: SubInstruction) {
+        println!("Running instruction {:?}", instruction);
         match instruction {
             SubInstruction::Noop() => {
                 // really
@@ -428,16 +431,19 @@ impl EclRunner {
             */
             // 45
             SubInstruction::SetAngleAndSpeed(angle, speed) => {
+                let angle = self.get_f32(angle);
+                let speed = self.get_f32(speed);
                 let mut enemy = self.enemy.borrow_mut();
                 enemy.update_mode = 0;
-                enemy.angle = self.get_f32(angle);
-                enemy.speed = self.get_f32(speed);
+                enemy.angle = angle;
+                enemy.speed = speed;
             }
             // 46
             SubInstruction::SetRotationSpeed(speed) => {
+                let rotation_speed = self.get_f32(speed);
                 let mut enemy = self.enemy.borrow_mut();
                 enemy.update_mode = 0;
-                enemy.rotation_speed = self.get_f32(speed);
+                enemy.rotation_speed = rotation_speed;
             }
             // 47
             SubInstruction::SetSpeed(speed) => {
@@ -460,6 +466,28 @@ impl EclRunner {
 
             // 83 -> star items >>> life items
 
+            // 97
+            SubInstruction::SetAnim(index) => {
+                // TODO: check in ghidra!
+                let mut enemy = self.enemy.borrow_mut();
+                enemy.set_anim(index as u8);
+            }
+
+            // 100
+            SubInstruction::SetDeathAnim(index) => {
+                // TODO: check in ghidra!
+                let mut enemy = self.enemy.borrow_mut();
+                enemy.death_anim = index;
+            }
+
+            // 103
+            SubInstruction::SetHitbox(width, height, depth) => {
+                // TODO: check in ghidra!
+                assert_eq!(depth, 32.);
+                let mut enemy = self.enemy.borrow_mut();
+                enemy.set_hitbox(width, height);
+            }
+
             _ => unimplemented!()
         }
     }
--- a/src/th06/enemy.rs
+++ b/src/th06/enemy.rs
@@ -91,12 +91,14 @@ impl Game {
     }
 
     /// Returns a list of all sprites currently being displayed on screen.
-    pub fn get_sprites(&self) -> Vec<Rc<RefCell<Sprite>>> {
+    pub fn get_sprites(&self) -> Vec<(f32, f32, f32, Rc<RefCell<Sprite>>)> {
         let mut sprites = vec![];
-        for anmrunner in self.anmrunners.iter() {
+        for enemy in self.enemies.iter() {
+            let enemy = enemy.borrow();
+            let anmrunner = enemy.anmrunner.upgrade().unwrap();
             let anmrunner = anmrunner.borrow();
             let sprite = anmrunner.get_sprite();
-            sprites.push(sprite);
+            sprites.push((enemy.pos.x, enemy.pos.y, enemy.z, sprite));
         }
         sprites
     }
@@ -139,7 +141,7 @@ pub struct Enemy {
     pub(crate) remaining_lives: u32,
     pub(crate) bullet_launch_interval: u32,
     pub(crate) bullet_launch_timer: u32,
-    pub(crate) death_anim: u32,
+    pub(crate) death_anim: i32,
     pub(crate) direction: u32,
     pub(crate) update_mode: u32,
 
@@ -245,6 +247,18 @@ impl Enemy {
     }
 }
 
+trait Renderable {
+    fn get_sprites(&self) -> Vec<Rc<RefCell<Sprite>>>;
+}
+
+impl Renderable for Enemy {
+    fn get_sprites(&self) -> Vec<Rc<RefCell<Sprite>>> {
+        let anmrunner = self.anmrunner.upgrade().unwrap();
+        let anmrunner = anmrunner.borrow();
+        vec![anmrunner.get_sprite()]
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;