Mercurial > touhou
comparison src/th06/anm0_vm.rs @ 646:7d92730bf543
Add a PRNG and use it for anm0 instruction 16.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 03 Aug 2019 23:30:15 +0200 |
parents | 7bde50132735 |
children | 3331eb7389b3 |
comparison
equal
deleted
inserted
replaced
645:7bde50132735 | 646:7d92730bf543 |
---|---|
6 Call, | 6 Call, |
7 Instruction, | 7 Instruction, |
8 }; | 8 }; |
9 use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula}; | 9 use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula}; |
10 use crate::util::math::Mat4; | 10 use crate::util::math::Mat4; |
11 use crate::util::prng::Prng; | |
11 use std::cell::RefCell; | 12 use std::cell::RefCell; |
12 use std::rc::Rc; | 13 use std::rc::{Rc, Weak}; |
13 | 14 |
14 /// TODO | 15 /// TODO |
15 #[repr(C)] | 16 #[repr(C)] |
16 #[derive(Debug)] | 17 #[derive(Debug)] |
17 pub struct Vertex { | 18 pub struct Vertex { |
202 | 203 |
203 /// Interpreter for `Anm0` instructions to update a `Sprite`. | 204 /// Interpreter for `Anm0` instructions to update a `Sprite`. |
204 pub struct AnmRunner { | 205 pub struct AnmRunner { |
205 anm: Anm0, | 206 anm: Anm0, |
206 sprite: Rc<RefCell<Sprite>>, | 207 sprite: Rc<RefCell<Sprite>>, |
208 prng: Weak<RefCell<Prng>>, | |
207 running: bool, | 209 running: bool, |
208 sprite_index_offset: u32, | 210 sprite_index_offset: u32, |
209 script: Script, | 211 script: Script, |
210 instruction_pointer: usize, | 212 instruction_pointer: usize, |
211 frame: u16, | 213 frame: u16, |
214 timeout: Option<u16>, | 216 timeout: Option<u16>, |
215 } | 217 } |
216 | 218 |
217 impl AnmRunner { | 219 impl AnmRunner { |
218 /// Create a new `AnmRunner`. | 220 /// Create a new `AnmRunner`. |
219 pub fn new(anm: &Anm0, script_id: u8, sprite: Rc<RefCell<Sprite>>, sprite_index_offset: u32) -> AnmRunner { | 221 pub fn new(anm: &Anm0, script_id: u8, sprite: Rc<RefCell<Sprite>>, prng: Weak<RefCell<Prng>>, sprite_index_offset: u32) -> AnmRunner { |
220 let mut runner = AnmRunner { | 222 let mut runner = AnmRunner { |
221 anm: anm.clone(), | 223 anm: anm.clone(), |
222 sprite: sprite, | 224 sprite: sprite, |
225 prng, | |
223 running: true, | 226 running: true, |
224 waiting: false, | 227 waiting: false, |
225 | 228 |
226 script: anm.scripts[&script_id].clone(), | 229 script: anm.scripts[&script_id].clone(), |
227 frame: 0, | 230 frame: 0, |
345 sprite.blendfunc = 0; | 348 sprite.blendfunc = 0; |
346 } | 349 } |
347 Instruction::KeepStill() => { | 350 Instruction::KeepStill() => { |
348 self.running = false; | 351 self.running = false; |
349 } | 352 } |
350 Instruction::LoadRandomSprite(min_index, amplitude) => { | 353 Instruction::LoadRandomSprite(min_index, mut amplitude) => { |
351 let sprite_index = min_index; // XXX: + randrange(amplitude); | 354 if amplitude > 0 { |
355 let prng = self.prng.upgrade().unwrap(); | |
356 let rand = prng.borrow_mut().get_u16(); | |
357 amplitude = (rand as u32) % amplitude; | |
358 } | |
359 let sprite_index = min_index + amplitude; | |
352 | 360 |
353 // TODO: refactor that with Instruction::LoadSprite. | 361 // TODO: refactor that with Instruction::LoadSprite. |
354 sprite.anm = Some(self.anm.clone()); | 362 sprite.anm = Some(self.anm.clone()); |
355 let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; | 363 let texcoords = &self.anm.sprites[(sprite_index + self.sprite_index_offset) as usize]; |
356 sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; | 364 sprite.texcoords = [texcoords.x, texcoords.y, texcoords.width, texcoords.height]; |