1use crate::ext::io::*;
3use crate::scripts::base::*;
4use crate::types::*;
5use crate::utils::lossless_audio::*;
6use crate::utils::pcm::*;
7use crate::utils::struct_pack::*;
8use anyhow::Result;
9use int_enum::IntEnum;
10use msg_tool_macro::*;
11use overf::wrapping;
12use std::io::{Read, Seek, Write};
13
14#[derive(Debug)]
15pub struct PcmBuilder {}
17
18impl PcmBuilder {
19 pub fn new() -> Self {
21 Self {}
22 }
23}
24
25impl ScriptBuilder for PcmBuilder {
26 fn default_encoding(&self) -> Encoding {
27 Encoding::Utf8
28 }
29
30 fn build_script(
31 &self,
32 buf: Vec<u8>,
33 _filename: &str,
34 _encoding: Encoding,
35 _archive_encoding: Encoding,
36 config: &ExtraConfig,
37 _archive: Option<&Box<dyn Script>>,
38 ) -> Result<Box<dyn Script>> {
39 Ok(Box::new(Pcm::new(MemReader::new(buf), config)?))
40 }
41
42 fn build_script_from_file(
43 &self,
44 filename: &str,
45 _encoding: Encoding,
46 _archive_encoding: Encoding,
47 config: &ExtraConfig,
48 _archive: Option<&Box<dyn Script>>,
49 ) -> Result<Box<dyn Script>> {
50 let file = std::fs::File::open(filename)?;
51 let f = std::io::BufReader::new(file);
52 Ok(Box::new(Pcm::new(f, config)?))
53 }
54
55 fn build_script_from_reader(
56 &self,
57 reader: Box<dyn ReadSeek>,
58 _filename: &str,
59 _encoding: Encoding,
60 _archive_encoding: Encoding,
61 config: &ExtraConfig,
62 _archive: Option<&Box<dyn Script>>,
63 ) -> Result<Box<dyn Script>> {
64 Ok(Box::new(Pcm::new(reader, config)?))
65 }
66
67 fn extensions(&self) -> &'static [&'static str] {
68 &["pcm"]
69 }
70
71 fn script_type(&self) -> &'static ScriptType {
72 &ScriptType::CircusPcm
73 }
74
75 fn is_this_format(&self, _filename: &str, buf: &[u8], buf_len: usize) -> Option<u8> {
76 if buf_len >= 4 && buf.starts_with(b"XPCM") {
77 Some(10)
78 } else {
79 None
80 }
81 }
82}
83
84#[derive(Debug, IntEnum)]
85#[repr(u32)]
86enum Mode {
87 Raw = 0,
88 Lzss = 1,
89 Adpcm = 2,
90 Zlib = 3,
91 Ogg = 5,
92}
93
94#[derive(Debug, StructPack, StructUnpack)]
95struct Header {
96 src_size: u32,
97 _mode: u32,
98 #[skip_pack_if(self.mode() != 5)]
99 #[skip_unpack_if((_mode & 0xFF) != 5)]
100 ogg_size: u32,
101 #[skip_pack_if(self.mode() == 5)]
102 #[skip_unpack_if((_mode & 0xFF) == 5)]
103 pcm: Option<PcmFormat>,
104}
105
106impl Header {
107 pub fn mode(&self) -> u32 {
108 self._mode & 0xFF
109 }
110
111 pub fn extra(&self) -> u32 {
112 (self._mode >> 8) & 0xFF
113 }
114}
115
116#[derive(Debug)]
117pub struct Pcm {
119 header: Header,
120 data: MemReader,
121 config: ExtraConfig,
122}
123
124impl Pcm {
125 pub fn new<R: Read + Seek>(mut reader: R, config: &ExtraConfig) -> Result<Self> {
130 let mut magic = [0u8; 4];
131 reader.read_exact(&mut magic)?;
132 if &magic != b"XPCM" {
133 return Err(anyhow::anyhow!("Invalid PCM header magic: {:?}", magic));
134 }
135 let header = Header::unpack(&mut reader, false, Encoding::Utf8)?;
136 let mode = Mode::try_from(header.mode())
137 .map_err(|_| anyhow::anyhow!("Unsupported PCM mode: {}", header.mode()))?;
138 let data = match mode {
139 Mode::Ogg => {
140 if header.ogg_size == 0 {
141 return Err(anyhow::anyhow!("Invalid OGG size in PCM header"));
142 }
143 let mut data = vec![0u8; header.ogg_size as usize];
144 reader.read_exact(&mut data)?;
145 data
146 }
147 Mode::Raw => {
148 let mut data = vec![0u8; header.src_size as usize];
149 reader.read_exact(&mut data)?;
150 data
151 }
152 Mode::Adpcm => Self::decode_adpcm(&mut reader, header.src_size as usize)?,
153 _ => {
154 PcmDecoder::new(reader, header.src_size as usize, header.extra(), mode)?.unpack()?
155 }
156 };
157 Ok(Self {
158 header,
159 data: MemReader::new(data),
160 config: config.clone(),
161 })
162 }
163
164 fn decode_adpcm<R: Read + Seek>(mut input: R, pcm_size: usize) -> Result<Vec<u8>> {
165 let input_len = input.stream_length()? - input.stream_position()?;
166 let mut output = Vec::with_capacity(pcm_size);
167 let mut table = [0u32; 6];
168 let mut channel = 0;
169 let mut src = 0;
170 let mut dst = 0;
171 while src < input_len && dst < pcm_size as u32 {
172 let data = input.read_i8()?;
173 src += 1;
174 table[channel * 3] =
175 table[channel * 3].wrapping_add((data as u32) << (table[channel * 3 + 1] & 0xFF));
176 if data == 0 {
177 if table[channel * 3 + 1] != 0 {
178 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_sub(1);
179 }
180 } else if data == 0x7F || data == -0x80 {
181 if table[channel * 3 + 1] != 8 {
182 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_add(1);
183 }
184 }
185 output.push(table[channel * 3] as u8);
186 output.push((table[channel * 3] >> 8) as u8);
187 channel = 1 - channel;
188 dst += 2;
189 }
190 Ok(output)
191 }
192}
193
194impl Script for Pcm {
195 fn default_output_script_type(&self) -> OutputScriptType {
196 OutputScriptType::Custom
197 }
198
199 fn default_format_type(&self) -> FormatOptions {
200 FormatOptions::None
201 }
202
203 fn is_output_supported(&self, output: OutputScriptType) -> bool {
204 matches!(output, OutputScriptType::Custom)
205 }
206
207 fn custom_output_extension<'a>(&'a self) -> &'a str {
208 if self.header.mode() == 5 {
209 "ogg"
210 } else {
211 self.config.lossless_audio_fmt.as_ref()
212 }
213 }
214
215 fn custom_export(&self, filename: &std::path::Path, _encoding: Encoding) -> Result<()> {
216 let mut writer = std::fs::File::create(filename)?;
217 if self.header.mode() == 5 {
218 writer.write_all(&self.data.data)?;
219 } else {
220 let fmt = self
221 .header
222 .pcm
223 .as_ref()
224 .ok_or_else(|| anyhow::anyhow!("PCM format not found in header"))?;
225 write_audio(fmt, self.data.to_ref(), writer, &self.config)?;
226 }
227 Ok(())
228 }
229}
230
231const UNK_43A254: [u8; 320] = [
232 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
233 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
234 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
235 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
236 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
237 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
238 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
239 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
240 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
241 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
242 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
243 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
244 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
245 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
246 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
247 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
248 0x55, 0x05, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00,
249 0xAA, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
250 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
251 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
252];
253const DWORD_43A358: [i32; 2048] = [
254 0x1000, 0x0000, 0x0FFF, 0x0006, 0x0FFF, 0x000C, 0x0FFF, 0x0012, 0x0FFF, 0x0019, 0x0FFF, 0x001F,
255 0x0FFF, 0x0025, 0x0FFF, 0x002B, 0x0FFF, 0x0032, 0x0FFF, 0x0038, 0x0FFF, 0x003E, 0x0FFF, 0x0045,
256 0x0FFF, 0x004B, 0x0FFF, 0x0051, 0x0FFF, 0x0057, 0x0FFE, 0x005E, 0x0FFE, 0x0064, 0x0FFE, 0x006A,
257 0x0FFE, 0x0071, 0x0FFE, 0x0077, 0x0FFE, 0x007D, 0x0FFD, 0x0083, 0x0FFD, 0x008A, 0x0FFD, 0x0090,
258 0x0FFD, 0x0096, 0x0FFC, 0x009D, 0x0FFC, 0x00A3, 0x0FFC, 0x00A9, 0x0FFC, 0x00AF, 0x0FFB, 0x00B6,
259 0x0FFB, 0x00BC, 0x0FFB, 0x00C2, 0x0FFB, 0x00C8, 0x0FFA, 0x00CF, 0x0FFA, 0x00D5, 0x0FFA, 0x00DB,
260 0x0FF9, 0x00E2, 0x0FF9, 0x00E8, 0x0FF9, 0x00EE, 0x0FF8, 0x00F4, 0x0FF8, 0x00FB, 0x0FF7, 0x0101,
261 0x0FF7, 0x0107, 0x0FF7, 0x010D, 0x0FF6, 0x0114, 0x0FF6, 0x011A, 0x0FF5, 0x0120, 0x0FF5, 0x0127,
262 0x0FF4, 0x012D, 0x0FF4, 0x0133, 0x0FF3, 0x0139, 0x0FF3, 0x0140, 0x0FF2, 0x0146, 0x0FF2, 0x014C,
263 0x0FF1, 0x0152, 0x0FF1, 0x0159, 0x0FF0, 0x015F, 0x0FF0, 0x0165, 0x0FEF, 0x016B, 0x0FEF, 0x0172,
264 0x0FEE, 0x0178, 0x0FEE, 0x017E, 0x0FED, 0x0184, 0x0FEC, 0x018B, 0x0FEC, 0x0191, 0x0FEB, 0x0197,
265 0x0FEB, 0x019D, 0x0FEA, 0x01A4, 0x0FE9, 0x01AA, 0x0FE9, 0x01B0, 0x0FE8, 0x01B6, 0x0FE7, 0x01BD,
266 0x0FE7, 0x01C3, 0x0FE6, 0x01C9, 0x0FE5, 0x01CF, 0x0FE4, 0x01D6, 0x0FE4, 0x01DC, 0x0FE3, 0x01E2,
267 0x0FE2, 0x01E8, 0x0FE1, 0x01EF, 0x0FE1, 0x01F5, 0x0FE0, 0x01FB, 0x0FDF, 0x0201, 0x0FDE, 0x0208,
268 0x0FDE, 0x020E, 0x0FDD, 0x0214, 0x0FDC, 0x021A, 0x0FDB, 0x0221, 0x0FDA, 0x0227, 0x0FD9, 0x022D,
269 0x0FD9, 0x0233, 0x0FD8, 0x0239, 0x0FD7, 0x0240, 0x0FD6, 0x0246, 0x0FD5, 0x024C, 0x0FD4, 0x0252,
270 0x0FD3, 0x0259, 0x0FD2, 0x025F, 0x0FD1, 0x0265, 0x0FD0, 0x026B, 0x0FCF, 0x0271, 0x0FCE, 0x0278,
271 0x0FCD, 0x027E, 0x0FCC, 0x0284, 0x0FCB, 0x028A, 0x0FCA, 0x0290, 0x0FC9, 0x0297, 0x0FC8, 0x029D,
272 0x0FC7, 0x02A3, 0x0FC6, 0x02A9, 0x0FC5, 0x02AF, 0x0FC4, 0x02B6, 0x0FC3, 0x02BC, 0x0FC2, 0x02C2,
273 0x0FC1, 0x02C8, 0x0FC0, 0x02CE, 0x0FBF, 0x02D5, 0x0FBE, 0x02DB, 0x0FBD, 0x02E1, 0x0FBB, 0x02E7,
274 0x0FBA, 0x02ED, 0x0FB9, 0x02F3, 0x0FB8, 0x02FA, 0x0FB7, 0x0300, 0x0FB6, 0x0306, 0x0FB4, 0x030C,
275 0x0FB3, 0x0312, 0x0FB2, 0x0318, 0x0FB1, 0x031F, 0x0FB0, 0x0325, 0x0FAE, 0x032B, 0x0FAD, 0x0331,
276 0x0FAC, 0x0337, 0x0FAB, 0x033D, 0x0FA9, 0x0344, 0x0FA8, 0x034A, 0x0FA7, 0x0350, 0x0FA5, 0x0356,
277 0x0FA4, 0x035C, 0x0FA3, 0x0362, 0x0FA1, 0x0368, 0x0FA0, 0x036F, 0x0F9F, 0x0375, 0x0F9D, 0x037B,
278 0x0F9C, 0x0381, 0x0F9B, 0x0387, 0x0F99, 0x038D, 0x0F98, 0x0393, 0x0F96, 0x0399, 0x0F95, 0x03A0,
279 0x0F94, 0x03A6, 0x0F92, 0x03AC, 0x0F91, 0x03B2, 0x0F8F, 0x03B8, 0x0F8E, 0x03BE, 0x0F8C, 0x03C4,
280 0x0F8B, 0x03CA, 0x0F89, 0x03D0, 0x0F88, 0x03D7, 0x0F86, 0x03DD, 0x0F85, 0x03E3, 0x0F83, 0x03E9,
281 0x0F82, 0x03EF, 0x0F80, 0x03F5, 0x0F7F, 0x03FB, 0x0F7D, 0x0401, 0x0F7B, 0x0407, 0x0F7A, 0x040D,
282 0x0F78, 0x0413, 0x0F77, 0x041A, 0x0F75, 0x0420, 0x0F73, 0x0426, 0x0F72, 0x042C, 0x0F70, 0x0432,
283 0x0F6E, 0x0438, 0x0F6D, 0x043E, 0x0F6B, 0x0444, 0x0F69, 0x044A, 0x0F68, 0x0450, 0x0F66, 0x0456,
284 0x0F64, 0x045C, 0x0F63, 0x0462, 0x0F61, 0x0468, 0x0F5F, 0x046E, 0x0F5D, 0x0474, 0x0F5C, 0x047A,
285 0x0F5A, 0x0480, 0x0F58, 0x0486, 0x0F56, 0x048C, 0x0F55, 0x0492, 0x0F53, 0x0498, 0x0F51, 0x049E,
286 0x0F4F, 0x04A5, 0x0F4D, 0x04AB, 0x0F4B, 0x04B1, 0x0F4A, 0x04B7, 0x0F48, 0x04BD, 0x0F46, 0x04C3,
287 0x0F44, 0x04C9, 0x0F42, 0x04CF, 0x0F40, 0x04D5, 0x0F3E, 0x04DB, 0x0F3C, 0x04E0, 0x0F3B, 0x04E6,
288 0x0F39, 0x04EC, 0x0F37, 0x04F2, 0x0F35, 0x04F8, 0x0F33, 0x04FE, 0x0F31, 0x0504, 0x0F2F, 0x050A,
289 0x0F2D, 0x0510, 0x0F2B, 0x0516, 0x0F29, 0x051C, 0x0F27, 0x0522, 0x0F25, 0x0528, 0x0F23, 0x052E,
290 0x0F21, 0x0534, 0x0F1F, 0x053A, 0x0F1D, 0x0540, 0x0F1B, 0x0546, 0x0F18, 0x054C, 0x0F16, 0x0552,
291 0x0F14, 0x0558, 0x0F12, 0x055D, 0x0F10, 0x0563, 0x0F0E, 0x0569, 0x0F0C, 0x056F, 0x0F0A, 0x0575,
292 0x0F08, 0x057B, 0x0F05, 0x0581, 0x0F03, 0x0587, 0x0F01, 0x058D, 0x0EFF, 0x0593, 0x0EFD, 0x0599,
293 0x0EFA, 0x059E, 0x0EF8, 0x05A4, 0x0EF6, 0x05AA, 0x0EF4, 0x05B0, 0x0EF2, 0x05B6, 0x0EEF, 0x05BC,
294 0x0EED, 0x05C2, 0x0EEB, 0x05C7, 0x0EE8, 0x05CD, 0x0EE6, 0x05D3, 0x0EE4, 0x05D9, 0x0EE2, 0x05DF,
295 0x0EDF, 0x05E5, 0x0EDD, 0x05EB, 0x0EDB, 0x05F0, 0x0ED8, 0x05F6, 0x0ED6, 0x05FC, 0x0ED4, 0x0602,
296 0x0ED1, 0x0608, 0x0ECF, 0x060E, 0x0ECD, 0x0613, 0x0ECA, 0x0619, 0x0EC8, 0x061F, 0x0EC5, 0x0625,
297 0x0EC3, 0x062B, 0x0EC0, 0x0630, 0x0EBE, 0x0636, 0x0EBC, 0x063C, 0x0EB9, 0x0642, 0x0EB7, 0x0648,
298 0x0EB4, 0x064D, 0x0EB2, 0x0653, 0x0EAF, 0x0659, 0x0EAD, 0x065F, 0x0EAA, 0x0664, 0x0EA8, 0x066A,
299 0x0EA5, 0x0670, 0x0EA3, 0x0676, 0x0EA0, 0x067B, 0x0E9E, 0x0681, 0x0E9B, 0x0687, 0x0E98, 0x068D,
300 0x0E96, 0x0692, 0x0E93, 0x0698, 0x0E91, 0x069E, 0x0E8E, 0x06A3, 0x0E8B, 0x06A9, 0x0E89, 0x06AF,
301 0x0E86, 0x06B5, 0x0E84, 0x06BA, 0x0E81, 0x06C0, 0x0E7E, 0x06C6, 0x0E7C, 0x06CB, 0x0E79, 0x06D1,
302 0x0E76, 0x06D7, 0x0E74, 0x06DC, 0x0E71, 0x06E2, 0x0E6E, 0x06E8, 0x0E6B, 0x06ED, 0x0E69, 0x06F3,
303 0x0E66, 0x06F9, 0x0E63, 0x06FE, 0x0E60, 0x0704, 0x0E5E, 0x070A, 0x0E5B, 0x070F, 0x0E58, 0x0715,
304 0x0E55, 0x071B, 0x0E53, 0x0720, 0x0E50, 0x0726, 0x0E4D, 0x072B, 0x0E4A, 0x0731, 0x0E47, 0x0737,
305 0x0E44, 0x073C, 0x0E42, 0x0742, 0x0E3F, 0x0748, 0x0E3C, 0x074D, 0x0E39, 0x0753, 0x0E36, 0x0758,
306 0x0E33, 0x075E, 0x0E30, 0x0763, 0x0E2D, 0x0769, 0x0E2B, 0x076F, 0x0E28, 0x0774, 0x0E25, 0x077A,
307 0x0E22, 0x077F, 0x0E1F, 0x0785, 0x0E1C, 0x078A, 0x0E19, 0x0790, 0x0E16, 0x0795, 0x0E13, 0x079B,
308 0x0E10, 0x07A0, 0x0E0D, 0x07A6, 0x0E0A, 0x07AC, 0x0E07, 0x07B1, 0x0E04, 0x07B7, 0x0E01, 0x07BC,
309 0x0DFE, 0x07C2, 0x0DFB, 0x07C7, 0x0DF8, 0x07CD, 0x0DF5, 0x07D2, 0x0DF2, 0x07D7, 0x0DEE, 0x07DD,
310 0x0DEB, 0x07E2, 0x0DE8, 0x07E8, 0x0DE5, 0x07ED, 0x0DE2, 0x07F3, 0x0DDF, 0x07F8, 0x0DDC, 0x07FE,
311 0x0DD9, 0x0803, 0x0DD5, 0x0809, 0x0DD2, 0x080E, 0x0DCF, 0x0813, 0x0DCC, 0x0819, 0x0DC9, 0x081E,
312 0x0DC6, 0x0824, 0x0DC2, 0x0829, 0x0DBF, 0x082E, 0x0DBC, 0x0834, 0x0DB9, 0x0839, 0x0DB6, 0x083F,
313 0x0DB2, 0x0844, 0x0DAF, 0x0849, 0x0DAC, 0x084F, 0x0DA9, 0x0854, 0x0DA5, 0x085A, 0x0DA2, 0x085F,
314 0x0D9F, 0x0864, 0x0D9B, 0x086A, 0x0D98, 0x086F, 0x0D95, 0x0874, 0x0D91, 0x087A, 0x0D8E, 0x087F,
315 0x0D8B, 0x0884, 0x0D87, 0x088A, 0x0D84, 0x088F, 0x0D81, 0x0894, 0x0D7D, 0x0899, 0x0D7A, 0x089F,
316 0x0D77, 0x08A4, 0x0D73, 0x08A9, 0x0D70, 0x08AF, 0x0D6C, 0x08B4, 0x0D69, 0x08B9, 0x0D65, 0x08BE,
317 0x0D62, 0x08C4, 0x0D5F, 0x08C9, 0x0D5B, 0x08CE, 0x0D58, 0x08D3, 0x0D54, 0x08D9, 0x0D51, 0x08DE,
318 0x0D4D, 0x08E3, 0x0D4A, 0x08E8, 0x0D46, 0x08EE, 0x0D43, 0x08F3, 0x0D3F, 0x08F8, 0x0D3C, 0x08FD,
319 0x0D38, 0x0902, 0x0D35, 0x0908, 0x0D31, 0x090D, 0x0D2D, 0x0912, 0x0D2A, 0x0917, 0x0D26, 0x091C,
320 0x0D23, 0x0921, 0x0D1F, 0x0927, 0x0D1C, 0x092C, 0x0D18, 0x0931, 0x0D14, 0x0936, 0x0D11, 0x093B,
321 0x0D0D, 0x0940, 0x0D09, 0x0945, 0x0D06, 0x094B, 0x0D02, 0x0950, 0x0CFE, 0x0955, 0x0CFB, 0x095A,
322 0x0CF7, 0x095F, 0x0CF3, 0x0964, 0x0CF0, 0x0969, 0x0CEC, 0x096E, 0x0CE8, 0x0973, 0x0CE5, 0x0978,
323 0x0CE1, 0x097D, 0x0CDD, 0x0982, 0x0CD9, 0x0987, 0x0CD6, 0x098D, 0x0CD2, 0x0992, 0x0CCE, 0x0997,
324 0x0CCA, 0x099C, 0x0CC7, 0x09A1, 0x0CC3, 0x09A6, 0x0CBF, 0x09AB, 0x0CBB, 0x09B0, 0x0CB7, 0x09B5,
325 0x0CB4, 0x09BA, 0x0CB0, 0x09BF, 0x0CAC, 0x09C4, 0x0CA8, 0x09C9, 0x0CA4, 0x09CE, 0x0CA0, 0x09D3,
326 0x0C9D, 0x09D7, 0x0C99, 0x09DC, 0x0C95, 0x09E1, 0x0C91, 0x09E6, 0x0C8D, 0x09EB, 0x0C89, 0x09F0,
327 0x0C85, 0x09F5, 0x0C81, 0x09FA, 0x0C7D, 0x09FF, 0x0C79, 0x0A04, 0x0C76, 0x0A09, 0x0C72, 0x0A0E,
328 0x0C6E, 0x0A12, 0x0C6A, 0x0A17, 0x0C66, 0x0A1C, 0x0C62, 0x0A21, 0x0C5E, 0x0A26, 0x0C5A, 0x0A2B,
329 0x0C56, 0x0A30, 0x0C52, 0x0A35, 0x0C4E, 0x0A39, 0x0C4A, 0x0A3E, 0x0C46, 0x0A43, 0x0C42, 0x0A48,
330 0x0C3E, 0x0A4D, 0x0C3A, 0x0A51, 0x0C36, 0x0A56, 0x0C31, 0x0A5B, 0x0C2D, 0x0A60, 0x0C29, 0x0A65,
331 0x0C25, 0x0A69, 0x0C21, 0x0A6E, 0x0C1D, 0x0A73, 0x0C19, 0x0A78, 0x0C15, 0x0A7C, 0x0C11, 0x0A81,
332 0x0C0D, 0x0A86, 0x0C08, 0x0A8B, 0x0C04, 0x0A8F, 0x0C00, 0x0A94, 0x0BFC, 0x0A99, 0x0BF8, 0x0A9D,
333 0x0BF4, 0x0AA2, 0x0BEF, 0x0AA7, 0x0BEB, 0x0AAC, 0x0BE7, 0x0AB0, 0x0BE3, 0x0AB5, 0x0BDF, 0x0ABA,
334 0x0BDA, 0x0ABE, 0x0BD6, 0x0AC3, 0x0BD2, 0x0AC8, 0x0BCE, 0x0ACC, 0x0BCA, 0x0AD1, 0x0BC5, 0x0AD5,
335 0x0BC1, 0x0ADA, 0x0BBD, 0x0ADF, 0x0BB8, 0x0AE3, 0x0BB4, 0x0AE8, 0x0BB0, 0x0AEC, 0x0BAC, 0x0AF1,
336 0x0BA7, 0x0AF6, 0x0BA3, 0x0AFA, 0x0B9F, 0x0AFF, 0x0B9A, 0x0B03, 0x0B96, 0x0B08, 0x0B92, 0x0B0C,
337 0x0B8D, 0x0B11, 0x0B89, 0x0B15, 0x0B85, 0x0B1A, 0x0B80, 0x0B1F, 0x0B7C, 0x0B23, 0x0B78, 0x0B28,
338 0x0B73, 0x0B2C, 0x0B6F, 0x0B31, 0x0B6A, 0x0B35, 0x0B66, 0x0B3A, 0x0B62, 0x0B3E, 0x0B5D, 0x0B42,
339 0x0B59, 0x0B47, 0x0B54, 0x0B4B, 0x0B50, 0x0B50, 0x0B4B, 0x0B54, 0x0B47, 0x0B59, 0x0B42, 0x0B5D,
340 0x0B3E, 0x0B62, 0x0B3A, 0x0B66, 0x0B35, 0x0B6A, 0x0B31, 0x0B6F, 0x0B2C, 0x0B73, 0x0B28, 0x0B78,
341 0x0B23, 0x0B7C, 0x0B1F, 0x0B80, 0x0B1A, 0x0B85, 0x0B15, 0x0B89, 0x0B11, 0x0B8D, 0x0B0C, 0x0B92,
342 0x0B08, 0x0B96, 0x0B03, 0x0B9A, 0x0AFF, 0x0B9F, 0x0AFA, 0x0BA3, 0x0AF6, 0x0BA7, 0x0AF1, 0x0BAC,
343 0x0AEC, 0x0BB0, 0x0AE8, 0x0BB4, 0x0AE3, 0x0BB8, 0x0ADF, 0x0BBD, 0x0ADA, 0x0BC1, 0x0AD5, 0x0BC5,
344 0x0AD1, 0x0BCA, 0x0ACC, 0x0BCE, 0x0AC8, 0x0BD2, 0x0AC3, 0x0BD6, 0x0ABE, 0x0BDA, 0x0ABA, 0x0BDF,
345 0x0AB5, 0x0BE3, 0x0AB0, 0x0BE7, 0x0AAC, 0x0BEB, 0x0AA7, 0x0BEF, 0x0AA2, 0x0BF4, 0x0A9D, 0x0BF8,
346 0x0A99, 0x0BFC, 0x0A94, 0x0C00, 0x0A8F, 0x0C04, 0x0A8B, 0x0C08, 0x0A86, 0x0C0D, 0x0A81, 0x0C11,
347 0x0A7C, 0x0C15, 0x0A78, 0x0C19, 0x0A73, 0x0C1D, 0x0A6E, 0x0C21, 0x0A69, 0x0C25, 0x0A65, 0x0C29,
348 0x0A60, 0x0C2D, 0x0A5B, 0x0C31, 0x0A56, 0x0C36, 0x0A51, 0x0C3A, 0x0A4D, 0x0C3E, 0x0A48, 0x0C42,
349 0x0A43, 0x0C46, 0x0A3E, 0x0C4A, 0x0A39, 0x0C4E, 0x0A35, 0x0C52, 0x0A30, 0x0C56, 0x0A2B, 0x0C5A,
350 0x0A26, 0x0C5E, 0x0A21, 0x0C62, 0x0A1C, 0x0C66, 0x0A17, 0x0C6A, 0x0A12, 0x0C6E, 0x0A0E, 0x0C72,
351 0x0A09, 0x0C76, 0x0A04, 0x0C79, 0x09FF, 0x0C7D, 0x09FA, 0x0C81, 0x09F5, 0x0C85, 0x09F0, 0x0C89,
352 0x09EB, 0x0C8D, 0x09E6, 0x0C91, 0x09E1, 0x0C95, 0x09DC, 0x0C99, 0x09D7, 0x0C9D, 0x09D3, 0x0CA0,
353 0x09CE, 0x0CA4, 0x09C9, 0x0CA8, 0x09C4, 0x0CAC, 0x09BF, 0x0CB0, 0x09BA, 0x0CB4, 0x09B5, 0x0CB7,
354 0x09B0, 0x0CBB, 0x09AB, 0x0CBF, 0x09A6, 0x0CC3, 0x09A1, 0x0CC7, 0x099C, 0x0CCA, 0x0997, 0x0CCE,
355 0x0992, 0x0CD2, 0x098D, 0x0CD6, 0x0987, 0x0CD9, 0x0982, 0x0CDD, 0x097D, 0x0CE1, 0x0978, 0x0CE5,
356 0x0973, 0x0CE8, 0x096E, 0x0CEC, 0x0969, 0x0CF0, 0x0964, 0x0CF3, 0x095F, 0x0CF7, 0x095A, 0x0CFB,
357 0x0955, 0x0CFE, 0x0950, 0x0D02, 0x094B, 0x0D06, 0x0945, 0x0D09, 0x0940, 0x0D0D, 0x093B, 0x0D11,
358 0x0936, 0x0D14, 0x0931, 0x0D18, 0x092C, 0x0D1C, 0x0927, 0x0D1F, 0x0921, 0x0D23, 0x091C, 0x0D26,
359 0x0917, 0x0D2A, 0x0912, 0x0D2D, 0x090D, 0x0D31, 0x0908, 0x0D35, 0x0902, 0x0D38, 0x08FD, 0x0D3C,
360 0x08F8, 0x0D3F, 0x08F3, 0x0D43, 0x08EE, 0x0D46, 0x08E8, 0x0D4A, 0x08E3, 0x0D4D, 0x08DE, 0x0D51,
361 0x08D9, 0x0D54, 0x08D3, 0x0D58, 0x08CE, 0x0D5B, 0x08C9, 0x0D5F, 0x08C4, 0x0D62, 0x08BE, 0x0D65,
362 0x08B9, 0x0D69, 0x08B4, 0x0D6C, 0x08AF, 0x0D70, 0x08A9, 0x0D73, 0x08A4, 0x0D77, 0x089F, 0x0D7A,
363 0x0899, 0x0D7D, 0x0894, 0x0D81, 0x088F, 0x0D84, 0x088A, 0x0D87, 0x0884, 0x0D8B, 0x087F, 0x0D8E,
364 0x087A, 0x0D91, 0x0874, 0x0D95, 0x086F, 0x0D98, 0x086A, 0x0D9B, 0x0864, 0x0D9F, 0x085F, 0x0DA2,
365 0x085A, 0x0DA5, 0x0854, 0x0DA9, 0x084F, 0x0DAC, 0x0849, 0x0DAF, 0x0844, 0x0DB2, 0x083F, 0x0DB6,
366 0x0839, 0x0DB9, 0x0834, 0x0DBC, 0x082E, 0x0DBF, 0x0829, 0x0DC2, 0x0824, 0x0DC6, 0x081E, 0x0DC9,
367 0x0819, 0x0DCC, 0x0813, 0x0DCF, 0x080E, 0x0DD2, 0x0809, 0x0DD5, 0x0803, 0x0DD9, 0x07FE, 0x0DDC,
368 0x07F8, 0x0DDF, 0x07F3, 0x0DE2, 0x07ED, 0x0DE5, 0x07E8, 0x0DE8, 0x07E2, 0x0DEB, 0x07DD, 0x0DEE,
369 0x07D7, 0x0DF2, 0x07D2, 0x0DF5, 0x07CD, 0x0DF8, 0x07C7, 0x0DFB, 0x07C2, 0x0DFE, 0x07BC, 0x0E01,
370 0x07B7, 0x0E04, 0x07B1, 0x0E07, 0x07AC, 0x0E0A, 0x07A6, 0x0E0D, 0x07A0, 0x0E10, 0x079B, 0x0E13,
371 0x0795, 0x0E16, 0x0790, 0x0E19, 0x078A, 0x0E1C, 0x0785, 0x0E1F, 0x077F, 0x0E22, 0x077A, 0x0E25,
372 0x0774, 0x0E28, 0x076F, 0x0E2B, 0x0769, 0x0E2D, 0x0763, 0x0E30, 0x075E, 0x0E33, 0x0758, 0x0E36,
373 0x0753, 0x0E39, 0x074D, 0x0E3C, 0x0748, 0x0E3F, 0x0742, 0x0E42, 0x073C, 0x0E44, 0x0737, 0x0E47,
374 0x0731, 0x0E4A, 0x072B, 0x0E4D, 0x0726, 0x0E50, 0x0720, 0x0E53, 0x071B, 0x0E55, 0x0715, 0x0E58,
375 0x070F, 0x0E5B, 0x070A, 0x0E5E, 0x0704, 0x0E60, 0x06FE, 0x0E63, 0x06F9, 0x0E66, 0x06F3, 0x0E69,
376 0x06ED, 0x0E6B, 0x06E8, 0x0E6E, 0x06E2, 0x0E71, 0x06DC, 0x0E74, 0x06D7, 0x0E76, 0x06D1, 0x0E79,
377 0x06CB, 0x0E7C, 0x06C6, 0x0E7E, 0x06C0, 0x0E81, 0x06BA, 0x0E84, 0x06B5, 0x0E86, 0x06AF, 0x0E89,
378 0x06A9, 0x0E8B, 0x06A3, 0x0E8E, 0x069E, 0x0E91, 0x0698, 0x0E93, 0x0692, 0x0E96, 0x068D, 0x0E98,
379 0x0687, 0x0E9B, 0x0681, 0x0E9E, 0x067B, 0x0EA0, 0x0676, 0x0EA3, 0x0670, 0x0EA5, 0x066A, 0x0EA8,
380 0x0664, 0x0EAA, 0x065F, 0x0EAD, 0x0659, 0x0EAF, 0x0653, 0x0EB2, 0x064D, 0x0EB4, 0x0648, 0x0EB7,
381 0x0642, 0x0EB9, 0x063C, 0x0EBC, 0x0636, 0x0EBE, 0x0630, 0x0EC0, 0x062B, 0x0EC3, 0x0625, 0x0EC5,
382 0x061F, 0x0EC8, 0x0619, 0x0ECA, 0x0613, 0x0ECD, 0x060E, 0x0ECF, 0x0608, 0x0ED1, 0x0602, 0x0ED4,
383 0x05FC, 0x0ED6, 0x05F6, 0x0ED8, 0x05F0, 0x0EDB, 0x05EB, 0x0EDD, 0x05E5, 0x0EDF, 0x05DF, 0x0EE2,
384 0x05D9, 0x0EE4, 0x05D3, 0x0EE6, 0x05CD, 0x0EE8, 0x05C7, 0x0EEB, 0x05C2, 0x0EED, 0x05BC, 0x0EEF,
385 0x05B6, 0x0EF2, 0x05B0, 0x0EF4, 0x05AA, 0x0EF6, 0x05A4, 0x0EF8, 0x059E, 0x0EFA, 0x0599, 0x0EFD,
386 0x0593, 0x0EFF, 0x058D, 0x0F01, 0x0587, 0x0F03, 0x0581, 0x0F05, 0x057B, 0x0F08, 0x0575, 0x0F0A,
387 0x056F, 0x0F0C, 0x0569, 0x0F0E, 0x0563, 0x0F10, 0x055D, 0x0F12, 0x0558, 0x0F14, 0x0552, 0x0F16,
388 0x054C, 0x0F18, 0x0546, 0x0F1B, 0x0540, 0x0F1D, 0x053A, 0x0F1F, 0x0534, 0x0F21, 0x052E, 0x0F23,
389 0x0528, 0x0F25, 0x0522, 0x0F27, 0x051C, 0x0F29, 0x0516, 0x0F2B, 0x0510, 0x0F2D, 0x050A, 0x0F2F,
390 0x0504, 0x0F31, 0x04FE, 0x0F33, 0x04F8, 0x0F35, 0x04F2, 0x0F37, 0x04EC, 0x0F39, 0x04E6, 0x0F3B,
391 0x04E0, 0x0F3C, 0x04DB, 0x0F3E, 0x04D5, 0x0F40, 0x04CF, 0x0F42, 0x04C9, 0x0F44, 0x04C3, 0x0F46,
392 0x04BD, 0x0F48, 0x04B7, 0x0F4A, 0x04B1, 0x0F4B, 0x04AB, 0x0F4D, 0x04A5, 0x0F4F, 0x049E, 0x0F51,
393 0x0498, 0x0F53, 0x0492, 0x0F55, 0x048C, 0x0F56, 0x0486, 0x0F58, 0x0480, 0x0F5A, 0x047A, 0x0F5C,
394 0x0474, 0x0F5D, 0x046E, 0x0F5F, 0x0468, 0x0F61, 0x0462, 0x0F63, 0x045C, 0x0F64, 0x0456, 0x0F66,
395 0x0450, 0x0F68, 0x044A, 0x0F69, 0x0444, 0x0F6B, 0x043E, 0x0F6D, 0x0438, 0x0F6E, 0x0432, 0x0F70,
396 0x042C, 0x0F72, 0x0426, 0x0F73, 0x0420, 0x0F75, 0x041A, 0x0F77, 0x0413, 0x0F78, 0x040D, 0x0F7A,
397 0x0407, 0x0F7B, 0x0401, 0x0F7D, 0x03FB, 0x0F7F, 0x03F5, 0x0F80, 0x03EF, 0x0F82, 0x03E9, 0x0F83,
398 0x03E3, 0x0F85, 0x03DD, 0x0F86, 0x03D7, 0x0F88, 0x03D0, 0x0F89, 0x03CA, 0x0F8B, 0x03C4, 0x0F8C,
399 0x03BE, 0x0F8E, 0x03B8, 0x0F8F, 0x03B2, 0x0F91, 0x03AC, 0x0F92, 0x03A6, 0x0F94, 0x03A0, 0x0F95,
400 0x0399, 0x0F96, 0x0393, 0x0F98, 0x038D, 0x0F99, 0x0387, 0x0F9B, 0x0381, 0x0F9C, 0x037B, 0x0F9D,
401 0x0375, 0x0F9F, 0x036F, 0x0FA0, 0x0368, 0x0FA1, 0x0362, 0x0FA3, 0x035C, 0x0FA4, 0x0356, 0x0FA5,
402 0x0350, 0x0FA7, 0x034A, 0x0FA8, 0x0344, 0x0FA9, 0x033D, 0x0FAB, 0x0337, 0x0FAC, 0x0331, 0x0FAD,
403 0x032B, 0x0FAE, 0x0325, 0x0FB0, 0x031F, 0x0FB1, 0x0318, 0x0FB2, 0x0312, 0x0FB3, 0x030C, 0x0FB4,
404 0x0306, 0x0FB6, 0x0300, 0x0FB7, 0x02FA, 0x0FB8, 0x02F3, 0x0FB9, 0x02ED, 0x0FBA, 0x02E7, 0x0FBB,
405 0x02E1, 0x0FBD, 0x02DB, 0x0FBE, 0x02D5, 0x0FBF, 0x02CE, 0x0FC0, 0x02C8, 0x0FC1, 0x02C2, 0x0FC2,
406 0x02BC, 0x0FC3, 0x02B6, 0x0FC4, 0x02AF, 0x0FC5, 0x02A9, 0x0FC6, 0x02A3, 0x0FC7, 0x029D, 0x0FC8,
407 0x0297, 0x0FC9, 0x0290, 0x0FCA, 0x028A, 0x0FCB, 0x0284, 0x0FCC, 0x027E, 0x0FCD, 0x0278, 0x0FCE,
408 0x0271, 0x0FCF, 0x026B, 0x0FD0, 0x0265, 0x0FD1, 0x025F, 0x0FD2, 0x0259, 0x0FD3, 0x0252, 0x0FD4,
409 0x024C, 0x0FD5, 0x0246, 0x0FD6, 0x0240, 0x0FD7, 0x0239, 0x0FD8, 0x0233, 0x0FD9, 0x022D, 0x0FD9,
410 0x0227, 0x0FDA, 0x0221, 0x0FDB, 0x021A, 0x0FDC, 0x0214, 0x0FDD, 0x020E, 0x0FDE, 0x0208, 0x0FDE,
411 0x0201, 0x0FDF, 0x01FB, 0x0FE0, 0x01F5, 0x0FE1, 0x01EF, 0x0FE1, 0x01E8, 0x0FE2, 0x01E2, 0x0FE3,
412 0x01DC, 0x0FE4, 0x01D6, 0x0FE4, 0x01CF, 0x0FE5, 0x01C9, 0x0FE6, 0x01C3, 0x0FE7, 0x01BD, 0x0FE7,
413 0x01B6, 0x0FE8, 0x01B0, 0x0FE9, 0x01AA, 0x0FE9, 0x01A4, 0x0FEA, 0x019D, 0x0FEB, 0x0197, 0x0FEB,
414 0x0191, 0x0FEC, 0x018B, 0x0FEC, 0x0184, 0x0FED, 0x017E, 0x0FEE, 0x0178, 0x0FEE, 0x0172, 0x0FEF,
415 0x016B, 0x0FEF, 0x0165, 0x0FF0, 0x015F, 0x0FF0, 0x0159, 0x0FF1, 0x0152, 0x0FF1, 0x014C, 0x0FF2,
416 0x0146, 0x0FF2, 0x0140, 0x0FF3, 0x0139, 0x0FF3, 0x0133, 0x0FF4, 0x012D, 0x0FF4, 0x0127, 0x0FF5,
417 0x0120, 0x0FF5, 0x011A, 0x0FF6, 0x0114, 0x0FF6, 0x010D, 0x0FF7, 0x0107, 0x0FF7, 0x0101, 0x0FF7,
418 0x00FB, 0x0FF8, 0x00F4, 0x0FF8, 0x00EE, 0x0FF9, 0x00E8, 0x0FF9, 0x00E2, 0x0FF9, 0x00DB, 0x0FFA,
419 0x00D5, 0x0FFA, 0x00CF, 0x0FFA, 0x00C8, 0x0FFB, 0x00C2, 0x0FFB, 0x00BC, 0x0FFB, 0x00B6, 0x0FFB,
420 0x00AF, 0x0FFC, 0x00A9, 0x0FFC, 0x00A3, 0x0FFC, 0x009D, 0x0FFC, 0x0096, 0x0FFD, 0x0090, 0x0FFD,
421 0x008A, 0x0FFD, 0x0083, 0x0FFD, 0x007D, 0x0FFE, 0x0077, 0x0FFE, 0x0071, 0x0FFE, 0x006A, 0x0FFE,
422 0x0064, 0x0FFE, 0x005E, 0x0FFE, 0x0057, 0x0FFF, 0x0051, 0x0FFF, 0x004B, 0x0FFF, 0x0045, 0x0FFF,
423 0x003E, 0x0FFF, 0x0038, 0x0FFF, 0x0032, 0x0FFF, 0x002B, 0x0FFF, 0x0025, 0x0FFF, 0x001F, 0x0FFF,
424 0x0019, 0x0FFF, 0x0012, 0x0FFF, 0x000C, 0x0FFF, 0x0006, 0x0FFF,
425];
426
427lazy_static::lazy_static! {
428 static ref WORD_6A56C8: Vec<i16> = init_table();
429}
430
431fn init_table() -> Vec<i16> {
432 let mut table = Vec::with_capacity(0x10000);
433 let mut cx: i16 = 0;
434 let mut dx: i16 = 0;
435 for _ in 0..0x8000 {
436 table.push(dx);
437 wrapping! {
438 dx -= 1;
439 cx += 1;
440 }
441 table.push(cx);
442 }
443 table
444}
445
446struct PcmDecoder {
447 pcm_data: Vec<u8>,
448 encoded: MemReader,
449 pcm_size: usize,
450 extra: u32,
451 dword_43a214: Vec<i32>,
452 unk_6a16c8: Vec<u8>,
453 a2: Vec<i32>,
455 a3: Vec<i32>,
457}
458
459impl PcmDecoder {
460 pub fn new<R: Read + Seek>(
461 mut input: R,
462 pcm_size: usize,
463 extra: u32,
464 mode: Mode,
465 ) -> Result<Self> {
466 if extra > 4 {
467 return Err(anyhow::anyhow!("Unsupported PCM extra: {}", extra));
468 }
469 let packed_size = input.read_u32()?;
470 let pcm_data = vec![0u8; pcm_size + 8192];
471 let encoded = match mode {
472 Mode::Lzss => {
473 let mut data = vec![0u8; packed_size as usize];
474 input.read_exact(&mut data)?;
475 Self::unpack_v1(&data)?
476 }
477 Mode::Zlib => {
478 let mut decoder = flate2::read::ZlibDecoder::new(input);
479 let mut data = Vec::new();
480 decoder.read_to_end(&mut data)?;
481 data
482 }
483 _ => return Err(anyhow::anyhow!("Unsupported PCM mode: {:?}", mode)),
484 };
485 Ok(Self {
486 pcm_data,
487 encoded: MemReader::new(encoded),
488 pcm_size,
489 extra,
490 dword_43a214: vec![0; 0x10],
491 unk_6a16c8: vec![0; 0x2000],
492 a2: vec![0; 0x1000],
493 a3: vec![0; 0x1000],
494 })
495 }
496
497 pub fn unpack(mut self) -> Result<Vec<u8>> {
498 let mut reader = MemReaderRef::new(&UNK_43A254);
499 reader.pos = self.extra as usize * 0x40;
500 for i in 0..0x10 {
501 self.dword_43a214[i] = reader.read_i32()?;
502 }
503 self.decode_v1()?;
504 self.pcm_data.truncate(self.pcm_size);
505 Ok(self.pcm_data)
506 }
507
508 fn decode_v1(&mut self) -> Result<()> {
509 let v14 = self.pcm_size / 2;
510 let mut v5 = 0;
511 let mut decoded = 0;
512 let mut dst_sizea = 0;
513 while dst_sizea < v14 {
514 self.sub_4121c0(v5)?;
515 v5 += 8192;
516 self.sub_411ab0(12);
517 let mut v6 = decoded;
518 let mut v7 = 0;
519 let mut v8 = 0;
520 let mut v9 = 32;
521 while v9 > -4064 {
522 if v7 + dst_sizea < v14 {
523 let mut v11;
524 if v9 > 0 && dst_sizea != 0 {
525 let v10 = (v7 as i64).wrapping_mul(self.a2[v8] as u32 as i64)
526 + (v9 as i64).wrapping_mul(i16::from_le_bytes([
527 self.pcm_data[v6],
528 self.pcm_data[v6 + 1],
529 ]) as i64);
530 v11 = (((v10 >> 32) & 0x1F) as i32 + v10 as i32) >> 5;
531 } else {
532 v11 = self.a2[v8];
533 }
534 if v11 > 32767 {
535 v11 = 32767;
536 } else if v11 < -32768 {
537 v11 = -32768;
538 }
539 let data = (v11 as i16).to_le_bytes();
540 self.pcm_data[v6] = data[0];
541 self.pcm_data[v6 + 1] = data[1];
542 }
543 v7 += 1;
544 v6 += 2;
545 v8 += 1;
546 v9 -= 1;
547 }
548 decoded += 8128;
549 dst_sizea += 4064;
550 }
551 Ok(())
552 }
553
554 fn sub_4121c0(&mut self, a1: usize) -> Result<()> {
555 let mut v1 = a1;
556 let mut v5 = 1;
557 for _ in 0..0x1000 {
558 self.unk_6a16c8[v5] = self.encoded.cpeek_u8_at(v1 as u64)?;
559 v1 += 1;
560 v5 += 2;
561 }
562 v5 = 0;
563 for _ in 0..0x800 {
564 let v7 = self.encoded.cpeek_u8_at(v1 as u64 + 0x800)?;
565 let v8 = self.encoded.cpeek_u8_at(v1 as u64)?;
566 self.unk_6a16c8[v5] = (v7 >> 4) | (v8 & 0xF0);
567 self.unk_6a16c8[v5 + 2] = (v8 << 4) | (v7 & 0x0F);
568 v5 += 4;
569 v1 += 1;
570 }
571 let mut v9 = 0;
572 v5 = 0;
573 for v11_chunk in (0..32768).step_by(16) {
574 let result = self.dword_43a214[v11_chunk / 0x1000];
575 let i1 = u16::from_le_bytes([self.unk_6a16c8[v5], self.unk_6a16c8[v5 + 1]]) as usize;
576 let i2 =
577 u16::from_le_bytes([self.unk_6a16c8[v5 + 2], self.unk_6a16c8[v5 + 3]]) as usize;
578 self.a2[v9] = result.wrapping_mul(WORD_6A56C8[i1] as i32);
579 self.a3[v9] = result.wrapping_mul(WORD_6A56C8[i2] as i32);
580 v9 += 1;
581 v5 += 4;
582 }
583 for i in v9..4096 {
584 self.a2[i] = 0;
585 self.a3[i] = 0;
586 }
587 Ok(())
588 }
589
590 fn sub_411ab0(&mut self, a1: i32) {
591 let mut v4 = 1 << a1;
592 let mut v5 = 1;
593 let mut v68 = 1;
594 let mut v6 = 1 << a1;
595 let v79 = 1 << a1;
596 if a1 >= 3 {
597 let mut v7 = v4 >> 1;
598 let mut v59 = a1 - 2;
599 loop {
600 let v63 = v4;
601 let v82 = DWORD_43A358[v5 as usize * 2];
602 let v66 = v7;
603 let mut v8 = v7 >> 1;
604 let v62 = v7 >> 1;
605 let v80 = DWORD_43A358[1 + 2 * v5 as usize];
606 let mut v77 = 0;
607 if v6 > 0 {
608 let mut v73 = 0;
609 let mut v69 = v8;
610 let mut v75 = v7;
611 let v9 = v8 + 1;
612 let v10 = v7 + v8;
613 let mut v64 = v9;
614 let mut v11 = 1;
615 let mut v12 = v10 + 1;
616 let mut v71 = v10;
617 let mut v13 = v7 + 1;
618 loop {
619 let v14 = self.a2[v75 as usize];
620 let v15 = self.a2[v73 as usize];
621 let v16 = self.a3[v11 as usize - 1] - self.a3[v13 as usize - 1];
622 self.a2[v73 as usize] += self.a2[v75 as usize];
623 self.a3[v11 as usize - 1] += self.a3[v13 as usize - 1];
624 self.a2[v75 as usize] = v15 - v14;
625 self.a3[v13 as usize - 1] = v16;
626 let v17 = self.a2[v13 as usize];
627 let v18 = self.a2[v11 as usize] - v17;
628 let v19 = self.a3[v11 as usize] - self.a3[v13 as usize];
629 self.a2[v11 as usize] += v17;
630 self.a3[v11 as usize] += self.a3[v13 as usize];
631 self.a2[v13 as usize] = (((v18 as i64).wrapping_mul(v82 as i64) as u64
632 >> 12)
633 + ((v19 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
634 as i32;
635 let pv = (v19 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
636 let nv = (v18 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
637 self.a3[v13 as usize] = pv.wrapping_sub(nv) as i32;
638 let v20 = self.a2[v69 as usize] - self.a2[v71 as usize];
639 let v21 = v64;
640 let v22 = self.a3[v64 as usize - 1] - self.a3[v12 as usize - 1];
641 self.a2[v69 as usize] += self.a2[v71 as usize];
642 self.a3[v21 as usize - 1] += self.a3[v12 as usize - 1];
643 self.a2[v71 as usize] = v22;
644 self.a3[v12 as usize - 1] = -v20;
645 let v23 = self.a2[v12 as usize];
646 let v24 = self.a2[v64 as usize] - v23;
647 let v25 = self.a3[v64 as usize] - self.a3[v12 as usize];
648 self.a2[v21 as usize] += v23;
649 self.a3[v21 as usize] += self.a3[v12 as usize];
650 let pv = (v25 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
651 let nv = (v24 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
652 self.a2[v12 as usize] = pv.wrapping_sub(nv) as i32;
653 self.a3[v12 as usize] = (-((((v24 as i64).wrapping_mul(v82 as i64) as u64
654 >> 12)
655 + ((v25 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
656 as i64)) as i32;
657 v13 += v63;
658 v75 += v63;
659 v11 += v63;
660 v73 += v63;
661 v12 += v63;
662 v71 += v63;
663 v77 += v63;
664 v69 += v63;
665 v64 += v63;
666 if v77 >= v79 {
667 break;
668 }
669 }
670 v8 = v62;
671 v5 = v68;
672 v7 = v66;
673 v6 = 1 << a1;
674 }
675 if v8 > 2 {
676 let mut v70 = 2;
677 let mut v72 = v7 + 2;
678 let mut v74 = v8 + 2;
679 let mut v27 = 1 + 4 * v5;
680 let mut v60 = v8 - 2;
681 let mut v76 = v8 + 2 + v7;
682 loop {
683 let v83 = DWORD_43A358[v27 as usize - 1];
684 let v81 = DWORD_43A358[v27 as usize];
685 let mut v78 = 0;
686 if v6 > 0 {
687 let mut v28 = v70;
688 let mut v29 = v72;
689 let mut v65 = v74;
690 let mut v85 = v76;
691 loop {
692 let v31 = self.a2[v29 as usize];
693 let v32 = self.a2[v28 as usize] - v31;
694 let v33 = self.a3[v28 as usize] - self.a3[v29 as usize];
695 self.a2[v28 as usize] += v31;
696 self.a3[v28 as usize] += self.a3[v29 as usize];
697 self.a2[v29 as usize] =
698 (((v32 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
699 + ((v33 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
700 as i32;
701 let pv = (v33 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
702 let nv = (v32 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
703 self.a3[v29 as usize] = pv.wrapping_sub(nv) as i32;
704 let v34 = self.a2[v65 as usize] - self.a2[v85 as usize];
705 let v35 = self.a3[v65 as usize] - self.a3[v85 as usize];
706 self.a2[v65 as usize] += self.a2[v85 as usize];
707 self.a3[v65 as usize] += self.a3[v85 as usize];
708 let pv = (v35 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
709 let nv = (v34 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
710 self.a2[v85 as usize] = pv.wrapping_sub(nv) as i32;
711 self.a3[v85 as usize] =
712 (-((((v34 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
713 + ((v35 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
714 as i64)) as i32;
715 v29 += v63;
716 v85 += v63;
717 v28 += v63;
718 v65 += v63;
719 v78 += v63;
720 if v78 >= v79 {
721 break;
722 }
723 }
724 v5 = v68;
725 v6 = 1 << a1;
726 }
727 v27 += 2 * v5;
728 v70 += 1;
729 v72 += 1;
730 v74 += 1;
731 v76 += 1;
732 v60 -= 1;
733 if v60 == 0 {
734 break;
735 }
736 }
737 }
738 v68 = 2 * v5;
739 v59 -= 1;
740 if v59 == 0 {
741 break;
742 }
743 v7 = v62;
744 v5 *= 2;
745 v4 = v66;
746 }
747 }
748 if !(a1 < 2 || v6 <= 0) {
749 let mut v37 = 1;
750 let mut v38 = 3;
751 let mut v88 = (v6 as u32 + 3) >> 2;
752 loop {
753 let v39 = self.a2[v37 as usize - 1];
754 let v40 = self.a2[v37 as usize + 1];
755 let v41 = self.a3[v38 as usize - 3] - self.a3[v38 as usize - 1];
756 self.a2[v37 as usize - 1] = v40 + v39;
757 v37 += 4;
758 self.a3[v38 as usize - 3] += self.a3[v38 as usize - 1];
759 self.a2[v37 as usize - 3] = v39 - v40;
760 self.a3[v38 as usize - 1] = v41;
761 let v42 = self.a2[v38 as usize];
762 let v43 = self.a3[v38 as usize - 2] - self.a3[v38 as usize];
763 v38 += 4;
764 let v44 = self.a2[v37 as usize - 4] - v42;
765 self.a2[v37 as usize - 4] += v42;
766 self.a3[v38 as usize - 6] += self.a3[v38 as usize - 4];
767 self.a2[v38 as usize - 4] = v43;
768 self.a3[v38 as usize - 4] = -v44;
769 v88 -= 1;
770 if v88 == 0 {
771 break;
772 }
773 }
774 v6 = v79;
775 }
776 let mut v45 = 0;
777 if v6 > 0 {
778 let mut v47 = 1;
779 let mut v89 = (v79 as u32 + 1) >> 1;
780 loop {
781 let v48 = self.a2[v47 as usize];
782 let v49 = self.a3[v47 as usize - 1] - self.a3[v47 as usize];
783 let v50 = self.a2[v45 as usize] - v48;
784 v47 += 2;
785 self.a2[v45 as usize] += v48;
786 v45 += 2;
787 self.a3[v47 as usize - 3] += self.a3[v47 as usize - 2];
788 self.a2[v47 as usize - 2] = v50;
789 self.a3[v47 as usize - 2] = v49;
790 v89 -= 1;
791 if v89 == 0 {
792 break;
793 }
794 }
795 v45 = 0;
796 v6 = v79;
797 }
798 let mut v51 = 0;
799 let mut result = v6 / 2;
800 let v67 = v6 / 2;
801 let mut v90 = 1;
802 if v6 - 1 > 1 {
803 let mut v54 = 1;
804 loop {
805 while result <= v51 {
806 v51 -= result;
807 result /= 2;
808 }
809 v51 += result;
810 if v90 < v51 {
811 self.a2.swap((v45 + v51) as usize, v54 as usize);
812 self.a3.swap(v51 as usize, v54 as usize);
813 }
814 v54 += 1;
815 v90 += 1;
816 if v90 >= v79 - 1 {
817 break;
818 }
819 result = v67;
820 }
821 v6 = v79;
822 }
823 while v6 > 0 {
824 let eax = self.a2[v45] << 4;
825 let edx = if eax < 0 { 0x3FFF } else { 0 };
826 self.a2[v45] = eax.wrapping_add(edx) >> 14;
827 v45 += 1;
828 v6 -= 1;
829 }
830 }
831
832 fn unpack_v1(input: &[u8]) -> Result<Vec<u8>> {
833 let packed_size = input.len();
834 let mut flag = 0;
835 let mut src = 0;
836 let mut output = Vec::new();
837 while src < packed_size {
838 flag >>= 1;
839 if (flag & 0x100) == 0 {
840 flag = input[src] as u32 | 0xFF00;
841 src += 1;
842 }
843 if (flag & 1) != 0 {
844 output.push(input[src]);
845 src += 1;
846 } else {
847 if src >= packed_size {
848 break;
849 }
850 let mut offset;
851 let count;
852 let ctl = input[src] as u32;
853 src += 1;
854 if ctl >= 0xc0 {
855 offset = input[src] as usize | (((ctl & 3) << 8) as usize);
856 src += 1;
857 count = 4 + ((ctl >> 2) & 0xF) as usize;
858 } else if ctl & 0x80 != 0 {
859 offset = (ctl & 0x1F) as usize;
860 count = (2 + ((ctl >> 5) & 3)) as usize;
861 if offset == 0 {
862 offset = input[src] as usize;
863 src += 1;
864 }
865 } else if ctl == 0x7F {
866 count = (2 + u16::from_le_bytes([input[src], input[src + 1]])) as usize;
867 offset = u16::from_le_bytes([input[src + 2], input[src + 3]]) as usize;
868 src += 4;
869 } else {
870 offset = u16::from_le_bytes([input[src], input[src + 1]]) as usize;
871 src += 2;
872 count = (ctl + 4) as usize;
873 }
874 let dst = output.len();
875 let copy_src = dst - offset;
876 for i in 0..count {
877 output.push(output[copy_src + i]);
878 }
879 }
880 }
881 Ok(output)
882 }
883}