Mercurial > touhou
comparison 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 |
comparison
equal
deleted
inserted
replaced
740:8d29dac12219 | 741:3555845f8cf4 |
---|---|
212 self.changed = true; | 212 self.changed = true; |
213 } | 213 } |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 struct Anms { | |
218 inner: Rc<RefCell<[Anm0; 2]>>, | |
219 } | |
220 | |
221 impl Anms { | |
222 fn new(anms: Rc<RefCell<[Anm0; 2]>>) -> Anms { | |
223 Anms { | |
224 inner: anms, | |
225 } | |
226 } | |
227 | |
228 fn load_sprite(&self, sprite: &mut Sprite, id: u8) { | |
229 let anms = self.inner.borrow(); | |
230 let mut anm = None; | |
231 let mut texcoords = None; | |
232 'anm: for anm0 in anms.iter() { | |
233 for sp in anm0.sprites.iter() { | |
234 if sp.index == id as u32 { | |
235 texcoords = Some(sp); | |
236 anm = Some(anm0.clone()); | |
237 break 'anm; | |
238 } | |
239 } | |
240 } | |
241 sprite.anm = anm; | |
242 if let Some(texcoords) = texcoords { | |
243 sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; | |
244 } | |
245 } | |
246 | |
247 fn get_script(&self, id: u8) -> Script { | |
248 let anms = self.inner.borrow(); | |
249 for anm0 in anms.iter() { | |
250 if anm0.scripts.contains_key(&id) { | |
251 return anm0.scripts[&id].clone(); | |
252 } | |
253 } | |
254 unreachable!(); | |
255 } | |
256 } | |
257 | |
217 /// Interpreter for `Anm0` instructions to update a `Sprite`. | 258 /// Interpreter for `Anm0` instructions to update a `Sprite`. |
218 pub struct AnmRunner { | 259 pub struct AnmRunner { |
219 anm: Anm0, | 260 anms: Anms, |
220 sprite: Rc<RefCell<Sprite>>, | 261 sprite: Rc<RefCell<Sprite>>, |
221 prng: Weak<RefCell<Prng>>, | 262 prng: Weak<RefCell<Prng>>, |
222 running: bool, | 263 running: bool, |
223 sprite_index_offset: u32, | 264 sprite_index_offset: u32, |
224 script: Script, | 265 script: Script, |
229 timeout: Option<u32>, | 270 timeout: Option<u32>, |
230 } | 271 } |
231 | 272 |
232 impl AnmRunner { | 273 impl AnmRunner { |
233 /// Create a new `AnmRunner`. | 274 /// Create a new `AnmRunner`. |
234 pub fn new(anm: &Anm0, script_id: u8, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, sprite_index_offset: u32) -> AnmRunner { | 275 pub fn new(anms: Rc<RefCell<[Anm0; 2]>>, script_id: u8, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, sprite_index_offset: u32) -> AnmRunner { |
276 let anms = Anms::new(anms); | |
277 let script = anms.get_script(script_id); | |
235 let mut runner = AnmRunner { | 278 let mut runner = AnmRunner { |
236 anm: anm.clone(), | 279 anms, |
237 sprite: sprite, | 280 sprite: sprite, |
238 prng, | 281 prng, |
239 running: true, | 282 running: true, |
240 waiting: false, | 283 waiting: false, |
241 | 284 |
242 script: anm.scripts[&script_id].clone(), | 285 script, |
243 frame: 0, | 286 frame: 0, |
244 timeout: None, | 287 timeout: None, |
245 instruction_pointer: 0, | 288 instruction_pointer: 0, |
246 variables: ([0, 0, 0, 0 ], | 289 variables: ([0, 0, 0, 0 ], |
247 [0., 0., 0., 0.], | 290 [0., 0., 0., 0.], |
319 Instruction::Delete() => { | 362 Instruction::Delete() => { |
320 sprite.removed = true; | 363 sprite.removed = true; |
321 self.running = false; | 364 self.running = false; |
322 } | 365 } |
323 Instruction::LoadSprite(sprite_index) => { | 366 Instruction::LoadSprite(sprite_index) => { |
324 sprite.anm = Some(self.anm.clone()); | 367 self.anms.load_sprite(&mut sprite, (sprite_index + self.sprite_index_offset) as u8); |
325 let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; | |
326 sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; | |
327 } | 368 } |
328 Instruction::SetScale(sx, sy) => { | 369 Instruction::SetScale(sx, sy) => { |
329 sprite.rescale = [sx, sy]; | 370 sprite.rescale = [sx, sy]; |
330 } | 371 } |
331 Instruction::SetAlpha(alpha) => { | 372 Instruction::SetAlpha(alpha) => { |
373 let prng = self.prng.upgrade().unwrap(); | 414 let prng = self.prng.upgrade().unwrap(); |
374 let rand = prng.borrow_mut().get_u16(); | 415 let rand = prng.borrow_mut().get_u16(); |
375 amplitude = (rand as u32) % amplitude; | 416 amplitude = (rand as u32) % amplitude; |
376 } | 417 } |
377 let sprite_index = min_index + amplitude; | 418 let sprite_index = min_index + amplitude; |
378 | 419 self.anms.load_sprite(&mut sprite, (sprite_index + self.sprite_index_offset) as u8); |
379 // TODO: refactor that with Instruction::LoadSprite. | |
380 sprite.anm = Some(self.anm.clone()); | |
381 let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; | |
382 sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; | |
383 } | 420 } |
384 Instruction::Move(x, y, z) => { | 421 Instruction::Move(x, y, z) => { |
385 sprite.dest_offset = [x, y, z]; | 422 sprite.dest_offset = [x, y, z]; |
386 } | 423 } |
387 Instruction::MoveToLinear(x, y, z, duration) => { | 424 Instruction::MoveToLinear(x, y, z, duration) => { |