RD-6: Implemeneted M_Init

This commit is contained in:
Jim
2026-05-28 20:41:59 +01:00
parent 93a3c8548e
commit dad59e261d
4 changed files with 330 additions and 2 deletions

View File

@@ -5,3 +5,8 @@ A Rust version of the original DOOM base on the offically released source code f
This is more of a learning exercise than something good! For example, the original `z_zone.c` and `z_zone.h` will be more "Rust-like" compared to the original version. This is more of a learning exercise than something good! For example, the original `z_zone.c` and `z_zone.h` will be more "Rust-like" compared to the original version.
This repository will only contain the SHAREWARE verison of the original DOOM1, but will be able to run both IWAD and PWADS. This repository will only contain the SHAREWARE verison of the original DOOM1, but will be able to run both IWAD and PWADS.
This repository will be done in two parts before a "release"
1. An initial port keeping as close to the original C code as possible, which some minor modifications where it is clear on how to convert the code to Rust
2. Rust-ify any (hopefully all) parts of the code, that is removing `unsafe` and other such things. This will also include breaking down some of the `uber` sized funtions of the original source into more managable bits

View File

@@ -8,6 +8,7 @@ use crate::m_argv;
use crate::m_argv::M_CheckParm; 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::m_menu::M_Init;
use crate::m_misc::M_LoadDefaults; use crate::m_misc::M_LoadDefaults;
use crate::v_video::V_Init; use crate::v_video::V_Init;
@@ -466,11 +467,12 @@ pub fn D_DoomMain() {
} }
} }
// TODO: Implement other inits
/*
println!("M_Init: Init miscellaneous info."); println!("M_Init: Init miscellaneous info.");
M_Init(); M_Init();
// TODO: Implement other inits
/*
println!("R_Init: Init DOOM refresh daemon - ") println!("R_Init: Init DOOM refresh daemon - ")
R_Init(); R_Init();

320
src/m_menu/mod.rs Normal file
View File

@@ -0,0 +1,320 @@
// Menu Widget stuff i.e episode selection etc.
// TODO: Implement d_event.handle
use std::ptr::addr_of_mut;
use crate::doomdef::{DOOMGLOBALS, GameMode};
#[repr(C)]
#[derive(Copy, Clone)]
#[allow(non_snake_case)]
struct menuitem_t {
status: i32,
name: [u8; 10],
routine: Option<fn(choice: i32)>,
// hotkey in menu
alpha_key: u8,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[allow(non_snake_case)]
struct menu_t {
/// Number of items in the menu
numitems: i32,
/// Pointer to the previous menu
prevMenu: *mut menu_t,
/// The menu items
menuItems: *mut menuitem_t,
/// draw routine
routine: Option<fn()>,
/// X of the menu
x: i32,
/// y of the menu
y: i32,
/// The last item the user was on in the menu
lastOn: i32
}
/// TEMP function
#[allow(non_snake_case)]
fn VoidRoutine() {
}
#[allow(non_snake_case)]
fn VoidRoutineWithChoice(choice: i32) {
let _ = choice;
}
// Main Menu
#[allow(non_snake_case)]
mod MainMenu {
use super::*;
/// Enumeration of the main menu options
#[allow(non_camel_case_types)]
pub(super) enum main_e {
newgame = 0,
options,
loadgame,
savegame,
readthis,
quitdoom,
main_end
}
/// Main Menu items
#[allow(non_upper_case_globals)]
pub(super) static mut MainMenu: [menuitem_t; 6] = [
menuitem_t {
status: 1,
name: *b"M_NGAME\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'n'
},
menuitem_t {
status: 1,
name: *b"M_OPTION\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'o'
},
menuitem_t {
status: 1,
name: *b"M_LOADG\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'l'
},
menuitem_t {
status: 1,
name: *b"M_SAVEG\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b's'
},
menuitem_t {
status: 1,
name: *b"M_RDTHIS\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'r'
},
menuitem_t {
status: 1,
name: *b"M_QUITG\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'q'
}
];
/// Default MainMenu
#[allow(non_upper_case_globals)]
pub(super) static mut MainDef: menu_t = menu_t {
numitems: main_e::main_end as i32,
prevMenu: std::ptr::null_mut(),
menuItems: &raw mut MainMenu as *mut menuitem_t, // Use &raw mut instead of .as_mut_ptr() to avoid illegal static mut references (Feels dirty)
routine: Some(VoidRoutine),
x: 97,
y: 64,
lastOn: 0,
};
}
// New Game menu
#[allow(non_snake_case)]
mod NewGameMenu {
use super::*;
/// Enumeration of the New Game options
#[allow(non_camel_case_types)]
pub(super) enum newgame_e {
killthings,
toorough,
hurtme,
violence,
nightmare,
newg_end
}
/// New Game Menu items
#[allow(non_upper_case_globals)]
pub(super) static mut NewGameMenu: [menuitem_t; 5] = [
menuitem_t {
status: 1,
name: *b"M_JKILL\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'i'
},
menuitem_t {
status: 1,
name: *b"M_ROUGH\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'h'
},
menuitem_t {
status: 1,
name: *b"M_HURT\0\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'h'
},
menuitem_t {
status: 1,
name: *b"M_ULTRA\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'u'
},
menuitem_t {
status: 1,
name: *b"M_NMARE\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'n'
}
];
#[allow(non_upper_case_globals)]
pub(super) static mut NewDef: menu_t = menu_t {
numitems: newgame_e::newg_end as i32,
prevMenu: std::ptr::null_mut(), // TODO: Add EpiDef
menuItems: &raw mut NewGameMenu as *mut menuitem_t, // Use &raw mut instead of .as_mut_ptr() to avoid illegal static mut references (Feels dirty)
routine: Some(VoidRoutine),
x: 48,
y: 63,
lastOn: newgame_e::hurtme as i32,
};
}
// TODO: add OptionsMenu
#[allow(non_snake_case)]
mod ReadThis1 {
use super::*;
/// Enumeration of the main menu options
#[allow(non_camel_case_types)]
pub(super) enum read_e {
rdthisempty1 = 0,
read1_end,
}
/// Read1 Menu items
#[allow(non_upper_case_globals)]
pub(super) static mut ReadMenu1: [menuitem_t; 1] = [
menuitem_t {
status: 1,
name: *b"\0\0\0\0\0\0\0\0\0\0",
routine: Some(VoidRoutineWithChoice),
alpha_key: b'0'
}
];
/// Default MainMenu
#[allow(non_upper_case_globals)]
pub(super) static mut Read1Def: menu_t = menu_t {
numitems: read_e::rdthisempty1 as i32,
prevMenu: addr_of_mut!(MainMenu::MainDef),
menuItems: &raw mut ReadMenu1 as *mut menuitem_t, // Use &raw mut instead of .as_mut_ptr() to avoid illegal static mut references (Feels dirty)
routine: Some(VoidRoutine),
x: 280,
y: 185,
lastOn: 0,
};
}
// TODO: The rest of this hell!
#[allow(non_upper_case_globals)]
static mut currentMenu: *mut menu_t = std::ptr::null_mut();
#[allow(non_upper_case_globals)]
static mut menuactive: bool = false;
#[allow(non_upper_case_globals)]
static mut itemOn: i32 = 0;
#[allow(non_upper_case_globals)]
static mut whichSkull: i32 = 0;
#[allow(non_upper_case_globals)]
static mut skullAnimCounter: i32 = 0;
#[allow(non_upper_case_globals)]
static mut screenSize: i32 = 0;
#[allow(non_upper_case_globals)]
static mut screenBlocks: i32 = 0;
#[allow(non_upper_case_globals)]
static mut messageToPrint: i32 = 0;
#[allow(non_upper_case_globals)]
static mut messageString: *mut u8 = std::ptr::null_mut();
#[allow(non_upper_case_globals)]
static mut messageLastMenuActive: i32 = 0;
#[allow(non_upper_case_globals)]
static mut quickSaveSlot: i32 = -1;
#[allow(non_snake_case)]
pub fn M_Ticket() {
}
#[allow(non_snake_case)]
pub fn M_Drawer() {
}
#[allow(non_snake_case)]
pub fn M_Init() {
unsafe {
currentMenu = addr_of_mut!(MainMenu::MainDef);
menuactive = false;
itemOn = (*currentMenu).lastOn;
whichSkull = 0;
skullAnimCounter = 10;
screenSize = screenBlocks - 3;
messageToPrint = 0;
messageString = std::ptr::null_mut();
messageLastMenuActive = menuactive as i32;
quickSaveSlot = -1;
match DOOMGLOBALS::with_ref(|g| g.gamemode) {
GameMode::Commercial => {
/*
Original source code comment:
// This is used because DOOM 2 had only one HELP
// page. I use CREDIT as second page now, but
// kept this hack for educational purposes.
*/
MainMenu::MainMenu[MainMenu::main_e::readthis as usize] = MainMenu::MainMenu[MainMenu::main_e::quitdoom as usize];
MainMenu::MainDef.numitems -=1;
MainMenu::MainDef.y += 8;
NewGameMenu::NewDef.prevMenu = addr_of_mut!(MainMenu::MainDef);
ReadThis1::Read1Def.routine = Some(VoidRoutine);
ReadThis1::Read1Def.x = 330;
ReadThis1::Read1Def.y = 165;
ReadThis1::ReadMenu1[ReadThis1::read_e::rdthisempty1 as usize].routine = Some(VoidRoutineWithChoice);
},
GameMode::Shareware | GameMode::Registered => {
// TODO EpiDef.numitems--
}
_ => {
// do nothing :)
}
}
}
}
#[allow(non_snake_case)]
pub fn M_StartControlPanel() {
}

View File

@@ -4,6 +4,7 @@ mod doomdef;
mod doomtype; mod doomtype;
mod hu_stuff; mod hu_stuff;
mod m_argv; mod m_argv;
mod m_menu;
mod m_misc; mod m_misc;
mod v_video; mod v_video;
mod w_wad; mod w_wad;