diff --git a/core/src/mmc/mapper.rs b/core/src/mmc/mapper.rs index d82cd18..5c81189 100644 --- a/core/src/mmc/mapper.rs +++ b/core/src/mmc/mapper.rs @@ -44,4 +44,5 @@ pub trait Mapper: Send { fn needs_bios(&self) -> bool {return false;} fn load_bios(&mut self, _: Vec) {} fn switch_disk(&mut self, _: usize) {} + fn vrc7_set_patches(&mut self, _patches: &[u8]) {} } diff --git a/core/src/mmc/nsf.rs b/core/src/mmc/nsf.rs index 333ca4c..336820b 100644 --- a/core/src/mmc/nsf.rs +++ b/core/src/mmc/nsf.rs @@ -1402,4 +1402,8 @@ impl Mapper for NsfMapper { fn audio_multiplexing(&mut self, emulate: bool) { self.n163_expansion_audio_chip.emulate_multiplexing = emulate; } + + fn vrc7_set_patches(&mut self, patches: &[u8]) { + self.vrc7_audio.set_patches(patches); + } } diff --git a/core/src/mmc/vrc7.rs b/core/src/mmc/vrc7.rs index 4bf3166..ebe7db4 100644 --- a/core/src/mmc/vrc7.rs +++ b/core/src/mmc/vrc7.rs @@ -1,6 +1,8 @@ // https://www.nesdev.org/wiki/VRC7 // https://www.nesdev.org/wiki/VRC7_audio +use std::convert::TryInto; + use ines::INesCartridge; use memoryblock::MemoryBlock; @@ -295,6 +297,10 @@ impl Mapper for Vrc7 { fn record_expansion_audio_output(&mut self, _nes_sample: f32) { self.audio.record_output(); } + + fn vrc7_set_patches(&mut self, patches: &[u8]) { + self.audio.set_patches(patches); + } } // TODO: explore and see if we can't somehow make these constant while keeping them @@ -917,6 +923,7 @@ impl Vrc7AudioChannel { pub struct Vrc7Audio { pub custom_patch: [u8; 8], + pub patches: [u8; 8 * 15], pub channel1: Vrc7AudioChannel, pub channel2: Vrc7AudioChannel, pub channel3: Vrc7AudioChannel, @@ -931,6 +938,7 @@ impl Vrc7Audio { pub fn new() -> Vrc7Audio { let thing = Vrc7Audio { custom_patch: [0u8; 8], + patches: DEFAULT_PATCH_TABLE, channel1: Vrc7AudioChannel::new(1), channel2: Vrc7AudioChannel::new(2), channel3: Vrc7AudioChannel::new(3), @@ -1070,7 +1078,7 @@ impl Vrc7Audio { self.channel1.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel1.instrument_index - 1) * 8) as usize; - self.channel1.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel1.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, 0x31 => { @@ -1080,7 +1088,7 @@ impl Vrc7Audio { self.channel2.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel2.instrument_index - 1) * 8) as usize; - self.channel2.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel2.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, 0x32 => { @@ -1090,7 +1098,7 @@ impl Vrc7Audio { self.channel3.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel3.instrument_index - 1) * 8) as usize; - self.channel3.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel3.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, 0x33 => { @@ -1100,7 +1108,7 @@ impl Vrc7Audio { self.channel4.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel4.instrument_index - 1) * 8) as usize; - self.channel4.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel4.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, 0x34 => { @@ -1110,7 +1118,7 @@ impl Vrc7Audio { self.channel5.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel5.instrument_index - 1) * 8) as usize; - self.channel5.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel5.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, 0x35 => { @@ -1120,7 +1128,7 @@ impl Vrc7Audio { self.channel6.load_patch(&self.custom_patch); } else { let patch_index = ((self.channel6.instrument_index - 1) * 8) as usize; - self.channel6.load_patch(&DEFAULT_PATCH_TABLE[patch_index .. patch_index + 8]); + self.channel6.load_patch(&self.patches[patch_index .. patch_index + 8]); } }, _ => {} @@ -1135,6 +1143,11 @@ impl Vrc7Audio { self.channel5.record_current_output(); self.channel6.record_current_output(); } + + pub fn set_patches(&mut self, patches: &[u8]) { + // This isn't going to be called during emulation, so no need to refresh. + self.patches = patches.try_into().unwrap_or(DEFAULT_PATCH_TABLE); + } } impl AudioChannelState for Vrc7AudioChannel {