Maraiah/source/marathon/trm.rs

174 lines
3.8 KiB
Rust
Raw Normal View History

2019-03-01 01:27:14 -08:00
//! Structures used by Marathon's Map format's terminal definitions.
2019-03-04 20:57:25 -08:00
use crate::durandal::{bin::*, err::*, text::*};
2019-02-16 09:07:28 -08:00
use bitflags::bitflags;
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
/// Reads an `InterGroup`.
pub fn read_group(b: &[u8]) -> ResultS<(InterGroup, usize)>
2019-02-08 21:08:53 -08:00
{
2019-02-18 20:06:34 -08:00
read_data! {
12, BE in b =>
flags = u16[0];
ttype = u16[2];
2019-03-04 06:00:03 -08:00
pdata = u16[4];
2019-03-04 20:57:25 -08:00
beg = u16[6] usize;
len = u16[8] usize;
2019-02-18 20:06:34 -08:00
lines = u16[10];
}
2019-02-21 13:12:26 -08:00
let flags = flag_ok!(GroupFlags, flags)?;
2019-03-04 06:00:03 -08:00
let ttype = match ttype {
0 => GroupType::Logon(pdata),
1 => GroupType::Unfinished,
2 => GroupType::Success,
3 => GroupType::Failure,
4 => GroupType::Info,
5 => GroupType::End,
6 => GroupType::TeleInter(pdata),
7 => GroupType::TeleIntra(pdata),
8 => GroupType::Checkpoint(pdata),
9 => GroupType::Sound(pdata),
10 => GroupType::Movie(pdata),
11 => GroupType::Track(pdata),
12 => GroupType::Pict(pdata),
13 => GroupType::Logoff(pdata),
14 => GroupType::Camera(pdata),
15 => GroupType::Static(pdata),
16 => GroupType::Tag(pdata),
n => return Err(ReprError::new(n).into()),
};
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
Ok((InterGroup{flags, ttype, lines, beg, len}, 12))
2019-02-08 21:08:53 -08:00
}
2019-03-01 01:27:14 -08:00
/// Reads a `Face`.
2019-03-04 20:57:25 -08:00
pub fn read_face(b: &[u8]) -> ResultS<(Face, usize)>
2019-02-08 21:08:53 -08:00
{
2019-02-18 20:06:34 -08:00
read_data! {
6, BE in b =>
2019-03-02 18:31:00 -08:00
start = u16[0] usize;
2019-02-18 20:06:34 -08:00
face = u16[2];
color = u16[4];
}
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
Ok((Face{start, face, color}, 6))
2019-02-08 21:08:53 -08:00
}
2019-03-01 01:27:14 -08:00
/// Reads a `term` chunk.
2019-02-18 08:52:18 -08:00
pub fn read_term(b: &[u8]) -> ResultS<(Terminal, usize)>
2019-02-08 21:08:53 -08:00
{
2019-02-18 20:06:34 -08:00
read_data! {
10, BE in b =>
2019-03-02 18:31:00 -08:00
end = u16[0] usize;
2019-02-18 20:06:34 -08:00
encoded = u16[2];
lines = u16[4];
2019-03-02 18:31:00 -08:00
group_n = u16[6] usize;
face_n = u16[8] usize;
2019-02-18 20:06:34 -08:00
}
let encoded = encoded != 0;
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
let (i_grp, x) = rd_array_num(&b[10..], group_n, read_group)?;
let (faces, y) = rd_array_num(&b[10 + x..], face_n, read_face)?;
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
let text = ok!(b.get(10 + x + y..end), "not enough data")?;
let text = if encoded {fuck_string(text)} else {text.to_vec()};
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
let mut groups = Vec::with_capacity(group_n);
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
for grp in &i_grp {
let flags = grp.flags;
let ttype = grp.ttype;
let lines = grp.lines;
let beg = grp.beg;
let len = grp.len;
let text = ok!(text.get(beg..beg + len), "bad offset")?;
let text = mac_roman_cstr(text);
2019-02-08 21:08:53 -08:00
2019-03-04 20:57:25 -08:00
groups.push(Group{flags, ttype, lines, text});
2019-02-08 21:08:53 -08:00
}
2019-02-18 08:52:18 -08:00
Ok((Terminal{lines, groups, faces}, end))
2019-02-08 21:08:53 -08:00
}
2019-03-04 20:57:25 -08:00
impl Default for GroupType
{
fn default() -> Self {GroupType::Unfinished}
}
2019-03-01 01:27:14 -08:00
/// A terminal definition, with collections of groups and faces.
2019-03-04 04:28:04 -08:00
#[derive(Debug, PartialEq, serde::Serialize)]
2019-02-08 21:08:53 -08:00
pub struct Terminal
{
2019-03-04 04:28:04 -08:00
pub lines: u16,
pub groups: Vec<Group>,
pub faces: Vec<Face>,
2019-02-08 21:08:53 -08:00
}
2019-03-01 01:27:14 -08:00
/// A text face.
2019-03-04 04:28:04 -08:00
#[derive(Debug, PartialEq, serde::Serialize)]
2019-02-08 21:08:53 -08:00
pub struct Face
{
2019-03-04 04:28:04 -08:00
pub start: usize,
pub face: u16,
pub color: u16,
2019-02-08 21:08:53 -08:00
}
2019-03-01 01:27:14 -08:00
/// A terminal command grouping.
2019-03-04 04:28:04 -08:00
#[derive(Debug, PartialEq, serde::Serialize)]
2019-02-08 21:08:53 -08:00
pub struct Group
{
2019-03-04 04:28:04 -08:00
pub flags: GroupFlags,
pub ttype: GroupType,
pub lines: u16,
pub text: String,
2019-02-08 21:08:53 -08:00
}
2019-03-04 20:57:25 -08:00
/// Interim structure.
#[derive(Debug)]
pub struct InterGroup
{
2019-03-09 14:03:20 -08:00
pub flags: GroupFlags,
pub ttype: GroupType,
pub lines: u16,
pub beg: usize,
pub len: usize,
2019-03-04 20:57:25 -08:00
}
2019-03-04 06:00:03 -08:00
/// The command of a `Group`.
2019-03-04 20:57:25 -08:00
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize)]
2019-03-04 06:00:03 -08:00
pub enum GroupType
{
Logon(u16),
Unfinished,
Success,
Failure,
Info,
End,
TeleInter(u16),
TeleIntra(u16),
Checkpoint(u16),
Sound(u16),
Movie(u16),
Track(u16),
Pict(u16),
Logoff(u16),
Camera(u16),
Static(u16),
Tag(u16),
}
2019-02-16 09:07:28 -08:00
bitflags! {
2019-03-01 01:27:14 -08:00
/// Flags for `Group`.
2019-03-04 20:57:25 -08:00
#[derive(Default, serde::Serialize)]
2019-02-16 09:07:28 -08:00
pub struct GroupFlags: u16
{
2019-03-09 14:03:20 -08:00
/// Draws the picture on the right.
2019-03-07 00:12:00 -08:00
const DRAW_ON_RIGHT = 1;
2019-03-09 14:03:20 -08:00
/// Draws the picture in the center.
2019-03-07 00:12:00 -08:00
const DRAW_CENTER = 1 << 1;
2019-02-16 09:07:28 -08:00
}
}
2019-02-08 21:08:53 -08:00
// EOF