lumps.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. use std::marker;
  2. use ratatui::symbols::Marker;
  3. use wad::Wad;
  4. #[derive(PartialEq, Clone)]
  5. pub enum MarkerType {
  6. Flat,
  7. Sprite,
  8. Texture,
  9. Sound,
  10. Map,
  11. Unknown,
  12. }
  13. #[derive(PartialEq)]
  14. pub enum FileType {
  15. Map,
  16. Things,
  17. Linedefs,
  18. Sidedefs,
  19. Vertexes,
  20. Segs,
  21. Ssectors,
  22. Nodes,
  23. Sectors,
  24. Reject,
  25. Blockmap,
  26. Behavior,
  27. //
  28. Flat,
  29. Sprite,
  30. Texture,
  31. Sfx,
  32. }
  33. #[derive(PartialEq)]
  34. pub enum MarkerBoundary {
  35. Single,
  36. Begin,
  37. End,
  38. Unknown,
  39. }
  40. pub enum LumpType {
  41. Marker(MarkerType, MarkerBoundary),
  42. File(FileType),
  43. }
  44. pub struct LumpInfo {
  45. pub name: String,
  46. pub size: usize,
  47. pub lump_type: Option<LumpType>,
  48. }
  49. fn determine_lump_type(
  50. current_group: &Option<MarkerType>,
  51. name: &str,
  52. size: usize,
  53. ) -> Option<LumpType> {
  54. // TODO Make sure that the map lumps are following a map?
  55. if size == 0 {
  56. match name {
  57. "F_START" => return Some(LumpType::Marker(MarkerType::Flat, MarkerBoundary::Begin)),
  58. "F_END" => return Some(LumpType::Marker(MarkerType::Flat, MarkerBoundary::End)),
  59. "S_START" => return Some(LumpType::Marker(MarkerType::Sprite, MarkerBoundary::Begin)),
  60. "S_END" => return Some(LumpType::Marker(MarkerType::Sprite, MarkerBoundary::End)),
  61. "TX_START" => return Some(LumpType::Marker(MarkerType::Texture, MarkerBoundary::Begin)),
  62. "TX_END" => return Some(LumpType::Marker(MarkerType::Texture, MarkerBoundary::End)),
  63. _ => {}
  64. }
  65. }
  66. match name {
  67. "THINGS" => return Some(LumpType::File(FileType::Things)),
  68. "LINEDEFS" => return Some(LumpType::File(FileType::Linedefs)),
  69. "SIDEDEFS" => return Some(LumpType::File(FileType::Sidedefs)),
  70. "VERTEXES" => return Some(LumpType::File(FileType::Vertexes)),
  71. "SEGS" => return Some(LumpType::File(FileType::Segs)),
  72. "SSECTORS" => return Some(LumpType::File(FileType::Ssectors)),
  73. "NODES" => return Some(LumpType::File(FileType::Nodes)),
  74. "SECTORS" => return Some(LumpType::File(FileType::Sectors)),
  75. "REJECT" => return Some(LumpType::File(FileType::Reject)),
  76. "BLOCKMAP" => return Some(LumpType::File(FileType::Blockmap)),
  77. "BEHAVIOR" => return Some(LumpType::File(FileType::Behavior)),
  78. _ => {}
  79. };
  80. if let Some(marker_type) = &current_group {
  81. match marker_type {
  82. MarkerType::Flat => return Some(LumpType::File(FileType::Flat)),
  83. MarkerType::Sprite => return Some(LumpType::File(FileType::Sprite)),
  84. MarkerType::Texture => return Some(LumpType::File(FileType::Texture)),
  85. _ => {},
  86. }
  87. }
  88. if name.starts_with("MAP") && name.len() == 5 {
  89. return Some(LumpType::File(FileType::Map));
  90. }
  91. None
  92. }
  93. pub fn get_lumps(wad: &Wad) -> Vec<LumpInfo> {
  94. let mut current_marker_group: Option<MarkerType> = None;
  95. wad.as_slice()
  96. .entry_iter()
  97. .map(|entry| {
  98. let lump_type = determine_lump_type(&current_marker_group, entry.display_name(), entry.lump.len());
  99. // Update the iterator state by checking the current lump's type if it's a marker.
  100. // Open/close marker groups depending on its type.
  101. match &lump_type {
  102. Some(LumpType::Marker(marker_type, boundary)) => {
  103. if *boundary == MarkerBoundary::End {
  104. current_marker_group = None;
  105. } else {
  106. match marker_type {
  107. MarkerType::Flat | MarkerType::Sprite | MarkerType::Texture => current_marker_group = Some(marker_type.clone()),
  108. _ => todo!(),
  109. }
  110. }
  111. },
  112. Some(LumpType::File(FileType::Map)) => current_marker_group = Some(MarkerType::Map),
  113. _ => {}
  114. };
  115. LumpInfo {
  116. name: entry.display_name().to_string(),
  117. size: entry.lump.len(),
  118. lump_type: lump_type,
  119. }
  120. })
  121. .collect()
  122. }