diff --git a/src/reskit/soundtrack/engines/echo/engine.rs b/src/reskit/soundtrack/engines/echo/engine.rs index 192881e..6178f61 100644 --- a/src/reskit/soundtrack/engines/echo/engine.rs +++ b/src/reskit/soundtrack/engines/echo/engine.rs @@ -1,5 +1,4 @@ -use std::{collections::{HashMap, HashSet}, error::Error, cmp::{min, max}}; -use linked_hash_map::LinkedHashMap; +use std::{collections::HashSet, error::Error, cmp::{min, max}}; use linked_hash_set::LinkedHashSet; use crate::reskit::{soundtrack::types::{PatternRow, Note, Channel, OctaveFrequency, Effect, Instrument, NoiseType, DcsgChannelMode, InstrumentType, CombinedAssets, Sample}, utility::print_warning}; @@ -63,11 +62,10 @@ const ESF_SEMITONE_B: u8 = 11; struct InstrumentSet<'a> { fm_ids: HashSet, psg_ids: HashSet, - module_set: &'a Vec, - total_set: &'a Vec, + module_instruments: &'a Vec, + total_instruments: &'a Vec, module_samples: &'a Vec, - total_samples: &'a Vec, - default_psg_id: Option + total_samples: &'a Vec } pub type EchoEvent = Vec; @@ -313,10 +311,10 @@ fn get_events_for_channel( channels: &mut [Channel], active_channel: usize, row: invalid_channel => return Err( format!( "internal error: get_events_for_channel: invalid channel {:#04X}", invalid_channel ) )? }; - // Hop one layer of indirection from `instrument` by getting it from instrument_set.module_set, - // then finding the index of that instrument in instrument_set.total_set. - let original_instrument = &asset_set.module_set[ *instrument as usize ]; - let instrument = asset_set.total_set.iter().position( | instrument | instrument == original_instrument ).ok_or( "internal error: could not locate instrument in combined instrument set" )?; + // Hop one layer of indirection from `instrument` by getting it from instrument_set.module_instruments, + // then finding the index of that instrument in instrument_set.total_instruments. + let original_instrument = &asset_set.module_instruments[ *instrument as usize ]; + let instrument = asset_set.total_instruments.iter().position( | instrument | instrument == original_instrument ).ok_or( "internal error: could not locate instrument in combined instrument set" )?; // Do not set the same instrument if it was already set before if &channels[ active_channel ].active_instrument != &Some( instrument as u16 ) { @@ -330,7 +328,12 @@ fn get_events_for_channel( channels: &mut [Channel], active_channel: usize, row: print_warning( "this is a psg channel, seting the default psg instrument so your note can still play..." ); if row.note.is_some() { // Set "__reskit_default_psg_instrument" - let instrument = asset_set.default_psg_id.ok_or( "internal error: no default psg instrument to apply" )?; + let default_psg_id = if let Some( position ) = asset_set.total_instruments.iter().position( | item | item.name == "__reskit_default_psg_instrument" ) { + Some( position as u16 ) + } else { + None + }; + let instrument = default_psg_id.ok_or( "internal error: no default psg instrument to apply" )?; events.push( vec![ ESF_SET_INSTRUMENT | channels[ active_channel ].id, instrument as u8 ] ); channels[ active_channel ].active_instrument = Some( instrument ); @@ -344,7 +347,12 @@ fn get_events_for_channel( channels: &mut [Channel], active_channel: usize, row: if channels[ active_channel ].active_instrument.is_none() && ( ESF_PSG_1..=ESF_PSG_4 ).contains( &channels[ active_channel ].id ) { if row.note.is_some() { // Set "__reskit_default_psg_instrument" - let instrument = asset_set.default_psg_id.ok_or( "internal error: no default psg instrument to apply" )?; + let default_psg_id = if let Some( position ) = asset_set.total_instruments.iter().position( | item | item.name == "__reskit_default_psg_instrument" ) { + Some( position as u16 ) + } else { + None + }; + let instrument = default_psg_id.ok_or( "internal error: no default psg instrument to apply" )?; events.push( vec![ ESF_SET_INSTRUMENT | channels[ active_channel ].id, instrument as u8 ] ); channels[ active_channel ].active_instrument = Some( instrument ); @@ -391,7 +399,7 @@ fn get_events_for_channel( channels: &mut [Channel], active_channel: usize, row: // Remember, instruments will always be listed first in the output source file, followed by pointers to samples // So the minimum sample offset is the number of instruments - events.push( vec![ ESF_NOTE_ON | channels[ active_channel ].id, global_sample_index as u8 + asset_set.total_set.len() as u8 ] ); + events.push( vec![ ESF_NOTE_ON | channels[ active_channel ].id, global_sample_index as u8 + asset_set.total_instruments.len() as u8 ] ); } } else if channels[ active_channel ].id == ESF_PSG_4 { // Find the single (and it should only ever be a single) Effect::DcsgNoiseMode attached to the channel @@ -832,20 +840,8 @@ fn get_delays( events: Vec, channels: &mut [Channel], ticks_to_wait: pub fn get_events_for_row( channels: &mut [Channel], module_instruments: &Vec, module_samples: &Vec, asset_set: &CombinedAssets, subrows: Vec<&PatternRow>, ticks_to_wait: u8 ) -> Result, Box> { let mut events: Vec = Vec::new(); - let mut index = 0; - - // Find the index of the default psg instrument, if it exists - let default_psg_id: Option = module_instruments.iter().find_map( | item | { - if item.name == "__reskit_default_psg_instrument" { - Some( index ) - } else { - index += 1; - None - } - } ); - // Generate InstrumentSet which is used to validate when instruments are set on channels - index = 0; + let mut index = 0; let fm_ids = module_instruments.iter() .filter_map( | instrument | if matches!( instrument.instrument_type, InstrumentType::Fm2612( _ ) ) { let result = index; @@ -872,11 +868,10 @@ pub fn get_events_for_row( channels: &mut [Channel], module_instruments: &Vec