5 Commits

15 changed files with 1444 additions and 10 deletions

2
.vscode/launch.json vendored
View File

@@ -16,7 +16,7 @@
}
},
"args": [
"./WADS/DOOM.WAD", "-dev", "-nomonsters", "-skill", "3"
"./WADS/DOOM.WAD", "-dev", "-nomonsters", "-skill", "3", "-config", "DEFAULT.CFG"
],
"cwd": "${workspaceFolder}"
},

View File

@@ -3,4 +3,8 @@ name = "RustyDoom"
version = "0.1.0"
edition = "2024"
[features]
default = []
french = []
[dependencies]

46
DEFAULT.CFG Normal file
View File

@@ -0,0 +1,46 @@
mouse_sensitivity 5
sfx_volume 8
music_volume 8
show_messages 1
key_right 77
key_left 75
key_up 72
key_down 80
key_strafeleft 51
key_straferight 52
key_fire 29
key_use 57
key_strafe 56
key_speed 54
use_mouse 1
mouseb_fire 0
mouseb_strafe 1
mouseb_forward 2
use_joystick 0
joyb_fire 0
joyb_strafe 1
joyb_use 3
joyb_speed 2
screenblocks 9
detaillevel 0
showmessages 1
comport 1
snd_channels 8
snd_musicdevice 4
snd_sfxdevice 3
snd_sbport 544
snd_sbirq 7
snd_sbdma 1
snd_mport -1
usegamma 0
chatmacro0 "no macro"
chatmacro1 "no macro"
chatmacro2 "no macro"
chatmacro3 "no macro"
chatmacro4 "no macro"
chatmacro5 "no macro"
chatmacro6 "no macro"
chatmacro7 "no macro"
chatmacro8 "no macro"
chatmacro9 "no macro"
0

View File

@@ -1,5 +1,7 @@
# RustyDoom
A rust version of the original Doom.
A Rust version of the original DOOM base on the offically released source code found at [https://github.com/id-software/doom](https://github.com/id-software/doom)
This is more of a learning exercise than something good!
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.

View File

@@ -8,8 +8,11 @@ use crate::m_argv;
use crate::m_argv::M_CheckParm;
use crate::m_argv::M_GetOptionalArgumentValueByArgument;
use crate::m_argv::PARM_NOT_FOUND;
use crate::m_misc::M_LoadDefaults;
use crate::v_video::V_Init;
use crate::w_wad::{W_CheckNumForName, W_InitMultipleFiles};
use crate::z_zone::Z_Init;
use crate::doomdef::{
VERSION,
@@ -399,18 +402,16 @@ pub fn D_DoomMain() {
}
}
// TODO: Implement subsytem inits
/*
println!("V_Init: allocate screens.");
V_Init();
println!("M_LoadDefaults: Load system defaults.")
println!("M_LoadDefaults: Load system defaults.");
M_LoadDefaults();
println!("Z_init: Init zone memory allocation daemon.");
Z_Init();
*/
println!("W_Init: Init WADfiles");
W_InitMultipleFiles(DOOMGLOBALS::with_ref(|g| g.wadfiles.clone())); // we are loading so how cares about a borrow

View File

@@ -0,0 +1,638 @@
/// English Language string constants
//
// D_Main
//
pub const D_DEVSTR: &'static str = "Development mode ON.\n";
pub const D_CDROM: &'static str = "CD-ROM Version: default.cfg from c:\\doomdata\n";
//
// M_Menu
//
pub const PRESSKEY: &'static str = "press a key.";
pub const PRESSYN: &'static str = "press y or n.";
pub const QUITMSG: &'static str = "are you sure you want to\nquit this great game?";
pub const LOADNET: &'static str = concat!("you can't do load while in a net game!\n\n", "press a key.");
pub const QLOADNET: &'static str = concat!("you can't quickload during a netgame!\n\n", "press a key.");
pub const QSAVESPOT: &'static str = concat!("you haven't picked a quicksave slot yet!\n\n", "press a key.");
pub const SAVEDEAD: &'static str = concat!("you can't save if you aren't playing!\n\n", "press a key.");
pub const QSPROMPT: &'static str = concat!("quicksave over your game named\n\n'%s'?\n\n", "press y or n.");
pub const QLPROMPT: &'static str = concat!("do you want to quickload the game named\n\n'%s'?\n\n", "press y or n.");
pub const NEWGAME: &'static str = concat!("you can't start a new game\n", "while in a network game.\n\n", "press a key.");
pub const NIGHTMARE: &'static str = concat!("are you sure? this skill level\n","isn't even remotely fair.\n\n", "press y or n.");
pub const SWSTRING: &'static str = concat!("this is the shareware version of doom.\n\n", "you need to order the entire trilogy.\n\n", "press a key.");
pub const MSGOFF: &'static str = "Messages OFF";
pub const MSGON: &'static str = "Messages ON";
pub const NETEND: &'static str = concat!("you can't end a netgame!\n\n", "press a key.");
pub const ENDGAME: &'static str = concat!("are you sure you want to end the game?\n\n", "press y or n.");
pub const DOSY: &'static str = "(press y to quit)";
pub const DETAILHI: &'static str = "High detail";
pub const DETAILLO: &'static str = "Low detail";
pub const GAMMALVL0: &'static str = "Gamma correction OFF";
pub const GAMMALVL1: &'static str = "Gamma correction level 1";
pub const GAMMALVL2: &'static str = "Gamma correction level 2";
pub const GAMMALVL3: &'static str = "Gamma correction level 3";
pub const GAMMALVL4: &'static str = "Gamma correction level 4";
pub const EMPTYSTRING: &'static str = "empty slot";
//
// P_inter.C
//
pub const GOTARMOR: &'static str = "Picked up the armor.";
pub const GOTMEGA: &'static str = "Picked up the MegaArmor!";
pub const GOTHTHBONUS: &'static str = "Picked up a health bonus.";
pub const GOTARMBONUS: &'static str = "Picked up an armor bonus.";
pub const GOTSTIM: &'static str = "Picked up a stimpack.";
pub const GOTMEDINEED: &'static str = "Picked up a medikit that you REALLY need!";
pub const GOTMEDIKIT: &'static str = "Picked up a medikit.";
pub const GOTSUPER: &'static str = "Supercharge!";
pub const GOTBLUECARD: &'static str = "Picked up a blue keycard.";
pub const GOTYELWCARD: &'static str = "Picked up a yellow keycard.";
pub const GOTREDCARD: &'static str = "Picked up a red keycard.";
pub const GOTBLUESKUL: &'static str = "Picked up a blue skull key.";
pub const GOTYELWSKUL: &'static str = "Picked up a yellow skull key.";
pub const GOTREDSKULL: &'static str = "Picked up a red skull key.";
pub const GOTINVUL: &'static str = "Invulnerability!";
pub const GOTBERSERK: &'static str = "Berserk!";
pub const GOTINVIS: &'static str = "Partial Invisibility";
pub const GOTSUIT: &'static str = "Radiation Shielding Suit";
pub const GOTMAP: &'static str = "Computer Area Map";
pub const GOTVISOR: &'static str = "Light Amplification Visor";
pub const GOTMSPHERE: &'static str = "MegaSphere!";
pub const GOTCLIP: &'static str = "Picked up a clip.";
pub const GOTCLIPBOX: &'static str = "Picked up a box of bullets.";
pub const GOTROCKET: &'static str = "Picked up a rocket.";
pub const GOTROCKBOX: &'static str = "Picked up a box of rockets.";
pub const GOTCELL: &'static str = "Picked up an energy cell.";
pub const GOTCELLBOX: &'static str = "Picked up an energy cell pack.";
pub const GOTSHELLS: &'static str = "Picked up 4 shotgun shells.";
pub const GOTSHELLBOX: &'static str = "Picked up a box of shotgun shells.";
pub const GOTBACKPACK: &'static str = "Picked up a backpack full of ammo!";
pub const GOTBFG9000: &'static str = "You got the BFG9000! Oh, yes.";
pub const GOTCHAINGUN: &'static str = "You got the chaingun!";
pub const GOTCHAINSAW: &'static str = "A chainsaw! Find some meat!";
pub const GOTLAUNCHER: &'static str = "You got the rocket launcher!";
pub const GOTPLASMA: &'static str = "You got the plasma gun!";
pub const GOTSHOTGUN: &'static str = "You got the shotgun!";
pub const GOTSHOTGUN2: &'static str = "You got the super shotgun!";
//
// P_Doors.C
//
pub const PD_BLUEO: &'static str = "You need a blue key to activate this object";
pub const PD_REDO: &'static str = "You need a red key to activate this object";
pub const PD_YELLOWO: &'static str = "You need a yellow key to activate this object";
pub const PD_BLUEK: &'static str = "You need a blue key to open this door";
pub const PD_REDK: &'static str = "You need a red key to open this door";
pub const PD_YELLOWK: &'static str = "You need a yellow key to open this door";
//
// G_game.C
//
pub const GGSAVED: &'static str = "game saved.";
//
// HU_stuff.C
//
pub const HUSTR_MSGU: &'static str = "[Message unsent]";
pub const HUSTR_E1M1: &'static str = "E1M1: Hangar";
pub const HUSTR_E1M2: &'static str = "E1M2: Nuclear Plant";
pub const HUSTR_E1M3: &'static str = "E1M3: Toxin Refinery";
pub const HUSTR_E1M4: &'static str = "E1M4: Command Control";
pub const HUSTR_E1M5: &'static str = "E1M5: Phobos Lab";
pub const HUSTR_E1M6: &'static str = "E1M6: Central Processing";
pub const HUSTR_E1M7: &'static str = "E1M7: Computer Station";
pub const HUSTR_E1M8: &'static str = "E1M8: Phobos Anomaly";
pub const HUSTR_E1M9: &'static str = "E1M9: Military Base";
pub const HUSTR_E2M1: &'static str = "E2M1: Deimos Anomaly";
pub const HUSTR_E2M2: &'static str = "E2M2: Containment Area";
pub const HUSTR_E2M3: &'static str = "E2M3: Refinery";
pub const HUSTR_E2M4: &'static str = "E2M4: Deimos Lab";
pub const HUSTR_E2M5: &'static str = "E2M5: Command Center";
pub const HUSTR_E2M6: &'static str = "E2M6: Halls of the Damned";
pub const HUSTR_E2M7: &'static str = "E2M7: Spawning Vats";
pub const HUSTR_E2M8: &'static str = "E2M8: Tower of Babel";
pub const HUSTR_E2M9: &'static str = "E2M9: Fortress of Mystery";
pub const HUSTR_E3M1: &'static str = "E3M1: Hell Keep";
pub const HUSTR_E3M2: &'static str = "E3M2: Slough of Despair";
pub const HUSTR_E3M3: &'static str = "E3M3: Pandemonium";
pub const HUSTR_E3M4: &'static str = "E3M4: House of Pain";
pub const HUSTR_E3M5: &'static str = "E3M5: Unholy Cathedral";
pub const HUSTR_E3M6: &'static str = "E3M6: Mt. Erebus";
pub const HUSTR_E3M7: &'static str = "E3M7: Limbo";
pub const HUSTR_E3M8: &'static str = "E3M8: Dis";
pub const HUSTR_E3M9: &'static str = "E3M9: Warrens";
pub const HUSTR_E4M1: &'static str = "E4M1: Hell Beneath";
pub const HUSTR_E4M2: &'static str = "E4M2: Perfect Hatred";
pub const HUSTR_E4M3: &'static str = "E4M3: Sever The Wicked";
pub const HUSTR_E4M4: &'static str = "E4M4: Unruly Evil";
pub const HUSTR_E4M5: &'static str = "E4M5: They Will Repent";
pub const HUSTR_E4M6: &'static str = "E4M6: Against Thee Wickedly";
pub const HUSTR_E4M7: &'static str = "E4M7: And Hell Followed";
pub const HUSTR_E4M8: &'static str = "E4M8: Unto The Cruel";
pub const HUSTR_E4M9: &'static str = "E4M9: Fear";
pub const HUSTR_1: &'static str = "level 1: entryway";
pub const HUSTR_2: &'static str = "level 2: underhalls";
pub const HUSTR_3: &'static str = "level 3: the gantlet";
pub const HUSTR_4: &'static str = "level 4: the focus";
pub const HUSTR_5: &'static str = "level 5: the waste tunnels";
pub const HUSTR_6: &'static str = "level 6: the crusher";
pub const HUSTR_7: &'static str = "level 7: dead simple";
pub const HUSTR_8: &'static str = "level 8: tricks and traps";
pub const HUSTR_9: &'static str = "level 9: the pit";
pub const HUSTR_10: &'static str = "level 10: refueling base";
pub const HUSTR_11: &'static str = "level 11: 'o' of destruction!";
pub const HUSTR_12: &'static str = "level 12: the factory";
pub const HUSTR_13: &'static str = "level 13: downtown";
pub const HUSTR_14: &'static str = "level 14: the inmost dens";
pub const HUSTR_15: &'static str = "level 15: industrial zone";
pub const HUSTR_16: &'static str = "level 16: suburbs";
pub const HUSTR_17: &'static str = "level 17: tenements";
pub const HUSTR_18: &'static str = "level 18: the courtyard";
pub const HUSTR_19: &'static str = "level 19: the citadel";
pub const HUSTR_20: &'static str = "level 20: gotcha!";
pub const HUSTR_21: &'static str = "level 21: nirvana";
pub const HUSTR_22: &'static str = "level 22: the catacombs";
pub const HUSTR_23: &'static str = "level 23: barrels o' fun";
pub const HUSTR_24: &'static str = "level 24: the chasm";
pub const HUSTR_25: &'static str = "level 25: bloodfalls";
pub const HUSTR_26: &'static str = "level 26: the abandoned mines";
pub const HUSTR_27: &'static str = "level 27: monster condo";
pub const HUSTR_28: &'static str = "level 28: the spirit world";
pub const HUSTR_29: &'static str = "level 29: the living end";
pub const HUSTR_30: &'static str = "level 30: icon of sin";
pub const HUSTR_31: &'static str = "level 31: wolfenstein";
pub const HUSTR_32: &'static str = "level 32: grosse";
pub const PHUSTR_1: &'static str ="level 1: congo";
pub const PHUSTR_2: &'static str ="level 2: well of souls";
pub const PHUSTR_3: &'static str ="level 3: aztec";
pub const PHUSTR_4: &'static str ="level 4: caged";
pub const PHUSTR_5: &'static str ="level 5: ghost town";
pub const PHUSTR_6: &'static str ="level 6: baron's lair";
pub const PHUSTR_7: &'static str ="level 7: caughtyard";
pub const PHUSTR_8: &'static str ="level 8: realm";
pub const PHUSTR_9: &'static str ="level 9: abattoire";
pub const PHUSTR_10: &'static str = "level 10: onslaught";
pub const PHUSTR_11: &'static str = "level 11: hunted";
pub const PHUSTR_12: &'static str = "level 12: speed";
pub const PHUSTR_13: &'static str = "level 13: the crypt";
pub const PHUSTR_14: &'static str = "level 14: genesis";
pub const PHUSTR_15: &'static str = "level 15: the twilight";
pub const PHUSTR_16: &'static str = "level 16: the omen";
pub const PHUSTR_17: &'static str = "level 17: compound";
pub const PHUSTR_18: &'static str = "level 18: neurosphere";
pub const PHUSTR_19: &'static str = "level 19: nme";
pub const PHUSTR_20: &'static str = "level 20: the death domain";
pub const PHUSTR_21: &'static str = "level 21: slayer";
pub const PHUSTR_22: &'static str = "level 22: impossible mission";
pub const PHUSTR_23: &'static str = "level 23: tombstone";
pub const PHUSTR_24: &'static str = "level 24: the final frontier";
pub const PHUSTR_25: &'static str = "level 25: the temple of darkness";
pub const PHUSTR_26: &'static str = "level 26: bunker";
pub const PHUSTR_27: &'static str = "level 27: anti-christ";
pub const PHUSTR_28: &'static str = "level 28: the sewers";
pub const PHUSTR_29: &'static str = "level 29: odyssey of noises";
pub const PHUSTR_30: &'static str = "level 30: the gateway of hell";
pub const PHUSTR_31: &'static str = "level 31: cyberden";
pub const PHUSTR_32: &'static str = "level 32: go 2 it";
pub const THUSTR_1: &'static str = "level 1: system control";
pub const THUSTR_2: &'static str = "level 2: human bbq";
pub const THUSTR_3: &'static str = "level 3: power control";
pub const THUSTR_4: &'static str = "level 4: wormhole";
pub const THUSTR_5: &'static str = "level 5: hanger";
pub const THUSTR_6: &'static str = "level 6: open season";
pub const THUSTR_7: &'static str = "level 7: prison";
pub const THUSTR_8: &'static str = "level 8: metal";
pub const THUSTR_9: &'static str = "level 9: stronghold";
pub const THUSTR_10: &'static str = "level 10: redemption";
pub const THUSTR_11: &'static str = "level 11: storage facility";
pub const THUSTR_12: &'static str = "level 12: crater";
pub const THUSTR_13: &'static str = "level 13: nukage processing";
pub const THUSTR_14: &'static str = "level 14: steel works";
pub const THUSTR_15: &'static str = "level 15: dead zone";
pub const THUSTR_16: &'static str = "level 16: deepest reaches";
pub const THUSTR_17: &'static str = "level 17: processing area";
pub const THUSTR_18: &'static str = "level 18: mill";
pub const THUSTR_19: &'static str = "level 19: shipping/respawning";
pub const THUSTR_20: &'static str = "level 20: central processing";
pub const THUSTR_21: &'static str = "level 21: administration center";
pub const THUSTR_22: &'static str = "level 22: habitat";
pub const THUSTR_23: &'static str = "level 23: lunar mining project";
pub const THUSTR_24: &'static str = "level 24: quarry";
pub const THUSTR_25: &'static str = "level 25: baron's den";
pub const THUSTR_26: &'static str = "level 26: ballistyx";
pub const THUSTR_27: &'static str = "level 27: mount pain";
pub const THUSTR_28: &'static str = "level 28: heck";
pub const THUSTR_29: &'static str = "level 29: river styx";
pub const THUSTR_30: &'static str = "level 30: last call";
pub const THUSTR_31: &'static str ="level 31: pharaoh";
pub const THUSTR_32: &'static str ="level 32: caribbean";
pub const HUSTR_CHATMACRO1: &'static str = "I'm ready to kick butt!";
pub const HUSTR_CHATMACRO2: &'static str = "I'm OK.";
pub const HUSTR_CHATMACRO3: &'static str = "I'm not looking too good!";
pub const HUSTR_CHATMACRO4: &'static str = "Help!";
pub const HUSTR_CHATMACRO5: &'static str = "You suck!";
pub const HUSTR_CHATMACRO6: &'static str = "Next time, scumbag...";
pub const HUSTR_CHATMACRO7: &'static str = "Come here!";
pub const HUSTR_CHATMACRO8: &'static str = "I'll take care of it.";
pub const HUSTR_CHATMACRO9: &'static str = "Yes";
pub const HUSTR_CHATMACRO0: &'static str = "No";
pub const HUSTR_TALKTOSELF1: &'static str = "You mumble to yourself";
pub const HUSTR_TALKTOSELF2: &'static str = "Who's there?";
pub const HUSTR_TALKTOSELF3: &'static str = "You scare yourself";
pub const HUSTR_TALKTOSELF4: &'static str = "You start to rave";
pub const HUSTR_TALKTOSELF5: &'static str = "You've lost it...";
pub const HUSTR_MESSAGESENT: &'static str = "[Message Sent]";
// The following should NOT be changed unless it seems
// just AWFULLY necessary
pub const HUSTR_PLRGREEN: &'static str = "Green: ";
pub const HUSTR_PLRINDIGO: &'static str = "Indigo: ";
pub const HUSTR_PLRBROWN: &'static str = "Brown: ";
pub const HUSTR_PLRRED: &'static str = "Red: ";
pub const HUSTR_KEYGREEN: &'static str = "g";
pub const HUSTR_KEYINDIGO: &'static str = "i";
pub const HUSTR_KEYBROWN: &'static str = "b";
pub const HUSTR_KEYRED: &'static str = "r";
//
// AM_map.C
//
pub const AMSTR_FOLLOWON: &'static str = "Follow Mode ON";
pub const AMSTR_FOLLOWOFF: &'static str = "Follow Mode OFF";
pub const AMSTR_GRIDON: &'static str = "Grid ON";
pub const AMSTR_GRIDOFF: &'static str = "Grid OFF";
pub const AMSTR_MARKEDSPOT: &'static str = "Marked Spot";
pub const AMSTR_MARKSCLEARED: &'static str = "All Marks Cleared";
//
// ST_stuff.C
//
pub const STSTR_MUS: &'static str = "Music Change";
pub const STSTR_NOMUS: &'static str = "IMPOSSIBLE SELECTION";
pub const STSTR_DQDON: &'static str = "Degreelessness Mode On";
pub const STSTR_DQDOFF: &'static str = "Degreelessness Mode Off";
pub const STSTR_KFAADDED: &'static str = "Very Happy Ammo Added";
pub const STSTR_FAADDED: &'static str = "Ammo (no keys) Added";
pub const STSTR_NCON: &'static str = "No Clipping Mode ON";
pub const STSTR_NCOFF: &'static str = "No Clipping Mode OFF";
pub const STSTR_BEHOLD: &'static str = "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp";
pub const STSTR_BEHOLDX: &'static str = "Power-up Toggled";
pub const STSTR_CHOPPERS: &'static str = "... doesn't suck - GM";
pub const STSTR_CLEV: &'static str = "Changing Level...";
//
// F_Finale.C
//
pub const E1TEXT: &'static str = concat!("Once you beat the big badasses and\n",
"clean out the moon base you're supposed\n",
"to win, aren't you? Aren't you? Where's\n",
"your fat reward and ticket home? What\n",
"the hell is this? It's not supposed to\n",
"end this way!\n",
"\n" ,
"It stinks like rotten meat, but looks\n",
"like the lost Deimos base. Looks like\n",
"you're stuck on The Shores of Hell.\n",
"The only way out is through.\n",
"\n",
"To continue the DOOM experience, play\n",
"The Shores of Hell and its amazing\n",
"sequel, Inferno!\n");
pub const E2TEXT: &'static str = concat!("You've done it! The hideous cyber-\n",
"demon lord that ruled the lost Deimos\n",
"moon base has been slain and you\n",
"are triumphant! But ... where are\n",
"you? You clamber to the edge of the\n",
"moon and look down to see the awful\n",
"truth.\n" ,
"\n",
"Deimos floats above Hell itself!\n",
"You've never heard of anyone escaping\n",
"from Hell, but you'll make the bastards\n",
"sorry they ever heard of you! Quickly,\n",
"you rappel down to the surface of\n",
"Hell.\n",
"\n" ,
"Now, it's on to the final chapter of\n",
"DOOM! -- Inferno.");
pub const E3TEXT: &'static str = concat!("The loathsome spiderdemon that\n",
"masterminded the invasion of the moon\n",
"bases and caused so much death has had\n",
"its ass kicked for all time.\n",
"\n",
"A hidden doorway opens and you enter.\n",
"You've proven too tough for Hell to\n",
"contain, and now Hell at last plays\n",
"fair -- for you emerge from the door\n",
"to see the green fields of Earth!\n",
"Home at last.\n" ,
"\n",
"You wonder what's been happening on\n",
"Earth while you were battling evil\n",
"unleashed. It's good that no Hell-\n",
"spawn could have come through that\n",
"door with you ...");
pub const E4TEXT: &'static str = concat!("the spider mastermind must have sent forth\n",
"its legions of hellspawn before your\n",
"final confrontation with that terrible\n",
"beast from hell. but you stepped forward\n",
"and brought forth eternal damnation and\n",
"suffering upon the horde as a true hero\n",
"would in the face of something so evil.\n",
"\n",
"besides, someone was gonna pay for what\n",
"happened to daisy, your pet rabbit.\n",
"\n",
"but now, you see spread before you more\n",
"potential pain and gibbitude as a nation\n",
"of demons run amok among our cities.\n",
"\n",
"next stop, hell on earth!");
// after level 6, put this:
pub const C1TEXT: &'static str = concat!("YOU HAVE ENTERED DEEPLY INTO THE INFESTED\n",
"STARPORT. BUT SOMETHING IS WRONG. THE\n",
"MONSTERS HAVE BROUGHT THEIR OWN REALITY\n",
"WITH THEM, AND THE STARPORT'S TECHNOLOGY\n",
"IS BEING SUBVERTED BY THEIR PRESENCE.\n",
"\n",
"AHEAD, YOU SEE AN OUTPOST OF HELL, A\n",
"FORTIFIED ZONE. IF YOU CAN GET PAST IT,\n",
"YOU CAN PENETRATE INTO THE HAUNTED HEART\n",
"OF THE STARBASE AND FIND THE CONTROLLING\n",
"SWITCH WHICH HOLDS EARTH'S POPULATION\n",
"HOSTAGE.");
// After level 11, put this:
pub const C2TEXT: &'static str = concat!("YOU HAVE WON! YOUR VICTORY HAS ENABLED\n",
"HUMANKIND TO EVACUATE EARTH AND ESCAPE\n",
"THE NIGHTMARE. NOW YOU ARE THE ONLY\n",
"HUMAN LEFT ON THE FACE OF THE PLANET.\n",
"CANNIBAL MUTATIONS, CARNIVOROUS ALIENS,\n",
"AND EVIL SPIRITS ARE YOUR ONLY NEIGHBORS.\n",
"YOU SIT BACK AND WAIT FOR DEATH, CONTENT\n",
"THAT YOU HAVE SAVED YOUR SPECIES.\n",
"\n",
"BUT THEN, EARTH CONTROL BEAMS DOWN A\n",
"MESSAGE FROM SPACE: \"SENSORS HAVE LOCATED\n",
"THE SOURCE OF THE ALIEN INVASION. IF YOU\n",
"GO THERE, YOU MAY BE ABLE TO BLOCK THEIR\n",
"ENTRY. THE ALIEN BASE IS IN THE HEART OF\n",
"YOUR OWN HOME CITY, NOT FAR FROM THE\n",
"STARPORT.\" SLOWLY AND PAINFULLY YOU GET\n",
"UP AND RETURN TO THE FRAY.");
// After level 20, put this:
pub const C3TEXT: &'static str = concat!("YOU ARE AT THE CORRUPT HEART OF THE CITY,\n",
"SURROUNDED BY THE CORPSES OF YOUR ENEMIES.\n",
"YOU SEE NO WAY TO DESTROY THE CREATURES'\n",
"ENTRYWAY ON THIS SIDE, SO YOU CLENCH YOUR\n",
"TEETH AND PLUNGE THROUGH IT.\n",
"\n",
"THERE MUST BE A WAY TO CLOSE IT ON THE\n",
"OTHER SIDE. WHAT DO YOU CARE IF YOU'VE\n",
"GOT TO GO THROUGH HELL TO GET TO IT?");
// After level 29, put this:
pub const C4TEXT: &'static str = concat!("THE HORRENDOUS VISAGE OF THE BIGGEST\n",
"DEMON YOU'VE EVER SEEN CRUMBLES BEFORE\n",
"YOU, AFTER YOU PUMP YOUR ROCKETS INTO\n",
"HIS EXPOSED BRAIN. THE MONSTER SHRIVELS\n",
"UP AND DIES, ITS THRASHING LIMBS\n",
"DEVASTATING UNTOLD MILES OF HELL'S\n",
"SURFACE.\n",
"\n",
"YOU'VE DONE IT. THE INVASION IS OVER.\n",
"EARTH IS SAVED. HELL IS A WRECK. YOU\n",
"WONDER WHERE BAD FOLKS WILL GO WHEN THEY\n",
"DIE, NOW. WIPING THE SWEAT FROM YOUR\n",
"FOREHEAD YOU BEGIN THE LONG TREK BACK\n",
"HOME. REBUILDING EARTH OUGHT TO BE A\n",
"LOT MORE FUN THAN RUINING IT WAS.\n");
// Before level 31, put this:
pub const C5TEXT: &'static str = concat!("CONGRATULATIONS, YOU'VE FOUND THE SECRET\n",
"LEVEL! LOOKS LIKE IT'S BEEN BUILT BY\n",
"HUMANS, RATHER THAN DEMONS. YOU WONDER\n",
"WHO THE INMATES OF THIS CORNER OF HELL\n",
"WILL BE.");
// Before level 32, put this:
pub const C6TEXT: &'static str = concat!("CONGRATULATIONS, YOU'VE FOUND THE\n",
"SUPER SECRET LEVEL! YOU'D BETTER\n",
"BLAZE THROUGH THIS ONE!\n");
// after map 06
pub const P1TEXT: &'static str = concat!("You gloat over the steaming carcass of the\n",
"Guardian. With its death, you've wrested\n",
"the Accelerator from the stinking claws\n",
"of Hell. You relax and glance around the\n",
"room. Damn! There was supposed to be at\n",
"least one working prototype, but you can't\n",
"see it. The demons must have taken it.\n",
"\n",
"You must find the prototype, or all your\n",
"struggles will have been wasted. Keep\n",
"moving, keep fighting, keep killing.\n",
"Oh yes, keep living, too.");
// after map 11
pub const P2TEXT: &'static str = concat!("Even the deadly Arch-Vile labyrinth could\n",
"not stop you, and you've gotten to the\n",
"prototype Accelerator which is soon\n",
"efficiently and permanently deactivated.\n",
"\n",
"You're good at that kind of thing.");
// after map 20
pub const P3TEXT: &'static str = concat!("You've bashed and battered your way into\n",
"the heart of the devil-hive. Time for a\n",
"Search-and-Destroy mission, aimed at the\n",
"Gatekeeper, whose foul offspring is\n",
"cascading to Earth. Yeah, he's bad. But\n",
"you know who's worse!\n",
"\n",
"Grinning evilly, you check your gear, and\n",
"get ready to give the bastard a little Hell\n",
"of your own making!");
// after map 30
pub const P4TEXT: &'static str = concat!("The Gatekeeper's evil face is splattered\n",
"all over the place. As its tattered corpse\n",
"collapses, an inverted Gate forms and\n",
"sucks down the shards of the last\n",
"prototype Accelerator, not to mention the\n",
"few remaining demons. You're done. Hell\n",
"has gone back to pounding bad dead folks \n",
"instead of good live ones. Remember to\n",
"tell your grandkids to put a rocket\n",
"launcher in your coffin. If you go to Hell\n",
"when you die, you'll need it for some\n",
"final cleaning-up ...");
// before map 31
pub const P5TEXT: &'static str = concat!("You've found the second-hardest level we\n",
"got. Hope you have a saved game a level or\n",
"two previous. If not, be prepared to die\n",
"aplenty. For master marines only.");
// before map 32
pub const P6TEXT: &'static str = concat!("Betcha wondered just what WAS the hardest\n",
"level we had ready for ya? Now you know.\n",
"No one gets out alive.");
pub const T1TEXT: &'static str = concat!("You've fought your way out of the infested\n",
"experimental labs. It seems that UAC has\n",
"once again gulped it down. With their\n",
"high turnover, it must be hard for poor\n",
"old UAC to buy corporate health insurance\n",
"nowadays..\n",
"\n",
"Ahead lies the military complex, now\n",
"swarming with diseased horrors hot to get\n",
"their teeth into you. With luck, the\n",
"complex still has some warlike ordnance\n",
"laying around.");
pub const T2TEXT: &'static str = concat!("You hear the grinding of heavy machinery\n",
"ahead. You sure hope they're not stamping\n",
"out new hellspawn, but you're ready to\n",
"ream out a whole herd if you have to.\n",
"They might be planning a blood feast, but\n",
"you feel about as mean as two thousand\n",
"maniacs packed into one mad killer.\n",
"\n",
"You don't plan to go down easy.");
pub const T3TEXT: &'static str = concat!("The vista opening ahead looks real damn\n",
"familiar. Smells familiar, too -- like\n",
"fried excrement. You didn't like this\n",
"place before, and you sure as hell ain't\n",
"planning to like it now. The more you\n",
"brood on it, the madder you get.\n",
"Hefting your gun, an evil grin trickles\n",
"onto your face. Time to take some names.");
pub const T4TEXT: &'static str = concat!("Suddenly, all is silent, from one horizon\n",
"to the other. The agonizing echo of Hell\n",
"fades away, the nightmare sky turns to\n",
"blue, the heaps of monster corpses start \n",
"to evaporate along with the evil stench \n",
"that filled the air. Jeeze, maybe you've\n",
"done it. Have you really won?\n",
"\n",
"Something rumbles in the distance.\n",
"A blue light begins to glow inside the\n",
"ruined skull of the demon-spitter.");
pub const T5TEXT: &'static str = concat!("What now? Looks totally different. Kind\n",
"of like King Tut's condo. Well,\n",
"whatever's here can't be any worse\n",
"than usual. Can it? Or maybe it's best\n",
"to let sleeping gods lie..");
pub const T6TEXT: &'static str = concat!("Time for a vacation. You've burst the\n",
"bowels of hell and by golly you're ready\n",
"for a break. You mutter to yourself,\n",
"Maybe someone else can kick Hell's ass\n",
"next time around. Ahead lies a quiet town,\n",
"with peaceful flowing water, quaint\n",
"buildings, and presumably no Hellspawn.\n",
"\n",
"As you step off the transport, you hear\n",
"the stomp of a cyberdemon's iron shoe.");
//
// Character cast strings F_FINALE.C
//
pub const CC_ZOMBIE: &'static str = "ZOMBIEMAN";
pub const CC_SHOTGUN: &'static str = "SHOTGUN GUY";
pub const CC_HEAVY: &'static str = "HEAVY WEAPON DUDE";
pub const CC_IMP: &'static str = "IMP";
pub const CC_DEMON: &'static str = "DEMON";
pub const CC_LOST: &'static str = "LOST SOUL";
pub const CC_CACO: &'static str = "CACODEMON";
pub const CC_HELL: &'static str = "HELL KNIGHT";
pub const CC_BARON: &'static str = "BARON OF HELL";
pub const CC_ARACH: &'static str = "ARACHNOTRON";
pub const CC_PAIN: &'static str = "PAIN ELEMENTAL";
pub const CC_REVEN: &'static str = "REVENANT";
pub const CC_MANCU: &'static str = "MANCUBUS";
pub const CC_ARCH: &'static str = "ARCH-VILE";
pub const CC_SPIDER: &'static str = "THE SPIDER MASTERMIND";
pub const CC_CYBER: &'static str = "THE CYBERDEMON";
pub const CC_HERO: &'static str = "OUR HERO";

View File

@@ -0,0 +1,3 @@
/// French Language string constants
///
/// NOT IMPLEMENTED "C'est injuste envers les Français !"

20
src/d_strings/mod.rs Normal file
View File

@@ -0,0 +1,20 @@
#[cfg(feature = "french")]
mod d_french;
#[cfg(not(feature = "french"))]
mod d_english;
#[cfg(feature = "french")]
pub use d_french::*;
#[cfg(not(feature = "french"))]
pub use d_english::*;
pub const SAVEGAMENAME: &'static str = "doomsav";
pub const DEVMPAS: &'static str = "devmaps";
pub const DEVDATA: &'static str = "devdata";
pub const NUM_QUITMESSAGES: i32 = 22;

View File

@@ -1,8 +1,38 @@
use std::cell::RefCell;
/// DOOM version
pub const VERSION:i32 = 110;
pub const D_DEVSTR: &str = "Development mode ON.";
/// BASE_WIDTH
/// For resize of screen, at start of game.
/// It will not work dynamically, see visplanes. TODO: Investigate what this means.
pub const BASE_WIDTH: i32 = 320;
/// Screen scale multiplier?
/// Original source comment:
/// It is educational but futile to change this
/// scaling e.g. to 2. Drawing of status bar,
/// menues etc. is tied to the scale implied
/// by the graphics.
pub const SCREEN_MUL: i32 = 1;
/// Inverse of the aspect ratio
pub const INV_ASPECT_RATIO: f32 = 0.625; // 0.75, ideally according to the original source
/// SCREENWIDTH
/// = SCREEN_MUL*BASE_WIDTH //320
pub const SCREENWIDTH: i32 = 320;
/// SCREENHEIGHT
/// (int)(SCREEN_MUL*BASE_WIDTH*INV_ASPECT_RATIO) //200
pub const SCREENHEIGHT:i32 = 200;
/// The maximum number of players, multiplayer/networking.
pub const MAXPLAYERS: i32 = 4;
/// The number of state updates (ticks) to be done per second
pub const TICRATE: i32 = 35;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GameMode {

10
src/doomtype/mod.rs Normal file
View File

@@ -0,0 +1,10 @@
const MAXCHAR: i8 = i8::MAX;
const MAXSHORT: i16 = i16::MAX;
const MAXINT: i32 = i32::MAX;
const MAXLONG: i32 = i32::MAX;
// Minimum values
const MINCHAR: i8 = i8::MIN;
const MINSHORT: i16 = i16::MIN;
const MININT: i32 = i32::MIN;
const MINLONG: i32 = i32::MIN;

99
src/hu_stuff/mod.rs Normal file
View File

@@ -0,0 +1,99 @@
/// Heads up display stuff
use std::sync::OnceLock;
use crate::doomdef::TICRATE;
use crate::d_strings;
/// The first font characters
pub const HU_FONTSTART: char = '!';
/// The last font characters
pub const HU_FONTEND: char = '_';
/// Number of glyphs in the font
pub const HU_FONTSIZE: u8 = (HU_FONTEND as u8 - HU_FONTSTART as u8) + 1;
pub const HU_BROADCAST: i32 = 5;
// pub const HU_MSGREFRESH = KEY_ENTER // Comes from doomdef.h TODO: implement more doomdef!
pub const HU_MSGX: i32 = 0;
pub const HU_MSGY: i32 = 0;
/// The width of a message in characters
pub const HU_MSGWIDTH: i32 = 64;
/// The height of a message in lines
pub const HU_MSGHEIGHT: i32 = 1;
/// The time a message should be displayed for before it disapears
pub const HU_MSGTIMEOUT: i32 = 4 * TICRATE;
/// Constant string arrays
static CHAT_MACROS_LOCK: OnceLock<[String; 10]> = OnceLock::new();
pub fn get_chat_macro_ptr(index: usize) -> *mut String {
let array_ref = CHAT_MACROS_LOCK.get_or_init(|| [
d_strings::HUSTR_CHATMACRO0.to_string(),
d_strings::HUSTR_CHATMACRO1.to_string(),
d_strings::HUSTR_CHATMACRO2.to_string(),
d_strings::HUSTR_CHATMACRO3.to_string(),
d_strings::HUSTR_CHATMACRO4.to_string(),
d_strings::HUSTR_CHATMACRO5.to_string(),
d_strings::HUSTR_CHATMACRO6.to_string(),
d_strings::HUSTR_CHATMACRO7.to_string(),
d_strings::HUSTR_CHATMACRO8.to_string(),
d_strings::HUSTR_CHATMACRO9.to_string(),
]);
// Cast the immutable reference from the lock to a raw mutable pointer
unsafe {
let array_ptr = array_ref.as_ptr() as *mut String;
array_ptr.add(index)
}
}
// HUD text stuff
#[allow(non_snake_case)]
pub fn HU_INIT() {
}
#[allow(non_snake_case)]
pub fn HU_Start() {
}
/*
// TODO: Implement d_event.h/c
#[allow(non_snake_case)]
pub fn HU_Responder(event_t* ev) {
}
*/
#[allow(non_snake_case)]
pub fn HU_Ticker() {
}
#[allow(non_snake_case)]
pub fn HU_Ticket() {
}
#[allow(non_snake_case)]
pub fn HU_dequeueChatChar() /*-> char */ {
}
#[allow(non_snake_case)]
pub fn HU_Erase() {
}

367
src/m_misc/mod.rs Normal file
View File

@@ -0,0 +1,367 @@
use std::ptr::addr_of_mut;
use crate::d_strings;
use crate::doomtype;
use crate::hu_stuff::get_chat_macro_ptr;
use crate::m_argv::{M_CheckParm, M_GetOptionalArgumentValueByArgument, PARM_NOT_FOUND};
// static mut variable stuff
#[allow(non_upper_case_globals)]
static mut mouseSensitivity: i32 = 0;
#[allow(non_upper_case_globals)]
static mut snd_SfxVolumne: i32 = 0;
#[allow(non_upper_case_globals)]
static mut snd_MusicVolume: i32 = 0;
#[allow(non_upper_case_globals)]
static mut showMessages: i32 = 0;
#[allow(non_upper_case_globals)]
static mut usemouse: i32 = 0;
#[allow(non_upper_case_globals)]
static mut mousebfire: i32 = 0;
#[allow(non_upper_case_globals)]
static mut mousebstrafe: i32 = 0;
#[allow(non_upper_case_globals)]
static mut mousebforward: i32 = 0;
#[allow(non_upper_case_globals)]
static mut usejoystick: i32 = 0;
#[allow(non_upper_case_globals)]
static mut joybfire: i32 = 0;
#[allow(non_upper_case_globals)]
static mut joybstrafe: i32 = 0;
#[allow(non_upper_case_globals)]
static mut joybuse: i32 = 0;
#[allow(non_upper_case_globals)]
static mut joybspeed: i32 = 0;
#[allow(non_upper_case_globals)]
static mut screenblocks: i32 = 0;
#[allow(non_upper_case_globals)]
static mut detailLevel: i32 = 0;
#[allow(non_upper_case_globals)]
static mut numChannels: i32 = 0;
#[allow(non_upper_case_globals)]
static mut usegamma: i32 = 0;
/// Represents a type-safe pointer to either a numeric or string global variable
pub enum DefaultLocation {
/// Pointer to an integer(i32) value
Int(*mut i32),
/// Pointer to a String value
Str(*mut String)
}
/// Represents a type to represent the extacted default fallback value
pub enum ConfigValue {
/// Represents an integer(i32) configuration value
Int(i32),
/// Represents a String configuration value
Str(String)
}
/// Represents the name, location and default value of a configuation variable
#[repr(C)]
pub struct default_t {
/// The key used for the configuration value from the corresponding '.cfg' file
pub name: &'static str,
/// The memory location of the global variable to update
pub location: DefaultLocation,
/// The fallback value if the setting is missing from the file
pub default_value: ConfigValue
}
fn get_defaults() -> Vec<default_t> {
unsafe {
vec![
// mouse_sensitivity
default_t {
name: "mouse_sensitivity",
location: DefaultLocation::Int(addr_of_mut!(mouseSensitivity)),
default_value: ConfigValue::Int(5)
},
// snd_SfxVolumne
default_t {
name: "sfx_volume",
location: DefaultLocation::Int(addr_of_mut!(snd_SfxVolumne)),
default_value: ConfigValue::Int(8)
},
// snd_MusicVolume
default_t {
name: "snd_MusicVolumne",
location: DefaultLocation::Int(addr_of_mut!(snd_MusicVolume)),
default_value: ConfigValue::Int(8)
},
// showMessages
default_t {
name: "show_messages",
location: DefaultLocation::Int(addr_of_mut!(showMessages)),
default_value: ConfigValue::Int(1)
},
// usemouse
default_t {
name: "use_mouse",
location: DefaultLocation::Int(addr_of_mut!(usemouse)),
default_value: ConfigValue::Int(1)
},
// mousebfire
default_t {
name: "mouseb_fire",
location: DefaultLocation::Int(addr_of_mut!(mousebfire)),
default_value: ConfigValue::Int(0)
},
// mousebstrafe
default_t {
name: "mouseb_strafe",
location: DefaultLocation::Int(addr_of_mut!(mousebstrafe)),
default_value: ConfigValue::Int(1)
},
// mousebforward
default_t {
name: "mouseb_forward",
location: DefaultLocation::Int(addr_of_mut!(mousebforward)),
default_value: ConfigValue::Int(2)
},
// usejoystick
default_t {
name: "use_joystick",
location: DefaultLocation::Int(addr_of_mut!(usejoystick)),
default_value: ConfigValue::Int(0)
},
// joybfire
default_t {
name: "joyb_fire",
location: DefaultLocation::Int(addr_of_mut!(joybfire)),
default_value: ConfigValue::Int(0)
},
// joybstrafe
default_t {
name: "joyb_strafe",
location: DefaultLocation::Int(addr_of_mut!(joybstrafe)),
default_value: ConfigValue::Int(1)
},
// joybuse
default_t {
name: "joyb_use",
location: DefaultLocation::Int(addr_of_mut!(joybuse)),
default_value: ConfigValue::Int(3)
},
// joybspeed
default_t {
name: "joyb_speed",
location: DefaultLocation::Int(addr_of_mut!(joybspeed)),
default_value: ConfigValue::Int(2)
},
// screenblocks
default_t {
name: "screenblocks",
location: DefaultLocation::Int(addr_of_mut!(screenblocks)),
default_value: ConfigValue::Int(9)
},
// detailLevel
default_t {
name: "detailLevel",
location: DefaultLocation::Int(addr_of_mut!(detailLevel)),
default_value: ConfigValue::Int(0)
},
// numChannels
default_t {
name: "snd_channels",
location: DefaultLocation::Int(addr_of_mut!(numChannels)),
default_value: ConfigValue::Int(3)
},
// usegamma
default_t {
name: "usegamma",
location: DefaultLocation::Int(addr_of_mut!(usegamma)),
default_value: ConfigValue::Int(0)
},
// chatmacro0
default_t {
name: "chatmacro0",
location: DefaultLocation::Str(get_chat_macro_ptr(0)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO0.to_string())
},
// chatmacro1
default_t {
name: "chatmacro1",
location: DefaultLocation::Str(get_chat_macro_ptr(1)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO1.to_string())
},
// chatmacro2
default_t {
name: "chatmacro2",
location: DefaultLocation::Str(get_chat_macro_ptr(2)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO2.to_string())
},
// chatmacro3
default_t {
name: "chatmacro3",
location: DefaultLocation::Str(get_chat_macro_ptr(3)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO3.to_string())
},
// chatmacro4
default_t {
name: "chatmacro4",
location: DefaultLocation::Str(get_chat_macro_ptr(4)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO4.to_string())
},
// chatmacro5
default_t {
name: "chatmacro5",
location: DefaultLocation::Str(get_chat_macro_ptr(5)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO5.to_string())
},
// chatmacro6
default_t {
name: "chatmacro6",
location: DefaultLocation::Str(get_chat_macro_ptr(6)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO6.to_string())
},
// chatmacro7
default_t {
name: "chatmacro7",
location: DefaultLocation::Str(get_chat_macro_ptr(7)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO7.to_string())
},
// chatmacro8
default_t {
name: "chatmacro8",
location: DefaultLocation::Str(get_chat_macro_ptr(8)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO8.to_string())
},
// chatmacro9
default_t {
name: "chatmacro9",
location: DefaultLocation::Str(get_chat_macro_ptr(9)),
default_value: ConfigValue::Str(d_strings::HUSTR_CHATMACRO9.to_string())
}
]
}
}
#[allow(non_snake_case)]
pub fn M_WriteFile(name: &str, source: std::fs::File, length: i64) {
}
#[allow(non_snake_case)]
pub fn M_ReadFile(name: &str, buffer: Vec<u8>) {
}
#[allow(non_snake_case)]
pub fn M_ScreenShot() {
}
#[allow(non_snake_case)]
pub fn M_LoadDefaults() {
// Set to defaults
let mut defaults = get_defaults();
for item in &defaults {
unsafe {
match &item.location {
DefaultLocation::Int(ptr) => {
if let ConfigValue::Int(val) = item.default_value {
**ptr = val;
}
}
DefaultLocation::Str(ptr) => {
if let ConfigValue::Str(val) = &item.default_value {
**ptr = val.clone();
}
}
}
}
} // end iter
// load custom cfg?
let mut cfg_location = "DEFAULT.CFG";
let p = M_CheckParm("-config");
if p != PARM_NOT_FOUND {
cfg_location = M_GetOptionalArgumentValueByArgument("-config").unwrap();
}
// read contents
if let Ok(cfg_content) = std::fs::read_to_string(cfg_location) {
for line in cfg_content.lines() {
let cfg_line = line.trim();
if cfg_line.is_empty() {
continue;
}
// split the non-empty cfg line into two
if let Some((parsed_cfg_key, parsed_cfg_value)) = cfg_line.split_once(char::is_whitespace) {
let key = parsed_cfg_key.trim();
let value = parsed_cfg_value.trim();
if let Some(cfg_item) = defaults.iter_mut().find(|d| d.name == key) {
unsafe {
match &cfg_item.location {
DefaultLocation::Int(ptr) => {
if value.starts_with("0x") {
if let Ok(num) = i32::from_str_radix(value, 16) {
**ptr = num;
}
else {
println!("Unable to parse value '{}' as an integer for configuation setting '{}'", value, key);
println!("Using defaults");
}
}
else if let Ok(num) = i32::from_str_radix(value, 10) {
**ptr = num;
}
else {
println!("Unable to parse value '{}' as an integer for configuation setting '{}'", value, key);
println!("Using defaults");
}
}
DefaultLocation::Str(ptr) => {
let cleaned_str = value.trim_matches('"').to_string();
**ptr = cleaned_str;
}
}
}
}
}
}
} else {
println!("Unable to read configuation file '{}'", &cfg_location);
println!("Using defaults");
}
}
#[allow(non_snake_case)]
pub fn M_SaveDefaults() {
}
#[allow(non_snake_case)]
pub fn M_DrawText(x: i32, y: i32, direct: bool, text: &str) {
}

View File

@@ -1,7 +1,13 @@
mod d_main;
mod d_strings;
mod doomdef;
mod doomtype;
mod hu_stuff;
mod m_argv;
mod m_misc;
mod v_video;
mod w_wad;
mod z_zone;
mod math;

43
src/v_video/mod.rs Normal file
View File

@@ -0,0 +1,43 @@
use crate::doomdef::{SCREENHEIGHT, SCREENWIDTH};
use crate::doomtype;
pub const CENTERY: i32 = SCREENHEIGHT / 2;
// static var stuff
#[allow(non_upper_case_globals)]
static mut screens: [[u8; (SCREENWIDTH*SCREENHEIGHT) as usize]; 5] = [[0u8; (SCREENWIDTH*SCREENHEIGHT) as usize]; 5];
#[allow(non_snake_case)]
pub fn V_Init() {
// Do nothing :)
// the memory is already allocated
}
#[allow(non_snake_case)]
pub fn V_CopyRect(srcx: i32, srcy: i32, srcscrn: i32, width: i32, height: i32, destx: i32, desty: i32, destscrn: i32) {
}
/*
TODO: Implement "r_data"
#[allow(non_snake_case)]
pub fn V_DrawPatch(x: i32, y: i32, scrn: i32, patch: Vec<patch_t>) {
}
#[allow(non_snake_case)]
pub fn V_DrawPatchDirect(x: i32, y: i32, scrn: i32, patch: Vec<patch_t>) {
}
*/
#[allow(non_snake_case)]
pub fn V_GetBlock(x: i32, y: i32, scrn: i32, width: i32, height: i32, dest: Vec<u8>) {
}
#[allow(non_snake_case)]
pub fn V_MarkRect(x: i32, y: i32, width: i32, height: i32) {
}

165
src/z_zone/mod.rs Normal file
View File

@@ -0,0 +1,165 @@
/// Memory allocator stuff
/// Compared to the original source, this will be some what "lean n' mean"
use std::cell::RefCell;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
/// The PurgeTags (PUs)
/// Tags < 100 are not overwritten untill freed
pub enum PurgeTag {
/// Static the entire execution time
Static = 1,
/// Static while playing
Sound = 2,
/// static while playing
Music = 3,
/// Original source comment: anything else dave wants static
Dave = 4,
/// static until level exit
Level = 50,
/// static for special thinkers in a level
LevSpec = 51,
// Tags >= 100 are "purgable" whenever needed
PurgeLevel = 100,
Cache = 101,
}
/// Provides metadata on
struct AllocMeta {
/// The size of the allocation
size: usize,
/// The PU tag associated with the allocation
tag: i32,
/// A pointer to the caller's tracking pointer, cleared automatically upon freeing
user: *mut *mut u8,
}
thread_local! {
// We promise not to be naughty and access this from another thread :)
/// Mapping from pointers (as usize) to the correspond AllocationMeta
static REGISTRY: RefCell<HashMap<usize, AllocMeta>> = RefCell::new(HashMap::new());
}
// Helper method that we can use to access the registry
fn with_registry<F, R>(f: F) -> R
where
F: FnOnce(&mut HashMap<usize, AllocMeta>) -> R
{
REGISTRY.with(|registry| f(&mut *registry.borrow_mut()))
}
#[allow(non_snake_case)]
/// Initalized the Zone memory allocator sub-system
pub fn Z_Init() {
// do nothing, we get lazy init of the registry.
}
#[allow(non_snake_case)]
/// Allocate a contiguous chunk of zeroed memory from the zone allocator
/// # Safety
/// This function returns a raw pointer that bypasses Rust's automatic memory
/// tracking. The returned memory must be manually reclaimed using `Z_Free`.
pub unsafe fn Z_Malloc(size: usize, tag: i32, user: *mut *mut u8) -> *mut u8 {
let mut buffer = vec![0u8; size];
let ptr = buffer.as_mut_ptr();
// ensures Rust does not drop the buffer at the end of this block
std::mem::forget(buffer);
// Update the engine's tracking pointer if one was provided
if !user.is_null() {
unsafe {
*user = ptr;
}
}
// Save allocation details using the pointer address as the key
with_registry(|map| {
map.insert(ptr as usize, AllocMeta { size, tag, user });
});
ptr
}
#[allow(non_snake_case)]
/// Reclaims and frees a allocation from Z_Malloc
/// # Safety
/// The provided pointer must point to a valid allocation tracked by the registry.
/// Passing an invalid or already freed pointer can result in undefined behavior
pub unsafe fn Z_Free(ptr: *mut u8) {
if ptr.is_null() {
return;
}
let removed = with_registry(|map| map.remove(&(ptr as usize)));
if let Some(meta) = removed {
// Clear the caller's tracking pointer to prevent use-after-free
if !meta.user.is_null() {
unsafe {
*meta.user = std::ptr::null_mut();
}
}
// re-build the vector so Rust can drop it
unsafe {
let _dropped_vec = Vec::from_raw_parts(ptr, meta.size, meta.size);
}
}
}
#[allow(non_snake_case)]
/// Frees all memory allocations between the specific lifetime PU tags.
/// # Safety
/// All pointers tracked within this tag boundary are invalidated and deallocate
pub unsafe fn Z_FreeTags(low_tag: i32, high_tag: i32) {
// get all of the allocations to free
let tags_to_free: Vec<usize> = with_registry(|map| {
map.iter()
.filter(|(_, meta)| meta.tag >= low_tag && meta.tag <= high_tag)
.map(|(ptr_addr,_)| *ptr_addr)
.collect()
});
// remove each pointer returned from the map and drop the memory
for ptr_addr in tags_to_free {
let removed_ptr = with_registry(|map| map.remove(&ptr_addr));
if let Some(meta) = removed_ptr {
let p = ptr_addr as *mut u8;
unsafe {
// clear caller tracking pointer to preven use after free
if !meta.user.is_null() {
*meta.user = std::ptr::null_mut();
}
let _dropped_vec = Vec::from_raw_parts(p, meta.size, meta.size);
}
}
}
}
// Internal ChangeTag function
#[allow(non_snake_case)]
fn Z_ChangeTagInternal(ptr: *mut u8, tag: i32) {
if ptr.is_null() {
return;
}
with_registry(|map| {
if let Some(meta) = map.get_mut(&(ptr as usize)) {
meta.tag = tag;
}
})
}
/// Modifies the lifetime tag of an active allocation.
///
/// # Safety
/// The provided pointer must point to a valid allocation tracked by the registry
#[allow(non_snake_case)]
pub unsafe fn Z_ChangeTag(ptr: *mut u8, tag: i32) {
// removes the original helper macro from the original C, we don't need withcraft here
Z_ChangeTagInternal(ptr, tag);
}