Skip to content

Commit

Permalink
pal4: recalc imageset coordinates when resizing texture
Browse files Browse the repository at this point in the history
  • Loading branch information
dontpanic92 committed May 14, 2024
1 parent 1bf2eff commit b843a15
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 31 deletions.
25 changes: 14 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tools/repacker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0"
indicatif = "0.17"
image = "0.23.0"
packfs ={ path = "../../yaobow/packfs" }
regex = "1.10"
zip = "1.2"
4 changes: 1 addition & 3 deletions tools/repacker/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::path::PathBuf;

mod pal4;

fn main() {
Expand All @@ -17,7 +15,7 @@ fn main() {
pal4::repack(pal4::Pal4RepackConfig {
input_folder: input_folder.to_string(),
output_file: output_file.to_string(),
resize_texture: false,
resize_texture: true,
});

println!("Repacking done!");
Expand Down
112 changes: 105 additions & 7 deletions tools/repacker/src/pal4.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::{
fs::File,
io::Write,
io::{Read, Write},
path::{Path, PathBuf},
time::Duration,
};

use image::{GenericImageView, ImageFormat, ImageOutputFormat};
use indicatif::ProgressBar;
use packfs::cpk::CpkArchive;
use zip::{write::SimpleFileOptions, ZipWriter};
Expand All @@ -22,15 +23,17 @@ pub fn repack(config: Pal4RepackConfig) {
let file = File::create(&config.output_file).unwrap();
let mut writer = ZipWriter::new(file);
repack_recursive(
&config,
&bar,
&PathBuf::from(config.input_folder).join("gamedata"),
&PathBuf::from(&config.input_folder).join("gamedata"),
&PathBuf::from(""),
&mut writer,
);
bar.finish();
}

fn repack_recursive(
config: &Pal4RepackConfig,
bar: &ProgressBar,
file_path: &Path,
dest_path: &Path,
Expand All @@ -46,18 +49,20 @@ fn repack_recursive(
for entry in file_path.read_dir().unwrap() {
let dest_path =
dest_path.join(entry.as_ref().unwrap().file_name().to_ascii_lowercase());
repack_recursive(bar, &entry.unwrap().path(), &dest_path, writer);
repack_recursive(&config, bar, &entry.unwrap().path(), &dest_path, writer);
}
} else {
let ext = file_path.extension().and_then(|ext| ext.to_str());
match ext {
Some("cpk") => {
let dest_path = dest_path.parent().unwrap();
repack_cpk(bar, file_path, dest_path, writer);
repack_cpk(config, bar, file_path, dest_path, writer);
}
_ => {
bar.set_message(format!("Processing {}", file_path.display()));
let content = std::fs::read(file_path).unwrap();
let (dest_path, content) = transform(config, dest_path, content);

writer
.start_file(
dest_path.to_str().unwrap(),
Expand All @@ -71,14 +76,21 @@ fn repack_recursive(
}
}

fn repack_cpk(bar: &ProgressBar, file_path: &Path, dest_path: &Path, writer: &mut ZipWriter<File>) {
fn repack_cpk(
config: &Pal4RepackConfig,
bar: &ProgressBar,
file_path: &Path,
dest_path: &Path,
writer: &mut ZipWriter<File>,
) {
let reader = Box::new(std::fs::File::open(file_path).unwrap());
let mut archive = CpkArchive::load(reader).unwrap();

let root = archive.build_directory();
let entry_path = PathBuf::from("");
let dest_path = dest_path.join(file_path.file_stem().unwrap().to_ascii_lowercase());
repack_cpk_recursive(
config,
bar,
&file_path,
&mut archive,
Expand All @@ -90,6 +102,7 @@ fn repack_cpk(bar: &ProgressBar, file_path: &Path, dest_path: &Path, writer: &mu
}

fn repack_cpk_recursive(
config: &Pal4RepackConfig,
bar: &ProgressBar,
archive_path: &Path,
archive: &mut CpkArchive,
Expand All @@ -112,6 +125,7 @@ fn repack_cpk_recursive(
)
.unwrap();
repack_cpk_recursive(
config,
bar,
archive_path,
archive,
Expand All @@ -127,14 +141,98 @@ fn repack_cpk_recursive(
entry_path.display(),
));

let content = archive.open_str(entry_path.to_str().unwrap()).unwrap();
let mut file = archive.open_str(entry_path.to_str().unwrap()).unwrap();
let mut content = Vec::new();
file.read_to_end(&mut content).unwrap();

let (dest_path, content) = transform(config, &dest_path, content);
writer
.start_file(
dest_path.to_str().unwrap(),
SimpleFileOptions::default().compression_method(zip::CompressionMethod::Zstd),
)
.unwrap();
writer.write_all(&content.content()).unwrap();
writer.write_all(&content).unwrap();
}
}
}

fn transform(config: &Pal4RepackConfig, dest_path: &Path, content: Vec<u8>) -> (PathBuf, Vec<u8>) {
let ext = dest_path.extension().and_then(|ext| ext.to_str());
match ext {
Some("png") | Some("dds") => {
if config.resize_texture {
let (new_dest_path, format, output_format) = match ext {
Some("png") => (
dest_path.with_extension("png"),
ImageFormat::Png,
ImageOutputFormat::Png,
),
Some("dds") => (
dest_path.with_extension("dds"),
ImageFormat::Dds,
ImageOutputFormat::Png,
),
_ => unreachable!(),
};
let new_content = resize_texture(&content, format, output_format);
match new_content {
Ok(content) => (new_dest_path, content),
Err(_) => {
println!("Failed to resize texture: {}", dest_path.display());
(dest_path.to_path_buf(), content)
}
}
} else {
(dest_path.to_path_buf(), content)
}
}
Some("imageset") => {
let new_content = recalc_imageset(&content);
(dest_path.to_path_buf(), new_content)
}
_ => (dest_path.to_path_buf(), content),
}
}

fn resize_texture(
content: &Vec<u8>,
image_format: ImageFormat,
output_format: ImageOutputFormat,
) -> anyhow::Result<Vec<u8>> {
let img = image::load_from_memory_with_format(&content, image_format)?;
let width = img.width();
let height = img.height();
let img = img.resize(width / 4, height / 4, image::imageops::FilterType::Lanczos3);
let mut buf = Vec::new();
img.write_to(&mut buf, output_format).unwrap();

Ok(buf)
}

fn recalc_imageset(content: &Vec<u8>) -> Vec<u8> {
let content = String::from_utf8_lossy(&content);
let xpos = regex::Regex::new(r#"(XPos=")(\d+)(")"#).unwrap();
let ypos = regex::Regex::new(r#"(YPos=")(\d+)(")"#).unwrap();
let width = regex::Regex::new(r#"(Width=")(\d+)(")"#).unwrap();
let height = regex::Regex::new(r#"(Height=")(\d+)(")"#).unwrap();

let content = recalc_imageset_item(&content, &xpos);
let content = recalc_imageset_item(&content, &ypos);
let content = recalc_imageset_item(&content, &width);
let content = recalc_imageset_item(&content, &height);

content.into_bytes()
}

fn recalc_imageset_item(content: &str, re: &regex::Regex) -> String {
let captures = re.captures_iter(&content).collect::<Vec<_>>();
let mut result = content.to_string();
for cap in captures.iter().rev() {
let value = cap[2].parse::<u32>().unwrap();
let new_value = value / 4;
result.replace_range(cap.get(2).unwrap().range(), &new_value.to_string());
}

result
}
4 changes: 2 additions & 2 deletions yaobow/shared/src/openpal4/asset_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ impl AssetLoader {
);

scene.add_entity(entity);

println!("Loaded scene: {} {}", scene_name, block_name);
Ok(scene)
}

Expand Down Expand Up @@ -245,10 +247,8 @@ impl AssetLoader {
},
);

println!("Loaded dff: {}", path);
Some(entity)
} else {
println!("Not Loaded dff: {}", path);
None
}
}
Expand Down
8 changes: 0 additions & 8 deletions yaobow/shared/src/openpal4/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,27 +320,19 @@ impl Pal4Scene {
return None;
}

println!("testing interadction");
let position = self.players[leader].world_transform().position();
let mut min_distance = 99999.;
let mut min_function = None;

println!("position: {:?}", position);

for (i, object) in self.objects.iter().enumerate() {
let entry = &self.objects_gob.as_ref().unwrap().entries[i];
let distance = Vec3::norm(&Vec3::sub(&object.world_transform().position(), &position));
println!(
"object: {:?} distance {:?}",
entry.research_function, distance
);
if distance < 50. && distance < min_distance && entry.research_function != "" {
min_distance = distance;
min_function = Some(entry.research_function.to_string().unwrap());
}
}

println!("min_function: {:?}", min_function);
min_function
}

Expand Down

0 comments on commit b843a15

Please sign in to comment.