mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-21 04:07:46 +00:00
Run rustfmt and fix more Clippy warnings
This commit is contained in:
parent
306a507969
commit
e5caab2e64
23 changed files with 174 additions and 161 deletions
|
@ -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
|
||||||
|
);
|
||||||
}
|
}
|
20
src/avfx.rs
20
src/avfx.rs
|
@ -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)
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
25
src/crc.rs
25
src/crc.rs
|
@ -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 {
|
||||||
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
@ -242,10 +242,7 @@ impl GameData {
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -12,19 +12,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
14
src/mtrl.rs
14
src/mtrl.rs
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/pap.rs
10
src/pap.rs
|
@ -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,19 +34,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
14
src/pbd.rs
14
src/pbd.rs
|
@ -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 })
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -46,15 +46,13 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
12
src/schd.rs
12
src/schd.rs
|
@ -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,19 +34,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
18
src/shpk.rs
18
src/shpk.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,13 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
43
src/stm.rs
43
src/stm.rs
|
@ -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());
|
||||||
|
|
20
src/tex.rs
20
src/tex.rs
|
@ -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,
|
||||||
|
|
|
@ -13,19 +13,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,17 @@ 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 {})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue