Maraiah/source/marathon/trm.rs

147 lines
2.9 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-02-18 20:06:34 -08:00
use crate::durandal::{err::*, text::*};
2019-02-16 09:07:28 -08:00
use bitflags::bitflags;
2019-02-08 21:08:53 -08:00
2019-03-01 01:27:14 -08:00
/// Reads a `Group`.
pub fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
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];
pdata = i16[4];
2019-03-02 18:31:00 -08:00
start = u16[6] usize;
size = u16[8] usize;
2019-02-18 20:06:34 -08:00
lines = u16[10];
}
2019-03-04 04:28:04 -08:00
let text = mac_roman_cstr(&text[start..start + size])?;
2019-02-21 13:12:26 -08:00
let flags = flag_ok!(GroupFlags, flags)?;
2019-02-08 21:08:53 -08:00
let ttype = GroupType::from_repr(ttype)?;
2019-02-16 09:07:28 -08:00
Ok(Group{flags, ttype, pdata, lines, text})
2019-02-08 21:08:53 -08:00
}
2019-03-01 01:27:14 -08:00
/// Reads a `Face`.
pub fn read_face(b: &[u8]) -> ResultS<Face>
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-02-18 09:33:58 -08:00
Ok(Face{start, face, color})
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
{
const SIZE_GROUP: usize = 12;
2019-02-08 21:53:27 -08:00
const SIZE_FACE: usize = 6;
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
let mut groups = Vec::with_capacity(group_n);
2019-02-08 21:53:27 -08:00
let mut faces = Vec::with_capacity(face_n);
2019-02-08 21:08:53 -08:00
let mut p = 10;
2019-02-08 21:08:53 -08:00
let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n;
2019-02-18 20:06:34 -08:00
let text = &b[text_st..end];
2019-02-08 21:53:27 -08:00
let text = if encoded {
fuck_string(text)
} else {
text.to_vec()
};
2019-02-08 21:08:53 -08:00
for _ in 0..group_n {
2019-02-18 20:06:34 -08:00
groups.push(read_group(&b[p..], &text)?);
2019-02-08 21:08:53 -08:00
p += SIZE_GROUP;
}
for _ in 0..face_n {
2019-02-18 20:06:34 -08:00
faces.push(read_face(&b[p..])?);
2019-02-08 21:08:53 -08:00
p += SIZE_FACE;
}
2019-02-18 08:52:18 -08:00
Ok((Terminal{lines, groups, faces}, end))
2019-02-08 21:08:53 -08:00
}
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 pdata: i16,
pub lines: u16,
pub text: String,
2019-02-08 21:08:53 -08:00
}
2019-02-16 09:07:28 -08:00
bitflags! {
2019-03-01 01:27:14 -08:00
/// Flags for `Group`.
2019-03-01 03:22:27 -08:00
#[derive(serde::Serialize)]
2019-02-16 09:07:28 -08:00
pub struct GroupFlags: u16
{
2019-02-17 19:25:20 -08:00
const DrawOnRight = 1;
const DrawCenter = 1 << 1;
2019-02-16 09:07:28 -08:00
}
}
2019-02-08 21:08:53 -08:00
c_enum! {
2019-03-01 01:27:14 -08:00
/// The command of a `Group`.
2019-03-04 04:28:04 -08:00
#[derive(Debug, PartialEq, serde::Serialize)]
2019-02-08 21:08:53 -08:00
pub enum GroupType: u16
{
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,
}
}
// EOF