Mercurial > touhou
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::*;