use glam::{Mat4, Vec2, Vec3, Vec4};
use ltk_hash::{BinHash, HashValue, HashWidth, WadHash};
use ltk_primitives::Color;
use crate::{property::Kind, stream::layout::Cursor, Error};
impl Cursor<'_> {
pub fn u8(&mut self) -> Result<u8, Error> {
Ok(self.take(1)?[0])
}
pub fn i8(&mut self) -> Result<i8, Error> {
Ok(self.u8()? as i8)
}
pub fn u16(&mut self) -> Result<u16, Error> {
Ok(u16::from_le_bytes(
self.take(2)?.try_into().expect("2 bytes"),
))
}
pub fn i16(&mut self) -> Result<i16, Error> {
Ok(self.u16()? as i16)
}
pub fn u32(&mut self) -> Result<u32, Error> {
Ok(u32::from_le_bytes(
self.take(4)?.try_into().expect("4 bytes"),
))
}
pub fn i32(&mut self) -> Result<i32, Error> {
Ok(self.u32()? as i32)
}
pub fn u64(&mut self) -> Result<u64, Error> {
Ok(u64::from_le_bytes(
self.take(8)?.try_into().expect("8 bytes"),
))
}
pub fn i64(&mut self) -> Result<i64, Error> {
Ok(self.u64()? as i64)
}
pub fn f32(&mut self) -> Result<f32, Error> {
Ok(f32::from_bits(self.u32()?))
}
pub fn bool(&mut self) -> Result<bool, Error> {
Ok(self.u8()? != 0)
}
pub fn vec2(&mut self) -> Result<Vec2, Error> {
Ok(Vec2::new(self.f32()?, self.f32()?))
}
pub fn vec3(&mut self) -> Result<Vec3, Error> {
Ok(Vec3::new(self.f32()?, self.f32()?, self.f32()?))
}
pub fn vec4(&mut self) -> Result<Vec4, Error> {
Ok(Vec4::new(
self.f32()?,
self.f32()?,
self.f32()?,
self.f32()?,
))
}
pub fn mat4_row_major(&mut self) -> Result<Mat4, Error> {
Ok(Mat4::from_cols(self.vec4()?, self.vec4()?, self.vec4()?, self.vec4()?).transpose())
}
pub fn color_u8(&mut self) -> Result<Color<u8>, Error> {
let rgba = self.take(4)?;
Ok(Color::new(rgba[0], rgba[1], rgba[2], rgba[3]))
}
pub fn bin_hash(&mut self) -> Result<BinHash, Error> {
Ok(BinHash(self.u32()?))
}
pub fn hash_value(&mut self) -> Result<HashValue, Error> {
Ok(match self.hash_width() {
HashWidth::W4 => HashValue::narrow(self.u32()?),
HashWidth::W8 => HashValue::wide(self.u64()?),
})
}
pub fn wad_hash(&mut self) -> Result<WadHash, Error> {
Ok(WadHash(self.u64()?))
}
pub fn kind(&mut self) -> Result<Kind, Error> {
let raw = self.u8()?;
Kind::unpack(raw, self.numbering().is_legacy())
}
}
impl<'a> Cursor<'a> {
pub fn str_u16(&mut self) -> Result<&'a str, Error> {
let len = self.u16()? as usize;
Ok(std::str::from_utf8(self.take(len)?)?)
}
}