Vertex Loading
Added the ability to load vertex data from the WAD. Still needs some processing to make more robust, but for now is loading data.
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