implement functionality behind div-apu ticks
This commit is contained in:
parent
e150005eda
commit
8d90da2e6d
|
@ -140,12 +140,16 @@ impl Apu {
|
||||||
if self.div_apu % 8 == 0 {
|
if self.div_apu % 8 == 0 {
|
||||||
// envelope sweep
|
// envelope sweep
|
||||||
self.channels.one.envelope_tick();
|
self.channels.one.envelope_tick();
|
||||||
|
self.channels.two.envelope_tick();
|
||||||
}
|
}
|
||||||
if self.div_apu % 4 == 0 {
|
if self.div_apu % 4 == 0 {
|
||||||
// ch1 frequency sweep
|
// ch1 frequency sweep
|
||||||
|
self.channels.one.frequency_tick();
|
||||||
}
|
}
|
||||||
if self.div_apu % 2 == 0 {
|
if self.div_apu % 2 == 0 {
|
||||||
// tick sound length timers
|
// tick sound length timers
|
||||||
|
self.channels.one.length_tick();
|
||||||
|
self.channels.two.length_tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct Sweep {
|
||||||
pace: u8,
|
pace: u8,
|
||||||
mode: EnvelopeMode,
|
mode: EnvelopeMode,
|
||||||
slope: u8,
|
slope: u8,
|
||||||
|
counter: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Sweep {
|
impl Default for Sweep {
|
||||||
|
@ -18,6 +19,7 @@ impl Default for Sweep {
|
||||||
pace: 0,
|
pace: 0,
|
||||||
mode: EnvelopeMode::Increase,
|
mode: EnvelopeMode::Increase,
|
||||||
slope: 0,
|
slope: 0,
|
||||||
|
counter: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +43,7 @@ impl Envelope {
|
||||||
counter: 0,
|
counter: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(&mut self) {
|
fn tick(&mut self) {
|
||||||
if self.rate == 0 {
|
if self.rate == 0 {
|
||||||
return;
|
return;
|
||||||
|
@ -167,8 +170,39 @@ impl PwmChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn envelope_tick(&mut self) {
|
pub(super) fn envelope_tick(&mut self) {
|
||||||
|
if self.enabled {
|
||||||
self.envelope.tick();
|
self.envelope.tick();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn frequency_tick(&mut self) {
|
||||||
|
if self.sweep.slope == 0 || !self.enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.sweep.counter += 1;
|
||||||
|
if self.sweep.counter % self.sweep.pace == 0 {
|
||||||
|
self.sweep.counter = 0;
|
||||||
|
let wavelength_diff = self.wavelength / (2_u16.pow(self.sweep.slope as u32));
|
||||||
|
let new_wavelength = match self.sweep.mode {
|
||||||
|
EnvelopeMode::Increase => self.wavelength + wavelength_diff,
|
||||||
|
EnvelopeMode::Decrease => self.wavelength.saturating_sub(wavelength_diff),
|
||||||
|
};
|
||||||
|
if new_wavelength > 0x7FF {
|
||||||
|
self.enabled = false;
|
||||||
|
} else {
|
||||||
|
self.wavelength = new_wavelength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn length_tick(&mut self) {
|
||||||
|
if self.length_enable && self.enabled {
|
||||||
|
self.length_timer += 1;
|
||||||
|
if self.length_timer >= 64 {
|
||||||
|
self.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn update_sweep(&mut self, pace: u8, mode: EnvelopeMode, slope: u8) {
|
pub(super) fn update_sweep(&mut self, pace: u8, mode: EnvelopeMode, slope: u8) {
|
||||||
self.sweep.pace = pace;
|
self.sweep.pace = pace;
|
||||||
|
|
Loading…
Reference in a new issue