From e1266685d947b1b2ea07a6390e142ab6f150d0df Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 10:29:02 +0300 Subject: [PATCH 01/19] Use proper function to set sound offsets in samples This fixes the following compilation warnings: src\sound\oalsound.cpp(1588): warning C4244: 'argument': conversion from 'unsigned int' to 'ALfloat', possible loss of data src\sound\oalsound.cpp(1796): warning C4244: 'argument': conversion from 'unsigned int' to 'ALfloat', possible loss of data --- src/sound/oalsound.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index f323f858a..77068cf96 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1585,7 +1585,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int else { if((chanflags&SNDF_ABSTIME)) - alSourcef(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo); + alSourcei(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo); else { float offset = std::chrono::duration_cast>( @@ -1793,7 +1793,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener else { if((chanflags&SNDF_ABSTIME)) - alSourcef(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo); + alSourcei(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo); else { float offset = std::chrono::duration_cast>( From 3d100e65789f6adcb09e9dc71f1316af501cc375 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 10:00:27 +0300 Subject: [PATCH 02/19] Removed unused #include's from music_libsndfile.cpp --- src/sound/musicformats/music_libsndfile.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index 91951c18b..5e7d620f3 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -38,10 +38,7 @@ #include "c_cvars.h" #include "critsec.h" #include "v_text.h" -#include "files.h" #include "templates.h" -#include "sndfile_decoder.h" -#include "mpg123_decoder.h" #include "m_fixed.h" // MACROS ------------------------------------------------------------------ From f7b8dadedbb04af625582ae7469d80508fdc7645 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 10:05:34 +0300 Subject: [PATCH 03/19] Made size of music stream buffer customizable Use snd_streambuffersize CVAR to set buffer size in kilobytes, from 16 to 1024 Name of existed CVAR from removed FMOD sound backend is used Increased default size of stream buffer to 64 kB like it was in FMOD backend --- src/sound/musicformats/music_libsndfile.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index 5e7d620f3..bdba19b4a 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -79,6 +79,18 @@ protected: // PUBLIC DATA DEFINITIONS ------------------------------------------------- +CUSTOM_CVAR(Int, snd_streambuffersize, 64, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 16) + { + self = 16; + } + else if (self > 1024) + { + self = 1024; + } +} + // PRIVATE DATA DEFINITIONS ------------------------------------------------ // CODE -------------------------------------------------------------------- @@ -206,7 +218,7 @@ SndFileSong::SndFileSong(FileReader *reader, SoundDecoder *decoder, uint32_t loo Reader = reader; Decoder = decoder; Channels = iChannels == ChannelConfig_Stereo? 2:1; - m_Stream = GSnd->CreateStream(Read, 32*1024, iChannels == ChannelConfig_Stereo? 0 : SoundStream::Mono, SampleRate, this); + m_Stream = GSnd->CreateStream(Read, snd_streambuffersize * 1024, iChannels == ChannelConfig_Stereo? 0 : SoundStream::Mono, SampleRate, this); } //========================================================================== From 132ea30f0d50cfeed092c40ddac1aa56827d8df7 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 15:02:31 +0300 Subject: [PATCH 04/19] Updated AppVeyor configuration Added packaging of build artifact which includes executable and .pk3's Removed obsolete environment variables for dependencies Permalinks to the last successful builds: Win32 Release: https://ci.appveyor.com/api/projects/coelckers/gzdoom/artifacts/gzdoom.zip?branch=master&job=Configuration%3A%20Release%3B%20Platform%3A%20Win32 x64 Release: https://ci.appveyor.com/api/projects/coelckers/gzdoom/artifacts/gzdoom.zip?branch=master&job=Configuration%3A%20Release%3B%20Platform%3A%20x64 Win32 Debug: https://ci.appveyor.com/api/projects/coelckers/gzdoom/artifacts/gzdoom.zip?branch=master&job=Configuration%3A%20Debug%3B%20Platform%3A%20Win32 x64 Debug: https://ci.appveyor.com/api/projects/coelckers/gzdoom/artifacts/gzdoom.zip?branch=master&job=Configuration%3A%20Debug%3B%20Platform%3A%20x64 --- .appveyor.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index c02cfca64..48b51af0b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -21,8 +21,6 @@ before_build: - cd build - if "%PLATFORM%"=="Win32" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 - if "%PLATFORM%"=="x64" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 Win64 - - set DEPS_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\ci_deps_win\include - - set DEPS_LIB_DIR=%APPVEYOR_BUILD_FOLDER%\ci_deps_win\lib\%PLATFORM% - cmake -G "%CMAKE_GENERATOR_NAME%" -T "v140_xp" -DCMAKE_BUILD_TYPE="%CONFIGURATION%" .. @@ -32,6 +30,13 @@ build: parallel: true verbosity: minimal +after_build: + - set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\ + - 7z a ..\gzdoom.zip "%OUTPUT_DIR%gzdoom.exe" "%OUTPUT_DIR%*.pk3" + +artifacts: + - path: gzdoom.zip + notifications: - provider: Email on_build_success: false From 60fe34349e39e78f3a5db5e07d6c80448f6e6cc7 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 16:54:22 +0300 Subject: [PATCH 05/19] Fixed applying of speed factor to player Part of https://forum.zdoom.org/viewtopic.php?t=56333 --- wadsrc/static/zscript/shared/player.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index b799f98c2..1223b6bf8 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -817,7 +817,7 @@ class PlayerPawn : Actor native double factor = 1.; for(let it = Inv; it != null; it = it.Inv) { - factor *= Inv.GetSpeedFactor (); + factor *= it.GetSpeedFactor (); } forward *= factor; side *= factor; From 26325edddc9ff311b2072745780e764ba4976973 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 May 2017 17:00:09 +0200 Subject: [PATCH 06/19] - fixed Ogg tag validation. --- src/sound/musicformats/music_libsndfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index bdba19b4a..d14c6b3ad 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -130,7 +130,7 @@ void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end } c -= 3; int len = c[0] + 256*c[1] + 65536*c[2]; - if (c[3] || len > 1000000 || len <= (eqp - c + 1)) + if (c[3] || len > 1000000 || len < (eqp - c - 3)) { // length looks fishy so retry with the next '=' continue; From bdac1c3ad1a72feeff68e9ef1a0e62cf86180012 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 8 May 2017 18:06:15 +0300 Subject: [PATCH 07/19] Fixed problem with looping of particular music tracks Part of https://forum.zdoom.org/viewtopic.php?t=56333 --- src/sound/musicformats/music_libsndfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index d14c6b3ad..85b670a6b 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -339,7 +339,7 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat if (currentpos + framestoread > song->Loop_End) { size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2; - size_t endlen = song->Decoder->read(buff, endblock); + size_t endlen = song->Decoder->read(buff, 0 == endblock ? len : endblock); if (endlen != 0) { buff = buff + endlen; From 4a5fe65ce8fffefdd4cd257f6e4c54b815a3c745 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 May 2017 19:12:29 +0200 Subject: [PATCH 08/19] - added missing check for RenderStyle None to GL weapon drawer. --- src/gl/scene/gl_weapon.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 2d2d827c6..23610fb01 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -338,6 +338,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { RenderStyle = rs.first; } + if (RenderStyle.BlendOp == STYLEOP_None) continue; if (vis.Invert) { From 762ba13cd94a792a54fdb372dd34523e83444d16 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 May 2017 19:30:51 +0200 Subject: [PATCH 09/19] - store the last found OpenGL version in the INI so that modern GL related options can be removed when running old hardware with software rendering. --- src/d_main.cpp | 2 ++ src/gl/compatibility/gl_20.cpp | 2 ++ src/gl/system/gl_interface.cpp | 4 +++- src/gl/system/gl_swframebuffer.cpp | 8 ++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index bed80387b..12acc62f5 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -132,6 +132,7 @@ extern void M_SetDefaultMode (); extern void G_NewInit (); extern void SetupPlayerClasses (); extern void HUD_InitHud(); +void gl_PatchMenu(); // remove modern OpenGL options on old hardware. void DeinitMenus(); const FIWADInfo *D_FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad); @@ -2639,6 +2640,7 @@ void D_DoomMain (void) } V_Init2(); + gl_PatchMenu(); UpdateJoystickMenu(NULL); v = Args->CheckValue ("-loadgame"); diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index d29823b75..d714d3e46 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -53,6 +53,7 @@ CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) //========================================================================== // @@ -64,6 +65,7 @@ CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) void gl_PatchMenu() { // Radial fog and Doom lighting are not available without full shader support. + if (!gl_legacy_mode) return; FOptionValues **opt = OptionValues.CheckKey("LightingModes"); if (opt != NULL) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 1a3f4b1ae..308d741bb 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -42,6 +42,8 @@ void gl_PatchMenu(); static TArray m_Extensions; RenderContext gl; +EXTERN_CVAR(Bool, gl_legacy_mode) + //========================================================================== // // @@ -311,8 +313,8 @@ void gl_LoadExtensions() FUDGE_FUNC(glRenderbufferStorage, EXT); FUDGE_FUNC(glBindRenderbuffer, EXT); FUDGE_FUNC(glCheckFramebufferStatus, EXT); - gl_PatchMenu(); } + gl_legacy_mode = gl.legacyMode; } //========================================================================== diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index 44d3b6d8b..fd0bb395e 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -92,6 +92,7 @@ EXTERN_CVAR(Float, Gamma) EXTERN_CVAR(Bool, vid_vsync) EXTERN_CVAR(Float, transsouls) EXTERN_CVAR(Int, vid_refreshrate) +EXTERN_CVAR(Bool, gl_legacy_mode) CVAR(Int, vid_max_width, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, vid_max_height, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -205,6 +206,13 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, const char *glversion = (const char*)glGetString(GL_VERSION); bool isGLES = (glversion && strlen(glversion) > 10 && memcmp(glversion, "OpenGL ES ", 10) == 0); + + // GL 3.0 is mostly broken on MESA drivers which really are the only relevant case here that doesn't fulfill the requirements based on version number alone. +#ifdef _WIN32 + gl_legacy_mode = !ogl_IsVersionGEQ(3, 0); +#else + gl_legacy_mode = !ogl_IsVersionGEQ(3, 1); +#endif if (!isGLES && ogl_IsVersionGEQ(3, 0) == 0) { Printf("OpenGL acceleration requires at least OpenGL 3.0. No Acceleration will be used.\n"); From c6a516089ec52d6ae758357de23b186fb838c77e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 May 2017 22:46:35 +0200 Subject: [PATCH 10/19] - fixed: OPLio::WriteTremolo wrote the wrong value for operator #0. --- src/sound/oplsynth/oplio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/oplsynth/oplio.cpp b/src/sound/oplsynth/oplio.cpp index e810a58c1..fb4d507a7 100644 --- a/src/sound/oplsynth/oplio.cpp +++ b/src/sound/oplsynth/oplio.cpp @@ -420,7 +420,7 @@ void OPLio::WriteTremolo(uint32_t channel, struct GenMidiVoice *voice, bool vibr val2 |= 0x40; } WriteOperator(OPL_REGS_TREMOLO, channel, 1, val2); - WriteOperator(OPL_REGS_TREMOLO, channel, 0, val2); + WriteOperator(OPL_REGS_TREMOLO, channel, 0, val1); } //---------------------------------------------------------------------------- From 8be7ff01dd0cbdfd83b9457ff42c05b9ea7e328f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 May 2017 09:57:38 +0200 Subject: [PATCH 11/19] - removed some pointless restrictions from AActor::IsOkayToAttack which prevented its use on normal monsters. This all made sense as long as the function was only used internally but that's not the case anymore. --- src/p_mobj.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f770d037a..b87d37fd6 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3823,28 +3823,22 @@ DEFINE_ACTION_FUNCTION(AActor, PlayActiveSound) bool AActor::IsOkayToAttack (AActor *link) { - if (!(player // Original AActor::IsOkayToAttack was only for players - // || (flags & MF_FRIENDLY) // Maybe let friendly monsters use the function as well? - || (flags5 & MF5_SUMMONEDMONSTER) // AMinotaurFriend has its own version, generalized to other summoned monsters - || (flags2 & MF2_SEEKERMISSILE))) // AHolySpirit and AMageStaffFX2 as well, generalized to other seeker missiles - { // Normal monsters and other actors always return false. - return false; - } // Standard things to eliminate: an actor shouldn't attack itself, // or a non-shootable, dormant, non-player-and-non-monster actor. if (link == this) return false; if (!(link->player||(link->flags3 & MF3_ISMONSTER)))return false; if (!(link->flags & MF_SHOOTABLE)) return false; if (link->flags2 & MF2_DORMANT) return false; + if (link->flags7 & MF7_NEVERTARGET) return false; // NEVERTARGET means just that. // An actor shouldn't attack friendly actors. The reference depends // on the type of actor: for a player's actor, itself; for a projectile, // its target; and for a summoned minion, its tracer. - AActor * Friend = NULL; - if (player) Friend = this; - else if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer; + AActor * Friend; + if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer; else if (flags2 & MF2_SEEKERMISSILE) Friend = target; else if ((flags & MF_FRIENDLY) && FriendPlayer) Friend = players[FriendPlayer-1].mo; + else Friend = this; // Friend checks if (link == Friend) return false; From 2bf8e8f1c0249fb41e6923c6794569f2055d4f26 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 May 2017 12:20:49 +0200 Subject: [PATCH 12/19] - fixed: InitClipper was missing a call to Clipper.Clear. --- src/gl/scene/gl_scenedrawer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 00426e36b..9209e6dad 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -69,6 +69,7 @@ public: void InitClipper(angle_t a1, angle_t a2) { + clipper.Clear(); clipper.SafeAddClipRangeRealAngles(a1, a2); } From 0a8083e2802cb8814913c7a3187ee3601554f078 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 May 2017 19:04:07 +0200 Subject: [PATCH 13/19] - fixed default obituary handling for predefined damagetypes. --- src/p_interaction.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 35e2bf7bc..7a9bdafe8 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -187,6 +187,7 @@ void SexMessage (const char *from, char *to, int gender, const char *victim, con void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgflags) { FName mod; + FString ret; const char *message; const char *messagename; char gendermessage[1024]; @@ -218,17 +219,17 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf } FString obit = DamageTypeDefinition::GetObituary(mod); - if (attacker == nullptr) messagename = obit; + if (attacker == nullptr && obit.IsNotEmpty()) messagename = obit; else { switch (mod) { - case NAME_Suicide: message = "$OB_SUICIDE"; break; - case NAME_Falling: message = "$OB_FALLING"; break; - case NAME_Crush: message = "$OB_CRUSH"; break; - case NAME_Exit: message = "$OB_EXIT"; break; - case NAME_Drowning: message = "$OB_WATER"; break; - case NAME_Slime: message = "$OB_SLIME"; break; + case NAME_Suicide: messagename = "$OB_SUICIDE"; break; + case NAME_Falling: messagename = "$OB_FALLING"; break; + case NAME_Crush: messagename = "$OB_CRUSH"; break; + case NAME_Exit: messagename = "$OB_EXIT"; break; + case NAME_Drowning: messagename = "$OB_WATER"; break; + case NAME_Slime: messagename = "$OB_SLIME"; break; case NAME_Fire: messagename = "$OB_LAVA"; break; } } @@ -250,7 +251,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf IFVIRTUALPTR(attacker, AActor, GetObituary) { VMValue params[] = { attacker, self, inflictor, mod.GetIndex(), !!(dmgflags & DMG_PLAYERATTACK) }; - FString ret; VMReturn rett(&ret); VMCall(func, params, countof(params), &rett, 1); if (ret.IsNotEmpty()) message = ret; From 60cc91e000c3994466b568eef043afe979e2d31f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 8 May 2017 16:59:31 -0700 Subject: [PATCH 14/19] Properly unload the backend sound buffers --- src/s_sound.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index d2a830fef..ea12fe97e 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -594,15 +594,14 @@ void S_CacheSound (sfxinfo_t *sfx) void S_UnloadSound (sfxinfo_t *sfx) { + if (sfx->data3d.isValid() && sfx->data != sfx->data3d) + GSnd->UnloadSound(sfx->data3d); if (sfx->data.isValid()) - { - if(sfx->data3d.isValid() && sfx->data != sfx->data3d) - GSnd->UnloadSound(sfx->data3d); GSnd->UnloadSound(sfx->data); - sfx->data.Clear(); - sfx->data3d.Clear(); + if (sfx->data.isValid() || sfx->data3d.isValid()) DPrintf(DMSG_NOTIFY, "Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); - } + sfx->data.Clear(); + sfx->data3d.Clear(); } //========================================================================== From fd8613a11e7e22c62300b5e3bc29fec3b329189b Mon Sep 17 00:00:00 2001 From: svdijk Date: Tue, 9 May 2017 20:34:57 +0200 Subject: [PATCH 15/19] CMake: Fix building on 32-bit Linux (Core 2 Duo) again. --- src/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95ab613c0..a9b65cb1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1265,12 +1265,13 @@ if( CMAKE_COMPILER_IS_GNUCXX ) set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" ) endif() if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) - # Need to enable intrinsics for this file. + # Need to enable intrinsics for these files. if( SSE_MATTERS ) set_source_files_properties( - x86.cpp - swrenderer/r_all.cpp + gl/system/gl_swframebuffer.cpp polyrenderer/poly_all.cpp + swrenderer/r_all.cpp + x86.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" ) endif() endif() From 7ad61a97edbc2f0f73488388cb14b2a9e66038e6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 9 May 2017 14:04:30 -0700 Subject: [PATCH 16/19] Fix handling long wait times on POSIX's I_WaitVBL usleep only works for sleeping up to one second. The function is also deprecated and nanosleep should be used instead. --- src/posix/sdl/i_system.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index 753589819..02dc270e4 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -113,7 +113,12 @@ void I_WaitVBL (int count) { // I_WaitVBL is never used to actually synchronize to the // vertical blank. Instead, it's used for delay purposes. - usleep (1000000 * count / 70); + struct timespec delay, rem; + delay.tv_sec = count / 70; + /* Avoid overflow. Microsec res should be good enough. */ + delay.tv_nsec = (count%70)*1000000/70 * 1000; + while(nanosleep(&delay, &rem) == -1 && errno == EINTR) + delay = rem; } // From f492e92cb5c3214a096c35934b0055c35f4be56c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 10 May 2017 02:43:00 +0200 Subject: [PATCH 17/19] - Handle degenerate triangles either sent as input or caused by clipping --- src/polyrenderer/drawers/poly_triangle.cpp | 32 +++++++++++++++++----- src/polyrenderer/drawers/poly_triangle.h | 1 + src/polyrenderer/drawers/screen_triangle.h | 32 ++++++++++++---------- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index 19628cf47..1cf9609cc 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -152,8 +152,28 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, return sv; } +bool PolyTriangleDrawer::is_degenerate(const ShadedTriVertex *vert) +{ + // A degenerate triangle has a zero cross product for two of its sides. + float ax = vert[1].x - vert[0].x; + float ay = vert[1].y - vert[0].y; + float az = vert[1].w - vert[0].w; + float bx = vert[2].x - vert[0].x; + float by = vert[2].y - vert[0].y; + float bz = vert[2].w - vert[0].w; + float crossx = ay * bz - az * by; + float crossy = az * bx - ax * bz; + float crossz = ax * by - ay * bx; + float crosslengthsqr = crossx * crossx + crossy * crossy + crossz * crossz; + return crosslengthsqr <= 1.e-6f; +} + void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread) { + // Reject triangle if degenerate + if (is_degenerate(vert)) + return; + // Cull, clip and generate additional vertices as needed TriVertex clippedvert[max_additional_vertices]; int numclipvert = clipedge(vert, clippedvert); @@ -224,14 +244,13 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool // Draw screen triangles if (ccw) { - for (int i = numclipvert; i > 1; i--) + for (int i = numclipvert - 1; i > 1; i--) { args->v1 = &clippedvert[numclipvert - 1]; args->v2 = &clippedvert[i - 1]; args->v3 = &clippedvert[i - 2]; - args->CalculateGradients(); - - ScreenTriangle::Draw(args, thread); + if (args->CalculateGradients()) + ScreenTriangle::Draw(args, thread); } } else @@ -241,9 +260,8 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool args->v1 = &clippedvert[0]; args->v2 = &clippedvert[i - 1]; args->v3 = &clippedvert[i]; - args->CalculateGradients(); - - ScreenTriangle::Draw(args, thread); + if (args->CalculateGradients()) + ScreenTriangle::Draw(args, thread); } } } diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index c939149d3..c663cd2d0 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -47,6 +47,7 @@ private: static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v); static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread); static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread); + static bool is_degenerate(const ShadedTriVertex *vertices); static int clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert); diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 3dd4c24eb..4339edaf4 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -66,29 +66,31 @@ struct TriDrawTriangleArgs ScreenTriangleStepVariables gradientX; ScreenTriangleStepVariables gradientY; - void CalculateGradients() + bool CalculateGradients() { - gradientX.W = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w); - gradientY.W = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w); - gradientX.U = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); - gradientY.U = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); - gradientX.V = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); - gradientY.V = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); + float bottomX = (v2->x - v3->x) * (v1->y - v3->y) - (v1->x - v3->x) * (v2->y - v3->y); + float bottomY = (v1->x - v3->x) * (v2->y - v3->y) - (v2->x - v3->x) * (v1->y - v3->y); + if ((bottomX >= -FLT_EPSILON && bottomX <= FLT_EPSILON) || (bottomY >= -FLT_EPSILON && bottomY <= FLT_EPSILON)) + return false; + + gradientX.W = FindGradientX(bottomX, v1->w, v2->w, v3->w); + gradientY.W = FindGradientY(bottomY, v1->w, v2->w, v3->w); + gradientX.U = FindGradientX(bottomX, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); + gradientY.U = FindGradientY(bottomY, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); + gradientX.V = FindGradientX(bottomX, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); + gradientY.V = FindGradientY(bottomY, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); + return true; } private: - static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2) + float FindGradientX(float bottomX, float c0, float c1, float c2) { - float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2); - float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2); - return top / bottom; + return ((c1 - c2) * (v1->y - v3->y) - (c0 - c2) * (v2->y - v3->y)) / bottomX; } - static float FindGradientY(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2) + float FindGradientY(float bottomY, float c0, float c1, float c2) { - float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2); - float bottom = (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2); - return top / bottom; + return ((c1 - c2) * (v1->x - v3->x) - (c0 - c2) * (v2->x - v3->x)) / bottomY; } }; From 092b339c8faadfd8bd4964bf8c553025d9532f96 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 9 May 2017 18:08:00 -0700 Subject: [PATCH 18/19] Replace usleep with nanosleep for macOS too --- src/posix/cocoa/i_system.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/posix/cocoa/i_system.mm b/src/posix/cocoa/i_system.mm index a9cb70809..7b7c6dcc2 100644 --- a/src/posix/cocoa/i_system.mm +++ b/src/posix/cocoa/i_system.mm @@ -77,7 +77,12 @@ void I_WaitVBL(const int count) { // I_WaitVBL is never used to actually synchronize to the // vertical blank. Instead, it's used for delay purposes. - usleep(1000000 * count / 70); + struct timespec delay, rem; + delay.tv_sec = count / 70; + /* Avoid overflow. Microsec res should be good enough. */ + delay.tv_nsec = (count%70)*1000000/70 * 1000; + while(nanosleep(&delay, &rem) == -1 && errno == EINTR) + delay = rem; } From 8fbb5372b2e934876dd2e288f73d49c4a4b690da Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 10 May 2017 11:34:48 +0300 Subject: [PATCH 19/19] Fixed 32-bit Windows crash reporter Restored old exception handling for 32-bit Windows executable Tested on 32-bit Windows XP (previously exited without notification), 64-bit Windows 7 and 10 (previously deadlocked in system DLLs) --- src/win32/i_main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index bf16a8708..c82fb1969 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1222,7 +1222,11 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info) // Otherwise, put the crashing thread to sleep and signal the main thread to clean up. if (GetCurrentThreadId() == MainThreadID) { +#ifdef _M_X64 *info->ContextRecord = MainThreadContext; +#else + info->ContextRecord->Eip = (DWORD_PTR)ExitFatally; +#endif // _M_X64 } else { @@ -1315,6 +1319,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n { SetUnhandledExceptionFilter (CatchAllExceptions); +#ifdef _M_X64 static bool setJumpResult = false; RtlCaptureContext(&MainThreadContext); if (setJumpResult) @@ -1323,6 +1328,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n return 0; } setJumpResult = true; +#endif // _M_X64 } #endif