From 43e476a11668c800db5459397dbf580289ffadb4 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Mon, 8 Jan 2024 22:15:46 -0800
Subject: [PATCH] wip

---
 src/main.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/src/main.rs b/src/main.rs
index ca96ef8..fce857e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,6 +6,8 @@ use anyhow::Result as AResult;
 #[command(author, version, about, long_about = None)]
 #[command(propagate_version = true)]
 struct Cli {
+	#[arg(long)]
+	vpk_path:Option<std::path::PathBuf>,
 	#[command(subcommand)]
 	command: Commands,
 }
@@ -14,6 +16,7 @@ struct Cli {
 enum Commands {
 	Download(MapList),
 	DownloadTextures(PathBufList),
+	ExtractTextures(PathBufList),
 	ConvertTextures,
 	DownloadMeshes(PathBufList),
 	Extract(PathBufList),
@@ -40,6 +43,7 @@ fn main() -> AResult<()> {
 	match cli.command {
 		Commands::Download(map_list)=>download(map_list.maps),
 		Commands::DownloadTextures(pathlist)=>download_textures(pathlist.paths),
+		Commands::ExtractTextures(pathlist)=>extract_textures(pathlist.paths,cli.vpk_path.unwrap()),
 		Commands::ConvertTextures=>convert_textures(),
 		Commands::DownloadMeshes(pathlist)=>download_meshes(pathlist.paths),
 		Commands::Extract(pathlist)=>extract(pathlist.paths),
@@ -1038,3 +1042,57 @@ fn write_attributes() -> AResult<()>{
 	}
 	Ok(())
 }
+
+fn extract_textures(paths:Vec<std::path::PathBuf>,vpk_path:std::path::PathBuf)->AResult<()>{
+	let vpk_index=vpk::VPK::read(&vpk_path)?;
+	let mut vpk_cache=std::collections::HashMap::new();
+	for path in paths{
+		let bsp=vbsp::Bsp::read(std::fs::read(path)?.as_ref())?;
+		for texture in bsp.textures(){
+			let texture_name=texture.texture_data().name();
+			let texture_file_name=format!("materials/{}.vtf",texture_name);
+			println!("texture_name={}",texture_file_name);
+			if let Some(stuff)=vpk_index.tree.get(texture_file_name.as_str()){
+				let vpk=if let Some(vpk)=vpk_cache.get(stuff.archive_path.as_str()){
+					println!("ayyyy");
+					vpk
+				}else{
+					println!("hiii");
+					let vpk=vpk::VPK::read(&std::path::PathBuf::from(&stuff.archive_path))?;
+					println!("hiiiiii");
+					vpk_cache.insert(stuff.archive_path.as_str(),vpk);
+					vpk_cache.get(stuff.archive_path.as_str()).unwrap()
+				};
+				if let Some(stuff)=vpk.tree.get(texture_file_name.as_str()){
+					let image=vtf::from_bytes(&mut stuff.get()?.to_vec())?.highres_image.decode(0)?.to_rgba8();
+
+					let format=if image.width()%4!=0||image.height()%4!=0{
+						image_dds::ImageFormat::R8G8B8A8Srgb
+					}else{
+						image_dds::ImageFormat::BC7Srgb
+					};
+					//this fails if the image dimensions are not a multiple of 4
+					let dds = image_dds::dds_from_image(
+						&image,
+						format,
+						image_dds::Quality::Slow,
+						image_dds::Mipmaps::GeneratedAutomatic,
+					)?;
+
+					//write dds
+					let mut dest=std::path::PathBuf::from("textures/dds");
+					dest.push(texture_name);
+					dest.set_extension("dds");
+					std::fs::create_dir_all(dest.parent().unwrap())?;
+					let mut writer = std::io::BufWriter::new(std::fs::File::create(dest)?);
+					dds.write(&mut writer)?;
+				}else{
+					println!("zip");
+				}
+			}else{
+				println!("nonadat");
+			}
+		}
+	}
+	Ok(())
+}
\ No newline at end of file