Compare commits

...

10 Commits

Author SHA1 Message Date
Wesley Irvin
14fd8919b0 Merge pull request 'First Window' (#18) from 2d-window into master
Reviewed-on: https://git.batesirvintech.net/wesley/doom-oxidized/pulls/18
2023-05-01 19:52:00 -04:00
Wesley Irvin
4440e56f85 First Window
Was able to render a window using sdl2. Needs to be broken out
into it's own separate components and abstracted away. This should
take care of the requirements for issue #12.
2023-05-01 19:48:39 -04:00
Wesley Irvin
ac3bdaca33 Merge pull request 'Error Rework / Code Refactor' (#17) from error-refactor into master
Reviewed-on: https://git.batesirvintech.net/wesley/doom-oxidized/pulls/17
2023-04-30 19:43:45 -04:00
Wesley Irvin
12c6d7122c Error Rework / Code Refactor
Added in being able to return an error when the path to a WAD is
not a valid path. This patch is to address issue #6.
2023-04-30 19:37:31 -04:00
Wesley Irvin
6939ac9c8d Merge pull request 'Linedef Loading' (#15) from linedef-loader into master
Reviewed-on: https://git.batesirvintech.net/wesley/doom-oxidized/pulls/15
2023-04-29 09:45:58 -04:00
Wesley Irvin
166b047a70 Linedef Loading
Added the ability to load linedefs from a wad file. Also added
functions to the linedef type to allow you to check the status of
each bit of the flags value making it very easy to check linedef
properties.
2023-04-29 09:39:26 -04:00
Wesley Irvin
510409c730 Merge pull request 'Vertex Loading' (#10) from vertex-loader into master
Reviewed-on: https://git.batesirvintech.net/wesley/doom-oxidized/pulls/10
2023-04-28 18:29:13 -04:00
Wesley Irvin
cd5f05daf5 Vertex Loading
Added the ability to load vertex data from the vertexes lump for
a given level. This is to close issue #5 to get vertex data
loading working.
2023-04-28 18:26:14 -04:00
Wesley Irvin
4a7a5c0f93 Merge pull request 'Permissions Fix' (#9) from permissions into master
Reviewed-on: https://git.batesirvintech.net/wesley/doom-oxidized/pulls/9
2023-04-27 18:00:45 -04:00
Wesley Irvin
430889ff09 Permissions Fix
Fixed up the public permissions for WADFile struct. It no longer
needs to restrict to the super module anymore as the architecture
has changed to be more accomodating. Also removed pub access from
the lump_directory as this will be accessed through the
implementation functions.
2023-04-27 17:58:23 -04:00
6 changed files with 306 additions and 35 deletions

View File

@@ -3,6 +3,5 @@ name = "doom-oxidized"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
sdl2 = "0.35.2"

112
src/doomlevel.rs Normal file
View File

@@ -0,0 +1,112 @@
mod linedef;
mod vertex;
use std::{
fs::File,
io::{Read, Seek, SeekFrom},
};
use self::linedef::Linedef;
use super::wadfile::WADFile;
use vertex::Vertex;
enum Lumps {
THINGS = 1,
LINEDEFS,
SIDEDEFS,
VERTEXES,
SEGS,
SSECTORS,
NODES,
SECTORS,
REJECT,
BLOCKMAP,
}
pub struct DoomLevel {
pub name: String,
pub vertexes: Vec<Vertex>,
pub linedefs: Vec<Linedef>,
}
impl DoomLevel {
pub fn load_level(wad_file: &WADFile, lvl_index: u32) -> Self {
Self {
name: wad_file.get_lump_name(lvl_index),
vertexes: load_vertexes(
wad_file,
wad_file.get_lump_offset(lvl_index + Lumps::VERTEXES as u32),
wad_file.get_lump_size(lvl_index + Lumps::VERTEXES as u32),
),
linedefs: load_linedefs(
wad_file,
wad_file.get_lump_offset(lvl_index + Lumps::LINEDEFS as u32),
wad_file.get_lump_size(lvl_index + Lumps::LINEDEFS as u32),
),
}
}
}
fn load_vertexes(wad_file: &WADFile, offset: u32, size: u32) -> Vec<Vertex> {
let num_vertex: u32 = size / 4u32;
let mut vertex_list: Vec<Vertex> = Vec::with_capacity(num_vertex as usize);
let mut vertex_data = File::open(&wad_file.wad_path).unwrap();
vertex_data.seek(SeekFrom::Start(offset as u64)).unwrap();
for _ in 0..num_vertex {
let mut x = [0; 2];
let mut y = [0; 2];
vertex_data.read(&mut x).unwrap();
vertex_data.read(&mut y).unwrap();
vertex_list.push(Vertex {
x: i16::from_le_bytes(x),
y: i16::from_le_bytes(y),
});
}
vertex_list
}
fn load_linedefs(wad_file: &WADFile, offset: u32, size: u32) -> Vec<Linedef> {
let num_linedef: u32 = size / 14u32;
let mut linedef_list: Vec<Linedef> = Vec::with_capacity(num_linedef as usize);
let mut linedef_data = File::open(&wad_file.wad_path).unwrap();
linedef_data.seek(SeekFrom::Start(offset as u64)).unwrap();
for _ in 0..num_linedef {
let mut start_vertex = [0; 2];
let mut end_vertex = [0; 2];
let mut flags = [0; 2];
let mut special_type = [0; 2];
let mut sector_tag = [0; 2];
let mut front_sidedef = [0; 2];
let mut back_sidedef = [0; 2];
linedef_data.read(&mut start_vertex).unwrap();
linedef_data.read(&mut end_vertex).unwrap();
linedef_data.read(&mut flags).unwrap();
linedef_data.read(&mut special_type).unwrap();
linedef_data.read(&mut sector_tag).unwrap();
linedef_data.read(&mut front_sidedef).unwrap();
linedef_data.read(&mut back_sidedef).unwrap();
linedef_list.push(Linedef {
start_vertex: i16::from_le_bytes(start_vertex),
end_vertex: i16::from_le_bytes(end_vertex),
flags: i16::from_le_bytes(flags),
special_type: i16::from_le_bytes(special_type),
sector_tag: i16::from_le_bytes(sector_tag),
front_sidedef: i16::from_le_bytes(front_sidedef),
back_sidedef: i16::from_le_bytes(back_sidedef),
});
}
linedef_list
}

47
src/doomlevel/linedef.rs Normal file
View File

@@ -0,0 +1,47 @@
pub struct Linedef {
pub start_vertex: i16,
pub end_vertex: i16,
pub flags: i16,
pub special_type: i16,
pub sector_tag: i16,
pub front_sidedef: i16,
pub back_sidedef: i16,
}
impl Linedef {
pub fn blocks_players(&self) -> bool {
self.flags & (1 << 0) != 0
}
pub fn blocks_monsters(&self) -> bool {
self.flags & (1 << 1) != 0
}
pub fn is_two_sided(&self) -> bool {
self.flags & (1 << 2) != 0
}
pub fn is_upper_unpegged(&self) -> bool {
self.flags & (1 << 3) != 0
}
pub fn is_lower_unpegged(&self) -> bool {
self.flags & (1 << 4) != 0
}
pub fn is_secret(&self) -> bool {
self.flags & (1 << 5) != 0
}
pub fn blocks_sound(&self) -> bool {
self.flags & (1 << 6) != 0
}
pub fn never_automap(&self) -> bool {
self.flags & (1 << 7) != 0
}
pub fn always_automap(&self) -> bool {
self.flags & (1 << 8) != 0
}
}

4
src/doomlevel/vertex.rs Normal file
View File

@@ -0,0 +1,4 @@
pub struct Vertex {
pub x: i16,
pub y: i16,
}

View File

@@ -1,9 +1,32 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
mod doomlevel;
mod wadfile; mod wadfile;
use doomlevel::DoomLevel;
use wadfile::WADFile; use wadfile::WADFile;
fn main() { static WIDTH: u32 = 320;
let wad_file = WADFile::from_path("WADs/doom1.wad"); static HEIGHT: u32 = 200;
static SCALING: u32 = 4;
fn find_sdl_gl_driver() -> Option<u32> {
for (index, item) in sdl2::render::drivers().enumerate() {
if item.name == "opengl" {
return Some(index as u32);
}
}
None
}
fn main() -> Result<(), &'static str> {
let wad_file = WADFile::from_path("WADs/doom1.wad")?;
let level = DoomLevel::load_level(&wad_file, wad_file.get_index_from_name("e1m1").unwrap());
println!( println!(
"WAD Path: {} "WAD Path: {}
@@ -32,8 +55,98 @@ Header:
); );
} }
println!("\nFirst 15 Vertex Entries for {}:", level.name);
for i in 0..15 {
println!(
"\t{} - ({}, {})",
i, level.vertexes[i].x, level.vertexes[i].y
);
}
let test_linedef = 247;
println!("\nLinedef Entry {} for {}:", test_linedef, level.name);
println!( println!(
"Index of e1m1 is: {}", "Start Vertex: {}
wad_file.get_index_from_name("e1m1").unwrap() End Vertex: {}
Flags: {}
Special Type: {}
Sector Tag: {}
Front Sidedef: {}
Back Sidedef: {}
Flags:
\tBlocks Players: {}
\tBlocks Monsters: {}
\tTwo Sided: {}
\tUpper Texture Unpegged: {}
\tLower Texture Unpegged: {}
\tSecret: {}
\tBlocks Sound: {}
\tNever Shows on Automap: {}
\tAlways Shows on Automap: {}",
level.linedefs[test_linedef].start_vertex,
level.linedefs[test_linedef].end_vertex,
level.linedefs[test_linedef].flags,
level.linedefs[test_linedef].special_type,
level.linedefs[test_linedef].sector_tag,
level.linedefs[test_linedef].front_sidedef,
level.linedefs[test_linedef].back_sidedef,
level.linedefs[test_linedef].blocks_players(),
level.linedefs[test_linedef].blocks_monsters(),
level.linedefs[test_linedef].is_two_sided(),
level.linedefs[test_linedef].is_upper_unpegged(),
level.linedefs[test_linedef].is_lower_unpegged(),
level.linedefs[test_linedef].is_secret(),
level.linedefs[test_linedef].blocks_sound(),
level.linedefs[test_linedef].never_automap(),
level.linedefs[test_linedef].always_automap()
); );
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem
.window("Doom - Oxidized", WIDTH * SCALING, HEIGHT * SCALING)
.position_centered()
.opengl()
.build()
.unwrap();
let mut canvas = window
.into_canvas()
.index(find_sdl_gl_driver().unwrap())
.build()
.unwrap();
canvas.set_draw_color(Color::RGB(0, 255, 255));
canvas.clear();
canvas.present();
let mut event_pump = sdl_context.event_pump().unwrap();
let mut i = 0;
'running: loop {
i = (i + 1) % 255;
canvas.set_draw_color(Color::RGB(i, 64, 255 - i));
canvas.clear();
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}
canvas.present();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 30));
}
Ok(())
} }

View File

@@ -4,31 +4,38 @@ use directory::Directory;
use std::{ use std::{
fs::File, fs::File,
io::{Read, Seek, SeekFrom}, io::{Read, Seek, SeekFrom},
path::Path,
}; };
pub struct WADFile { pub struct WADFile {
pub(super) wad_path: String, pub wad_path: String,
pub(super) identifier: String, pub identifier: String,
pub(super) num_lumps: u32, pub num_lumps: u32,
pub(super) init_offset: u32, pub init_offset: u32,
pub(super) lump_directory: Vec<Directory>, lump_directory: Vec<Directory>,
} }
impl WADFile { impl WADFile {
pub fn from_path(path: &str) -> Self { pub fn from_path(path: &str) -> Result<Self, &str> {
let wad_file = Path::new(path);
if !(wad_file.exists()) {
return Err("Could not open file!");
}
let header_data = get_header_data(path); let header_data = get_header_data(path);
let mut lump_dir: Vec<Directory> = Vec::with_capacity(header_data.1 as usize); let mut lump_dir: Vec<Directory> = Vec::with_capacity(header_data.1 as usize);
get_lump_dir(path, &header_data.2, &header_data.1, &mut lump_dir); get_lump_dir(path, &header_data.2, &header_data.1, &mut lump_dir);
Self { Ok(Self {
wad_path: path.to_string(), wad_path: path.to_string(),
identifier: header_data.0, identifier: header_data.0,
num_lumps: header_data.1, num_lumps: header_data.1,
init_offset: header_data.2, init_offset: header_data.2,
lump_directory: lump_dir, lump_directory: lump_dir,
} })
} }
pub fn get_lump_name(&self, index: u32) -> String { pub fn get_lump_name(&self, index: u32) -> String {
@@ -74,20 +81,15 @@ fn get_lump_dir(path: &str, dir_offset: &u32, num_lumps: &u32, lump_buffer: &mut
let mut lump_pos = [0; 4]; let mut lump_pos = [0; 4];
let mut lump_size = [0; 4]; let mut lump_size = [0; 4];
let mut lump_name = [0; 8]; let mut lump_name = [0; 8];
let mut name = String::with_capacity(8);
wad_data.read(&mut lump_pos).unwrap(); wad_data.read(&mut lump_pos).unwrap();
wad_data.read(&mut lump_size).unwrap(); wad_data.read(&mut lump_size).unwrap();
wad_data.read(&mut lump_name).unwrap(); wad_data.read(&mut lump_name).unwrap();
for letter in 0..lump_name.len() {
name.push(lump_name[letter] as char);
}
lump_buffer.push(Directory { lump_buffer.push(Directory {
lump_pos: u32::from_le_bytes(lump_pos), lump_pos: u32::from_le_bytes(lump_pos),
lump_size: u32::from_le_bytes(lump_size), lump_size: u32::from_le_bytes(lump_size),
lump_name: name, lump_name: String::from_utf8(lump_name.to_vec()).unwrap(),
}) })
} }
} }
@@ -95,23 +97,17 @@ fn get_lump_dir(path: &str, dir_offset: &u32, num_lumps: &u32, lump_buffer: &mut
fn get_header_data(path: &str) -> (String, u32, u32) { fn get_header_data(path: &str) -> (String, u32, u32) {
let mut wad_data = File::open(&path).unwrap(); let mut wad_data = File::open(&path).unwrap();
let mut header = [0; 12]; let mut wad_id = [0; 4];
let mut dir_size = [0; 4];
let mut dir_offset = [0; 4];
wad_data.read(&mut header).unwrap(); wad_data.read(&mut wad_id).unwrap();
wad_data.read(&mut dir_size).unwrap();
let mut wad_type = String::with_capacity(4); wad_data.read(&mut dir_offset).unwrap();
wad_type.push(header[0] as char);
wad_type.push(header[1] as char);
wad_type.push(header[2] as char);
wad_type.push(header[3] as char);
let lump_bytes: [u8; 4] = [header[4], header[5], header[6], header[7]];
let offset_bytes: [u8; 4] = [header[8], header[9], header[10], header[11]];
( (
wad_type, String::from_utf8(wad_id.to_vec()).unwrap(),
u32::from_le_bytes(lump_bytes), u32::from_le_bytes(dir_size),
u32::from_le_bytes(offset_bytes), u32::from_le_bytes(dir_offset),
) )
} }