diff --git a/source/common/audio/sound/i_sound.cpp b/source/common/audio/sound/i_sound.cpp index efd8a06e1..5f9fdda18 100644 --- a/source/common/audio/sound/i_sound.cpp +++ b/source/common/audio/sound/i_sound.cpp @@ -70,9 +70,6 @@ CVAR(Int, snd_hrtf, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(String, snd_backend, DEF_BACKEND, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -// killough 2/21/98: optionally use varying pitched sounds -CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE) - SoundRenderer *GSnd; bool nosound; bool nosfx; @@ -134,7 +131,7 @@ public: void SetMusicVolume (float volume) { } - SoundHandle LoadSound(uint8_t *sfxdata, int length) + SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) { SoundHandle retval = { NULL }; return retval; @@ -178,11 +175,11 @@ public: } // Starts a sound. - FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) + FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } - FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) + FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } diff --git a/source/common/audio/sound/i_sound.h b/source/common/audio/sound/i_sound.h index 016098d48..080515494 100644 --- a/source/common/audio/sound/i_sound.h +++ b/source/common/audio/sound/i_sound.h @@ -105,7 +105,7 @@ public: virtual bool IsNull() { return false; } virtual void SetSfxVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0; - virtual SoundHandle LoadSound(uint8_t *sfxdata, int length) = 0; + virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) = 0; SoundHandle LoadSoundVoc(uint8_t *sfxdata, int length); virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1) = 0; virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory @@ -117,8 +117,8 @@ public: virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0; // Starts a sound. - virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; - virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; + virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; + virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; // Stops a sound channel. virtual void StopChannel (FISoundChannel *chan) = 0; diff --git a/source/common/audio/sound/oalsound.cpp b/source/common/audio/sound/oalsound.cpp index dd7af7485..6f6e4e3ee 100644 --- a/source/common/audio/sound/oalsound.cpp +++ b/source/common/audio/sound/oalsound.cpp @@ -110,7 +110,6 @@ ReverbContainer *ForcedEnvironment; EXTERN_CVAR (Int, snd_channels) EXTERN_CVAR (Int, snd_samplerate) EXTERN_CVAR (Bool, snd_waterreverb) -EXTERN_CVAR (Bool, snd_pitched) EXTERN_CVAR (Int, snd_hrtf) @@ -527,8 +526,6 @@ public: #define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */ -#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f) - static size_t GetChannelCount(ChannelConfig chans) { switch(chans) @@ -1099,7 +1096,7 @@ SoundHandle OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, int length, int return retval; } -SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length) +SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) { SoundHandle retval = { NULL }; ALenum format = AL_NONE; @@ -1109,7 +1106,16 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length) uint32_t loop_start = 0, loop_end = ~0u; zmusic_bool startass = false, endass = false; - FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass); + if (def_loop_start < 0) + { + FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass); + } + else + { + loop_start = def_loop_start; + loop_end = def_loop_end; + startass = endass = true; + } auto decoder = CreateDecoder(sfxdata, length, true); if (!decoder) return retval; @@ -1224,7 +1230,7 @@ SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int return stream; } -FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) +FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { if(FreeSfx.Size() == 0) { @@ -1270,9 +1276,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f); } if(WasInWater && !(chanflags&SNDF_NOREVERB)) - alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT); + alSourcef(source, AL_PITCH, pitch * PITCH_MULT); else - alSourcef(source, AL_PITCH, PITCH(pitch)); + alSourcef(source, AL_PITCH, pitch); if(!reuse_chan || reuse_chan->StartTime == 0) { @@ -1326,7 +1332,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int } FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, - FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, + FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { float dist_sqr = (float)(pos - listener->position).LengthSquared(); @@ -1438,9 +1444,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f); } if(WasInWater && !(chanflags&SNDF_NOREVERB)) - alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT); + alSourcef(source, AL_PITCH, pitch * PITCH_MULT); else - alSourcef(source, AL_PITCH, PITCH(pitch)); + alSourcef(source, AL_PITCH, pitch); if(!reuse_chan || reuse_chan->StartTime == 0) { @@ -1762,7 +1768,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener) { ALuint source = GET_PTRID(schan->SysChannel); if (source && !(schan->ChanFlags & CHANF_UI)) - alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT); + alSourcef(source, AL_PITCH, schan->Pitch * PITCH_MULT); schan = schan->NextChan; } getALError(); @@ -1800,7 +1806,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener) { ALuint source = GET_PTRID(schan->SysChannel); if (source && !(schan->ChanFlags & CHANF_UI)) - alSourcef(source, AL_PITCH, schan->Pitch / 128.0f); + alSourcef(source, AL_PITCH, schan->Pitch); schan = schan->NextChan; } getALError(); diff --git a/source/common/audio/sound/oalsound.h b/source/common/audio/sound/oalsound.h index 93436f4ec..4b277bc25 100644 --- a/source/common/audio/sound/oalsound.h +++ b/source/common/audio/sound/oalsound.h @@ -34,7 +34,7 @@ public: virtual void SetSfxVolume(float volume); virtual void SetMusicVolume(float volume); - virtual SoundHandle LoadSound(uint8_t *sfxdata, int length); + virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end); virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1); virtual void UnloadSound(SoundHandle sfx); virtual unsigned int GetMSLength(SoundHandle sfx); @@ -45,8 +45,8 @@ public: virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata); // Starts a sound. - virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime); - virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime); + FISoundChannel *StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) override; + FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) override; // Changes a channel's volume. virtual void ChannelVolume(FISoundChannel *chan, float volume); diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp index 97225c87c..f3b0fb412 100644 --- a/source/common/audio/sound/s_sound.cpp +++ b/source/common/audio/sound/s_sound.cpp @@ -49,6 +49,8 @@ CVARD(Bool, snd_enabled, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enables/disables sound effects") CVAR(Bool, i_soundinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, i_pauseinbackground, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +// killough 2/21/98: optionally use varying pitched sounds +CVAR(Bool, snd_pitched, false, CVAR_ARCHIVE) int SoundEnabled() { @@ -368,6 +370,31 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a } } +//========================================================================== +// +// +// +//========================================================================== + +static float CalcPitch(int pitchmask, float defpitch, float defpitchmax) +{ + if (defpitch > 0.0) // $PitchSet overrides $PitchShift + { + if (defpitchmax > 0.0 && defpitch != defpitchmax) + { + defpitch = (float)pr_soundpitch.GenRand_Real1() * (defpitchmax - defpitch) + defpitch; + } + return defpitch; + } + + // Vary the sfx pitches. Overridden by $PitchSet and A_StartSound. + if (pitchmask != 0 && snd_pitched) + { + return (DEFAULT_PITCH - (pr_soundpitch() & pitchmask) + (pr_soundpitch() & pitchmask)) / (float)DEFAULT_PITCH; + } + return 1.f; +} + //========================================================================== // // S_StartSound @@ -386,7 +413,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, EChanFlags chanflags = flags; int basepriority; FSoundID org_id; - int pitch; FSoundChan *chan; FVector3 pos, vel; FRolloffInfo *rolloff; @@ -419,7 +445,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, float limit_range = sfx->LimitRange; float defpitch = sfx->DefPitch; float defpitchmax = sfx->DefPitchMax; - auto pitchmask = sfx->PitchMask; rolloff = &sfx->Rolloff; // Resolve player sounds, random sounds, and aliases @@ -542,16 +567,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, return NULL; } - // Vary the sfx pitches. Overridden by $PitchSet and A_StartSound. - if (pitchmask != 0) - { - pitch = DEFAULT_PITCH - (rand() & pitchmask) + (rand() & pitchmask); - } - else - { - pitch = DEFAULT_PITCH; - } - + float pitch = spitch > 0 ? spitch : CalcPitch(sfx->PitchMask, defpitch, defpitchmax); if (chanflags & CHANF_EVICTED) { chan = NULL; @@ -614,27 +630,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, { chan->Source = source; } - - if (spitch > 0.0) // A_StartSound has top priority over all others. - SetPitch(chan, spitch); - else if (defpitch > 0.0) // $PitchSet overrides $PitchShift - { - if (defpitchmax > 0.0) - { - if (defpitchmax < defpitch) - std::swap(defpitch, defpitchmax); - - if (defpitch != defpitchmax) - { - FRandom &rng = pr_soundpitch; - int random = (rng)(0x7FFF); - float frandom = random / float(0x7FFF); - - defpitch = frandom * (defpitchmax - defpitch) + defpitch; - } - } - SetPitch(chan, defpitch); - } } return chan; @@ -774,7 +769,7 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx) // If that fails, let the sound system try and figure it out. else { - sfx->data = GSnd->LoadSound(sfxdata.Data(), size); + sfx->data = GSnd->LoadSound(sfxdata.Data(), size, sfx->LoopStart, sfx->LoopEnd); } } @@ -1077,7 +1072,7 @@ void SoundEngine::SetPitch(FSoundChan *chan, float pitch) { assert(chan != nullptr); GSnd->ChannelPitch(chan, max(0.0001f, pitch)); - chan->Pitch = max(1, int(float(DEFAULT_PITCH) * pitch)); + chan->Pitch = pitch; } //========================================================================== diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index 3c6efe13b..822623529 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -97,11 +97,13 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1); bool bUsed = false; bool bSingular = false; 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 FSoundID link = NO_LINK; constexpr static FSoundID NO_LINK = FSoundID::fromInt(-1); @@ -120,7 +122,7 @@ struct FSoundChan : public FISoundChannel float Volume; int EntChannel; // Actor's sound channel. int UserData; // Not used by the engine, the caller can use this to store some additional info. - int16_t Pitch; // Pitch variation. + float Pitch; // Pitch variation. int16_t NearLimit; int8_t Priority; uint8_t SourceType; diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index 011a9cadb..98763724f 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -422,7 +422,7 @@ void FFont::ReadSheetFont(TArray &folderdata, int width, int height { for (int x = 0; x < numtex_x; x++) { - auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * width, width, height); + auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * height, width, height); FImageTexture *imgtex = new FImageTexture(image); auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar); gtex->SetWorldPanning(true); diff --git a/source/common/rendering/gl/gl_shader.cpp b/source/common/rendering/gl/gl_shader.cpp index 87fbe7979..02f1e308d 100644 --- a/source/common/rendering/gl/gl_shader.cpp +++ b/source/common/rendering/gl/gl_shader.cpp @@ -239,6 +239,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * float uClipHeight; float uClipHeightDirection; int uShadowmapFilter; + + int uLightBlendMode; }; uniform int uTextureMode; @@ -332,6 +334,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * uniform sampler2D texture9; uniform sampler2D texture10; uniform sampler2D texture11; + uniform sampler2D texture12; // timer data uniform float timer; diff --git a/source/common/rendering/hwrenderer/data/hw_viewpointuniforms.h b/source/common/rendering/hwrenderer/data/hw_viewpointuniforms.h index 3d28f5c4a..def3b4808 100644 --- a/source/common/rendering/hwrenderer/data/hw_viewpointuniforms.h +++ b/source/common/rendering/hwrenderer/data/hw_viewpointuniforms.h @@ -4,6 +4,15 @@ struct HWDrawInfo; +enum class ELightBlendMode : uint8_t +{ + CLAMP = 0, + CLAMP_COLOR = 1, + NOCLAMP = 2, + + DEFAULT = CLAMP, +}; + struct HWViewpointUniforms { VSMatrix mProjectionMatrix; @@ -19,6 +28,8 @@ struct HWViewpointUniforms float mClipHeightDirection = 0.f; int mShadowmapFilter = 1; + int mLightBlendMode = 0; + void CalcDependencies() { mNormalViewMatrix.computeNormalMatrix(mViewMatrix); diff --git a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 6a8d15af3..9cf1badb7 100644 --- a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -570,7 +570,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm, float flash) void PPTonemap::UpdateTextures() { - if (gl_tonemap == Palette && !PaletteTexture.Data) + // level.info->tonemap cannot be ETonemapMode::Palette, so it's fine to only check gl_tonemap here + if (ETonemapMode((int)gl_tonemap) == ETonemapMode::Palette && !PaletteTexture.Data) { std::shared_ptr data(new uint32_t[512 * 512], [](void *p) { delete[](uint32_t*)p; }); @@ -598,7 +599,9 @@ void PPTonemap::UpdateTextures() void PPTonemap::Render(PPRenderState *renderstate) { - if (gl_tonemap == 0) + ETonemapMode current_tonemap = (level_tonemap != ETonemapMode::None) ? level_tonemap : ETonemapMode((int)gl_tonemap); + + if (current_tonemap == ETonemapMode::None) { return; } @@ -606,14 +609,14 @@ void PPTonemap::Render(PPRenderState *renderstate) UpdateTextures(); PPShader *shader = nullptr; - switch (gl_tonemap) + switch (current_tonemap) { default: - case Linear: shader = &LinearShader; break; - case Reinhard: shader = &ReinhardShader; break; - case HejlDawson: shader = &HejlDawsonShader; break; - case Uncharted2: shader = &Uncharted2Shader; break; - case Palette: shader = &PaletteShader; break; + case ETonemapMode::Linear: shader = &LinearShader; break; + case ETonemapMode::Reinhard: shader = &ReinhardShader; break; + case ETonemapMode::HejlDawson: shader = &HejlDawsonShader; break; + case ETonemapMode::Uncharted2: shader = &Uncharted2Shader; break; + case ETonemapMode::Palette: shader = &PaletteShader; break; } renderstate->PushGroup("tonemap"); @@ -622,7 +625,7 @@ void PPTonemap::Render(PPRenderState *renderstate) renderstate->Shader = shader; renderstate->Viewport = screen->mScreenViewport; renderstate->SetInputCurrent(0); - if (gl_tonemap == Palette) + if (current_tonemap == ETonemapMode::Palette) renderstate->SetInputTexture(1, &PaletteTexture); renderstate->SetOutputNext(); renderstate->SetNoBlend(); diff --git a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h index 71defdcae..357396da7 100644 --- a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h +++ b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h @@ -13,6 +13,19 @@ typedef IntRect PPViewport; class PPTexture; class PPShader; +enum class ETonemapMode : uint8_t +{ + None, + Uncharted2, + HejlDawson, + Reinhard, + Linear, + Palette, + NumTonemapModes +}; + + + enum class PPFilterMode { Nearest, Linear }; enum class PPWrapMode { Clamp, Repeat }; enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap }; @@ -541,6 +554,7 @@ private: class PPTonemap { public: + void SetTonemapMode(ETonemapMode tm) { level_tonemap = tm; } void Render(PPRenderState *renderstate); void ClearTonemapPalette() { PaletteTexture = {}; } @@ -554,17 +568,7 @@ private: PPShader HejlDawsonShader = { "shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} }; PPShader Uncharted2Shader = { "shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} }; PPShader PaletteShader = { "shaders/pp/tonemap.fp", "#define PALETTE\n", {} }; - - enum TonemapMode - { - None, - Uncharted2, - HejlDawson, - Reinhard, - Linear, - Palette, - NumTonemapModes - }; + ETonemapMode level_tonemap = ETonemapMode::None; }; ///////////////////////////////////////////////////////////////////////////// @@ -840,8 +844,11 @@ public: PPCustomShaders customShaders; + void SetTonemapMode(ETonemapMode tm) { tonemap.SetTonemapMode(tm); } void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight); void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight); }; + extern Postprocess hw_postprocess; + diff --git a/source/common/rendering/vulkan/shaders/vk_shader.cpp b/source/common/rendering/vulkan/shaders/vk_shader.cpp index 1c6df42f1..25b585531 100644 --- a/source/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/source/common/rendering/vulkan/shaders/vk_shader.cpp @@ -175,6 +175,8 @@ static const char *shaderBindings = R"( float uClipHeight; float uClipHeightDirection; int uShadowmapFilter; + + int uLightBlendMode; }; layout(set = 1, binding = 1, std140) uniform MatricesUBO { @@ -244,6 +246,7 @@ static const char *shaderBindings = R"( layout(set = 2, binding = 8) uniform sampler2D texture9; layout(set = 2, binding = 9) uniform sampler2D texture10; layout(set = 2, binding = 10) uniform sampler2D texture11; + layout(set = 2, binding = 11) uniform sampler2D texture12; // This must match the PushConstants struct layout(push_constant) uniform PushConstants diff --git a/source/common/scripting/core/maps.cpp b/source/common/scripting/core/maps.cpp index 28fda643e..68eab6d3d 100644 --- a/source/common/scripting/core/maps.cpp +++ b/source/common/scripting/core/maps.cpp @@ -438,10 +438,12 @@ template void MapIteratorSetValue(I * self, expand_types_vm ) \ + DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValueString< FMapIterator_I32_Str > ) \ { \ PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \ - ACTION_RETURN_STRING( MapIteratorGetValue(self) ); \ + FString out; \ + MapIteratorGetValueString(self , out); \ + ACTION_RETURN_STRING( out ); \ } #define DEF_MAP_IT_S_S() \ diff --git a/source/common/textures/hw_material.cpp b/source/common/textures/hw_material.cpp index c6b38e5a6..2517c098e 100644 --- a/source/common/textures/hw_material.cpp +++ b/source/common/textures/hw_material.cpp @@ -133,12 +133,15 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags) if (index >= FIRST_USER_SHADER) { const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER]; - if (tx->Layers && usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material + if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material { - for (auto& texture : tx->Layers->CustomShaderTextures) + if (tx->Layers) { - if (texture == nullptr) continue; - mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable. + for (auto& texture : tx->Layers->CustomShaderTextures) + { + if (texture == nullptr) continue; + mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable. + } } mShaderIndex = index; } diff --git a/source/common/utility/palette.cpp b/source/common/utility/palette.cpp index c1728a3ad..e7bc61f09 100644 --- a/source/common/utility/palette.cpp +++ b/source/common/utility/palette.cpp @@ -418,19 +418,34 @@ void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, con // color, so find a duplicate pair of palette entries, make one of them a // duplicate of color 0, and remap every graphic so that it uses that entry // instead of entry 0. -void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap) +void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* lastcolormap) { for (int i = 0; i < 256; i++) Remap[i] = i; PalEntry color0 = BaseColors[0]; int i; + // First try for an exact match of color 0. Only Hexen does not have one. - for (i = 1; i < 256; ++i) + if (!lastcolormap) { - if (BaseColors[i] == color0) + for (i = 1; i < 256; ++i) { - Remap[0] = i; - break; + if (BaseColors[i] == color0) + { + Remap[0] = i; + break; + } + } + } + else + { + for (i = 1; i < 256; ++i) + { + if ((BaseColors[i] == color0) && (lastcolormap[i] == lastcolormap[0])) + { + Remap[0] = i; + break; + } } } @@ -448,21 +463,44 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap) sortcopy[i] = (BaseColors[i] & 0xffffff) | (i << 24); } qsort(sortcopy, 256, 4, sortforremap); - for (i = 255; i > 0; --i) + if (!lastcolormap) { - if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) + for (i = 255; i > 0; --i) { - int new0 = sortcopy[i].a; - int dup = sortcopy[i - 1].a; - if (new0 > dup) + if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) { - // Make the lower-numbered entry a copy of color 0. (Just because.) - std::swap(new0, dup); + int new0 = sortcopy[i].a; + int dup = sortcopy[i - 1].a; + if (new0 > dup) + { + // Make the lower-numbered entry a copy of color 0. (Just because.) + std::swap(new0, dup); + } + Remap[0] = new0; + Remap[new0] = dup; + BaseColors[new0] = color0; + break; + } + } + } + else + { + for (i = 255; i > 0; --i) + { + if (((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) && (lastcolormap[sortcopy[i].a] == lastcolormap[sortcopy[i - 1].a])) + { + int new0 = sortcopy[i].a; + int dup = sortcopy[i - 1].a; + if (new0 > dup) + { + // Make the lower-numbered entry a copy of color 0. (Just because.) + std::swap(new0, dup); + } + Remap[0] = new0; + Remap[new0] = dup; + BaseColors[new0] = color0; + break; } - Remap[0] = new0; - Remap[new0] = dup; - BaseColors[new0] = color0; - break; } } } diff --git a/source/common/utility/palutil.h b/source/common/utility/palutil.h index bbd8f9a2d..6faa7b5df 100644 --- a/source/common/utility/palutil.h +++ b/source/common/utility/palutil.h @@ -14,7 +14,7 @@ void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int // Given an array of colors, fills in remap with values to remap the // passed array of colors to BaseColors. Used for loading palette downconversions of PNGs. void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors); -void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap); +void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* cmapdata = nullptr); // Colorspace conversion RGB <-> HSV void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index db597a8e4..304800ba5 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -165,6 +165,7 @@ bool G_Responder(event_t* ev); void HudScaleChanged(); bool M_SetSpecialMenu(FName& menu, int param); void OnMenuOpen(bool makeSound); +void DestroyAltHUD(); DStatusBarCore* StatusBar; @@ -622,6 +623,7 @@ int GameMain() } //DeleteScreenJob(); if (gi) gi->FreeLevelData(); + DestroyAltHUD(); DeinitMenus(); if (StatusBar) StatusBar->Destroy(); StatusBar = nullptr; diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 95d62a6e4..adb174078 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -42,9 +42,11 @@ #include "s_music.h" #include "sc_man.h" #include "s_soundinternal.h" +#include "gamecontrol.h" #include #include "raze_music.h" +#include "games/duke/src/sounds.h" // MACROS ------------------------------------------------------------------ @@ -56,7 +58,12 @@ enum SICommands SI_ConReserve, SI_Alias, SI_Limit, - SI_Singular + SI_Singular, + SI_PitchSet, + SI_PitchSetDuke, + SI_DukeFlags, + SI_Loop, + SI_BloodRelVol, }; @@ -87,6 +94,11 @@ static const char *SICommandStrings[] = "$alias", "$limit", "$singular", + "$pitchset", + "$pitchsetduke", + "$dukeflags", + "$loop", + "$bloodrelvol", NULL }; @@ -287,6 +299,46 @@ static void S_AddSNDINFO (int lump) } break; + case SI_PitchSet: { + // $pitchset [range maximum] + FSoundID sfx; + + sc.MustGetString(); + sfx = soundEngine->FindSoundTentative(sc.String); + sc.MustGetFloat(); + auto sfxp = soundEngine->GetWritableSfx(sfx); + sfxp->DefPitch = (float)sc.Float; + if (sc.CheckFloat()) + { + sfxp->DefPitchMax = (float)sc.Float; + } + else + { + sfxp->DefPitchMax = 0; + } + } + break; + + case SI_PitchSetDuke: { + // $pitchset [range maximum] + // Same as above, but uses Duke's value range of 1200 units per octave. + FSoundID sfx; + + sc.MustGetString(); + sfx = soundEngine->FindSoundTentative(sc.String); + sc.MustGetFloat(); + auto sfxp = soundEngine->GetWritableSfx(sfx); + sfxp->DefPitch = (float)pow(2, sc.Float / 1200.); + if (sc.CheckFloat()) + { + sfxp->DefPitchMax = (float)pow(2, sc.Float / 1200.); + } + else + { + sfxp->DefPitchMax = 0; + } + break; + } case SI_ConReserve: { // $conreserve @@ -300,6 +352,75 @@ static void S_AddSNDINFO (int lump) break; } + case SI_DukeFlags: { + static const char* dukeflags[] = { "LOOP", "MSFX", "TALK", "GLOBAL", nullptr}; + + // dukesound .. + // Sets a pitch range for the sound. + sc.MustGetString(); + auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); + int flags = 0; + while (sc.GetString()) + { + int bit = sc.MatchString(dukeflags); + if (bit == -1) break; + flags |= 1 << bit; + } + if (isDukeEngine()) + { + auto sfx = soundEngine->GetWritableSfx(sfxid); + if (sfx->UserData.Size() < Duke3d::kMaxUserData) + { + sfx->UserData.Resize(Duke3d::kMaxUserData); + memset(sfx->UserData.Data(), 0, Duke3d::kMaxUserData * sizeof(int)); + } + sfx->UserData[Duke3d::kFlags] = flags; + } + else + { + sc.ScriptMessage("'$dukeflags' is not available in the current game and will be ignored"); + } + break; + + } + + case SI_Loop: { + // loop + // Sets loop points for the given sound in samples. Only really useful for WAV - for Ogg and FLAC use the metadata they can contain. + sc.MustGetString(); + auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); + auto sfx = soundEngine->GetWritableSfx(sfxid); + sc.MustGetNumber(); + sfx->LoopStart = sc.Number; + if (sc.CheckNumber()) + sfx->LoopEnd = sc.Number; + break; + } + + case SI_BloodRelVol: { + // bloodrelvol + // Sets Blood's hacky volume modifier. + sc.MustGetString(); + auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); + auto sfx = soundEngine->GetWritableSfx(sfxid); + sc.MustGetNumber(); + if (isBlood()) + { + auto sfx = soundEngine->GetWritableSfx(sfxid); + if (sfx->UserData.Size() < 1) + { + sfx->UserData.Resize(1); + } + sfx->UserData[0] = sc.Number; + } + else + { + sc.ScriptMessage("'$bloodrelvol' is not available in the current game and will be ignored"); + } + break; + } + + default: { // Got a logical sound mapping FString name (sc.String); diff --git a/source/core/postprocessor.cpp b/source/core/postprocessor.cpp index f296e08ae..dea137219 100644 --- a/source/core/postprocessor.cpp +++ b/source/core/postprocessor.cpp @@ -103,6 +103,17 @@ DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetSpriteLotag) return 0; } +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetSpriteSector) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_UINT(sprite); + PARAM_INT(sect); + if (sprite < self->sprites->sprites.Size()) + self->sprites->sprites[sprite].sectp = §or[sect]; + + return 0; +} + DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ChangeSpriteFlags) { PARAM_SELF_PROLOGUE(DLevelPostProcessor); diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 6e05cda80..5a310441b 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -250,6 +250,7 @@ void HWDrawInfo::SetupView(FRenderState &state, float vx, float vy, float vz, bo SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror); SetCameraPos(vp.Pos); VPUniforms.CalcDependencies(); + VPUniforms.mLightBlendMode = 0; vpIndex = screen->mViewpoints->SetViewpoint(state, &VPUniforms); } diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index 8fccda3fa..b1d28d2ec 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -1128,6 +1128,10 @@ int HWWall::CheckWallSprite(tspritetype* spr, tspritetype* last) void HWWall::ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* sector) { + if (spr->time == 1373) + { + int a = 0; + } auto tex = TexMan.GetGameTexture(spr->spritetexture()); if (!tex || !tex->isValid()) return; diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 71953737f..fcafed6c6 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -106,8 +106,8 @@ static void SerializeGlobals(FSerializer& arc) static void SerializeSession(FSerializer& arc) { - // In Duke we now have reliable sound names. - if (isDukeEngine()) arc.SetUniqueSoundNames(); + // In Duke and Blood we now have reliable sound names. + if (isDukeEngine() || isBlood()) arc.SetUniqueSoundNames(); arc.ReadObjects(false); SerializeMap(arc); diff --git a/source/core/shared_hud.cpp b/source/core/shared_hud.cpp index 292420d66..49f275b69 100644 --- a/source/core/shared_hud.cpp +++ b/source/core/shared_hud.cpp @@ -134,14 +134,18 @@ static DObject* DoCreateAltHUD(const FName classname) return althud; } -void CreateAltHUD() +void DestroyAltHUD() { if (AltHud) { AltHud->Destroy(); AltHud = nullptr; } +} +void CreateAltHUD() +{ + DestroyAltHUD(); /* if (!hud_althud_forceinternal) AltHud = DoCreateAltHUD(gameinfo.althudclass); diff --git a/source/games/blood/src/seq.cpp b/source/games/blood/src/seq.cpp index 724da41f2..f8383ba38 100644 --- a/source/games/blood/src/seq.cpp +++ b/source/games/blood/src/seq.cpp @@ -386,7 +386,7 @@ void SEQINST::Update() if (snd.isvalid()) { auto udata = soundEngine->GetUserData(snd); - int relVol = udata ? udata[2] : 255; + int relVol = udata ? udata[0] : 255; sfxPlay3DSoundCP(actor, sndId, -1, 0, 0, (surfSfxMove[surf][2] != relVol) ? relVol : surfSfxMove[surf][3]); } } diff --git a/source/games/blood/src/sfx.cpp b/source/games/blood/src/sfx.cpp index c56ef3294..754f39750 100644 --- a/source/games/blood/src/sfx.cpp +++ b/source/games/blood/src/sfx.cpp @@ -147,13 +147,12 @@ void GameInterface::UpdateSounds() // //--------------------------------------------------------------------------- -FSoundID getSfx(FSoundID soundId, float& attenuation, int& pitch, int& relvol) +FSoundID getSfx(FSoundID soundId, float& attenuation, int& relvol) { auto udata = soundEngine->GetUserData(soundId); - if (pitch < 0) pitch = udata ? udata[0] : 0x10000; if (relvol < 0) relvol = 0; - else if (relvol == 0) relvol = udata && udata[2] ? udata[2] : 80; + else if (relvol == 0) relvol = udata && udata[0] ? udata[0] : 80; if (relvol > 255) relvol = 255; // Limit the attenuation. More than 2.0 is simply too much. attenuation = relvol > 0 ? clamp(80.f / relvol, 0.f, 2.f) : 1.f; @@ -177,7 +176,7 @@ void sfxPlay3DSound(const DVector3& pos, int soundId, sectortype* pSector) float attenuation; int pitch = -1; int relvol = 0; - sid = getSfx(sid, attenuation, pitch, relvol); + sid = getSfx(sid, attenuation, relvol); auto sfx = soundEngine->GetSfx(sid); EChanFlags flags = CHANF_OVERLAP; if (sfx && sfx->LoopStart >= 0) flags |= CHANF_LOOP; @@ -194,14 +193,14 @@ void sfxPlay3DSound(const DVector3& pos, int soundId, sectortype* pSector) void sfxPlay3DSoundCP(DBloodActor* pActor, int soundId, int playchannel, int playflags, int pitch, int volume) { - if (!SoundEnabled() || soundId < 0 || !pActor) return; + if (!SoundEnabled() || soundId <= 0 || !pActor) return; auto sid = soundEngine->FindSoundByResID(soundId); if (!sid.isvalid()) return; auto svec = GetSoundPos(pActor->spr.pos); float attenuation; - sid = getSfx(sid, attenuation, pitch, volume); + sid = getSfx(sid, attenuation, volume); if (volume == -1) volume = 80; if (playchannel >= 0) diff --git a/source/games/blood/src/sound.cpp b/source/games/blood/src/sound.cpp index 76ed757ad..4ab0445ee 100644 --- a/source/games/blood/src/sound.cpp +++ b/source/games/blood/src/sound.cpp @@ -62,24 +62,42 @@ void ByteSwapSFX(SFX* pSFX) // // S_AddBloodSFX // -// Registers a new sound with the name ".sfx" -// Actual sound data is searched for in the ns_bloodraw namespace. -// //========================================================================== static void S_AddBloodSFX(int lumpnum) { + FSoundID sfxnum; + + int resid = fileSystem.GetResourceId(lumpnum); + sfxinfo_t* soundfx = nullptr; + + sfxnum = soundEngine->FindSoundByResIDNoHash(resid); + if (sfxnum.isvalid()) + { + soundfx = soundEngine->GetWritableSfx(sfxnum); + if (soundfx->UserData.Size() == 0) + { + soundfx->UserData.Resize(1); + soundfx->UserData[1] = 80; // default for RelVol + } + if (!soundfx->bTentative) return; // sound was already defined. + } + auto sfxlump = fileSystem.ReadFile(lumpnum); SFX* sfx = (SFX*)sfxlump.GetMem(); ByteSwapSFX(sfx); + FStringf rawname("%s.raw", sfx->rawName); auto rawlump = fileSystem.FindFile(rawname); - FSoundID sfxnum; if (rawlump != -1) { - sfxnum = soundEngine->AddSoundLump(sfx->rawName, rawlump, 0, fileSystem.GetResourceId(lumpnum), 6); - auto soundfx = soundEngine->GetWritableSfx(sfxnum); + if (!sfxnum.isvalid()) + { + sfxnum = soundEngine->AddSoundLump(FStringf("SfxSound@%04d", resid), rawlump, 0, resid, 6); // use a generic name here in case sound replacements are being used. + soundfx = soundEngine->GetWritableSfx(sfxnum); + soundfx->UserData.Resize(1); + } if (sfx->format < 5 || sfx->format > 12) { // [0..4] + invalid formats soundfx->RawRate = 11025; @@ -92,14 +110,18 @@ static void S_AddBloodSFX(int lumpnum) { // [9..12] soundfx->RawRate = 44100; } + soundfx->NearLimit = 6; + soundfx->lumpnum = rawlump; soundfx->bLoadRAW = true; + soundfx->bExternal = true; + soundfx->bTentative = false; soundfx->LoopStart = LittleLong(sfx->loopStart); //S_sfx[sfxnum].Volume = sfx->relVol / 255.f; This cannot be done because this volume setting is optional. - soundfx->UserData.Resize(3); + // pitchrange is unused. + if (sfx->pitch != 0x10000) soundfx->DefPitch = sfx->pitch / 65536.f; + else soundfx->DefPitch = 0; int* udata = (int*)soundfx->UserData.Data(); - udata[0] = sfx->pitch; - udata[1] = sfx->pitchRange; - udata[2] = sfx->relVol; + udata[0] = sfx->relVol; } } @@ -122,8 +144,7 @@ void sndInit(void) auto type = fileSystem.GetResourceType(i); if (!stricmp(type, "SFX")) { - if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == NO_SOUND) - S_AddBloodSFX(i); + S_AddBloodSFX(i); } else if (!stricmp(type, "WAV") || !stricmp(type, "OGG") || !stricmp(type, "FLAC") || !stricmp(type, "VOC")) { @@ -193,7 +214,7 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop, if (nVolume < 0) { auto udata = soundEngine->GetUserData(snd); - if (udata) nVolume = min(Scale(udata[2], 255, 100), 255); + if (udata) nVolume = min(Scale(udata[0], 255, 100), 255); else nVolume = 255; } if (bLoop) chanflags |= CHANF_LOOP; diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 108f9efa0..3aabae408 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -250,7 +250,7 @@ DDukeActor* aim(DDukeActor* actor, int abase) setFreeAimVelocity(vel, zvel, plr->Angles.getPitchWithView(), 16.); HitInfo hit{}; - hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel), hit, CLIPMASK1); + hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel * 64), hit, CLIPMASK1); if (hit.actor() != nullptr) { diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index f6a9b4c23..88fc77bce 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -679,7 +679,7 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw double zoffs = 32; if (isWorldTour()) // Twentieth Anniversary World Tour zoffs *= (actor->spr.scale.Y * 0.8); - pos.Z += zoffs; + pos.Z -= zoffs; } else if (actor->spr.picnum == DTILE_BOSS2) { @@ -687,7 +687,7 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw double zoffs = 24; if (isWorldTour()) // Twentieth Anniversary World Tour zoffs *= (actor->spr.scale.Y * 0.8); - pos.Z -= zoffs; + pos.Z += zoffs; } double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length(); diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 784757f75..6e687cb41 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -174,19 +174,6 @@ void S_CacheAllSounds(void) // //========================================================================== -static inline int S_GetPitch(FSoundID soundid) -{ - auto const* snd = soundEngine->GetUserData(soundid); - if (!snd) return 0; - int const range = abs(snd[kPitchEnd] - snd[kPitchStart]); - return (range == 0) ? snd[kPitchStart] : min(snd[kPitchStart], snd[kPitchEnd]) + rand() % range; -} - -float S_ConvertPitch(int lpitch) -{ - return powf(2, lpitch / 1200.f); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave. -} - int S_GetUserFlags(FSoundID soundid) { if (!soundEngine->isValidSoundId(soundid)) return 0; @@ -222,7 +209,7 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit if (sfx->UserData.Size() >= kMaxUserData) { auto& sndinf = sfx->UserData; - settable = !!(sndinf[kFlags] & SF_CONDEFINED); + settable = sfx->bExternal; } } if (!settable) @@ -234,9 +221,6 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit // Set everything to 0 to have default handling. sfx->UserData.Resize(kMaxUserData); auto& sndinf = sfx->UserData; - sndinf[kPitchStart] = 0; - sndinf[kPitchEnd] = 0; - sndinf[kPriority] = 0; // Raze's sound engine does not use this. sndinf[kVolAdjust] = 0; sndinf[kWorldTourMapping] = 0; sndinf[kFlags] = 0; @@ -245,10 +229,9 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit sfx->ResourceId = index; sfx->UserData.Resize(kMaxUserData); + sfx->bExternal = true; auto& sndinf = sfx->UserData; - sndinf[kFlags] = (type & ~SF_ONEINST_INTERNAL) | SF_CONDEFINED; - if (sndinf[kFlags] & SF_LOOP) - sndinf[kFlags] |= SF_ONEINST_INTERNAL; + sndinf[kFlags] = (type & SF_CON_MASK); // Take care of backslashes in sound names. Also double backslashes which occur in World Tour. FString fn = filename; @@ -263,13 +246,14 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit fn.Substitute(".ogg", ".voc"); sfx->lumpnum = S_LookupSound(fn); } - sndinf[kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX); - sndinf[kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX); - sndinf[kPriority] = priority & 255; + if (minpitch != 0 || maxpitch != 0) + { + sfx->DefPitch = (float)pow(2, clamp(minpitch, INT16_MIN, INT16_MAX) / 1200.); + sfx->DefPitchMax = (float)pow(2, clamp(maxpitch, INT16_MIN, INT16_MAX) / 1200.); + } sndinf[kVolAdjust] = clamp(distance, INT16_MIN, INT16_MAX); sndinf[kWorldTourMapping] = 0; sfx->Volume = volume; - //sfx->NearLimit = index == TELEPORTER + 1? 6 : 0; // the teleporter sound cannot be unlimited due to how it gets used. sfx->bTentative = false; return 0; } @@ -501,25 +485,20 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int S_GetCamera(&campos, nullptr, &camsect); GetPositionInfo(actor, soundid, camsect, campos, pos, &sndist, &sndpos); - int pitch = S_GetPitch(soundid); auto sfx = soundEngine->GetSfx(soundid); bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || ((sfx->ResourceId == PIPEBOMB_EXPLODE || sfx->ResourceId == LASERTRIP_EXPLODE || sfx->ResourceId == RPG_EXPLODE)); bool underwater = ps[screenpeek].insector() && ps[screenpeek].cursector->lotag == ST_2_UNDERWATER; - if (explosion) - { - if (underwater) - pitch -= 1024; - } - else + float pitch = 0; + if (!explosion) { if (sndist > 32767 && !issoundcontroller(actor) && (userflags & (SF_LOOP | SF_MSFX)) == 0) return -1; if (underwater && (userflags & SF_TALK) == 0) - pitch = -768; + pitch = 0.64f; } bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid); @@ -528,7 +507,7 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int int const repeatp = (userflags & SF_LOOP); - if (repeatp && (userflags & SF_ONEINST_INTERNAL) && is_playing) + if (repeatp && is_playing) { return -1; } @@ -543,8 +522,16 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int if (userflags & SF_LOOP) flags |= CHANF_LOOP; float vol = attenuation == ATTN_NONE ? 0.8f : 1.f; if (currentCommentarySound != NO_SOUND) vol *= 0.25f; - auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, S_ConvertPitch(pitch)); - if (chan) chan->UserData = (currentCommentarySound != NO_SOUND); + auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, pitch); + if (chan) + { + if (explosion && underwater) + { + pitch = float(chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55); // todo: fix pitch storage in backend. + soundEngine->SetPitch(chan, pitch); + } + chan->UserData = (currentCommentarySound != NO_SOUND); + } return chan ? 0 : -1; } @@ -564,11 +551,9 @@ int S_PlaySound(FSoundID soundid, int channel, EChanFlags flags, float vol) if ((!(snd_speech & 1) && (userflags & SF_TALK))) return -1; - int const pitch = S_GetPitch(soundid); - if (userflags & SF_LOOP) flags |= CHANF_LOOP; if (currentCommentarySound != NO_SOUND) vol *= 0.25f; - auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr, S_ConvertPitch(pitch)); + auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr); if (chan) chan->UserData = (currentCommentarySound != NO_SOUND); return chan ? 0 : -1; } diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 33c52d5cf..54d8402f9 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -18,23 +18,20 @@ enum { SF_TALK = 4, SF_ADULT = 8, SF_GLOBAL = 16, - SF_ONEINST_INTERNAL = 32, - SF_CONDEFINED = 64, SF_DTAG = 128, + SF_CON_MASK = 159, }; enum esound_t { - kPitchStart, - kPitchEnd, kVolAdjust, - kPriority, kFlags, kWorldTourMapping, kMaxUserData }; +class DDukeActor; int S_PlaySound(FSoundID num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol = 0.8f); int S_PlaySound3D(FSoundID num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0); int S_PlayActorSound(FSoundID soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0); diff --git a/wadsrc/static/filter/blood/sndinfo.txt b/wadsrc/static/filter/blood/sndinfo.txt new file mode 100644 index 000000000..d877718f3 --- /dev/null +++ b/wadsrc/static/filter/blood/sndinfo.txt @@ -0,0 +1,927 @@ +$conreserve AMB1 1 +$conreserve AMB2 2 +$conreserve AMB3 3 +$conreserve AMB4 4 +$conreserve AMB5 5 +$conreserve AMB6 6 +$conreserve AMB7 7 +$conreserve AMB8 8 +$conreserve AMB9 9 +$conreserve AMB10 10 +$conreserve AMB11 11 +$conreserve AMB12 12 +$conreserve AMB13 13 +$conreserve AMB14 14 +$conreserve AMB15 15 +$conreserve AMB16 16 +$conreserve AMB17 17 +$conreserve AMB18 18 +$conreserve AMB19 19 +$conreserve AMB20 20 +$conreserve AMB21 21 +$conreserve AMB22 22 +$conreserve AMB24 24 +$conreserve AMB25 25 +$conreserve AMB26 26 +$conreserve RAIN2 27 +$conreserve QAMB1 28 +$conreserve QAMB2 29 +$conreserve QAMB3 30 +$conreserve QAMB4 31 +$conreserve QAMB5 32 +$conreserve QAMB6 33 +$conreserve QAMB7 34 +$conreserve QAMB8 35 +$conreserve QAMB9 36 +$conreserve QAMB10 37 +$conreserve QAMB11 38 +$conreserve QAMB12 39 +$conreserve WATERLAP 40 +$conreserve WATER2 41 +$conreserve UNDERWAT 42 +$conreserve CHAIN1 43 +$conreserve CHAIN2 44 +$conreserve CHAIN4 46 +$conreserve CHAIN5 47 +$conreserve ERIEDRNE 48 +$conreserve SWAMP 49 +$conreserve TORCH 50 +$conreserve MTLDRN 52 +$conreserve HOWLING 54 +$conreserve GRGLNG 56 +$conreserve DRONE 57 +$conreserve 1WIND 58 +$conreserve CHANT 59 +$conreserve HRTBT 60 +$conreserve TRAIN1 61 +$conreserve CHAIN6 62 +$conreserve ICHANT 63 +$conreserve ELCLOOP1 64 +$conreserve MUZAK22 65 +$conreserve ERTHLOOP 66 +$conreserve FANLUP2 67 +$conreserve DORCREAK 100 +$conreserve DOOROPEN 101 +$conreserve RUSTDOOR 102 +$conreserve DOORSLID 103 +$conreserve GEARSTAR 104 +$conreserve ELEVMOVE 105 +$conreserve SLABMOVE 106 +$conreserve QAIRDOOR 107 +$conreserve QDOORMV1 110 +$conreserve QHYDRO1 111 +$conreserve QMEDPLAT 112 +$conreserve QPLAT1 113 +$conreserve CRYPTLP1 114 +$conreserve QTRAIN1 115 +$conreserve QWINCH2 116 +$conreserve CREAKSML 117 +$conreserve CREAKROT 118 +$conreserve CREAKSLD 119 +$conreserve SLIDOOR1 120 +$conreserve SLIDOOR2 121 +$conreserve FLSHDOR1 122 +$conreserve FLSHDOR2 123 +$conreserve CRYPTLP 124 +$conreserve GEARHALT 150 +$conreserve ELEVSTOP 151 +$conreserve ELEVSTRT 152 +$conreserve ELSTOP2 153 +$conreserve QBASESE2 155 +$conreserve QDDOOR2 156 +$conreserve QDRCLOS4 157 +$conreserve HYDRO2A 158 +$conreserve QPLAT2 159 +$conreserve QSTNDR2 160 +$conreserve DOORCLOS 162 +$conreserve ELSTOP3 163 +$conreserve HYDRO2 164 +$conreserve HYDRO3 165 +$conreserve HYDRO4 166 +$conreserve ELVSTR2 167 +$conreserve SLIDSTP1 168 +$conreserve SLIDSTP2 169 +$conreserve FLSHSTP1 170 +$conreserve FLSHSTP2 171 +$conreserve FART1 172 +$conreserve FART2 173 +$conreserve CRYPTSTP 174 +$conreserve SWITCH5 200 +$conreserve QBASETRY 201 +$conreserve BASEUSE 202 +$conreserve QLATCH2 203 +$conreserve RUNETRY 206 +$conreserve RUNEUSE 207 +$conreserve FLICK 208 +$conreserve SWTCHWRK 209 +$conreserve SWTCHBRK 210 +$conreserve SWITCH1 211 +$conreserve SWITCH2 212 +$conreserve SWITCH3 213 +$conreserve RUNETRY2 214 +$conreserve ICEVIO 218 +$conreserve CHANT1LP 219 +$conreserve CHANT2LP 220 +$conreserve 13CHA 221 +$conreserve 13CHU 222 +$conreserve 13DEATH 223 +$conreserve 13KILL 224 +$conreserve BUZZ2 225 +$conreserve SIREN1 226 +$conreserve FLYBY1 227 +$conreserve FLYBY2 228 +$conreserve MACHGUN2 229 +$conreserve MACHGUN3 230 +$conreserve TANK2 231 +$conreserve JEEP1 232 +$conreserve JEEP2 233 +$conreserve SHELL1 234 +$conreserve SHELL2 235 +$conreserve BCREAK1 236 +$conreserve BCREAK2 237 +$conreserve BCREAK3 238 +$conreserve BCREAK4 239 +$conreserve BRGLOOP 240 +$conreserve ICEMELO1 241 +$conreserve ICEMELO2 242 +$conreserve ICEMELO3 243 +$conreserve ICEMELLP 244 +$conreserve CRACK2 245 +$conreserve MOAN4 246 +$conreserve MOAN3 247 +$conreserve MOAN2LP 248 +$conreserve SPARK 249 +$conreserve ARC1 250 +$conreserve ARC2 251 +$conreserve ARC3 252 +$conreserve SEWAGE 253 +$conreserve THUNDER1 254 +$conreserve THUNDER2 255 +$conreserve QTHUNDER 256 +$conreserve CLOCK 257 +$conreserve GUST1 258 +$conreserve GUST2 259 +$conreserve GUST3 260 +$conreserve GUST4 261 +$conreserve CREAK 262 +$conreserve BUBRISE 263 +$conreserve ERTHRMBL 265 +$conreserve SINEWAVE 266 +$conreserve WHISPERS 267 +$conreserve MOANS 268 +$conreserve LAUGH 269 +$conreserve BELL 270 +$conreserve 1OWL 271 +$conreserve 2OWL 272 +$conreserve TRNCRASH 274 +$conreserve TRNBRAKE 275 +$conreserve TRNHRN 276 +$conreserve TRAINSTP 277 +$conreserve HUM 278 +$conreserve RIFF1 279 +$conreserve RIFF2 280 +$conreserve RIFF3 281 +$conreserve TICKET 282 +$conreserve HEYSTOP 283 +$conreserve PING 284 +$conreserve FLATLIN1 285 +$conreserve FLATLIN2 286 +$conreserve MOAN2 287 +$conreserve SCREAM 288 +$conreserve HELPME 289 +$conreserve SOBBING 290 +$conreserve ELECGEN2 291 +$conreserve TURBGEN2 292 +$conreserve SMALWOOF 293 +$conreserve SMALPAIN 294 +$conreserve AMBULONG 295 +$conreserve AMBUSHRT 296 +$conreserve BUZSLOW2 297 +$conreserve ELECPOP2 298 +$conreserve ELECPOP4 299 +$conreserve GLASHIT2 300 +$conreserve POTTERY 301 +$conreserve MGDIE 302 +$conreserve EXPLODCS 303 +$conreserve EXPLODCM 304 +$conreserve EXPLODCL 305 +$conreserve EXPLODFS 306 +$conreserve EXPLODFM 307 +$conreserve EXPLODFL 308 +$conreserve EXPLODUS 309 +$conreserve EXPLODUM 310 +$conreserve EXPLODUL 311 +$conreserve SPLNTWOD 312 +$conreserve SHATSTON 313 +$conreserve RENMETAL 314 +$conreserve SHRED1 315 +$conreserve SHRED2 316 +$conreserve BALLNPOP 317 +$conreserve HEADSQ 318 +$conreserve GIBSQ 319 +$conreserve NAPLMEX2 320 +$conreserve RESPAWN 350 +$conreserve BURN 351 +$conreserve SIZZLE 352 +$conreserve SIZZLE2 353 +$conreserve DRIP1 354 +$conreserve DRIP2 355 +$conreserve DRIP3 356 +$conreserve PUNT 357 +$conreserve BOULDERS 358 +$conreserve MGFIRE 359 +$conreserve PADLOCK 360 +$conreserve BURSTFLM 361 +$conreserve BLDSPRY1 362 +$conreserve RING 363 +$conreserve SNAKEHIS 364 +$conreserve SNAKEPIT 365 +$conreserve CASHREG 366 +$conreserve DIALTONE 367 +$conreserve BUSYSIG 368 +$conreserve TOILET 369 +$conreserve RECSCRAP 370 +$conreserve DRIP4 371 +$conreserve DRIP5 372 +$conreserve DRIP6 373 +$conreserve PAILKICK 374 +$conreserve SIZZLE1 375 +$conreserve SAWRUN 376 +$conreserve SAWCUT 377 +$conreserve SAWCOCK1 378 +$conreserve REAPPEAR 379 +$conreserve RESPAWN2 380 +$conreserve BLDSPT2 381 +$conreserve BLADEDRP 382 +$conreserve BDYPRTIM 383 +$conreserve BDYPTIM2 384 +$conreserve BLUDSPLT 385 +$conreserve ZIPOPEN 400 +$conreserve ZIPCLOSE 401 +$conreserve ZIPLIGHT 402 +$conreserve SHOTCOCK 410 +$conreserve SHOTFIRE 411 +$conreserve SHOTFIR2 412 +$conreserve SHOTLOAD 413 +$conreserve FLAREF 420 +$conreserve FLAREFUW 421 +$conreserve FLARAIR2 422 +$conreserve FLAR_WAT 423 +$conreserve TOMCOCK 430 +$conreserve _TOM 431 +$conreserve SPRAYCAN 440 +$conreserve SPRAYFIR 441 +$conreserve TNTFUSE 450 +$conreserve PROXARM 451 +$conreserve PROXDET 452 +$conreserve REMFIRE 453 +$conreserve REMDET 454 +$conreserve TNTTOSS 455 +$conreserve VOOSTAB 460 +$conreserve VOOCHANT 461 +$conreserve VOOBURN 462 +$conreserve VOOLAUGH 463 +$conreserve TESSNGFR 470 +$conreserve TESALTFR 471 +$conreserve ROTBAREL 472 +$conreserve SNGAIR2 473 +$conreserve ALTAIR2 474 +$conreserve TESALTF2 475 +$conreserve TESLA1 476 +$conreserve TALTAC3 477 +$conreserve TESLAZ1 478 +$conreserve TESLAZ2 479 +$conreserve BLASTER 480 +$conreserve BLASTARC 481 +$conreserve STAFFIRE 489 +$conreserve LLSNGFR3 490 +$conreserve LLALTFR2 491 +$conreserve LLCHARGE 492 +$conreserve SKULAIR4 493 +$conreserve LALTFR1 494 +$conreserve ACIDHIT1 495 +$conreserve ACIDHIT2 496 +$conreserve BEASTCLW 499 +$conreserve PSTONE 500 +$conreserve PMETAL 501 +$conreserve PWOOD 502 +$conreserve PFLESH 503 +$conreserve UPSTONE 504 +$conreserve UPMETAL 505 +$conreserve UPWOOD 506 +$conreserve UPFLESH 507 +$conreserve BSTONE 510 +$conreserve BMETAL 511 +$conreserve BWOOD 512 +$conreserve BFLESH 513 +$conreserve BWATER 514 +$conreserve RICOCHT1 515 +$conreserve RICOCHT2 516 +$conreserve RICOCHT3 517 +$conreserve TESSNGHT 518 +$conreserve TESALTHT 519 +$conreserve ELECDAM2 520 +$conreserve LLSNGHT2 521 +$conreserve LLALTHT 522 +$conreserve CLAW 530 +$conreserve LNDSTONE 600 +$conreserve LNDMETAL 601 +$conreserve LNDWOOD 602 +$conreserve LNDFLESH 603 +$conreserve LNDWATER 604 +$conreserve LNDDIRT 605 +$conreserve BODYHIT1 607 +$conreserve MTSHLS 608 +$conreserve SHTSHL 609 +$conreserve SHTSHL2 610 +$conreserve SHTSHL3 611 +$conreserve SHTSHL4 612 +$conreserve JUMP 700 +$conreserve LAND 701 +$conreserve HUNT1 702 +$conreserve HUNT2 703 +$conreserve HUNT3 704 +$conreserve HUNT4 705 +$conreserve UWBREATH 706 +$conreserve FRBREATH 707 +$conreserve SWIM 708 +$conreserve SWIMUW 709 +$conreserve PAIN1 710 +$conreserve PAIN2 711 +$conreserve PAIN3 712 +$conreserve PAIN4 713 +$conreserve PAIN5 714 +$conreserve PAIN6 715 +$conreserve DIE1 716 +$conreserve DIE2 717 +$conreserve DIE3 718 +$conreserve FALL 719 +$conreserve SUBMERGE 720 +$conreserve EMERGE 721 +$conreserve GASP 722 +$conreserve INHALE 723 +$conreserve UNDCHOKE 724 +$conreserve PLAY1100 725 +$conreserve PLAY1101 726 +$conreserve PLAY1102 727 +$conreserve PLAY1103 728 +$conreserve PLAY1104 729 +$conreserve PLAY1105 730 +$conreserve PLAY1106 731 +$conreserve PLAY1107 732 +$conreserve PLAY1108 733 +$conreserve PLAY1109 734 +$conreserve PLAY1110 735 +$conreserve PLAY1111 736 +$conreserve PLAY1112 737 +$conreserve PLAY1113 738 +$conreserve PLAY1114 739 +$conreserve PLAY1115 740 +$conreserve PLAY1116 741 +$conreserve PLAY1118 742 +$conreserve PLAY1119 743 +$conreserve PLAY1120 744 +$conreserve BST_FLSH 745 +$conreserve PLAYCHOK 746 +$conreserve PLAYCHK2 747 +$conreserve PICKUP 775 +$conreserve POWERUP 776 +$conreserve WEAPONUP 777 +$conreserve MESSAGE 778 +$conreserve PICKARMR 779 +$conreserve PICKHEAL 780 +$conreserve PICKKEY 781 +$conreserve AMMO 782 +$conreserve FFSTONE1 802 +$conreserve FFSTONE2 803 +$conreserve FFMETAL1 804 +$conreserve FFMETAL2 805 +$conreserve FFWOOD1 806 +$conreserve FFWOOD2 807 +$conreserve FFFLESH1 808 +$conreserve FFFLESH2 809 +$conreserve FFWATER1 810 +$conreserve FFWATER2 811 +$conreserve FFDIRT1 812 +$conreserve FFDIRT2 813 +$conreserve FFCLAY1 814 +$conreserve FFCLAY2 815 +$conreserve FFSNOW1 816 +$conreserve FFSNOW2 817 +$conreserve FFICE1 818 +$conreserve FFICE2 819 +$conreserve FFLEAF1 820 +$conreserve FFLEAF2 821 +$conreserve FFCLOTH1 822 +$conreserve FFCLOTH2 823 +$conreserve FFPLANT1 824 +$conreserve FFPLANT2 825 +$conreserve FFGOO1 826 +$conreserve FFGOO2 827 +$conreserve FFLAVA1 828 +$conreserve FFLAVA2 829 +$conreserve CULTTOSS 1000 +$conreserve CULTATT1 1001 +$conreserve CULTATT2 1002 +$conreserve CULTSPT1 1003 +$conreserve CULTSPT2 1004 +$conreserve CULTSPT3 1005 +$conreserve CULTSPT4 1006 +$conreserve CULTSPT5 1007 +$conreserve CULTROM1 1008 +$conreserve CULTROM2 1009 +$conreserve CULTROM3 1010 +$conreserve CULTROM4 1011 +$conreserve CULTROM5 1012 +$conreserve CULTPAN1 1013 +$conreserve CULTPAN2 1014 +$conreserve CULTPAN3 1015 +$conreserve CULTPAN4 1016 +$conreserve CULTPAN5 1017 +$conreserve CULTDIE1 1018 +$conreserve CULTDIE2 1019 +$conreserve CULTDIE3 1020 +$conreserve CULTGLO1 1021 +$conreserve CULTGLO2 1022 +$conreserve CULTGLO3 1023 +$conreserve CULTGLO4 1024 +$conreserve CULTFIR1 1031 +$conreserve CULTFIR2 1032 +$conreserve CULTFIR3 1033 +$conreserve TCLTTOSS 4000 +$conreserve TCLTATT1 4001 +$conreserve TCLTATT2 4002 +$conreserve TCLTSPT1 4003 +$conreserve TCLTSPT2 4004 +$conreserve TCLTSPT3 4005 +$conreserve TCLTSPT4 4006 +$conreserve TCLTSPT5 4007 +$conreserve TCLTROM1 4008 +$conreserve TCLTROM2 4009 +$conreserve TCLTROM3 4010 +$conreserve TCLTROM4 4011 +$conreserve TCLTROM5 4012 +$conreserve TCLTPAN1 4013 +$conreserve TCLTPAN2 4014 +$conreserve TCLTPAN3 4015 +$conreserve TCLTPAN4 4016 +$conreserve TCLTPAN5 4017 +$conreserve TCLTDIE1 4018 +$conreserve TCLTDIE2 4019 +$conreserve TCLTDIE3 4020 +$conreserve TCLTGLO1 4021 +$conreserve TCLTGLO2 4022 +$conreserve TCLTFIR1 4031 +$conreserve TCLTFIR2 4032 +$conreserve TCLTFIR3 4033 +$conreserve AZOMRISE 1100 +$conreserve AZOMSWIP 1101 +$conreserve AZOMSTND 1102 +$conreserve AZOMSPOT 1103 +$conreserve AZOMROAM 1104 +$conreserve AZOMMOAN 1105 +$conreserve AZOMPAIN 1106 +$conreserve AZOMDIE1 1107 +$conreserve AZOMDIE2 1108 +$conreserve AZOMDIE3 1109 +$conreserve FZOMSPOT 1200 +$conreserve FZOMROAM 1201 +$conreserve FZOMPAIN 1202 +$conreserve FZOMPUKE 1203 +$conreserve FZOMDIE1 1204 +$conreserve FZOMDIE2 1205 +$conreserve FZOMDIE3 1206 +$conreserve CLEAVER 1207 +$conreserve CERBSPOT 1300 +$conreserve CERBPAIN 1302 +$conreserve CERBDIE1 1303 +$conreserve CERBDIE2 1304 +$conreserve CERBDIE3 1305 +$conreserve HOUNDBIT 1306 +$conreserve HOUNDBT2 1307 +$conreserve HOUNDBT3 1308 +$conreserve FIRBALL 1309 +$conreserve GARGSPOT 1400 +$conreserve GARGROAM 1401 +$conreserve GARGPAIN 1402 +$conreserve GARGDIE1 1403 +$conreserve GARGDIE2 1404 +$conreserve GARGDIE3 1405 +$conreserve GARGCLAW 1406 +$conreserve GARGBLST 1407 +$conreserve GARGTHRO 1408 +$conreserve SARGSPOT 1450 +$conreserve SARGROAM 1451 +$conreserve SARGPAIN 1452 +$conreserve SARGDIE1 1453 +$conreserve SARGDIE2 1454 +$conreserve SARGDIE3 1455 +$conreserve SARGCLAW 1456 +$conreserve SARGBLST 1457 +$conreserve SARGTHRO 1458 +$conreserve EELSPOT 1500 +$conreserve EELROAM 1501 +$conreserve EELPAIN 1502 +$conreserve EELDIE1 1503 +$conreserve EELDIE2 1504 +$conreserve EELDIE3 1505 +$conreserve PHANSPOT 1600 +$conreserve PHANROAM 1601 +$conreserve PHANPAIN 1602 +$conreserve PHANDIE1 1603 +$conreserve PHANDIE3 1604 +$conreserve PHANDIE3A 1605 +$conreserve GILLSPOT 1700 +$conreserve GILLROAM 1701 +$conreserve GILLPAIN 1702 +$conreserve GILLDIE1 1703 +$conreserve GILLDIE2 1704 +$conreserve GILLDIE3 1705 +$conreserve SPIDSPOT 1800 +$conreserve SPIDROAM 1801 +$conreserve SPIDPAIN 1802 +$conreserve SPIDDIE1 1803 +$conreserve SPIDDIE2 1804 +$conreserve SPIDDIE3 1805 +$conreserve MSPIDIE 1850 +$conreserve MSPIPAN1 1851 +$conreserve MSPIPAN2 1852 +$conreserve MSPISPT1 1853 +$conreserve MSPISPT2 1854 +$conreserve HANDSPOT 1900 +$conreserve HANDROAM 1901 +$conreserve HANDPAIN 1902 +$conreserve HANDDIE1 1903 +$conreserve HANDDIE2 1904 +$conreserve HANDDIE3 1905 +$conreserve BATSPOT 2000 +$conreserve BATROAM 2001 +$conreserve BATPAIN 2002 +$conreserve BATDIE1 2003 +$conreserve BATDIE2 2004 +$conreserve BATDIE3 2005 +$conreserve BAT 2006 +$conreserve RATSPOT 2100 +$conreserve RATROAM 2101 +$conreserve RATPAIN 2102 +$conreserve RATDIE1 2103 +$conreserve RATDIE2 2104 +$conreserve RATDIE3 2105 +$conreserve PODSQUIS 2200 +$conreserve PODOPEN 2201 +$conreserve PODDIE1 2203 +$conreserve PODDIE2 2204 +$conreserve PODDIE3 2205 +$conreserve PODSWISH 2206 +$conreserve CERBSPOTA 2300 +$conreserve CERBROAM 2301 +$conreserve CERBPAIN2 2302 +$conreserve CERBPAIN3 2303 +$conreserve CERBDIE2A 2304 +$conreserve CERBDIE3A 2305 +$conreserve CERBDIE4 2306 +$conreserve TBBOW1 2350 +$conreserve TBBOW2 2351 +$conreserve TBKNEEL1 2352 +$conreserve TBKNEEL2 2353 +$conreserve TBKNEEL3 2354 +$conreserve TBKNEEL4 2355 +$conreserve TBWAIT1 2356 +$conreserve TBWAIT2 2357 +$conreserve TBLAUGH1 2360 +$conreserve TBLAUGH2 2361 +$conreserve TBLAUGH3 2362 +$conreserve TBLAUGH4 2363 +$conreserve TBLAUGH5 2364 +$conreserve TBSACRI1 2365 +$conreserve TBSACRI2 2366 +$conreserve TBSACRI3 2367 +$conreserve TBWORSH1 2368 +$conreserve TBWORSH2 2369 +$conreserve TBPAIN1 2370 +$conreserve TBPAIN2 2371 +$conreserve TBPAIN3 2372 +$conreserve TBPAIN4 2373 +$conreserve TBPAIN5 2374 +$conreserve TBPAIN6 2375 +$conreserve TBPAIN7 2377 +$conreserve TBDIES 2380 +$conreserve TCHNEVAP 2381 +$conreserve FLYBUZZ 2400 +$conreserve MFLY 2401 +$conreserve FPODCLOS 2450 +$conreserve FPODCOL2 2451 +$conreserve FPODEXP2 2452 +$conreserve FPODOPEN 2453 +$conreserve FPODSPIT 2454 +$conreserve FPODCLOS2 2470 +$conreserve PODCOL2 2471 +$conreserve PODEXP2 2472 +$conreserve NPODOPEN 2473 +$conreserve PODSPIT1 2474 +$conreserve PODSPIT2 2475 +$conreserve TENTDWN3 2500 +$conreserve TENTEXP 2501 +$conreserve TENTSWP4 2502 +$conreserve TENTUP3 2503 +$conreserve 1001 3000 +$conreserve 1002 3001 +$conreserve 1003 3002 +$conreserve 1004 3003 +$conreserve 1005 3004 +$conreserve 1006 3005 +$conreserve 1007 3006 +$conreserve 1008 3007 +$conreserve 1009 3008 +$conreserve 1010 3009 +$conreserve 1011 3010 +$conreserve 1012 3011 +$conreserve 1013 3012 +$conreserve 1014 3013 +$conreserve 1015 3014 +$conreserve 1016 3015 +$conreserve 1017 3016 +$conreserve 1018 3017 +$conreserve 1019 3018 +$conreserve 1020 3019 +$conreserve 1021 3020 +$conreserve 1022 3021 +$conreserve 1023 3022 +$conreserve 1024 3023 +$conreserve 1025 3024 +$conreserve 1026 3025 +$conreserve 1027 3026 +$conreserve 1028 3027 +$conreserve 1029 3028 +$conreserve 1030 3029 +$conreserve 1031 3030 +$conreserve 1032 3031 +$conreserve 1033 3032 +$conreserve 1034 3033 +$conreserve 1035 3034 +$conreserve 1036 3035 +$conreserve 1037 3036 +$conreserve 1038 3037 +$conreserve 1039 3038 +$conreserve 1040 3039 +$conreserve 1041 3040 +$conreserve 1042 3041 +$conreserve 1043 3042 +$conreserve 1044 3043 +$conreserve 1045 3044 +$conreserve 1046 3045 +$conreserve 1047 3046 +$conreserve 1048 3047 +$conreserve 1049 3048 +$conreserve 1050 3049 +$conreserve 1051 3050 +$conreserve 1052 3051 +$conreserve 1053 3052 +$conreserve 1054 3053 +$conreserve 1055 3054 +$conreserve 1056 3055 +$conreserve 1057 3056 +$conreserve 1059 3058 +$conreserve 1060 3059 +$conreserve 1061 3060 +$conreserve 1062 3061 +$conreserve 1063 3062 +$conreserve 1064 3063 +$conreserve 1065 3064 +$conreserve 1066 3065 +$conreserve 1067 3066 +$conreserve 1068 3067 +$conreserve 1069 3068 +$conreserve 1070 3069 +$conreserve 1071 3070 +$conreserve 1072 3071 +$conreserve 1073 3072 +$conreserve 1074 3073 +$conreserve 1075 3074 +$conreserve 1076 3075 +$conreserve 1077 3076 +$conreserve 1078 3077 +$conreserve 1079 3078 +$conreserve 1080 3079 +$conreserve 1081 3080 +$conreserve 1082 3081 +$conreserve 1083 3082 +$conreserve 1084 3083 +$conreserve 1085 3084 +$conreserve 1093 3100 +$conreserve 1094 3101 +$conreserve 1095 3102 +$conreserve 1097 3103 +$conreserve VO3011 3104 +$conreserve VO3024 3105 +$conreserve VO3026 3106 +$conreserve VO3030 3107 +$conreserve VO3033 3108 +$conreserve VO3034 3109 +$conreserve VO3035 3110 +$conreserve VO3039 3111 +$conreserve 2100 3200 +$conreserve 2101 3201 +$conreserve 2102 3202 +$conreserve 2103 3203 +$conreserve 2104 3204 +$conreserve 2105 3205 +$conreserve 2106 3206 +$conreserve 2107 3207 +$conreserve 2108 3208 +$conreserve 2109 3209 +$conreserve ZOMBIE 3210 +$conreserve 2111 3211 +$conreserve 2112 3212 +$conreserve 2113 3213 +$conreserve 2114 3214 +$conreserve 2116 3216 +$conreserve VO1 3300 +$conreserve VO2 3301 +$conreserve VO3 3302 +$conreserve VO4 3303 +$conreserve VO5 3304 +$conreserve VO6 3305 +$conreserve VO7 3306 +$conreserve VO8 3307 +$conreserve VO9 3308 +$conreserve VO10 3309 +$conreserve VO12 3310 +$conreserve VO13 3311 +$conreserve VO14 3312 +$conreserve VO15 3313 +$conreserve VO16 3314 +$conreserve VO17 3317 +$conreserve VO18 3318 +$conreserve VO19 3319 +$conreserve VO20 3320 +$conreserve VO21 3321 +$conreserve VO22 3322 +$conreserve VO23 3323 +$conreserve VO24 3324 +$conreserve VO25 3325 +$conreserve VO26 3326 +$conreserve VO27 3327 +$conreserve VO28 3328 +$conreserve VO29 3329 +$conreserve VO30 3330 +$conreserve VO31 3331 +$conreserve VO32 3332 +$conreserve VO33 3333 +$conreserve VO34 3334 +$conreserve VO35 3335 +$conreserve VO36 3336 +$conreserve VO37 3337 +$conreserve VO38 3338 +$conreserve VO39 3339 +$conreserve VO40 3340 +$conreserve VO41 3341 +$conreserve VO42 3342 +$conreserve VO43 3343 +$conreserve VO44 3344 +$conreserve ALIVE 3345 +$conreserve BONED 4100 +$conreserve CASTRA 4101 +$conreserve CREAMED 4102 +$conreserve DESTRO 4103 +$conreserve DICED 4104 +$conreserve DISEMBO 4105 +$conreserve FLATTE 4106 +$conreserve JUSTICE 4107 +$conreserve MADNESS 4108 +$conreserve DECIMAT 4109 +$conreserve KILLED 4110 +$conreserve MINCMEAT 4111 +$conreserve MASSACR 4112 +$conreserve MUTILA 4113 +$conreserve REAMED 4114 +$conreserve RIPPED 4115 +$conreserve SLAUGHT 4116 +$conreserve SLICED 4117 +$conreserve SMASHED 4118 +$conreserve SODOMIZ 4119 +$conreserve SPLATT 4120 +$conreserve SQUASH 4121 +$conreserve THROTTL 4122 +$conreserve WASTED 4123 +$conreserve 10 4124 +$conreserve OMNI24 4125 +$conreserve OMNI25 4126 +$conreserve OMNI26 4127 +$conreserve OMNI27 4128 +$conreserve OMNI32 4129 +$conreserve OMNI34 4130 +$conreserve OMNI35 4141 +$conreserve OMNI36 4132 +$conreserve OMNI37 4133 +$conreserve OMNI41 4134 +$conreserve OMNI43 4135 +$conreserve OMNI44 4136 +$conreserve OMNI5 4200 +$conreserve OMNI7 4202 +$conreserve OMNI8 4203 +$conreserve OMNI9 4204 +$conreserve OMNI12 4206 +$conreserve OMNI13 4207 +$conreserve OMNI16 4208 +$conreserve OMNI20 4210 +$conreserve OMNI21 4211 +$conreserve OMNI22 4212 +$conreserve OMNI23 4213 +$conreserve OMNI15A 4300 +$conreserve TAUNT0 4400 +$conreserve TAUNT1 4401 +$conreserve TAUNT2 4402 +$conreserve TAUNT3 4403 +$conreserve TAUNT4 4404 +$conreserve TAUNT5 4405 +$conreserve TAUNT6 4406 +$conreserve TAUNT7 4407 +$conreserve TAUNT8 4408 +$conreserve TAUNT9 4409 +$conreserve 3000 4500 +$conreserve 3001B 4502 +$conreserve 3002A 4503 +$conreserve 3002B 4504 +$conreserve 3002C 4505 +$conreserve 3002D 4506 +$conreserve 3003 4507 +$conreserve 3004B 4509 +$conreserve 3006 4511 +$conreserve 3007 4512 +$conreserve 3008 4513 +$conreserve 3009 4514 +$conreserve 3010 4515 +$conreserve 3011 4516 +$conreserve 3012 4517 +$conreserve 3013 4518 +$conreserve 3014 4519 +$conreserve 3015 4520 +$conreserve 3016A 4521 +$conreserve 3017 4523 +$conreserve 3018B 4525 +$conreserve 3019 4526 +$conreserve 3020 4527 +$conreserve 3021 4528 +$conreserve 3022B 4530 +$conreserve 3023A 4531 +$conreserve 3024 4533 +$conreserve 3025 4534 +$conreserve 3026 4535 +$conreserve 3027 4536 +$conreserve 3028 4537 +$conreserve 3029 4538 +$conreserve 3030 4539 +$conreserve 3031 4540 +$conreserve 3032 4541 +$conreserve 3033 4542 +$conreserve 3034 4543 +$conreserve 3035 4544 +$conreserve 3036 4545 +$conreserve 3037 4546 +$conreserve 3038 4547 +$conreserve 3039 4548 +$conreserve ICRYING 7000 +$conreserve ICRYING2 7001 +$conreserve IDONHME 7002 +$conreserve IGOAWAY2 7003 +$conreserve IGOAWAY3 7004 +$conreserve INOPLACE 7005 +$conreserve IPLEASE 7006 +$conreserve ISCREAM1 7007 +$conreserve ISCREAM2 7008 +$conreserve 8000 8000 +$conreserve 8001 8001 +$conreserve 8002 8002 +$conreserve 8003 8003 +$conreserve 8004 8004 +$conreserve 8005 8005 +$conreserve 8006 8006 +$conreserve 8007 8007 +$conreserve BEASTD4 9000 +$conreserve BEASTD3 9001 +$conreserve BEASTD2 9002 +$conreserve BEASTD1 9003 +$conreserve BEAST1 9004 +$conreserve BEAST2 9005 +$conreserve BEAST3 9006 +$conreserve CALEBM1 9007 +$conreserve CULTMO1 9008 +$conreserve ROAR1 9009 +$conreserve ROAR2 9010 +$conreserve ROAR3 9011 +$conreserve SLASH1 9012 +$conreserve SLASH2 9013 +$conreserve SLASH3 9014 +$conreserve T1005 10001 +$conreserve T1002 10000 +$conreserve STOMP3 9017 +$conreserve STOMP4 9016 +$conreserve STOM5 9015 +$conreserve T1006 10002 +$conreserve T1010 10003 +$conreserve T1011 10004 +$conreserve T1015 10005 +$conreserve T1051 10006 +$conreserve T1003 11000 +$conreserve T1013 11001 diff --git a/wadsrc/static/filter/dukelike/rmapinfo.texflags b/wadsrc/static/filter/dukelike/rmapinfo.texflags index 671f2c18f..3736ec554 100644 --- a/wadsrc/static/filter/dukelike/rmapinfo.texflags +++ b/wadsrc/static/filter/dukelike/rmapinfo.texflags @@ -117,7 +117,7 @@ switches comboswitch = "TECHSWITCH", "TECHSWITCHON" comboswitch = "ALIENSWITCH", "ALIENSWITCHON" accessswitch = "ACCESSSWITCH", "ACCESSSWITCHON", nofilter, oneway - accessswitch = "ACCESSSWITCH2", "ACCESSSWITCH2", nofilter, oneway + accessswitch = "ACCESSSWITCH2", "ACCESSSWITCH2ON", nofilter, oneway switch = "DIPSWITCH2", "DIPSWITCH2ON", shootable switch = "DIPSWITCH3", "DIPSWITCH3ON", shootable multiswitch = "MULTISWITCH", "MULTISWITCH_2", "MULTISWITCH_3", "MULTISWITCH_4" diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index e02727d66..a76fdc80f 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -325,7 +325,7 @@ float R_DoomLightingEquation(float light) // This is a lot more primitive than Doom's lighting... float numShades = float(uPalLightLevels & 255); float curshade = (1.0 - light) * (numShades - 1.0); - float visibility = max(uGlobVis * uLightFactor * abs(z), 0.0); + float visibility = max(uGlobVis * uLightFactor * z, 0.0); float shade = clamp((curshade + visibility), 0.0, numShades - 1.0); return clamp(shade * uLightDist, 0.0, 1.0); } @@ -344,10 +344,86 @@ float R_DoomLightingEquation(float light) //=========================================================================== // -// Check if light is in shadow according to its 1D shadow map +// Check if light is in shadow // //=========================================================================== +#ifdef SUPPORTS_RAYTRACING + +bool traceHit(vec3 origin, vec3 direction, float dist) +{ + rayQueryEXT rayQuery; + rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, dist); + while(rayQueryProceedEXT(rayQuery)) { } + return rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionNoneEXT; +} + +vec2 softshadow[9 * 3] = vec2[]( + vec2( 0.0, 0.0), + vec2(-2.0,-2.0), + vec2( 2.0, 2.0), + vec2( 2.0,-2.0), + vec2(-2.0, 2.0), + vec2(-1.0,-1.0), + vec2( 1.0, 1.0), + vec2( 1.0,-1.0), + vec2(-1.0, 1.0), + + vec2( 0.0, 0.0), + vec2(-1.5,-1.5), + vec2( 1.5, 1.5), + vec2( 1.5,-1.5), + vec2(-1.5, 1.5), + vec2(-0.5,-0.5), + vec2( 0.5, 0.5), + vec2( 0.5,-0.5), + vec2(-0.5, 0.5), + + vec2( 0.0, 0.0), + vec2(-1.25,-1.75), + vec2( 1.75, 1.25), + vec2( 1.25,-1.75), + vec2(-1.75, 1.75), + vec2(-0.75,-0.25), + vec2( 0.25, 0.75), + vec2( 0.75,-0.25), + vec2(-0.25, 0.75) +); + +float shadowAttenuation(vec4 lightpos, float lightcolorA) +{ + float shadowIndex = abs(lightcolorA) - 1.0; + if (shadowIndex >= 1024.0) + return 1.0; // Don't cast rays for this light + + vec3 origin = pixelpos.xzy; + vec3 target = lightpos.xzy + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes + + vec3 direction = normalize(target - origin); + float dist = distance(origin, target); + + if (uShadowmapFilter <= 0) + { + return traceHit(origin, direction, dist) ? 0.0 : 1.0; + } + else + { + vec3 v = (abs(direction.x) > abs(direction.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); + vec3 xdir = normalize(cross(direction, v)); + vec3 ydir = cross(direction, xdir); + + float sum = 0.0; + int step_count = uShadowmapFilter * 9; + for (int i = 0; i <= step_count; i++) + { + vec3 pos = target + xdir * softshadow[i].x + ydir * softshadow[i].y; + sum += traceHit(origin, normalize(pos - origin), dist) ? 0.0 : 1.0; + } + return sum / step_count; + } +} + +#else #ifdef SUPPORTS_SHADOWMAPS float shadowDirToU(vec2 dir) @@ -491,6 +567,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA) return 1.0; } +#endif #endif float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle) diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 9d5599b29..7c137fff3 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -5,11 +5,15 @@ layout(location = 2) in vec4 aColor; layout(location = 0) out vec4 vTexCoord; layout(location = 1) out vec4 vColor; +layout(location = 9) out vec3 vLightmap; #ifndef SIMPLE // we do not need these for simple shaders layout(location = 3) in vec4 aVertex2; layout(location = 4) in vec4 aNormal; layout(location = 5) in vec4 aNormal2; +layout(location = 6) in vec3 aLightmap; +layout(location = 7) in vec4 aBoneWeight; +layout(location = 8) in uvec4 aBoneSelector; layout(location = 2) out vec4 pixelpos; layout(location = 3) out vec3 glowdist; @@ -23,6 +27,14 @@ layout(location = 7) out vec4 ClipDistanceA; layout(location = 8) out vec4 ClipDistanceB; #endif +struct BonesResult +{ + vec3 Normal; + vec4 Position; +}; + +BonesResult ApplyBones(); + void main() { float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4; @@ -30,9 +42,11 @@ void main() vec2 parmTexCoord; vec4 parmPosition; - parmTexCoord = aTexCoord; - parmPosition = aPosition; + BonesResult bones = ApplyBones(); + parmTexCoord = aTexCoord; + parmPosition = bones.Position; + #ifndef SIMPLE vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor); #else @@ -51,6 +65,8 @@ void main() #endif #ifndef SIMPLE + vLightmap = aLightmap; + pixelpos.xyz = worldcoord.xyz; pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; @@ -78,14 +94,7 @@ void main() ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z); } - #ifdef HAS_UNIFORM_VERTEX_DATA - if ((useVertexData & 2) == 0) - vWorldNormal = NormalModelMatrix * vec4(normalize(uVertexNormal.xyz), 1.0); - else - vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0); - #else - vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0); - #endif + vWorldNormal = NormalModelMatrix * vec4(normalize(bones.Normal), 1.0); vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0); #endif @@ -142,3 +151,66 @@ void main() gl_PointSize = 1.0; } + +#if !defined(SIMPLE) +vec3 GetAttrNormal() +{ + #ifdef HAS_UNIFORM_VERTEX_DATA + if ((useVertexData & 2) == 0) + return uVertexNormal.xyz; + else + return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor); + #else + return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor); + #endif +} + +void AddWeightedBone(uint boneIndex, float weight, inout vec4 position, inout vec3 normal) +{ + if (weight != 0.0) + { + mat4 transform = bones[uBoneIndexBase + int(boneIndex)]; + mat3 rotation = mat3(transform); + position += (transform * aPosition) * weight; + normal += (rotation * aNormal.xyz) * weight; + } +} + +BonesResult ApplyBones() +{ + BonesResult result; + if (uBoneIndexBase >= 0 && aBoneWeight != vec4(0.0)) + { + result.Position = vec4(0.0); + result.Normal = vec3(0.0); + + // We use low precision input for our bone weights. Rescale so the sum still is 1.0 + float totalWeight = aBoneWeight.x + aBoneWeight.y + aBoneWeight.z + aBoneWeight.w; + float weightMultiplier = 1.0 / totalWeight; + vec4 boneWeight = aBoneWeight * weightMultiplier; + + AddWeightedBone(aBoneSelector.x, boneWeight.x, result.Position, result.Normal); + AddWeightedBone(aBoneSelector.y, boneWeight.y, result.Position, result.Normal); + AddWeightedBone(aBoneSelector.z, boneWeight.z, result.Position, result.Normal); + AddWeightedBone(aBoneSelector.w, boneWeight.w, result.Position, result.Normal); + + result.Position.w = 1.0; // For numerical stability + } + else + { + result.Position = aPosition; + result.Normal = GetAttrNormal(); + } + return result; +} + +#else + +BonesResult ApplyBones() +{ + BonesResult result; + result.Position = aPosition; + return result; +} + +#endif diff --git a/wadsrc/static/shaders/glsl/material_normal.fp b/wadsrc/static/shaders/glsl/material_normal.fp index 02c905623..b9d25852c 100644 --- a/wadsrc/static/shaders/glsl/material_normal.fp +++ b/wadsrc/static/shaders/glsl/material_normal.fp @@ -59,7 +59,21 @@ vec3 ProcessMaterialLight(Material material, vec3 color) } } - vec3 frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + vec3 frag; + + if ( uLightBlendMode == 1 ) + { // COLOR_CORRECT_CLAMPING + vec3 lightcolor = color + desaturate(dynlight).rgb; + frag = material.Base.rgb * ((lightcolor / max(max(max(lightcolor.r, lightcolor.g), lightcolor.b), 1.4) * 1.4)); + } + else if ( uLightBlendMode == 2 ) + { // UNCLAMPED + frag = material.Base.rgb * (color + desaturate(dynlight).rgb); + } + else + { + frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + } if (uLightIndex >= 0) { diff --git a/wadsrc/static/shaders/glsl/material_specular.fp b/wadsrc/static/shaders/glsl/material_specular.fp index 015586f95..12eabd33e 100644 --- a/wadsrc/static/shaders/glsl/material_specular.fp +++ b/wadsrc/static/shaders/glsl/material_specular.fp @@ -66,9 +66,25 @@ vec3 ProcessMaterialLight(Material material, vec3 color) } } } + + if ( uLightBlendMode == 1 ) + { // COLOR_CORRECT_CLAMPING + dynlight.rgb = color + desaturate(dynlight).rgb; + specular.rgb = desaturate(specular).rgb; - dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); - specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4); + dynlight.rgb = ((dynlight.rgb / max(max(max(dynlight.r, dynlight.g), dynlight.b), 1.4) * 1.4)); + specular.rgb = ((specular.rgb / max(max(max(specular.r, specular.g), specular.b), 1.4) * 1.4)); + } + else if ( uLightBlendMode == 2 ) + { // UNCLAMPED + dynlight.rgb = color + desaturate(dynlight).rgb; + specular.rgb = desaturate(specular).rgb; + } + else + { + dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4); + } vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb; diff --git a/wadsrc/static/zscript/games/duke/actors/soundcontroller.zs b/wadsrc/static/zscript/games/duke/actors/soundcontroller.zs index 49009b784..501028b06 100644 --- a/wadsrc/static/zscript/games/duke/actors/soundcontroller.zs +++ b/wadsrc/static/zscript/games/duke/actors/soundcontroller.zs @@ -45,7 +45,7 @@ class DukeSoundController : DukeActor let sec = self.sector; if (self.lotag < 999 && sec.lotag >= 0 && sec.lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && sec.floorz != sec.ceilingz) { - int flags = Duke.GetSoundFlags(self.lotag); + int flags = Duke.GetSoundFlags(Raze.FindSoundByResID(self.lotag)); if (flags & Duke.SF_MSFX) { double distance = (p.actor.pos - self.pos).Length(); diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 351016e00..90f66dd88 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -198,8 +198,8 @@ struct Duke native } else { - if (align != -1) x -= myfont.StringWidth(text) * (align == 0 ? 0.2 : 0.4); - Screen.DrawText(myfont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha); + if (align != -1) x -= myfont.StringWidth(text) * (align == 0 ? 0.175 : 0.35); + Screen.DrawText(myfont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.35, DTA_ScaleY, 0.35, DTA_Alpha, alpha); } } diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index e6efb496c..64fd5bb16 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -495,6 +495,9 @@ class DukeLevelSummaryScreen : SummaryScreenBase TextureID texBg; TextureID texOv[4]; + double text_x; + double val_x; + enum EScreenFlags { printTimeText = 1, @@ -555,6 +558,37 @@ class DukeLevelSummaryScreen : SummaryScreenBase return false; } + private void CalcLayout() + { + static const String texts[] = { "$TXT_YourTime", "$TXT_ParTime", "$TXT_3DRTIME", "$TXT_EnemiesKilled", "$TXT_EnemiesLeft", "$TXT_SECFND", "$TXT_SECMISS" }; + let myfont = Raze.PickSmallFont(); + let fact = screen.GetAspectRatio(); + let vwidth = 320 * 0.75 * fact; + let left = 5 + (320 - vwidth) / 2; + let twidth = 0.0; + + text_x = 10; + val_x = 151; + for(int i = 0; i < texts.size(); i++) + { + twidth = max(twidth, myfont.StringWidth(texts[i])); + } + if (twidth > 140 && twidth < 156) + { + val_x += twidth - 140; + } + else if (twidth >= 156) + { + val_x = 166; + text_x -= twidth - 156; + if (text_x < left) + { + val_x += left - text_x; + text_x = left; + } + } + } + override void Start() { Duke.PlayBonusMusic(); @@ -562,6 +596,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase override void OnTick() { + CalcLayout(); if ((displaystate & printStatsAll) != printStatsAll) { if (ticks == 15 * 3) @@ -610,23 +645,23 @@ class DukeLevelSummaryScreen : SummaryScreenBase void PrintTime() { String tempbuf; - Duke.GameText(10, 59 + 9, "$TXT_YourTime", 0); - Duke.GameText(10, 69 + 9, "$TXT_ParTime", 0); + Duke.GameText(text_x, 59 + 9, "$TXT_YourTime", 0); + Duke.GameText(text_x, 69 + 9, "$TXT_ParTime", 0); if (!Raze.isNamWW2GI()) - Duke.GameText(10, 79 + 9, "$TXT_3DRTIME", 0); + Duke.GameText(text_x, 79 + 9, "$TXT_3DRTIME", 0); if (displaystate & printTimeVal) { tempbuf = FormatTime(stats.time); - Duke.GameText((320 >> 2) + 71, 59 + 9, tempbuf, 0); + Duke.GameText(val_x, 59 + 9, tempbuf, 0); tempbuf = FormatTime(level.parTime); - Duke.GameText((320 >> 2) + 71, 69 + 9, tempbuf, 0); + Duke.GameText(val_x, 69 + 9, tempbuf, 0); if (!Raze.isNamWW2GI()) { tempbuf = FormatTime(level.designerTime); - Duke.GameText((320 >> 2) + 71, 79 + 9, tempbuf, 0); + Duke.GameText(val_x, 79 + 9, tempbuf, 0); } } } @@ -634,13 +669,13 @@ class DukeLevelSummaryScreen : SummaryScreenBase void PrintKills() { String tempbuf; - Duke.GameText(10, 94 + 9, "$TXT_EnemiesKilled", 0); - Duke.GameText(10, 104 + 9, "$TXT_EnemiesLeft", 0); + Duke.GameText(text_x, 94 + 9, "$TXT_EnemiesKilled", 0); + Duke.GameText(text_x, 104 + 9, "$TXT_EnemiesLeft", 0); if (displaystate & printKillsVal) { tempbuf = String.Format("%-3d", stats.kills); - Duke.GameText((320 >> 2) + 70, 94 + 9, tempbuf, 0); + Duke.GameText(val_x, 94 + 9, tempbuf, 0); if (stats.maxkills < 0) { @@ -650,22 +685,22 @@ class DukeLevelSummaryScreen : SummaryScreenBase { tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills)); } - Duke.GameText((320 >> 2) + 70, 104 + 9, tempbuf, 0); + Duke.GameText(val_x, 104 + 9, tempbuf, 0); } } void PrintSecrets() { String tempbuf; - Duke.GameText(10, 119 + 9, "$TXT_SECFND", 0); - Duke.GameText(10, 129 + 9, "$TXT_SECMISS", 0); + Duke.GameText(text_x, 119 + 9, "$TXT_SECFND", 0); + Duke.GameText(text_x, 129 + 9, "$TXT_SECMISS", 0); if (displaystate & printSecretsVal) { tempbuf = String.Format("%-3d", stats.secrets); - Duke.GameText((320 >> 2) + 70, 119 + 9, tempbuf, 0); + Duke.GameText(val_x, 119 + 9, tempbuf, 0); tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets)); - Duke.GameText((320 >> 2) + 70, 129 + 9, tempbuf, 0); + Duke.GameText(val_x, 129 + 9, tempbuf, 0); } } @@ -675,19 +710,6 @@ class DukeLevelSummaryScreen : SummaryScreenBase Duke.GameText(160, 190, "$PRESSKEY", 8 - (sin(ticks * 4) * 8), 0); - if (displaystate & printTimeText) - { - PrintTime(); - } - if (displaystate & printKillsText) - { - PrintKills(); - } - if (displaystate & printSecretsText) - { - PrintSecrets(); - } - if (displaystate & dukeAnim) { switch (((ticks - dukeAnimStart) >> 2) % 15) @@ -718,6 +740,20 @@ class DukeLevelSummaryScreen : SummaryScreenBase } } + if (displaystate & printTimeText) + { + PrintTime(); + } + if (displaystate & printKillsText) + { + PrintKills(); + } + if (displaystate & printSecretsText) + { + PrintSecrets(); + } + + if (lastmapname) Duke.BigText(160, 20 - 6, lastmapname, 0); Duke.BigText(160, 36 - 6, "$Completed", 0); } @@ -738,6 +774,13 @@ class RRLevelSummaryScreen : SummaryScreenBase int exitSoundStart; TextureID texBg; + double text_x; + double val_x; + double val_x2; + double press_x; + double map_x; + + enum EFlags { printTimeText = 1, @@ -792,6 +835,67 @@ class RRLevelSummaryScreen : SummaryScreenBase return false; } + private void CalcLayout() + { + static const String texts[] = { "$TXT_YerTime", "$TXT_ParTime", "$TXT_XTRTIME"}; + static const String texts2[] = { "$TXT_VarmintsKilled", "$TXT_VarmintsLeft", "$TXT_SECFND", "$TXT_SECMISS" }; + let myfont = Raze.PickBigFont(); + let fact = screen.GetAspectRatio(); + let vwidth = 320 * 0.75 * fact; + let left = 5 + (320 - vwidth) / 2; + let twidth = 0.0; + let twidth1 = 0.0; + + text_x = 30; + val_x = 191; + val_x2 = 231; + for(int i = 0; i < texts.size(); i++) + { + twidth1 = max(twidth1, 0.35 * myfont.StringWidth(texts[i])); + } + for(int i = 0; i < texts2.size(); i++) + { + twidth = max(twidth, 0.35 * myfont.StringWidth(texts2[i])); + } + + if (twidth1 > 155 && twidth1 < 190 && twidth < 230) + { + Console.printf("small case: %f, %f", twidth, val_x); + val_x = val_x2; + return; + } + twidth = max(twidth, twidth1 + 40); + + if (twidth >= 195 && twidth < 230) + { + val_x2 += twidth - 195; + val_x = val_x2; + } + else if (twidth >= 230) + { + val_x2 = 266; + text_x -= twidth - 230; + if (text_x < left) + { + val_x2 += left - text_x; + text_x = left; + } + val_x = val_x2; + } + + map_x = 80; + let w = myfont.StringWidth(lastmapname) * 0.35; + if (w > 320) map_x = -(w - 320) / 2; + else if (w > 240) map_x = (320 - w) / 2; + + press_x = 15; + w = myfont.StringWidth("$PRESSKEY") * 0.35; + if (w > 320) press_x = -(w - 320) / 2; + else if (w > 300) press_x = (320 - w) / 2; + + } + + override void OnTick() { if ((displaystate & printStatsAll) != printStatsAll) @@ -841,33 +945,33 @@ class RRLevelSummaryScreen : SummaryScreenBase void PrintTime() { String tempbuf; - Duke.BigText(30, 48, "$TXT_YerTime", -1); - Duke.BigText(30, 64, "$TXT_ParTime", -1); - Duke.BigText(30, 80, "$TXT_XTRTIME", -1); + Duke.BigText(text_x, 48, "$TXT_YerTime", -1); + Duke.BigText(text_x, 64, "$TXT_ParTime", -1); + Duke.BigText(text_x, 80, "$TXT_XTRTIME", -1); if (displaystate & printTimeVal) { tempbuf = FormatTime(stats.time); - Duke.BigText(191, 48, tempbuf, -1); + Duke.BigText(val_x, 48, tempbuf, -1); tempbuf = FormatTime(level.parTime); - Duke.BigText(191, 64, tempbuf, -1); + Duke.BigText(val_x, 64, tempbuf, -1); tempbuf = FormatTime(level.designerTime); - Duke.BigText(191, 80, tempbuf, -1); + Duke.BigText(val_x, 80, tempbuf, -1); } } void PrintKills() { String tempbuf; - Duke.BigText(30, 112, "$TXT_VarmintsKilled", -1); - Duke.BigText(30, 128, "$TXT_VarmintsLeft", -1); + Duke.BigText(text_x, 112, "$TXT_VarmintsKilled", -1); + Duke.BigText(text_x, 128, "$TXT_VarmintsLeft", -1); if (displaystate & printKillsVal) { tempbuf = String.Format("%-3d", stats.kills); - Duke.BigText(231, 112, tempbuf, -1); + Duke.BigText(val_x2, 112, tempbuf, -1); if (stats.maxkills < 0) { tempbuf = "$TXT_N_A"; @@ -876,31 +980,32 @@ class RRLevelSummaryScreen : SummaryScreenBase { tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills)); } - Duke.BigText(231, 128, tempbuf, -1); + Duke.BigText(val_x2, 128, tempbuf, -1); } } void PrintSecrets() { String tempbuf; - Duke.BigText(30, 144, "$TXT_SECFND", -1); - Duke.BigText(30, 160, "$TXT_SECMISS", -1); + Duke.BigText(text_x, 144, "$TXT_SECFND", -1); + Duke.BigText(text_x, 160, "$TXT_SECMISS", -1); if (displaystate & printSecretsVal) { tempbuf = String.Format("%-3d", stats.secrets); - Duke.BigText(231, 144, tempbuf, -1); + Duke.BigText(val_x2, 144, tempbuf, -1); tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets)); - Duke.BigText(231, 160, tempbuf, -1); + Duke.BigText(val_x2, 160, tempbuf, -1); } } override void Draw(double sr) { + CalcLayout(); Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); - Duke.BigText(80, 16, lastmapname, -1); - Duke.BigText(15, 192, "$PRESSKEY", -1); + Duke.BigText(map_x, 16, lastmapname, -1); + Duke.BigText(press_x, 192, "$PRESSKEY", -1); if (displaystate & printTimeText) { diff --git a/wadsrc/static/zscript/level_compatibility.zs b/wadsrc/static/zscript/level_compatibility.zs index e1135f56e..13ecda6f5 100644 --- a/wadsrc/static/zscript/level_compatibility.zs +++ b/wadsrc/static/zscript/level_compatibility.zs @@ -12,6 +12,10 @@ class LevelCompatibility : LevelPostProcessor case 'b522da99f32a71ab31fc27aaba9b7f43': // Duke E2L1 World Tour SplitSector(37, 269, 274); // sector bleeds into another area. break; + + case '459c71d47b5beaa058253e162fd5a5c2': // World Tour e5l1.map + for(int i = 1373; i <= 1376; i++) SetSpriteSector(i, 860); // fix bad sector in a few sprites. + break; case 'c3bfb6a6e7cded2e5fe16cea86632d79': // CP07 SplitSector(33, 192, 196); // sector bleeds into another area. diff --git a/wadsrc/static/zscript/level_postprocessor.zs b/wadsrc/static/zscript/level_postprocessor.zs index 02ec4cab0..570db5c86 100644 --- a/wadsrc/static/zscript/level_postprocessor.zs +++ b/wadsrc/static/zscript/level_postprocessor.zs @@ -6,6 +6,7 @@ class LevelPostProcessor native play } protected native void SetSpriteLotag(int sprite, int tag); + protected native void SetSpriteSector(int sprite, int tag); protected native void ChangeSpriteFlags(int sprite, int set, int clear); protected native void sw_serp_continue(); protected native void SplitSector(int sect, int wal1, int wal2);