1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-06-06 14:47:46 +00:00

Fix various Cargo and Clippy warnings

This commit is contained in:
Joshua Goins 2025-06-02 17:32:31 -04:00
parent b0047dd77d
commit 1d3192de23
22 changed files with 71 additions and 142 deletions

View file

@ -15,27 +15,27 @@ fn main() {
return; return;
} }
/// Collect our arguments // Collect our arguments
let game_dir = &args[1]; let game_dir = &args[1];
let file_path = &args[2]; let file_path = &args[2];
let destination_path = &args[3]; 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); 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 { let Some(game_file) = game_data.extract(file_path) else {
println!("File {} not found!", file_path); println!("File {} not found!", file_path);
return; return;
}; };
/// Create the file to write into. // Create the file to write into.
let Ok(mut file) = File::create(destination_path) else { let Ok(mut file) = File::create(destination_path) else {
println!("Failed to open file {} for writing.", destination_path); println!("Failed to open file {} for writing.", destination_path);
return; 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() { if file.write_all(&game_file).is_err() {
println!("Failed to write to file {}.", destination_path); println!("Failed to write to file {}.", destination_path);
return; return;

View file

@ -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]); 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> { pub struct BitReader<'a> {
data: &'a [u8], data: &'a [u8],
bit_pos: usize, bit_pos: usize,

View file

@ -3,28 +3,6 @@
#![allow(clippy::too_many_arguments)] #![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] #[inline]
pub const fn color(r: u8, g: u8, b: u8, a: u8) -> u32 { pub const fn color(r: u8, g: u8, b: u8, a: u8) -> u32 {
u32::from_le_bytes([b, g, r, a]) u32::from_le_bytes([b, g, r, a])

View file

@ -54,25 +54,6 @@ pub(crate) fn strings_parser(
Ok(strings) Ok(strings)
} }
#[binrw::parser(reader)]
pub(crate) fn string_from_offset(start: u64) -> BinResult<String> {
let offset: u32 = reader.read_le::<u32>()?;
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::<u8>().unwrap() as char;
while next_char != '\0' {
string.push(next_char);
next_char = reader.read_le::<u8>().unwrap() as char;
}
reader.seek(SeekFrom::Start(old_pos))?;
Ok(string)
}
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]),

View file

@ -1,6 +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
#![allow(unused_variables)] // just binrw things with br(temp)
use std::io::{BufWriter, Cursor}; use std::io::{BufWriter, Cursor};
use binrw::BinRead; use binrw::BinRead;

View file

@ -41,7 +41,7 @@ pub fn parse_rows(exh: &EXH, data_offsets: &Vec<ExcelDataOffset>) -> BinResult<V
reader.seek(SeekFrom::Start(offset.offset.into()))?; reader.seek(SeekFrom::Start(offset.offset.into()))?;
// TODO: use DataSection here // TODO: use DataSection here
let size: u32 = u32::read_be(reader).unwrap(); let _size: u32 = u32::read_be(reader).unwrap();
let row_count: u16 = u16::read_be(reader).unwrap(); let row_count: u16 = u16::read_be(reader).unwrap();
//let row_header = DataSection::read(reader)?; //let row_header = DataSection::read(reader)?;

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#![allow(clippy::unnecessary_fallible_conversions)] // This wrongly trips on binrw code #![allow(clippy::unnecessary_fallible_conversions)] // This wrongly trips on binrw code
#![allow(unused_variables)] // just binrw things with br(temp)
use std::io::BufWriter; use std::io::BufWriter;
use std::io::Cursor; use std::io::Cursor;
@ -17,7 +18,6 @@ use crate::common::Language;
#[binrw] #[binrw]
#[brw(magic = b"EXHF")] #[brw(magic = b"EXHF")]
#[brw(big)] #[brw(big)]
#[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub struct EXHHeader { pub struct EXHHeader {
pub(crate) version: u16, pub(crate) version: u16,

View file

@ -10,6 +10,6 @@ use super::GameInstanceObject;
#[br(little)] #[br(little)]
pub struct AetheryteInstanceObject { pub struct AetheryteInstanceObject {
pub parent_data: GameInstanceObject, pub parent_data: GameInstanceObject,
#[brw(pad_after = 4)] // padding
pub bound_instance_id: u32, pub bound_instance_id: u32,
padding: u32,
} }

View file

@ -23,8 +23,8 @@ pub struct EnvSetInstanceObject {
pub shape: EnvSetShape, pub shape: EnvSetShape,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
pub is_env_map_shooting_point: bool, pub is_env_map_shooting_point: bool,
#[brw(pad_after = 2)] // padding
pub priority: u8, pub priority: u8,
padding: u16,
pub effective_range: f32, pub effective_range: f32,
pub interpolation_time: i32, pub interpolation_time: i32,
pub reverb: f32, pub reverb: f32,

View file

@ -23,6 +23,6 @@ pub struct ExitRangeInstanceObject {
pub index: i32, pub index: i32,
pub destination_instance_id: u32, pub destination_instance_id: u32,
pub return_instance_id: u32, pub return_instance_id: u32,
#[brw(pad_after = 4)] // padding
pub player_running_direction: f32, pub player_running_direction: f32,
padding: u32,
} }

View file

@ -39,19 +39,18 @@ pub struct LightInstanceObject {
pub texture_path_offset: u32, pub texture_path_offset: u32,
pub diffuse_color_hdri: ColorHDRI, pub diffuse_color_hdri: ColorHDRI,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[brw(pad_after = 3)] // padding
pub follows_directional_light: bool, pub follows_directional_light: bool,
padding1: u8,
padding2: u16,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
pub specular_enabled: bool, pub specular_enabled: bool,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
pub bg_shadow_enabled: bool, pub bg_shadow_enabled: bool,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[brw(pad_after = 1)] // padding
pub character_shadow_enabled: bool, pub character_shadow_enabled: bool,
padding3: u8,
pub shadow_clip_range: f32, pub shadow_clip_range: f32,
pub plane_light_rotation_x: f32, pub plane_light_rotation_x: f32,
pub plane_light_rotation_y: f32, pub plane_light_rotation_y: f32,
#[brw(pad_after = 1)] // padding
pub merge_group_id: u16, pub merge_group_id: u16,
padding4: u8,
} }

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
#![allow(unused_variables)] // just binrw things with br(temp)
use std::io::{Cursor, Read, Seek, SeekFrom, Write}; use std::io::{Cursor, Read, Seek, SeekFrom, Write};
use crate::common_file_operations::{ use crate::common_file_operations::{read_bool_from, write_bool_as, write_string};
read_bool_from, string_from_offset, write_bool_as, write_string,
};
use crate::{ByteBuffer, ByteSpan}; use crate::{ByteBuffer, ByteSpan};
use binrw::{BinRead, BinReaderExt, BinWrite, binread}; use binrw::{BinRead, BinReaderExt, BinWrite, binread};
use binrw::{Endian, Error, binrw}; 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 // Also see https://github.com/aers/FFXIVClientStructs/blob/6b62122cae38bfbc016bf697bef75f80f37abac1/FFXIVClientStructs/FFXIV/Client/LayoutEngine/ILayoutInstance.cs
/// "LGB1" /// "LGB1"
const LGB1_ID: u32 = u32::from_le_bytes(*b"LGB1"); pub const LGB1_ID: u32 = u32::from_le_bytes(*b"LGB1");
/// "LGP1" /// "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. /// A string that exists in a different location in the file, usually a heap with a bunch of other strings.
#[binrw] #[binrw]
@ -368,37 +368,36 @@ pub enum LayerEntryData {
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[br(little)]
pub struct VFXInstanceObject { pub struct VFXInstanceObject {
asset_path_offset: u32, pub asset_path_offset: u32,
soft_particle_fade_range: f32, #[brw(pad_after = 4)] // padding
padding: u32, pub soft_particle_fade_range: f32,
color: Color, pub color: Color,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
auto_play: bool, pub auto_play: bool,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
no_far_clip: bool, #[brw(pad_after = 2)] // padding
padding1: u16, pub no_far_clip: bool,
fade_near_start: f32, pub fade_near_start: f32,
fade_near_end: f32, pub fade_near_end: f32,
fade_far_start: f32, pub fade_far_start: f32,
fade_far_end: f32, pub fade_far_end: f32,
z_correct: f32, pub z_correct: f32,
} }
#[binread] #[binread]
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[br(little)]
pub struct GatheringInstanceObject { pub struct GatheringInstanceObject {
gathering_point_id: u32, #[brw(pad_after = 4)] // padding
padding: u32, pub gathering_point_id: u32,
} }
#[binread] #[binread]
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[br(little)]
pub struct TreasureInstanceObject { pub struct TreasureInstanceObject {
nonpop_init_zone: u8, #[brw(pad_after = 11)] // padding
padding1: [u8; 3], pub nonpop_init_zone: u8,
padding2: [u32; 2],
} }
// Unimplemented because I haven't needed it yet: // Unimplemented because I haven't needed it yet:
@ -533,8 +532,8 @@ pub struct LayerHeader {
#[derive(Debug)] #[derive(Debug)]
#[brw(little)] #[brw(little)]
#[allow(dead_code)] // most of the fields are unused at the moment #[allow(dead_code)] // most of the fields are unused at the moment
struct LayerSetReferenced { pub struct LayerSetReferenced {
layer_set_id: u32, pub layer_set_id: u32,
} }
#[binrw] #[binrw]
@ -542,18 +541,17 @@ struct LayerSetReferenced {
#[brw(little)] #[brw(little)]
#[br(import(data_heap: &StringHeap), stream = r)] #[br(import(data_heap: &StringHeap), stream = r)]
#[bw(import(data_heap: &mut StringHeap))] #[bw(import(data_heap: &mut StringHeap))]
#[allow(dead_code)] // most of the fields are unused at the moment pub struct LayerSetReferencedList {
struct LayerSetReferencedList {
referenced_type: LayerSetReferencedType, referenced_type: LayerSetReferencedType,
#[br(temp)] #[br(temp)]
#[bw(calc = data_heap.get_free_offset(&layer_sets))] #[bw(calc = data_heap.get_free_offset(&layer_sets))]
layer_set_offset: i32, layer_set_offset: i32,
#[bw(calc = layer_sets.len() as i32)] #[bw(calc = layer_sets.len() as i32)]
layer_set_count: i32, pub layer_set_count: i32,
#[br(count = layer_set_count)] #[br(count = layer_set_count)]
#[bw(ignore)] #[bw(ignore)]
layer_sets: Vec<LayerSetReferenced>, pub layer_sets: Vec<LayerSetReferenced>,
} }
#[binread] #[binread]
@ -613,7 +611,7 @@ const LAYER_CHUNK_HEADER_SIZE: usize = 24;
#[binread] #[binread]
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[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 #[allow(dead_code)] // most of the fields are unused at the moment
pub struct InstanceObject { pub struct InstanceObject {
asset_type: LayerEntryType, asset_type: LayerEntryType,
@ -708,9 +706,8 @@ impl LayerGroup {
let start = cursor.stream_position().unwrap(); let start = cursor.stream_position().unwrap();
let string_heap = StringHeap::from(start); let string_heap = StringHeap::from(start);
objects.push( objects
InstanceObject::read_le_args(&mut cursor, (start, &string_heap)).unwrap(), .push(InstanceObject::read_le_args(&mut cursor, (&string_heap,)).unwrap());
);
} }
} }

View file

@ -9,23 +9,23 @@ use super::common::RelativePositions;
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[br(little)]
pub struct GameInstanceObject { pub struct GameInstanceObject {
base_id: u32, pub base_id: u32,
} }
#[binread] #[binread]
#[derive(Debug)] #[derive(Debug)]
#[br(little)] #[br(little)]
pub struct NPCInstanceObject { pub struct NPCInstanceObject {
parent_data: GameInstanceObject, pub parent_data: GameInstanceObject,
pop_weather: u32, pub pop_weather: u32,
pop_time_start: u8, pub pop_time_start: u8,
pop_time_end: u8, #[brw(pad_after = 2)] // padding
padding: u16, pub pop_time_end: u8,
move_ai: u32, pub move_ai: u32,
wandering_range: u8, pub wandering_range: u8,
route: u8, pub route: u8,
event_group: u16, #[brw(pad_after = 8)] // padding
padding1: [u32; 2], pub event_group: u16,
} }
#[binread] #[binread]
@ -33,8 +33,8 @@ pub struct NPCInstanceObject {
#[br(little)] #[br(little)]
pub struct ENPCInstanceObject { pub struct ENPCInstanceObject {
pub parent_data: NPCInstanceObject, pub parent_data: NPCInstanceObject,
#[brw(pad_after = 8)] // padding
pub behavior: u32, pub behavior: u32,
padding: [u32; 2],
} }
#[binread] #[binread]

View file

@ -21,8 +21,7 @@ pub struct PopRangeInstanceObject {
pub pop_type: PopType, pub pop_type: PopType,
pub relative_positions: RelativePositions, pub relative_positions: RelativePositions,
pub inner_radius_ratio: f32, pub inner_radius_ratio: f32,
#[brw(pad_after = 7)] // padding
pub index: u8, pub index: u8,
padding1: [u8; 3],
padding2: u32,
// TODO: read relative positions // TODO: read relative positions
} }

View file

@ -56,13 +56,13 @@ pub struct SharedGroupInstance {
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
pub random_timeline_loop_playback: bool, pub random_timeline_loop_playback: bool,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[brw(pad_after = 1)] // padding
pub collision_controllable_without_eobj: bool, pub collision_controllable_without_eobj: bool,
padding: u8,
pub bound_client_path_instance_id: u32, pub bound_client_path_instance_id: u32,
pub move_path_settings: i32, pub move_path_settings: i32,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[brw(pad_after = 3)] // padding
pub not_create_navimesh_door: bool, pub not_create_navimesh_door: bool,
padding1: [u8; 3],
pub initial_transform_state: TransformState, pub initial_transform_state: TransformState,
pub initial_color_state: ColourState, pub initial_color_state: ColourState,
// TODO: read move path settings // TODO: read move path settings

View file

@ -24,7 +24,6 @@ pub struct TriggerBoxInstanceObject {
pub trigger_box_shape: TriggerBoxShape, pub trigger_box_shape: TriggerBoxShape,
pub priority: i16, pub priority: i16,
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[brw(pad_after = 5)] // padding
pub enabled: bool, pub enabled: bool,
padidng: u8,
padding1: u32,
} }

View file

@ -807,10 +807,10 @@ mod tests {
let mut dir = std::env::temp_dir(); let mut dir = std::env::temp_dir();
dir.push("physis-patch-tests"); dir.push("physis-patch-tests");
if dir.exists() { 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() dir.to_str().unwrap().to_string()
} }

View file

@ -1,6 +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
#![allow(unused_variables)] // shut up a nonsensical error in binrw for checksum
use std::io::{BufWriter, Cursor}; use std::io::{BufWriter, Cursor};
use crate::common_file_operations::{read_bool_from, read_string, write_bool_as, write_string}; use crate::common_file_operations::{read_bool_from, read_string, write_bool_as, write_string};

View file

@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#![allow(unused_variables)] // just binrw things with br(temp)
use binrw::binrw; use binrw::binrw;
#[binrw] #[binrw]

View file

@ -1,6 +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
#![allow(unused_variables)] // just binrw things with br(temp)
use std::io::{Cursor, SeekFrom}; use std::io::{Cursor, SeekFrom};
use crate::ByteSpan; use crate::ByteSpan;
@ -136,7 +138,7 @@ pub struct Node {
#[br(little)] #[br(little)]
#[br(magic = b"ShPk")] #[br(magic = b"ShPk")]
#[derive(Debug)] #[derive(Debug)]
#[allow(dead_code, unused_variables)] #[allow(dead_code, unused)]
pub struct ShaderPackage { pub struct ShaderPackage {
version: u32, version: u32,

View file

@ -198,7 +198,7 @@ impl SqPackIndex {
let (directory, filename) = lowercase.split_at(pos); let (directory, filename) = lowercase.split_at(pos);
let directory_crc = CRC.checksum(directory.as_bytes()); 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 { Hash::SplitPath {
name: filename_crc, name: filename_crc,

View file

@ -53,6 +53,7 @@ bitflags! {
#[binrw] #[binrw]
#[brw(repr = u32)] #[brw(repr = u32)]
#[derive(Debug)] #[derive(Debug)]
#[allow(non_camel_case_types)] // NOTE: It's currently allowed to make updating this list not a giant pain
enum TextureFormat { enum TextureFormat {
L8_UNORM = 0x1130, L8_UNORM = 0x1130,
A8_UNORM = 0x1131, A8_UNORM = 0x1131,