RD-2: Implemented W_Init. This adds W_InitMultipleFiles and W_CheckNumForName
This commit was merged in pull request #2.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,3 +19,4 @@
|
|||||||
/target
|
/target
|
||||||
|
|
||||||
/WADS/*
|
/WADS/*
|
||||||
|
!/WADS/DOOM1.wad
|
||||||
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"./WADS/DOOM.WAD", "-dev", "@configs.txt", "-nomonsters", "-file", "test.WAD", "test2.WAD", "-skill", "3"
|
"./WADS/DOOM.WAD", "-dev", "-nomonsters", "-skill", "3"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
WADS/doom1.wad
Normal file
BIN
WADS/doom1.wad
Normal file
Binary file not shown.
@@ -9,6 +9,8 @@ use crate::m_argv::M_CheckParm;
|
|||||||
use crate::m_argv::M_GetOptionalArgumentValueByArgument;
|
use crate::m_argv::M_GetOptionalArgumentValueByArgument;
|
||||||
use crate::m_argv::PARM_NOT_FOUND;
|
use crate::m_argv::PARM_NOT_FOUND;
|
||||||
|
|
||||||
|
use crate::w_wad::{W_CheckNumForName, W_InitMultipleFiles};
|
||||||
|
|
||||||
use crate::doomdef::{
|
use crate::doomdef::{
|
||||||
VERSION,
|
VERSION,
|
||||||
// D_DEVSTR,
|
// D_DEVSTR,
|
||||||
@@ -407,10 +409,10 @@ pub fn D_DoomMain() {
|
|||||||
|
|
||||||
println!("Z_init: Init zone memory allocation daemon.");
|
println!("Z_init: Init zone memory allocation daemon.");
|
||||||
Z_Init();
|
Z_Init();
|
||||||
|
|
||||||
println!("W_Init: Init WADfiles");
|
|
||||||
W_InitMultipleFiles(wadfiles);
|
|
||||||
*/
|
*/
|
||||||
|
println!("W_Init: Init WADfiles");
|
||||||
|
W_InitMultipleFiles(DOOMGLOBALS::with_ref(|g| g.wadfiles.clone())); // we are loading so how cares about a borrow
|
||||||
|
|
||||||
let is_modified = DOOMGLOBALS::with_ref(|g| g.modifiedgame);
|
let is_modified = DOOMGLOBALS::with_ref(|g| g.modifiedgame);
|
||||||
|
|
||||||
@@ -426,12 +428,13 @@ pub fn D_DoomMain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if g_mode == GameMode::Registered {
|
if g_mode == GameMode::Registered {
|
||||||
for lump in iwads_lumps_to_check.iter().take(24) {
|
let missing_registered_lump = iwads_lumps_to_check
|
||||||
// TODO: Implement check
|
.iter()
|
||||||
// for (i = 0;i < 23; i++)
|
.any(|lump_name| W_CheckNumForName(lump_name) == -1);
|
||||||
// if (W_CheckNumForName(name[i])<0)
|
if missing_registered_lump {
|
||||||
// I_Error("\nThis is not the registered version.");
|
// TODO: Implement I_Error
|
||||||
}
|
// I_Error("\nThis is not the registered version.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +544,7 @@ pub fn D_DoomMain() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let g_action = DOOMGLOBALS::with_ref(|g| g.gameaction);
|
// let g_action = DOOMGLOBALS::with_ref(|g| g.gameaction);
|
||||||
|
|
||||||
// TODO: Impement Game actions
|
// TODO: Impement Game actions
|
||||||
// if g_action != ga_loadgame {
|
// if g_action != ga_loadgame {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::sync::{Mutex, MutexGuard, OnceLock};
|
|
||||||
|
|
||||||
|
|
||||||
pub const VERSION:i32 = 110;
|
pub const VERSION:i32 = 110;
|
||||||
pub const D_DEVSTR: &str = "Development mode ON.";
|
pub const D_DEVSTR: &str = "Development mode ON.";
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum GameMode {
|
pub enum GameMode {
|
||||||
Shareware,
|
Shareware,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
mod d_main;
|
mod d_main;
|
||||||
mod m_argv;
|
|
||||||
mod doomdef;
|
mod doomdef;
|
||||||
|
mod m_argv;
|
||||||
|
mod w_wad;
|
||||||
mod math;
|
mod math;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
235
src/w_wad/mod.rs
Normal file
235
src/w_wad/mod.rs
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
|
use std::mem::size_of;
|
||||||
|
use std::os::windows::io::AsRawHandle;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut numlumps: i32 = 0;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut lumpinfo: Vec<lumpinfo_t> = Vec::new();
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut reloadlump: i32 = 0;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
static mut reloadname: String = String::new();
|
||||||
|
|
||||||
|
/// Struct of the header of a WAD file
|
||||||
|
/// All integers are 4 bytes long in x86-style little-endian order. Their values can never exceed 231-1
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wadinfo_t {
|
||||||
|
/// ASCII identifer, either IWAD or PWAD
|
||||||
|
pub identification: [u8; 4],
|
||||||
|
|
||||||
|
/// The number of lumps in the WAD
|
||||||
|
pub numlumps: i32,
|
||||||
|
|
||||||
|
/// Pointer to the location of the directory
|
||||||
|
pub infotableofs: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct of fileumps of a WAD file
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct filelump_t {
|
||||||
|
|
||||||
|
/// Pointer to the start of the lumps data in the WAD file
|
||||||
|
pub filepos: i32,
|
||||||
|
|
||||||
|
/// The size of the lump in bytes
|
||||||
|
pub size: i32,
|
||||||
|
|
||||||
|
/// ASCII string identifying the lumps name
|
||||||
|
/// must be null terminated if less than 8 characters long
|
||||||
|
/// For safety, padd till end with null chars
|
||||||
|
pub name: [u8; 8],
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: RD-2: fill in if it is even needed for this port??
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct lumpinfo_t {
|
||||||
|
|
||||||
|
pub name: [u8; 8],
|
||||||
|
|
||||||
|
pub handle: isize,
|
||||||
|
|
||||||
|
pub position: i32,
|
||||||
|
|
||||||
|
pub size: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn W_AddFile(file: &str) {
|
||||||
|
// Get reference to static vvariables to be used locally
|
||||||
|
let (lumpinfo_ref, reloadname_ref) = unsafe {
|
||||||
|
(
|
||||||
|
&mut *std::ptr::addr_of_mut!(lumpinfo),
|
||||||
|
&mut *std::ptr::addr_of_mut!(reloadname)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if file.as_bytes()[0] == '~' as u8 {
|
||||||
|
unsafe {
|
||||||
|
reloadname = file.chars().skip(1).collect();
|
||||||
|
reloadlump = numlumps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fileinfo: Vec<filelump_t> = Vec::new();
|
||||||
|
|
||||||
|
let mut handle: File = match std::fs::File::open(&file) {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(_) => {
|
||||||
|
println!(" couldn't open {}", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("adding {}",file);
|
||||||
|
|
||||||
|
if !file.to_ascii_lowercase().ends_with(".wad") {
|
||||||
|
// process single lump
|
||||||
|
let file_meta = handle.metadata().unwrap();
|
||||||
|
// Single lump file
|
||||||
|
let mut singleinfo = filelump_t {
|
||||||
|
filepos: 0,
|
||||||
|
size: file_meta.len() as i32,
|
||||||
|
name: [0; 8]
|
||||||
|
};
|
||||||
|
let name = Path::new(file)
|
||||||
|
.file_name()
|
||||||
|
.and_then(|os_str| os_str.to_str()).unwrap();
|
||||||
|
for (i, byte) in name.as_bytes().iter().take(8).enumerate() {
|
||||||
|
singleinfo.name[i] = *byte;
|
||||||
|
}
|
||||||
|
fileinfo.push(singleinfo);
|
||||||
|
unsafe {numlumps += 1};
|
||||||
|
} else {
|
||||||
|
// WAD file
|
||||||
|
let mut header: wadinfo_t = wadinfo_t {
|
||||||
|
identification: [0; 4],
|
||||||
|
numlumps: 0,
|
||||||
|
infotableofs: 0
|
||||||
|
};
|
||||||
|
handle.read_exact(&mut header.identification).unwrap();
|
||||||
|
let mut int_buf:[u8; 4] = [0u8; 4];
|
||||||
|
handle.read_exact(&mut int_buf).unwrap();
|
||||||
|
header.numlumps = i32::from_le_bytes(int_buf);
|
||||||
|
handle.read_exact(&mut int_buf).unwrap();
|
||||||
|
header.infotableofs = i32::from_le_bytes(int_buf);
|
||||||
|
|
||||||
|
if !header.identification.eq_ignore_ascii_case(b"IWAD") {
|
||||||
|
if !header.identification.eq_ignore_ascii_case(b"PWAD") {
|
||||||
|
// TODO: Implement I_Error
|
||||||
|
// I_Error ("Wad file %s doesn't have IWAD or PWAD id\n", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = handle.seek(SeekFrom::Start(header.infotableofs as u64));
|
||||||
|
fileinfo.resize(header.numlumps as usize, filelump_t {
|
||||||
|
filepos: 0,
|
||||||
|
size: 0,
|
||||||
|
name: [0; 8],
|
||||||
|
});
|
||||||
|
let dirinfo_bytes = header.numlumps as usize * size_of::<filelump_t>();
|
||||||
|
unsafe {
|
||||||
|
let fileinfo_slice = std::slice::from_raw_parts_mut(
|
||||||
|
fileinfo.as_mut_ptr() as *mut u8,
|
||||||
|
dirinfo_bytes,
|
||||||
|
);
|
||||||
|
handle.read_exact(fileinfo_slice).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// enusre LE-ness of the ints
|
||||||
|
for fl in &mut fileinfo {
|
||||||
|
fl.filepos = i32::from_le(fl.filepos);
|
||||||
|
fl.size = i32::from_le(fl.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe{numlumps += header.numlumps}
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_reloaded = !reloadname_ref.is_empty();
|
||||||
|
let storehandle: isize = if is_reloaded {
|
||||||
|
-1 // Original C code closes the file immediately if it's a reloaded file
|
||||||
|
} else {
|
||||||
|
// get raw Windows HANDLE as an integer pointer
|
||||||
|
let raw_handle = handle.as_raw_handle() as isize;
|
||||||
|
// Tells rust to "trust us" and keeps the handle open after this function scope
|
||||||
|
std::mem::forget(handle);
|
||||||
|
raw_handle
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
lumpinfo_ref.reserve(fileinfo.len());
|
||||||
|
for info in fileinfo {
|
||||||
|
lumpinfo_ref.push( lumpinfo_t {
|
||||||
|
handle: storehandle,
|
||||||
|
position: info.filepos,
|
||||||
|
size: info.size,
|
||||||
|
name: info.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_InitMultipleFiles(filenames: Vec<String>) {
|
||||||
|
|
||||||
|
for file in filenames {
|
||||||
|
W_AddFile(&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsafe{numlumps == 0} {
|
||||||
|
// TODO: Implement I_Error
|
||||||
|
// I_Error("W_InitFiles: no files found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up lump cache
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_Reload() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_CheckNumForName(name: &str) -> i32 {
|
||||||
|
let lumpinfo_ref = unsafe { &*std::ptr::addr_of!(lumpinfo) };
|
||||||
|
|
||||||
|
let mut search_name = [0u8; 8];
|
||||||
|
for (i, byte) in name.as_bytes().iter().take(8).enumerate() {
|
||||||
|
search_name[i] = byte.to_ascii_uppercase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Scan backwards so PWAD patches take precedence over IWAD assets
|
||||||
|
lumpinfo_ref
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.rev() // Iterates backward from the end
|
||||||
|
.find(|(_, lump)| lump.name == search_name)
|
||||||
|
.map(|(index, _)| index as i32) // If found, return the index
|
||||||
|
.unwrap_or(-1) // "TFB. Not found." -> return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_LumpLength() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_ReadLump() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_CacheLumpNum() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn W_CacheLumpName() {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user