aboutsummaryrefslogtreecommitdiff
path: root/light-client/tools/src/bin/tex_compose.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-15 20:49:45 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-15 20:49:45 +0200
commit53bd35b77a1240bc0d571d1e7cff3591ca6fde9a (patch)
tree49646c59e3786436655b809c09d113e6124eaa63 /light-client/tools/src/bin/tex_compose.rs
parentc82a2bf203f3495865fd40527fa41a9e32f7aa9c (diff)
downloadhurrycurry-53bd35b77a1240bc0d571d1e7cff3591ca6fde9a.tar
hurrycurry-53bd35b77a1240bc0d571d1e7cff3591ca6fde9a.tar.bz2
hurrycurry-53bd35b77a1240bc0d571d1e7cff3591ca6fde9a.tar.zst
texture compose system
Diffstat (limited to 'light-client/tools/src/bin/tex_compose.rs')
-rw-r--r--light-client/tools/src/bin/tex_compose.rs138
1 files changed, 138 insertions, 0 deletions
diff --git a/light-client/tools/src/bin/tex_compose.rs b/light-client/tools/src/bin/tex_compose.rs
new file mode 100644
index 00000000..77e69c45
--- /dev/null
+++ b/light-client/tools/src/bin/tex_compose.rs
@@ -0,0 +1,138 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use clap::Parser;
+use std::{
+ collections::HashMap,
+ fs::{read_to_string, File},
+ io::{BufRead, BufReader, BufWriter, Write},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ catalogue: PathBuf,
+ texture_dir: PathBuf,
+ output_dir: PathBuf,
+}
+
+fn main() {
+ let Args {
+ catalogue,
+ texture_dir,
+ output_dir,
+ } = Args::parse();
+
+ for line in read_to_string(catalogue).unwrap().lines() {
+ let (line, _) = line.split_once(";").unwrap_or((line, ""));
+ let line = line.trim();
+ if line.is_empty() {
+ continue;
+ }
+
+ let (name, rest) = line.split_once("=").unwrap();
+ let (connects, rest) = rest.split_once(":").unwrap_or(("", rest));
+ eprintln!(" compose {name:?} ({connects})");
+
+ let mut texels = HashMap::new();
+
+ for part in rest.split(",") {
+ let mut mods = part.split("~");
+ let texname = mods.next().unwrap();
+
+ let mut hflip = false;
+ let mut vflip = true;
+ let mut xoff = 0;
+ let mut yoff = 0;
+
+ for m in mods {
+ if m == "hflip" {
+ hflip = !hflip
+ }
+ if m == "vflip" {
+ vflip = !vflip
+ }
+ if let Some(m) = m.strip_prefix("x") {
+ xoff += m.parse::<i32>().unwrap();
+ }
+ if let Some(m) = m.strip_prefix("y") {
+ yoff += m.parse::<i32>().unwrap();
+ }
+ }
+
+ let texpath = texture_dir.join(texname).with_extension("ta");
+ eprintln!(" + {texpath:?}");
+ let file = BufReader::new(File::open(&texpath).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let (width, height) = (tex[0].chars().count(), tex.len());
+
+ for (mut y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ if vflip {
+ y = height - y - 1
+ }
+ for (mut x, char) in line.chars().enumerate() {
+ if hflip {
+ x = width - x - 1
+ }
+ let e = texels
+ .entry((x as i32 + xoff, y as i32 + yoff))
+ .or_insert(' ');
+ if char != ' ' {
+ *e = char
+ }
+ }
+ }
+ }
+
+ let mut min_x = 0;
+ let mut min_y = 0;
+ let mut max_x = 0;
+ let mut max_y = 0;
+ for (x, y) in texels.keys() {
+ min_x = min_x.min(*x);
+ min_y = min_y.min(*y);
+ max_x = max_x.max(*x);
+ max_y = max_y.max(*y);
+ }
+
+ let width = max_x - min_x;
+ let height = max_y - min_y;
+
+ let mut name = name.to_string();
+ if !connects.is_empty() {
+ name += "+";
+ name += connects;
+ }
+ let outpath = output_dir.join(name).with_extension("ta");
+ let mut output = BufWriter::new(File::create(outpath).unwrap());
+
+ for y in 0..height {
+ for x in 0..width {
+ write!(
+ output,
+ "{}",
+ texels.get(&(x + min_x, max_y - y - 1)).unwrap_or(&' ')
+ )
+ .unwrap();
+ }
+ writeln!(output).unwrap();
+ }
+ }
+}