start implementing SGD

This commit is contained in:
mykola2312 2023-08-30 20:57:05 +03:00
parent 236bf7fdca
commit a52aed8934
7 changed files with 97 additions and 6 deletions

23
Cargo.lock generated
View file

@ -44,6 +44,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fot-save-edit"
version = "0.1.0"
@ -52,10 +58,27 @@ dependencies = [
"byteorder",
"deflate",
"encoding_rs",
"indexmap",
"inflate",
"memmem",
]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "inflate"
version = "0.4.5"

View file

@ -10,5 +10,6 @@ anyhow = "1.0.75"
byteorder = "1.4.3"
deflate = "1.0.0"
encoding_rs = "0.8.33"
indexmap = "2.0.0"
inflate = "0.4.5"
memmem = "0.1.1"

View file

@ -2,6 +2,7 @@ mod decoder;
mod fstring;
mod raw;
pub mod save;
mod sgd;
mod stream;
mod tag;
mod world;

View file

@ -7,13 +7,13 @@ use std::io::Cursor;
// FString - Fallout
#[derive(Debug, PartialEq)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub enum FStringEncoding {
ANSI,
WCS2,
}
#[derive(Debug)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct FString {
pub encoding: FStringEncoding,
pub enc_len: usize,

57
src/fot/sgd.rs Normal file
View file

@ -0,0 +1,57 @@
use super::decoder::Decoder;
use super::fstring::FString;
use super::raw::Raw;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::Result;
use indexmap::IndexMap;
pub struct SGD {
tag: Tag,
unk1: Vec<u8>,
pub dialogs: IndexMap<FString, Vec<FString>>,
enc_size: usize,
}
impl Decoder for SGD {
fn decode(raw: &Raw, offset: usize, size: usize) -> Result<Self> {
let mut rd = ReadStream::new(raw, offset);
let tag: Tag = rd.read(0)?;
let unk1 = rd.read_bytes(0x48)?;
let mut dialogs: IndexMap<FString, Vec<FString>> = IndexMap::new();
let n = rd.read_u32()? as usize;
let mut names: Vec<FString> = Vec::with_capacity(n);
for _ in 0..n {
names.push(rd.read::<FString>(0)?);
}
let m = rd.read_u32()? as usize;
assert!(m == n, "SGD m != n");
for _ in 0..m {
let k = rd.read_u32()? as usize;
let mut lines: Vec<FString> = Vec::with_capacity(k);
for _ in 0..k {
lines.push(rd.read::<FString>(0)?);
}
dialogs.insert(names.remove(m), lines);
}
let enc_size = rd.offset() - offset;
Ok(SGD {
tag,
unk1,
dialogs,
enc_size,
})
}
fn encode(&self) -> Result<Raw> {
todo!();
}
fn get_enc_size(&self) -> usize {
todo!()
}
}

View file

@ -1,5 +1,6 @@
use super::decoder::Decoder;
use super::raw::Raw;
use anyhow::anyhow;
use anyhow::Result;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::Cursor;
@ -10,9 +11,9 @@ pub struct ReadStream<'a> {
}
impl<'a> ReadStream<'a> {
pub fn new(raw: &Raw, start: usize) -> ReadStream {
pub fn new(raw: &Raw, offset: usize) -> ReadStream {
let mut rdr = Cursor::new(&raw.mem[..]);
rdr.set_position(start as u64);
rdr.set_position(offset as u64);
ReadStream { raw: raw, rdr: rdr }
}
@ -24,6 +25,14 @@ impl<'a> ReadStream<'a> {
self.rdr.set_position(self.rdr.position() + size as u64);
}
pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
if self.offset() + size > self.raw.mem.len() {
Err(anyhow!("read_bytes size is bigger than buffer"))
} else {
Ok(self.raw.mem[self.offset()..self.offset() + size].to_vec())
}
}
pub fn read<T: Decoder>(&mut self, size: usize) -> Result<T> {
let val = T::decode(&self.raw, self.offset(), size)?;
self.skip(val.get_enc_size());

View file

@ -1,6 +1,6 @@
use super::stream::{ReadStream, WriteStream};
use super::decoder::Decoder;
use super::raw::Raw;
use super::stream::{ReadStream, WriteStream};
use anyhow::Result;
#[derive(Debug)]