diff --git a/.gitignore b/.gitignore index ea8c4bf..dbad59f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ /target +/EDEN.DAT +/losteden.iml +/NOVO.DAT +/.idea/ diff --git a/src/main.rs b/src/main.rs index 75d2f0f..6ddb3a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,53 +1,71 @@ -use std::io::SeekFrom; use std::fs::File; -use std::io::{Read, Seek}; -use byteorder::{LittleEndian, ReadBytesExt}; -use std::fmt; +use std::io::{Read, Seek, Write}; // https://gist.github.com/falsovsky/da9a2de2c9a65282527fbd462bd92914 +// https://github.com/scummvm/scummvm/blob/90f2ff2532ca71033b4393b9ce604c9b0e6cafa0/engines/cryo/defs.h#L761 +// https://github.com/scummvm/scummvm/blob/master/engines/cryo/resource.cpp#L73 +#[derive(Debug)] +struct DatHeader { + pub total: u16, // 2621 - Para obrigar os dados começarem a partir do offset 65536 + pub files: Vec +} + +impl DatHeader { + fn new(total: u16) -> Self { + Self { total, files: Vec::new() } + } + + fn from_bytes(buffer: [u8; 2]) -> Self { + Self { + total: u16::from_le_bytes(buffer.try_into().expect("Slice with incorrect length")), + files: Vec::new() + } + } + + fn to_bytes(&self) -> [u8; 2] { + self.total.to_le_bytes() + } +} + +#[derive(Debug)] struct DatFile { - name: [u8; 12], - unknown: [u8; 4], - size: [u8; 4], - offset: [u8; 4], + // 16 Bytes - Apenas 12 Bytes usados, resto com \0 + pub name: String, + pub size: u32, + pub offset: u32, + pub flag: u8 } - -impl fmt::Debug for DatFile { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DatFile") - .field("name", &self.file_name()) - .field("size", &self.file_size()) - .field("offset", &self.file_offset()) - .finish() - } -} - impl DatFile { - fn file_name(&self) -> &str { - std::str::from_utf8(&self.name).unwrap() + fn new(name: String, size: u32, offset: u32, flag: u8) -> Self { + Self { + name, size, offset, flag + } } - fn file_size(&self) -> u32 { - let mut size_buf = &self.size[..]; - size_buf.read_u32::().unwrap() + fn from_bytes(file_bytes: [u8; 25]) -> Self { + Self { + name: std::str::from_utf8(&file_bytes[0..16]).unwrap().to_string().replace('\0', ""), + size: u32::from_le_bytes(file_bytes[16..20].try_into().expect("Slice with incorrect length")), + offset: u32::from_le_bytes(file_bytes[20..24].try_into().expect("Slice with incorrect length")), + flag: file_bytes[24] + } } - fn file_offset(&self) -> u32 { - let mut offset_buf = &self.offset[..]; - offset_buf.read_u32::().unwrap() - } -} - -struct Dat { - total: [u8; 2], -} - - -impl Dat { - fn get_value(&self) -> u16 { - let mut current = &self.total[..]; - current.read_u16::().unwrap() + fn to_bytes(&self) -> [u8; 25] { + let mut file_bytes: [u8; 25] = [0; 25]; + // name + if self.name.len() > 12 { + panic!("Filename invalido"); + } + file_bytes[0..self.name.as_bytes().len()].clone_from_slice(self.name.as_bytes()); + // size + file_bytes[16..20].clone_from_slice(&self.size.to_le_bytes()); + // offset + file_bytes[20..24].clone_from_slice(&self.offset.to_le_bytes()); + // flag + file_bytes[24] = self.flag; + file_bytes } } @@ -55,30 +73,29 @@ fn main() -> std::io::Result<()> { let mut f = File::open("EDEN.DAT")?; // Read Total Files - let mut buffer: [u8; 2] = [0; 2]; - let _ = f.read(&mut buffer); - let dat = Dat{ total: buffer }; + let mut file_dat: [u8; 2] = [0; 2]; + let _ = f.read(&mut file_dat); + let mut dat = DatHeader::from_bytes(file_dat); - // Read File Name - let mut file_name: [u8; 12] = [0; 12]; - let _ = f.read(&mut file_name); + println!("Valor: {:?} - Hex: {:02X?}", dat.total, dat.to_bytes()); - // Skip 4 bytes - f.seek(SeekFrom::Current(4)).unwrap(); + for _ in 0..dat.total { + let mut file_dat: [u8; 25] = [0; 25]; + let _ = f.read(&mut file_dat); - // Read File Size - let mut file_size: [u8; 4] = [0; 4]; - let _ = f.read(&mut file_size); + if file_dat[0] == 0 { + continue + } + let my_file = DatFile::from_bytes(file_dat); + println!("{:?} - {:02X?}", my_file, my_file.to_bytes()); + dat.files.push(my_file); + } - // Read File Offset - let mut file_offset: [u8; 4] = [0; 4]; - let _ = f.read(&mut file_offset); - - let my_file: DatFile = DatFile{ name: file_name, size: file_size, offset: file_offset }; - - println!("{:?}", my_file); - - println!("{:?}", dat.get_value()); + let mut f = File::create("NOVO.DAT")?; + let _ = f.write(&dat.to_bytes()); + for file in dat.files { + let _ = f.write(&file.to_bytes()); + } Ok(()) } \ No newline at end of file