aboutsummaryrefslogtreecommitdiff
path: root/src/bin/textures.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/textures.rs')
-rw-r--r--src/bin/textures.rs84
1 files changed, 55 insertions, 29 deletions
diff --git a/src/bin/textures.rs b/src/bin/textures.rs
index 5cfaaa7..83ffb07 100644
--- a/src/bin/textures.rs
+++ b/src/bin/textures.rs
@@ -1,10 +1,12 @@
+use anyhow::anyhow;
+use log::warn;
use std::{
env::args,
fs::{File, create_dir_all},
- io::{BufReader, Seek, SeekFrom},
+ io::{BufReader, Read, Seek, SeekFrom},
};
use unity_tools::{
- classes::{FromValue, texture2d::Texture2d},
+ classes::{FromValue, texture2d::Texture2D},
object::read_value,
serialized_file::read_serialized_file,
unityfs::UnityFS,
@@ -12,37 +14,61 @@ use unity_tools::{
fn main() -> anyhow::Result<()> {
env_logger::init_from_env("LOG");
- let file = BufReader::new(File::open(args().nth(1).unwrap())?);
- let mut fs = UnityFS::open(file)?;
+ let file = || BufReader::new(File::open(args().nth(1).unwrap()).unwrap());
+ let mut fs = UnityFS::open(file())?;
+ let mut fs2 = UnityFS::open(file())?;
let mut i = 0;
create_dir_all("/tmp/tex").unwrap();
- for node in fs.nodes().to_vec() {
- if node.name.ends_with(".resource") || node.name.ends_with(".resS") {
- continue;
- }
- let mut cab = fs.read(&node)?;
- let file = read_serialized_file(&mut cab)?;
- for ob in file.objects {
- cab.seek(SeekFrom::Start(ob.data_offset))?;
- let typetree = if ob.type_id < 0 {
- unimplemented!()
- } else {
- &file.types[ob.type_id as usize]
- };
- if let Some(typetree) = &typetree.type_tree {
- if typetree.type_string != "Texture2D" {
- continue;
- }
- let value = read_value(typetree, file.endianness, &mut cab)?;
- let texture = Texture2d::from_value(value).unwrap();
- if texture.image_data.len() > 0 {
- let path = format!("/tmp/tex/{i}.png");
- println!("{path}");
- texture.to_image().unwrap().save(path).unwrap();
- i += 1;
- }
+
+ let cabfile = fs
+ .nodes()
+ .iter()
+ .find(|n| !n.name.ends_with(".resource") && !n.name.ends_with(".resS"))
+ .ok_or(anyhow!("no CAB file found"))?
+ .to_owned();
+ let ressfile = fs2
+ .nodes()
+ .iter()
+ .find(|n| n.name.ends_with(".resS"))
+ .ok_or(anyhow!("no resS file found"))?
+ .to_owned();
+
+ let mut cab = fs.read(&cabfile)?;
+ let mut ress = fs2.read(&ressfile)?;
+ let file = read_serialized_file(&mut cab)?;
+ for ob in file.objects {
+ cab.seek(SeekFrom::Start(ob.data_offset))?;
+ let typetree = if ob.type_id < 0 {
+ unimplemented!()
+ } else {
+ &file.types[ob.type_id as usize]
+ };
+ if let Some(typetree) = &typetree.type_tree {
+ if typetree.type_string != "Texture2D" {
+ continue;
+ }
+ let value = read_value(typetree, file.endianness, &mut cab)?;
+ let mut texture = Texture2D::from_value(value).unwrap();
+ if texture.image_data.len() == 0 {
+ ress.seek(SeekFrom::Start(texture.stream_data.offset as u64))?;
+ ress.by_ref()
+ .take(texture.stream_data.size as u64)
+ .read_to_end(&mut texture.image_data)?;
+ }
+ let path = format!(
+ "/tmp/tex/{}_{i}.png",
+ texture.name.replace("/", "-").replace(".", "-")
+ );
+ println!(
+ "{path} {}x{} {:?}",
+ texture.width, texture.height, texture.format
+ );
+ match texture.to_image() {
+ Ok(im) => im.save(path).unwrap(),
+ Err(e) => warn!("{e}"),
}
+ i += 1;
}
}