add shp.rs
parent
06524be57b
commit
dcc80def5f
|
@ -883,7 +883,7 @@ if matte:
|
|||
|
||||
### Collection Header ###
|
||||
|
||||
32 bytes
|
||||
Collection Header is 32 bytes.
|
||||
|
||||
| Type | Description | Name |
|
||||
| ---- | ----------- | ---- |
|
||||
|
@ -896,13 +896,25 @@ if matte:
|
|||
|
||||
### Collection Definition ###
|
||||
|
||||
544 bytes (no, I'm not kidding)
|
||||
Collection Definition is 544 bytes (no, I'm not kidding, there are actually 506
|
||||
unused bytes.)
|
||||
|
||||
| Type | Description | Name |
|
||||
| ---- | ----------- | ---- |
|
||||
| u16 | Version, not checked by engine (current is 3) | Version |
|
||||
| u16 | Collection Type | Type |
|
||||
| 2 bytes | Unused | |
|
||||
| u16 | Colors per CLUT | Colors |
|
||||
| u16 | Number of CLUTs | CLUNum |
|
||||
| u32 | Offset to CLUTs | CLUOfs |
|
||||
| u16 | Number of sequences | SeqNum |
|
||||
| u32 | Offset to sequences | SeqOfs |
|
||||
| u16 | Number of frames | FrmNum |
|
||||
| u32 | Offset to frames | FrmOfs |
|
||||
| u16 | Number of bitmaps | BmpNum |
|
||||
| u32 | Offset to bitmaps | BmpOfs |
|
||||
| 2 bytes | Unused | |
|
||||
| u32 | Size of entire collection | |
|
||||
|
||||
# ENUMERATIONS ################################################################
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! Text conversion utilities.
|
||||
|
||||
use crate::durandal::err::*;
|
||||
|
||||
/// Dumps a slice of memory as text to stderr.
|
||||
pub fn dump_mem(b: &[u8])
|
||||
{
|
||||
|
@ -66,6 +68,21 @@ pub fn fuck_string(s: &[u8]) -> Vec<u8>
|
|||
v
|
||||
}
|
||||
|
||||
/// Reads a Pascal-style byte string with bounds checking.
|
||||
pub fn pascal_str(b: &[u8]) -> ResultS<&[u8]>
|
||||
{
|
||||
if b.len() < 1 {
|
||||
Err(err_msg("not enough data for string"))
|
||||
} else {
|
||||
let s = b[0] as usize;
|
||||
if s + 1 > b.len() {
|
||||
Err(err_msg("not enough data in string"))
|
||||
} else {
|
||||
Ok(&b[1..1 + s])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts input from Mac Roman to a Unicode string.
|
||||
pub fn mac_roman_conv(s: &[u8]) -> String
|
||||
{
|
||||
|
|
66
src/main.rs
66
src/main.rs
|
@ -78,73 +78,9 @@ fn process_wad(b: &[u8]) -> ResultS<()>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn collection(b: &[u8]) -> ResultS<()>
|
||||
{
|
||||
let version = b.c_u16b(0)?;
|
||||
let dt_type = b.c_u16b(2)?;
|
||||
let flags = b.c_u16b(4)?;
|
||||
let colors = b.c_u16b(6)?;
|
||||
let clu_num = b.c_u16b(8)?;
|
||||
let clu_ofs = b.c_u32b(10)?;
|
||||
let seq_num = b.c_u16b(14)?;
|
||||
let seq_ofs = b.c_u32b(16)?;
|
||||
let frm_num = b.c_u16b(20)?;
|
||||
let frm_ofs = b.c_u32b(22)?;
|
||||
let bmp_num = b.c_u16b(26)?;
|
||||
let bmp_ofs = b.c_u32b(28)?;
|
||||
let scale = b.c_i16b(30)?;
|
||||
let size = b.c_u32b(32)?;
|
||||
dbg!(version);
|
||||
dbg!(dt_type);
|
||||
dbg!(flags);
|
||||
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!(scale);
|
||||
dbg!(size);
|
||||
eprintln!("[end of collection]");
|
||||
|
||||
if version != 3 {
|
||||
return Err(err_msg("invalid collection version number"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_shp(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 {
|
||||
eprintln!("collection {} has lo-res frames", i);
|
||||
collection(&b[offset_lo..offset_lo + length_lo])?;
|
||||
}
|
||||
if offset_hi != u32::max_value() as usize {
|
||||
eprintln!("collection {} has hi-res frames", i);
|
||||
collection(&b[offset_hi..offset_hi + length_hi])?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
shp::testfn_replaceme(b)
|
||||
}
|
||||
|
||||
fn main() -> ResultS<()>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
pub mod machdr;
|
||||
pub mod map;
|
||||
pub mod pict;
|
||||
pub mod shp;
|
||||
pub mod term;
|
||||
pub mod wad;
|
||||
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
//! 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
|
Loading…
Reference in New Issue