Support for effect Bxx (looping)
parent
db302a7f7e
commit
33b16767db
|
@ -3,7 +3,7 @@ use convert_case::{Case, Casing};
|
||||||
use samplerate::convert;
|
use samplerate::convert;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::reskit::{soundtrack::{formats::dmf::{DmfModule, ECHO_EWF_SAMPLE_RATE}, types::{InstrumentType, SampleFormat, Channel, PatternRow}}, utility::{print_warning, Ring}};
|
use crate::reskit::{soundtrack::{formats::dmf::{DmfModule, ECHO_EWF_SAMPLE_RATE}, types::{InstrumentType, SampleFormat, Channel, PatternRow}}, utility::{print_warning, Ring}};
|
||||||
use super::engine::{EchoFormat, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_FM_6, ESF_PSG_1, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, EchoEvent, get_events_for_row, compact_delays};
|
use super::engine::{EchoFormat, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_FM_6, ESF_PSG_1, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, EchoEvent, get_events_for_row, compact_delays, ESF_SET_LOOP, ESF_GO_TO_LOOP, ESF_STOP};
|
||||||
|
|
||||||
|
|
||||||
impl EchoFormat for DmfModule {
|
impl EchoFormat for DmfModule {
|
||||||
|
@ -332,10 +332,16 @@ impl EchoFormat for DmfModule {
|
||||||
self.instruments.len() as u8
|
self.instruments.len() as u8
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Is this the pattern matrix row that we repeat to?
|
||||||
|
// If so, insert an ESF_LOOP_SET here.
|
||||||
|
if let Some( repeat_row ) = self.loop_at {
|
||||||
|
if row_number == repeat_row {
|
||||||
|
all_events.push( vec![ ESF_SET_LOOP ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Transfer ESF events to the main stream
|
// Transfer ESF events to the main stream
|
||||||
all_events.extend( events_this_row );
|
all_events.extend( events_this_row );
|
||||||
|
|
||||||
// Any jumps?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compact sequences of delays to save rom space
|
// Compact sequences of delays to save rom space
|
||||||
|
@ -344,7 +350,7 @@ impl EchoFormat for DmfModule {
|
||||||
esf.extend( event );
|
esf.extend( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
esf.push( 0xFF ); // Terminate the stream
|
esf.push( if let None = self.loop_at { ESF_STOP } else { ESF_GO_TO_LOOP } ); // Terminate the stream
|
||||||
|
|
||||||
Ok( esf )
|
Ok( esf )
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,10 @@ const ESF_SET_FM_DIRECT_0: u8 = 0xF8;
|
||||||
const ESF_SET_FM_DIRECT_1: u8 = 0xF9;
|
const ESF_SET_FM_DIRECT_1: u8 = 0xF9;
|
||||||
const ESF_SET_FLAGS: u8 = 0xFA;
|
const ESF_SET_FLAGS: u8 = 0xFA;
|
||||||
const ESF_CLEAR_FLAGS: u8 = 0xFB;
|
const ESF_CLEAR_FLAGS: u8 = 0xFB;
|
||||||
const ESF_GOTO: u8 = 0xFC;
|
pub const ESF_GO_TO_LOOP: u8 = 0xFC;
|
||||||
const ESF_LOOP_SET: u8 = 0xFD;
|
pub const ESF_SET_LOOP: u8 = 0xFD;
|
||||||
const ESF_DELAY_LONG: u8 = 0xFE;
|
const ESF_DELAY_LONG: u8 = 0xFE;
|
||||||
const ESF_STOP: u8 = 0xFF;
|
pub const ESF_STOP: u8 = 0xFF;
|
||||||
|
|
||||||
pub const ESF_FM_1: u8 = 0x00;
|
pub const ESF_FM_1: u8 = 0x00;
|
||||||
pub const ESF_FM_2: u8 = 0x01;
|
pub const ESF_FM_2: u8 = 0x01;
|
||||||
|
@ -537,6 +537,9 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
|
||||||
print_warning( "Effect:DcsgNoiseMode can only be applied to SN4. ignoring..." );
|
print_warning( "Effect:DcsgNoiseMode can only be applied to SN4. ignoring..." );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Effect::PositionJump { pattern: _ } => {
|
||||||
|
// Nothing to do - handled as we iterate through the rows.
|
||||||
|
},
|
||||||
unsupported_effect => print_warning( &format!( "effect unsupported: {:?}. your soundtrack may sound different than expected.", unsupported_effect ) )
|
unsupported_effect => print_warning( &format!( "effect unsupported: {:?}. your soundtrack may sound different than expected.", unsupported_effect ) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ pub struct DmfModule {
|
||||||
frame_mode: FrameMode,
|
frame_mode: FrameMode,
|
||||||
pub rows_per_pattern: u32,
|
pub rows_per_pattern: u32,
|
||||||
pattern_matrix: Vec<Vec<u16>>,
|
pattern_matrix: Vec<Vec<u16>>,
|
||||||
|
pub loop_at: Option<u32>,
|
||||||
pub channel_patterns: Vec<Vec<PatternRow>>,
|
pub channel_patterns: Vec<Vec<PatternRow>>,
|
||||||
pub instruments: Vec<Instrument>,
|
pub instruments: Vec<Instrument>,
|
||||||
pub samples: Vec<Sample>
|
pub samples: Vec<Sample>
|
||||||
|
@ -449,6 +450,7 @@ impl DmfModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
// (channel, patterns)
|
// (channel, patterns)
|
||||||
|
let mut loop_at: Option<u32> = None;
|
||||||
let mut channel_patterns: Vec<Vec<PatternRow>> = Vec::new();
|
let mut channel_patterns: Vec<Vec<PatternRow>> = Vec::new();
|
||||||
for channel in 0..system_total_channels {
|
for channel in 0..system_total_channels {
|
||||||
let mut channel_rows: Vec<PatternRow> = Vec::new();
|
let mut channel_rows: Vec<PatternRow> = Vec::new();
|
||||||
|
@ -527,6 +529,10 @@ impl DmfModule {
|
||||||
DMF_EFFECT_POSITION_JUMP => {
|
DMF_EFFECT_POSITION_JUMP => {
|
||||||
let pattern = effect_value.ok_or( "invalid file: expected effect value for position jump" )?;
|
let pattern = effect_value.ok_or( "invalid file: expected effect value for position jump" )?;
|
||||||
|
|
||||||
|
if let None = loop_at {
|
||||||
|
loop_at = Some( pattern as u32 * rows_per_pattern );
|
||||||
|
}
|
||||||
|
|
||||||
Effect::PositionJump { pattern }
|
Effect::PositionJump { pattern }
|
||||||
},
|
},
|
||||||
DMF_EFFECT_PATTERN_BREAK => {
|
DMF_EFFECT_PATTERN_BREAK => {
|
||||||
|
@ -659,7 +665,7 @@ impl DmfModule {
|
||||||
Ok(
|
Ok(
|
||||||
DmfModule {
|
DmfModule {
|
||||||
path: path.to_string(), platform, version, time_base, speed_a, speed_b, frame_mode, rows_per_pattern,
|
path: path.to_string(), platform, version, time_base, speed_a, speed_b, frame_mode, rows_per_pattern,
|
||||||
pattern_matrix, channel_patterns, instruments, samples
|
pattern_matrix, loop_at, channel_patterns, instruments, samples
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue