1use crate::ext::io::*;
2use anyhow::Result;
3use std::any::Any;
4use std::ffi::CString;
5
6pub trait Disasm: Sized {
7 fn disassmble(self) -> Result<(Vec<usize>, Vec<Ws2DString>)>;
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11enum Oper {
12 B,
14 H,
16 I,
18 A,
20 F,
22 S,
24 ARR,
26}
27use Oper::*;
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub enum StringType {
31 Name,
32 Message,
33 Internal,
34}
35
36#[derive(Debug, Clone)]
37pub struct Ws2DString {
38 pub text: CString,
39 pub offset: usize,
40 pub len: usize,
41 pub typ: StringType,
42}
43
44struct DisasmBase<'a> {
45 reader: MemReaderRef<'a>,
46 opers: &'a [(u8, &'static [Oper])],
47 addresses: Vec<usize>,
48 texts: Vec<Ws2DString>,
49}
50
51impl<'a> DisasmBase<'a> {
52 pub fn new(data: &'a [u8], opers: &'a [(u8, &'static [Oper])]) -> Self {
53 DisasmBase {
54 reader: MemReaderRef::new(data),
55 opers,
56 addresses: Vec::new(),
57 texts: Vec::new(),
58 }
59 }
60
61 fn read_instruction(&mut self) -> Result<(u8, Vec<Box<dyn Any>>)> {
62 let opcode = self.reader.read_u8()?;
63 let opers = self
64 .opers
65 .iter()
66 .find(|&&(op, _)| op == opcode)
67 .ok_or_else(|| anyhow::anyhow!("Unknown opcode: {opcode}"))?;
68 let operands = self.read_operands(opers.1)?;
69 Ok((opcode, operands))
70 }
71
72 fn read_operands(&mut self, opers: &[Oper]) -> Result<Vec<Box<dyn Any>>> {
73 let mut operands = Vec::new();
74 let mut i = 0;
75 let oper_len = opers.len();
76 while i < oper_len {
77 let oper = opers[i];
78 if i < oper_len - 1 && opers[i + 1] == ARR {
79 i += 1;
80 let count = self.reader.read_u8()?;
81 for _ in 0..count {
82 operands.push(self.read_operand(oper)?);
83 }
84 } else {
85 let operand = self.read_operand(oper)?;
86 operands.push(operand);
87 }
88 i += 1;
89 }
90 Ok(operands)
91 }
92
93 fn read_operand(&mut self, oper: Oper) -> Result<Box<dyn Any>> {
94 match oper {
95 B => {
96 let value = self.reader.read_u8()?;
97 Ok(Box::new(value))
98 }
99 H => {
100 let value = self.reader.read_i16()?;
101 Ok(Box::new(value))
102 }
103 I => {
104 let value = self.reader.read_i32()?;
105 Ok(Box::new(value))
106 }
107 A => {
108 let pos = self.reader.pos;
109 let address = self.reader.read_i32()?;
110 self.addresses.push(pos);
111 Ok(Box::new(address))
112 }
113 F => {
114 let value = self.reader.read_f32()?;
115 Ok(Box::new(value))
116 }
117 S => {
118 let offset = self.reader.pos;
119 let s = self.reader.read_cstring()?;
120 let len = s.as_bytes_with_nul().len();
121 let str = Ws2DString {
122 text: s,
123 offset,
124 len,
125 typ: StringType::Internal,
126 };
127 Ok(Box::new(str))
128 }
129 _ => {
130 Err(anyhow::anyhow!("Unsupported operand type: {:?}", oper))
132 }
133 }
134 }
135
136 fn handle_choice_screen(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
137 if operands.len() < 1 {
138 return Err(anyhow::anyhow!("Invalid operands for choice screen"));
139 }
140 let first = operands.remove(0);
141 let num_choices = first
142 .downcast::<u8>()
143 .map_err(|_| anyhow::anyhow!("Invalid choice count"))?;
144 for _ in 0..*num_choices {
145 let mut opers = self.read_operands(&[H, S, B, H])?;
146 let range = opers.remove(1);
147 let mut range = range
148 .downcast::<Ws2DString>()
149 .map_err(|_| anyhow::anyhow!("Invalid range operand"))?;
150 if range.len > 1 {
151 range.typ = StringType::Message;
152 self.texts.push(*range);
153 }
154 self.read_instruction()?;
155 }
156 Ok(())
157 }
158
159 fn handle_message(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
160 if operands.len() < 3 {
161 return Err(anyhow::anyhow!("Invalid operands for message"));
162 }
163 let range = operands.remove(2);
164 let mut range = range
165 .downcast::<Ws2DString>()
166 .map_err(|_| anyhow::anyhow!("Invalid range operand"))?;
167 if range.len > 1 {
168 range.typ = StringType::Message;
169 self.texts.push(*range);
170 }
171 Ok(())
172 }
173
174 fn handle_name(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
175 if operands.len() < 1 {
176 return Err(anyhow::anyhow!("Invalid operands for name"));
177 }
178 let name = operands.remove(0);
179 let mut name = name
180 .downcast::<Ws2DString>()
181 .map_err(|_| anyhow::anyhow!("Invalid name operand"))?;
182 if name.len > 1 {
183 name.typ = StringType::Name;
184 self.texts.push(*name);
185 }
186 Ok(())
187 }
188}
189
190impl<'a> Disasm for DisasmBase<'a> {
191 fn disassmble(mut self) -> Result<(Vec<usize>, Vec<Ws2DString>)> {
192 let maxlen = self.reader.data.len() - 8;
193 while self.reader.pos < maxlen {
194 let (opcode, mut operands) = self.read_instruction()?;
195 match opcode {
196 0x0F => self.handle_choice_screen(&mut operands)?,
197 0x14 => self.handle_message(&mut operands)?,
198 0x15 => self.handle_name(&mut operands)?,
199 _ => {}
200 }
201 for oper in operands {
202 if let Ok(str) = oper.downcast::<Ws2DString>() {
203 if str.len > 1 {
204 self.texts.push(*str);
205 }
206 }
207 }
208 }
209 self.texts.sort_by_key(|s| s.offset);
210 Ok((self.addresses, self.texts))
211 }
212}
213
214const V1_OPS: [(u8, &'static [Oper]); 103] = [
215 (0x00, &[]),
216 (0x01, &[B, H, F, A, A]),
217 (0x02, &[A]),
218 (0x04, &[S]),
219 (0x05, &[]),
220 (0x06, &[A]),
221 (0x07, &[S]),
222 (0x08, &[B]),
223 (0x09, &[B, H, F]),
224 (0x0A, &[H, F]),
225 (0x0B, &[H, B]),
226 (0x0C, &[H, B, H, ARR]),
227 (0x0D, &[H, H, F]),
228 (0x0E, &[H, H, B]),
229 (0x0F, &[B]),
230 (0x11, &[S, F]),
231 (0x12, &[S, B, S]),
232 (0x13, &[]),
233 (0x14, &[I, S, S]),
234 (0x15, &[S]),
235 (0x16, &[B]),
236 (0x17, &[]),
237 (0x18, &[B, S]),
238 (0x19, &[]),
239 (0x1A, &[S]),
240 (0x1B, &[B]),
241 (0x1C, &[S, S, H]),
242 (0x1D, &[H]),
243 (0x1E, &[S, S, F, F, H, H, B]),
244 (0x1F, &[S, F]),
245 (0x20, &[S, F, H]),
246 (0x21, &[S, H, H, H]),
247 (0x22, &[S, B]),
248 (0x28, &[S, S, F, F, H, H, B, H, H, B]),
249 (0x29, &[S, F]),
250 (0x2A, &[S, F, H]),
251 (0x2B, &[S]),
252 (0x2C, &[S]),
253 (0x2D, &[S, B]),
254 (0x2E, &[]),
255 (0x2F, &[S, H, F]),
256 (0x32, &[S]),
257 (0x33, &[S, S, B, B]),
258 (0x34, &[S, S, B, B]),
259 (0x35, &[S, S, B, B, B]),
260 (0x36, &[S, F, F, F, F, F, F, F, B, B]),
261 (0x37, &[S]),
262 (0x38, &[S, B]),
263 (0x39, &[S, B, B, H, ARR]),
264 (0x3A, &[S, B, B]),
265 (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
266 (0x3C, &[S]),
267 (0x3D, &[H]),
268 (0x3E, &[]),
269 (0x3F, &[S, ARR]),
270 (0x40, &[S, S, B]),
271 (0x41, &[S, B]),
272 (0x42, &[S, H]),
273 (0x43, &[S]),
274 (0x44, &[S, S, B]),
275 (0x45, &[S, H, F, F, F, F]),
276 (0x46, &[S, H, B, F, F, F, F]),
277 (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
278 (0x48, &[S, S, H, B, B, S]),
279 (0x49, &[S, S, S]),
280 (0x4A, &[S, S]),
281 (0x4B, &[S, H, H, F, F, F, F]),
282 (0x4C, &[S, H, H, B, F, F, F, F]),
283 (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
284 (0x4E, &[S, S, H, H, B, B, S]),
285 (0x4F, &[S, S, H, S]),
286 (0x50, &[S, S, H]),
287 (0x51, &[S, S, H, F, B]),
288 (0x52, &[S, S, F, H, F, B, S]),
289 (0x53, &[S, S]),
290 (0x54, &[S, S, S]),
291 (0x55, &[S, S]),
292 (
293 0x56,
294 &[
295 S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
296 ],
297 ),
298 (0x57, &[S, H]),
299 (0x58, &[S, S]),
300 (0x59, &[S, S, H]),
301 (0x5A, &[S, H, ARR]),
302 (0x5B, &[S, H, B]),
303 (0x5C, &[S]),
304 (0x5D, &[S, S, B]),
305 (0x5E, &[S, F, F]),
306 (0x64, &[B]),
307 (0x65, &[H, B, F, F, B, S]),
308 (0x66, &[S]),
309 (0x67, &[B, B, H, F, F, F, F, F, B]),
310 (0x68, &[B]),
311 (0x6E, &[S, S]),
312 (0x6F, &[S]),
313 (0x70, &[S, H]),
314 (0x71, &[]),
315 (0x72, &[S, H, H, S]),
316 (0x73, &[S, S, H]),
317 (0xFA, &[]),
318 (0xFB, &[B]),
319 (0xFC, &[H]),
320 (0xFD, &[]),
321 (0xFE, &[S]),
322 (0xFF, &[]),
323];
324
325const V2_OPS: [(u8, &'static [Oper]); 134] = [
326 (0x00, &[]),
327 (0x01, &[B, H, F, A, A]),
328 (0x02, &[A]),
329 (0x04, &[S]),
330 (0x05, &[]),
331 (0x06, &[A]),
332 (0x07, &[S]),
333 (0x08, &[B]),
334 (0x09, &[B, H, F]),
335 (0x0A, &[H, F]),
336 (0x0B, &[H, B]),
337 (0x0C, &[H, B, H, ARR]),
338 (0x0D, &[H, H, F]),
339 (0x0E, &[H, H, B]),
340 (0x0F, &[B]),
341 (0x11, &[S, F]),
342 (0x12, &[S, B, S]),
343 (0x13, &[]),
344 (0x14, &[I, S, S]),
345 (0x15, &[S]),
346 (0x16, &[B]),
347 (0x17, &[]),
348 (0x18, &[B, S]),
349 (0x19, &[]),
350 (0x1A, &[S]),
351 (0x1B, &[B]),
352 (0x1C, &[S, S, H, B]),
353 (0x1D, &[H]),
354 (0x1E, &[S, S, F, F, H, H, B]),
355 (0x1F, &[S, F]),
356 (0x20, &[S, F, H]),
357 (0x21, &[S, H, H, H]),
358 (0x22, &[S, B]),
359 (0x28, &[S, S, F, F, H, H, B, H, H, B]),
360 (0x29, &[S, F]),
361 (0x2A, &[S, F, H]),
362 (0x2B, &[S]),
363 (0x2C, &[S]),
364 (0x2D, &[S, B]),
365 (0x2E, &[]),
366 (0x2F, &[S, H, F]),
367 (0x32, &[S]),
368 (0x33, &[S, S, B, B]),
369 (0x34, &[S, S, B, B]),
370 (0x35, &[S, S, B, B, B]),
371 (0x36, &[S, F, F, F, F, F, F, F, B, B]),
372 (0x37, &[S]),
373 (0x38, &[S, B]),
374 (0x39, &[S, B, B, H, ARR]),
375 (0x3A, &[S, B, B]),
376 (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
377 (0x3C, &[S]),
378 (0x3D, &[H]),
379 (0x3E, &[]),
380 (0x3F, &[S, ARR]),
381 (0x40, &[S, S, B]),
382 (0x41, &[S, B]),
383 (0x42, &[S, H]),
384 (0x43, &[S]),
385 (0x44, &[S, S, B]),
386 (0x45, &[S, H, F, F, F, F]),
387 (0x46, &[S, H, B, F, F, F, F]),
388 (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
389 (0x48, &[S, S, H, B, B, S]),
390 (0x49, &[S, S, S]),
391 (0x4A, &[S, S]),
392 (0x4B, &[S, H, H, F, F, F, F]),
393 (0x4C, &[S, H, H, B, F, F, F, F]),
394 (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
395 (0x4E, &[S, S, H, H, B, B, S]),
396 (0x4F, &[S, S, H, S]),
397 (0x50, &[S, S, H]),
398 (0x51, &[S, S, H, F, B]),
399 (0x52, &[S, S, F, H, F, B, S]),
400 (0x53, &[S, S]),
401 (0x54, &[S, S, S]),
402 (0x55, &[S, S]),
403 (
404 0x56,
405 &[
406 S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
407 ],
408 ),
409 (0x57, &[S, H]),
410 (0x58, &[S, S]),
411 (0x59, &[S, S, H]),
412 (0x5A, &[S, H, ARR]),
413 (0x5B, &[S, H, B]),
414 (0x5C, &[S]),
415 (0x5D, &[S, S, B]),
416 (0x5E, &[S, F, F]),
417 (0x5F, &[S]),
418 (0x60, &[H, H, H, H]),
419 (0x61, &[B, F, F, F, F]),
420 (0x62, &[S]),
421 (0x63, &[S, B]),
422 (0x64, &[B]),
423 (0x65, &[H, B, F, F, B, S]),
424 (0x66, &[S]),
425 (0x67, &[B, B, H, F, F, F, F, F, B]),
426 (0x68, &[B]),
427 (0x69, &[S, B, B, F, F, F, F, F, H, F]),
428 (0x6A, &[S, H, B, B, S]),
429 (0x6E, &[S, S]),
430 (0x6F, &[S]),
431 (0x70, &[S, H]),
432 (0x71, &[]),
433 (0x72, &[S, H, H, S]),
434 (0x73, &[S, S, H]),
435 (0x74, &[S, S]),
436 (0x75, &[S, S]),
437 (0x78, &[S, S, B, B]),
438 (0x79, &[S, S, F]),
439 (0x7A, &[S, S, F, B, B, S]),
440 (0x7B, &[S, S]),
441 (0x7C, &[S, S, F]),
442 (0x7D, &[S, F]),
443 (0x7E, &[S]),
444 (0xC8, &[]),
445 (0xC9, &[S, S, H, H, H]),
446 (0xCA, &[S, S]),
447 (0xCB, &[S, B, B]),
448 (0xCC, &[]),
449 (0xCD, &[S, S, S, S, S, F, B]),
450 (0xCE, &[B]),
451 (0xCF, &[S, S, F]),
452 (0xD0, &[S, H]),
453 (0xD1, &[S, H]),
454 (0xD2, &[S]),
455 (0xD3, &[S]),
456 (0xD4, &[S, H, H]),
457 (0xF8, &[]),
458 (0xF9, &[B, S]),
459 (0xFA, &[]),
460 (0xFB, &[B]),
461 (0xFC, &[H]),
462 (0xFD, &[]),
463 (0xFE, &[S]),
464 (0xFF, &[]),
465];
466
467const V3_OPS: [(u8, &'static [Oper]); 165] = [
468 (0x00, &[]),
469 (0x01, &[B, H, F, A, A]),
470 (0x02, &[A]),
471 (0x04, &[S]),
472 (0x05, &[]),
473 (0x06, &[A]),
474 (0x07, &[S]),
475 (0x08, &[B]),
476 (0x09, &[B, H, F]),
477 (0x0A, &[H, F]),
478 (0x0B, &[H, B]),
479 (0x0C, &[H, B, H, ARR]),
480 (0x0D, &[H, H, F]),
481 (0x0E, &[H, H, B]),
482 (0x0F, &[B]),
483 (0x11, &[S, B, F]),
484 (0x12, &[S, B, S]),
485 (0x13, &[]),
486 (0x14, &[I, S, S, B]),
487 (0x15, &[S, B]),
488 (0x16, &[B, B]),
489 (0x17, &[]),
490 (0x18, &[B, S]),
491 (0x19, &[]),
492 (0x1A, &[S]),
493 (0x1B, &[B]),
494 (0x1C, &[S, S, H, B]),
495 (0x1D, &[H]),
496 (0x1E, &[S, S, F, F, H, H, B, F]),
497 (0x1F, &[S, F]),
498 (0x20, &[S, F, H]),
499 (0x21, &[S, H, H, H]),
500 (0x22, &[S, B]),
501 (0x28, &[S, S, F, F, H, H, B, H, H, B, F]),
502 (0x29, &[S, F]),
503 (0x2A, &[S, F, H]),
504 (0x2B, &[S]),
505 (0x2C, &[S]),
506 (0x2D, &[S, B]),
507 (0x2E, &[]),
508 (0x2F, &[S, H, F]),
509 (0x32, &[S]),
510 (0x33, &[S, S, B, B]),
511 (0x34, &[S, S, B, B]),
512 (0x35, &[S, S, B, B, B]),
513 (0x36, &[S, F, F, F, F, F, F, F, B, B]),
514 (0x37, &[S]),
515 (0x38, &[S, B]),
516 (0x39, &[S, B, B, H, ARR]),
517 (0x3A, &[S, B, B]),
518 (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
519 (0x3C, &[S]),
520 (0x3D, &[H]),
521 (0x3E, &[]),
522 (0x3F, &[S, ARR]),
523 (0x40, &[S, S, B]),
524 (0x41, &[S, B]),
525 (0x42, &[S, H]),
526 (0x43, &[S]),
527 (0x44, &[S, S, B]),
528 (0x45, &[S, H, F, F, F, F]),
529 (0x46, &[S, H, B, F, F, F, F]),
530 (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
531 (0x48, &[S, S, H, B, B, S]),
532 (0x49, &[S, S, S]),
533 (0x4A, &[S, S]),
534 (0x4B, &[S, H, H, F, F, F, F]),
535 (0x4C, &[S, H, H, B, F, F, F, F]),
536 (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
537 (0x4E, &[S, S, H, H, B, B, S]),
538 (0x4F, &[S, S, H, S]),
539 (0x50, &[S, S, H]),
540 (0x51, &[S, S, H, F, B]),
541 (0x52, &[S, S, F, H, F, B, S]),
542 (0x53, &[S, S]),
543 (0x54, &[S, S, S]),
544 (0x55, &[S, S]),
545 (
546 0x56,
547 &[
548 S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
549 ],
550 ),
551 (0x57, &[S, H]),
552 (0x58, &[S, S]),
553 (0x59, &[S, S, H]),
554 (0x5A, &[S, H, ARR]),
555 (0x5B, &[S, H, B]),
556 (0x5C, &[S]),
557 (0x5D, &[S, S, B]),
558 (0x5E, &[S, F, F]),
559 (0x5F, &[S]),
560 (0x60, &[H, H, H, H]),
561 (0x61, &[B, F, F, F, F]),
562 (0x62, &[S]),
563 (0x63, &[S, B]),
564 (0x64, &[B]),
565 (0x65, &[H, B, F, F, B, S]),
566 (0x66, &[S]),
567 (0x67, &[B, B, H, F, F, F, F, F, B]),
568 (0x68, &[B]),
569 (0x69, &[S, B, B, F, F, F, F, F, H, F]),
570 (0x6A, &[S, H, B, B, S]),
571 (0x6B, &[S, S]),
572 (0x6C, &[S, F, F]),
573 (0x6E, &[S, S]),
574 (0x6F, &[S]),
575 (0x70, &[S, H]),
576 (0x71, &[]),
577 (0x72, &[S, H, H, S]),
578 (0x73, &[S, S, H]),
579 (0x74, &[S, S]),
580 (0x75, &[S, S]),
581 (0x78, &[S, S, B, B, B]),
582 (0x79, &[S, S, F]),
583 (0x7A, &[S, S, F, B, B, S]),
584 (0x7B, &[S, S]),
585 (0x7C, &[S, S, F]),
586 (0x7D, &[S, F]),
587 (0x7E, &[S]),
588 (0x7F, &[S, F, F, F, F, F]),
589 (0x80, &[S]),
590 (0x81, &[S, B, S, F, F, B]),
591 (0x82, &[S, S, F]),
592 (0x83, &[S, S, F, F]),
593 (0x84, &[S, S, S, F, H, F]),
594 (0x85, &[S, S, B, F]),
595 (0x86, &[S, F, F, F]),
596 (0x87, &[S, F]),
597 (0x88, &[S, S, S, F, H, F]),
598 (0x8C, &[S, S, S, B, B]),
599 (0x8D, &[I, S, S, B, B, S]),
600 (0x8E, &[I, S, S, B, B, S]),
601 (0x8F, &[S, S]),
602 (0x90, &[S]),
603 (0x96, &[H, F, F, F, F]),
604 (0x97, &[H, B, F, F, F, F]),
605 (0x98, &[S, H, B, B, F, F, F, F, F, H, F]),
606 (0x99, &[S, H, B, B, S]),
607 (0x9A, &[]),
608 (0x9B, &[S]),
609 (0x9C, &[S, S]),
610 (0x9D, &[S]),
611 (0x9E, &[S, B]),
612 (0x9F, &[S, B]),
613 (0xC8, &[]),
614 (0xC9, &[S, S, H, H, H, H]),
615 (0xCA, &[S, S]),
616 (0xCB, &[S, B, B]),
617 (0xCC, &[]),
618 (0xCD, &[S, S, S, S, S, F, B]),
619 (0xCE, &[B]),
620 (0xCF, &[S, S, F]),
621 (0xD0, &[S, H]),
622 (0xD1, &[S, H]),
623 (0xD2, &[S]),
624 (0xD3, &[S]),
625 (0xD4, &[S, H, H]),
626 (0xE6, &[I, I]),
627 (0xE7, &[]),
628 (0xE8, &[]),
629 (0xF0, &[B]),
630 (0xF8, &[]),
631 (0xF9, &[B, S]),
632 (0xFA, &[]),
633 (0xFB, &[B]),
634 (0xFC, &[H]),
635 (0xFD, &[]),
636 (0xFE, &[S]),
637 (0xFF, &[]),
638];
639
640const OPS: [&[(u8, &'static [Oper])]; 3] = [&V1_OPS, &V2_OPS, &V3_OPS];
641
642pub fn disassmble(data: &[u8]) -> Result<(Vec<usize>, Vec<Ws2DString>)> {
643 for op in &OPS {
644 let disasm = DisasmBase::new(data, op);
645 match disasm.disassmble() {
646 Ok(result) => return Ok(result),
647 Err(_) => continue, }
649 }
650 Err(anyhow::anyhow!(
651 "Failed to disassemble the data with all known versions"
652 ))
653}