implement full decoding of ESH values
This commit is contained in:
parent
1339b4da9e
commit
c69ae933c0
3 changed files with 75 additions and 5 deletions
|
|
@ -74,7 +74,7 @@ esh data types
|
||||||
|
|
||||||
13 - frame, 48 bytes -- multiply all numbers by 4.0. I have strong feeling that it is
|
13 - frame, 48 bytes -- multiply all numbers by 4.0. I have strong feeling that it is
|
||||||
// a 3x4 translation transform matrix, because one of the dumps showed it was
|
// a 3x4 translation transform matrix, because one of the dumps showed it was
|
||||||
uint8_t unk1[36]
|
uint8_t unk1[0x24]
|
||||||
float c
|
float c
|
||||||
float b
|
float b
|
||||||
float a
|
float a
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ pub enum ESHValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ESHValue {
|
impl ESHValue {
|
||||||
|
const HDR_SIZE: usize = 8;
|
||||||
|
|
||||||
const TYPE_BOOL: u32 = 1;
|
const TYPE_BOOL: u32 = 1;
|
||||||
const TYPE_FLOAT: u32 = 2;
|
const TYPE_FLOAT: u32 = 2;
|
||||||
const TYPE_INT: u32 = 3;
|
const TYPE_INT: u32 = 3;
|
||||||
|
|
@ -60,6 +62,68 @@ impl ESHValue {
|
||||||
const TYPE_RECT: u32 = 14;
|
const TYPE_RECT: u32 = 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Decoder for ESHValue {
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
||||||
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
|
let data_type = rd.read_u32()?;
|
||||||
|
let data_size = rd.read_u32()?;
|
||||||
|
|
||||||
|
Ok(match data_type {
|
||||||
|
Self::TYPE_BOOL => ESHValue::Bool(rd.read_u8()? == 1),
|
||||||
|
Self::TYPE_FLOAT => ESHValue::Float(rd.read_f32()?),
|
||||||
|
Self::TYPE_INT => ESHValue::Int(rd.read_i32()?),
|
||||||
|
Self::TYPE_STRING => ESHValue::String(rd.read::<FString>(0)?),
|
||||||
|
Self::TYPE_SPRITE => ESHValue::Sprite(rd.read::<FString>(0)?),
|
||||||
|
Self::TYPE_ESBIN => {
|
||||||
|
let bin_size = rd.read_u32()?;
|
||||||
|
ESHValue::Binary(rd.read_bytes(bin_size as usize)?)
|
||||||
|
},
|
||||||
|
Self::TYPE_ENTTITYFLAGS => {
|
||||||
|
let entity_id = rd.read_u16()?;
|
||||||
|
let flags = rd.read_u16()?;
|
||||||
|
ESHValue::EntityFlags(ESHEntityFlags { entity_id, flags })
|
||||||
|
},
|
||||||
|
Self::TYPE_FRAME => {
|
||||||
|
let unk1 = rd.read_bytes(0x24)?;
|
||||||
|
let c = rd.read_f32()? * 4.;
|
||||||
|
let b = rd.read_f32()? * 4.;
|
||||||
|
let a = rd.read_f32()? * 4.;
|
||||||
|
ESHValue::Frame(ESHFrame { unk1, a, b, c })
|
||||||
|
},
|
||||||
|
Self::TYPE_RECT => {
|
||||||
|
let top = rd.read_i32()?;
|
||||||
|
let left = rd.read_i32()?;
|
||||||
|
let right = rd.read_i32()?;
|
||||||
|
let bottom = rd.read_i32()?;
|
||||||
|
ESHValue::Rect(ESHRect { top, left, right, bottom })
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
let data = rd.read_bytes(data_size as usize)?;
|
||||||
|
ESHValue::Unknown(ESHUnknown { data_type, data })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encode(&self) -> Result<Raw> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_enc_size(&self) -> usize {
|
||||||
|
Self::HDR_SIZE + match self {
|
||||||
|
ESHValue::Unknown(unk) => unk.data.len(),
|
||||||
|
ESHValue::Bool(_) => 1,
|
||||||
|
ESHValue::Float(_) => 4,
|
||||||
|
ESHValue::Int(_) => 4,
|
||||||
|
ESHValue::String(str) => str.get_enc_size(),
|
||||||
|
ESHValue::Sprite(spr) => spr.get_enc_size(),
|
||||||
|
ESHValue::Binary(bin) => bin.len(),
|
||||||
|
ESHValue::EntityFlags(_) => 4,
|
||||||
|
ESHValue::Frame(_) => 0x30,
|
||||||
|
ESHValue::Rect(_) => 0x10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ESH {
|
pub struct ESH {
|
||||||
pub tag: Tag,
|
pub tag: Tag,
|
||||||
|
|
@ -76,10 +140,8 @@ impl Decoder for ESH {
|
||||||
let mut props: IndexMap<FString, ESHValue> = IndexMap::with_capacity(n);
|
let mut props: IndexMap<FString, ESHValue> = IndexMap::with_capacity(n);
|
||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
let name: FString = rd.read(0)?;
|
let name: FString = rd.read(0)?;
|
||||||
let data_type = rd.read_u32()?;
|
let value: ESHValue = rd.read(0)?;
|
||||||
let data_size = rd.read_u32()? as usize;
|
props.insert(name, value);
|
||||||
let data = rd.read_bytes(data_size)?;
|
|
||||||
//props.insert(name, ESHValue { data_type, data });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let enc_size = rd.offset() - offset;
|
let enc_size = rd.offset() - offset;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ impl<'a> ReadStream<'a> {
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_u8(&mut self) -> Result<u8> {
|
||||||
|
Ok(self.rdr.read_u8()?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_u16(&mut self) -> Result<u16> {
|
pub fn read_u16(&mut self) -> Result<u16> {
|
||||||
Ok(self.rdr.read_u16::<LittleEndian>()?)
|
Ok(self.rdr.read_u16::<LittleEndian>()?)
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +103,10 @@ impl WriteStream {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_u8(&mut self, val: u8) -> Result<()> {
|
||||||
|
Ok(self.buf.write_u8(val)?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write_u16(&mut self, val: u16) -> Result<()> {
|
pub fn write_u16(&mut self, val: u16) -> Result<()> {
|
||||||
Ok(self.buf.write_u16::<LittleEndian>(val)?)
|
Ok(self.buf.write_u16::<LittleEndian>(val)?)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue