Compare commits
	
		
			2 commits
		
	
	
		
			5e36a84f51
			...
			36c1e52e29
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						36c1e52e29 | ||
| 
							 | 
						e84b6d2e3f | 
					 2 changed files with 120 additions and 34 deletions
				
			
		
							
								
								
									
										8
									
								
								build.rs
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								build.rs
									
									
									
									
									
								
							| 
						 | 
					@ -6,7 +6,7 @@ fn main() {
 | 
				
			||||||
    let mut consts = ConstWriter::for_build("lsdpack_bc")
 | 
					    let mut consts = ConstWriter::for_build("lsdpack_bc")
 | 
				
			||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
        .finish_dependencies();
 | 
					        .finish_dependencies();
 | 
				
			||||||
    let bytes: Vec<u8> = SONG_SOURCE
 | 
					    let mut bytes: Vec<u8> = SONG_SOURCE
 | 
				
			||||||
        .lines()
 | 
					        .lines()
 | 
				
			||||||
        .map(|s| s.trim().strip_prefix("DB "))
 | 
					        .map(|s| s.trim().strip_prefix("DB "))
 | 
				
			||||||
        .flatten() // filter to lines starting with DB
 | 
					        .flatten() // filter to lines starting with DB
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,12 @@ fn main() {
 | 
				
			||||||
        .flatten() // filter to lines from SongLocations
 | 
					        .flatten() // filter to lines from SongLocations
 | 
				
			||||||
        .map(|s| usize::from_str_radix(s.split_once('$').unwrap().1, 16).unwrap() - 0x4000)
 | 
					        .map(|s| usize::from_str_radix(s.split_once('$').unwrap().1, 16).unwrap() - 0x4000)
 | 
				
			||||||
        .collect();
 | 
					        .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_DATA", "u8", &bytes);
 | 
				
			||||||
    consts.add_array("LSDPACK_SONG_POSITIONS", "usize", &song_positions);
 | 
					    consts.add_array("LSDPACK_SONG_POSITIONS", "usize", &song_positions);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										140
									
								
								src/lsdpack.rs
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								src/lsdpack.rs
									
									
									
									
									
								
							| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
 | 
					use core::{fmt::Write, ops::Add};
 | 
				
			||||||
use gba::prelude::*;
 | 
					use gba::prelude::*;
 | 
				
			||||||
use voladdress::{Safe, VolAddress};
 | 
					use voladdress::{Safe, VolAddress};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[allow(dead_code)]
 | 
					#[allow(dead_code)]
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone, Debug)]
 | 
				
			||||||
enum LsdpackCmd {
 | 
					enum LsdpackCmd {
 | 
				
			||||||
    // special commands (not just plain register writes)
 | 
					    // special commands (not just plain register writes)
 | 
				
			||||||
    EndTick = 0,
 | 
					    EndTick = 0,
 | 
				
			||||||
| 
						 | 
					@ -139,11 +140,24 @@ impl Lsdpack {
 | 
				
			||||||
    fn write_next_samples(&mut self) {
 | 
					    fn write_next_samples(&mut self) {
 | 
				
			||||||
        let ptr = self.sample_ptr;
 | 
					        let ptr = self.sample_ptr;
 | 
				
			||||||
        self.sample_ptr += 16;
 | 
					        self.sample_ptr += 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // let sound_enabled = SOUND_ENABLED.read();
 | 
					        // let sound_enabled = SOUND_ENABLED.read();
 | 
				
			||||||
        // SOUND_ENABLED.write(sound_enabled.with_wave_playing(false));
 | 
					        // 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 lrvol = LEFT_RIGHT_VOLUME.read();
 | 
				
			||||||
        WAVE_BANK.write(WaveBank::new().with_enabled(false));
 | 
					        //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(
 | 
					        WAVE_RAM.index(0).write(u32::from_le_bytes(
 | 
				
			||||||
            TryFrom::try_from(&self.data[ptr..ptr + 4]).unwrap(),
 | 
					            TryFrom::try_from(&self.data[ptr..ptr + 4]).unwrap(),
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
| 
						 | 
					@ -156,10 +170,20 @@ impl Lsdpack {
 | 
				
			||||||
        WAVE_RAM.index(3).write(u32::from_le_bytes(
 | 
					        WAVE_RAM.index(3).write(u32::from_le_bytes(
 | 
				
			||||||
            TryFrom::try_from(&self.data[ptr + 12..ptr + 16]).unwrap(),
 | 
					            TryFrom::try_from(&self.data[ptr + 12..ptr + 16]).unwrap(),
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
        WAVE_BANK.write(WaveBank::new().with_enabled(true));
 | 
					        */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //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);
 | 
					        // SOUND_ENABLED.write(sound_enabled);
 | 
				
			||||||
        LEFT_RIGHT_VOLUME.write(lrvol);
 | 
					        //LEFT_RIGHT_VOLUME.write(lrvol);
 | 
				
			||||||
        WAVE_FREQ.write(WaveFrequency::new().with_length(self.sample_pitch));
 | 
					
 | 
				
			||||||
 | 
					        unsafe { WAVE_FREQ.cast() }.write(self.sample_pitch);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[link_section = ".iwram"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
| 
						 | 
					@ -183,6 +207,33 @@ impl Lsdpack {
 | 
				
			||||||
            ongoing = flagged_ongoing;
 | 
					            ongoing = flagged_ongoing;
 | 
				
			||||||
            ongoing &= self.apply_cmd(cmd);
 | 
					            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"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
| 
						 | 
					@ -206,13 +257,21 @@ impl Lsdpack {
 | 
				
			||||||
    #[link_section = ".iwram"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
    fn write_lsb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
 | 
					    fn write_lsb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
 | 
				
			||||||
        let voladdr = unsafe { voladdr.cast::<u16>() };
 | 
					        let voladdr = unsafe { voladdr.cast::<u16>() };
 | 
				
			||||||
        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"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
    fn write_msb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
 | 
					    fn write_msb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
 | 
				
			||||||
        let voladdr = unsafe { voladdr.cast::<u16>() };
 | 
					        let voladdr = unsafe { voladdr.cast::<u16>() };
 | 
				
			||||||
        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"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
| 
						 | 
					@ -225,6 +284,22 @@ impl Lsdpack {
 | 
				
			||||||
    #[link_section = ".iwram"]
 | 
					    #[link_section = ".iwram"]
 | 
				
			||||||
    fn apply_cmd(&mut self, cmd: LsdpackCmd) -> bool {
 | 
					    fn apply_cmd(&mut self, cmd: LsdpackCmd) -> bool {
 | 
				
			||||||
        use LsdpackCmd::*;
 | 
					        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 {
 | 
					        match cmd {
 | 
				
			||||||
            // special commands:
 | 
					            // special commands:
 | 
				
			||||||
            EndTick => return false,
 | 
					            EndTick => return false,
 | 
				
			||||||
| 
						 | 
					@ -303,44 +378,49 @@ impl Lsdpack {
 | 
				
			||||||
            // general register writes:
 | 
					            // general register writes:
 | 
				
			||||||
            Pu0Sweep => unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()),
 | 
					            Pu0Sweep => unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()),
 | 
				
			||||||
            Pu0LengthWave => self.write_lsb(TONE1_PATTERN),
 | 
					            Pu0LengthWave => self.write_lsb(TONE1_PATTERN),
 | 
				
			||||||
            Pu0Env => self.write_msb(TONE1_PATTERN),
 | 
					            Pu0Env => {
 | 
				
			||||||
 | 
					                self.next_byte();
 | 
				
			||||||
 | 
					            } //self.write_msb(TONE1_PATTERN),
 | 
				
			||||||
            Pu0PitchLsb => self.write_lsb(TONE1_FREQUENCY),
 | 
					            Pu0PitchLsb => self.write_lsb(TONE1_FREQUENCY),
 | 
				
			||||||
            Pu0PitchMsb => self.write_msb(TONE1_FREQUENCY),
 | 
					            Pu0PitchMsb => self.write_msb(TONE1_FREQUENCY),
 | 
				
			||||||
            Pu1LengthWave => self.write_lsb(TONE2_PATTERN),
 | 
					            Pu1LengthWave => self.write_lsb(TONE2_PATTERN),
 | 
				
			||||||
            Pu1Env => self.write_msb(TONE2_PATTERN),
 | 
					            Pu1Env => {
 | 
				
			||||||
 | 
					                self.next_byte();
 | 
				
			||||||
 | 
					            } //self.write_msb(TONE2_PATTERN),
 | 
				
			||||||
            Pu1PitchLsb => self.write_lsb(TONE2_FREQUENCY),
 | 
					            Pu1PitchLsb => self.write_lsb(TONE2_FREQUENCY),
 | 
				
			||||||
            Pu1PitchMsb => self.write_msb(TONE2_FREQUENCY),
 | 
					            Pu1PitchMsb => self.write_msb(TONE2_FREQUENCY),
 | 
				
			||||||
            WavOnOff => WAVE_BANK.write(WaveBank::new().with_enabled(self.next_byte() != 0)),
 | 
					            //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),
 | 
					            WavLength => self.write_lsb(WAVE_LEN_VOLUME),
 | 
				
			||||||
            WavEnv => self.write_msb(WAVE_LEN_VOLUME),
 | 
					            WavEnv => self.write_msb(WAVE_LEN_VOLUME),
 | 
				
			||||||
            WavPitchLsb => self.write_lsb(WAVE_FREQ),
 | 
					            WavPitchLsb => self.write_lsb(WAVE_FREQ),
 | 
				
			||||||
            WavPitchMsb => self.write_msb(WAVE_FREQ),
 | 
					            WavPitchMsb => self.write_msb(WAVE_FREQ),
 | 
				
			||||||
            NoiLength => self.write_lsb(NOISE_LEN_ENV),
 | 
					            NoiLength => self.write_lsb(NOISE_LEN_ENV),
 | 
				
			||||||
            NoiEnv => self.write_msb(NOISE_LEN_ENV),
 | 
					            NoiEnv => {
 | 
				
			||||||
 | 
					                self.next_byte();
 | 
				
			||||||
 | 
					            } //self.write_msb(NOISE_LEN_ENV),
 | 
				
			||||||
            NoiWave => self.write_lsb(NOISE_FREQ),
 | 
					            NoiWave => self.write_lsb(NOISE_FREQ),
 | 
				
			||||||
            NoiTrig => self.write_msb(NOISE_FREQ),
 | 
					            NoiTrig => self.write_msb(NOISE_FREQ),
 | 
				
			||||||
            ChannelVolume => self.write_lsb(LEFT_RIGHT_VOLUME),
 | 
					            ChannelVolume => self.write_lsb(LEFT_RIGHT_VOLUME),
 | 
				
			||||||
            Pan => self.write_msb(LEFT_RIGHT_VOLUME),
 | 
					            Pan => self.write_msb(LEFT_RIGHT_VOLUME),
 | 
				
			||||||
            SoundOffOn => unsafe { SOUND_ENABLED.cast() }.write(self.next_byte()),
 | 
					            SoundOffOn => unsafe { SOUND_ENABLED.cast() }.write(self.next_byte()),
 | 
				
			||||||
            WavePattern0 => todo!(),
 | 
					            WavePattern0 | WavePattern1 | WavePattern2 | WavePattern3 | WavePattern4
 | 
				
			||||||
            WavePattern1 => todo!(),
 | 
					            | WavePattern5 | WavePattern6 | WavePattern7 | WavePattern8 | WavePattern9
 | 
				
			||||||
            WavePattern2 => todo!(),
 | 
					            | WavePatternA | WavePatternB | WavePatternC | WavePatternD | WavePatternE
 | 
				
			||||||
            WavePattern3 => todo!(),
 | 
					            | WavePatternF => {
 | 
				
			||||||
            WavePattern4 => todo!(),
 | 
					                let which = cmd as u8 as usize & 0xF;
 | 
				
			||||||
            WavePattern5 => todo!(),
 | 
					                unsafe {
 | 
				
			||||||
            WavePattern6 => todo!(),
 | 
					                    ((0x04000090 + which) as *mut u8).write_volatile(self.next_byte());
 | 
				
			||||||
            WavePattern7 => todo!(),
 | 
					                }
 | 
				
			||||||
            WavePattern8 => todo!(),
 | 
					            }
 | 
				
			||||||
            WavePattern9 => todo!(),
 | 
					 | 
				
			||||||
            WavePatternA => todo!(),
 | 
					 | 
				
			||||||
            WavePatternB => todo!(),
 | 
					 | 
				
			||||||
            WavePatternC => todo!(),
 | 
					 | 
				
			||||||
            WavePatternD => todo!(),
 | 
					 | 
				
			||||||
            WavePatternE => todo!(),
 | 
					 | 
				
			||||||
            WavePatternF => todo!(),
 | 
					 | 
				
			||||||
            _Invalid0B | _Invalid0C | _Invalid0D | _Invalid0E | _Invalid0F | _Invalid15
 | 
					            _Invalid0B | _Invalid0C | _Invalid0D | _Invalid0E | _Invalid0F | _Invalid15
 | 
				
			||||||
            | _Invalid1F | _Invalid27 | _Invalid28 | _Invalid29 | _Invalid2A | _Invalid2B
 | 
					            | _Invalid1F | _Invalid27 | _Invalid28 | _Invalid29 | _Invalid2A | _Invalid2B
 | 
				
			||||||
            | _Invalid2C | _Invalid2D | _Invalid2E | _Invalid2F => unimplemented!(),
 | 
					            | _Invalid2C | _Invalid2D | _Invalid2E | _Invalid2F => {
 | 
				
			||||||
 | 
					                unimplemented!("Invalid command: {:x}", cmd as u8)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        true
 | 
					        true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue