Skip to content

Commit

Permalink
WIP: feat(deserailize): Add bincode and deserialize
Browse files Browse the repository at this point in the history
Signed-off-by: dark0dave <dark0dave@mykolab.com>
  • Loading branch information
dark0dave committed Nov 12, 2023
1 parent 24d41b3 commit a5021b5
Show file tree
Hide file tree
Showing 31 changed files with 574 additions and 222 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 32 additions & 9 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
pub mod args;
use std::{
fs::{self, File},
io::{BufReader, Read},
io::{BufReader, Read, Write},
path::Path,
process::exit,
str,
};

use args::Args;
Expand All @@ -13,12 +14,31 @@ use models::{
key::Key,
model::Model,
resources::types::{extention_to_resource_type, ResourceType},
spell::Spell,
tlk::Lookup,
};

use erased_serde::Serializer;

fn write_file(path: &Path, model: std::rc::Rc<dyn Model>) {
fn write_file(path: &Path, extension: &str, buffer: &[u8]) {
let file_name = Path::new(path.file_stem().unwrap_or_default()).with_extension(extension);
if let Ok(mut file) = File::create(file_name) {
if let Err(err) = file.write_all(buffer) {
println!("Error: {}", err);
}
}
}

fn json_back_to_ie_type(path: &Path) {
let file_contents = read_file(path);
if let Ok(spell) = serde_json::from_slice::<Spell>(&file_contents) {
write_file(path, "spl", &spell.to_bytes())
} else {
panic!("Could not convert back to model")
}
}

fn write_model(path: &Path, model: std::rc::Rc<dyn Model>) {
let file_name = Path::new(path.file_stem().unwrap_or_default()).with_extension("json");
if let Ok(file) = File::create(file_name) {
let mut json = serde_json::Serializer::new(file);
Expand All @@ -29,7 +49,7 @@ fn write_file(path: &Path, model: std::rc::Rc<dyn Model>) {
}
}

fn from_file(path: &Path) -> Vec<u8> {
fn read_file(path: &Path) -> Vec<u8> {
let file = File::open(path).unwrap_or_else(|_| panic!("Could not open file: {:#?}", path));
let mut reader = BufReader::new(file);
let mut buffer = Vec::new();
Expand All @@ -40,7 +60,7 @@ fn from_file(path: &Path) -> Vec<u8> {
}

fn parse_tlk_file(path: &Path) -> Lookup {
let buffer = from_file(path);
let buffer = read_file(path);
Lookup::new(&buffer)
}

Expand All @@ -51,14 +71,14 @@ fn parse_key_file(path: &Path, buffer: &[u8]) -> Vec<Biff> {
key.bif_entries
.iter()
.map(|bif_ref| {
let buffer = from_file(&parent.join(bif_ref.name.to_string()).with_extension("bif"));
let buffer = read_file(&parent.join(bif_ref.name.to_string()).with_extension("bif"));
Biff::new(&buffer)
})
.collect()
}

fn get_model_from_file(path: &Path, json: bool) -> Vec<Biff> {
let buffer = from_file(path);
let buffer = read_file(path);
let extention = path
.extension()
.unwrap_or_default()
Expand All @@ -71,15 +91,18 @@ fn get_model_from_file(path: &Path, json: bool) -> Vec<Biff> {
if resource_type == ResourceType::NotFound {
return match extention.as_str() {
"key" => parse_key_file(path, &buffer),
"biff" => vec![Biff::new(&from_file(path))],
"json" => panic!(),
"biff" => vec![Biff::new(&read_file(path))],
"json" => {
json_back_to_ie_type(&path);
exit(0)
}
_ => panic!("Unprocessable file type: {:?}", path.as_os_str()),
};
}

let model = from_buffer(&buffer, resource_type).expect("Could not parse file");
if json {
write_file(path, model);
write_model(path, model);
} else {
println!("{:?}", model);
}
Expand Down
Binary file added gate1.spl
Binary file not shown.
7 changes: 6 additions & 1 deletion models/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@ edition = "2021"

[dependencies]
erased-serde = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0.189", features = ["derive"] }

[dev-dependencies]
pretty_assertions = "1.3.0"
serde_json = "1.0.94"
tempfile = "3"
63 changes: 34 additions & 29 deletions models/src/area.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::rc::Rc;

use serde::Serialize;
use serde::{Deserialize, Serialize};

use crate::common::header::Header;
use crate::item_table::ItemReferenceTable;
Expand All @@ -9,7 +9,8 @@ use crate::resources::utils::{copy_buff_to_struct, copy_transmute_buff};
use crate::tlk::Lookup;
use crate::{common::fixed_char_array::FixedCharSlice, game::GlobalVarriables};

#[derive(Debug, Serialize)]
#[repr(C)]
#[derive(Debug, Serialize, Deserialize)]
pub struct Area {
pub header: FileHeader,
pub actors: Vec<Actor>,
Expand Down Expand Up @@ -108,11 +109,15 @@ impl Model for Area {
fn name(&self, _lookup: &Lookup) -> String {
self.header.area_wed.to_string().replace(".WED", ".ARE")
}

fn to_bytes(&self) -> Vec<u8> {
todo!()
}
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Header
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct FileHeader {
pub header: Header<4, 4>,
pub area_wed: FixedCharSlice<8>,
Expand Down Expand Up @@ -173,12 +178,12 @@ pub struct FileHeader {
// bgee and bg2:tob
pub rest_movie_night: FixedCharSlice<8>,
#[serde(skip_serializing)]
_unused: [u8; 56],
_unused: FixedCharSlice<56>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Actor
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Deserialize, Serialize)]
pub struct Actor {
pub name: FixedCharSlice<32>,
pub current_x_coordinate: u16,
Expand Down Expand Up @@ -209,12 +214,12 @@ pub struct Actor {
pub offset_to_cre_structure: u32,
pub size_of_stored_cre_structure: u32,
#[serde(skip_serializing)]
pub _unused_2: [u8; 128],
pub _unused_2: FixedCharSlice<128>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Info
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Region {
pub name: FixedCharSlice<32>,
pub region_type: u16,
Expand Down Expand Up @@ -249,7 +254,7 @@ pub struct Region {

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Spawn
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct SpawnPoint {
pub name: FixedCharSlice<32>,
pub x_coordinate: u16,
Expand Down Expand Up @@ -301,24 +306,24 @@ pub struct SpawnPoint {
// Offset 0x006c
pub spawn_weight_of_10th_creature_slot: u8,
#[serde(skip_serializing)]
pub unused: [u8; 38],
pub unused: FixedCharSlice<38>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Entrance
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Entrance {
pub name: FixedCharSlice<32>,
pub x_coordinate: u16,
pub y_coordinate: u16,
pub orientation: u16,
#[serde(skip_serializing)]
pub unused: [u8; 66],
pub unused: FixedCharSlice<66>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Container
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Container {
pub name: FixedCharSlice<32>,
pub x_coordinate: u16,
Expand Down Expand Up @@ -349,22 +354,22 @@ pub struct Container {
pub break_difficulty: u32,
pub lockpick_string: FixedCharSlice<4>,
#[serde(skip_serializing)]
pub unused: [u8; 56],
pub unused: FixedCharSlice<56>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Item
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct AreaItem(pub ItemReferenceTable);

// An array of points used to create the outlines of regions and containers. Elements are 16-bit words stored x0, y0, x1, y1 etc.
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Vertice(pub u16);

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Ambient
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Ambients {
pub name: FixedCharSlice<32>,
pub x_coordinate: u16,
Expand All @@ -391,22 +396,22 @@ pub struct Ambients {
pub ambient_appearence_schedule: u32,
pub flags: u32,
#[serde(skip_serializing)]
_unused_2: [u8; 64],
_unused_2: FixedCharSlice<64>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Variable
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct AreaVarriable(pub GlobalVarriables);

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Explored
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct ExploredBitmask(pub u8);

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Door
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Door {
pub name: FixedCharSlice<32>,
// Link with WED
Expand Down Expand Up @@ -450,7 +455,7 @@ pub struct Door {

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Anim
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Animation {
pub name: FixedCharSlice<32>,
pub x_coordinate: u16,
Expand All @@ -477,7 +482,7 @@ pub struct Animation {

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Automap
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct AutomapNotesBGEE {
pub x_coordinate: u16,
pub y_coordinate: u16,
Expand All @@ -488,12 +493,12 @@ pub struct AutomapNotesBGEE {
pub colour: u16,
pub note_count: u32,
#[serde(skip_serializing)]
pub unused: [u8; 36],
pub unused: FixedCharSlice<36>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_TiledObj
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct TiledObject {
pub name: FixedCharSlice<32>,
pub tile_id: FixedCharSlice<8>,
Expand All @@ -503,12 +508,12 @@ pub struct TiledObject {
pub count_of_closed_search_squares: u16,
pub offset_to_closed_search_squares: u32,
#[serde(skip_serializing)]
pub unused: [u8; 48],
pub unused: FixedCharSlice<48>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_ProjTraps
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct ProjectileTrap {
pub projectile_resref: FixedCharSlice<8>,
pub effect_block_offset: u32,
Expand All @@ -525,7 +530,7 @@ pub struct ProjectileTrap {

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Song_entries
#[repr(C, packed)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct SongEntry {
pub day_song_reference_number: u32,
pub night_song_reference_number: u32,
Expand All @@ -545,7 +550,7 @@ pub struct SongEntry {
pub main_night_ambient_volume_percent: u32,
pub reverb_or_unused: u32,
#[serde(skip_serializing)]
pub unused: [u8; 60],
pub unused: FixedCharSlice<60>,
}

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/are_v1.htm#formAREAV1_0_Rest_Interruptions
Expand All @@ -566,5 +571,5 @@ pub struct RestInterruption {
pub probability_day_per_hour: u16,
pub probability_night_per_hour: u16,
#[serde(skip_serializing)]
pub unused: [u8; 56],
pub unused: FixedCharSlice<56>,
}
1 change: 1 addition & 0 deletions models/src/biff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::resources::utils::{copy_buff_to_struct, copy_transmute_buff};
use crate::{from_buffer, model::Model, resources::types::ResourceType};

// https://gibberlings3.github.io/iesdp/file_formats/ie_formats/bif_v1.htm
#[repr(C)]
#[derive(Debug)]
pub struct Biff {
pub header: BiffHeader,
Expand Down
Loading

0 comments on commit a5021b5

Please sign in to comment.