From cc729e38d86d54110f616b2c126e3aa3d53405fe Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 21 Apr 2024 10:04:35 -0400 Subject: [PATCH] Add crc method to SHPK for calculating it's value, add test for selector --- Cargo.toml | 7 ++++--- src/shpk.rs | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e6df754..9a66afc 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,6 @@ hmac-sha512 = "1" # used while rust doesn't have native benchmarking capability brunch = { version = "0.5.3", default-features = false } -# used for testing our jamcrc implementation -crc = "3" [features] default = ["visual_data"] @@ -67,4 +65,7 @@ half = { version = "2", optional = true } bitflags = { version = "1.3", optional = true } # needed for dxt/bc decompression -texture2ddecoder = { version = "0.0.5", optional = true } \ No newline at end of file +texture2ddecoder = { version = "0.0.5", optional = true } + +# used for testing our jamcrc implementation and currently SHPK +crc = "3" \ No newline at end of file diff --git a/src/shpk.rs b/src/shpk.rs index ece5b24..8d0db6b 100644 --- a/src/shpk.rs +++ b/src/shpk.rs @@ -5,6 +5,7 @@ use std::io::{Cursor, SeekFrom}; use crate::ByteSpan; use binrw::{binread, BinRead}; +use crc::{Algorithm, Crc}; #[binread] #[br(little, import { @@ -68,11 +69,12 @@ pub struct MaterialParameter { } #[binread] -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] +#[repr(C)] #[allow(unused)] pub struct Key { - id: u32, - default_value: u32, + pub id: u32, + pub default_value: u32, } #[binread] @@ -171,7 +173,7 @@ pub struct ShaderPackage { #[br(count = scene_key_count)] scene_keys: Vec, #[br(count = material_key_count)] - material_keys: Vec, + pub material_keys: Vec, sub_view_key1_default: u32, sub_view_key2_default: u32, @@ -186,6 +188,12 @@ pub struct ShaderPackage { node_aliases: Vec, } +const SELECTOR_MULTIPLER: u32 = 31; + +// TODO: replace use of crc crate here +const CRC_32_TEST: Algorithm = Algorithm { width: 32, poly: 0x04c11db7, init: 0x00000000, refin: true, refout: true, xorout: 0x00000000, check: 0x765e7680, residue: 0xc704dd7b }; +const JAMCR: Crc = Crc::::new(&CRC_32_TEST); + impl ShaderPackage { /// Reads an existing SHPK file pub fn from_existing(buffer: ByteSpan) -> Option { @@ -241,17 +249,22 @@ impl ShaderPackage { for key in keys { selector = selector.wrapping_add(key.wrapping_mul(multiplier)); - multiplier = multiplier.wrapping_mul(31); + multiplier = multiplier.wrapping_mul(SELECTOR_MULTIPLER); } selector } + + pub fn crc(str: &str) -> u32 { + return JAMCR.checksum(str.as_bytes()); + } } #[cfg(test)] mod tests { use std::fs::read; use std::path::PathBuf; + use crate::repository::Category::Shader; use super::*; @@ -264,4 +277,21 @@ mod tests { // Feeding it invalid data should not panic ShaderPackage::from_existing(&read(d).unwrap()); } + + #[test] + fn test_crc() { + assert_eq!(ShaderPackage::crc("PASS_0"), 0xC5A5389C); + assert_eq!(ShaderPackage::crc("DecodeDepthBuffer"), 0x2C6C023C); + } + + #[test] + fn test_selector() { + 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")], + &[3756477356, 1556481461, 1111668802, 428675533], + &[ShaderPackage::crc("Default"), ShaderPackage::crc("SUB_VIEW_MAIN")]); + + assert_eq!(selector, 0x1075AE91); + } }