Mercurial > touhou
diff src/th06/anm0_vm.rs @ 741:3555845f8cf4
Make it so we can use more than a single anm0 in an EclRunner.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 07 Jan 2020 00:06:18 +0100 |
parents | 6d4802abe134 |
children | 0a250ddfae79 |
line wrap: on
line diff
--- a/src/th06/anm0_vm.rs +++ b/src/th06/anm0_vm.rs @@ -214,9 +214,50 @@ impl Sprite { } } +struct Anms { + inner: Rc<RefCell<[Anm0; 2]>>, +} + +impl Anms { + fn new(anms: Rc<RefCell<[Anm0; 2]>>) -> Anms { + Anms { + inner: anms, + } + } + + fn load_sprite(&self, sprite: &mut Sprite, id: u8) { + let anms = self.inner.borrow(); + let mut anm = None; + let mut texcoords = None; + 'anm: for anm0 in anms.iter() { + for sp in anm0.sprites.iter() { + if sp.index == id as u32 { + texcoords = Some(sp); + anm = Some(anm0.clone()); + break 'anm; + } + } + } + sprite.anm = anm; + if let Some(texcoords) = texcoords { + sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; + } + } + + fn get_script(&self, id: u8) -> Script { + let anms = self.inner.borrow(); + for anm0 in anms.iter() { + if anm0.scripts.contains_key(&id) { + return anm0.scripts[&id].clone(); + } + } + unreachable!(); + } +} + /// Interpreter for `Anm0` instructions to update a `Sprite`. pub struct AnmRunner { - anm: Anm0, + anms: Anms, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, running: bool, @@ -231,15 +272,17 @@ pub struct AnmRunner { impl AnmRunner { /// Create a new `AnmRunner`. - pub fn new(anm: &Anm0, script_id: u8, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, sprite_index_offset: u32) -> AnmRunner { + pub fn new(anms: Rc<RefCell<[Anm0; 2]>>, script_id: u8, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, sprite_index_offset: u32) -> AnmRunner { + let anms = Anms::new(anms); + let script = anms.get_script(script_id); let mut runner = AnmRunner { - anm: anm.clone(), + anms, sprite: sprite, prng, running: true, waiting: false, - script: anm.scripts[&script_id].clone(), + script, frame: 0, timeout: None, instruction_pointer: 0, @@ -321,9 +364,7 @@ impl AnmRunner { self.running = false; } Instruction::LoadSprite(sprite_index) => { - sprite.anm = Some(self.anm.clone()); - let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; - sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; + self.anms.load_sprite(&mut sprite, (sprite_index + self.sprite_index_offset) as u8); } Instruction::SetScale(sx, sy) => { sprite.rescale = [sx, sy]; @@ -375,11 +416,7 @@ impl AnmRunner { amplitude = (rand as u32) % amplitude; } let sprite_index = min_index + amplitude; - - // TODO: refactor that with Instruction::LoadSprite. - sprite.anm = Some(self.anm.clone()); - let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; - sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; + self.anms.load_sprite(&mut sprite, (sprite_index + self.sprite_index_offset) as u8); } Instruction::Move(x, y, z) => { sprite.dest_offset = [x, y, z];