Maraiah/src/marathon/shp.rs

205 lines
4.5 KiB
Rust

//! Marathon Shapes format handling.
use crate::durandal::{bin::*, err::*, fx32::*, /*image::*,*/ text::*};
use bitflags::bitflags;
fn color(b: &[u8]) -> ResultS<()>
{
let lum = b[0];
let ind = b[1];
let r = b.c_u16b(2)?;
let g = b.c_u16b(4)?;
let b = b.c_u16b(6)?;
// col = Color::from_rgb16(r, g, b);
let lum = match lum {
128 => true,
0 => false,
_ => {
return Err(err_msg("invalid flag in color"));
}
};
dbg!(lum);
dbg!(ind);
dbg!(r);
dbg!(g);
dbg!(b);
Ok(())
}
fn frame(b: &[u8]) -> ResultS<()>
{
let flags = b.c_u16b(0)?;
let minlight = b.c_u32b(2)?;
let bmp_ind = b.c_u16b(6)?;
// orig_x = b.c_i16b(8)?;
// orig_y = b.c_i16b(10)?;
// key_x = b.c_i16b(12)?;
// key_y = b.c_i16b(14)?;
let wrl_l = b.c_i16b(16)?;
let wrl_r = b.c_i16b(18)?;
let wrl_t = b.c_i16b(20)?;
let wrl_b = b.c_i16b(22)?;
let wrl_x = b.c_i16b(24)?;
let wrl_y = b.c_i16b(26)?;
let flags = FrameFlags::from_bits(flags).ok_or_else(bad_flag)?;
let minlight = Fx32::from_bits(minlight);
dbg!(flags);
dbg!(minlight);
dbg!(bmp_ind);
dbg!(wrl_l);
dbg!(wrl_r);
dbg!(wrl_t);
dbg!(wrl_b);
dbg!(wrl_x);
dbg!(wrl_y);
Ok(())
}
fn sequence(b: &[u8]) -> ResultS<()>
{
// sq_type = b.c_u16b(0)?;
// flags = b.c_u16b(2)?;
let name = mac_roman_conv(pascal_str(&b[4..38])?);
let v_type = b.c_u16b(38)?;
let frames = b.c_u16b(40)?;
let ticks = b.c_u16b(42)?;
let key = b.c_u16b(44)?;
let xfer = b.c_u16b(46)?;
let xfer_pd = b.c_u16b(48)?;
let snd_beg = b.c_u16b(50)?;
let snd_key = b.c_u16b(52)?;
let snd_end = b.c_u16b(54)?;
// xform = b.c_u16b(56)?;
let loop_f = b.c_u16b(58)?;
let snd_beg = ObjID::from_repr(snd_beg);
let snd_key = ObjID::from_repr(snd_key);
let snd_end = ObjID::from_repr(snd_end);
dbg!(name);
dbg!(v_type);
dbg!(frames);
dbg!(ticks);
dbg!(key);
dbg!(xfer);
dbg!(xfer_pd);
dbg!(snd_beg);
dbg!(snd_key);
dbg!(snd_end);
dbg!(loop_f);
Ok(())
}
fn collection(b: &[u8]) -> ResultS<()>
{
let version = b.c_u16b(0)?;
let cl_type = b.c_u16b(2)?;
// flags = b.c_u16b(4)?;
let colors = b.c_u16b(6)? as usize;
let clu_num = b.c_u16b(8)? as usize;
let clu_ofs = b.c_u32b(10)? as usize;
let seq_num = b.c_u16b(14)? as usize;
let seq_ofs = b.c_u32b(16)? as usize;
let frm_num = b.c_u16b(20)? as usize;
let frm_ofs = b.c_u32b(22)? as usize;
let bmp_num = b.c_u16b(26)? as usize;
let bmp_ofs = b.c_u32b(28)? as usize;
// xform = b.c_i16b(30)?;
let size = b.c_u32b(32)? as usize;
let cl_type = CollectionType::from_repr(cl_type)?;
dbg!(version);
dbg!(cl_type);
dbg!(colors);
dbg!(clu_num);
dbg!(clu_ofs);
dbg!(seq_num);
dbg!(seq_ofs);
dbg!(frm_num);
dbg!(frm_ofs);
dbg!(bmp_num);
dbg!(bmp_ofs);
dbg!(size);
eprintln!("[end of collection]");
if version != 3 {
return Err(err_msg("invalid collection version number"));
}
for i in 0..clu_num {
for j in 0..colors {
let p = clu_ofs + 8 * j + i * 8 * colors;
color(&b[p..])?;
}
}
for i in 0..frm_num {
let p = b.c_u32b(frm_ofs + 4 * i)? as usize;
frame(&b[p..])?;
}
for i in 0..seq_num {
let p = b.c_u32b(seq_ofs + 4 * i)? as usize;
sequence(&b[p..])?;
}
Ok(())
}
pub fn testfn_replaceme(b: &[u8]) -> ResultS<()>
{
for i in 0..32 {
let p = 32 * i;
let status = b.c_u16b(p + 0)?;
let flags = b.c_u16b(p + 2)?;
let offset_lo = b.c_u32b(p + 4)? as usize;
let length_lo = b.c_u32b(p + 8)? as usize;
let offset_hi = b.c_u32b(p + 12)? as usize;
let length_hi = b.c_u32b(p + 16)? as usize;
dbg!(i);
dbg!(status);
dbg!(flags);
dbg!(offset_lo);
dbg!(length_lo);
dbg!(offset_hi);
dbg!(length_hi);
if offset_lo != u32::max_value() as usize {
collection(&b[offset_lo..offset_lo + length_lo])?;
}
if offset_hi != u32::max_value() as usize {
collection(&b[offset_hi..offset_hi + length_hi])?;
}
}
Ok(())
}
bitflags! {
pub struct FrameFlags: u16
{
const Obscure = 0x20_00;
const FlipY = 0x40_00;
const FlipX = 0x80_00;
}
}
c_enum! {
#[derive(Debug)]
pub enum CollectionType: u16
{
0 => Unused,
1 => Wall,
2 => Object,
3 => Interface,
4 => Scenery,
}
}
// EOF