ittech/data/envelope.rs
1use super::*;
2
3
4#[derive(Clone, Debug)]
5pub struct Envelope {
6    /// Envelope Flags
7    pub flags: EnvelopeFlags,
8
9    pub envelope_loop: Option<EnvelopeLoop>,
10
11    pub sustain_loop: Option<EnvelopeLoop>,
12
13    /// Envelope Node Positions / Values
14    pub nodes: Vec<Node>,
15}
16
17bitflags! {
18    pub struct EnvelopeFlags: u8 {
19        /// Envelope on/off, 1 = on, 0 = off
20        const ENABLED = 1 << 0;
21
22        /// Loop on/off, 1 = on, 0 = off
23        const LOOP = 1 << 1;
24
25        /// SusLoop on/off, 1 = on, 0 = off
26        const SUSTAIN = 1 << 2;
27
28        // These are not mentioned in ITTECH.TXT and there are no comment in OpenMPT, documentation
29        // here is just our assumption.
30        //
31        // We assume CARRY is for the carry button in Instrument configuration in OpenMPT.
32        const CARRY = 1 << 3;
33        // Filter is probably only useful on a pitch envelope and makes it act like a filter
34        // envelope instead.
35        const FILTER = 1 << 7;
36    }
37}
38
39#[derive(Clone, Copy, Debug)]
40pub struct Node {
41    pub value: i8,
42    pub tick: u16,
43}
44
45// TODO Is the loop an inclusive "interval"? That is, is the node marked as `end` used in the loop?
46//      Our guess would be yes, but check with OpenMPT code or interface first.
47#[derive(Clone, Copy, Debug)]
48pub struct EnvelopeLoop {
49    /// Start - offset of the node
50    pub start: u8,
51
52    /// End - offset of the node
53    ///
54    /// Must be always `>= start`
55    pub end: u8,
56}