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

View file

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

View file

@ -35,9 +35,15 @@ impl World {
let esh: ESH = rd.read(0)?; let esh: ESH = rd.read(0)?;
dbg!(&esh); 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()?; let esh2 = esh.encode()?;
esh2.dump(Path::new("esh2.bin"))?; 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(()) Ok(())
} }