Maraiah/src/marathon/term.rs

136 lines
2.8 KiB
Rust
Raw Normal View History

2018-12-11 00:08:23 -08:00
use crate::durandal::{bin::*, err::*, text::*};
2018-09-11 01:21:36 -07:00
use std::fmt;
2018-12-13 01:06:57 -08:00
fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
2018-09-11 01:21:36 -07:00
{
2018-12-11 19:58:58 -08:00
// flags = b.c_u16b( 0)?;
2018-12-13 01:06:57 -08:00
let ttype = b.c_u16b( 2)?;
2018-12-11 19:58:58 -08:00
let pdata = b.c_i16b( 4)?;
let start = b.c_u16b( 6)? as usize;
let size = b.c_u16b( 8)? as usize;
let lines = b.c_u16b(10)?;
let text = mac_roman_conv(&text[start..start+size]);
2018-12-13 01:06:57 -08:00
let ttype = GroupType::from_repr(ttype)?;
2018-12-11 19:58:58 -08:00
Ok(Group{ttype, pdata, lines, text})
}
2018-09-11 01:21:36 -07:00
2018-12-13 01:06:57 -08:00
fn read_face(b: &[u8]) -> ResultS<Face>
2018-12-11 19:58:58 -08:00
{
let start = b.c_u16b(0)? as usize;
let face = b.c_u16b(2)?;
let color = b.c_u16b(4)?;
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
Ok(Face{start, face, color})
}
2018-09-11 01:21:36 -07:00
2018-12-13 01:06:57 -08:00
fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)>
2018-12-11 19:58:58 -08:00
{
const SIZE_GROUP: usize = 12;
const SIZE_FACE : usize = 6;
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
let end = b.c_u16b(0)? as usize;
let encoded = b.c_u16b(2)? & 1 != 0;
let lines = b.c_u16b(4)?;
let group_n = b.c_u16b(6)? as usize;
let face_n = b.c_u16b(8)? as usize;
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
let mut groups = Vec::with_capacity(group_n);
let mut faces = Vec::with_capacity( face_n);
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
let mut p = 10; // size of header
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n;
let text = &b[text_st..end];
let text = if encoded {fuck_string(text)} else {text.to_vec()};
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
for _ in 0..group_n {
groups.push(read_group(&b[p..], &text)?);
p += SIZE_GROUP;
}
2018-09-11 01:21:36 -07:00
2018-12-11 19:58:58 -08:00
for _ in 0..face_n {
faces.push(read_face(&b[p..])?);
p += SIZE_FACE;
2018-09-11 01:21:36 -07:00
}
2018-12-11 19:58:58 -08:00
Ok((end, Terminal{lines, groups, faces}))
}
impl Terminal
{
2018-09-11 12:07:42 -07:00
pub fn chunk(b: &[u8]) -> ResultS<Vec<Terminal>>
2018-09-11 01:21:36 -07:00
{
let mut v = Vec::new();
let mut p = 0;
2018-12-10 23:32:59 -08:00
while p < b.len() {
2018-12-11 19:58:58 -08:00
let (size, trm) = read_terminal(&b[p..])?;
2018-09-11 01:21:36 -07:00
v.push(trm);
2018-12-11 19:58:58 -08:00
p += size;
2018-09-11 01:21:36 -07:00
}
2018-09-11 12:07:42 -07:00
Ok(v)
2018-09-11 01:21:36 -07:00
}
}
#[derive(Debug)]
pub struct Terminal
{
2018-12-11 19:58:58 -08:00
lines: u16,
groups: Vec<Group>,
faces: Vec<Face>,
2018-09-11 01:21:36 -07:00
}
2018-12-13 01:06:57 -08:00
#[derive(Debug)]
2018-09-11 01:21:36 -07:00
pub struct Face
{
2018-12-11 19:58:58 -08:00
start: usize,
face: u16,
color: u16,
2018-09-11 01:21:36 -07:00
}
pub struct Group
{
2018-12-13 01:06:57 -08:00
ttype: GroupType,
2018-12-11 19:58:58 -08:00
pdata: i16,
lines: u16,
text: String,
2018-09-11 01:21:36 -07:00
}
2018-12-13 01:06:57 -08:00
c_enum! {
#[derive(Debug)]
pub enum GroupType: u16
2018-12-11 16:06:51 -08:00
{
2018-12-13 01:06:57 -08:00
0 => Logon,
1 => Unfinished,
2 => Success,
3 => Failure,
4 => Info,
5 => End,
6 => TeleInter,
7 => TeleIntra,
8 => Checkpoint,
9 => Sound,
10 => Movie,
11 => Track,
12 => Pict,
13 => Logoff,
14 => Camera,
15 => Static,
16 => Tag,
2018-12-11 16:06:51 -08:00
}
2018-09-11 01:21:36 -07:00
}
impl fmt::Debug for Group
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
2018-12-11 19:58:58 -08:00
write!(f, "Group{{{:?} {} {}", self.ttype, self.pdata, self.lines)?;
2018-12-13 01:06:57 -08:00
if self.text.len() != 0 {write!(f, ";\n{}", self.text)?;}
2018-09-11 01:21:36 -07:00
write!(f, "}}")
}
}
// EOF