1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-20 19:57:45 +00:00

Run rustfmt and fix more Clippy warnings

This commit is contained in:
Joshua Goins 2024-05-18 09:42:07 -04:00
parent 306a507969
commit e5caab2e64
23 changed files with 174 additions and 161 deletions

View file

@ -1,11 +1,11 @@
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use physis::common::Platform;
use physis::gamedata::GameData;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use physis::common::Platform;
use physis::gamedata::GameData;
/// A simple program that allows a user to extract raw files from the game /// A simple program that allows a user to extract raw files from the game
fn main() { fn main() {
@ -44,5 +44,8 @@ fn main() {
return; return;
}; };
println!("Successfully extracted {} to {}!", file_path, destination_path); println!(
} "Successfully extracted {} to {}!",
file_path, destination_path
);
}

View file

@ -2,19 +2,17 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::io::{Cursor, Seek, SeekFrom}; use std::io::{Cursor, Seek, SeekFrom};
use std::ptr::read;
use crate::ByteSpan; use crate::ByteSpan;
use binrw::{binread, BinReaderExt, binrw};
use binrw::BinRead; use binrw::BinRead;
use crate::dat::Block; use binrw::{binread, binrw, BinReaderExt};
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
#[brw(little)] #[brw(little)]
struct AvfxHeader { struct AvfxHeader {
name: u32, name: u32,
size: u32 size: u32,
} }
#[binread] #[binread]
@ -291,17 +289,11 @@ impl Avfx {
let mut avfx = Avfx::default(); let mut avfx = Avfx::default();
let read_bool = |cursor: &mut Cursor<ByteSpan>| { let read_bool = |cursor: &mut Cursor<ByteSpan>| cursor.read_le::<u8>().unwrap() == 1u8;
return cursor.read_le::<u8>().unwrap() == 1u8;
};
let read_uint = |cursor: &mut Cursor<ByteSpan>| { let read_uint = |cursor: &mut Cursor<ByteSpan>| cursor.read_le::<u32>().unwrap();
return cursor.read_le::<u32>().unwrap();
};
let read_float = |cursor: &mut Cursor<ByteSpan>| { let read_float = |cursor: &mut Cursor<ByteSpan>| cursor.read_le::<f32>().unwrap();
return cursor.read_le::<f32>().unwrap();
};
while cursor.position() < header.size as u64 { while cursor.position() < header.size as u64 {
let last_pos = cursor.position(); let last_pos = cursor.position();
@ -522,7 +514,7 @@ impl Avfx {
let new_pos = cursor.position(); let new_pos = cursor.position();
let read_bytes = (new_pos - last_pos) - 8; let read_bytes = (new_pos - last_pos) - 8;
let padding = block.size as u64 - read_bytes; let padding = block.size as u64 - read_bytes;
cursor.seek(SeekFrom::Current(padding as i64)); cursor.seek(SeekFrom::Current(padding as i64)).ok()?;
} }
Some(avfx) Some(avfx)

View file

@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::io::SeekFrom;
use binrw::{binread, BinReaderExt, BinResult}; use binrw::{binread, BinReaderExt, BinResult};
use half::f16; use half::f16;
use std::io::SeekFrom;
pub(crate) fn read_bool_from<T: std::convert::From<u8> + std::cmp::PartialEq>(x: T) -> bool { pub(crate) fn read_bool_from<T: std::convert::From<u8> + std::cmp::PartialEq>(x: T) -> bool {
x == T::from(1u8) x == T::from(1u8)
@ -17,17 +17,19 @@ pub(crate) fn write_bool_as<T: std::convert::From<u8>>(x: &bool) -> T {
} }
} }
#[binrw::parser(reader, endian)] #[binrw::parser(reader)]
pub(crate) fn strings_parser(base_offset: u64, strings_offset: &Vec<u16>) -> BinResult<Vec<String>> { pub(crate) fn strings_parser(
let mut strings: Vec<String> = base_offset: u64,
vec![]; strings_offset: &Vec<u16>,
) -> BinResult<Vec<String>> {
let mut strings: Vec<String> = vec![];
for offset in strings_offset { for offset in strings_offset {
let string_offset = base_offset + *offset as u64; let string_offset = base_offset + *offset as u64;
let mut string = String::new(); let mut string = String::new();
reader.seek(SeekFrom::Start(string_offset as u64))?; reader.seek(SeekFrom::Start(string_offset))?;
let mut next_char = reader.read_le::<u8>().unwrap() as char; let mut next_char = reader.read_le::<u8>().unwrap() as char;
while next_char != '\0' { while next_char != '\0' {
string.push(next_char); string.push(next_char);
@ -42,7 +44,7 @@ pub(crate) fn strings_parser(base_offset: u64, strings_offset: &Vec<u16>) -> Bin
fn read_half1(data: [u16; 1]) -> Half1 { fn read_half1(data: [u16; 1]) -> Half1 {
Half1 { Half1 {
value: f16::from_bits(data[0]) value: f16::from_bits(data[0]),
} }
} }
@ -56,7 +58,7 @@ pub(crate) struct Half1 {
fn read_half2(data: [u16; 2]) -> Half2 { fn read_half2(data: [u16; 2]) -> Half2 {
Half2 { Half2 {
x: f16::from_bits(data[0]), x: f16::from_bits(data[0]),
y: f16::from_bits(data[0]) y: f16::from_bits(data[0]),
} }
} }
@ -72,7 +74,7 @@ fn read_half3(data: [u16; 3]) -> Half3 {
Half3 { Half3 {
r: f16::from_bits(data[0]), r: f16::from_bits(data[0]),
g: f16::from_bits(data[0]), g: f16::from_bits(data[0]),
b: f16::from_bits(data[0]) b: f16::from_bits(data[0]),
} }
} }
@ -82,7 +84,7 @@ fn read_half3(data: [u16; 3]) -> Half3 {
pub(crate) struct Half3 { pub(crate) struct Half3 {
pub r: f16, pub r: f16,
pub g: f16, pub g: f16,
pub b: f16 pub b: f16,
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::ops::{Add, AddAssign, BitXor, BitXorAssign};
use libz_ng_sys::z_off_t; use libz_ng_sys::z_off_t;
use std::ops::{Add, AddAssign, BitXor, BitXorAssign};
/// CRC used for filepath hashes in index file /// CRC used for filepath hashes in index file
pub(crate) struct Jamcrc { pub(crate) struct Jamcrc {
@ -49,7 +49,7 @@ fn crc32(crc: u32, s: &[u8]) -> u32 {
} }
fn crc32_combine(crc1: u32, crc2: u32, len2: usize) -> u32 { fn crc32_combine(crc1: u32, crc2: u32, len2: usize) -> u32 {
unsafe { libz_ng_sys::crc32_combine(crc1, crc2, len2 as z_off_t) as u32 } unsafe { libz_ng_sys::crc32_combine(crc1, crc2, len2 as z_off_t) as u32 }
} }
/// CRC used for shader keys /// CRC used for shader keys
@ -62,10 +62,7 @@ pub(crate) struct XivCrc32 {
impl XivCrc32 { impl XivCrc32 {
pub(crate) fn new(crc: u32, len: usize) -> Self { pub(crate) fn new(crc: u32, len: usize) -> Self {
Self { Self { crc, len }
crc,
len,
}
} }
} }
@ -75,7 +72,7 @@ impl From<&[u8]> for XivCrc32 {
} }
} }
impl <const N: usize> From<&[u8; N]> for XivCrc32 { impl<const N: usize> From<&[u8; N]> for XivCrc32 {
fn from(s: &[u8; N]) -> Self { fn from(s: &[u8; N]) -> Self {
Self::new(!crc32(0xFFFFFFFF, s), N) Self::new(!crc32(0xFFFFFFFF, s), N)
} }
@ -91,7 +88,10 @@ impl Add<XivCrc32> for XivCrc32 {
type Output = XivCrc32; type Output = XivCrc32;
fn add(self, rhs: XivCrc32) -> Self::Output { fn add(self, rhs: XivCrc32) -> Self::Output {
Self::new(crc32_combine(self.crc, rhs.crc, rhs.len), self.len + rhs.len) Self::new(
crc32_combine(self.crc, rhs.crc, rhs.len),
self.len + rhs.len,
)
} }
} }
@ -119,8 +119,8 @@ impl BitXorAssign<XivCrc32> for XivCrc32 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crc::{Algorithm, Crc};
use super::*; use super::*;
use crc::{Algorithm, Crc};
#[test] #[test]
fn check_jamcrc() { fn check_jamcrc() {
@ -137,7 +137,16 @@ mod tests {
#[test] #[test]
fn check_xivcrc() { fn check_xivcrc() {
const CRC_32_TEST: Algorithm<u32> = Algorithm { width: 32, poly: 0x04c11db7, init: 0x00000000, refin: true, refout: true, xorout: 0x00000000, check: 0x765e7680, residue: 0xc704dd7b }; const CRC_32_TEST: Algorithm<u32> = Algorithm {
width: 32,
poly: 0x04c11db7,
init: 0x00000000,
refin: true,
refout: true,
xorout: 0x00000000,
check: 0x765e7680,
residue: 0xc704dd7b,
};
const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_TEST); const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_TEST);
let str = "Default"; let str = "Default";

View file

@ -157,11 +157,11 @@ impl GameData {
/// } /// }
/// ``` /// ```
pub fn exists(&mut self, path: &str) -> bool { pub fn exists(&mut self, path: &str) -> bool {
let Some(index_path) = self.get_index_filenames(path) else { let Some((_, _)) = self.get_index_filenames(path) else {
return false; return false;
}; };
return self.find_entry(path).is_some(); self.find_entry(path).is_some()
} }
/// Extracts the file located at `path`. This is returned as an in-memory buffer, and will usually /// Extracts the file located at `path`. This is returned as an in-memory buffer, and will usually
@ -225,8 +225,8 @@ impl GameData {
&repository.name, &repository.name,
&repository.index_filename(chunk, category), &repository.index_filename(chunk, category),
] ]
.iter() .iter()
.collect(); .collect();
index1_filenames.push((index_path.into_os_string().into_string().unwrap(), chunk)); index1_filenames.push((index_path.into_os_string().into_string().unwrap(), chunk));
@ -236,16 +236,13 @@ impl GameData {
&repository.name, &repository.name,
&repository.index2_filename(chunk, category), &repository.index2_filename(chunk, category),
] ]
.iter() .iter()
.collect(); .collect();
index2_filenames.push((index2_path.into_os_string().into_string().unwrap(), chunk)); index2_filenames.push((index2_path.into_os_string().into_string().unwrap(), chunk));
} }
Some(( Some((index1_filenames, index2_filenames))
index1_filenames,
index2_filenames
))
} }
/// Read an excel sheet by name (e.g. "Achievement") /// Read an excel sheet by name (e.g. "Achievement")
@ -408,8 +405,7 @@ impl GameData {
fn cache_index2_file(&mut self, filename: &str) { fn cache_index2_file(&mut self, filename: &str) {
if !self.index2_files.contains_key(filename) { if !self.index2_files.contains_key(filename) {
if let Some(index_file) = Index2File::from_existing(filename) { if let Some(index_file) = Index2File::from_existing(filename) {
self.index2_files self.index2_files.insert(filename.to_string(), index_file);
.insert(filename.to_string(), index_file);
} }
} }
} }

View file

@ -18,8 +18,7 @@ impl Hwc {
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let mut rgba = Vec::new(); let mut rgba = vec![0; CURSOR_WIDTH * CURSOR_HEIGHT * 4];
rgba.resize(CURSOR_WIDTH * CURSOR_HEIGHT * 4, 0);
cursor.read_exact(&mut rgba).ok()?; cursor.read_exact(&mut rgba).ok()?;
Some(Self { rgba }) Some(Self { rgba })

View file

@ -9,7 +9,6 @@ use crate::common::Platform;
use crate::crc::Jamcrc; use crate::crc::Jamcrc;
use binrw::binrw; use binrw::binrw;
use binrw::BinRead; use binrw::BinRead;
use modular_bitfield::prelude::*;
#[binrw] #[binrw]
#[br(magic = b"SqPack\0\0")] #[br(magic = b"SqPack\0\0")]
@ -40,7 +39,7 @@ pub struct SqPackIndexHeader {
dir_index_data_hash: [u8; 64], dir_index_data_hash: [u8; 64],
index_type: u32, index_type: u32,
#[br(pad_before = 656)] #[br(pad_before = 656)]
self_hash: [u8; 64] self_hash: [u8; 64],
} }
#[binrw] #[binrw]

View file

@ -12,20 +12,18 @@ use binrw::BinRead;
#[brw(little)] #[brw(little)]
struct IwcHeader { struct IwcHeader {
count: u16, count: u16,
part_mask: u16 part_mask: u16,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Iwc { pub struct Iwc {}
}
impl Iwc { impl Iwc {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = IwcHeader::read(&mut cursor).ok()?; IwcHeader::read(&mut cursor).ok()?;
Some(Iwc{}) Some(Iwc {})
} }
} }

View file

@ -752,7 +752,9 @@ impl MDL {
for shape_value in shape_values { for shape_value in shape_values {
let old_vertex = let old_vertex =
vertices[indices[shape_value.base_indices_index as usize] as usize]; vertices[indices[shape_value.base_indices_index as usize] as usize];
let new_vertex = vertices[(shape_value.replacing_vertex_index as usize).saturating_sub(model.meshes[j as usize].start_index as usize)]; let new_vertex = vertices[(shape_value.replacing_vertex_index
as usize)
.saturating_sub(model.meshes[j as usize].start_index as usize)];
let vertex = &mut morphed_vertices let vertex = &mut morphed_vertices
[indices[shape_value.base_indices_index as usize] as usize]; [indices[shape_value.base_indices_index as usize] as usize];

View file

@ -5,9 +5,9 @@
use std::io::Cursor; use std::io::Cursor;
use crate::ByteSpan;
use binrw::{binrw, BinRead, binread};
use crate::common_file_operations::{Half1, Half2, Half3}; use crate::common_file_operations::{Half1, Half2, Half3};
use crate::ByteSpan;
use binrw::{binread, binrw, BinRead};
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
@ -139,7 +139,7 @@ pub struct ConstantStruct {
pub struct Constant { pub struct Constant {
id: u32, id: u32,
num_values: u32, num_values: u32,
values: [f32; 4] values: [f32; 4],
} }
// from https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Data/Parsing/MtrlStructs.cs // from https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Data/Parsing/MtrlStructs.cs
@ -202,7 +202,7 @@ pub struct Sampler {
texture_index: u8, texture_index: u8,
unknown1: u8, unknown1: u8,
unknown2: u8, unknown2: u8,
unknown3: u8 unknown3: u8,
} }
#[binrw] #[binrw]
@ -258,7 +258,7 @@ pub struct Material {
pub constants: Vec<Constant>, pub constants: Vec<Constant>,
pub samplers: Vec<Sampler>, pub samplers: Vec<Sampler>,
pub color_table: Option<ColorTable>, pub color_table: Option<ColorTable>,
pub color_dye_table: Option<ColorDyeTable> pub color_dye_table: Option<ColorDyeTable>,
} }
impl Material { impl Material {
@ -309,7 +309,7 @@ impl Material {
constants.push(Constant { constants.push(Constant {
id: constant.constant_id, id: constant.constant_id,
num_values: num_floats as u32, num_values: num_floats as u32,
values values,
}); });
} }
@ -320,7 +320,7 @@ impl Material {
constants, constants,
samplers: mat_data.samplers, samplers: mat_data.samplers,
color_table: mat_data.color_table, color_table: mat_data.color_table,
color_dye_table: mat_data.color_dye_table color_dye_table: mat_data.color_dye_table,
}) })
} }
} }

View file

@ -17,7 +17,7 @@ enum SkeletonType {
#[brw(magic = 2u8)] #[brw(magic = 2u8)]
DemiHuman, DemiHuman,
#[brw(magic = 3u8)] #[brw(magic = 3u8)]
Weapon Weapon,
} }
#[binrw] #[binrw]
@ -34,20 +34,18 @@ struct PapHeader {
info_offset: i32, info_offset: i32,
havok_position: i32, havok_position: i32,
footer_position: i32 footer_position: i32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Pap { pub struct Pap {}
}
impl Pap { impl Pap {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = PapHeader::read(&mut cursor).ok()?; PapHeader::read(&mut cursor).ok()?;
Some(Pap{}) Some(Pap {})
} }
} }

View file

@ -1,12 +1,12 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::io::{Cursor, Seek, SeekFrom}; use std::io::{Cursor, SeekFrom};
use crate::ByteSpan;
use binrw::{binread, binrw};
use binrw::{BinRead, BinReaderExt};
use crate::common_file_operations::strings_parser; use crate::common_file_operations::strings_parser;
use crate::ByteSpan;
use binrw::binread;
use binrw::BinRead;
#[binread] #[binread]
#[derive(Debug)] #[derive(Debug)]
@ -18,7 +18,6 @@ struct RacialDeformer {
#[br(count = bone_count)] #[br(count = bone_count)]
bone_name_offsets: Vec<u16>, bone_name_offsets: Vec<u16>,
#[br(args(data_offset as u64, &bone_name_offsets), parse_with = strings_parser)] #[br(args(data_offset as u64, &bone_name_offsets), parse_with = strings_parser)]
#[br(restore_position)] #[br(restore_position)]
bone_names: Vec<String>, bone_names: Vec<String>,
@ -31,7 +30,6 @@ struct RacialDeformer {
#[br(count = bone_count)] #[br(count = bone_count)]
#[br(err_context("offset = {} bone count = {}", data_offset, bone_count))] #[br(err_context("offset = {} bone count = {}", data_offset, bone_count))]
transform: Vec<[f32; 12]>, transform: Vec<[f32; 12]>,
} }
#[binread] #[binread]
@ -47,7 +45,7 @@ struct PreBoneDeformerItem {
#[br(args { data_offset: data_offset })] #[br(args { data_offset: data_offset })]
#[br(seek_before = SeekFrom::Start(data_offset as u64))] #[br(seek_before = SeekFrom::Start(data_offset as u64))]
#[br(restore_position)] #[br(restore_position)]
deformer: RacialDeformer deformer: RacialDeformer,
} }
#[binread] #[binread]
@ -95,7 +93,7 @@ impl PreBoneDeformer {
/// Reads an existing PBD file /// Reads an existing PBD file
pub fn from_existing(buffer: ByteSpan) -> Option<PreBoneDeformer> { pub fn from_existing(buffer: ByteSpan) -> Option<PreBoneDeformer> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let mut header = PreBoneDeformerHeader::read(&mut cursor).ok()?; let header = PreBoneDeformerHeader::read(&mut cursor).ok()?;
Some(PreBoneDeformer { header }) Some(PreBoneDeformer { header })
} }

View file

@ -18,20 +18,18 @@ struct PhybHeader {
data_type: u32, data_type: u32,
collision_offset: u32, collision_offset: u32,
simulator_offset: u32 simulator_offset: u32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Phyb { pub struct Phyb {}
}
impl Phyb { impl Phyb {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = PhybHeader::read(&mut cursor).ok()?; PhybHeader::read(&mut cursor).ok()?;
Some(Phyb{}) Some(Phyb {})
} }
} }

View file

@ -242,8 +242,14 @@ mod tests {
version: None, version: None,
}; };
assert_eq!(repo.index_filename(0, Category::Music), "0c0000.win32.index"); assert_eq!(
assert_eq!(repo.index2_filename(0, Category::Music), "0c0000.win32.index2"); repo.index_filename(0, Category::Music),
"0c0000.win32.index"
);
assert_eq!(
repo.index2_filename(0, Category::Music),
"0c0000.win32.index2"
);
assert_eq!( assert_eq!(
repo.dat_filename(0, Category::GameScript, 1), repo.dat_filename(0, Category::GameScript, 1),
"0b0000.win32.dat1" "0b0000.win32.dat1"
@ -261,7 +267,10 @@ mod tests {
}; };
assert_eq!(repo.index_filename(0, Category::Music), "0c0000.ps3.index"); assert_eq!(repo.index_filename(0, Category::Music), "0c0000.ps3.index");
assert_eq!(repo.index2_filename(0, Category::Music), "0c0000.ps3.index2"); assert_eq!(
repo.index2_filename(0, Category::Music),
"0c0000.ps3.index2"
);
assert_eq!( assert_eq!(
repo.dat_filename(0, Category::GameScript, 1), repo.dat_filename(0, Category::GameScript, 1),
"0b0000.ps3.dat1" "0b0000.ps3.dat1"
@ -278,7 +287,10 @@ mod tests {
}; };
assert_eq!(repo.index_filename(0, Category::Music), "0c0000.ps4.index"); assert_eq!(repo.index_filename(0, Category::Music), "0c0000.ps4.index");
assert_eq!(repo.index2_filename(0, Category::Music), "0c0000.ps4.index2"); assert_eq!(
repo.index2_filename(0, Category::Music),
"0c0000.ps4.index2"
);
assert_eq!( assert_eq!(
repo.dat_filename(0, Category::GameScript, 1), repo.dat_filename(0, Category::GameScript, 1),
"0b0000.ps4.dat1" "0b0000.ps4.dat1"

View file

@ -46,16 +46,14 @@ struct ScdHeader {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Scd { pub struct Scd {}
}
impl Scd { impl Scd {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = ScdHeader::read(&mut cursor).ok()?; ScdHeader::read(&mut cursor).ok()?;
Some(Scd{}) Some(Scd {})
} }
} }

View file

@ -4,7 +4,7 @@
use std::io::Cursor; use std::io::Cursor;
use crate::ByteSpan; use crate::ByteSpan;
use binrw::{binread, binrw}; use binrw::binread;
use binrw::BinRead; use binrw::BinRead;
#[binread] #[binread]
@ -13,7 +13,7 @@ enum ShaderStage {
#[br(magic = 0u8)] #[br(magic = 0u8)]
Vertex, Vertex,
#[br(magic = 1u8)] #[br(magic = 1u8)]
Pixel Pixel,
} }
#[binread] #[binread]
@ -34,20 +34,18 @@ struct SchdHeader {
file_length: i32, file_length: i32,
shader_offset: u32, shader_offset: u32,
parameter_offset: u32 parameter_offset: u32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Schd { pub struct Schd {}
}
impl Schd { impl Schd {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = SchdHeader::read(&mut cursor).ok()?; SchdHeader::read(&mut cursor).ok()?;
Some(Schd{}) Some(Schd {})
} }
} }

View file

@ -18,20 +18,18 @@ struct SgbHeader {
pub identifier: String, pub identifier: String,
file_size: i32, file_size: i32,
total_chunk_count: i32 total_chunk_count: i32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Sgb { pub struct Sgb {}
}
impl Sgb { impl Sgb {
/// Reads an existing SGB file /// Reads an existing SGB file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = SgbHeader::read(&mut cursor).ok()?; SgbHeader::read(&mut cursor).ok()?;
Some(Sgb{}) Some(Sgb {})
} }
} }

View file

@ -3,9 +3,9 @@
use std::io::{Cursor, SeekFrom}; use std::io::{Cursor, SeekFrom};
use crate::crc::XivCrc32;
use crate::ByteSpan; use crate::ByteSpan;
use binrw::{binread, BinRead}; use binrw::{binread, BinRead};
use crate::crc::XivCrc32;
#[binread] #[binread]
#[br(little, import { #[br(little, import {
@ -271,7 +271,7 @@ impl ShaderPackage {
} }
pub fn crc(str: &str) -> u32 { pub fn crc(str: &str) -> u32 {
return XivCrc32::from(str).crc; XivCrc32::from(str).crc
} }
} }
@ -302,9 +302,19 @@ mod tests {
fn test_selector() { fn test_selector() {
let selector = ShaderPackage::build_selector_from_all_keys( let selector = ShaderPackage::build_selector_from_all_keys(
&[], &[],
&[ShaderPackage::crc("TransformViewSkin"), ShaderPackage::crc("GetAmbientLight_SH"), ShaderPackage::crc("GetReflectColor_Texture"), ShaderPackage::crc("GetAmbientOcclusion_None"), ShaderPackage::crc("ApplyDitherClipOff")], &[
ShaderPackage::crc("TransformViewSkin"),
ShaderPackage::crc("GetAmbientLight_SH"),
ShaderPackage::crc("GetReflectColor_Texture"),
ShaderPackage::crc("GetAmbientOcclusion_None"),
ShaderPackage::crc("ApplyDitherClipOff"),
],
&[3756477356, 1556481461, 1111668802, 428675533], &[3756477356, 1556481461, 1111668802, 428675533],
&[ShaderPackage::crc("Default"), ShaderPackage::crc("SUB_VIEW_MAIN")]); &[
ShaderPackage::crc("Default"),
ShaderPackage::crc("SUB_VIEW_MAIN"),
],
);
assert_eq!(selector, 0x1075AE91); assert_eq!(selector, 0x1075AE91);
} }

View file

@ -21,16 +21,14 @@ struct SkpHeader {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Skp { pub struct Skp {}
}
impl Skp { impl Skp {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = SkpHeader::read(&mut cursor).ok()?; SkpHeader::read(&mut cursor).ok()?;
Some(Skp{}) Some(Skp {})
} }
} }

View file

@ -1,15 +1,12 @@
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::io::{Cursor, Read, Seek, SeekFrom}; use std::io::{Cursor, Seek, SeekFrom};
use crate::ByteSpan;
use binrw::{binread, BinReaderExt, binrw};
use binrw::__private::assert;
use binrw::BinRead;
use half::f16;
use crate::common_file_operations::{Half1, Half3}; use crate::common_file_operations::{Half1, Half3};
use crate::model_vertex_declarations::VertexType::Half2; use crate::ByteSpan;
use binrw::BinRead;
use binrw::{binrw, BinReaderExt};
/// Maximum number of elements in one row /// Maximum number of elements in one row
const MAX_ELEMENTS: usize = 128; const MAX_ELEMENTS: usize = 128;
@ -25,7 +22,7 @@ struct StmHeader {
keys: Vec<u16>, keys: Vec<u16>,
#[br(count = entry_count)] #[br(count = entry_count)]
offsets: Vec<u16> offsets: Vec<u16>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -34,13 +31,11 @@ pub struct DyePack {
specular: [f32; 3], specular: [f32; 3],
emissive: [f32; 3], emissive: [f32; 3],
gloss: f32, gloss: f32,
specular_power: f32 specular_power: f32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct StainingTemplate { pub struct StainingTemplate {}
}
impl StainingTemplate { impl StainingTemplate {
/// Reads an existing ULD file /// Reads an existing ULD file
@ -52,7 +47,7 @@ impl StainingTemplate {
let offset = entry_offset as i32 * 2 + 8 + 4 * header.entry_count; let offset = entry_offset as i32 * 2 + 8 + 4 * header.entry_count;
// read the stm entry // read the stm entry
cursor.seek(SeekFrom::Start(offset as u64)); cursor.seek(SeekFrom::Start(offset as u64)).ok()?;
// read the value offsets // read the value offsets
let mut ends = [0u16; 5]; let mut ends = [0u16; 5];
@ -60,29 +55,31 @@ impl StainingTemplate {
*end = cursor.read_le::<u16>().unwrap() * 2; *end = cursor.read_le::<u16>().unwrap() * 2;
} }
let new_offset = (offset + 10) as u64; /*let new_offset = (offset + 10) as u64;
let diffuse_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset, ends[0] as usize); let diffuse_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset, ends[0] as usize);
let specular_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[0] as u64, ends[1] as usize - ends[0] as usize); let specular_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[0] as u64, ends[1] as usize - ends[0] as usize);
let emissive_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[1] as u64, ends[2] as usize - ends[1] as usize); let emissive_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[1] as u64, ends[2] as usize - ends[1] as usize);
let gloss_entries = StainingTemplate::read_array::<Half1>(&mut cursor, new_offset + ends[2] as u64, ends[3] as usize - ends[2] as usize); let gloss_entries = StainingTemplate::read_array::<Half1>(&mut cursor, new_offset + ends[2] as u64, ends[3] as usize - ends[2] as usize);
let specular_power_entries = StainingTemplate::read_array::<Half1>(&mut cursor, new_offset + ends[3] as u64, ends[4] as usize - ends[3] as usize); let specular_power_entries = StainingTemplate::read_array::<Half1>(&mut cursor, new_offset + ends[3] as u64, ends[4] as usize - ends[3] as usize);*/
break;
} }
Some(StainingTemplate{}) Some(StainingTemplate {})
} }
fn read_array<T: binrw::BinRead<Args<'static> = ()> + Default + Clone + Copy>(cursor: &mut Cursor<ByteSpan>, offset: u64, size: usize) -> Vec<T> { fn read_array<T: binrw::BinRead<Args<'static> = ()> + Default + Clone + Copy>(
cursor.seek(SeekFrom::Start(offset)); cursor: &mut Cursor<ByteSpan>,
offset: u64,
size: usize,
) -> Vec<T> {
cursor.seek(SeekFrom::Start(offset)).unwrap();
let array_size = size / std::mem::size_of::<T>(); let array_size = size / std::mem::size_of::<T>();
if array_size == 0 { if array_size == 0 {
return vec![T::default(); MAX_ELEMENTS]; vec![T::default(); MAX_ELEMENTS]
} else if array_size == 1 { } else if array_size == 1 {
let element = cursor.read_le::<T>().unwrap(); let element = cursor.read_le::<T>().unwrap();
return vec![element; MAX_ELEMENTS]; vec![element; MAX_ELEMENTS]
} else if array_size < MAX_ELEMENTS { } else if array_size < MAX_ELEMENTS {
let real_count = array_size - MAX_ELEMENTS / std::mem::size_of::<T>(); let real_count = array_size - MAX_ELEMENTS / std::mem::size_of::<T>();
let mut values = vec![]; let mut values = vec![];
@ -97,13 +94,13 @@ impl StainingTemplate {
let eof_marker = cursor.read_le::<u8>().unwrap(); let eof_marker = cursor.read_le::<u8>().unwrap();
assert_eq!(eof_marker, 0xFF); assert_eq!(eof_marker, 0xFF);
for i in 0..MAX_ELEMENTS { for _ in 0..MAX_ELEMENTS {
indices.push(cursor.read_le::<u8>().unwrap()); indices.push(cursor.read_le::<u8>().unwrap());
} }
let mut vec = vec![]; let mut vec = vec![];
for index in indices { for index in indices {
if index >= 0 && (index as usize) < values.len() { if (index as usize) < values.len() {
vec.push(values[index as usize]); vec.push(values[index as usize]);
} else { } else {
vec.push(T::default()); vec.push(T::default());

View file

@ -74,7 +74,7 @@ struct TexHeader {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum TextureType { pub enum TextureType {
TwoDimensional, TwoDimensional,
ThreeDimensional ThreeDimensional,
} }
pub struct Texture { pub struct Texture {
@ -111,7 +111,11 @@ impl Texture {
match header.format { match header.format {
TextureFormat::B4G4R4A4 => { TextureFormat::B4G4R4A4 => {
dst = vec![0u8; header.width as usize * header.height as usize * header.depth as usize * 4]; dst =
vec![
0u8;
header.width as usize * header.height as usize * header.depth as usize * 4
];
let mut offset = 0; let mut offset = 0;
let mut dst_offset = 0; let mut dst_offset = 0;
@ -134,7 +138,11 @@ impl Texture {
} }
} }
TextureFormat::B8G8R8A8 => { TextureFormat::B8G8R8A8 => {
dst = vec![0u8; header.width as usize * header.height as usize * header.depth as usize * 4]; dst =
vec![
0u8;
header.width as usize * header.height as usize * header.depth as usize * 4
];
let mut offset = 0; let mut offset = 0;
@ -179,7 +187,11 @@ impl Texture {
} }
Some(Texture { Some(Texture {
texture_type: if header.attribute.contains(TextureAttribute::TEXTURE_TYPE3_D) { TextureType::ThreeDimensional } else { TextureType::TwoDimensional }, texture_type: if header.attribute.contains(TextureAttribute::TEXTURE_TYPE3_D) {
TextureType::ThreeDimensional
} else {
TextureType::TwoDimensional
},
width: header.width as u32, width: header.width as u32,
height: header.height as u32, height: header.height as u32,
depth: header.depth as u32, depth: header.depth as u32,

View file

@ -13,20 +13,18 @@ use binrw::BinRead;
struct TmbHeader { struct TmbHeader {
magic: i32, // TODO: figure out what this magic: i32, // TODO: figure out what this
size: i32, size: i32,
entry_count: i32 entry_count: i32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Tmb { pub struct Tmb {}
}
impl Tmb { impl Tmb {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = TmbHeader::read(&mut cursor).ok()?; TmbHeader::read(&mut cursor).ok()?;
Some(Tmb{}) Some(Tmb {})
} }
} }

View file

@ -24,20 +24,18 @@ struct UldHeader {
pub version: String, pub version: String,
component_offset: u32, component_offset: u32,
widget_offset: u32 widget_offset: u32,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Uld { pub struct Uld {}
}
impl Uld { impl Uld {
/// Reads an existing ULD file /// Reads an existing ULD file
pub fn from_existing(buffer: ByteSpan) -> Option<Self> { pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
let header = UldHeader::read(&mut cursor).ok()?; UldHeader::read(&mut cursor).ok()?;
Some(Uld{}) Some(Uld {})
} }
} }