diff --git a/lib/sdk/src/filetype/texture.rs b/lib/sdk/src/filetype/texture.rs index 7486fb8..7912e45 100644 --- a/lib/sdk/src/filetype/texture.rs +++ b/lib/sdk/src/filetype/texture.rs @@ -6,7 +6,7 @@ use color_eyre::eyre::Context; use color_eyre::{eyre, SectionExt}; use color_eyre::{Help, Result}; use oodle::{OodleLZ_CheckCRC, OodleLZ_FuzzSafe}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use tokio::fs; use crate::binary::sync::{ReadExt, WriteExt}; @@ -14,6 +14,30 @@ use crate::bundle::file::UserFile; use crate::murmur::{HashGroup, IdString32, IdString64}; use crate::{BundleFile, BundleFileType, BundleFileVariant}; +#[derive(Clone, Debug, Deserialize, Serialize)] +struct TextureDefinition { + common: TextureDefinitionPlatform, + // Stingray supports per-platform sections here, where you can create overrides with the same + // values as in `common`. But since we only support PC, we don't need to implement + // that. +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +struct TextureDefinitionPlatform { + input: TextureDefinitionInput, + output: TextureDefinitionOutput, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +struct TextureDefinitionInput { + filename: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +struct TextureDefinitionOutput { + category: String, +} + bitflags! { #[derive(Clone, Copy, Debug)] struct TextureFlags: u32 { @@ -227,8 +251,21 @@ impl Texture { } #[tracing::instrument] - fn to_user_files(&self, name: String) -> Vec { - let mut files = Vec::with_capacity(2); + fn to_sjson(&self, filename: String) -> Result { + let texture = TextureDefinition { + common: TextureDefinitionPlatform { + input: TextureDefinitionInput { filename }, + output: TextureDefinitionOutput { + category: self.category.display().to_string(), + }, + }, + }; + serde_sjson::to_string(&texture).wrap_err("Failed to serialize texture definition") + } + + #[tracing::instrument] + fn to_user_files(&self, name: String) -> Result> { + let mut files = Vec::with_capacity(3); // TODO: Don't clone. @@ -240,35 +277,20 @@ impl Texture { )); } + { + let data = self.to_sjson(name.clone())?.as_bytes().to_vec(); + let name = PathBuf::from(&name) + .with_extension("texture") + .display() + .to_string(); + files.push(UserFile::with_name(data, name)); + } + files.push(UserFile::with_name(self.data.clone(), name)); - files + Ok(files) } } -#[derive(Clone, Debug, Deserialize)] -struct TextureDefinition { - common: TextureDefinitionPlatform, - // Stingray supports per-platform sections here, where you can create overrides with the same - // values as in `common`. But since we only support PC, we don't need to implement - // that. -} - -#[derive(Clone, Debug, Deserialize)] -struct TextureDefinitionPlatform { - input: TextureDefinitionInput, - output: TextureDefinitionOutput, -} - -#[derive(Clone, Debug, Deserialize)] -struct TextureDefinitionInput { - filename: String, -} - -#[derive(Clone, Debug, Deserialize)] -struct TextureDefinitionOutput { - category: String, -} - #[tracing::instrument(skip(ctx, data), fields(buf_len = data.as_ref().len()))] pub(crate) async fn decompile_data( ctx: &crate::Context, @@ -287,8 +309,9 @@ pub(crate) async fn decompile_data( }; let texture = Texture::from_binary(ctx, &mut r, stream_r.as_mut())?; - let files = texture.to_user_files(name); - Ok(files) + texture + .to_user_files(name) + .wrap_err("Failed to build user files") } #[tracing::instrument(skip(ctx))]