aboutsummaryrefslogtreecommitdiff
path: root/light-client/tools/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-15 15:00:27 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-15 15:00:27 +0200
commit340aa47c4652fe2f0ec5b0e4f293cfff407a0e6c (patch)
tree1d0aad02c54a223b092eb74d065dfbc68cba56f6 /light-client/tools/src
parentd3101bbfd9adf84ef8f0061383272eeaecf224d3 (diff)
downloadhurrycurry-340aa47c4652fe2f0ec5b0e4f293cfff407a0e6c.tar
hurrycurry-340aa47c4652fe2f0ec5b0e4f293cfff407a0e6c.tar.bz2
hurrycurry-340aa47c4652fe2f0ec5b0e4f293cfff407a0e6c.tar.zst
add texture import/export system for light client
Diffstat (limited to 'light-client/tools/src')
-rw-r--r--light-client/tools/src/bin/tex_export.rs58
-rw-r--r--light-client/tools/src/bin/tex_import.rs58
-rw-r--r--light-client/tools/src/bin/tex_pack.rs77
-rw-r--r--light-client/tools/src/lib.rs0
4 files changed, 193 insertions, 0 deletions
diff --git a/light-client/tools/src/bin/tex_export.rs b/light-client/tools/src/bin/tex_export.rs
new file mode 100644
index 00000000..2132b5ed
--- /dev/null
+++ b/light-client/tools/src/bin/tex_export.rs
@@ -0,0 +1,58 @@
+use clap::Parser;
+use image::Rgba;
+use std::{
+ collections::HashMap,
+ fs::File,
+ io::{BufRead, BufReader},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ input: PathBuf,
+ output: PathBuf,
+}
+
+fn main() {
+ let Args {
+ input,
+ output: out_path,
+ } = Args::parse();
+
+ let palette = include_str!("../../../textures/palette.csv")
+ .split('\n')
+ .filter(|l| !l.is_empty())
+ .map(|s| {
+ let (c, s) = s.split_once(",").unwrap();
+ let (r, s) = s.split_once(",").unwrap();
+ let (g, s) = s.split_once(",").unwrap();
+ let (b, a) = s.split_once(",").unwrap();
+ (
+ c.chars().next().unwrap(),
+ [
+ r.parse().unwrap(),
+ g.parse().unwrap(),
+ b.parse().unwrap(),
+ a.parse().unwrap(),
+ ],
+ )
+ })
+ .collect::<HashMap<_, _>>();
+
+ let file = BufReader::new(File::open(&input).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let (width, height) = (tex[0].len(), tex.len());
+
+ let mut output = image::ImageBuffer::<Rgba<u8>, Vec<_>>::new(width as u32, height as u32);
+
+ for (y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ for (x, char) in line.chars().enumerate() {
+ output.put_pixel(x as u32, y as u32, Rgba(*palette.get(&char).unwrap()));
+ }
+ }
+
+ output.save(out_path).unwrap();
+}
diff --git a/light-client/tools/src/bin/tex_import.rs b/light-client/tools/src/bin/tex_import.rs
new file mode 100644
index 00000000..89cbc8c9
--- /dev/null
+++ b/light-client/tools/src/bin/tex_import.rs
@@ -0,0 +1,58 @@
+use clap::Parser;
+use std::{
+ collections::HashMap,
+ fs::File,
+ io::{BufWriter, Write},
+ path::PathBuf,
+ process::exit,
+};
+
+#[derive(Parser)]
+struct Args {
+ input: PathBuf,
+ output: PathBuf,
+}
+
+fn main() {
+ let Args { input, output } = Args::parse();
+
+ let palette = include_str!("../../../textures/palette.csv")
+ .split('\n')
+ .filter(|l| !l.is_empty())
+ .map(|s| {
+ let (c, s) = s.split_once(",").unwrap();
+ let (r, s) = s.split_once(",").unwrap();
+ let (g, s) = s.split_once(",").unwrap();
+ let (b, a) = s.split_once(",").unwrap();
+ (
+ [
+ r.parse().unwrap(),
+ g.parse().unwrap(),
+ b.parse().unwrap(),
+ a.parse().unwrap(),
+ ],
+ c.chars().next().unwrap(),
+ )
+ })
+ .collect::<HashMap<_, _>>();
+
+ let input = image::open(input).unwrap().to_rgba8();
+ let mut output = BufWriter::new(File::create(output).unwrap());
+
+ for y in 0..input.height() {
+ for x in 0..input.width() {
+ let mut c = input.get_pixel(x, y).0;
+ if c[3] == 0 {
+ c = [0, 0, 0, 0];
+ }
+ let Some(char) = palette.get(&c) else {
+ eprintln!("color at {x},{y} not in palette: {c:?}");
+ exit(1);
+ };
+ write!(output, "{char}").unwrap();
+ }
+ writeln!(output).unwrap();
+ }
+ output.flush().unwrap();
+ output.into_inner().unwrap().flush().unwrap()
+}
diff --git a/light-client/tools/src/bin/tex_pack.rs b/light-client/tools/src/bin/tex_pack.rs
new file mode 100644
index 00000000..23056608
--- /dev/null
+++ b/light-client/tools/src/bin/tex_pack.rs
@@ -0,0 +1,77 @@
+use clap::Parser;
+use std::{
+ fs::File,
+ io::{BufRead, BufReader, BufWriter, Write},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ atlas_out: PathBuf,
+ atlas_meta_out: PathBuf,
+ inputs: Vec<PathBuf>,
+}
+
+fn main() {
+ let Args {
+ inputs,
+ atlas_meta_out,
+ atlas_out,
+ } = Args::parse();
+
+ let atlas_size = 1024;
+
+ let mut cursor_x = 0;
+ let mut cursor_y = 0;
+ let mut row_height = 0;
+
+ let mut texels = vec![vec![' '; atlas_size]; atlas_size];
+ let mut metadata = Vec::new();
+
+ for path in inputs {
+ let file = BufReader::new(File::open(&path).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let (width, height) = (tex[0].len(), tex.len());
+
+ if cursor_x + width > atlas_size {
+ cursor_y += row_height;
+ row_height = 0;
+ cursor_x = 0;
+ }
+ if cursor_y + height > atlas_size {
+ panic!("texture too big or atlas full")
+ }
+ row_height = row_height.max(atlas_size);
+ let texcoord = [cursor_x, cursor_y];
+
+ for (y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ for (x, char) in line.chars().enumerate() {
+ texels[cursor_y + y][cursor_x + x] = char;
+ }
+ }
+
+ metadata.push((
+ texcoord,
+ path.file_stem().unwrap().to_str().unwrap().to_string(),
+ ));
+
+ cursor_x += atlas_size;
+ }
+
+ let mut atlas_out = BufWriter::new(File::create(atlas_out).unwrap());
+ let mut atlas_meta_out = BufWriter::new(File::create(atlas_meta_out).unwrap());
+
+ for line in texels {
+ for char in line {
+ write!(atlas_out, "{char}").unwrap()
+ }
+ writeln!(atlas_out).unwrap();
+ }
+
+ for ([x, y], name) in metadata {
+ writeln!(atlas_meta_out, "{x},{y},{name}").unwrap();
+ }
+}
diff --git a/light-client/tools/src/lib.rs b/light-client/tools/src/lib.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/light-client/tools/src/lib.rs