|
|
@@ -0,0 +1,150 @@
|
|
|
+// primarily used for writing the file
|
|
|
+use std::f64::consts::PI;
|
|
|
+use std::{env, fs, path::Path};
|
|
|
+
|
|
|
+const PROJECTION_PLANE_WIDTH: usize = 320;
|
|
|
+const TILE_SIZE: f64 = 64.0;
|
|
|
+
|
|
|
+const ANGLE_0: usize = 0;
|
|
|
+const ANGLE_60: usize = PROJECTION_PLANE_WIDTH;
|
|
|
+const ANGLE_30: usize = ANGLE_60 / 2;
|
|
|
+const ANGLE_90: usize = ANGLE_30 * 3;
|
|
|
+const ANGLE_180: usize = ANGLE_60 * 3;
|
|
|
+const ANGLE_270: usize = ANGLE_90 * 3;
|
|
|
+const ANGLE_360: usize = ANGLE_60 * 6;
|
|
|
+
|
|
|
+const MAX_RAY_LENGTH: usize = 2048;
|
|
|
+const WALL_HEIGHT_SCALE_FACTOR: usize = 18000;
|
|
|
+const WALL_HEIGHT_MAX: i32 = 640;
|
|
|
+const WALL_HEIGHT_MIN: i32 = 8;
|
|
|
+
|
|
|
+fn clamp(x: i32, min: i32, max: i32) -> i32 {
|
|
|
+ if x < min {
|
|
|
+ min
|
|
|
+ } else if x > max {
|
|
|
+ max
|
|
|
+ } else {
|
|
|
+ x
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn radian(angle: usize) -> f64 {
|
|
|
+ angle as f64 * PI / ANGLE_180 as f64
|
|
|
+}
|
|
|
+
|
|
|
+fn iradian(angle: i32) -> f64 {
|
|
|
+ angle as f64 * PI / ANGLE_180 as f64
|
|
|
+}
|
|
|
+
|
|
|
+fn float_to_fix(x: f64) -> i32 {
|
|
|
+ (x * 65536.0) as i32
|
|
|
+}
|
|
|
+
|
|
|
+fn stringify(name: &str, arr: &[i32], size: usize) -> String {
|
|
|
+ let mut array_string = String::from("static ");
|
|
|
+ array_string.push_str(name);
|
|
|
+ array_string.push_str(":[i32; ");
|
|
|
+ array_string.push_str(size.to_string().as_str());
|
|
|
+ array_string.push_str("] = [\r\n");
|
|
|
+ for a in arr {
|
|
|
+ // a little bit of formatting is happening as well
|
|
|
+ array_string.push_str("\u{20}\u{20}\u{20}\u{20}");
|
|
|
+ array_string.push_str(a.to_string().as_str());
|
|
|
+ array_string.push_str(",\r\n");
|
|
|
+ }
|
|
|
+ array_string.push_str("];\r\n");
|
|
|
+ array_string
|
|
|
+}
|
|
|
+
|
|
|
+fn main() {
|
|
|
+ const SIZE: usize = ANGLE_360 + 1;
|
|
|
+
|
|
|
+ let mut sin: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut cos: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut tan: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut isin: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut icos: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut itan: [i32; SIZE] = [0; SIZE];
|
|
|
+
|
|
|
+ for i in 0..=1920 {
|
|
|
+ sin[i] = float_to_fix(radian(i).sin());
|
|
|
+ cos[i] = float_to_fix(radian(i).cos());
|
|
|
+ tan[i] = float_to_fix(radian(i).tan());
|
|
|
+ isin[i] = float_to_fix(1.0 / radian(i).sin());
|
|
|
+ icos[i] = float_to_fix(1.0 / radian(i).cos());
|
|
|
+ itan[i] = float_to_fix(1.0 / radian(i).tan());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ let mut output = stringify("SIN", &sin, SIZE);
|
|
|
+ output.push_str(stringify("COS", &cos, SIZE).as_str());
|
|
|
+ output.push_str(stringify("TAN", &tan, SIZE).as_str());
|
|
|
+ output.push_str(stringify("ISIN", &isin, SIZE).as_str());
|
|
|
+ output.push_str(stringify("ICOS", &icos, SIZE).as_str());
|
|
|
+ output.push_str(stringify("ITAN", &itan, SIZE).as_str());
|
|
|
+
|
|
|
+ let mut x_step: [i32; SIZE] = [0; SIZE];
|
|
|
+ let mut y_step: [i32; SIZE] = [0; SIZE];
|
|
|
+
|
|
|
+ for i in 0..=1920 {
|
|
|
+ let mut step: f64;
|
|
|
+
|
|
|
+ if radian(i).tan() == 0.0 {
|
|
|
+ step = f64::MAX
|
|
|
+ } else {
|
|
|
+ step = TILE_SIZE / radian(i).tan();
|
|
|
+
|
|
|
+ if i >= ANGLE_90 && i < ANGLE_270 {
|
|
|
+ if step < 0.0 {
|
|
|
+ step = -step;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if step > 0.0 {
|
|
|
+ step = -step;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ x_step[i] = float_to_fix(step);
|
|
|
+ }
|
|
|
+
|
|
|
+ for i in 0..=1920 {
|
|
|
+ let mut step = TILE_SIZE * radian(i).tan();
|
|
|
+
|
|
|
+ if i >= ANGLE_0 && i < ANGLE_180 {
|
|
|
+ if step < 0.0 {
|
|
|
+ step = -step;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if step > 0.0 {
|
|
|
+ step = -step;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ y_step[i] = (step * 65536.0) as i32; //float_to_fix(step);
|
|
|
+ }
|
|
|
+
|
|
|
+ output.push_str(stringify("X_STEP", &x_step, SIZE).as_str());
|
|
|
+ output.push_str(stringify("Y_STEP", &y_step, SIZE).as_str());
|
|
|
+
|
|
|
+ let mut fisheye: [i32; PROJECTION_PLANE_WIDTH] = [0; PROJECTION_PLANE_WIDTH];
|
|
|
+
|
|
|
+ for i in 0..PROJECTION_PLANE_WIDTH {
|
|
|
+ fisheye[i] = float_to_fix(1.0 / iradian(i as i32 - ANGLE_30 as i32).cos());
|
|
|
+ }
|
|
|
+
|
|
|
+ output.push_str(stringify("FISHEYE", &fisheye, PROJECTION_PLANE_WIDTH).as_str());
|
|
|
+
|
|
|
+ let mut wall_height: [i32; MAX_RAY_LENGTH + 1] = [0; MAX_RAY_LENGTH + 1];
|
|
|
+ for i in 0..=MAX_RAY_LENGTH {
|
|
|
+ wall_height[i] = clamp((WALL_HEIGHT_SCALE_FACTOR / i.max(1)) as i32, WALL_HEIGHT_MIN, WALL_HEIGHT_MAX);
|
|
|
+ }
|
|
|
+
|
|
|
+ output.push_str(stringify("WALL_HEIGHT", &wall_height, MAX_RAY_LENGTH + 1).as_str());
|
|
|
+
|
|
|
+ // write the string to a file. OUT_DIR environment variable is defined by cargo
|
|
|
+ let out_dir = env::var("OUT_DIR").unwrap();
|
|
|
+ let dest_path = Path::new(&out_dir).join("lookup.rs");
|
|
|
+ fs::write(&dest_path, output).unwrap();
|
|
|
+}
|