From 2d5061e81f91807ebe054790719c1ce8be7fb482 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Sep 2016 11:58:12 +0200 Subject: [PATCH 1/7] - fixed: DScroller did not initialize m_LastHeight in all situations. This caused a problem with the serializer because RapidJSON aborts the write of a floating point value if it is invalid. - ensure that floats are always written out. If the actual value causes an error (i.e. INF or NaN), write a 0 to guarantee proper formatting. --- src/p_scroll.cpp | 2 ++ src/serializer.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/p_scroll.cpp b/src/p_scroll.cpp index 2c7333a21..f2ece8b3d 100644 --- a/src/p_scroll.cpp +++ b/src/p_scroll.cpp @@ -259,6 +259,7 @@ DScroller::DScroller (EScroll type, double dx, double dy, m_Accel = accel; m_Parts = scrollpos; m_vdx = m_vdy = 0; + m_LastHeight = 0; if ((m_Control = control) != -1) m_LastHeight = sectors[control].CenterFloor () + sectors[control].CenterCeiling (); @@ -342,6 +343,7 @@ DScroller::DScroller (double dx, double dy, const line_t *l, m_vdx = m_vdy = 0; m_Accel = accel; m_Parts = scrollpos; + m_LastHeight = 0; if ((m_Control = control) != -1) m_LastHeight = sectors[control].CenterFloor() + sectors[control].CenterCeiling(); m_Affectee = int(l->sidedef[0] - sides); diff --git a/src/serializer.cpp b/src/serializer.cpp index 445a3b22b..47e096b7b 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -215,8 +215,14 @@ struct FWriter void Double(double k) { - if (mWriter1) mWriter1->Double(k); - else if (mWriter2) mWriter2->Double(k); + if (mWriter1) + { + if (!mWriter1->Double(k)) mWriter1->Double(0); + } + else if (mWriter2) + { + if (!mWriter2->Double(k)) mWriter2->Double(0); + } } }; From a83d1facdf15c8c869ce9bf99b4890a88e08cd88 Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Mon, 26 Sep 2016 20:31:09 -0400 Subject: [PATCH 2/7] Use GLOB_RECURSE and exclude file names with brackets, for a more complete list of PK3 source files for the IDE. # Conflicts: # CMakeLists.txt --- CMakeLists.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97c44355a..922406942 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ endif() # Simplify pk3 building, add_pk3(filename srcdirectory) function( add_pk3 PK3_NAME PK3_DIR ) + # message(STATUS "Creating build rule for PK3 ${PK3_NAME} ${PK3_DIR}") # Generate target name. Just use "pk3" for main pk3 target. string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} ) if( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) @@ -48,8 +49,19 @@ function( add_pk3 PK3_NAME PK3_DIR ) COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} DEPENDS zipdir ) endif() - # Grab a list of top-level PK3 folder files, so we can conveniently see them in the IDE - file(GLOB PK3_SRCS ${PK3_DIR}/*) + file(GLOB_RECURSE PK3_SRCS ${PK3_DIR}/*) + # We're specifically avoiding some gzdoom .png files with brackets in the + # file names here, because they confuse CMake. + # This only affects the list of source files shown in the IDE. + # It does not actually remove the files from the PK3 archive. + string(REPLACE "[" confusing_bracket PK3_SRCS "${PK3_SRCS}") + string(REPLACE "]" confusing_bracket PK3_SRCS "${PK3_SRCS}") + foreach(PK3_SRC ${PK3_SRCS}) + if(${PK3_SRC} MATCHES confusing_bracket) + # message(STATUS "Ignoring PK3 file name containing brackets "${PK3_SRC}) + list(REMOVE_ITEM PK3_SRCS ${PK3_SRC}) + endif() + endforeach() # Touch the zipdir executable here so that the pk3s are forced to # rebuild each time since their dependecy has "changed." add_custom_target( ${PK3_TARGET} ALL From 3ecd20c4a163f8f2fd77fda745898492fc5de36e Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Tue, 27 Sep 2016 19:48:04 -0400 Subject: [PATCH 3/7] Enhance IDE list of PK3 source files using a more complicated approach than I had hoped for. --- CMakeLists.txt | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 922406942..541347f14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,24 @@ if(CMAKE_CROSSCOMPILING) include(${IMPORT_EXECUTABLES}) endif() +# Recursive function to place PK3 archive source files into a hierarchy of source file in the IDE +function( assort_pk3_source_folder FOLDER_NAME PK3_DIR ) + # Assort source files into folders in the IDE + file(GLOB PK3_SRCS ${PK3_DIR}/*) # Create list of all files in this folder + foreach(PK3_SRC ${PK3_SRCS}) + # If there are subfolders, recurse into them + if(IS_DIRECTORY ${PK3_SRC}) + get_filename_component(DIRNAME ${PK3_SRC} NAME) + # Exclude folder from list of source files + list(REMOVE_ITEM PK3_SRCS ${PK3_SRC}) + # Recurse deeper into the filesystem folder tree + assort_pk3_source_folder( ${FOLDER_NAME}\\${DIRNAME} ${PK3_SRC} ) + endif() + # Assign IDE group for current top-level source files + source_group(${FOLDER_NAME} FILES ${PK3_SRCS}) + endforeach() +endfunction() + # Simplify pk3 building, add_pk3(filename srcdirectory) function( add_pk3 PK3_NAME PK3_DIR ) # message(STATUS "Creating build rule for PK3 ${PK3_NAME} ${PK3_DIR}") @@ -49,25 +67,33 @@ function( add_pk3 PK3_NAME PK3_DIR ) COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} DEPENDS zipdir ) endif() + # Create a list of source files for this PK3, for use in the IDE + # Phase 1: Create a list of all source files for this PK3 archive, except + # for a couple of strife image file names that confuse CMake. file(GLOB_RECURSE PK3_SRCS ${PK3_DIR}/*) - # We're specifically avoiding some gzdoom .png files with brackets in the + # Exclude from the source list some gzdoom .png files with brackets in the # file names here, because they confuse CMake. # This only affects the list of source files shown in the IDE. # It does not actually remove the files from the PK3 archive. + # First replace that toxic bracket character with something we can handle string(REPLACE "[" confusing_bracket PK3_SRCS "${PK3_SRCS}") string(REPLACE "]" confusing_bracket PK3_SRCS "${PK3_SRCS}") - foreach(PK3_SRC ${PK3_SRCS}) + foreach(PK3_SRC ${PK3_SRCS}) # All source files at all levels + # Exclude those quarantined source file source file names that once had a bracket if(${PK3_SRC} MATCHES confusing_bracket) # message(STATUS "Ignoring PK3 file name containing brackets "${PK3_SRC}) list(REMOVE_ITEM PK3_SRCS ${PK3_SRC}) endif() endforeach() + # Phase 2: Create the PK3 build rule, including the source file list for the IDE # Touch the zipdir executable here so that the pk3s are forced to - # rebuild each time since their dependecy has "changed." + # rebuild each time since their dependency has "changed." add_custom_target( ${PK3_TARGET} ALL COMMAND ${CMAKE_COMMAND} -E touch $ DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} SOURCES ${PK3_SRCS}) + # Phase 3: Assign source files to a nice folder structure in the IDE + assort_pk3_source_folder("Source Files" ${PK3_DIR}) endfunction() # Macro for building libraries without debugging information From b400cf145499b8d0cda654938f5fc658bf929df9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 30 Sep 2016 10:50:41 +0200 Subject: [PATCH 4/7] - added an integrity check to the SNDINFO parser to detect and eliminate recursive links. Normally these would crash the sound code later. - allow recursive linking of $random definitions (as long as they do not link back, see above.) - fixed the sound precaching which did not handle $alias inside $random. Normally this went undetected but in cases where the random sound index was the same as a sound index in the current link chain this could hang the function. --- src/s_advsound.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++-- src/s_sound.cpp | 15 ++++--- 2 files changed, 107 insertions(+), 11 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index b073070fd..c1c19aabf 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -51,6 +51,7 @@ #include "i_system.h" #include "d_player.h" #include "serializer.h" +#include "v_text.h" // MACROS ------------------------------------------------------------------ @@ -326,6 +327,99 @@ void S_HashSounds () } } +//========================================================================== +// +// S_CheckIntegrity +// +// Scans the entire sound list and looks for recursive definitions. +//========================================================================== + +static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArray &chain) +{ + sfxinfo_t *me = sfx; + bool success = true; + unsigned siz = chain.Size(); + + if (sfx->bPlayerReserve) + { + return true; + } + + // There is a bad link in here, but let's report it only for the sound that contains the broken definition. + // Once that sound has been disabled this one will work again. + if (chain.Find(sfx) < chain.Size()) + { + return true; + } + chain.Push(sfx); + + if (me->bRandomHeader) + { + const FRandomSoundList *list = &S_rnd[me->link]; + for (int i = 0; i < list->NumSounds; ++i) + { + auto rsfx = &S_sfx[list->Sounds[i]]; + if (rsfx == startsfx) + { + Printf(TEXTCOLOR_RED "recursive sound $random found for %s:\n", startsfx->name); + success = false; + for (unsigned i = 1; i %s\n", chain[i]->name); + } + } + else + { + success &= S_CheckSound(startsfx, rsfx, chain); + } + } + } + else if (me->link != sfxinfo_t::NO_LINK) + { + me = &S_sfx[me->link]; + if (me == startsfx) + { + Printf(TEXTCOLOR_RED "recursive sound $alias found for %s:\n", startsfx->name); + success = false; + for (unsigned i = 1; i %s\n", chain[i]->name); + } + chain.Resize(siz); + } + else + { + success &= S_CheckSound(startsfx, me, chain); + } + } + chain.Pop(); + return success; +} + +void S_CheckIntegrity() +{ + TArray chain; + TArray broken; + + broken.Resize(S_sfx.Size()); + memset(&broken[0], 0, sizeof(bool)*S_sfx.Size()); + for (unsigned i = 0; i < S_sfx.Size(); i++) + { + auto &sfx = S_sfx[i]; + broken[i] = !S_CheckSound(&sfx, &sfx, chain); + } + for (unsigned i = 0; i < S_sfx.Size(); i++) + { + if (broken[i]) + { + auto &sfx = S_sfx[i]; + Printf(TEXTCOLOR_RED "Sound %s has been disabled\n", sfx.name); + sfx.bRandomHeader = false; + sfx.link = 0; // link to the empty sound. + } + } +} + //========================================================================== // // S_PickReplacement @@ -334,13 +428,12 @@ void S_HashSounds () // is not the head of a random list, then the sound passed is returned. //========================================================================== -int S_PickReplacement (int refid) +int S_PickReplacement(int refid) { - if (S_sfx[refid].bRandomHeader) + while (S_sfx[refid].bRandomHeader) { const FRandomSoundList *list = &S_rnd[S_sfx[refid].link]; - - return list->Sounds[pr_randsound() % list->NumSounds]; + refid = list->Sounds[pr_randsound() % list->NumSounds]; } return refid; } @@ -941,6 +1034,7 @@ void S_ParseSndInfo (bool redefine) S_ShrinkPlayerSoundLists (); sfx_empty = Wads.CheckNumForName ("dsempty", ns_sounds); + S_CheckIntegrity(); } //========================================================================== @@ -961,6 +1055,7 @@ void S_AddLocalSndInfo(int lump) } S_ShrinkPlayerSoundLists (); + S_CheckIntegrity(); } //========================================================================== diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 06df0dbad..524b12175 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -522,18 +522,19 @@ void S_CacheSound (sfxinfo_t *sfx) { return; } - else if (sfx->bRandomHeader) + sfxinfo_t *orig = sfx; + while (!sfx->bRandomHeader && sfx->link != sfxinfo_t::NO_LINK) { - S_CacheRandomSound (sfx); + sfx = &S_sfx[sfx->link]; + } + if (sfx->bRandomHeader) + { + S_CacheRandomSound(sfx); } else { - while (sfx->link != sfxinfo_t::NO_LINK) - { - sfx = &S_sfx[sfx->link]; - } + S_LoadSound(sfx); sfx->bUsed = true; - S_LoadSound (sfx); } } } From e9ce699042878b58c155acfc089cda2cb9ff785b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 1 Oct 2016 12:17:15 +0300 Subject: [PATCH 5/7] Fixed compilation with GCC or Clang --- src/s_advsound.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index c1c19aabf..0db9365c2 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -361,11 +361,11 @@ static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArraySounds[i]]; if (rsfx == startsfx) { - Printf(TEXTCOLOR_RED "recursive sound $random found for %s:\n", startsfx->name); + Printf(TEXTCOLOR_RED "recursive sound $random found for %s:\n", startsfx->name.GetChars()); success = false; for (unsigned i = 1; i %s\n", chain[i]->name); + Printf(TEXTCOLOR_ORANGE " -> %s\n", chain[i]->name.GetChars()); } } else @@ -379,11 +379,11 @@ static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArraylink]; if (me == startsfx) { - Printf(TEXTCOLOR_RED "recursive sound $alias found for %s:\n", startsfx->name); + Printf(TEXTCOLOR_RED "recursive sound $alias found for %s:\n", startsfx->name.GetChars()); success = false; for (unsigned i = 1; i %s\n", chain[i]->name); + Printf(TEXTCOLOR_ORANGE " -> %s\n", chain[i]->name.GetChars()); } chain.Resize(siz); } @@ -413,7 +413,7 @@ void S_CheckIntegrity() if (broken[i]) { auto &sfx = S_sfx[i]; - Printf(TEXTCOLOR_RED "Sound %s has been disabled\n", sfx.name); + Printf(TEXTCOLOR_RED "Sound %s has been disabled\n", sfx.name.GetChars()); sfx.bRandomHeader = false; sfx.link = 0; // link to the empty sound. } From 099bfed806bb3b72824ac6ae8015df99ce90b392 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 1 Oct 2016 12:27:24 +0300 Subject: [PATCH 6/7] Fixed endianness issue with precaching of MUS files --- src/sound/music_mus_midiout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/music_mus_midiout.cpp b/src/sound/music_mus_midiout.cpp index 17426a798..58b86201a 100644 --- a/src/sound/music_mus_midiout.cpp +++ b/src/sound/music_mus_midiout.cpp @@ -211,11 +211,11 @@ bool MUSSong2::CheckDone() void MUSSong2::Precache() { - TArray work(MusHeader->NumInstruments); + TArray work(LittleShort(MusHeader->NumInstruments)); const BYTE *used = (BYTE *)MusHeader + sizeof(MUSHeader) / sizeof(BYTE); int i, k; - for (i = k = 0; i < MusHeader->NumInstruments; ++i) + for (i = k = 0; i < LittleShort(MusHeader->NumInstruments); ++i) { BYTE instr = used[k++]; WORD val; From 7720359f4cf22266bb4b9bb09b1d956322197819 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 1 Oct 2016 12:08:07 +0200 Subject: [PATCH 7/7] - fixed: AActor::Masacre must restore the flag if it cannot kill the monster. --- src/p_mobj.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 400b41798..90a800fa7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1323,6 +1323,9 @@ bool AActor::Massacre () if (health > 0) { + auto f = flags; + auto f2 = flags2; + flags |= MF_SHOOTABLE; flags2 &= ~(MF2_DORMANT|MF2_INVULNERABLE); do @@ -1331,6 +1334,12 @@ bool AActor::Massacre () P_DamageMobj (this, NULL, NULL, TELEFRAG_DAMAGE, NAME_Massacre); } while (health != prevhealth && health > 0); //abort if the actor wasn't hurt. + if (health > 0) + { + // restore flags if this did not kill the monster. + flags = f; + flags2 = f2; + } return health <= 0; } return false;