1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
//
// msc
//  L Command
//  L Script
//  L MscsbFile
//

#[macro_use] extern crate nom;
extern crate byteorder;

mod mscb_file;
pub use mscb_file::MscsbFile;

#[derive(Debug, Copy, Clone)]
pub enum Cmd {
    Nop, // 0
    Unk1, // 1
    Begin {
        arg_count: u16,
        var_count: u16
    }, // 2
    End, // 3
    Jump {
        loc: u32
    }, // 4
    Jump5 {
        loc: u32
    }, // 5
    Return6, // 6
    Return7, // 7
    Return8, // 8
    Return9, // 9
    PushInt {
        val: u32,
    }, // 0xA
    PushVar {
        var_type: u8,
        var_num: u16,
    }, // 0xB
    ErrorC,
    PushShort {
        val: u16
    }, // 0xD
    AddI, // 0xE
    SubI, // 0xF
    MultI,// 0x10
    DivI, // 0x11
    ModI, // 0x12
    NegI, // 0x13
    IncI {
        var_type: u8,
        var_num: u16,
    }, // 0x14
    DecI{
        var_type: u8,
        var_num: u16,
    }, // 0x15
    AndI, // 0x16
    OrI,  // 0x17
    NotI, // 0x18
    XorI, // 0x19
    ShiftL,//0x1A
    ShiftR,//0x1B
    SetVar {
        var_type: u8,
        var_num: u16,
    },   //0x1C
    AddVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x1D
    SubVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x1E
    MultVarBy{
        var_type: u8,
        var_num: u16,
    },//0x1F
    DivVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x20
    ModVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x21
    AndVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x22
    OrVarBy{
        var_type: u8,
        var_num: u16,
    },  //0x23
    XorVarBy{
        var_type: u8,
        var_num: u16,
    }, //0x24
    Equals,    // 0x25
    NotEquals, // 0x26
    LessThan,  // 0x27
    LessOrEqual,//0x28
    Greater,   // 0x29
    GreaterOrEqual,//0x2A
    Not,           // 0x2B
    PrintF {
        arg_count: u8
    },    // 0x2C
    Sys {
        arg_count: u8,
        sys_num: u8,
    },   // 0x2D
    Try {
        loc: u32,
    },      // 0x2E
    CallFunc {
        arg_count: u8,
    },  // 0x2F
    CallFunc2 {
        arg_count: u8,
    }, // 0x2F
    CallFunc3 {
        arg_count: u8,
    }, // 0x2F
    Push,    // 0x32
    Pop,     // 0x33
    If {
        loc: u32,
    },   // 0x34
    IfNot {
        loc: u32,
    },// 0x35
    Else {
        loc: u32,
    }, // 0x36
    Error37, // 0x37
    IntToFloat {
        stack_pos: u8,
    }, // 0x38
    FloatToInt {
        stack_pos: u8,
    }, // 0x39
    AddF, // 0x3A
    SubF, // 0x3B
    MultF,// 0x3C
    DivF, // 0x3D
    NegF, // 0x3E
    IncF{
        var_type: u8,
        var_num: u16,
    }, // 0x3F
    DecF{
        var_type: u8,
        var_num: u16,
    }, // 0x40
    VarSetF{
        var_type: u8,
        var_num: u16,
    }, // 0x41
    AddVarByF{
        var_type: u8,
        var_num: u16,
    }, //0x42
    SubVarByF{
        var_type: u8,
        var_num: u16,
    }, //0x43
    MultVarByF{
        var_type: u8,
        var_num: u16,
    },//0x44
    DivVarByF{
        var_type: u8,
        var_num: u16,
    }, //0x45
    EqualsF,    // 0x46
    NotEqualsF, // 0x47
    LessThanF,  // 0x48
    LessOrEqualF,//0x49
    GreaterF,   // 0x4A
    GreaterOrEqualF,//0x4B
    Error4C, // 0x4C
    Exit, // 0x4D
}

#[derive(Debug, Clone)]
pub struct Command {
    pub cmd: Cmd,
    pub push_bit: bool,
    pub position: u32,
}

#[derive(Debug, Clone)]
pub struct Script {
    pub commands: Vec<Command>,
    pub bounds: (u32, u32),
}

impl Script {
    pub fn iter(&self) -> std::slice::Iter<Command> {
        self.commands.iter()
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_parser() {
        let pikachu = MscsbFile::open("/home/jam/dev/msc/pikachu.mscsb").unwrap();
        println!("# of scripts - {}", pikachu.scripts.len());
        println!("Script 1\n--------");
        for c in pikachu.scripts[0].iter() {
            println!("{:?}", c);
        }
    }
}