From 993d44c33bfaa3dc08dfd87fcd809df0d8e88f8a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Apr 2023 08:43:00 +0200 Subject: [PATCH 01/38] - deduplication of text content. This mainly maps the item tags to other available text with the same content. --- wadsrc/static/language.def | 44 +++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/language.def b/wadsrc/static/language.def index 0a975ba74..06565402e 100644 --- a/wadsrc/static/language.def +++ b/wadsrc/static/language.def @@ -326,7 +326,9 @@ HE3TEXT = ""; HE4TEXT = ""; HE5TEXT = ""; +// // mappings for duplicate texts +// CNTRLMNU_TITLE = "$$OPTMNU_CONTROLS"; MOUSEMNU_TITLE = "$$OPTMNU_MOUSE"; @@ -337,7 +339,47 @@ OPENALMNU_TITLE = "$$SNDMNU_OPENAL"; SNDMNU_TITLE = "$$OPTMNU_SOUND"; MODMNU_TITLE = "$$SNDMNU_MODREPLAYER"; MISCMNU_TITLE = "$$OPTMNU_MISCELLANEOUS"; - GLMNU_TEXOPT = "$$GLTEXMNU_TITLE"; +SCORE_ITEMS = "$$TXT_IMITEMS"; +SCORE_KILLS = "$$TXT_IMKILLS"; + +FN_ZOMBIE = "$$CC_ZOMBIE"; +FN_IMP = "$$CC_IMP"; +FN_DEMON = "$$CC_DEMON"; +FN_LOST = "$$CC_LOST"; +FN_CACO = "$$CC_CACO"; +FN_HELL = "$$CC_HELL"; +FN_BARON = "$$CC_BARON"; +FN_ARACH = "$$CC_ARACH"; +FN_PAIN = "$$CC_PAIN"; +FN_REVEN = "$$CC_REVEN"; +FN_MANCU = "$$CC_MANCU"; +FN_ARCH = "$$CC_ARCH"; + +TAG_GAUNTLETS = "$$TXT_WPNGAUNTLETS"; +TAG_GAUNTLETSP = "$$TXT_WPNGAUNTLETS"; +TAG_CROSSBOW = "$$TXT_WPNCROSSBOW"; +TAG_CROSSBOWP = "$$TXT_WPNCROSSBOW"; +TAG_STAFFP = "$$TAG_STAFF"; +TAG_GOLDWANDP = "$$TAG_GOLDWAND"; +TAG_BLASTER = "$$TXT_WPNBLASTER"; +TAG_BLASTERP = "$$TXT_WPNBLASTER"; +TAG_SKULLROD = "$$TXT_WPNSKULLROD"; +TAG_SKULLRODP = "$$TXT_WPNSKULLROD"; +TAG_PHOENIXROD = "$$TXT_WPNPHOENIXROD"; +TAG_PHOENIXRODP = "$$TXT_WPNPHOENIXROD"; +TAG_MACE = "$$TXT_WPNMACE"; +TAG_MACEP = "$$TXT_WPNMACE"; + +TAG_ARTIEGG = "$$TXT_ARTIEGG"; +TAG_ARTIFIREBOMB = "$$TXT_ARTIFIREBOMB"; +TAG_ARTIFLY = "$$TXT_ARTIFLY"; +TAG_ARTIHEALTH = "$$TXT_ARTIHEALTH"; +TAG_ARTIINVISIBILITY = "$$TXT_ARTIINVISIBILITY"; +TAG_ARTIINVULNERABILITY = "$$TXT_ARTIINVULNERABILITY"; +TAG_ARTITELEPORT = "$$TXT_ARTITELEPORT; +TAG_ARTITOMEOFPOWER = "$$TXT_ARTITOMEOFPOWER"; +TAG_ARTITORCH = "$$TXT_ARTITORCH"; + From e5fcb331df10d39b0d55cb49600dd4307a0d5c0e Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 30 Apr 2023 10:38:41 -0400 Subject: [PATCH 02/38] - remove `vid_gpuswitch` and all its handling; it is only as of now useful in old unsupported versions of Windows 7/8/10 which are no longer supported --- src/common/platform/win32/hardware.cpp | 34 -------------------------- wadsrc/static/menudef.txt | 11 --------- 2 files changed, 45 deletions(-) diff --git a/src/common/platform/win32/hardware.cpp b/src/common/platform/win32/hardware.cpp index 1933bb521..16123fdd9 100644 --- a/src/common/platform/win32/hardware.cpp +++ b/src/common/platform/win32/hardware.cpp @@ -61,33 +61,6 @@ int currentcanvas = -1; int currentgpuswitch = -1; bool changerenderer; -// Optimus/Hybrid switcher -CUSTOM_CVAR(Int, vid_gpuswitch, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if (self != currentgpuswitch) - { - switch (self) - { - case 0: - Printf("Selecting default GPU...\n"); - break; - case 1: - Printf("Selecting high-performance dedicated GPU...\n"); - break; - case 2: - Printf("Selecting power-saving integrated GPU...\n"); - break; - default: - Printf("Unknown option (%d) - falling back to 'default'\n", *vid_gpuswitch); - self = 0; - break; - } - Printf("You must restart " GAMENAME " for this change to take effect.\n"); - } -} - - - void I_ShutdownGraphics () { if (screen) @@ -102,13 +75,6 @@ void I_ShutdownGraphics () void I_InitGraphics () { - // todo: implement ATI version of this. this only works for nvidia notebooks, for now. - currentgpuswitch = vid_gpuswitch; - if (currentgpuswitch == 1) - _putenv("SHIM_MCCOMPAT=0x800000001"); // discrete - else if (currentgpuswitch == 2) - _putenv("SHIM_MCCOMPAT=0x800000000"); // integrated - // If the focus window is destroyed, it doesn't go back to the active window. // (e.g. because the net pane was up, and a button on it had focus) if (GetFocus() == NULL && GetActiveWindow() == mainwindow.GetHandle()) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index dd5a6d9fc..6af3dc8a0 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -886,13 +886,6 @@ OptionValue VanillaTrans 3.0, "$OPTVAL_VTAVANILLA" } -OptionValue GPUSwitch -{ - 0.0, "$OPTVAL_DEFAULT" - 1.0, "$OPTVAL_DEDICATED" - 2.0, "$OPTVAL_INTEGRATED" -} - OptionValue PreferBackend { 0, "$OPTVAL_OPENGL" @@ -2284,10 +2277,6 @@ OptionMenu VideoModeMenu protected { Option "$VIDMNU_HIDPI", "vid_hidpi", "YesNo" } - IfOption(Windows) - { - Option "$DSPLYMNU_GPUSWITCH", vid_gpuswitch, "GPUSwitch" - } Option "$VIDMNU_FORCEASPECT", "vid_aspect", "ForceRatios" Option "$VIDMNU_CROPASPECT", "vid_cropaspect", "CropAspect" From a5f0174e0780563325509c99d596d451ece48c73 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 30 Apr 2023 10:50:14 -0400 Subject: [PATCH 03/38] - addendum to previous commit: forgot one line --- src/common/platform/win32/hardware.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/platform/win32/hardware.cpp b/src/common/platform/win32/hardware.cpp index 16123fdd9..4aec98da8 100644 --- a/src/common/platform/win32/hardware.cpp +++ b/src/common/platform/win32/hardware.cpp @@ -58,7 +58,6 @@ IVideo *gl_CreateVideo(); void I_RestartRenderer(); int currentcanvas = -1; -int currentgpuswitch = -1; bool changerenderer; void I_ShutdownGraphics () From 39cea95dba2ddf7f367b7425b3acea5cec3c85b2 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 30 Apr 2023 10:54:51 -0400 Subject: [PATCH 04/38] - fix language grammar in `language.def` --- wadsrc/static/language.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/language.def b/wadsrc/static/language.def index 06565402e..43e9afbf1 100644 --- a/wadsrc/static/language.def +++ b/wadsrc/static/language.def @@ -378,7 +378,7 @@ TAG_ARTIFLY = "$$TXT_ARTIFLY"; TAG_ARTIHEALTH = "$$TXT_ARTIHEALTH"; TAG_ARTIINVISIBILITY = "$$TXT_ARTIINVISIBILITY"; TAG_ARTIINVULNERABILITY = "$$TXT_ARTIINVULNERABILITY"; -TAG_ARTITELEPORT = "$$TXT_ARTITELEPORT; +TAG_ARTITELEPORT = "$$TXT_ARTITELEPORT"; TAG_ARTITOMEOFPOWER = "$$TXT_ARTITOMEOFPOWER"; TAG_ARTITORCH = "$$TXT_ARTITORCH"; From 9ca30826db7f919ae29640b965e4dfa0fd20c374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 13 May 2023 18:18:45 -0300 Subject: [PATCH 05/38] Fix win32 mouse cursor permanently disappearing --- src/common/platform/win32/i_mouse.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/common/platform/win32/i_mouse.cpp b/src/common/platform/win32/i_mouse.cpp index 908452916..37ee35709 100644 --- a/src/common/platform/win32/i_mouse.cpp +++ b/src/common/platform/win32/i_mouse.cpp @@ -189,6 +189,8 @@ CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) // //========================================================================== +static bool mouse_shown = true; + static void SetCursorState(bool visible) { CursorState = visible || !m_hidepointer; @@ -196,13 +198,19 @@ static void SetCursorState(bool visible) { if (CursorState) { - ShowCursor(1); - SetCursor((HCURSOR)(intptr_t)GetClassLongPtr(mainwindow.GetHandle(), GCLP_HCURSOR)); + if(!mouse_shown) + { + ShowCursor(true); + mouse_shown = true; + } } else { - ShowCursor(0); - SetCursor(NULL); + if(mouse_shown) + { + ShowCursor(false); + mouse_shown = false; + } } } } From 6f964e8d35ba4463ea2764e24906d2d8e785b5d5 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Sat, 13 May 2023 19:44:50 -0700 Subject: [PATCH 06/38] add changeskill command --- docs/console.html | 6 ++++++ src/console/c_cmds.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/console.html b/docs/console.html index d5ca0a735..7fb5d4c8c 100644 --- a/docs/console.html +++ b/docs/console.html @@ -2361,6 +2361,11 @@ alias -creep "joy_speedmultiplier 1.0" of a music lump or file on disk (which need not have been specified with the -file parameter). +
changeskill skill
+
Changes the current skill of the game. The skill change will take + effect at the next map change. The skill must be a number. The default skill + levels range from 0 to 4 inclusive. +
chase
Turns the chasecom on and off. This command also works while watching demos, so you can bind it to a key and watch demos in the third @@ -3177,6 +3182,7 @@ alias -creep "joy_speedmultiplier 1.0" centerview
changemap
changemus
+ changeskill
chase
chase_dist
chase_height
diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index c5752c9b9..f48dcfa82 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -408,6 +408,39 @@ CCMD (changemap) } } +CCMD (changeskill) +{ + if (!players[consoleplayer].mo || !usergame) + { + Printf ("Use the skill command when not in a game.\n"); + return; + } + + if (!players[consoleplayer].settings_controller && netgame) + { + Printf ("Only setting controllers can change the skill.\n"); + return; + } + + if (argv.argc() == 2) + { + int skill = atoi(argv[1]); + if (skill < 0 || skill >= AllSkills.Size()) + { + Printf ("Skill %d is out of range.\n", skill); + } + else + { + NextSkill = skill; + Printf ("Skill %d will take effect on the next map.\n", skill); + } + } + else + { + Printf ("Usage: changeskill \n"); + } +} + CCMD (give) { if (CheckCheatmode () || argv.argc() < 2) From ca0db39027f7042376e8cc5e6571fc464f3d0eda Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Sat, 13 May 2023 21:39:55 -0700 Subject: [PATCH 07/38] Fix BUILD_SHARED_LIBS build option on Windows This commit fixes the build error "unresolved external symbol GetModuleInformation" when the project is built on Windows with BUILD_SHARED_LIBS enabled. Gzdoom must be linked against "psapi". When BUILD_SHARED_LIBS is off (default), it gets linked because the discord-rpc library is linked against it and then statically linked into the project. The issue is fixed by making Gzdoom itself explicitly link against "psapi" too. --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e05d7c094..cf254ad6a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ if( WIN32 ) add_definitions( -D_WIN32 ) set( PROJECT_LIBRARIES + psapi wsock32 winmm dinput8 From 1589afb46e3ae50a00886ad20f8a8d85802f63fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 13 May 2023 20:30:42 -0300 Subject: [PATCH 08/38] Add Voodoo Zombie Compatflag --- src/d_main.cpp | 2 +- src/doomdef.h | 1 + src/gamedata/g_mapinfo.cpp | 1 + src/maploader/compatibility.cpp | 1 + src/playsim/p_interaction.cpp | 17 +++++++-- wadsrc/static/zscript/actors/player/player.zs | 35 +++++++++++++++++-- wadsrc/static/zscript/constants.zs | 1 + 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 31e1568ba..6e88286c8 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -625,7 +625,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_TRACE | COMPATF_MISSILECLIP | COMPATF_SOUNDTARGET | COMPATF_NO_PASSMOBJ | COMPATF_LIMITPAIN | COMPATF_DEHHEALTH | COMPATF_INVISIBILITY | COMPATF_CROSSDROPOFF | COMPATF_VILEGHOSTS | COMPATF_HITSCAN | COMPATF_WALLRUN | COMPATF_NOTOSSDROPS | COMPATF_LIGHT | COMPATF_MASKEDMIDTEX; - w = COMPATF2_BADANGLES | COMPATF2_FLOORMOVE | COMPATF2_POINTONLINE | COMPATF2_EXPLODE2 | COMPATF2_NOMBF21; + w = COMPATF2_BADANGLES | COMPATF2_FLOORMOVE | COMPATF2_POINTONLINE | COMPATF2_EXPLODE2 | COMPATF2_NOMBF21 | COMPATF2_VOODOO_ZOMBIES; break; case 3: // Boom compat mode diff --git a/src/doomdef.h b/src/doomdef.h index 8dd96ea70..bdeb81611 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -233,6 +233,7 @@ enum : unsigned int COMPATF2_AVOID_HAZARDS = 1 << 12, // another MBF thing. COMPATF2_STAYONLIFT = 1 << 13, // yet another MBF thing. COMPATF2_NOMBF21 = 1 << 14, // disable MBF21 features that may clash with certain maps + COMPATF2_VOODOO_ZOMBIES = 1 << 15, // [RL0] allow playerinfo, playerpawn, and voodoo health to all be different, and skip killing the player's mobj if a voodoo doll dies to allow voodoo zombies }; diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index b87036be7..a5b0bfb1c 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -1842,6 +1842,7 @@ MapFlagHandlers[] = { "compat_avoidhazards", MITYPE_COMPATFLAG, 0, COMPATF2_AVOID_HAZARDS }, { "compat_stayonlift", MITYPE_COMPATFLAG, 0, COMPATF2_STAYONLIFT }, { "compat_nombf21", MITYPE_COMPATFLAG, 0, COMPATF2_NOMBF21 }, + { "compat_voodoozombies", MITYPE_COMPATFLAG, 0, COMPATF2_VOODOO_ZOMBIES }, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index a9d9ca0e5..2a0fa0749 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -171,6 +171,7 @@ static FCompatOption Options[] = { "railing", COMPATF2_RAILING, SLOT_COMPAT2 }, { "scriptwait", COMPATF2_SCRIPTWAIT, SLOT_COMPAT2 }, { "nombf21", COMPATF2_NOMBF21, SLOT_COMPAT2 }, + { "voodoozombies", COMPATF2_VOODOO_ZOMBIES, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/playsim/p_interaction.cpp b/src/playsim/p_interaction.cpp index 2c89e3cc1..4baac07a4 100644 --- a/src/playsim/p_interaction.cpp +++ b/src/playsim/p_interaction.cpp @@ -1335,13 +1335,24 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da } } + bool compat_voodoo_zombie = target->Level->i_compatflags2 & COMPATF2_VOODOO_ZOMBIES; + player->health -= damage; // mirror mobj health here for Dave - // [RH] Make voodoo dolls and real players record the same health - target->health = player->mo->health -= damage; + if(compat_voodoo_zombie) + { // [RL0] To allow voodoo zombies, don't set the voodoo doll to the player mobj's health and don't change the player mobj's health on damage + target->health -= damage; + } + else + { // [RH] Make voodoo dolls and real players record the same health + target->health = player->mo->health -= damage; + } if (player->health < 50 && !deathmatch && !(flags & DMG_FORCED)) { P_AutoUseStrifeHealth (player); - player->mo->health = player->health; + if(!compat_voodoo_zombie) + { // [RL0] To match vanilla behavior, don't set the player mo's health to 0 if voodoo zombies compat is enabled + player->mo->health = player->health; + } } if (player->health <= 0) { diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index 7039f9436..5f6d0f616 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -85,6 +85,11 @@ class PlayerPawn : Actor flagdef CanSuperMorph: PlayerFlags, 1; flagdef CrouchableMorph: PlayerFlags, 2; flagdef WeaponLevel2Ended: PlayerFlags, 3; + + enum EPrivatePlayerFlags + { + PF_VOODOO_ZOMBIE = 1<<4, + } Default { @@ -777,14 +782,16 @@ class PlayerPawn : Actor Super.Die (source, inflictor, dmgflags, MeansOfDeath); if (player != NULL && player.mo == self) player.bonuscount = 0; - - if (player != NULL && player.mo != self) + + // [RL0] To allow voodoo zombies, don't kill the player together with voodoo dolls if the compat flag is enabled + if (player != NULL && player.mo != self && !(Level.compatflags2 & COMPATF2_VOODOO_ZOMBIES)) { // Make the real player die, too player.mo.Die (source, inflictor, dmgflags, MeansOfDeath); } else { - if (player != NULL && sv_weapondrop) + // [RL0] player.mo == self will always be true if COMPATF2_VOODOO_ZOMBIES is false, so there's no need to check the compatflag here too, just self + if (player != NULL && sv_weapondrop && player.mo == self) { // Voodoo dolls don't drop weapons let weap = player.ReadyWeapon; if (weap != NULL) @@ -1609,6 +1616,12 @@ class PlayerPawn : Actor { let player = self.player; UserCmd cmd = player.cmd; + + // [RL0] Mark players that became zombies (this stays even if they 'revive' by healing, until a level change) + if((Level.compatflags2 & COMPATF2_VOODOO_ZOMBIES) && player.health <= 0 && player.mo.health > 0) + { + PlayerFlags |= PF_VOODOO_ZOMBIE; + } CheckFOV(); @@ -1692,6 +1705,9 @@ class PlayerPawn : Actor void BringUpWeapon () { + // [RL0] Don't bring up weapon when in a voodoo zombie state + if(PlayerFlags & PF_VOODOO_ZOMBIE) return; + let player = self.player; if (player.PendingWeapon == WP_NOCHANGE) { @@ -2007,6 +2023,19 @@ class PlayerPawn : Actor void PlayerFinishLevel (int mode, int flags) { + // [RL0] Handle player exit behavior for voodoo zombies + if(PlayerFlags & PF_VOODOO_ZOMBIE) + { + if(player.health > 0) + { + PlayerFlags &= ~PF_VOODOO_ZOMBIE; + } + else + { + bShootable = false; + bKilled = true; + } + } Inventory item, next; let p = player; diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 66426a125..8e31a68ea 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -1429,6 +1429,7 @@ enum ECompatFlags COMPATF2_EXPLODE1 = 1 << 8, // No vertical explosion thrust COMPATF2_EXPLODE2 = 1 << 9, // Use original explosion code throughout. COMPATF2_RAILING = 1 << 10, // Bugged Strife railings. + COMPATF2_VOODOO_ZOMBIES = 1 << 15, // allow playerinfo, playerpawn, and voodoo health to all be different, and allow monster targetting of 'dead' players that have positive health }; const M_E = 2.7182818284590452354; // e From 677b08406405693ab53c281c4d71c19b9b078030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 14 May 2023 02:41:11 -0300 Subject: [PATCH 09/38] Fill in ECompatFlags --- wadsrc/static/zscript/constants.zs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 8e31a68ea..fe44f2c3d 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -1429,6 +1429,10 @@ enum ECompatFlags COMPATF2_EXPLODE1 = 1 << 8, // No vertical explosion thrust COMPATF2_EXPLODE2 = 1 << 9, // Use original explosion code throughout. COMPATF2_RAILING = 1 << 10, // Bugged Strife railings. + COMPATF2_SCRIPTWAIT = 1 << 11, // Use old scriptwait implementation where it doesn't wait on a non-running script. + COMPATF2_AVOID_HAZARDS = 1 << 12, // another MBF thing. + COMPATF2_STAYONLIFT = 1 << 13, // yet another MBF thing. + COMPATF2_NOMBF21 = 1 << 14, // disable MBF21 features that may clash with certain maps COMPATF2_VOODOO_ZOMBIES = 1 << 15, // allow playerinfo, playerpawn, and voodoo health to all be different, and allow monster targetting of 'dead' players that have positive health }; From acfe82b9a832f84a30b93a14172aead7307be1fe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 May 2023 09:31:17 +0200 Subject: [PATCH 10/38] - Backend update from Raze. --- src/common/2d/v_2ddrawer.h | 2 +- src/common/2d/v_draw.cpp | 6 +++--- src/common/audio/sound/i_soundinternal.h | 1 + src/common/audio/sound/s_sound.cpp | 2 +- src/common/audio/sound/s_soundinternal.h | 6 +++--- src/common/cutscenes/playmve.cpp | 2 +- src/common/engine/namedef.h | 1 + src/common/engine/sc_man_scanner.re | 1 + src/common/fonts/singlepicfont.cpp | 8 ++++---- src/common/fonts/v_font.cpp | 6 +++--- src/common/rendering/gl/gl_framebuffer.cpp | 1 - src/common/rendering/gles/gles_framebuffer.cpp | 1 - src/common/rendering/vulkan/system/vk_renderdevice.cpp | 1 - src/common/scripting/frontend/zcc-parse.lemon | 7 +++++++ src/common/scripting/vm/vm.h | 7 +++++++ src/common/textures/textureid.h | 6 +++--- src/common/textures/texturemanager.cpp | 4 ++-- src/common/textures/texturemanager.h | 2 +- src/common/textures/v_collection.cpp | 4 ++-- src/common/utility/files.h | 2 +- src/common/utility/tarray.h | 5 +++-- 21 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/common/2d/v_2ddrawer.h b/src/common/2d/v_2ddrawer.h index 7203ca3c1..fc2970b15 100644 --- a/src/common/2d/v_2ddrawer.h +++ b/src/common/2d/v_2ddrawer.h @@ -217,7 +217,7 @@ public: double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double lightlevel, uint32_t *indices, size_t indexcount); void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, const unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, const IntRect* clip); - void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex, + void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int pic, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex, int clipx1, int clipy1, int clipx2, int clipy2); void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0, PalEntry color = 0xffffffff, ERenderStyle rs = STYLE_Normal); diff --git a/src/common/2d/v_draw.cpp b/src/common/2d/v_draw.cpp index 7c1beb0c8..85ed31517 100644 --- a/src/common/2d/v_draw.cpp +++ b/src/common/2d/v_draw.cpp @@ -1786,12 +1786,12 @@ DEFINE_ACTION_FUNCTION(FCanvas, Dim) // //========================================================================== -void DrawBorder (F2DDrawer *drawer, FTextureID picnum, int x1, int y1, int x2, int y2) +void DrawBorder (F2DDrawer *drawer, FTextureID texid, int x1, int y1, int x2, int y2) { int filltype = (ui_screenborder_classic_scaling) ? -1 : 0; - if (picnum.isValid()) + if (texid.isValid()) { - drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(picnum, false), filltype); + drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(texid, false), filltype); } else { diff --git a/src/common/audio/sound/i_soundinternal.h b/src/common/audio/sound/i_soundinternal.h index 1ef4178d4..4787aa12a 100644 --- a/src/common/audio/sound/i_soundinternal.h +++ b/src/common/audio/sound/i_soundinternal.h @@ -32,6 +32,7 @@ enum EChanFlag CHANF_LOCAL = 16384, // only plays locally for the calling actor CHANF_TRANSIENT = 32768, // Do not record in savegames - used for sounds that get restarted outside the sound system (e.g. ambients in SW and Blood) CHANF_FORCE = 65536, // Start, even if sound is paused. + CHANF_SINGULAR = 0x20000, // Only start if no sound of this name is already playing. }; typedef TFlags EChanFlags; diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index f3b0fb412..2544d1f87 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -488,7 +488,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, } // If this is a singular sound, don't play it if it's already playing. - if (sfx->bSingular && CheckSingular(sound_id)) + if ((sfx->bSingular || (flags & CHANF_SINGULAR)) && CheckSingular(sound_id)) { chanflags |= CHANF_EVICTED; } diff --git a/src/common/audio/sound/s_soundinternal.h b/src/common/audio/sound/s_soundinternal.h index dae8a0ee2..782fbe325 100644 --- a/src/common/audio/sound/s_soundinternal.h +++ b/src/common/audio/sound/s_soundinternal.h @@ -90,6 +90,7 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1); float DefPitchMax = 0.f; // Randomized range with stronger control over pitch itself. int16_t NearLimit = 4; // 0 means unlimited. + int16_t UserVal = 0; // repurpose this gap for something useful uint8_t PitchMask = 0; bool bRandomHeader = false; bool bLoadRAW = false; @@ -99,17 +100,16 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1); bool bTentative = true; bool bExternal = false; - TArray UserData; - int RawRate = 0; // Sample rate to use when bLoadRAW is true int LoopStart = -1; // -1 means no specific loop defined int LoopEnd = -1; // -1 means no specific loop defined + float Attenuation = 1.f; // Multiplies the attenuation passed to S_Sound. FSoundID link = NO_LINK; constexpr static FSoundID NO_LINK = FSoundID::fromInt(-1); + TArray UserData; FRolloffInfo Rolloff{}; - float Attenuation = 1.f; // Multiplies the attenuation passed to S_Sound. }; diff --git a/src/common/cutscenes/playmve.cpp b/src/common/cutscenes/playmve.cpp index 70b56b43a..3c49e9610 100644 --- a/src/common/cutscenes/playmve.cpp +++ b/src/common/cutscenes/playmve.cpp @@ -546,7 +546,7 @@ bool InterplayDecoder::Open(FileReader &fr_) int chunkType = LE_16(&chunkPreamble[2]); if (chunkType == CHUNK_VIDEO) bAudioEnabled = false; - else + else if (bAudioEnabled) { if (ProcessNextChunk() != CHUNK_INIT_AUDIO) { diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 92fa6fa34..2571cb315 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -270,3 +270,4 @@ xx(BuiltinNameToClass) xx(BuiltinClassCast) xx(ScreenJobRunner) +xx(Action) diff --git a/src/common/engine/sc_man_scanner.re b/src/common/engine/sc_man_scanner.re index 59c3c7712..b5cce6d09 100644 --- a/src/common/engine/sc_man_scanner.re +++ b/src/common/engine/sc_man_scanner.re @@ -220,6 +220,7 @@ std2: 'bright' { RET(StateOptions ? TK_Bright : TK_Identifier); } 'fast' { RET(StateOptions ? TK_Fast : TK_Identifier); } 'slow' { RET(StateOptions ? TK_Slow : TK_Identifier); } + 'ticadjust' { RET(StateOptions ? TK_NoDelay : TK_Identifier); } 'nodelay' { RET(StateOptions ? TK_NoDelay : TK_Identifier); } 'canraise' { RET(StateOptions ? TK_CanRaise : TK_Identifier); } 'offset' { RET(StateOptions ? TK_Offset : TK_Identifier); } diff --git a/src/common/fonts/singlepicfont.cpp b/src/common/fonts/singlepicfont.cpp index 687602876..30fdf8711 100644 --- a/src/common/fonts/singlepicfont.cpp +++ b/src/common/fonts/singlepicfont.cpp @@ -65,21 +65,21 @@ protected: FSinglePicFont::FSinglePicFont(const char *picname) : FFont(-1) // Since lump is only needed for priority information we don't need to worry about this here. { - FTextureID picnum = TexMan.CheckForTexture (picname, ETextureType::Any); + FTextureID texid = TexMan.CheckForTexture (picname, ETextureType::Any); - if (!picnum.isValid()) + if (!texid.isValid()) { I_FatalError ("%s is not a font or texture", picname); } - auto pic = TexMan.GetGameTexture(picnum); + auto pic = TexMan.GetGameTexture(texid); FontName = picname; FontHeight = (int)pic->GetDisplayHeight(); SpaceWidth = (int)pic->GetDisplayWidth(); GlobalKerning = 0; FirstChar = LastChar = 'A'; - PicNum = picnum; + PicNum = texid; } //========================================================================== diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index f51813aeb..cb206a4ec 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -138,10 +138,10 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) return font; } } - FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any); - if (picnum.isValid()) + FTextureID texid = TexMan.CheckForTexture (name, ETextureType::Any); + if (texid.isValid()) { - auto tex = TexMan.GetGameTexture(picnum); + auto tex = TexMan.GetGameTexture(texid); if (tex && tex->GetSourceLump() >= folderfile) { FFont *CreateSinglePicFont(const char *name); diff --git a/src/common/rendering/gl/gl_framebuffer.cpp b/src/common/rendering/gl/gl_framebuffer.cpp index 6ea31e5bd..4b20db68f 100644 --- a/src/common/rendering/gl/gl_framebuffer.cpp +++ b/src/common/rendering/gl/gl_framebuffer.cpp @@ -63,7 +63,6 @@ #include "hw_cvars.h" EXTERN_CVAR (Bool, vid_vsync) -EXTERN_CVAR(Bool, r_drawvoxels) EXTERN_CVAR(Int, gl_tonemap) EXTERN_CVAR(Bool, cl_capfps) EXTERN_CVAR(Int, gl_pipeline_depth); diff --git a/src/common/rendering/gles/gles_framebuffer.cpp b/src/common/rendering/gles/gles_framebuffer.cpp index 0d0a459c0..bbade7896 100644 --- a/src/common/rendering/gles/gles_framebuffer.cpp +++ b/src/common/rendering/gles/gles_framebuffer.cpp @@ -61,7 +61,6 @@ #include "hw_cvars.h" EXTERN_CVAR (Bool, vid_vsync) -EXTERN_CVAR(Bool, r_drawvoxels) EXTERN_CVAR(Int, gl_tonemap) EXTERN_CVAR(Bool, cl_capfps) EXTERN_CVAR(Int, gl_pipeline_depth); diff --git a/src/common/rendering/vulkan/system/vk_renderdevice.cpp b/src/common/rendering/vulkan/system/vk_renderdevice.cpp index 8f4f1b737..7ef3e5531 100644 --- a/src/common/rendering/vulkan/system/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/system/vk_renderdevice.cpp @@ -68,7 +68,6 @@ FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames, int maxFrames = -1); -EXTERN_CVAR(Bool, r_drawvoxels) EXTERN_CVAR(Int, gl_tonemap) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, cl_capfps) diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index 1a9146f37..71385c582 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -272,6 +272,13 @@ dottable_id(X) ::= IDENTIFIER(A). id->Id = A.Name(); X = id; } +// this is needed for defining properties named 'action'. +dottable_id(X) ::= ACTION(A). +{ + NEW_AST_NODE(Identifier,id,A); + id->Id = NAME_Action; + X = id; +} dottable_id(X) ::= dottable_id(A) DOT IDENTIFIER(B). { NEW_AST_NODE(Identifier,id2,A); diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 3766e9d31..01e98fb61 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -194,6 +194,12 @@ struct VMReturn *(void **)Location = val; } + void SetConstPointer(const void *val) + { + assert(RegType == REGT_POINTER); + *(const void **)Location = val; + } + void SetObject(DObject *val) { assert(RegType == REGT_POINTER); @@ -759,6 +765,7 @@ struct AFuncDesc class AActor; #define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0) +#define ACTION_RETURN_CONST_POINTER(v) do { const void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetConstPointer(state); return 1; } return 0; } while(0) #define ACTION_RETURN_POINTER(v) do { void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0) #define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetObject(state); return 1; } return 0; } while(0) #define ACTION_RETURN_FLOAT(v) do { double u = v; if (numret > 0) { assert(ret != nullptr); ret->SetFloat(u); return 1; } return 0; } while(0) diff --git a/src/common/textures/textureid.h b/src/common/textures/textureid.h index e30b4e86a..c441cb9d5 100644 --- a/src/common/textures/textureid.h +++ b/src/common/textures/textureid.h @@ -45,7 +45,7 @@ public: bool operator > (FTextureID other) const { return texnum > other.texnum; } protected: - FTextureID(int num) { texnum = num; } + constexpr FTextureID(int num) : texnum(num) { } private: int texnum; }; @@ -53,13 +53,13 @@ private: class FNullTextureID : public FTextureID { public: - FNullTextureID() : FTextureID(0) {} + constexpr FNullTextureID() : FTextureID(0) {} }; // This is for the script interface which needs to do casts from int to texture. class FSetTextureID : public FTextureID { public: - FSetTextureID(int v) : FTextureID(v) {} + constexpr FSetTextureID(int v) : FTextureID(v) {} }; diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 94aa40de1..988498408 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -498,9 +498,9 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype) // //========================================================================== -void FTextureManager::ReplaceTexture (FTextureID picnum, FGameTexture *newtexture, bool free) +void FTextureManager::ReplaceTexture (FTextureID texid, FGameTexture *newtexture, bool free) { - int index = picnum.GetIndex(); + int index = texid.GetIndex(); if (unsigned(index) >= Textures.Size()) return; diff --git a/src/common/textures/texturemanager.h b/src/common/textures/texturemanager.h index 575e838ea..3f80514f3 100644 --- a/src/common/textures/texturemanager.h +++ b/src/common/textures/texturemanager.h @@ -137,7 +137,7 @@ public: void AddTextures(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo&), void (*customtexturehandler)() = nullptr); void DeleteAll(); - void ReplaceTexture (FTextureID picnum, FGameTexture *newtexture, bool free); + void ReplaceTexture (FTextureID texid, FGameTexture *newtexture, bool free); int NumTextures () const { return (int)Textures.Size(); } diff --git a/src/common/textures/v_collection.cpp b/src/common/textures/v_collection.cpp index 2b51885bf..975287680 100644 --- a/src/common/textures/v_collection.cpp +++ b/src/common/textures/v_collection.cpp @@ -62,8 +62,8 @@ void FImageCollection::Add (const char **patchNames, int numPatches, ETextureTyp for (int i = 0; i < numPatches; ++i) { - FTextureID picnum = TexMan.CheckForTexture(patchNames[i], namespc); - ImageMap[OldCount + i] = picnum; + FTextureID texid = TexMan.CheckForTexture(patchNames[i], namespc); + ImageMap[OldCount + i] = texid; } } diff --git a/src/common/utility/files.h b/src/common/utility/files.h index 66fa9a354..24d66e1d7 100644 --- a/src/common/utility/files.h +++ b/src/common/utility/files.h @@ -184,7 +184,7 @@ public: return mReader->Seek((long)offset, origin); } - Size Read(void *buffer, Size len) + Size Read(void *buffer, Size len) const { return mReader->Read(buffer, (long)len); } diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index 29d62289c..a21226095 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -327,9 +327,10 @@ public: } // returns address of first element - T *Data() const + T *Data(size_t index = 0) const { - return &Array[0]; + assert(index <= Count); + return &Array[index]; } unsigned IndexOf(const T& elem) const From 245dac814ee84bcb1403a0c95f6a1f0a6d0c2734 Mon Sep 17 00:00:00 2001 From: l2ksolkov Date: Sun, 28 May 2023 20:29:24 -0700 Subject: [PATCH 11/38] Add missing include guards --- src/common/console/c_commandbuffer.h | 1 + src/common/console/c_consolebuffer.h | 1 + src/common/engine/serializer_internal.h | 1 + src/common/filesystem/ancientzip.h | 1 + src/common/platform/win32/winres.h | 1 + src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h | 2 +- src/common/scripting/jit/jitintern.h | 2 +- src/common/textures/animlib.h | 1 + src/common/textures/hires/hqnx_asm/hqnx_asm_Image.h | 1 + src/common/utility/weightedlist.h | 1 + src/d_defcvars.h | 1 + src/g_pch.h | 1 + src/g_pch2.h | 1 + src/gamedata/doomfont.h | 1 + src/r_data/r_vanillatrans.h | 1 + src/rendering/hwrenderer/hw_vertexbuilder.h | 2 +- src/rendering/swrenderer/textures/warpbuffer.h | 1 + 17 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/common/console/c_commandbuffer.h b/src/common/console/c_commandbuffer.h index 179651c45..637027b27 100644 --- a/src/common/console/c_commandbuffer.h +++ b/src/common/console/c_commandbuffer.h @@ -1,3 +1,4 @@ +#pragma once #include #include "zstring.h" diff --git a/src/common/console/c_consolebuffer.h b/src/common/console/c_consolebuffer.h index 58bc0edea..8d4e235d5 100644 --- a/src/common/console/c_consolebuffer.h +++ b/src/common/console/c_consolebuffer.h @@ -32,6 +32,7 @@ **--------------------------------------------------------------------------- ** */ +#pragma once #include #include diff --git a/src/common/engine/serializer_internal.h b/src/common/engine/serializer_internal.h index 31cf76c1a..05b6dcad0 100644 --- a/src/common/engine/serializer_internal.h +++ b/src/common/engine/serializer_internal.h @@ -1,3 +1,4 @@ +#pragma once const char* UnicodeToString(const char* cc); const char* StringToUnicode(const char* cc, int size = -1); diff --git a/src/common/filesystem/ancientzip.h b/src/common/filesystem/ancientzip.h index 621505504..6241f775d 100644 --- a/src/common/filesystem/ancientzip.h +++ b/src/common/filesystem/ancientzip.h @@ -1,3 +1,4 @@ +#pragma once #include "files.h" #include "engineerrors.h" diff --git a/src/common/platform/win32/winres.h b/src/common/platform/win32/winres.h index 6d78230d8..a2b8711a6 100644 --- a/src/common/platform/win32/winres.h +++ b/src/common/platform/win32/winres.h @@ -10,6 +10,7 @@ // winres.h - Windows resource definitions // extracted from WINUSER.H and COMMCTRL.H +#pragma once #ifdef _AFX_MINREBUILD #pragma component(minrebuild, off) diff --git a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h index f52af7ebc..8efe61738 100644 --- a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h +++ b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h @@ -1,4 +1,4 @@ - +#pragma once #include "tarray.h" #include "hwrenderer/data/buffers.h" diff --git a/src/common/scripting/jit/jitintern.h b/src/common/scripting/jit/jitintern.h index aaf8d70a6..05dfd62df 100644 --- a/src/common/scripting/jit/jitintern.h +++ b/src/common/scripting/jit/jitintern.h @@ -1,4 +1,4 @@ - +#pragma once #include "jit.h" #include "types.h" diff --git a/src/common/textures/animlib.h b/src/common/textures/animlib.h index 23d0d89da..661f00fb2 100644 --- a/src/common/textures/animlib.h +++ b/src/common/textures/animlib.h @@ -24,6 +24,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) */ //------------------------------------------------------------------------- +#pragma once #include ///////////////////////////////////////////////////////////////////////////// diff --git a/src/common/textures/hires/hqnx_asm/hqnx_asm_Image.h b/src/common/textures/hires/hqnx_asm/hqnx_asm_Image.h index 918b904fe..6e2a93108 100644 --- a/src/common/textures/hires/hqnx_asm/hqnx_asm_Image.h +++ b/src/common/textures/hires/hqnx_asm/hqnx_asm_Image.h @@ -19,6 +19,7 @@ //#ifdef WIN32 //#define DLL __declspec(dllexport) //#else +#pragma once #define DLL //#endif diff --git a/src/common/utility/weightedlist.h b/src/common/utility/weightedlist.h index cd6a4ba0e..fb956a462 100644 --- a/src/common/utility/weightedlist.h +++ b/src/common/utility/weightedlist.h @@ -31,6 +31,7 @@ **--------------------------------------------------------------------------- ** */ +#pragma once #include #include diff --git a/src/d_defcvars.h b/src/d_defcvars.h index 73f110c70..8bf3d7c18 100644 --- a/src/d_defcvars.h +++ b/src/d_defcvars.h @@ -19,6 +19,7 @@ // defcvars loader split from d_main.cpp // //----------------------------------------------------------------------------- +#pragma once #define SHOULD_BLACKLIST(name) \ if (#name[0]==CurrentFindCVar[0]) \ diff --git a/src/g_pch.h b/src/g_pch.h index bad3eda56..cf3dfdbd5 100644 --- a/src/g_pch.h +++ b/src/g_pch.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/src/g_pch2.h b/src/g_pch2.h index 4cd69197e..f5871488a 100644 --- a/src/g_pch2.h +++ b/src/g_pch2.h @@ -1,4 +1,5 @@ // This is separate because the files being compiled with it use different compiler settings which may affect how the header is compiled +#pragma once #include #include #include diff --git a/src/gamedata/doomfont.h b/src/gamedata/doomfont.h index 9b44a480f..b9d14db7d 100644 --- a/src/gamedata/doomfont.h +++ b/src/gamedata/doomfont.h @@ -1,6 +1,7 @@ // // Globally visible constants. // +#pragma once #define HU_FONTSTART uint8_t('!') // the first font characters #define HU_FONTEND uint8_t('\377') // the last font characters diff --git a/src/r_data/r_vanillatrans.h b/src/r_data/r_vanillatrans.h index 702fc8212..d6b6a5d9e 100644 --- a/src/r_data/r_vanillatrans.h +++ b/src/r_data/r_vanillatrans.h @@ -30,6 +30,7 @@ **--------------------------------------------------------------------------- ** */ +#pragma once void UpdateVanillaTransparency(); diff --git a/src/rendering/hwrenderer/hw_vertexbuilder.h b/src/rendering/hwrenderer/hw_vertexbuilder.h index 4fbe9916f..0444613be 100644 --- a/src/rendering/hwrenderer/hw_vertexbuilder.h +++ b/src/rendering/hwrenderer/hw_vertexbuilder.h @@ -1,4 +1,4 @@ - +#pragma once #include "tarray.h" #include "r_defs.h" struct vertex_t; diff --git a/src/rendering/swrenderer/textures/warpbuffer.h b/src/rendering/swrenderer/textures/warpbuffer.h index 778706850..594903a53 100644 --- a/src/rendering/swrenderer/textures/warpbuffer.h +++ b/src/rendering/swrenderer/textures/warpbuffer.h @@ -31,6 +31,7 @@ **--------------------------------------------------------------------------- ** */ +#pragma once #include "textures.h" #include "texturemanager.h" From 170cc8d7bacb65ae7694ed4639f8ed9fccdb4448 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 11 Jun 2023 12:14:35 +0300 Subject: [PATCH 12/38] - reduced string duplication in macOS detection --- src/common/platform/posix/cocoa/i_main.mm | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 3e257a5ce..2b6a23f0d 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -151,21 +151,21 @@ void I_DetectOS() case 10: switch (version.minorVersion) { - case 12: name = "macOS Sierra"; break; - case 13: name = "macOS High Sierra"; break; - case 14: name = "macOS Mojave"; break; - case 15: name = "macOS Catalina"; break; - case 16: name = "macOS Big Sur"; break; + case 12: name = "Sierra"; break; + case 13: name = "High Sierra"; break; + case 14: name = "Mojave"; break; + case 15: name = "Catalina"; break; + case 16: name = "Big Sur"; break; } break; case 11: - name = "macOS Big Sur"; + name = "Big Sur"; break; case 12: - name = "macOS Monterey"; + name = "Monterey"; break; case 13: - name = "macOS Ventura"; + name = "Ventura"; break; } @@ -186,7 +186,7 @@ void I_DetectOS() "Unknown"; #endif - Printf("%s running %s %d.%d.%d (%s) %s\n", model, name, + Printf("%s running macOS %s %d.%d.%d (%s) %s\n", model, name, int(version.majorVersion), int(version.minorVersion), int(version.patchVersion), release, architecture); } From 3ddf72104bf14519fb3df3eef7d5eb328525c160 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 11 Jun 2023 12:14:58 +0300 Subject: [PATCH 13/38] - added detection of macOS 14 --- src/common/platform/posix/cocoa/i_main.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 2b6a23f0d..8a9d96b07 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -167,6 +167,9 @@ void I_DetectOS() case 13: name = "Ventura"; break; + case 14: + name = "Sonoma"; + break; } char release[16] = "unknown"; From 40679294df8a4a1c68829aa9b7b7661ba96e5110 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 16 Jun 2023 20:50:04 +0200 Subject: [PATCH 14/38] - fixed some warnings. --- src/common/engine/palettecontainer.cpp | 2 +- src/common/engine/palettecontainer.h | 2 +- src/common/utility/vectors.h | 2 +- src/console/c_cmds.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/engine/palettecontainer.cpp b/src/common/engine/palettecontainer.cpp index 9648f2528..800dc31c6 100644 --- a/src/common/engine/palettecontainer.cpp +++ b/src/common/engine/palettecontainer.cpp @@ -367,7 +367,7 @@ static bool IndexOutOfRange(const int start1, const int end1, const int start2, // //---------------------------------------------------------------------------- -bool FRemapTable::operator==(const FRemapTable& o) +bool FRemapTable::operator==(const FRemapTable& o) const { // Two translations are identical when they have the same amount of colors // and the palette values for both are identical. diff --git a/src/common/engine/palettecontainer.h b/src/common/engine/palettecontainer.h index e1d0befd3..a220873a6 100644 --- a/src/common/engine/palettecontainer.h +++ b/src/common/engine/palettecontainer.h @@ -19,7 +19,7 @@ struct FRemapTable FRemapTable(const FRemapTable& o) = default; FRemapTable& operator=(const FRemapTable& o) = default; - bool operator==(const FRemapTable& o); + bool operator==(const FRemapTable& o) const; void MakeIdentity(); bool IsIdentity() const; bool AddIndexRange(int start, int end, int pal1, int pal2); diff --git a/src/common/utility/vectors.h b/src/common/utility/vectors.h index 140c310f0..f392f561f 100644 --- a/src/common/utility/vectors.h +++ b/src/common/utility/vectors.h @@ -561,7 +561,7 @@ struct TVector3 void GetRightUp(TVector3 &right, TVector3 &up) { TVector3 n(X, Y, Z); - TVector3 fn(fabs(n.X), fabs(n.Y), fabs(n.Z)); + TVector3 fn((vec_t)fabs(n.X), (vec_t)fabs(n.Y), (vec_t)fabs(n.Z)); int major = 0; if (fn[1] > fn[major]) major = 1; diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index f48dcfa82..6e21cfcc2 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -425,7 +425,7 @@ CCMD (changeskill) if (argv.argc() == 2) { int skill = atoi(argv[1]); - if (skill < 0 || skill >= AllSkills.Size()) + if ((unsigned)skill >= AllSkills.Size()) { Printf ("Skill %d is out of range.\n", skill); } From 62b9243142ba51f1dd31d8d7b3bcb4afa2296983 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 15 Jun 2023 23:13:11 +0200 Subject: [PATCH 15/38] - made some changes to vectors.h so that it can be used without the floating point function replacements. Using __has_include and providing fallback implementations. --- .../vulkan/renderer/vk_renderpass.cpp | 1 + src/common/utility/vectors.h | 32 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp index 257f35c16..e445723d0 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp @@ -35,6 +35,7 @@ #include "hw_viewpointuniforms.h" #include "v_2ddrawer.h" #include "i_specialpaths.h" +#include "cmdlib.h" VkRenderPassManager::VkRenderPassManager(VulkanRenderDevice* fb) : fb(fb) { diff --git a/src/common/utility/vectors.h b/src/common/utility/vectors.h index f392f561f..ea5cb5250 100644 --- a/src/common/utility/vectors.h +++ b/src/common/utility/vectors.h @@ -44,23 +44,32 @@ #include #include #include + +// this is needed to properly normalize angles. We cannot do that with compiler provided conversions because they differ too much #include "xs_Float.h" -#include "math/cmath.h" -#include "basics.h" -#include "cmdlib.h" - - -#define EQUAL_EPSILON (1/65536.) // make this a local inline function to avoid any dependencies on other headers and not pollute the global namespace namespace pi { inline constexpr double pi() { return 3.14159265358979323846; } - inline constexpr double pif() { return 3.14159265358979323846f; } + inline constexpr float pif() { return 3.14159265358979323846f; } } +// optionally use reliable math routines if reproducability across hardware is important., but let this still compile without them. +#if __has_include("math/cmath.h") +#include "math/cmath.h" +#else +double g_cosdeg(double v) { return cos(v * (pi::pi() / 180.)); } +double g_sindeg(double v) { return sin(v * (pi::pi() / 180.)); } +double g_cos(double v) { return cos(v); } +double g_sin(double v) { return sin(v); } +double g_sqrt(double v) { return sqrt(v); } +double g_atan2(double v, double w) { return atan2(v, w); } +#endif +#define EQUAL_EPSILON (1/65536.) + template struct TVector3; template struct TRotator; template struct TAngle; @@ -1450,8 +1459,13 @@ public: double Tan() const { + // use an optimized approach if we have a sine table. If not just call the CRT's tan function. +#if __has_include("math/cmath.h") const auto bam = BAMs(); return g_sinbam(bam) / g_cosbam(bam); +#else + return vec_t(tan(Radians())); +#endif } // This is for calculating vertical velocity. For high pitches the tangent will become too large to be useful. @@ -1460,9 +1474,11 @@ public: return clamp(Tan(), -max, max); } + // returns sign of the NORMALIZED angle. int Sgn() const { - return ::Sgn(int(BAMs())); + auto val = int(BAMs()); + return (val > 0) - (val < 0); } }; From 89d8c7b4fecab9d007e21bd0d87e8b2dbf349b6c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 15 Jun 2023 23:22:41 +0200 Subject: [PATCH 16/38] - minor cleanup of i_soundinternal.h. --- src/common/audio/sound/i_soundinternal.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/common/audio/sound/i_soundinternal.h b/src/common/audio/sound/i_soundinternal.h index 4787aa12a..52dabeea3 100644 --- a/src/common/audio/sound/i_soundinternal.h +++ b/src/common/audio/sound/i_soundinternal.h @@ -5,7 +5,6 @@ #include #include "vectors.h" -#include "tarray.h" #include "tflags.h" enum EChanFlag @@ -38,8 +37,6 @@ enum EChanFlag typedef TFlags EChanFlags; DEFINE_TFLAGS_OPERATORS(EChanFlags) -class FileReader; - // For convenience, this structure matches FMOD_REVERB_PROPERTIES. // Since I can't very well #include system-specific stuff in the // main game files, I duplicate it here. @@ -78,14 +75,17 @@ struct REVERB_PROPERTIES unsigned int Flags; }; -#define REVERB_FLAGS_DECAYTIMESCALE 0x00000001 -#define REVERB_FLAGS_REFLECTIONSSCALE 0x00000002 -#define REVERB_FLAGS_REFLECTIONSDELAYSCALE 0x00000004 -#define REVERB_FLAGS_REVERBSCALE 0x00000008 -#define REVERB_FLAGS_REVERBDELAYSCALE 0x00000010 -#define REVERB_FLAGS_DECAYHFLIMIT 0x00000020 -#define REVERB_FLAGS_ECHOTIMESCALE 0x00000040 -#define REVERB_FLAGS_MODULATIONTIMESCALE 0x00000080 +enum EReverbFlags +{ + REVERB_FLAGS_DECAYTIMESCALE = 0x00000001, + REVERB_FLAGS_REFLECTIONSSCALE = 0x00000002, + REVERB_FLAGS_REFLECTIONSDELAYSCALE = 0x00000004, + REVERB_FLAGS_REVERBSCALE = 0x00000008, + REVERB_FLAGS_REVERBDELAYSCALE = 0x00000010, + REVERB_FLAGS_DECAYHFLIMIT = 0x00000020, + REVERB_FLAGS_ECHOTIMESCALE = 0x00000040, + REVERB_FLAGS_MODULATIONTIMESCALE = 0x00000080, +}; struct ReverbContainer { @@ -144,8 +144,6 @@ struct FISoundChannel EChanFlags ChanFlags; }; -class SoundStream; - void S_SetSoundPaused(int state); From 99c76a3ff5b1a094593b52b0e9b22b300bde77b4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 16 Jun 2023 21:53:42 +0200 Subject: [PATCH 17/38] - BCOMPATF_NOSECTIONMERGE is not safe for the self referencing sector hacks in the Final doom IWADs. --- src/maploader/compatibility.cpp | 3 +-- wadsrc_extra/static/iwadinfo.txt | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index 2a0fa0749..1d135132d 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -292,12 +292,11 @@ FName MapLoader::CheckCompatibility(MapData *map) Level->ib_compatflags = 0; // When playing Doom IWAD levels force BCOMPATF_NOSECTIONMERGE, COMPAT_SHORTTEX and COMPATF_LIGHT. - // I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt. BCOMPATF_NOSECTIONMERGE is mainly for MAP18's sector 0 + // I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt. // TNT's MAP31 also needs COMPATF_STAIRINDEX but that only gets activated for TNT.WAD. if (fileSystem.GetFileContainer(map->lumpnum) == fileSystem.GetIwadNum() && (gameinfo.flags & GI_COMPATSHORTTEX) && Level->maptype == MAPTYPE_DOOM) { Level->ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT; - Level->ib_compatflags = BCOMPATF_NOSECTIONMERGE; if (gameinfo.flags & GI_COMPATSTAIRS) Level->ii_compatflags |= COMPATF_STAIRINDEX; } diff --git a/wadsrc_extra/static/iwadinfo.txt b/wadsrc_extra/static/iwadinfo.txt index a1c419d4e..11387e29c 100644 --- a/wadsrc_extra/static/iwadinfo.txt +++ b/wadsrc_extra/static/iwadinfo.txt @@ -326,7 +326,7 @@ IWad Config = "Doom" IWADName = "doom.wad", 2 Mapinfo = "mapinfo/ultdoom.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", "DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1", "E4M2", @@ -343,7 +343,7 @@ IWad Config = "Doom" IWADName = "doomunity.wad", 2 Mapinfo = "mapinfo/ultdoom.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", "DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1", "E4M2", @@ -375,7 +375,7 @@ IWad Config = "Doom" IWADName = "doom.wad" Mapinfo = "mapinfo/doomxbox.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", "DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1", "E4M2", "E1M10", "SEWERS" @@ -391,7 +391,7 @@ IWad Config = "Doom" IWADName = "doom.wad" Mapinfo = "mapinfo/ultdoom.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", "DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1", "E4M2" @@ -407,7 +407,7 @@ IWad Config = "Doom" IWADName = "doom.wad", 1 Mapinfo = "mapinfo/doom1.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", "DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1" @@ -422,7 +422,7 @@ IWad Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom1.txt" - Compatibility = "Shareware", "Shorttex" + Compatibility = "Shareware", "Shorttex", "nosectionmerge" MustContain = "E1M1" BannerColors = "54 54 54", "a8 a8 a8" IgnoreTitlePatches = 1 @@ -492,7 +492,7 @@ IWad Config = "Doom" IWADName = "doom2.wad" Mapinfo = "mapinfo/doom2bfg.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "MAP01", "DMENUPIC", "M_ACPT", "M_CAN", "M_EXITO", "M_CHG" BannerColors = "a8 00 00", "a8 a8 a8" Load = "nerve.wad" @@ -507,7 +507,7 @@ IWad Config = "Doom" IWADName = "doom2unity.wad" Mapinfo = "mapinfo/doom2unity.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "MAP01", "DMENUPIC" BannerColors = "00 7c 00", "a8 a8 a8" IgnoreTitlePatches = 1 @@ -522,7 +522,7 @@ IWad Config = "Doom" IWADName = "doom2.wad", 1 Mapinfo = "mapinfo/doom2xbox.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "MAP01", "MAP33", "CWILV32" BannerColors = "18 18 18", "a8 a8 a8" IgnoreTitlePatches = 1 @@ -538,7 +538,7 @@ IWad Config = "Doom" IWADName = "doom2f.wad", 1 Mapinfo = "mapinfo/doom2.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "MAP01", "WIOBJ" BannerColors = "ff ff ff", "a8 00 00" } @@ -552,7 +552,7 @@ IWad Config = "Doom" IWADName = "doom2.wad", 1 Mapinfo = "mapinfo/doom2.txt" - Compatibility = "Shorttex" + Compatibility = "Shorttex", "nosectionmerge" MustContain = "MAP01" BannerColors = "a8 00 00", "a8 a8 a8" IgnoreTitlePatches = 1 From 4538236a38aed286bb6ea7da4b2a0e8bfc8d3d3e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 17 Jun 2023 09:49:15 +0200 Subject: [PATCH 18/38] - cleaned i_music.h off external dependencies. * take I_BuildMIDIMenuList out of it * pass the command line state to disable music from the init call. * don't declare internal 'nomusic' variable in the header. --- src/common/audio/music/i_music.cpp | 5 ++--- src/common/audio/music/i_music.h | 13 +------------ src/common/audio/music/music.cpp | 4 ++++ src/common/menu/menudef.cpp | 1 + src/sound/s_doomsound.cpp | 3 ++- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index 0bc858292..6b8580724 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -40,7 +40,6 @@ #include #include -#include "m_argv.h" #include "filesystem.h" #include "c_dispatch.h" @@ -218,13 +217,13 @@ static void SetupDMXGUS() // //========================================================================== -void I_InitMusic(void) +void I_InitMusic(int musicstate) { I_InitSoundFonts(); snd_musicvolume->Callback (); - nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound"); + nomusic = musicstate; snd_mididevice->Callback(); diff --git a/src/common/audio/music/i_music.h b/src/common/audio/music/i_music.h index a6609eadb..aa2d48e62 100644 --- a/src/common/audio/music/i_music.h +++ b/src/common/audio/music/i_music.h @@ -34,27 +34,16 @@ #ifndef __I_MUSIC_H__ #define __I_MUSIC_H__ -#include "c_cvars.h" - -class FileReader; -struct FOptionValues; - // // MUSIC I/O // -void I_InitMusic (); -void I_BuildMIDIMenuList (FOptionValues *); +void I_InitMusic (int); // Volume. void I_SetRelativeVolume(float); void I_SetMusicVolume (double volume); -extern int nomusic; - -EXTERN_CVAR(Bool, mus_enabled) -EXTERN_CVAR(Float, snd_musicvolume) - inline float AmplitudeTodB(float amplitude) { diff --git a/src/common/audio/music/music.cpp b/src/common/audio/music/music.cpp index 610f0368f..6101dc1cc 100644 --- a/src/common/audio/music/music.cpp +++ b/src/common/audio/music/music.cpp @@ -53,9 +53,11 @@ #include "gain_analysis.h" #include "i_specialpaths.h" #include "configfile.h" +#include "c_cvars.h" // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- +extern int nomusic; extern float S_GetMusicVolume (const char *music); static void S_ActivatePlayList(bool goBack); @@ -81,6 +83,8 @@ static MusicCallbacks mus_cb = { nullptr, DefaultOpenMusic }; // PUBLIC DATA DEFINITIONS ------------------------------------------------- +EXTERN_CVAR(Bool, mus_enabled) +EXTERN_CVAR(Float, snd_musicvolume) EXTERN_CVAR(Int, snd_mididevice) EXTERN_CVAR(Float, mod_dumb_mastervolume) EXTERN_CVAR(Float, fluid_gain) diff --git a/src/common/menu/menudef.cpp b/src/common/menu/menudef.cpp index 4fbeeb0bb..e81bda2d2 100644 --- a/src/common/menu/menudef.cpp +++ b/src/common/menu/menudef.cpp @@ -1662,6 +1662,7 @@ static void InitMusicMenus() // Special menus will be created once all engine data is loaded // //============================================================================= +void I_BuildMIDIMenuList(FOptionValues*); void M_CreateMenus() { diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index bc5c092b0..50509eb3d 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -66,6 +66,7 @@ #include "g_game.h" #include "s_music.h" #include "v_draw.h" +#include "m_argv.h" // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -229,7 +230,7 @@ void S_Init() } I_InitSound(); - I_InitMusic(); + I_InitMusic(Args->CheckParm("-nomusic") || Args->CheckParm("-nosound")); // Heretic and Hexen have sound curve lookup tables. Doom does not. int curvelump = fileSystem.CheckNumForName("SNDCURVE"); From c675d60bacefd9c6651b8006f799f7bb55d0870b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Jun 2023 09:44:34 +0200 Subject: [PATCH 19/38] - finish the implementation for nosectionmerge. --- src/d_iwad.cpp | 1 + src/gamedata/gi.h | 1 + src/maploader/compatibility.cpp | 13 ++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 431c37813..4266b75a7 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -148,6 +148,7 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize, else if(sc.Compare("Extended")) iwad->flags |= GI_MENUHACK_EXTENDED; else if(sc.Compare("Shorttex")) iwad->flags |= GI_COMPATSHORTTEX; else if(sc.Compare("Stairs")) iwad->flags |= GI_COMPATSTAIRS; + else if (sc.Compare("nosectionmerge")) iwad->flags |= GI_NOSECTIONMERGE; else sc.ScriptError(NULL); } while (sc.CheckString(",")); diff --git a/src/gamedata/gi.h b/src/gamedata/gi.h index 5f11ecfa5..5e713628d 100644 --- a/src/gamedata/gi.h +++ b/src/gamedata/gi.h @@ -51,6 +51,7 @@ enum GI_COMPATPOLY1 = 0x00000040, // Hexen's MAP36 needs old polyobject drawing GI_COMPATPOLY2 = 0x00000080, // so does HEXDD's MAP47 GI_IGNORETITLEPATCHES = 0x00000200, // Ignore the map name graphics when not runnning in English language + GI_NOSECTIONMERGE = 0x00000400, // For the original id IWADs: avoid merging sections due to how idbsp created its sectors. }; #include "gametype.h" diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index 1d135132d..f85d89b19 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -294,10 +294,17 @@ FName MapLoader::CheckCompatibility(MapData *map) // When playing Doom IWAD levels force BCOMPATF_NOSECTIONMERGE, COMPAT_SHORTTEX and COMPATF_LIGHT. // I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt. // TNT's MAP31 also needs COMPATF_STAIRINDEX but that only gets activated for TNT.WAD. - if (fileSystem.GetFileContainer(map->lumpnum) == fileSystem.GetIwadNum() && (gameinfo.flags & GI_COMPATSHORTTEX) && Level->maptype == MAPTYPE_DOOM) + if (fileSystem.GetFileContainer(map->lumpnum) == fileSystem.GetIwadNum()) { - Level->ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT; - if (gameinfo.flags & GI_COMPATSTAIRS) Level->ii_compatflags |= COMPATF_STAIRINDEX; + if ((gameinfo.flags & GI_COMPATSHORTTEX) && Level->maptype == MAPTYPE_DOOM) + { + Level->ii_compatflags = COMPATF_SHORTTEX | COMPATF_LIGHT; + if (gameinfo.flags & GI_COMPATSTAIRS) Level->ii_compatflags |= COMPATF_STAIRINDEX; + } + if (gameinfo.flags & GI_NOSECTIONMERGE) + { + Level->ib_compatflags |= BCOMPATF_NOSECTIONMERGE; + } } map->GetChecksum(md5.Bytes); From 01dfcc7d9564013ae26c79ecb642e4e5578905b1 Mon Sep 17 00:00:00 2001 From: l2ksolkov Date: Sun, 18 Jun 2023 22:07:08 -0700 Subject: [PATCH 20/38] Fix compilation on FreeBSD Fixes #2073 Changes get_current_dir_name to functionally equivalent getcwd. Also moves "printf.h" to outside linux ifdef. --- src/common/platform/posix/sdl/i_system.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index e81c97f68..c0b8cc1fc 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -51,7 +51,6 @@ #include #include #include -#include "printf.h" #endif #include @@ -65,6 +64,7 @@ #include "c_cvars.h" #include "palutil.h" #include "st_start.h" +#include "printf.h" #ifndef NO_GTK @@ -408,7 +408,7 @@ FString I_GetFromClipboard (bool use_primary_selection) FString I_GetCWD() { - char* curdir = get_current_dir_name(); + char* curdir = getcwd(NULL,0); if (!curdir) { return ""; @@ -447,7 +447,8 @@ unsigned int I_MakeRNGSeed() void I_OpenShellFolder(const char* infolder) { - char* curdir = get_current_dir_name(); + + char* curdir = getcwd(NULL,0); if (!chdir(infolder)) { From bc41356b35c29c2b0fec55bb345bc6a5ac824e40 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Mon, 19 Jun 2023 04:38:35 -0400 Subject: [PATCH 21/38] - minor formatting fix --- src/common/platform/posix/sdl/i_system.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index c0b8cc1fc..ab0c6bd7d 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -447,7 +447,6 @@ unsigned int I_MakeRNGSeed() void I_OpenShellFolder(const char* infolder) { - char* curdir = getcwd(NULL,0); if (!chdir(infolder)) From 7dda6570ec2cce9799dc26ea794fadb125713349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 19 Apr 2023 10:24:39 -0300 Subject: [PATCH 22/38] remove memory leak in `A_ChangeModel` --- src/playsim/p_actionfunctions.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 157ef9336..48d2b2249 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5155,13 +5155,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel) if (mobj->modelData == nullptr) { auto ptr = Create(); + ptr->hasModel = mobj->hasmodel ? 1 : 0; - ptr->modelIDs = *new TArray(); - ptr->skinIDs = *new TArray(); - ptr->surfaceSkinIDs = *new TArray(); - ptr->animationIDs = *new TArray(); - ptr->modelFrameGenerators = *new TArray(); ptr->modelDef = NAME_None; + mobj->modelData = ptr; mobj->hasmodel = 1; GC::WriteBarrier(mobj, ptr); From 30e7b30c45cad7e65339be8f54ea2e2f746362e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 20 Apr 2023 22:02:16 -0300 Subject: [PATCH 23/38] Simplify DirectNativeDesc, allow FName as a native parameter --- src/common/scripting/vm/vm.h | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 01e98fb61..1a8706353 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -617,6 +617,7 @@ namespace template struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; + template<> struct native_is_valid { static const bool value = true; static const bool retval = true; static_assert(sizeof(FName) == sizeof(int)); }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = false;}; // Bool as return does not work! @@ -627,26 +628,7 @@ struct DirectNativeDesc { DirectNativeDesc() = default; - #define TP(n) typename P##n - #define VP(n) ValidateType() - template DirectNativeDesc(Ret(*func)()) : Ptr(reinterpret_cast(func)) { ValidateRet(); } - template DirectNativeDesc(Ret(*func)(P1)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); } - template DirectNativeDesc(Ret(*func)(P1,P2)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); } - template DirectNativeDesc(Ret(*func)(P1,P2,P3)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14); } - template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14), VP(15); } -#undef TP - #undef VP + template DirectNativeDesc(Ret(*func)(Params...)) : Ptr(reinterpret_cast(func)) { ValidateRet(); (ValidateType(), ...); } template void ValidateType() { static_assert(native_is_valid::value, "Argument type is not valid as a direct native parameter or return type"); } template void ValidateRet() { static_assert(native_is_valid::retval, "Return type is not valid as a direct native parameter or return type"); } From 5b85557ddbc59d6ad2e46d07d1f5d777404e0db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 20 Apr 2023 22:03:17 -0300 Subject: [PATCH 24/38] add TArray::AppendFill for appending a single value multiple times --- src/common/utility/tarray.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index a21226095..3d49f1868 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -54,6 +54,7 @@ #include #include #include +#include #if !defined(_WIN32) #include // for intptr_t @@ -420,6 +421,26 @@ public: return start; } + unsigned AppendFill(const T& val, unsigned append_count) + { + unsigned start = Count; + + Grow(append_count); + Count += append_count; + if constexpr (std::is_trivially_copyable::value) + { + std::fill(Array + start, Array + Count, val); + } + else + { + for (unsigned i = 0; i < append_count; i++) + { + new(&Array[start + i]) T(val); + } + } + return start; + } + bool Pop () { if (Count > 0) From b55ffdbfd3e0045a05af7b6fb017543b629966e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 20 Apr 2023 22:06:55 -0300 Subject: [PATCH 25/38] major A_ChangeModel cleanup --- src/playsim/actor.h | 1 + src/playsim/p_actionfunctions.cpp | 323 ++++++++++++++++++------------ src/playsim/p_mobj.cpp | 9 + src/r_data/models.cpp | 32 ++- 4 files changed, 229 insertions(+), 136 deletions(-) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 5db2754df..2521cd2a2 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -691,6 +691,7 @@ public: DActorModelData() = default; virtual void Serialize(FSerializer& arc) override; + virtual void OnDestroy() override; }; class DViewPosition : public DObject diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 48d2b2249..49f33342e 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5107,7 +5107,196 @@ enum ChangeModelFlags CMDL_USESURFACESKIN = 1 << 2, }; -DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel) +void ChangeModelNative( + AActor * self, + AActor * invoker, + FStateParamInfo * stateinfo, + FName modeldef, + int i_modelindex, + const FString &p_modelpath, + FName model, + int i_skinindex, + const FString &p_skinpath, + FName skin, + int flags, + int generatorindex, + int i_animationindex, + const FString &p_animationpath, + FName animation +) { + if(!self) ThrowAbortException(X_READ_NIL, "In function parameter self"); + + if (modeldef != NAME_None && PClass::FindClass(modeldef.GetChars()) == nullptr) + { + Printf("Attempt to pass invalid modeldef name %s in %s.", modeldef.GetChars(), self->GetCharacterName()); + return; + } + + unsigned modelindex = i_modelindex < 0 ? 0 : i_modelindex; + unsigned skinindex = i_skinindex < 0 ? 0 : i_skinindex; + unsigned animationindex = i_animationindex < 0 ? 0 : i_animationindex; + + AActor* mobj = (ACTION_CALL_FROM_PSPRITE() && (flags & CMDL_WEAPONTOPLAYER)) || ACTION_CALL_FROM_INVENTORY() ? self : invoker; + + FString modelpath = p_modelpath; + FString skinpath = p_skinpath; + FString animationpath = p_animationpath; + + if (modelpath.Len() != 0 && modelpath[(int)modelpath.Len() - 1] != '/') modelpath += '/'; + if (skinpath.Len() != 0 && skinpath[(int)skinpath.Len() - 1] != '/') skinpath += '/'; + if (animationpath.Len() != 0 && animationpath[(int)animationpath.Len() - 1] != '/') animationpath += '/'; + + if (mobj->modelData == nullptr) + { + auto ptr = Create(); + + ptr->hasModel = mobj->hasmodel; + ptr->modelDef = NAME_None; + + mobj->modelData = ptr; + mobj->hasmodel = true; + GC::WriteBarrier(mobj, ptr); + }; + + unsigned skinPosition = skinindex + modelindex * MD3_MAX_SURFACES; + + int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2; + int queryAnimation = animation != NAME_None ? FindModel(animationpath.GetChars(), animation.GetChars()) : -1; + + mobj->modelData->modelDef = modeldef; + + assert(mobj->modelData->modelIDs.Size() == mobj->modelData->modelFrameGenerators.Size()); + + if(mobj->modelData->modelIDs.Size() < modelindex) + { + mobj->modelData->modelIDs.AppendFill(-1, modelindex - mobj->modelData->modelIDs.Size()); + mobj->modelData->modelFrameGenerators.AppendFill(-1, modelindex - mobj->modelData->modelFrameGenerators.Size()); + } + + if(mobj->modelData->animationIDs.Size() < animationindex) + { + mobj->modelData->animationIDs.AppendFill(-1, animationindex - mobj->modelData->animationIDs.Size()); + } + + if(flags & CMDL_USESURFACESKIN) + { + if(mobj->modelData->surfaceSkinIDs.Size() < skinPosition) + { + mobj->modelData->surfaceSkinIDs.AppendFill(FNullTextureID(), skinPosition - mobj->modelData->surfaceSkinIDs.Size()); + } + } + else if(mobj->modelData->skinIDs.Size() < skinindex) + { + mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size()); + } + + if(mobj->modelData->modelIDs.Size() == modelindex) + { + mobj->modelData->modelIDs.Push(queryModel); + mobj->modelData->modelFrameGenerators.Push(generatorindex); + } + else + { + mobj->modelData->modelIDs[modelindex] = queryModel; + mobj->modelData->modelFrameGenerators[modelindex] = generatorindex; + } + + if(mobj->modelData->animationIDs.Size() == animationindex) + { + mobj->modelData->animationIDs.Push(queryAnimation); + } + else + { + mobj->modelData->animationIDs[animationindex] = queryAnimation; + } + + auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID(); + + if (flags & CMDL_USESURFACESKIN) + { + if(mobj->modelData->surfaceSkinIDs.Size() == skinPosition) + { + mobj->modelData->surfaceSkinIDs.Push(skindata); + } + else + { + mobj->modelData->surfaceSkinIDs[skinPosition] = skindata; + } + } + else + { + if(mobj->modelData->skinIDs.Size() == skinindex) + { + mobj->modelData->skinIDs.Push(skindata); + } + else + { + mobj->modelData->skinIDs[skinindex] = skindata; + } + } + + //[SM] - We need to serialize file paths and model names so that they are pushed on loading save files. Likewise, let's not include models that were already parsed when initialized. + if (queryModel >= 0) + { + FString fullName; + fullName.Format("%s%s", modelpath.GetChars(), model.GetChars()); + bool found = false; + + for (auto &m : savedModelFiles) + { + if(m.CompareNoCase(fullName) == 0) + { + found = true; + break; + } + } + if(!found) for (auto &m : Models) + { + if (m->mFileName.CompareNoCase(fullName) == 0) + { + found = true; + break; + } + } + if(!found) savedModelFiles.Push(fullName); + } + //Same for animations + if (queryAnimation >= 0) + { + FString fullName; + fullName.Format("%s%s", animationpath.GetChars(), animation.GetChars()); + bool found = false; + + for (auto &m : savedModelFiles) + { + if(m.CompareNoCase(fullName) == 0) + { + found = true; + break; + } + } + if(!found) for (auto &m : Models) + { + if (m->mFileName.CompareNoCase(fullName) == 0) + { + found = true; + break; + } + } + if(!found) savedModelFiles.Push(fullName); + } + + if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->surfaceSkinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None) + { + mobj->hasmodel = mobj->modelData->hasModel; + mobj->modelData->Destroy(); + mobj->modelData = nullptr; + } + + return; +} + +DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_ChangeModel, ChangeModelNative) { PARAM_ACTION_PROLOGUE(AActor); PARAM_NAME(modeldef); @@ -5122,138 +5311,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel) PARAM_INT(animationindex); PARAM_STRING_VAL(animationpath); PARAM_NAME(animation); - - if (self == nullptr) - ACTION_RETURN_BOOL(false); - else if (modeldef != NAME_None && PClass::FindClass(modeldef.GetChars()) == nullptr) - { - Printf("Attempt to pass invalid modeldef name %s in %s.", modeldef.GetChars(), self->GetCharacterName()); - ACTION_RETURN_BOOL(false); - } - else if (modelindex < 0) - { - Printf("Attempt to pass invalid model index %d in %s, index must be non-negative.", modelindex, self->GetCharacterName()); - ACTION_RETURN_BOOL(false); - } - else if (skinindex < 0) - { - Printf("Attempt to pass invalid skin index %d in %s, index must be non-negative.", skinindex, self->GetCharacterName()); - ACTION_RETURN_BOOL(false); - } - else if (animationindex < 0) - { - Printf("Attempt to pass invalid animation index %d in %s, index must be non-negative.", animationindex, self->GetCharacterName()); - ACTION_RETURN_BOOL(false); - } - - AActor* mobj = (ACTION_CALL_FROM_PSPRITE() && (flags & CMDL_WEAPONTOPLAYER)) || ACTION_CALL_FROM_INVENTORY() ? self : stateowner; - - if (modelpath[(int)modelpath.Len() - 1] != '/') modelpath += '/'; - if (skinpath[(int)skinpath.Len() - 1] != '/') skinpath += '/'; - if (animationpath[(int)animationpath.Len() - 1] != '/') animationpath += '/'; - - if (mobj->modelData == nullptr) - { - auto ptr = Create(); - - ptr->hasModel = mobj->hasmodel ? 1 : 0; - ptr->modelDef = NAME_None; - - mobj->modelData = ptr; - mobj->hasmodel = 1; - GC::WriteBarrier(mobj, ptr); - } - - int maxModels = mobj->modelData->modelIDs.Size(); - int maxSkins = mobj->modelData->skinIDs.Size(); - int maxSurfaceSkins = mobj->modelData->surfaceSkinIDs.Size(); - int maxAnimations = mobj->modelData->animationIDs.Size(); - int maxGenerators = mobj->modelData->modelFrameGenerators.Size(); - - int skinPosition = skinindex + modelindex * MD3_MAX_SURFACES; - - int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2; - int queryAnimation = animation != NAME_None ? FindModel(animationpath.GetChars(), animation.GetChars()) : -1; - - //[SM] - Let's clear out any potential entries at the specified indices - mobj->modelData->modelDef = modeldef; - if(maxModels > modelindex) mobj->modelData->modelIDs.Pop(mobj->modelData->modelIDs[modelindex]); - if(maxAnimations > animationindex) mobj->modelData->animationIDs.Pop(mobj->modelData->animationIDs[animationindex]); - if(maxGenerators > modelindex) mobj->modelData->modelFrameGenerators.Pop(mobj->modelData->modelFrameGenerators[modelindex]); - - if (flags & CMDL_USESURFACESKIN) - { - if (maxSurfaceSkins > skinPosition) - mobj->modelData->surfaceSkinIDs.Delete(skinPosition); //[SM] - It seems the only way to make sure this does what it's told is from Delete, not Pop - } - else - { - if (maxSkins > skinindex) - mobj->modelData->skinIDs.Pop(mobj->modelData->skinIDs[skinindex]); - } - - //[SM] - We need to fill up any holes this new index will make so that it doesn't leave behind any undefined behavior - while ((int)mobj->modelData->modelIDs.Size() < modelindex) mobj->modelData->modelIDs.Push(-1); - while ((int)mobj->modelData->modelFrameGenerators.Size() < modelindex) mobj->modelData->modelFrameGenerators.Push(-1); - while ((int)mobj->modelData->animationIDs.Size() < modelindex) mobj->modelData->animationIDs.Push(-1); - if (flags & CMDL_USESURFACESKIN) - while ((int)mobj->modelData->surfaceSkinIDs.Size() < skinPosition) mobj->modelData->surfaceSkinIDs.Push(FNullTextureID()); - else - while ((int)mobj->modelData->skinIDs.Size() < skinindex) mobj->modelData->skinIDs.Push(FNullTextureID()); - mobj->modelData->modelIDs.Insert(modelindex, queryModel); - mobj->modelData->modelFrameGenerators.Insert(modelindex, generatorindex); - mobj->modelData->animationIDs.Insert(animationindex, queryAnimation); - if (flags & CMDL_USESURFACESKIN) - mobj->modelData->surfaceSkinIDs.Insert(skinPosition, skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID()); - else - mobj->modelData->skinIDs.Insert(skinindex, skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID()); - - //[SM] - We need to serialize file paths and model names so that they are pushed on loading save files. Likewise, let's not include models that were already parsed when initialized. - if (queryModel >= 0) - { - FString fullName; - fullName.Format("%s%s", modelpath.GetChars(), model.GetChars()); - bool allowPush = true; - for (unsigned i = 0; i < savedModelFiles.Size(); i++) if (!savedModelFiles[i].CompareNoCase(fullName)) allowPush = false; - for (unsigned i = 0; i < Models.Size()-1; i++) if (!Models[i]->mFileName.CompareNoCase(fullName)) allowPush = false; - - if(allowPush) savedModelFiles.Push(fullName); - } - //Same for animations - if (queryAnimation >= 0) - { - FString fullName; - fullName.Format("%s%s", animationpath.GetChars(), animation.GetChars()); - bool allowPush = true; - for (unsigned i = 0; i < savedModelFiles.Size(); i++) if (!savedModelFiles[i].CompareNoCase(fullName)) allowPush = false; - for (unsigned i = 0; i < Models.Size() - 1; i++) if (!Models[i]->mFileName.CompareNoCase(fullName)) allowPush = false; - - if (allowPush) savedModelFiles.Push(fullName); - } - - //[SM] - if an indice of modelIDs or skinIDs comes up blank and it's the last one, just delete it. For using very large amounts of indices, common sense says to just not run this repeatedly. - while (mobj->modelData->modelIDs.Size() > 0 && mobj->modelData->modelIDs.Last() == -1) - mobj->modelData->modelIDs.Pop(mobj->modelData->modelIDs.Last()); - while (mobj->modelData->modelFrameGenerators.Size() > 0 && mobj->modelData->modelFrameGenerators.Last() == -1) - mobj->modelData->modelFrameGenerators.Pop(mobj->modelData->modelFrameGenerators.Last()); - while (mobj->modelData->skinIDs.Size() > 0 && mobj->modelData->skinIDs.Last() == FNullTextureID()) - mobj->modelData->skinIDs.Pop(mobj->modelData->skinIDs.Last()); - while (mobj->modelData->surfaceSkinIDs.Size() > 0 && mobj->modelData->surfaceSkinIDs.Last() == FNullTextureID()) - mobj->modelData->surfaceSkinIDs.Pop(mobj->modelData->surfaceSkinIDs.Last()); - while (mobj->modelData->animationIDs.Size() > 0 && mobj->modelData->animationIDs.Last() == -1) - mobj->modelData->animationIDs.Pop(mobj->modelData->animationIDs.Last()); - - if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->surfaceSkinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None) - { - mobj->hasmodel = mobj->modelData->hasModel; - mobj->modelData->modelIDs.Reset(); - mobj->modelData->modelFrameGenerators.Reset(); - mobj->modelData->skinIDs.Reset(); - mobj->modelData->surfaceSkinIDs.Reset(); - mobj->modelData->animationIDs.Reset(); - mobj->modelData->Destroy(); - } + ChangeModelNative(self,stateowner,stateinfo,modeldef,modelindex,modelpath,model,skinindex,skinpath,skin,flags,generatorindex,animationindex,animationpath,animation); return 0; } diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index e6321139a..987436424 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -1336,6 +1336,15 @@ void DActorModelData::Serialize(FSerializer& arc) ("hasModel", hasModel); } +void DActorModelData::OnDestroy() +{ + modelIDs.Reset(); + modelFrameGenerators.Reset(); + skinIDs.Reset(); + surfaceSkinIDs.Reset(); + animationIDs.Reset(); +} + //---------------------------------------------------------------------------- // // PROC P_ExplodeMissile diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index fd7d0c06c..03d1def7e 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -344,16 +344,40 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr if (actor->modelData->skinIDs[i].isValid()) skinid = actor->modelData->skinIDs[i]; } - for (int surface = i * MD3_MAX_SURFACES; surface < (i + 1) * MD3_MAX_SURFACES; surface++) + + unsigned sz1 = smf->surfaceskinIDs.Size(); + unsigned sz2 = actor->modelData->surfaceSkinIDs.Size(); + unsigned end = (i + 1) * MD3_MAX_SURFACES; + + if(actor->modelData->surfaceSkinIDs.Size() > 0) { - if (surface < (int)actor->modelData->surfaceSkinIDs.Size()) + long last_ok = -1; + surfaceskinids.Resize(actor->modelData->surfaceSkinIDs.Size()); + for (unsigned surface = i * MD3_MAX_SURFACES; surface < end; surface++) { + if (surface >= sz2) break; + if (actor->modelData->surfaceSkinIDs[surface].isValid()) { - // only make a copy of the surfaceskinIDs array if really needed - if (surfaceskinids.Size() == 0) surfaceskinids = smf->surfaceskinIDs; surfaceskinids[surface] = actor->modelData->surfaceSkinIDs[surface]; + last_ok = surface; } + else if(surface < sz1) + { + surfaceskinids[surface] = smf->surfaceskinIDs[surface]; + } + else + { + surfaceskinids[surface].SetInvalid(); + } + } + if(last_ok >= 0) + { + surfaceskinids.Resize(max(last_ok + 1, (long)sz1)); // clear out + } + else + { + surfaceskinids.Clear(); } } } From 61d68eb2d6141f6b254df508f4f155ba80cb28d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 27 May 2023 18:40:04 -0300 Subject: [PATCH 26/38] Rewrite changed model rendering code, and change how model skins are handled --- src/common/engine/serializer.h | 2 +- src/playsim/actor.h | 19 +++-- src/playsim/p_actionfunctions.cpp | 74 +++++++++-------- src/playsim/p_mobj.cpp | 17 +++- src/r_data/models.cpp | 132 ++++++++++++++++++------------ 5 files changed, 148 insertions(+), 96 deletions(-) diff --git a/src/common/engine/serializer.h b/src/common/engine/serializer.h index 63bfb3529..93c7ef5a1 100644 --- a/src/common/engine/serializer.h +++ b/src/common/engine/serializer.h @@ -234,6 +234,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def); FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def); FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def); +FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &sid, struct ModelOverride *def); template >*/> FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **) @@ -244,7 +245,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **) return arc; } - template FSerializer &Serialize(FSerializer &arc, const char *key, TArray &value, TArray *def) { diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 2521cd2a2..baf78fe2e 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -677,17 +677,22 @@ enum EViewPosFlags // [MC] Flags for SetViewPos. VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position. }; +struct ModelOverride +{ + int modelID; + TArray surfaceSkinIDs; +}; + class DActorModelData : public DObject { DECLARE_CLASS(DActorModelData, DObject); public: - FName modelDef; - bool hasModel; - TArray modelIDs; - TArray skinIDs; - TArray surfaceSkinIDs; - TArray animationIDs; - TArray modelFrameGenerators; + FName modelDef; + bool hasModel; + TArray models; + TArray skinIDs; + TArray animationIDs; + TArray modelFrameGenerators; DActorModelData() = default; virtual void Serialize(FSerializer& arc) override; diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 49f33342e..6eec02193 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5158,18 +5158,16 @@ void ChangeModelNative( GC::WriteBarrier(mobj, ptr); }; - unsigned skinPosition = skinindex + modelindex * MD3_MAX_SURFACES; - int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2; int queryAnimation = animation != NAME_None ? FindModel(animationpath.GetChars(), animation.GetChars()) : -1; mobj->modelData->modelDef = modeldef; - assert(mobj->modelData->modelIDs.Size() == mobj->modelData->modelFrameGenerators.Size()); + assert(mobj->modelData->models.Size() == mobj->modelData->modelFrameGenerators.Size()); - if(mobj->modelData->modelIDs.Size() < modelindex) + if(mobj->modelData->models.Size() < modelindex) { - mobj->modelData->modelIDs.AppendFill(-1, modelindex - mobj->modelData->modelIDs.Size()); + mobj->modelData->models.AppendFill({-1, {}}, modelindex - mobj->modelData->models.Size()); mobj->modelData->modelFrameGenerators.AppendFill(-1, modelindex - mobj->modelData->modelFrameGenerators.Size()); } @@ -5178,26 +5176,51 @@ void ChangeModelNative( mobj->modelData->animationIDs.AppendFill(-1, animationindex - mobj->modelData->animationIDs.Size()); } - if(flags & CMDL_USESURFACESKIN) - { - if(mobj->modelData->surfaceSkinIDs.Size() < skinPosition) - { - mobj->modelData->surfaceSkinIDs.AppendFill(FNullTextureID(), skinPosition - mobj->modelData->surfaceSkinIDs.Size()); - } - } - else if(mobj->modelData->skinIDs.Size() < skinindex) + auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID(); + + if(!(flags & CMDL_USESURFACESKIN) && mobj->modelData->skinIDs.Size() < skinindex) { mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size()); } - if(mobj->modelData->modelIDs.Size() == modelindex) + if(mobj->modelData->models.Size() == modelindex) { - mobj->modelData->modelIDs.Push(queryModel); - mobj->modelData->modelFrameGenerators.Push(generatorindex); + + if(flags & CMDL_USESURFACESKIN && skinindex >= 0) + { + TArray surfaceSkins; + if(skinindex > 0) + { + surfaceSkins.AppendFill(FNullTextureID(), skinindex - 1); + } + surfaceSkins.Push(skindata); + mobj->modelData->models.Push({queryModel, std::move(surfaceSkins)}); + mobj->modelData->modelFrameGenerators.Push(generatorindex); + } + else + { + mobj->modelData->models.Push({queryModel, {}}); + mobj->modelData->modelFrameGenerators.Push(generatorindex); + } } else { - mobj->modelData->modelIDs[modelindex] = queryModel; + if(flags & CMDL_USESURFACESKIN && skinindex >= 0) + { + if(skinindex > mobj->modelData->models[modelindex].surfaceSkinIDs.Size()) + { + mobj->modelData->models[modelindex].surfaceSkinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->models[modelindex].surfaceSkinIDs.Size()); + } + if(skinindex == mobj->modelData->models[modelindex].surfaceSkinIDs.Size()) + { + mobj->modelData->models[modelindex].surfaceSkinIDs.Push(skindata); + } + else + { + mobj->modelData->models[modelindex].surfaceSkinIDs[skinindex] = skindata; + } + } + mobj->modelData->models[modelindex].modelID = queryModel; mobj->modelData->modelFrameGenerators[modelindex] = generatorindex; } @@ -5210,20 +5233,7 @@ void ChangeModelNative( mobj->modelData->animationIDs[animationindex] = queryAnimation; } - auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID(); - - if (flags & CMDL_USESURFACESKIN) - { - if(mobj->modelData->surfaceSkinIDs.Size() == skinPosition) - { - mobj->modelData->surfaceSkinIDs.Push(skindata); - } - else - { - mobj->modelData->surfaceSkinIDs[skinPosition] = skindata; - } - } - else + if (!(flags & CMDL_USESURFACESKIN)) { if(mobj->modelData->skinIDs.Size() == skinindex) { @@ -5286,7 +5296,7 @@ void ChangeModelNative( if(!found) savedModelFiles.Push(fullName); } - if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->surfaceSkinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None) + if (mobj->modelData->models.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None) { mobj->hasmodel = mobj->modelData->hasModel; mobj->modelData->Destroy(); diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 987436424..543c80f1d 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -1324,13 +1324,22 @@ bool AActor::Massacre () // //---------------------------------------------------------------------------- +FSerializer &Serialize(FSerializer &arc, const char *key, ModelOverride &sid, ModelOverride *def) +{ + arc.BeginObject(key); + arc("modelID", sid.modelID); + arc("surfaceSkinIDs", sid.surfaceSkinIDs); + arc.EndObject(); + return arc; +} + void DActorModelData::Serialize(FSerializer& arc) { Super::Serialize(arc); arc("modelDef", modelDef) - ("modelIDs", modelIDs) + ("models", models) ("skinIDs", skinIDs) - ("surfaceSkinIDs", surfaceSkinIDs) + //("surfaceSkinIDs", surfaceSkinIDs) ("animationIDs", animationIDs) ("modelFrameGenerators", modelFrameGenerators) ("hasModel", hasModel); @@ -1338,10 +1347,10 @@ void DActorModelData::Serialize(FSerializer& arc) void DActorModelData::OnDestroy() { - modelIDs.Reset(); + models.Reset(); modelFrameGenerators.Reset(); skinIDs.Reset(); - surfaceSkinIDs.Reset(); + //surfaceSkinIDs.Reset(); animationIDs.Reset(); } diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index 03d1def7e..0c91a248b 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -299,12 +299,12 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr } } - int modelsamount = smf->modelsAmount; + unsigned modelsamount = smf->modelsAmount; //[SM] - if we added any models for the frame to also render, then we also need to update modelsAmount for this smf if (actor->modelData != nullptr) { - if (actor->modelData->modelIDs.Size() > (unsigned)modelsamount) - modelsamount = actor->modelData->modelIDs.Size(); + if (actor->modelData->models.Size() > modelsamount) + modelsamount = actor->modelData->models.Size(); } TArray surfaceskinids; @@ -313,81 +313,108 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr int boneStartingPosition = 0; bool evaluatedSingle = false; - for (int i = 0; i < modelsamount; i++) + for (unsigned i = 0; i < modelsamount; i++) { int modelid = -1; int animationid = -1; int modelframe = -1; int modelframenext = -1; - FTextureID skinid; skinid.SetInvalid(); + FTextureID skinid; skinid.SetNull(); surfaceskinids.Clear(); + if (actor->modelData != nullptr) { - if (i < (int)actor->modelData->modelIDs.Size()) - modelid = actor->modelData->modelIDs[i]; + //modelID + if (actor->modelData->models.Size() > i && actor->modelData->models[i].modelID >= 0) + { + modelid = actor->modelData->models[i].modelID; + } + else if(smf->modelsAmount > i) + { + modelid = smf->modelIDs[i]; + } - if (i < (int)actor->modelData->animationIDs.Size()) + //animationID + if (actor->modelData->animationIDs.Size() > i && actor->modelData->animationIDs[i] >= 0) + { animationid = actor->modelData->animationIDs[i]; - - if (i < (int)actor->modelData->modelFrameGenerators.Size()) - { - //[SM] - We will use this little snippet to allow a modder to specify a model index to clone. It's also pointless to clone something that clones something else in this case. And causes me headaches. - if (actor->modelData->modelFrameGenerators[i] >= 0 && actor->modelData->modelFrameGenerators[i] <= modelsamount && smf->modelframes[actor->modelData->modelFrameGenerators[i]] != -1) - { - modelframe = smf->modelframes[actor->modelData->modelFrameGenerators[i]]; - if (smfNext) modelframenext = smfNext->modelframes[actor->modelData->modelFrameGenerators[i]]; - } } - if (i < (int)actor->modelData->skinIDs.Size()) + else if(smf->modelsAmount > i) { - if (actor->modelData->skinIDs[i].isValid()) - skinid = actor->modelData->skinIDs[i]; + animationid = smf->animationIDs[i]; } - unsigned sz1 = smf->surfaceskinIDs.Size(); - unsigned sz2 = actor->modelData->surfaceSkinIDs.Size(); - unsigned end = (i + 1) * MD3_MAX_SURFACES; + //modelFrame + if (actor->modelData->modelFrameGenerators.Size() > i + && actor->modelData->modelFrameGenerators[i] >= 0 + && actor->modelData->modelFrameGenerators[i] < modelsamount + && smf->modelframes[actor->modelData->modelFrameGenerators[i]] >= 0 + ) { + modelframe = smf->modelframes[actor->modelData->modelFrameGenerators[i]]; - if(actor->modelData->surfaceSkinIDs.Size() > 0) - { - long last_ok = -1; - surfaceskinids.Resize(actor->modelData->surfaceSkinIDs.Size()); - for (unsigned surface = i * MD3_MAX_SURFACES; surface < end; surface++) + if (smfNext) { - if (surface >= sz2) break; - - if (actor->modelData->surfaceSkinIDs[surface].isValid()) + if(smfNext->modelframes[actor->modelData->modelFrameGenerators[i]] >= 0) { - surfaceskinids[surface] = actor->modelData->surfaceSkinIDs[surface]; - last_ok = surface; - } - else if(surface < sz1) - { - surfaceskinids[surface] = smf->surfaceskinIDs[surface]; + modelframenext = smfNext->modelframes[actor->modelData->modelFrameGenerators[i]]; } else { - surfaceskinids[surface].SetInvalid(); + modelframenext = smfNext->modelframes[i]; } } - if(last_ok >= 0) + } + else if(smf->modelsAmount > i) + { + modelframe = smf->modelframes[i]; + if (smfNext) modelframenext = smfNext->modelframes[i]; + } + + //skinID + if (actor->modelData->skinIDs.Size() > i && actor->modelData->skinIDs[i].isValid()) + { + skinid = actor->modelData->skinIDs[i]; + } + else if(smf->modelsAmount > i) + { + skinid = smf->skinIDs[i]; + } + + //surfaceSkinIDs + if(actor->modelData->models.Size() > i && actor->modelData->models[i].surfaceSkinIDs.Size() > 0) + { + unsigned sz1 = smf->surfaceskinIDs.Size(); + unsigned sz2 = actor->modelData->models[i].surfaceSkinIDs.Size(); + unsigned start = i * MD3_MAX_SURFACES; + + surfaceskinids = actor->modelData->models[i].surfaceSkinIDs; + surfaceskinids.Resize(MD3_MAX_SURFACES); + + for (unsigned surface = 0; surface < MD3_MAX_SURFACES; surface++) { - surfaceskinids.Resize(max(last_ok + 1, (long)sz1)); // clear out - } - else - { - surfaceskinids.Clear(); + if (sz2 > surface && (actor->modelData->models[i].surfaceSkinIDs[surface].isValid())) + { + continue; + } + if((surface + start) < sz1) + { + surfaceskinids[surface] = smf->surfaceskinIDs[surface + start]; + } + else + { + surfaceskinids[surface].SetNull(); + } } } } - if (i < smf->modelsAmount) + else { - if (modelid == -1) modelid = smf->modelIDs[i]; - if (animationid == -1) animationid = smf->animationIDs[i]; - if (modelframe == -1) modelframe = smf->modelframes[i]; - if (modelframenext == -1 && smfNext) modelframenext = smfNext->modelframes[i]; - if (!skinid.isValid()) skinid = smf->skinIDs[i]; + modelid = smf->modelIDs[i]; + animationid = smf->animationIDs[i]; + modelframe = smf->modelframes[i]; + if (smfNext) modelframenext = smfNext->modelframes[i]; + skinid = smf->skinIDs[i]; } if (modelid >= 0) @@ -396,8 +423,9 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr auto tex = skinid.isValid() ? TexMan.GetGameTexture(skinid, true) : nullptr; mdl->BuildVertexBuffer(renderer); - auto& ssids = surfaceskinids.Size() > 0 ? surfaceskinids : smf->surfaceskinIDs; - auto ssidp = (unsigned)(i * MD3_MAX_SURFACES) < ssids.Size() ? &ssids[i * MD3_MAX_SURFACES] : nullptr; + auto ssidp = surfaceskinids.Size() > 0 + ? surfaceskinids.Data() + : (((i * MD3_MAX_SURFACES) < smf->surfaceskinIDs.Size()) ? &smf->surfaceskinIDs[i * MD3_MAX_SURFACES] : nullptr); bool nextFrame = smfNext && modelframe != modelframenext; From 49eae742721b85e01d8035c1d4d7d83dd23e11f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Tue, 30 May 2023 09:08:19 -0300 Subject: [PATCH 27/38] assert that FName is a POD and as such is passed directly on registers, so that if it changes to be a non-pod, it won't silently break parameters --- src/common/scripting/vm/vm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 1a8706353..ca13763f9 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -45,6 +45,7 @@ #include "memarena.h" #include "name.h" #include "scopebarrier.h" +#include class DObject; union VMOP; @@ -617,7 +618,7 @@ namespace template struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; - template<> struct native_is_valid { static const bool value = true; static const bool retval = true; static_assert(sizeof(FName) == sizeof(int)); }; + template<> struct native_is_valid { static const bool value = true; static const bool retval = true; static_assert(sizeof(FName) == sizeof(int)); static_assert(std::is_pod_v);}; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = false;}; // Bool as return does not work! From 0e438f10f3f0bf08e3f51a899bb9d221e77e03c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 31 May 2023 11:13:30 -0300 Subject: [PATCH 28/38] fix CMDL_HideModel --- src/r_data/models.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index 0c91a248b..ad9c9978a 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -330,6 +330,10 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr { modelid = actor->modelData->models[i].modelID; } + else if(actor->modelData->models.Size() > i && actor->modelData->models[i].modelID == -2) + { + continue; + } else if(smf->modelsAmount > i) { modelid = smf->modelIDs[i]; From c6978c23ab70ed8b464f26f6dda5aab102aeb063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 15 Jun 2023 19:30:46 -0300 Subject: [PATCH 29/38] Disable FName as a native parameter --- src/common/scripting/vm/vm.h | 3 ++- src/playsim/p_actionfunctions.cpp | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index ca13763f9..9529cf5c0 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -618,7 +618,8 @@ namespace template struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; - template<> struct native_is_valid { static const bool value = true; static const bool retval = true; static_assert(sizeof(FName) == sizeof(int)); static_assert(std::is_pod_v);}; + // [RL0] this is disabled for now due to graf's concerns + // template<> struct native_is_valid { static const bool value = true; static const bool retval = true; static_assert(sizeof(FName) == sizeof(int)); static_assert(std::is_pod_v);}; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = true; }; template<> struct native_is_valid { static const bool value = true; static const bool retval = false;}; // Bool as return does not work! diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 6eec02193..97cb4fe27 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5111,21 +5111,26 @@ void ChangeModelNative( AActor * self, AActor * invoker, FStateParamInfo * stateinfo, - FName modeldef, + int i_modeldef, int i_modelindex, const FString &p_modelpath, - FName model, + int i_model, int i_skinindex, const FString &p_skinpath, - FName skin, + int i_skin, int flags, int generatorindex, int i_animationindex, const FString &p_animationpath, - FName animation + int i_animation ) { if(!self) ThrowAbortException(X_READ_NIL, "In function parameter self"); + FName modeldef { ENamedName(i_modeldef) }; + FName model { ENamedName(i_model) }; + FName skin { ENamedName(i_skin) }; + FName animation { ENamedName(i_animation) }; + if (modeldef != NAME_None && PClass::FindClass(modeldef.GetChars()) == nullptr) { Printf("Attempt to pass invalid modeldef name %s in %s.", modeldef.GetChars(), self->GetCharacterName()); @@ -5322,7 +5327,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_ChangeModel, ChangeModelNative) PARAM_STRING_VAL(animationpath); PARAM_NAME(animation); - ChangeModelNative(self,stateowner,stateinfo,modeldef,modelindex,modelpath,model,skinindex,skinpath,skin,flags,generatorindex,animationindex,animationpath,animation); + ChangeModelNative(self,stateowner,stateinfo,modeldef.GetIndex(),modelindex,modelpath,model.GetIndex(),skinindex,skinpath,skin.GetIndex(),flags,generatorindex,animationindex,animationpath,animation.GetIndex()); return 0; } From abcc0421e4b31f5ed81da0d6260a3534b537cc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 26 Jun 2023 16:48:53 -0300 Subject: [PATCH 30/38] Fix size miscalculation for surfaceSkinIDs --- src/playsim/p_actionfunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 97cb4fe27..19ac2c32e 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5196,7 +5196,7 @@ void ChangeModelNative( TArray surfaceSkins; if(skinindex > 0) { - surfaceSkins.AppendFill(FNullTextureID(), skinindex - 1); + surfaceSkins.AppendFill(FNullTextureID(), skinindex); } surfaceSkins.Push(skindata); mobj->modelData->models.Push({queryModel, std::move(surfaceSkins)}); From a8b8de94d60346d0c89f63758d9138c9d5b786d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 26 Jun 2023 16:51:17 -0300 Subject: [PATCH 31/38] misc cleanup/fixes --- src/playsim/p_actionfunctions.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 19ac2c32e..2d9e488a1 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5183,11 +5183,6 @@ void ChangeModelNative( auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID(); - if(!(flags & CMDL_USESURFACESKIN) && mobj->modelData->skinIDs.Size() < skinindex) - { - mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size()); - } - if(mobj->modelData->models.Size() == modelindex) { @@ -5216,6 +5211,7 @@ void ChangeModelNative( { mobj->modelData->models[modelindex].surfaceSkinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->models[modelindex].surfaceSkinIDs.Size()); } + if(skinindex == mobj->modelData->models[modelindex].surfaceSkinIDs.Size()) { mobj->modelData->models[modelindex].surfaceSkinIDs.Push(skindata); @@ -5225,8 +5221,8 @@ void ChangeModelNative( mobj->modelData->models[modelindex].surfaceSkinIDs[skinindex] = skindata; } } - mobj->modelData->models[modelindex].modelID = queryModel; - mobj->modelData->modelFrameGenerators[modelindex] = generatorindex; + if(queryModel != -1) mobj->modelData->models[modelindex].modelID = queryModel; + if(generatorindex != -1) mobj->modelData->modelFrameGenerators[modelindex] = generatorindex; } if(mobj->modelData->animationIDs.Size() == animationindex) @@ -5240,6 +5236,11 @@ void ChangeModelNative( if (!(flags & CMDL_USESURFACESKIN)) { + if(mobj->modelData->skinIDs.Size() < skinindex) + { + mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size()); + } + if(mobj->modelData->skinIDs.Size() == skinindex) { mobj->modelData->skinIDs.Push(skindata); From 71d4eb66f2c16fb068eaabb1717544e8ad53c17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 28 Jun 2023 14:28:07 -0300 Subject: [PATCH 32/38] Clear Services Map during VM Shutdown --- src/common/objects/dobjtype.cpp | 3 +++ src/common/scripting/interface/vmnatives.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/common/objects/dobjtype.cpp b/src/common/objects/dobjtype.cpp index b39c930f8..f9ccc4c77 100644 --- a/src/common/objects/dobjtype.cpp +++ b/src/common/objects/dobjtype.cpp @@ -231,6 +231,8 @@ void PClass::StaticInit () // //========================================================================== +void ClearServices(); + void PClass::StaticShutdown () { if (WP_NOCHANGE != nullptr) @@ -238,6 +240,7 @@ void PClass::StaticShutdown () delete WP_NOCHANGE; } + ClearServices(); // delete all variables containing pointers to script functions. for (auto p : FunctionPtrList) { diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 2c7df6fb7..54cc0d2a9 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -57,8 +57,8 @@ static ZSMap AllServices; -static void MarkServices() { - +static void MarkServices() +{ ZSMap::Iterator it(AllServices); ZSMap::Pair* pair; while (it.NextPair(pair)) @@ -82,6 +82,11 @@ void InitServices() GC::AddMarkerFunc(&MarkServices); } +void ClearServices() +{ + AllServices.Clear(); +} + //========================================================================== From 602c7c4e249b7d903b3becce919d48c8450941a4 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Wed, 5 Jul 2023 07:38:55 +0200 Subject: [PATCH 33/38] fix UMAPINFO boss action clearing. This did not handle the case where the actions were cleared without adding new ones and also did not clear the MBF21 boss action flags. --- src/gamedata/umapinfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gamedata/umapinfo.cpp b/src/gamedata/umapinfo.cpp index d6b391039..006e4629a 100644 --- a/src/gamedata/umapinfo.cpp +++ b/src/gamedata/umapinfo.cpp @@ -42,6 +42,7 @@ struct UMapEntry FString InterText; FString InterTextSecret; TArray BossActions; + bool BossCleared = false; char levelpic[9] = ""; char nextmap[9] = ""; @@ -268,6 +269,7 @@ static int ParseStandardProperty(FScanner &scanner, UMapEntry *mape) // mark level free of boss actions classnum = special = tag = -1; mape->BossActions.Clear(); + mape->BossCleared = true; } else { @@ -446,11 +448,12 @@ void CommitUMapinfo(level_info_t *defaultinfo) levelinfo->InterMusic = map.intermusic; levelinfo->intermusicorder = 0; } - if (map.BossActions.Size() > 0) + if (map.BossActions.Size() > 0 || map.BossCleared) { // Setting a boss action will deactivate the flag based monster actions. levelinfo->specialactions = std::move(map.BossActions); levelinfo->flags &= ~(LEVEL_BRUISERSPECIAL | LEVEL_CYBORGSPECIAL | LEVEL_SPIDERSPECIAL | LEVEL_MAP07SPECIAL | LEVEL_MINOTAURSPECIAL | LEVEL_HEADSPECIAL | LEVEL_SORCERER2SPECIAL | LEVEL_SPECACTIONSMASK | LEVEL_SPECKILLMONSTERS); + levelinfo->flags3 &= ~(LEVEL3_E1M8SPECIAL | LEVEL3_E2M8SPECIAL | LEVEL3_E3M8SPECIAL | LEVEL3_E4M8SPECIAL | LEVEL3_E4M6SPECIAL); } const int exflags = FExitText::DEF_TEXT | FExitText::DEF_BACKDROP | FExitText::DEF_MUSIC; From e23bb092b4d1b0b6ed4c5466d4dd14db5d2eac29 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson <18584402+madame-rachelle@users.noreply.github.com> Date: Wed, 5 Jul 2023 09:20:16 -0400 Subject: [PATCH 34/38] Update README.md - use alternate vanity service for discord link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 227935d3c..7268877ea 100644 --- a/README.md +++ b/README.md @@ -24,5 +24,5 @@ To build GZDoom, please see the [wiki](https://zdoom.org/wiki/) and see the "Pro - https://zdoom.org/ - Home Page - https://forum.zdoom.org/ - Forum - https://zdoom.org/wiki/ - Wiki -- https://discord.gg/zdoom - Discord Server +- https://dsc.gg/zdoom - Discord Server - https://docs.google.com/spreadsheets/d/1pvwXEgytkor9SClCiDn4j5AH7FedyXS-ocCbsuQIXDU/edit?usp=sharing - Translation sheet (Google Docs) From 7e8bb6ea30f90f6434a5e69bf0238cd88361c619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 5 Jul 2023 21:31:43 -0300 Subject: [PATCH 35/38] fix steamapps folder case --- src/posix/i_steam.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index 15265a6e0..5945dff3a 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -187,7 +187,7 @@ TArray I_GetSteamPath() return result; } - SteamInstallFolders.Push(appSupportPath + "/Steam/SteamApps/common"); + SteamInstallFolders.Push(appSupportPath + "/Steam/steamapps/common"); #else char* home = getenv("HOME"); if(home != NULL && *home != '\0') @@ -210,7 +210,7 @@ TArray I_GetSteamPath() return result; } - regPath.Format("%s/.local/share/Steam/SteamApps/common", home); + regPath.Format("%s/.local/share/Steam/steamapps/common", home); SteamInstallFolders.Push(regPath); } #endif From 7235058f0990540562551036160589736224a892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 5 Jul 2023 21:31:52 -0300 Subject: [PATCH 36/38] scan secondary library folders on windows --- src/win32/i_steam.cpp | 128 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 5 deletions(-) diff --git a/src/win32/i_steam.cpp b/src/win32/i_steam.cpp index 056b59364..5b62ae435 100644 --- a/src/win32/i_steam.cpp +++ b/src/win32/i_steam.cpp @@ -80,6 +80,112 @@ #include "cmdlib.h" #include "i_interface.h" + +//TODO maybe move this code to a separate cpp file, so that there isn't code duplication between the win32 and posix backends +static void PSR_FindEndBlock(FScanner &sc) +{ + int depth = 1; + do + { + if(sc.CheckToken('}')) + --depth; + else if(sc.CheckToken('{')) + ++depth; + else + sc.MustGetAnyToken(); + } + while(depth); +} +static void PSR_SkipBlock(FScanner &sc) +{ + sc.MustGetToken('{'); + PSR_FindEndBlock(sc); +} +static bool PSR_FindAndEnterBlock(FScanner &sc, const char* keyword) +{ + // Finds a block with a given keyword and then enter it (opening brace) + // Should be closed with PSR_FindEndBlock + while(sc.GetToken()) + { + if(sc.TokenType == '}') + { + sc.UnGet(); + return false; + } + + sc.TokenMustBe(TK_StringConst); + if(!sc.Compare(keyword)) + { + if(!sc.CheckToken(TK_StringConst)) + PSR_SkipBlock(sc); + } + else + { + sc.MustGetToken('{'); + return true; + } + } + return false; +} +static TArray PSR_ReadBaseInstalls(FScanner &sc) +{ + TArray result; + + // Get a list of possible install directories. + while(sc.GetToken()) + { + if(sc.TokenType == '}') + break; + + sc.TokenMustBe(TK_StringConst); + FString key(sc.String); + if(key.Left(18).CompareNoCase("BaseInstallFolder_") == 0) + { + sc.MustGetToken(TK_StringConst); + result.Push(FString(sc.String) + "/steamapps/common"); + } + else + { + if(sc.CheckToken('{')) + PSR_FindEndBlock(sc); + else + sc.MustGetToken(TK_StringConst); + } + } + + return result; +} +static TArray ParseSteamRegistry(const char* path) +{ + TArray dirs; + + // Read registry data + FScanner sc; + if (sc.OpenFile(path)) + { + sc.SetCMode(true); + + // Find the SteamApps listing + if (PSR_FindAndEnterBlock(sc, "InstallConfigStore")) + { + if (PSR_FindAndEnterBlock(sc, "Software")) + { + if (PSR_FindAndEnterBlock(sc, "Valve")) + { + if (PSR_FindAndEnterBlock(sc, "Steam")) + { + dirs = PSR_ReadBaseInstalls(sc); + } + PSR_FindEndBlock(sc); + } + PSR_FindEndBlock(sc); + } + PSR_FindEndBlock(sc); + } + } + return dirs; +} + //========================================================================== // // QueryPathKey @@ -240,18 +346,30 @@ TArray I_GetSteamPath() "Doom 2/finaldoombase" }; - FString path; + FString steamPath; - if (!QueryPathKey(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", L"SteamPath", path)) + if (!QueryPathKey(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", L"SteamPath", steamPath)) { - if (!QueryPathKey(HKEY_LOCAL_MACHINE, L"Software\\Valve\\Steam", L"InstallPath", path)) + if (!QueryPathKey(HKEY_LOCAL_MACHINE, L"Software\\Valve\\Steam", L"InstallPath", steamPath)) return result; } - path += "/SteamApps/common/"; + + TArray paths = ParseSteamRegistry(steamPath + "/config/config.vdf"); + + for(FString &path : paths) + { + path.ReplaceChars('\\','/'); + path+="/"; + } + + paths.Push(steamPath + "/steamapps/common/"); for(unsigned int i = 0; i < countof(steam_dirs); ++i) { - result.Push(path + steam_dirs[i]); + for(const FString &path : paths) + { + result.Push(path + steam_dirs[i]); + } } return result; From bcfa43b7d6a5ace58649b6ccf42c0d72605e9346 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Tice Date: Wed, 5 Jul 2023 21:38:22 -0400 Subject: [PATCH 37/38] Replace .local/share/Steam with .steam/steam .local/share/Steam doesn't exist on all distros, but .steam/steam does. --- src/posix/i_steam.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index 5945dff3a..82c2c9d98 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -198,7 +198,7 @@ TArray I_GetSteamPath() // .steam at some point. Not sure if it's just my setup so I guess we // can fall back on it? if(!FileExists(regPath)) - regPath.Format("%s/.local/share/Steam/config/config.vdf", home); + regPath.Format("%s/.steam/steam/config/config.vdf", home); try { @@ -210,7 +210,7 @@ TArray I_GetSteamPath() return result; } - regPath.Format("%s/.local/share/Steam/steamapps/common", home); + regPath.Format("%s/.steam/steam/steamapps/common", home); SteamInstallFolders.Push(regPath); } #endif From 99850ea216ef13d56fb6e65e927aabd76d91b601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 8 Jul 2023 23:47:11 -0300 Subject: [PATCH 38/38] fix the ammocount parameter in Weapon.CheckAmmo --- wadsrc/static/zscript/actors/inventory/weapons.zs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/wadsrc/static/zscript/actors/inventory/weapons.zs b/wadsrc/static/zscript/actors/inventory/weapons.zs index d4aa0e57d..72f31b1f9 100644 --- a/wadsrc/static/zscript/actors/inventory/weapons.zs +++ b/wadsrc/static/zscript/actors/inventory/weapons.zs @@ -932,6 +932,7 @@ class Weapon : StateProvider int count1, count2; int enough, enoughmask; int lAmmoUse1; + int lAmmoUse2 = AmmoUse2; if (sv_infiniteammo || (Owner.FindInventory ('PowerInfiniteAmmo', true) != null)) { @@ -957,20 +958,21 @@ class Weapon : StateProvider count1 = (Ammo1 != null) ? Ammo1.Amount : 0; count2 = (Ammo2 != null) ? Ammo2.Amount : 0; - if (bDehAmmo && Ammo1 == null) - { - lAmmoUse1 = 0; - } - else if (ammocount >= 0 && bDehAmmo) + if (ammocount >= 0) { lAmmoUse1 = ammocount; + lAmmoUse2 = ammocount; + } + else if (bDehAmmo && Ammo1 == null) + { + lAmmoUse1 = 0; } else { lAmmoUse1 = AmmoUse1; } - enough = (count1 >= lAmmoUse1) | ((count2 >= AmmoUse2) << 1); + enough = (count1 >= lAmmoUse1) | ((count2 >= lAmmoUse2) << 1); if (useboth) { enoughmask = 3;