399 lines
18 KiB
Rust
399 lines
18 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: <fn::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
|