fixed bug wihen WriteStream::write_bytes wrote data at wrong position. ESH encoding and decoding fully implemented and tested

This commit is contained in:
mykola2312 2023-08-31 12:12:33 +03:00
parent bc339d57a6
commit 8fe330b368
3 changed files with 27 additions and 10 deletions

View file

@ -18,6 +18,10 @@ pub struct ESHEntityFlags {
pub flags: u16,
}
impl ESHEntityFlags {
const SIZE: usize = 4;
}
#[derive(Debug)]
pub struct ESHFrame {
pub unk1: Vec<u8>,
@ -26,6 +30,10 @@ pub struct ESHFrame {
pub c: f32,
}
impl ESHFrame {
const SIZE: usize = 48;
}
#[derive(Debug)]
pub struct ESHRect {
pub top: i32,
@ -34,6 +42,10 @@ pub struct ESHRect {
pub bottom: i32,
}
impl ESHRect {
const SIZE: usize = 16;
}
#[derive(Debug)]
pub enum ESHValue {
Unknown(ESHUnknown),
@ -75,8 +87,7 @@ impl Decoder for ESHValue {
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)?)
ESHValue::Binary(rd.read_bytes(data_size as usize)?)
}
Self::TYPE_ENTTITYFLAGS => {
let entity_id = rd.read_u16()?;
@ -156,14 +167,14 @@ impl Decoder for ESHValue {
}
ESHValue::EntityFlags(eflags) => {
wd.write_u32(Self::TYPE_ENTTITYFLAGS)?;
wd.write_u32(4)?;
wd.write_u32(ESHEntityFlags::SIZE as u32)?;
wd.write_u16(eflags.entity_id)?;
wd.write_u16(eflags.flags)?;
}
ESHValue::Frame(frame) => {
wd.write_u32(Self::TYPE_FRAME)?;
wd.write_u32(0x24)?;
wd.write_u32(ESHFrame::SIZE as u32)?;
wd.write_bytes(&frame.unk1);
wd.write_f32(frame.c / 4.)?;
@ -172,7 +183,7 @@ impl Decoder for ESHValue {
}
ESHValue::Rect(rect) => {
wd.write_u32(Self::TYPE_RECT)?;
wd.write_u32(0x10)?;
wd.write_u32(ESHRect::SIZE as u32)?;
wd.write_i32(rect.top)?;
wd.write_i32(rect.left)?;
@ -194,9 +205,9 @@ impl Decoder for ESHValue {
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,
ESHValue::EntityFlags(_) => ESHEntityFlags::SIZE,
ESHValue::Frame(_) => ESHFrame::SIZE,
ESHValue::Rect(_) => ESHRect::SIZE,
}
}
}

View file

@ -98,8 +98,8 @@ impl WriteStream {
}
pub fn write_bytes(&mut self, bytes: &[u8]) {
self.buf.get_mut().extend(bytes.iter());
self.skip(bytes.len());
self.buf.get_mut().extend(bytes.iter());
}
pub fn write<T: Decoder>(&mut self, val: &T) -> Result<()> {

View file

@ -35,9 +35,15 @@ impl World {
let esh: ESH = rd.read(0)?;
dbg!(&esh);
let esh1 = Raw {
offset: 0,
size: 0,
mem: self.data.mem[0x14AC..0x14AC+esh.get_enc_size()].to_vec()
};
esh1.dump(Path::new("esh1.bin"))?;
let esh2 = esh.encode()?;
esh2.dump(Path::new("esh2.bin"))?;
assert_eq!(&self.data.mem[0x14AC..0x14AC+esh.get_enc_size()], &esh2.mem, "ESH encoding test passed");
assert_eq!(esh1.mem, esh2.mem, "ESH encoding test passed");
Ok(())
}