build.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // primarily used for writing the file
  2. use std::f64::consts::PI;
  3. use std::{env, fs, path::Path};
  4. const PROJECTION_PLANE_WIDTH: usize = 320;
  5. const TILE_SIZE: f64 = 64.0;
  6. const ANGLE_0: usize = 0;
  7. const ANGLE_60: usize = PROJECTION_PLANE_WIDTH;
  8. const ANGLE_30: usize = ANGLE_60 / 2;
  9. const ANGLE_90: usize = ANGLE_30 * 3;
  10. const ANGLE_180: usize = ANGLE_60 * 3;
  11. const ANGLE_270: usize = ANGLE_90 * 3;
  12. const ANGLE_360: usize = ANGLE_60 * 6;
  13. const MAX_RAY_LENGTH: usize = 2048;
  14. const WALL_HEIGHT_SCALE_FACTOR: usize = 18000;
  15. const WALL_HEIGHT_MAX: i32 = 640;
  16. const WALL_HEIGHT_MIN: i32 = 8;
  17. fn clamp(x: i32, min: i32, max: i32) -> i32 {
  18. if x < min {
  19. min
  20. } else if x > max {
  21. max
  22. } else {
  23. x
  24. }
  25. }
  26. fn radian(angle: usize) -> f64 {
  27. angle as f64 * PI / ANGLE_180 as f64
  28. }
  29. fn iradian(angle: i32) -> f64 {
  30. angle as f64 * PI / ANGLE_180 as f64
  31. }
  32. fn float_to_fix(x: f64) -> i32 {
  33. (x * 65536.0) as i32
  34. }
  35. fn stringify(name: &str, arr: &[i32], size: usize) -> String {
  36. let mut array_string = String::from("static ");
  37. array_string.push_str(name);
  38. array_string.push_str(":[i32; ");
  39. array_string.push_str(size.to_string().as_str());
  40. array_string.push_str("] = [\r\n");
  41. for a in arr {
  42. // a little bit of formatting is happening as well
  43. array_string.push_str("\u{20}\u{20}\u{20}\u{20}");
  44. array_string.push_str(a.to_string().as_str());
  45. array_string.push_str(",\r\n");
  46. }
  47. array_string.push_str("];\r\n");
  48. array_string
  49. }
  50. fn main() {
  51. const SIZE: usize = ANGLE_360 + 1;
  52. let mut sin: [i32; SIZE] = [0; SIZE];
  53. let mut cos: [i32; SIZE] = [0; SIZE];
  54. let mut tan: [i32; SIZE] = [0; SIZE];
  55. let mut isin: [i32; SIZE] = [0; SIZE];
  56. let mut icos: [i32; SIZE] = [0; SIZE];
  57. let mut itan: [i32; SIZE] = [0; SIZE];
  58. for i in 0..=1920 {
  59. sin[i] = float_to_fix(radian(i).sin());
  60. cos[i] = float_to_fix(radian(i).cos());
  61. tan[i] = float_to_fix(radian(i).tan());
  62. isin[i] = float_to_fix(1.0 / radian(i).sin());
  63. icos[i] = float_to_fix(1.0 / radian(i).cos());
  64. itan[i] = float_to_fix(1.0 / radian(i).tan());
  65. }
  66. let mut output = stringify("SIN", &sin, SIZE);
  67. output.push_str(stringify("COS", &cos, SIZE).as_str());
  68. output.push_str(stringify("TAN", &tan, SIZE).as_str());
  69. output.push_str(stringify("ISIN", &isin, SIZE).as_str());
  70. output.push_str(stringify("ICOS", &icos, SIZE).as_str());
  71. output.push_str(stringify("ITAN", &itan, SIZE).as_str());
  72. let mut x_step: [i32; SIZE] = [0; SIZE];
  73. let mut y_step: [i32; SIZE] = [0; SIZE];
  74. for i in 0..=1920 {
  75. let mut step: f64;
  76. if radian(i).tan() == 0.0 {
  77. step = f64::MAX
  78. } else {
  79. step = TILE_SIZE / radian(i).tan();
  80. if i >= ANGLE_90 && i < ANGLE_270 {
  81. if step > 0.0 {
  82. step = -step;
  83. }
  84. } else {
  85. if step < 0.0 {
  86. step = -step;
  87. }
  88. }
  89. }
  90. x_step[i] = float_to_fix(step);
  91. }
  92. for i in 0..=1920 {
  93. let mut step = TILE_SIZE * radian(i).tan();
  94. if i >= ANGLE_0 && i < ANGLE_180 {
  95. if step < 0.0 {
  96. step = -step;
  97. }
  98. } else {
  99. if step > 0.0 {
  100. step = -step;
  101. }
  102. }
  103. y_step[i] = (step * 65536.0) as i32; //float_to_fix(step);
  104. }
  105. output.push_str(stringify("X_STEP", &x_step, SIZE).as_str());
  106. output.push_str(stringify("Y_STEP", &y_step, SIZE).as_str());
  107. let mut fisheye: [i32; PROJECTION_PLANE_WIDTH] = [0; PROJECTION_PLANE_WIDTH];
  108. for i in 0..PROJECTION_PLANE_WIDTH {
  109. fisheye[i] = float_to_fix(1.0 / iradian(i as i32 - ANGLE_30 as i32).cos());
  110. }
  111. output.push_str(stringify("FISHEYE", &fisheye, PROJECTION_PLANE_WIDTH).as_str());
  112. let mut wall_height: [i32; MAX_RAY_LENGTH + 1] = [0; MAX_RAY_LENGTH + 1];
  113. for i in 0..=MAX_RAY_LENGTH {
  114. wall_height[i] = clamp((WALL_HEIGHT_SCALE_FACTOR / i.max(1)) as i32, WALL_HEIGHT_MIN, WALL_HEIGHT_MAX);
  115. }
  116. output.push_str(stringify("WALL_HEIGHT", &wall_height, MAX_RAY_LENGTH + 1).as_str());
  117. // write the string to a file. OUT_DIR environment variable is defined by cargo
  118. let out_dir = env::var("OUT_DIR").unwrap();
  119. let dest_path = Path::new(&out_dir).join("lookup.rs");
  120. fs::write(&dest_path, output).unwrap();
  121. }