diff --git a/MarathonData.md b/MarathonData.md index 008b8f8..eb0fecf 100644 --- a/MarathonData.md +++ b/MarathonData.md @@ -381,12 +381,13 @@ main menu, and physics files. Here is a listing of all chunks used within them: | `påth` | Not analyzed (å is $8C) (guardpaths) | | `plac` | Not analyzed (item placement) | | `door` | No test data (extra door data) | -| `PLAT` | No test data (platform static data) | -| `medi` | Media (liquids) | +| `plat` | No test data (platform data) | +| `PLAT` | Not analyzed (saved platform data) | +| `medi` | Array of Media Data | | `ambi` | Array of Ambient Sounds | | `bonk` | Array of Random Sounds | | `term` | Array of Terminals | -| `iidx` | Not analyzed (map indices) | +| `iidx` | Not analyzed (saved map indices) | | `ShPa` | Not analyzed (shapes) | | `MMLS` | Not analyzed (MML scripts) | | `LUAS` | Not analyzed (Lua scripts) | @@ -792,6 +793,34 @@ Random Sound is 32 bytes. - `Flags` is a Random Sound Flags bit field. - `Phase` must be `65535`. +### Media Data ### + +Media Data is 32 bytes. "Media" refers to liquids, presumably because of the +plural of the definition of "medium," a "middle place or degree," as in, it's a +part of the map in the middle of a wall. + +| Name | Type | Offset | +| ---- | ---- | ------ | +| `Type` | `u16` | `0` | +| `Flags` | `u16` | `2` | +| `Control` | `u16` | `4` | +| `Direction` | `angle` | `6` | +| `Magnitude` | `unit` | `8` | +| `Low` | `unit` | `10` | +| `High` | `unit` | `12` | +| `Origin` | `struct` | `14` | +| `Height` | `unit` | `18` | +| `Minimum` | `fixed` | `20` | +| `Texture` | `u16` | `24` | +| `XferMode` | `u16` | `26` | + +- `Type` is a Media Type enumeration. +- `Flags` is a Media Flags bit field. +- `Control` is the index of a light which is used to control the height of this +media. +- `Texture` is an Object ID representing the texture index. +- `XferMode` is a Transfer Mode enumeration. + ### Static Map Info ### Static Map Info is 88 bytes. @@ -1545,6 +1574,15 @@ unobstructed. - `Smooth` does a sine transition in the same fashion as `Linear`. - `Flicker` flickers between a random smoothed intensity and the final one. +### Media Type ### + +| Name | Value | +| ---- | ----- | +| `Water` | `0` | +| `Lava` | `1` | +| `Goo` | `2` | +| `Sewage` | `3` | + # FLAGS ####################################################################### ### Endpoint Flags ### @@ -1749,4 +1787,13 @@ gravity. | ---- | --- | | `IgnoreDirection` | `0` | +### Media Flags ### + +| Name | Bit | +| ---- | --- | +| `SoundObstruct` | `0` | + +- `SoundObstruct` means the media makes no sound when under the floor. This is +most sensible for, for instance, lava which can be drained. + diff --git a/src/main.rs b/src/main.rs index 6cd8851..0180bf9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,6 +57,7 @@ fn dump_chunk(opt: &Options, cid: Ident, cnk: &[u8], eid: u16) -> ResultS<()> b"OBJS" => make_yaml(opt, &rd_array(cnk, map::read_objs)?)?, b"ambi" => make_yaml(opt, &rd_array(cnk, map::read_ambi)?)?, b"bonk" => make_yaml(opt, &rd_array(cnk, map::read_bonk)?)?, + b"medi" => make_yaml(opt, &rd_array(cnk, map::read_medi)?)?, b"term" => make_yaml(opt, &rd_array(cnk, trm::read_term)?)?, _ => (), } diff --git a/src/marathon/map.rs b/src/marathon/map.rs index 8572975..e008bcc 100644 --- a/src/marathon/map.rs +++ b/src/marathon/map.rs @@ -255,6 +255,39 @@ pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)> yaw_dta, pit_nrm, pit_dta}, 32)) } +pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> +{ + read_data! { + 32, BE in b => + mtype = u16[0]; + flags = u16[2]; + control = u16[4]; + dir = u16[6]; + mag = u16[8]; + hei_lo = u16[10]; + hei_hi = u16[12]; + orig = read_point[14..18]; + hei_nrm = u16[18]; + min_lt = u32[20]; + texture = u16[24]; + xfer = u16[26]; + } + + let mtype = MediaType::from_repr(mtype)?; + let xfer = TransferMode::from_repr(xfer)?; + let texture = ObjID::from_repr(texture); + let min_lt = Fixed::from_bits(min_lt); + let hei_nrm = Unit::from_bits(hei_nrm); + let hei_hi = Unit::from_bits(hei_hi); + let hei_lo = Unit::from_bits(hei_lo); + let dir = Angle::from_bits(dir); + let mag = Unit::from_bits(mag); + let flr_obs = flags != 0; + + Ok((Media{mtype, flr_obs, control, dir, mag, hei_lo, hei_hi, orig, hei_nrm, + min_lt, texture, xfer}, 32)) +} + #[derive(Clone, PartialEq, Serialize)] pub struct Point { @@ -380,6 +413,23 @@ pub struct SoundRand pub pit_dta: Fixed, } +#[derive(Debug, Serialize)] +pub struct Media +{ + pub mtype: MediaType, + pub flr_obs: bool, + pub control: u16, + pub dir: Angle, + pub mag: Unit, + pub hei_lo: Unit, + pub hei_hi: Unit, + pub orig: Point, + pub hei_nrm: Unit, + pub min_lt: Fixed, + pub texture: ObjID, + pub xfer: TransferMode, +} + #[derive(Debug, PartialEq, Serialize)] pub struct Minf { @@ -557,6 +607,17 @@ c_enum! { } } +c_enum! { + #[derive(Debug, Serialize)] + pub enum MediaType: u16 + { + 0 => Water, + 1 => Lava, + 2 => Goo, + 3 => Sewage, + } +} + impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result