diff --git a/build.rs b/build.rs index 42f31d8..13d9b4c 100644 --- a/build.rs +++ b/build.rs @@ -6,7 +6,7 @@ fn main() { let mut consts = ConstWriter::for_build("lsdpack_bc") .unwrap() .finish_dependencies(); - let bytes: Vec = SONG_SOURCE + let mut bytes: Vec = SONG_SOURCE .lines() .map(|s| s.trim().strip_prefix("DB ")) .flatten() // filter to lines starting with DB @@ -29,6 +29,12 @@ fn main() { .flatten() // filter to lines from SongLocations .map(|s| usize::from_str_radix(s.split_once('$').unwrap().1, 16).unwrap() - 0x4000) .collect(); + // gba psg has inverted wave channel polarity + for sample_pair in &mut bytes[0..*song_positions.iter().min().unwrap()] { + let upper = *sample_pair & 0xF0; + let lower = *sample_pair & 0x0F; + *sample_pair = (0xF0 - upper) | (0x0F - lower); + } consts.add_array("LSDPACK_DATA", "u8", &bytes); consts.add_array("LSDPACK_SONG_POSITIONS", "usize", &song_positions); } diff --git a/src/lsdpack.rs b/src/lsdpack.rs index d0b0aba..f486609 100644 --- a/src/lsdpack.rs +++ b/src/lsdpack.rs @@ -1,9 +1,10 @@ +use core::{fmt::Write, ops::Add}; use gba::prelude::*; use voladdress::{Safe, VolAddress}; #[allow(dead_code)] #[repr(u8)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] enum LsdpackCmd { // special commands (not just plain register writes) EndTick = 0, @@ -139,11 +140,24 @@ impl Lsdpack { fn write_next_samples(&mut self) { let ptr = self.sample_ptr; self.sample_ptr += 16; - //let sound_enabled = SOUND_ENABLED.read(); - //SOUND_ENABLED.write(sound_enabled.with_wave_playing(false)); - let lrvol = LEFT_RIGHT_VOLUME.read(); - LEFT_RIGHT_VOLUME.write(lrvol.with_wave_left(false).with_wave_right(false)); - WAVE_BANK.write(WaveBank::new().with_enabled(false)); + + // let sound_enabled = SOUND_ENABLED.read(); + // SOUND_ENABLED.write(sound_enabled.with_wave_playing(false)); + + //let lrvol = LEFT_RIGHT_VOLUME.read(); + //LEFT_RIGHT_VOLUME.write(lrvol.with_wave_left(false).with_wave_right(false)); + + let wb = WAVE_BANK.read(); + //WAVE_BANK.write(WaveBank::new().with_enabled(false)); + + let wave_ram_ptr = (WAVE_RAM.as_mut_ptr() as *mut u8); + for i in 0..16 { + unsafe { + wave_ram_ptr.add(i).write_volatile(self.data[ptr + i]); + } + } + + /* WAVE_RAM.index(0).write(u32::from_le_bytes( TryFrom::try_from(&self.data[ptr..ptr + 4]).unwrap(), )); @@ -156,10 +170,20 @@ impl Lsdpack { WAVE_RAM.index(3).write(u32::from_le_bytes( TryFrom::try_from(&self.data[ptr + 12..ptr + 16]).unwrap(), )); - WAVE_BANK.write(WaveBank::new().with_enabled(true)); - //SOUND_ENABLED.write(sound_enabled); - LEFT_RIGHT_VOLUME.write(lrvol); - WAVE_FREQ.write(WaveFrequency::new().with_length(self.sample_pitch)); + */ + + //WAVE_BANK.write(WaveBank::new().with_enabled(true)); + WAVE_BANK.write( + WaveBank::new() + .with_enabled(true) + .with_two_banks(false) + .with_bank1(!wb.bank1()), + ); + + // SOUND_ENABLED.write(sound_enabled); + //LEFT_RIGHT_VOLUME.write(lrvol); + + unsafe { WAVE_FREQ.cast() }.write(self.sample_pitch); } #[link_section = ".iwram"] @@ -183,6 +207,33 @@ impl Lsdpack { ongoing = flagged_ongoing; ongoing &= self.apply_cmd(cmd); } + + /* // stupid hack while testing. only enable wav channel so i can hear it at all + SOUND_ENABLED.write( + SoundEnable::new() + .with_tone1_playing(false) + .with_tone2_playing(false) + .with_wave_playing(true) + .with_noise_playing(false) + .with_enabled(true), + ); + LEFT_RIGHT_VOLUME.write( + LeftRightVolume::new() + .with_tone1_left(false) + .with_tone1_right(false) + .with_tone2_left(false) + .with_tone2_right(false) + .with_wave_left(true) + .with_wave_right(true) + .with_noise_right(false) + .with_noise_left(false) + .with_left_volume(3) + .with_right_volume(3), + ); + // */ + + //WAVE_BANK.write(WaveBank::new().with_enabled(true)); + //WAVE_LEN_VOLUME.write(WaveLenVolume::new().with_length(255).with_volume(1)); } #[link_section = ".iwram"] @@ -206,13 +257,21 @@ impl Lsdpack { #[link_section = ".iwram"] fn write_lsb(&mut self, voladdr: VolAddress) { let voladdr = unsafe { voladdr.cast::() }; - voladdr.write((voladdr.read() & 0xFF00) | (self.next_byte() as u16)); + //voladdr.write((voladdr.read() & 0xFF00) | (self.next_byte() as u16)); + unsafe { + (voladdr.as_mut_ptr() as *mut u8).write_volatile(self.next_byte()); + } } #[link_section = ".iwram"] fn write_msb(&mut self, voladdr: VolAddress) { let voladdr = unsafe { voladdr.cast::() }; - voladdr.write((voladdr.read() & 0xFF) | ((self.next_byte() as u16) << 8)); + //voladdr.write((voladdr.read() & 0xFF) | ((self.next_byte() as u16) << 8)); + unsafe { + (voladdr.as_mut_ptr() as *mut u8) + .add(1) + .write_volatile(self.next_byte()); + } } #[link_section = ".iwram"] @@ -225,6 +284,22 @@ impl Lsdpack { #[link_section = ".iwram"] fn apply_cmd(&mut self, cmd: LsdpackCmd) -> bool { use LsdpackCmd::*; + /* + if let Ok(mut logger) = + gba::mgba::MgbaBufferedLogger::try_new(gba::mgba::MgbaMessageLevel::Info) + { + match cmd { + SampleStart | SampleNext | WavOnOff | WavLength | WavEnv | WavPitchLsb + | WavPitchMsb | ChannelVolume | Pan | SoundOffOn | WavePattern0 | WavePattern1 + | WavePattern2 | WavePattern3 | WavePattern4 | WavePattern5 | WavePattern6 + | WavePattern7 | WavePattern8 | WavePattern9 | WavePatternA | WavePatternB + | WavePatternC | WavePatternD | WavePatternE | WavePatternF => { + writeln!(logger, "{:?}", cmd).ok(); + } + _ => {} + } + } + // */ match cmd { // special commands: EndTick => return false, @@ -242,7 +317,6 @@ impl Lsdpack { NextBank => { /* lol */ } AmpDecPu0 => { // https://github.com/LIJI32/SameBoy/blob/27b5935b8d0e0af988bcac8e55e92703af24f335/Core/apu.c#L341 - /* let base = TONE1_PATTERN.read(); TONE1_PATTERN.write( base.with_volume(0) @@ -259,10 +333,8 @@ impl Lsdpack { .with_step_increasing(true) .with_step_time(0), ); // $FF12 <- $18 - */ } AmpDecPu1 => { - /* let base = TONE2_PATTERN.read(); TONE2_PATTERN.write( base.with_volume(0) @@ -279,10 +351,8 @@ impl Lsdpack { .with_step_increasing(true) .with_step_time(0), ); // $FF17 <- $18 - */ } AmpDecNoi => { - /* let base = NOISE_LEN_ENV.read(); NOISE_LEN_ENV.write( base.with_volume(0) @@ -299,51 +369,53 @@ impl Lsdpack { .with_step_increasing(true) .with_step_time(0), ); // $FF21 <- $18 - */ } - PitchPu0 => {} //self.write_u16le(TONE1_FREQUENCY), - PitchPu1 => {} //self.write_u16le(TONE2_FREQUENCY), + PitchPu0 => self.write_u16le(TONE1_FREQUENCY), + PitchPu1 => self.write_u16le(TONE2_FREQUENCY), PitchWav => self.write_u16le(WAVE_FREQ), SampleNext => self.write_next_samples(), // general register writes: - Pu0Sweep => {} //unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()), - Pu0LengthWave => {} //self.write_lsb(TONE1_PATTERN), - Pu0Env => {} //self.write_msb(TONE1_PATTERN), - Pu0PitchLsb => {} //self.write_lsb(TONE1_FREQUENCY), - Pu0PitchMsb => {} //self.write_msb(TONE1_FREQUENCY), - Pu1LengthWave => {} //self.write_lsb(TONE2_PATTERN), - Pu1Env => {} //self.write_msb(TONE2_PATTERN), - Pu1PitchLsb => {} //self.write_lsb(TONE2_FREQUENCY), - Pu1PitchMsb => {} //self.write_msb(TONE2_FREQUENCY), - WavOnOff => WAVE_BANK.write(WaveBank::new().with_enabled(self.next_byte() != 0)), + Pu0Sweep => unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()), + Pu0LengthWave => self.write_lsb(TONE1_PATTERN), + Pu0Env => { + self.next_byte(); + } //self.write_msb(TONE1_PATTERN), + Pu0PitchLsb => self.write_lsb(TONE1_FREQUENCY), + Pu0PitchMsb => self.write_msb(TONE1_FREQUENCY), + Pu1LengthWave => self.write_lsb(TONE2_PATTERN), + Pu1Env => { + self.next_byte(); + } //self.write_msb(TONE2_PATTERN), + Pu1PitchLsb => self.write_lsb(TONE2_FREQUENCY), + Pu1PitchMsb => self.write_msb(TONE2_FREQUENCY), + //WavOnOff => unsafe { WAVE_BANK.cast() }.write(self.next_byte()), + WavOnOff => WAVE_BANK.write( + WaveBank::new().with_enabled(self.next_byte() != 0), //.with_two_banks(true) + //.with_bank1(false), + ), WavLength => self.write_lsb(WAVE_LEN_VOLUME), WavEnv => self.write_msb(WAVE_LEN_VOLUME), WavPitchLsb => self.write_lsb(WAVE_FREQ), WavPitchMsb => self.write_msb(WAVE_FREQ), - NoiLength => {} //self.write_lsb(NOISE_LEN_ENV), - NoiEnv => {} //self.write_msb(NOISE_LEN_ENV), - NoiWave => {} //self.write_lsb(NOISE_FREQ), - NoiTrig => {} //self.write_msb(NOISE_FREQ), + NoiLength => self.write_lsb(NOISE_LEN_ENV), + NoiEnv => { + self.next_byte(); + } //self.write_msb(NOISE_LEN_ENV), + NoiWave => self.write_lsb(NOISE_FREQ), + NoiTrig => self.write_msb(NOISE_FREQ), ChannelVolume => self.write_lsb(LEFT_RIGHT_VOLUME), Pan => self.write_msb(LEFT_RIGHT_VOLUME), SoundOffOn => unsafe { SOUND_ENABLED.cast() }.write(self.next_byte()), - WavePattern0 => todo!("WavePattern0"), - WavePattern1 => todo!("WavePattern1"), - WavePattern2 => todo!("WavePattern2"), - WavePattern3 => todo!("WavePattern3"), - WavePattern4 => todo!("WavePattern4"), - WavePattern5 => todo!("WavePattern5"), - WavePattern6 => todo!("WavePattern6"), - WavePattern7 => todo!("WavePattern7"), - WavePattern8 => todo!("WavePattern8"), - WavePattern9 => todo!("WavePattern9"), - WavePatternA => todo!("WavePatternA"), - WavePatternB => todo!("WavePatternB"), - WavePatternC => todo!("WavePatternC"), - WavePatternD => todo!("WavePatternD"), - WavePatternE => todo!("WavePatternE"), - WavePatternF => todo!("WavePatternF"), + WavePattern0 | WavePattern1 | WavePattern2 | WavePattern3 | WavePattern4 + | WavePattern5 | WavePattern6 | WavePattern7 | WavePattern8 | WavePattern9 + | WavePatternA | WavePatternB | WavePatternC | WavePatternD | WavePatternE + | WavePatternF => { + let which = cmd as u8 as usize & 0xF; + unsafe { + ((0x04000090 + which) as *mut u8).write_volatile(self.next_byte()); + } + } _Invalid0B | _Invalid0C | _Invalid0D | _Invalid0E | _Invalid0F | _Invalid15 | _Invalid1F | _Invalid27 | _Invalid28 | _Invalid29 | _Invalid2A | _Invalid2B | _Invalid2C | _Invalid2D | _Invalid2E | _Invalid2F => {