use std::{ fs::{read_to_string, File}, io::Write, }; use image::{GenericImageView, ImageReader}; const FULL_CHARSET: &[u8] = b" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n\t"; fn main() { golfed(); // source code conversion let source_text = read_to_string("../Assets/test/quine.shader").unwrap(); let mut encoded_text: Vec = Vec::new(); let mut temp = 0; let mut i = 0; let mut blob_start = 0; for (index, char) in source_text.chars().enumerate() { if char == '?' { blob_start = index; } temp <<= 8; let char_index = FULL_CHARSET .iter() .position(|&c| c == char as u8) .unwrap_or_else(|| { println!("char {char:?} not in charset"); 0 }); temp |= (char_index as u32) & 0xff; i += 1; if i == 4 { i = 0; encoded_text.push(temp); temp = 0; } } if i > 0 { temp <<= (4 - i) * 8; encoded_text.push(temp); } let mut out_string = String::new(); out_string += "\t\t\t\tconst uint text[] = {"; for t in &encoded_text { out_string += &format!("{t:#010x},"); } out_string += "};\n"; out_string += &format!("\t\t\t\tconst uint text_len = {};\n", encoded_text.len()); out_string += &format!("\t\t\t\tconst uint blob_start = {blob_start};\n"); // font let img = ImageReader::open("vgafont.png").unwrap().decode().unwrap(); let mut out = Vec::new(); for &c in FULL_CHARSET { let col = c as u32 & 0b1_1111; let row = (c as u32 >> 5) & 0b111; let mut encoded: [u32; 4] = [0; 4]; for section in 0..4 { for y in 0..4 { for x in 0..8 { let px = col * 9 + x; let py = row * 16 + (16 - 1 - section * 4) - y; let pixel = (img.get_pixel(px, py).0[0] != 0) as u32; let offset = x + ((y & 3) << 3); encoded[section as usize] |= pixel << offset; } } } out.push(encoded); } out_string += "\n\t\t\t\tconst uint font_a[48][4] = {"; for (i, c) in out.iter().enumerate() { if i == 48 { out_string += &format!("}};\n\t\t\t\tconst uint font_b[{}][4] = {{", out.len() - 48); } out_string += &format!("{{{},{},{},{}}},", c[0], c[1], c[2], c[3]); } out_string += "};\n"; let mut file = File::create("out.h").unwrap(); file.write_all(out_string.as_bytes()).unwrap(); } fn golfed() { // source code conversion let source_text = read_to_string("../Assets/test/quine_golf.shader").unwrap(); let mut encoded_text: Vec = Vec::new(); let mut temp = 0; let mut i = 0; let mut blob_start = 0; let mut used_charset: Vec<_> = " 0123456789abcdefx,".chars().collect(); for (index, char) in source_text.chars().enumerate() { if char == '?' && blob_start == 0 { blob_start = index; continue; } temp *= 80; let char_index = used_charset .iter() .position(|&c| c == char) .unwrap_or_else(|| { used_charset.push(char); used_charset.len() - 1 }); temp += char_index as u32; i += 1; if i == 5 { i = 0; encoded_text.push(temp); temp = 0; } } if i > 0 { for _ in 0..(5 - i) { temp *= 80; } encoded_text.push(temp); } let mut out_string = String::new(); out_string += "g t[]={"; for t in &encoded_text { out_string += &format!("{t:#010x},"); } out_string += "};\n"; out_string += &format!("g b={blob_start};\n"); out_string += &format!( "uint magic_number_L_plus_b= {};\n", encoded_text.len() * 11 + blob_start ); out_string += &format!("uint magic_number_L= {};\n", encoded_text.len() * 11); // font let img = ImageReader::open("6x6.png").unwrap().decode().unwrap(); let mut out = Vec::new(); for c in used_charset { let col = c as u32 & 0b1_1111; let row = (c as u32 >> 5) & 0b111; let mut encoded = 0u32; for y in 0..6 { for x in 0..5 { let px = col * 6 + x; let py = row * 6 + 5 - y; let pixel = (img.get_pixel(px, py).0[0] > 40) as u32; let offset = x + y * 5; encoded |= pixel << offset; } } out.push(encoded); } out_string += "g R[]={"; for (_i, c) in out.iter().enumerate() { out_string += &format!("{c},"); } out_string += "};\n"; let mut file = File::create("out_golfed.h").unwrap(); file.write_all(out_string.as_bytes()).unwrap(); }