diff options
Diffstat (limited to 'src/convert.rs')
-rw-r--r-- | src/convert.rs | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/src/convert.rs b/src/convert.rs index 9ed703f..5ae394c 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -17,7 +17,7 @@ struct PlayerState struct Player<'a> { - h: Rc<RefCell<dyn CellHandler>>, + h: Box<RefCell<dyn CellHandler>>, it: &'a itfile::ITFile } @@ -29,7 +29,7 @@ pub struct Converter<'a> trait CellHandler { - fn process(&mut self, ch: u8, cell: itfile::Cell, player: &mut Player); + fn process(&mut self, ch: u8, cell: itfile::Cell, ps: PlayerState) -> PlayerState; fn result_data(&mut self) -> Box<dyn Any>; } @@ -62,7 +62,7 @@ struct ConvertCellHandler<'a> impl<'a> Player<'a> { - fn new(handler: Rc<RefCell<dyn CellHandler>>, it: &'a itfile::ITFile) -> Player<'a> + fn new(handler: Box<RefCell<dyn CellHandler>>, it: &'a itfile::ITFile) -> Player<'a> { Player { @@ -70,27 +70,26 @@ impl<'a> Player<'a> it } } - fn process_pattern(&mut self, pat: usize, st: PlayerState) -> PlayerState + fn process_pattern(&self, pat: usize, st: PlayerState) -> PlayerState { let skip_row = if !st.skip_row == 0 { 0 } else { st.skip_row }; - let ret = PlayerState{ + let mut ret = PlayerState { skip_row: !0, skip_ord: !0, current_ord: 0, current_row: 0, in_loop: false }; - self.skip_row = !0; for r in skip_row..self.it.patterns[pat].nrows { - self.current_row = r; + ret.current_row = r; for c in 0..64 { let cell = *self.it.patterns[pat].cell_at(r, c); - Rc::clone(&self.h).borrow_mut().process(c as u8, cell, self); + ret = (&self.h).borrow_mut().process(c as u8, cell, ret); } - Rc::clone(&self.h).borrow_mut().process(!0, itfile::Cell::default(), self); - if (!self.skip_row) != 0 || (!self.skip_ord) != 0 { return; } + ret = (&self.h).borrow_mut().process(!0, itfile::Cell::default(), ret); + if (!ret.skip_row) != 0 || (!ret.skip_ord) != 0 { return ret; } } ret } @@ -99,28 +98,39 @@ impl<'a> Player<'a> /// passing !0 to row or ord if it's unused /// /// in_loop == true inhibits loop detection and should only be used for SBx - fn skip_to(&mut self, row: u16, ord: u8, in_loop: bool) + fn skip_to(&self, row: u16, ord: u8, in_loop: bool, ps: PlayerState) -> PlayerState { - self.skip_row = if !row != 0 { row } else { self.skip_row }; - self.skip_ord = if !ord != 0 { ord } else { self.skip_ord }; - self.in_loop = in_loop; + PlayerState { + skip_row: if !row != 0 { row } else { ps.skip_row }, + skip_ord: if !ord != 0 { ord } else { ps.skip_ord }, + in_loop, + ..ps + } } - fn process_orders(&mut self) + fn process_orders(&self) { - self.skip_to(!0, !0, false); + let mut ps = PlayerState { + skip_row: !0, + skip_ord: !0, + current_ord: 0, + current_row: 0, + in_loop: false + }; + let mut oid = 0; loop { if oid >= self.it.orders.len() { break; } if self.it.orders[oid] == 0xff { break; } if self.it.orders[oid] == 0xfe { continue; } - self.process_pattern(self.it.orders[oid].into()); - if !self.skip_ord != 0 + ps.current_ord = oid as u8; + ps = self.process_pattern(self.it.orders[oid].into(), ps); + if !ps.skip_ord != 0 { - if self.skip_ord as usize <= oid && !self.in_loop + if ps.skip_ord as usize <= oid && !ps.in_loop { println!("loop?"); } - else { oid = self.skip_ord as usize; } - self.skip_ord = !0; + else { oid = ps.skip_ord as usize; } + ps.skip_ord = !0; } else { oid += 1; } } @@ -129,9 +139,9 @@ impl<'a> Player<'a> impl CellHandler for PrePassCellHandler { - fn process(&mut self, ch: u8, cell: itfile::Cell, _p: &mut Player) + fn process(&mut self, ch: u8, cell: itfile::Cell, ps: PlayerState) -> PlayerState { - if ch == 0xff { return; } + if ch == 0xff { return ps; } let itfile::Cell{mask, mut inst, ..} = cell; if mask & 0x22 != 0 { self.chinst[ch as usize] = inst; } @@ -139,6 +149,7 @@ impl CellHandler for PrePassCellHandler { inst = self.chinst[ch as usize]; } if mask & 0x11 != 0 { self.instchmap.as_mut().unwrap().insert((ch, inst)); } + ps } fn result_data(&mut self) -> Box<dyn Any> { Box::new(self.instchmap.take().unwrap()) } @@ -157,9 +168,10 @@ impl<'a> ConvertCellHandler<'a> impl<'a> CellHandler for ConvertCellHandler<'a> { - fn process(&mut self, ch: u8, cell: itfile::Cell, player: &mut Player) + fn process(&mut self, ch: u8, cell: itfile::Cell, ps: PlayerState) -> PlayerState { let itfile::Cell{mask, note, inst, vol, efx, fxp} = cell; + ps } fn result_data(&mut self) -> Box<dyn Any> { Box::new(()) } @@ -174,9 +186,9 @@ impl<'a> Converter<'a> fn pre_pass(&'a mut self) { let h = PrePassCellHandler{instchmap: Some(BTreeSet::new()), chinst: [0; 64]}; - let mut p = Player::new(Rc::new(RefCell::new(h)), self.it); + let p = Player::new(Box::new(RefCell::new(h)), self.it); p.process_orders(); - let Player{mut h, ..} = p; + let Player{h, ..} = p; if let Ok(m) = h.borrow_mut().result_data().downcast::<BTreeSet<(u8, u8)>>() { let mut instch = BTreeMap::new(); |