diff --git a/examples/extractor.rs b/examples/extractor.rs index e1390f5..9464614 100644 --- a/examples/extractor.rs +++ b/examples/extractor.rs @@ -15,27 +15,27 @@ fn main() { return; } - /// Collect our arguments + // Collect our arguments let game_dir = &args[1]; let file_path = &args[2]; let destination_path = &args[3]; - /// Create a GameData struct, this manages the repositories. It allows us to easily extract files. + // Create a GameData struct, this manages the repositories. It allows us to easily extract files. let mut game_data = GameData::from_existing(Platform::Win32, game_dir); - /// Extract said file: + // Extract said file: let Some(game_file) = game_data.extract(file_path) else { println!("File {} not found!", file_path); return; }; - /// Create the file to write into. + // Create the file to write into. let Ok(mut file) = File::create(destination_path) else { println!("Failed to open file {} for writing.", destination_path); return; }; - /// Since GameData::extract returns a byte buffer, it's trivial to write that to a file on disk. + // Since GameData::extract returns a byte buffer, it's trivial to write that to a file on disk. if file.write_all(&game_file).is_err() { println!("Failed to write to file {}.", destination_path); return; diff --git a/src/bcn/bitreader.rs b/src/bcn/bitreader.rs index 1685581..a44c4a2 100644 --- a/src/bcn/bitreader.rs +++ b/src/bcn/bitreader.rs @@ -8,39 +8,6 @@ fn getbits_raw(buf: &[u8], bit_offset: usize, num_bits: usize, dst: &mut [u8]) { dst[0..(bytes_end - bytes_offset)].copy_from_slice(&buf[bytes_offset..bytes_end]); } -#[inline] -pub fn getbits(buf: &[u8], bit_offset: usize, num_bits: usize) -> i32 { - let shift = bit_offset % 8; - - let mut raw = [0u8; 4]; - getbits_raw(buf, bit_offset, num_bits, &mut raw); - - // shift the bits we don't need out - i32::from_le_bytes(raw) >> shift & ((1 << num_bits) - 1) -} - -#[inline] -pub fn getbits64(buf: &[u8], bit: isize, len: usize) -> u64 { - let mask: u64 = if len == 64 { - 0xffffffffffffffff - } else { - (1 << len) - 1 - }; - if len == 0 { - 0 - } else if bit >= 64 { - u64::from_le_bytes(buf[8..16].try_into().unwrap()) >> (bit - 64) & mask - } else if bit <= 0 { - u64::from_le_bytes(buf[..8].try_into().unwrap()) << 0u64.overflowing_sub(bit as u64).0 - & mask - } else if bit as usize + len <= 64 { - u64::from_le_bytes(buf[..8].try_into().unwrap()) >> bit & mask - } else { - u64::from_le_bytes(buf[..8].try_into().unwrap()) >> bit - | u64::from_le_bytes(buf[8..16].try_into().unwrap()) << (64 - bit) & mask - } -} - pub struct BitReader<'a> { data: &'a [u8], bit_pos: usize, diff --git a/src/bcn/color.rs b/src/bcn/color.rs index 6edd022..eb7c6c9 100644 --- a/src/bcn/color.rs +++ b/src/bcn/color.rs @@ -3,28 +3,6 @@ #![allow(clippy::too_many_arguments)] -pub static TRANSPARENT_MASK: u32 = { - #[cfg(target_endian = "little")] - { - 0x00ffffff - } - #[cfg(target_endian = "big")] - { - 0xffffff00 - } -}; - -pub static TRANSPARENT_SHIFT: u32 = { - #[cfg(target_endian = "little")] - { - 24 - } - #[cfg(target_endian = "big")] - { - 0 - } -}; - #[inline] pub const fn color(r: u8, g: u8, b: u8, a: u8) -> u32 { u32::from_le_bytes([b, g, r, a]) diff --git a/src/common_file_operations.rs b/src/common_file_operations.rs index d28dad2..eb49290 100644 --- a/src/common_file_operations.rs +++ b/src/common_file_operations.rs @@ -54,25 +54,6 @@ pub(crate) fn strings_parser( Ok(strings) } -#[binrw::parser(reader)] -pub(crate) fn string_from_offset(start: u64) -> BinResult { - let offset: u32 = reader.read_le::()?; - - let mut string = String::new(); - - let old_pos = reader.stream_position()?; - - reader.seek(SeekFrom::Start(start + offset as u64))?; - reader.seek(SeekFrom::Start(start))?; - let mut next_char = reader.read_le::().unwrap() as char; - while next_char != '\0' { - string.push(next_char); - next_char = reader.read_le::().unwrap() as char; - } - reader.seek(SeekFrom::Start(old_pos))?; - Ok(string) -} - fn read_half1(data: [u16; 1]) -> Half1 { Half1 { value: f16::from_bits(data[0]), diff --git a/src/exd.rs b/src/exd.rs index 93f8b29..a0ce5de 100644 --- a/src/exd.rs +++ b/src/exd.rs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2023 Joshua Goins // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(unused_variables)] // just binrw things with br(temp) + use std::io::{BufWriter, Cursor}; use binrw::BinRead; diff --git a/src/exd_file_operations.rs b/src/exd_file_operations.rs index 502d407..e338e61 100644 --- a/src/exd_file_operations.rs +++ b/src/exd_file_operations.rs @@ -41,7 +41,7 @@ pub fn parse_rows(exh: &EXH, data_offsets: &Vec) -> BinResult)] pub is_env_map_shooting_point: bool, + #[brw(pad_after = 2)] // padding pub priority: u8, - padding: u16, pub effective_range: f32, pub interpolation_time: i32, pub reverb: f32, diff --git a/src/layer/exit_range.rs b/src/layer/exit_range.rs index 7c3d575..6c13475 100644 --- a/src/layer/exit_range.rs +++ b/src/layer/exit_range.rs @@ -23,6 +23,6 @@ pub struct ExitRangeInstanceObject { pub index: i32, pub destination_instance_id: u32, pub return_instance_id: u32, + #[brw(pad_after = 4)] // padding pub player_running_direction: f32, - padding: u32, } diff --git a/src/layer/light.rs b/src/layer/light.rs index a0e0ca7..1529da8 100644 --- a/src/layer/light.rs +++ b/src/layer/light.rs @@ -39,19 +39,18 @@ pub struct LightInstanceObject { pub texture_path_offset: u32, pub diffuse_color_hdri: ColorHDRI, #[br(map = read_bool_from::)] + #[brw(pad_after = 3)] // padding pub follows_directional_light: bool, - padding1: u8, - padding2: u16, #[br(map = read_bool_from::)] pub specular_enabled: bool, #[br(map = read_bool_from::)] pub bg_shadow_enabled: bool, #[br(map = read_bool_from::)] + #[brw(pad_after = 1)] // padding pub character_shadow_enabled: bool, - padding3: u8, pub shadow_clip_range: f32, pub plane_light_rotation_x: f32, pub plane_light_rotation_y: f32, + #[brw(pad_after = 1)] // padding pub merge_group_id: u16, - padding4: u8, } diff --git a/src/layer/mod.rs b/src/layer/mod.rs index b688873..90982c8 100644 --- a/src/layer/mod.rs +++ b/src/layer/mod.rs @@ -1,11 +1,11 @@ // SPDX-FileCopyrightText: 2024 Joshua Goins // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(unused_variables)] // just binrw things with br(temp) + use std::io::{Cursor, Read, Seek, SeekFrom, Write}; -use crate::common_file_operations::{ - read_bool_from, string_from_offset, write_bool_as, write_string, -}; +use crate::common_file_operations::{read_bool_from, write_bool_as, write_string}; use crate::{ByteBuffer, ByteSpan}; use binrw::{BinRead, BinReaderExt, BinWrite, binread}; use binrw::{Endian, Error, binrw}; @@ -67,9 +67,9 @@ pub use trigger_box::TriggerBoxShape; // Also see https://github.com/aers/FFXIVClientStructs/blob/6b62122cae38bfbc016bf697bef75f80f37abac1/FFXIVClientStructs/FFXIV/Client/LayoutEngine/ILayoutInstance.cs /// "LGB1" -const LGB1_ID: u32 = u32::from_le_bytes(*b"LGB1"); +pub const LGB1_ID: u32 = u32::from_le_bytes(*b"LGB1"); /// "LGP1" -const LGP1_ID: u32 = u32::from_le_bytes(*b"LGP1"); +pub const LGP1_ID: u32 = u32::from_le_bytes(*b"LGP1"); /// A string that exists in a different location in the file, usually a heap with a bunch of other strings. #[binrw] @@ -368,37 +368,36 @@ pub enum LayerEntryData { #[derive(Debug)] #[br(little)] pub struct VFXInstanceObject { - asset_path_offset: u32, - soft_particle_fade_range: f32, - padding: u32, - color: Color, + pub asset_path_offset: u32, + #[brw(pad_after = 4)] // padding + pub soft_particle_fade_range: f32, + pub color: Color, #[br(map = read_bool_from::)] - auto_play: bool, + pub auto_play: bool, #[br(map = read_bool_from::)] - no_far_clip: bool, - padding1: u16, - fade_near_start: f32, - fade_near_end: f32, - fade_far_start: f32, - fade_far_end: f32, - z_correct: f32, + #[brw(pad_after = 2)] // padding + pub no_far_clip: bool, + pub fade_near_start: f32, + pub fade_near_end: f32, + pub fade_far_start: f32, + pub fade_far_end: f32, + pub z_correct: f32, } #[binread] #[derive(Debug)] #[br(little)] pub struct GatheringInstanceObject { - gathering_point_id: u32, - padding: u32, + #[brw(pad_after = 4)] // padding + pub gathering_point_id: u32, } #[binread] #[derive(Debug)] #[br(little)] pub struct TreasureInstanceObject { - nonpop_init_zone: u8, - padding1: [u8; 3], - padding2: [u32; 2], + #[brw(pad_after = 11)] // padding + pub nonpop_init_zone: u8, } // Unimplemented because I haven't needed it yet: @@ -533,8 +532,8 @@ pub struct LayerHeader { #[derive(Debug)] #[brw(little)] #[allow(dead_code)] // most of the fields are unused at the moment -struct LayerSetReferenced { - layer_set_id: u32, +pub struct LayerSetReferenced { + pub layer_set_id: u32, } #[binrw] @@ -542,18 +541,17 @@ struct LayerSetReferenced { #[brw(little)] #[br(import(data_heap: &StringHeap), stream = r)] #[bw(import(data_heap: &mut StringHeap))] -#[allow(dead_code)] // most of the fields are unused at the moment -struct LayerSetReferencedList { +pub struct LayerSetReferencedList { referenced_type: LayerSetReferencedType, #[br(temp)] #[bw(calc = data_heap.get_free_offset(&layer_sets))] layer_set_offset: i32, #[bw(calc = layer_sets.len() as i32)] - layer_set_count: i32, + pub layer_set_count: i32, #[br(count = layer_set_count)] #[bw(ignore)] - layer_sets: Vec, + pub layer_sets: Vec, } #[binread] @@ -613,7 +611,7 @@ const LAYER_CHUNK_HEADER_SIZE: usize = 24; #[binread] #[derive(Debug)] #[br(little)] -#[br(import(start: u64, string_heap: &StringHeap))] +#[br(import(string_heap: &StringHeap))] #[allow(dead_code)] // most of the fields are unused at the moment pub struct InstanceObject { asset_type: LayerEntryType, @@ -708,9 +706,8 @@ impl LayerGroup { let start = cursor.stream_position().unwrap(); let string_heap = StringHeap::from(start); - objects.push( - InstanceObject::read_le_args(&mut cursor, (start, &string_heap)).unwrap(), - ); + objects + .push(InstanceObject::read_le_args(&mut cursor, (&string_heap,)).unwrap()); } } diff --git a/src/layer/npc.rs b/src/layer/npc.rs index 73cee6e..8299fa4 100644 --- a/src/layer/npc.rs +++ b/src/layer/npc.rs @@ -9,23 +9,23 @@ use super::common::RelativePositions; #[derive(Debug)] #[br(little)] pub struct GameInstanceObject { - base_id: u32, + pub base_id: u32, } #[binread] #[derive(Debug)] #[br(little)] pub struct NPCInstanceObject { - parent_data: GameInstanceObject, - pop_weather: u32, - pop_time_start: u8, - pop_time_end: u8, - padding: u16, - move_ai: u32, - wandering_range: u8, - route: u8, - event_group: u16, - padding1: [u32; 2], + pub parent_data: GameInstanceObject, + pub pop_weather: u32, + pub pop_time_start: u8, + #[brw(pad_after = 2)] // padding + pub pop_time_end: u8, + pub move_ai: u32, + pub wandering_range: u8, + pub route: u8, + #[brw(pad_after = 8)] // padding + pub event_group: u16, } #[binread] @@ -33,8 +33,8 @@ pub struct NPCInstanceObject { #[br(little)] pub struct ENPCInstanceObject { pub parent_data: NPCInstanceObject, + #[brw(pad_after = 8)] // padding pub behavior: u32, - padding: [u32; 2], } #[binread] diff --git a/src/layer/pop.rs b/src/layer/pop.rs index fe61138..3ba95a6 100644 --- a/src/layer/pop.rs +++ b/src/layer/pop.rs @@ -21,8 +21,7 @@ pub struct PopRangeInstanceObject { pub pop_type: PopType, pub relative_positions: RelativePositions, pub inner_radius_ratio: f32, + #[brw(pad_after = 7)] // padding pub index: u8, - padding1: [u8; 3], - padding2: u32, // TODO: read relative positions } diff --git a/src/layer/shared_group.rs b/src/layer/shared_group.rs index 3d00fe6..4e38baf 100644 --- a/src/layer/shared_group.rs +++ b/src/layer/shared_group.rs @@ -56,13 +56,13 @@ pub struct SharedGroupInstance { #[br(map = read_bool_from::)] pub random_timeline_loop_playback: bool, #[br(map = read_bool_from::)] + #[brw(pad_after = 1)] // padding pub collision_controllable_without_eobj: bool, - padding: u8, pub bound_client_path_instance_id: u32, pub move_path_settings: i32, #[br(map = read_bool_from::)] + #[brw(pad_after = 3)] // padding pub not_create_navimesh_door: bool, - padding1: [u8; 3], pub initial_transform_state: TransformState, pub initial_color_state: ColourState, // TODO: read move path settings diff --git a/src/layer/trigger_box.rs b/src/layer/trigger_box.rs index 9c29ab9..8aedceb 100644 --- a/src/layer/trigger_box.rs +++ b/src/layer/trigger_box.rs @@ -24,7 +24,6 @@ pub struct TriggerBoxInstanceObject { pub trigger_box_shape: TriggerBoxShape, pub priority: i16, #[br(map = read_bool_from::)] + #[brw(pad_after = 5)] // padding pub enabled: bool, - padidng: u8, - padding1: u32, } diff --git a/src/patch.rs b/src/patch.rs index 904f99c..14526c4 100755 --- a/src/patch.rs +++ b/src/patch.rs @@ -807,10 +807,10 @@ mod tests { let mut dir = std::env::temp_dir(); dir.push("physis-patch-tests"); if dir.exists() { - fs::remove_dir_all(&dir); + fs::remove_dir_all(&dir).unwrap(); } - fs::create_dir_all(&dir); + fs::create_dir_all(&dir).unwrap(); dir.to_str().unwrap().to_string() } diff --git a/src/savedata/chardat.rs b/src/savedata/chardat.rs index f96fecc..f03c647 100644 --- a/src/savedata/chardat.rs +++ b/src/savedata/chardat.rs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2023 Joshua Goins // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(unused_variables)] // shut up a nonsensical error in binrw for checksum + use std::io::{BufWriter, Cursor}; use crate::common_file_operations::{read_bool_from, read_string, write_bool_as, write_string}; diff --git a/src/savedata/dat.rs b/src/savedata/dat.rs index 37d7b68..6fd8d91 100644 --- a/src/savedata/dat.rs +++ b/src/savedata/dat.rs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2025 Joshua Goins // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(unused_variables)] // just binrw things with br(temp) + use binrw::binrw; #[binrw] diff --git a/src/shpk.rs b/src/shpk.rs index a823144..d7f76c2 100644 --- a/src/shpk.rs +++ b/src/shpk.rs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2023 Joshua Goins // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(unused_variables)] // just binrw things with br(temp) + use std::io::{Cursor, SeekFrom}; use crate::ByteSpan; @@ -136,7 +138,7 @@ pub struct Node { #[br(little)] #[br(magic = b"ShPk")] #[derive(Debug)] -#[allow(dead_code, unused_variables)] +#[allow(dead_code, unused)] pub struct ShaderPackage { version: u32, diff --git a/src/sqpack/index.rs b/src/sqpack/index.rs index 03695e8..1d75cf4 100644 --- a/src/sqpack/index.rs +++ b/src/sqpack/index.rs @@ -198,7 +198,7 @@ impl SqPackIndex { let (directory, filename) = lowercase.split_at(pos); let directory_crc = CRC.checksum(directory.as_bytes()); - let filename_crc = CRC.checksum(filename[1..filename.len()].as_bytes()); + let filename_crc = CRC.checksum(&filename.as_bytes()[1..filename.len()]); Hash::SplitPath { name: filename_crc, diff --git a/src/tex.rs b/src/tex.rs index 5119ca0..e44c452 100644 --- a/src/tex.rs +++ b/src/tex.rs @@ -53,6 +53,7 @@ bitflags! { #[binrw] #[brw(repr = u32)] #[derive(Debug)] +#[allow(non_camel_case_types)] // NOTE: It's currently allowed to make updating this list not a giant pain enum TextureFormat { L8_UNORM = 0x1130, A8_UNORM = 0x1131,