Maraiah/maraiah/map/lite.rs

399 lines
13 KiB
Rust

//! `Light` type.
use super::{ltfn, TICKS_PER_SECOND};
use crate::{err::*, fixed::Fixed};
/// Reads a `LITE` chunk.
pub fn read(b: &[u8]) -> ResultS<(Light, usize)>
{
read_data! {
endian: BIG, buf: b, size: 100, start: 0, data {
let ltype = u16[0] enum LightType;
let flags = u16[2] flag LightFlags;
let phase = i16[4];
let act_pri = ltfn::read[6; 14];
let act_sec = ltfn::read[20; 14];
let act_mid = ltfn::read[34; 14];
let ina_pri = ltfn::read[48; 14];
let ina_sec = ltfn::read[62; 14];
let ina_mid = ltfn::read[76; 14];
let tag = u16[90];
}
}
Ok((Light{ltype, flags, phase, act_pri, act_sec, act_mid, ina_pri, ina_sec,
ina_mid, tag}, 100))
}
/// Reads an old `LITE` chunk.
pub fn read_old(b: &[u8]) -> ResultS<(Light, usize)>
{
read_data! {
endian: BIG, buf: b, size: 32, start: 0, data {
let ltype = u16[2] usize;
let mode = u16[4];
let phase = i16[6];
let min = Fixed[8];
let max = Fixed[12];
let prd = u16[16];
}
}
if OLD_LIGHT_DEFINITIONS.len() < ltype {
bail!("bad old light type");
}
let lite = &OLD_LIGHT_DEFINITIONS[ltype];
let on = mode == 0 || mode == 1;
let strobe = ltype == 3;
let flags = if on {lite.flags | LightFlags::INIT_ACTIVE} else {lite.flags};
// modify each old light function accordingly
let old_lfun = move |func: &ltfn::LightFunc| -> ltfn::LightFunc {
ltfn::LightFunc{ftype: func.ftype,
prd_nrm: if strobe {prd / 4 + 1} else {func.prd_nrm},
prd_dta: func.prd_dta,
val_nrm: if func.val_nrm > 0.into() {max} else {min},
val_dta: func.val_dta}
};
Ok((Light{flags,
phase,
act_pri: old_lfun(&lite.act_pri),
act_sec: old_lfun(&lite.act_sec),
act_mid: old_lfun(&lite.act_mid),
ina_pri: old_lfun(&lite.ina_pri),
ina_sec: old_lfun(&lite.ina_sec),
ina_mid: old_lfun(&lite.ina_mid),
tag: 0,
..*lite}, 32))
}
/// A dynamic polygon light.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Light {
pub ltype: LightType,
pub flags: LightFlags,
pub phase: i16,
pub act_pri: ltfn::LightFunc,
pub act_sec: ltfn::LightFunc,
pub act_mid: ltfn::LightFunc,
pub ina_pri: ltfn::LightFunc,
pub ina_sec: ltfn::LightFunc,
pub ina_mid: ltfn::LightFunc,
pub tag: u16,
}
c_bitfield! {
/// Flags for `Light`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct LightFlags: u16 {
INIT_ACTIVE = 0,
SLAVE_VALUE = 1,
STATELESS = 2,
}
}
c_enum! {
/// The type of a `Light`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum LightType: u16 {
Normal = 0,
Strobe = 1,
Media = 2,
}
}
const OLD_LIGHT_DEFINITIONS: [Light; 8] = [
// Normal
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
tag: 0},
// Rheostat
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 3,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 3,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Flourescent
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Fluorescent,
prd_nrm: TICKS_PER_SECOND * 3,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Strobe
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Flicker
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Flicker,
prd_nrm: TICKS_PER_SECOND * 3,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Pulsate
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2 - 1,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2 - 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2 - 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Smooth,
prd_nrm: TICKS_PER_SECOND * 2,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Annoying
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Random,
prd_nrm: 2,
prd_dta: 1,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: 2,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Random,
prd_nrm: 1,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
// Energy Efficient
Light{ltype: LightType::Normal,
flags: LightFlags::SLAVE_VALUE,
phase: 0,
act_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
act_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
act_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Linear,
prd_nrm: TICKS_PER_SECOND * 2,
prd_dta: 0,
val_nrm: Fixed::from_int(1),
val_dta: Fixed::from_int(0)},
ina_pri: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_sec: ltfn::LightFunc{ftype: ltfn::LightFuncType::Constant,
prd_nrm: TICKS_PER_SECOND,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
ina_mid: ltfn::LightFunc{ftype: ltfn::LightFuncType::Linear,
prd_nrm: TICKS_PER_SECOND * 2,
prd_dta: 0,
val_nrm: Fixed::from_int(0),
val_dta: Fixed::from_int(0)},
tag: 0},
];
// EOF