Mercurial > touhou
annotate formats/src/th06/msg.rs @ 782:a30ce01b9154
formats: Rewrite msg parsing in Rust
| author | Link Mauve <linkmauve@linkmauve.fr> |
|---|---|
| date | Thu, 20 Nov 2025 19:02:19 +0100 |
| parents | |
| children |
| rev | line source |
|---|---|
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
1 //! MSG format support. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
3 use encoding_rs::SHIFT_JIS; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
4 use nom::{ |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 multi::length_count, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
6 number::complete::{le_u16, le_u32, le_u8}, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
7 IResult, Parser, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
8 }; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
9 use std::collections::BTreeMap; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
10 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
11 /// Parse a SHIFT_JIS byte string of length 34 into a String. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
12 #[allow(non_snake_case)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
13 pub fn le_String(i: &[u8]) -> IResult<&[u8], String> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
14 let data = i.splitn(2, |c| *c == b'\0').nth(0).unwrap(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
15 let (string, _encoding, _replaced) = SHIFT_JIS.decode(data); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
16 Ok((b"", string.into_owned())) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
17 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
18 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
19 /// A single instruction, part of a `Script`. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
20 #[derive(Debug, Clone)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
21 pub struct Call { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
22 /// Time at which this instruction will be called. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
23 pub time: u16, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
24 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
25 /// The instruction to call. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
26 pub instr: Instruction, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
27 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
28 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
29 /// Main struct of the MSG format. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
30 #[derive(Debug, Clone)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
31 pub struct Msg { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
32 /// Map of indices to scripts in this msg. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
33 pub scripts: BTreeMap<u8, Vec<Call>>, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
34 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
35 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
36 impl Msg { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
37 /// Parse a slice of bytes into a `Msg` struct. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
38 pub fn from_slice(data: &[u8]) -> IResult<&[u8], Msg> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
39 parse_msg.parse(data) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
40 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
41 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
42 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
43 macro_rules! gen_match { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
44 ($arg_type:ident) => { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
45 ${concat(le_, $arg_type)} |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
46 }; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
47 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
48 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
49 macro_rules! declare_msg_instructions { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
50 ($($opcode:tt => fn $name:ident($($arg:ident: $arg_type:ident),*)),*,) => { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
51 /// Available instructions in a `Msg`. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
52 #[allow(missing_docs)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
53 #[derive(Debug, Clone, PartialEq)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
54 pub enum Instruction { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
55 $( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
56 $name($($arg_type),*) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
57 ),* |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
58 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
59 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
60 fn parse_instruction_args(mut i: &[u8], opcode: u8) -> IResult<&[u8], Instruction> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
61 let instr = match opcode { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
62 $( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
63 $opcode => { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
64 $( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
65 let (i2, $arg) = gen_match!($arg_type)(i)?; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
66 i = i2; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
67 )* |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
68 Instruction::$name($($arg),*) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
69 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
70 )* |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
71 // XXX: use a more specific error instead. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
72 _ => return Err(nom::Err::Failure(nom::error::Error::new(i, nom::error::ErrorKind::Eof))) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
73 }; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
74 Ok((i, instr)) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
75 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
76 }; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
77 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
78 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
79 declare_msg_instructions! { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
80 0 => fn Unk1(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
81 1 => fn Enter(side: u16, effect: u16), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
82 2 => fn ChangeFace(side: u16, index: u16), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
83 3 => fn DisplayText(side: u16, index: u16, text: String), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
84 4 => fn Pause(duration: u32), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
85 5 => fn Animate(side: u16, effect: u16), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
86 6 => fn SpawnEnemySprite(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
87 7 => fn ChangeMusic(track: u32), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
88 8 => fn DisplayDescription(side: u16, index: u16, text: String), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
89 9 => fn ShowScores(unk1: u32), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
90 10 => fn Freeze(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
91 11 => fn NextStage(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
92 12 => fn Unk2(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
93 13 => fn SetAllowSkip(boolean: u32), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
94 14 => fn Unk3(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
95 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
96 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
97 fn parse_msg(input: &[u8]) -> IResult<&[u8], Msg> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
98 let (mut i, entry_offsets) = length_count(le_u32, le_u32).parse(input)?; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
99 let first_offset = entry_offsets[0]; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
100 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
101 let mut scripts = BTreeMap::new(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
102 for (index, offset) in entry_offsets |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
103 .into_iter() |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
104 .enumerate() |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
105 .map(|(index, offset)| (index as u8, offset)) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
106 { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
107 if input.len() < offset as usize { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
108 return Err(nom::Err::Failure(nom::error::Error::new( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
109 input, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
110 nom::error::ErrorKind::Eof, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
111 ))); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
112 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
113 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
114 // In EoSD, Reimu’s scripts start at 0, and Marisa’s ones at 10. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
115 // If Reimu has less than 10 scripts, the remaining offsets are equal to her first. |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
116 if index > 0 && offset == first_offset { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
117 continue; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
118 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
119 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
120 i = &input[offset as usize..]; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
121 let mut instructions = Vec::new(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
122 loop { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
123 let (i2, (time, opcode, size)) = (le_u16, le_u8, le_u8).parse(i)?; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
124 if time == 0 && opcode == 0 && size == 0 { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
125 break; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
126 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
127 let (i2, data) = (&i2[size as usize..], &i2[..size as usize]); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
128 let (empty, instr) = parse_instruction_args(data, opcode)?; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
129 assert!(empty.is_empty()); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
130 instructions.push(Call { time, instr }); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
131 i = i2; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
132 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
133 scripts.insert(index, instructions); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
134 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
135 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
136 Ok((i, Msg { scripts })) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
137 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
138 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
139 #[cfg(test)] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
140 mod tests { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
141 use super::*; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
142 use std::fs::File; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
143 use std::io::{self, Read}; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
144 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
145 #[test] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
146 fn msg() { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
147 println!("{}", std::env::current_dir().unwrap().display()); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
148 let file = File::open("EoSD/ST/msg1.dat").unwrap(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
149 let mut file = io::BufReader::new(file); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
150 let mut buf = Vec::new(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
151 file.read_to_end(&mut buf).unwrap(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
152 let (_, msg) = Msg::from_slice(&buf).unwrap(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
153 assert_eq!(msg.scripts.len(), 4); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
154 assert_eq!(msg.scripts[&0].len(), 89); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
155 assert_eq!(msg.scripts[&1].len(), 13); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
156 assert_eq!(msg.scripts[&10].len(), 58); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
157 assert_eq!(msg.scripts[&11].len(), 13); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
158 let script = &msg.scripts[&0]; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
159 assert_eq!(script[3].time, 60); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
160 assert_eq!( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
161 script[3].instr, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
162 Instruction::DisplayText(0, 0, String::from("久々のお仕事だわ。")) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
163 ); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
164 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
165 } |
