lib.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. use shared::consts;
  2. use shared::fp::{ ToFixedPoint };
  3. use shared::radian;
  4. use proc_macro2::TokenStream;
  5. use quote::quote;
  6. const TILE_SIZE: f64 = consts::TILE_SIZE as f64;
  7. fn clamp(x: i32, min: i32, max: i32) -> i32 {
  8. if x < min {
  9. min
  10. } else if x > max {
  11. max
  12. } else {
  13. x
  14. }
  15. }
  16. fn declare_trig_tables() -> TokenStream {
  17. const SIZE: usize = (consts::ANGLE_360 + 1) as usize;
  18. let mut sin: [i32; SIZE] = [0; SIZE];
  19. let mut cos: [i32; SIZE] = [0; SIZE];
  20. let mut tan: [i32; SIZE] = [0; SIZE];
  21. let mut isin: [i32; SIZE] = [0; SIZE];
  22. let mut icos: [i32; SIZE] = [0; SIZE];
  23. let mut itan: [i32; SIZE] = [0; SIZE];
  24. for i in 0..SIZE {
  25. sin[i] = (radian!(i).sin()).to_fp();
  26. cos[i] = (radian!(i).cos()).to_fp();
  27. tan[i] = (radian!(i).tan()).to_fp();
  28. isin[i] = (1.0 / radian!(i).sin()).to_fp();
  29. icos[i] = (1.0 / radian!(i).cos()).to_fp();
  30. itan[i] = (1.0 / radian!(i).tan()).to_fp() ;
  31. }
  32. quote! {
  33. static SIN: [i32; #SIZE] = [ #(#sin),* ];
  34. static COS: [i32; #SIZE] = [ #(#cos),* ];
  35. static TAN: [i32; #SIZE] = [ #(#tan),* ];
  36. static ISIN: [i32; #SIZE] = [ #(#isin),* ];
  37. static ICOS: [i32; #SIZE] = [ #(#icos),* ];
  38. static ITAN: [i32; #SIZE] = [ #(#itan),* ];
  39. }
  40. }
  41. fn declare_step_tables() -> TokenStream {
  42. const SIZE: usize = (consts::ANGLE_360 + 1) as usize;
  43. let mut x_step: [i32; SIZE] = [0; SIZE];
  44. let mut y_step: [i32; SIZE] = [0; SIZE];
  45. for i in 0..SIZE {
  46. let mut step: f64;
  47. if radian!(i).tan() == 0.0 {
  48. step = f64::MAX
  49. } else {
  50. step = TILE_SIZE / radian!(i).tan();
  51. if i >= consts::ANGLE_90.try_into().unwrap() && i < consts::ANGLE_270.try_into().unwrap() {
  52. if step > 0.0 {
  53. step = -step;
  54. }
  55. } else {
  56. if step < 0.0 {
  57. step = -step;
  58. }
  59. }
  60. }
  61. x_step[i] = step.to_fp();
  62. }
  63. for i in 0..SIZE {
  64. let mut step = TILE_SIZE * radian!(i).tan();
  65. if i >= consts::ANGLE_0.try_into().unwrap() && i < consts::ANGLE_180.try_into().unwrap() {
  66. if step < 0.0 {
  67. step = -step;
  68. }
  69. } else {
  70. if step > 0.0 {
  71. step = -step;
  72. }
  73. }
  74. y_step[i] = step.to_fp();
  75. }
  76. quote! {
  77. static X_STEP: [i32; #SIZE] = [ #(#x_step),* ];
  78. static Y_STEP: [i32; #SIZE] = [ #(#y_step),* ];
  79. }
  80. }
  81. fn declare_fisheye_table() -> TokenStream {
  82. const SIZE: usize = consts::PROJECTION_PLANE_WIDTH as usize;
  83. let mut fisheye: [i32; SIZE] = [0; SIZE];
  84. for i in 0..SIZE {
  85. fisheye[i] = (1.0 / radian!(i as i32 - consts::ANGLE_30 as i32).cos()).to_fp();
  86. }
  87. quote! {
  88. static FISHEYE: [i32; #SIZE] = [ #(#fisheye),* ];
  89. }
  90. }
  91. fn declare_wall_height_table() -> TokenStream {
  92. const SIZE: usize = (consts::MAX_RAY_LENGTH + 1) as usize;
  93. let mut wall_height: [i32; SIZE] = [0; SIZE];
  94. for i in 0..=consts::MAX_RAY_LENGTH {
  95. wall_height[i as usize] = clamp(consts::WALL_HEIGHT_SCALE_FACTOR / i.max(1), consts::WALL_HEIGHT_MIN, consts::WALL_HEIGHT_MAX);
  96. }
  97. quote! {
  98. static WALL_HEIGHT: [i32; #SIZE] = [ #(#wall_height),* ];
  99. }
  100. }
  101. fn declare_floor_ceiling_tables() -> TokenStream {
  102. // let mut FLOOR_TEXTURE_Y_RAYS: [i32; PROJECTION_PLANE_WIDTH * PROJECTION_PLANE_CENTRE_Y] = [0; PROJECTION_PLANE_WIDTH * PROJECTION_PLANE_CENTRE_Y];
  103. // let mut FLOOR_TEXTURE_X_RAYS: [i32; PROJECTION_PLANE_WIDTH * PROJECTION_PLANE_CENTRE_Y] = [0; PROJECTION_PLANE_WIDTH * PROJECTION_PLANE_CENTRE_Y];
  104. // for y in (PROJECTION_PLANE_CENTRE_Y + 1)..PROJECTION_PLANE_HEIGHT {
  105. // let ratio: f64 = PLAYER_HEIGHT as f64 / (y - PROJECTION_PLANE_CENTRE_Y) as f64;
  106. // for sweep in 0..PROJECTION_PLANE_WIDTH {
  107. // let distance = DISTANCE_TO_PROJECTION_PLANE as f64 * ratio * fisheye[sweep];
  108. // }
  109. // }
  110. // var diagonalDistance=Math.floor((this.fPlayerDistanceToTheProjectionPlane * ratio) * (this.fFishTable[castColumn]));
  111. // var yEnd = Math.floor(diagonalDistance * this.fSinTable[castArc]);
  112. // var xEnd = Math.floor(diagonalDistance * this.fCosTable[castArc]);
  113. quote! {
  114. }
  115. }
  116. #[proc_macro]
  117. pub fn insert_lookup_tables(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
  118. let trig_tables = declare_trig_tables();
  119. let step_tables = declare_step_tables();
  120. let fisheye_table = declare_fisheye_table();
  121. let wall_height_table = declare_wall_height_table();
  122. let floor_ceiling_tables = declare_floor_ceiling_tables();
  123. proc_macro::TokenStream::from(quote! {
  124. #trig_tables
  125. #step_tables
  126. #fisheye_table
  127. #wall_height_table
  128. #floor_ceiling_tables
  129. })
  130. }