Merge branch 'vertex-loader'
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
mod lumps;
|
mod lumps;
|
||||||
|
mod types;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod wad;
|
mod wad;
|
||||||
|
|
||||||
|
|||||||
13
src/lumps/lump.rs
Normal file
13
src/lumps/lump.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Lump {
|
||||||
|
pub name: String,
|
||||||
|
pub lump_type: LumpType,
|
||||||
|
pub offset: u32,
|
||||||
|
pub size: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum LumpType {
|
||||||
|
Unknown,
|
||||||
|
Vertex,
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
mod lump;
|
||||||
|
mod vertex;
|
||||||
|
|
||||||
|
pub use lump::Lump;
|
||||||
|
pub use lump::LumpType;
|
||||||
|
pub use vertex::VertexLump;
|
||||||
|
|||||||
19
src/lumps/vertex.rs
Normal file
19
src/lumps/vertex.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use crate::types::Vertex;
|
||||||
|
|
||||||
|
pub struct VertexLump {
|
||||||
|
pub vertexes: Vec<Vertex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VertexLump {
|
||||||
|
pub fn num_vertexes(&self) -> usize {
|
||||||
|
self.vertexes.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all_vertexes(&self) -> Vec<Vertex> {
|
||||||
|
self.vertexes.to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_vertex(&self, pos: usize) -> Vertex {
|
||||||
|
self.vertexes[pos].to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +1,76 @@
|
|||||||
use crate::WADFile;
|
use crate::WADFile;
|
||||||
|
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
static WAD_INSTANCE: OnceLock<WADFile> = OnceLock::new();
|
||||||
|
|
||||||
|
/// Helper function to access the WAD file once
|
||||||
|
fn get_wad() -> &'static WADFile {
|
||||||
|
WAD_INSTANCE.get_or_init(|| WADFile::new(String::from("WADs/doom1.wad")))
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn successful_wad_id() {
|
pub fn successful_wad_id() {
|
||||||
let wad_file = WADFile::new(String::from("WADs/doom1.wad"));
|
let wad_file = get_wad();
|
||||||
|
|
||||||
assert_eq!(wad_file.wad_id, "IWAD");
|
assert_eq!(wad_file.wad_id, "IWAD");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn correct_lumps() {
|
pub fn correct_lumps() {
|
||||||
let wad_file = WADFile::new(String::from("WADs/doom1.wad"));
|
let wad_file = get_wad();
|
||||||
|
|
||||||
assert_eq!(wad_file.num_lumps, 1264);
|
assert_eq!(wad_file.num_lumps, 1264);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn correct_dir_size() {
|
pub fn correct_dir_size() {
|
||||||
let wad_file = WADFile::new(String::from("WADs/doom1.wad"));
|
let wad_file = get_wad();
|
||||||
|
|
||||||
assert_eq!(wad_file.directory.len(), 1264);
|
assert_eq!(wad_file.directory.len(), 1264);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn correct_lump_name() {
|
pub fn correct_lump_name() {
|
||||||
let wad_file = WADFile::new(String::from("WADs/doom1.wad"));
|
let wad_file = get_wad();
|
||||||
|
|
||||||
assert_eq!(wad_file.directory[0].name, "PLAYPAL");
|
assert_eq!(wad_file.directory[0].name, "PLAYPAL");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn read_level_lump() {
|
pub fn read_level_lump() {
|
||||||
let wad_file = WADFile::new(String::from("WADs/doom1.wad"));
|
let wad_file = get_wad();
|
||||||
|
|
||||||
assert_eq!(wad_file.directory[6].name, "E1M1");
|
assert_eq!(wad_file.directory[6].name, "E1M1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn read_vertex_lump() {
|
||||||
|
let wad_file = get_wad();
|
||||||
|
|
||||||
|
let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned());
|
||||||
|
|
||||||
|
assert_ne!(vertex_lump.vertexes.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn read_num_vertexes() {
|
||||||
|
let wad_file = get_wad();
|
||||||
|
|
||||||
|
let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned());
|
||||||
|
|
||||||
|
assert_eq!(vertex_lump.vertexes.len(), 1868 / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn read_first_vertex() {
|
||||||
|
use crate::types::Vertex;
|
||||||
|
|
||||||
|
let wad_file = get_wad();
|
||||||
|
|
||||||
|
let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned());
|
||||||
|
|
||||||
|
let correct_vertex = Vertex { x: 1088, y: -3680 };
|
||||||
|
|
||||||
|
assert_eq!(vertex_lump.get_vertex(0), correct_vertex);
|
||||||
|
}
|
||||||
|
|||||||
3
src/types/mod.rs
Normal file
3
src/types/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod vertex;
|
||||||
|
|
||||||
|
pub use vertex::Vertex;
|
||||||
5
src/types/vertex.rs
Normal file
5
src/types/vertex.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Vertex {
|
||||||
|
pub x: i16,
|
||||||
|
pub y: i16,
|
||||||
|
}
|
||||||
@@ -41,3 +41,11 @@ pub fn read_u32_le(bytes: &[u8]) -> u32 {
|
|||||||
u32::from_le_bytes(bytes[..4].try_into().unwrap())
|
u32::from_le_bytes(bytes[..4].try_into().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_i16_le(bytes: &[u8]) -> i16 {
|
||||||
|
if bytes.len() < 2 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
i16::from_le_bytes(bytes[..2].try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ mod error;
|
|||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
pub use helpers::read_ascii;
|
pub use helpers::read_ascii;
|
||||||
|
pub use helpers::read_i16_le;
|
||||||
pub use helpers::read_u32_le;
|
pub use helpers::read_u32_le;
|
||||||
pub use helpers::validate_wad;
|
pub use helpers::validate_wad;
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
pub struct Directory {
|
|
||||||
pub filepos: u32,
|
|
||||||
pub size: u32,
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ use crate::utils::{read_ascii, read_u32_le};
|
|||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
pub fn read_data(data: &[u8]) -> Self {
|
pub fn read_data(data: &[u8]) -> Self {
|
||||||
let id = read_ascii(&data[..4]);
|
let id = read_ascii(&data[..4]).to_string();
|
||||||
let lumps = read_u32_le(&data[4..8]);
|
let lumps = read_u32_le(&data[4..8]);
|
||||||
let offset = read_u32_le(&data[8..12]);
|
let offset = read_u32_le(&data[8..12]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
mod directory;
|
|
||||||
mod header;
|
mod header;
|
||||||
mod wadfile;
|
mod wadfile;
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
use std::{fs::File, io::Read, path::Path};
|
use std::{fs::File, io::Read, path::Path};
|
||||||
|
|
||||||
use super::{directory::Directory, header::Header};
|
use super::header::Header;
|
||||||
use crate::utils::{read_ascii, read_u32_le, validate_wad};
|
use crate::lumps::{Lump, LumpType, VertexLump};
|
||||||
|
use crate::types::Vertex;
|
||||||
|
use crate::utils::{read_ascii, read_i16_le, read_u32_le, validate_wad};
|
||||||
|
|
||||||
pub struct WADFile {
|
pub struct WADFile {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub wad_id: String,
|
pub wad_id: String,
|
||||||
pub num_lumps: u32,
|
pub num_lumps: u32,
|
||||||
pub dir_offset: u32,
|
pub dir_offset: u32,
|
||||||
pub directory: Vec<Directory>,
|
pub directory: Vec<Lump>,
|
||||||
pub wad_data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WADFile {
|
impl WADFile {
|
||||||
@@ -27,17 +29,19 @@ impl WADFile {
|
|||||||
|
|
||||||
let wad_header = Header::read_data(&file_buffer[0..12]);
|
let wad_header = Header::read_data(&file_buffer[0..12]);
|
||||||
|
|
||||||
let mut wad_dir: Vec<Directory> = Vec::with_capacity(wad_header.num_lumps as usize);
|
let mut lump_dir: Vec<Lump> = Vec::with_capacity(wad_header.num_lumps as usize);
|
||||||
let offset = wad_header.dir_offset;
|
let offset = wad_header.dir_offset;
|
||||||
|
|
||||||
for entry in 0..wad_header.num_lumps {
|
for entry in 0..wad_header.num_lumps {
|
||||||
let startpos = (offset + 16 * entry) as usize;
|
let startpos = (offset + 16 * entry) as usize;
|
||||||
let filepos = read_u32_le(&file_buffer[startpos..startpos + 4]);
|
let lump_offset = read_u32_le(&file_buffer[startpos..startpos + 4]);
|
||||||
let size = read_u32_le(&file_buffer[startpos + 4..startpos + 8]);
|
let size = read_u32_le(&file_buffer[startpos + 4..startpos + 8]);
|
||||||
let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]);
|
let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]);
|
||||||
wad_dir.push(Directory {
|
let lump_type = LumpType::Unknown;
|
||||||
filepos,
|
lump_dir.push(Lump {
|
||||||
name,
|
name,
|
||||||
|
offset: lump_offset,
|
||||||
|
lump_type,
|
||||||
size,
|
size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -47,8 +51,29 @@ impl WADFile {
|
|||||||
wad_id: wad_header.wad_id,
|
wad_id: wad_header.wad_id,
|
||||||
num_lumps: wad_header.num_lumps,
|
num_lumps: wad_header.num_lumps,
|
||||||
dir_offset: wad_header.dir_offset,
|
dir_offset: wad_header.dir_offset,
|
||||||
directory: wad_dir,
|
directory: lump_dir,
|
||||||
wad_data: file_buffer,
|
data: file_buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_vertex_lump(&self, lump: Lump) -> VertexLump {
|
||||||
|
let lump_offset = lump.offset as usize;
|
||||||
|
let lump_size = lump.size as usize;
|
||||||
|
let lump_data = &self.data[lump_offset..lump_offset + lump_size];
|
||||||
|
let lump_entries: usize = lump_size / 4;
|
||||||
|
let mut vertexes: Vec<Vertex> = Vec::with_capacity(lump_size / 4);
|
||||||
|
|
||||||
|
for entry in 0..lump_entries {
|
||||||
|
let startpos = entry * 4;
|
||||||
|
let vertex_x = read_i16_le(&lump_data[startpos..startpos + 2]);
|
||||||
|
let vertex_y = read_i16_le(&lump_data[startpos + 2..startpos + 4]);
|
||||||
|
|
||||||
|
vertexes.push(Vertex {
|
||||||
|
x: vertex_x,
|
||||||
|
y: vertex_y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexLump { vertexes }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user