From bd104fbae065d69c10d1e1dfcc3599ca0156eff9 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 8 Jul 2023 15:29:00 -0400 Subject: [PATCH] Add support for loading character .dat files --- src/chardat.rs | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 ++ src/race.rs | 6 +-- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/chardat.rs diff --git a/src/chardat.rs b/src/chardat.rs new file mode 100644 index 0000000..7953a94 --- /dev/null +++ b/src/chardat.rs @@ -0,0 +1,106 @@ +use crate::gamedata::MemoryBuffer; +use crate::sha1::Sha1; +use binrw::{binread, binrw}; +use binrw::BinRead; +use std::fs::read; +use std::io::{Cursor, Seek, SeekFrom}; +use std::ops::Sub; +use crate::race::{Gender, Race, Subrace}; + +fn convert_dat_race(x: u8) -> Race { + match x { + 1 => Race::Hyur, + 2 => Race::Elezen, + 3 => Race::Lalafell, + 4 => Race::Miqote, + 5 => Race::Roegadyn, + 6 => Race::AuRa, + 7 => Race::Hrothgar, + 8 => Race::Viera, + _ => Race::Hyur + } +} + +fn convert_dat_gender(x: u8) -> Gender { + match x { + 0 => Gender::Male, + 1 => Gender::Female, + _ => Gender::Male + } +} + +fn convert_dat_subrace(x: u8) -> Subrace { + match x { + 1 => Subrace::Midlander, + 2 => Subrace::Highlander, + 3 => Subrace::Wildwood, + 4 => Subrace::Duskwight, + 5 => Subrace::Plainsfolk, + 6 => Subrace::Dunesfolk, + 7 => Subrace::Seeker, + 8 => Subrace::Keeper, + 9 => Subrace:: SeaWolf, + 10 => Subrace::Hellsguard, + 11 => Subrace::Raen, + 12 => Subrace::Xaela, + 13 => Subrace::Hellion, + 14 => Subrace::Lost, + 15 => Subrace::Rava, + 16 => Subrace::Veena, + _ => Subrace::Midlander + } +} + +#[binread] +#[br(little)] +#[repr(C)] +#[br(magic = 0x2013FF14u32)] +#[derive(Debug)] +pub struct CharDat { // version 4 + pub version: u32, + #[br(pad_after = 4)] + pub checksum: u32, + + #[br(map = | x: u8 | convert_dat_race(x) )] + pub race: Race, + #[br(map = | x: u8 | convert_dat_gender(x) )] + pub gender: Gender, + pub age: u8, // Normal = 1, Old = 3, Young = 4 + pub height: u8, + #[br(map = | x: u8 | convert_dat_subrace(x) )] + pub subrace: Subrace, + pub head: u8, + pub hair: u8, + #[br(map = | x: u8 | x != 0 )] + pub enable_highlights: bool, + pub skin_tone: u8, + pub right_eye_color: u8, + pub hair_tone: u8, + pub highlights: u8, + pub facial_features: u8, + pub limbal_eyes: u8, + pub eyebrows: u8, + pub left_eye_color: u8, + pub eyes: u8, + pub nose: u8, + pub jaw: u8, + pub mouth: u8, + pub lips_tone_fur_pattern: u8, + pub tail: u8, + pub face_paint: u8, + pub bust: u8, + pub face_paint_color: u8, + pub voice: u8, + + #[br(pad_before = 1)] + pub timestamp: [u8; 4] +} + +impl CharDat { + /// Parses an existing dat file. + pub fn from_existing(buffer: &MemoryBuffer) -> Option { + let mut cursor = Cursor::new(buffer); + + Some(CharDat::read(&mut cursor).ok()?) + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index edbde95..232bad8 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,5 +76,8 @@ pub mod mtrl; /// Reading character parameter files (CMP) pub mod cmp; +/// Reading character save datas files (DAT) +pub mod chardat; + mod crc; mod sha1; diff --git a/src/race.rs b/src/race.rs index 1b60e3b..554c8c2 100755 --- a/src/race.rs +++ b/src/race.rs @@ -1,4 +1,4 @@ -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Debug)] #[repr(u8)] /// Gender of the character. pub enum Gender { @@ -6,7 +6,7 @@ pub enum Gender { Female, } -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Debug)] #[repr(u8)] /// The race's "subrace". Each race has two subraces, which are actually identical (even down to the ids!) /// with the exception of Hyurs, which have two unique subraces that are really two separate races. @@ -29,7 +29,7 @@ pub enum Subrace { Veena, } -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Debug)] #[repr(u8)] /// The major races of Eorzea. pub enum Race {