diff --git a/src/compatibility.cpp b/src/compatibility.cpp index f47ea9a96..9fd9f5746 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -52,6 +52,7 @@ #include "p_tags.h" #include "r_state.h" #include "w_wad.h" +#include "textures.h" #include "g_levellocals.h" // MACROS ------------------------------------------------------------------ @@ -80,13 +81,15 @@ enum CP_SETSPECIAL, CP_CLEARSPECIAL, CP_SETACTIVATION, - CP_SECTORFLOOROFFSET, + CP_SETSECTOROFFSET, CP_SETSECTORSPECIAL, CP_SETWALLYSCALE, + CP_SETWALLTEXTURE, CP_SETTHINGZ, CP_SETTAG, CP_SETTHINGFLAGS, CP_SETVERTEX, + CP_SETTHINGSKILLS, }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -166,8 +169,14 @@ static const char *const WallTiers[] = "Top", "Mid", "Bot", NULL }; +static const char *const SectorPlanes[] = +{ + "floor", "ceil", NULL +}; + static TArray CompatParams; static int ii_compatparams; +static TArray TexNames; // CODE -------------------------------------------------------------------- @@ -288,12 +297,14 @@ void ParseCompatibility() sc.MustGetNumber(); CompatParams.Push(sc.Number); } - else if (sc.Compare("sectorflooroffset")) + else if (sc.Compare("setsectoroffset")) { if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SECTORFLOOROFFSET); + CompatParams.Push(CP_SETSECTOROFFSET); sc.MustGetNumber(); CompatParams.Push(sc.Number); + sc.MustGetString(); + CompatParams.Push(sc.MustMatchString(SectorPlanes)); sc.MustGetFloat(); CompatParams.Push(int(sc.Float*65536.)); } @@ -319,6 +330,26 @@ void ParseCompatibility() sc.MustGetFloat(); CompatParams.Push(int(sc.Float*65536.)); } + else if (sc.Compare("setwalltexture")) + { + if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_SETWALLTEXTURE); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + sc.MustGetString(); + CompatParams.Push(sc.MustMatchString(LineSides)); + sc.MustGetString(); + CompatParams.Push(sc.MustMatchString(WallTiers)); + sc.MustGetString(); + const FString texName = sc.String; + const unsigned int texIndex = TexNames.Find(texName); + const unsigned int texCount = TexNames.Size(); + if (texIndex == texCount) + { + TexNames.Push(texName); + } + CompatParams.Push(texIndex); + } else if (sc.Compare("setthingz")) { if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); @@ -358,6 +389,15 @@ void ParseCompatibility() CompatParams.Push(int(sc.Float * 256)); // do not use full fixed here so that it can eventually handle larger levels flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES; } + else if (sc.Compare("setthingskills")) + { + if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_SETTHINGSKILLS); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + } else { sc.UnGet(); @@ -542,16 +582,19 @@ void SetCompatibilityParams() i += 3; break; } - case CP_SECTORFLOOROFFSET: + case CP_SETSECTOROFFSET: { if ((unsigned)CompatParams[i+1] < level.sectors.Size()) { sector_t *sec = &level.sectors[CompatParams[i+1]]; - const double delta = CompatParams[i + 2] / 65536.0; - sec->floorplane.ChangeHeight(delta); - sec->ChangePlaneTexZ(sector_t::floor, delta); + const double delta = CompatParams[i + 3] / 65536.0; + secplane_t& plane = sector_t::floor == CompatParams[i + 2] + ? sec->floorplane + : sec->ceilingplane; + plane.ChangeHeight(delta); + sec->ChangePlaneTexZ(CompatParams[i + 2], delta); } - i += 3; + i += 4; break; } case CP_SETSECTORSPECIAL: @@ -577,6 +620,21 @@ void SetCompatibilityParams() i += 5; break; } + case CP_SETWALLTEXTURE: + { + if ((unsigned)CompatParams[i + 1] < level.lines.Size()) + { + side_t *side = level.lines[CompatParams[i + 1]].sidedef[CompatParams[i + 2]]; + if (side != NULL) + { + assert(TexNames.Size() > (unsigned int)CompatParams[i + 4]); + const FTextureID texID = TexMan.GetTexture(TexNames[CompatParams[i + 4]], FTexture::TEX_Any); + side->SetTexture(CompatParams[i + 3], texID); + } + } + i += 5; + break; + } case CP_SETTHINGZ: { // When this is called, the things haven't been spawned yet so we can alter the position inside the MapThings array. @@ -623,6 +681,15 @@ void SetCompatibilityParams() i += 4; break; } + case CP_SETTHINGSKILLS: + { + if ((unsigned)CompatParams[i + 1] < MapThingsConverted.Size()) + { + MapThingsConverted[CompatParams[i + 1]].SkillFilter = CompatParams[i + 2]; + } + i += 3; + break; + } } } } diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index ca153980d..44d3b6d8b 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -71,6 +71,10 @@ #include "swrenderer/scene/r_light.h" +#ifndef NO_SSE +#include +#endif + CVAR(Int, gl_showpacks, 0, 0) #ifndef WIN32 // Defined in fb_d3d9 for Windows CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -2383,6 +2387,41 @@ bool OpenGLSWFrameBuffer::OpenGLPal::Update() // See explanation in UploadPalette() for skipat rationale. skipat = MIN(numEntries, DoColorSkip ? 256 - 8 : 256); +#ifndef NO_SSE + // Manual SSE vectorized version here to workaround a bug in GCC's auto-vectorizer + + int sse_count = skipat / 4 * 4; + for (i = 0; i < sse_count; i += 4) + { + _mm_storeu_si128((__m128i*)(&buff[i]), _mm_loadu_si128((__m128i*)(&pal[i]))); + } + switch (skipat - i) + { + // fall through is intentional + case 3: buff[i] = pal[i].d; i++; + case 2: buff[i] = pal[i].d; i++; + case 1: buff[i] = pal[i].d; i++; + default: i++; + } + sse_count = numEntries / 4 * 4; + __m128i alphamask = _mm_set1_epi32(0xff000000); + while (i < sse_count) + { + __m128i lastcolor = _mm_loadu_si128((__m128i*)(&pal[i - 1])); + __m128i color = _mm_loadu_si128((__m128i*)(&pal[i])); + _mm_storeu_si128((__m128i*)(&buff[i]), _mm_or_si128(_mm_and_si128(alphamask, color), _mm_andnot_si128(alphamask, lastcolor))); + i += 4; + } + switch (numEntries - i) + { + // fall through is intentional + case 3: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; + case 2: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; + case 1: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; + default: break; + } + +#else for (i = 0; i < skipat; ++i) { buff[i] = ColorARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b); @@ -2391,6 +2430,7 @@ bool OpenGLSWFrameBuffer::OpenGLPal::Update() { buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); } +#endif if (numEntries > 1) { i = numEntries - 1; @@ -2544,7 +2584,7 @@ void OpenGLSWFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, in } if (In2D < 2) { - Super::Dim(color, amount, x1, y1, w, h); + Super::DoDim(color, amount, x1, y1, w, h); return; } if (!InScene) diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 81d9cfe0a..25cf6b8f8 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -69,6 +69,7 @@ PClass *DefaultListMenuClass; PClass *DefaultOptionMenuClass; void I_BuildALDeviceList(FOptionValues *opt); +void I_BuildALResamplersList(FOptionValues *opt); DEFINE_GLOBAL_NAMED(OptionSettings, OptionMenuSettings) @@ -1433,6 +1434,11 @@ void M_CreateMenus() { I_BuildALDeviceList(*opt); } + opt = OptionValues.CheckKey(NAME_Alresamplers); + if (opt != nullptr) + { + I_BuildALResamplersList(*opt); + } } //============================================================================= diff --git a/src/namedef.h b/src/namedef.h index ad29da9ba..f4f9a22c8 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -713,6 +713,7 @@ xx(Crosshairs) xx(Colorpickermenu) xx(Mididevices) xx(Aldevices) +xx(Alresamplers) xx(CustomizeControls) xx(MessageOptions) xx(AutomapOptions) diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 5d2ad6cab..ce9e78456 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -82,15 +82,16 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan double frontfloorz1 = frontsector->floorplane.ZatPoint(line->v1); double frontceilz2 = frontsector->ceilingplane.ZatPoint(line->v2); double frontfloorz2 = frontsector->floorplane.ZatPoint(line->v2); + double topTexZ = frontsector->GetPlaneTexZ(sector_t::ceiling); + double bottomTexZ = frontsector->GetPlaneTexZ(sector_t::floor); if (line->backsector == nullptr) { if (line->sidedef) { wall.SetCoords(line->v1->fPos(), line->v2->fPos(), frontceilz1, frontfloorz1, frontceilz2, frontfloorz2); - wall.TopZ = frontceilz1; - wall.BottomZ = frontfloorz1; - wall.UnpeggedCeil = frontceilz1; + wall.TopTexZ = topTexZ; + wall.BottomTexZ = bottomTexZ; wall.Texpart = side_t::mid; wall.Polyportal = polyportal; wall.Render(worldToClip, clipPlane, cull); @@ -125,9 +126,8 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan if ((topceilz1 > topfloorz1 || topceilz2 > topfloorz2) && line->sidedef && !bothSkyCeiling) { wall.SetCoords(line->v1->fPos(), line->v2->fPos(), topceilz1, topfloorz1, topceilz2, topfloorz2); - wall.TopZ = topceilz1; - wall.BottomZ = topfloorz1; - wall.UnpeggedCeil = topceilz1; + wall.TopTexZ = topTexZ; + wall.BottomTexZ = MIN(topfloorz1, topfloorz2); wall.Texpart = side_t::top; wall.Render(worldToClip, clipPlane, cull); } @@ -135,9 +135,10 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef && !bothSkyFloor) { wall.SetCoords(line->v1->fPos(), line->v2->fPos(), bottomceilz1, bottomfloorz1, bottomceilz2, bottomfloorz2); - wall.TopZ = bottomceilz1; - wall.BottomZ = bottomfloorz2; - wall.UnpeggedCeil = topceilz1; + wall.TopTexZ = MAX(bottomceilz1, bottomceilz2); + wall.BottomTexZ = bottomTexZ; + wall.UnpeggedCeil1 = topceilz1; + wall.UnpeggedCeil2 = topceilz2; wall.Texpart = side_t::bottom; wall.Render(worldToClip, clipPlane, cull); } @@ -145,9 +146,8 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan if (line->sidedef) { wall.SetCoords(line->v1->fPos(), line->v2->fPos(), middleceilz1, middlefloorz1, middleceilz2, middlefloorz2); - wall.TopZ = middleceilz1; - wall.BottomZ = middlefloorz1; - wall.UnpeggedCeil = topceilz1; + wall.TopTexZ = MAX(middleceilz1, middleceilz2); + wall.BottomTexZ = MIN(middlefloorz1, middlefloorz2); wall.Texpart = side_t::mid; wall.Masked = true; @@ -171,6 +171,8 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyC double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1); double frontceilz2 = fakeFloor->top.plane->ZatPoint(line->v2); double frontfloorz2 = fakeFloor->bottom.plane->ZatPoint(line->v2); + double topTexZ = frontsector->GetPlaneTexZ(sector_t::ceiling); + double bottomTexZ = frontsector->GetPlaneTexZ(sector_t::floor); RenderPolyWall wall; wall.LineSeg = line; @@ -181,9 +183,10 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyC wall.SubsectorDepth = subsectorDepth; wall.StencilValue = stencilValue; wall.SetCoords(line->v1->fPos(), line->v2->fPos(), frontceilz1, frontfloorz1, frontceilz2, frontfloorz2); - wall.TopZ = frontceilz1; - wall.BottomZ = frontfloorz1; - wall.UnpeggedCeil = frontceilz1; + wall.TopTexZ = topTexZ; + wall.BottomTexZ = bottomTexZ; + wall.UnpeggedCeil1 = frontceilz1; + wall.UnpeggedCeil2 = frontceilz2; wall.Texpart = side_t::mid; wall.Render(worldToClip, clipPlane, cull); } @@ -229,15 +232,17 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c if (tex) { - PolyWallTextureCoords texcoords(tex, LineSeg, Line, Side, Texpart, TopZ, BottomZ, UnpeggedCeil); - vertices[0].u = (float)texcoords.u1; - vertices[0].v = (float)texcoords.v1; - vertices[1].u = (float)texcoords.u2; - vertices[1].v = (float)texcoords.v1; - vertices[2].u = (float)texcoords.u2; - vertices[2].v = (float)texcoords.v2; - vertices[3].u = (float)texcoords.u1; - vertices[3].v = (float)texcoords.v2; + PolyWallTextureCoordsU texcoordsU(tex, LineSeg, Line, Side, Texpart); + PolyWallTextureCoordsV texcoordsVLeft(tex, Line, Side, Texpart, ceil1, floor1, UnpeggedCeil1, TopTexZ, BottomTexZ); + PolyWallTextureCoordsV texcoordsVRght(tex, Line, Side, Texpart, ceil2, floor2, UnpeggedCeil2, TopTexZ, BottomTexZ); + vertices[0].u = (float)texcoordsU.u1; + vertices[0].v = (float)texcoordsVLeft.v1; + vertices[1].u = (float)texcoordsU.u2; + vertices[1].v = (float)texcoordsVRght.v1; + vertices[2].u = (float)texcoordsU.u2; + vertices[2].v = (float)texcoordsVRght.v2; + vertices[3].u = (float)texcoordsU.u1; + vertices[3].v = (float)texcoordsVLeft.v2; } // Masked walls clamp to the 0-1 range (no texture repeat) @@ -356,13 +361,7 @@ int RenderPolyWall::GetLightLevel() ///////////////////////////////////////////////////////////////////////////// -PolyWallTextureCoords::PolyWallTextureCoords(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil) -{ - CalcU(tex, lineseg, line, side, texpart); - CalcV(tex, line, side, texpart, topz, bottomz, unpeggedceil); -} - -void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart) +PolyWallTextureCoordsU::PolyWallTextureCoordsU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart) { double lineLength = side->TexelLength; double lineStart = 0.0; @@ -384,7 +383,9 @@ void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *lineseg, const lin u2 /= texWidth; } -void PolyWallTextureCoords::CalcV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil) +///////////////////////////////////////////////////////////////////////////// + +PolyWallTextureCoordsV::PolyWallTextureCoordsV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ) { double vscale = side->GetTextureYScale(texpart) * tex->Scale.Y; @@ -396,22 +397,33 @@ void PolyWallTextureCoords::CalcV(FTexture *tex, const line_t *line, const side_ { default: case side_t::mid: - CalcVMidPart(tex, line, side, topz, bottomz, vscale, yoffset); + CalcVMidPart(tex, line, side, topTexZ, bottomTexZ, vscale, yoffset); break; case side_t::top: - CalcVTopPart(tex, line, side, topz, bottomz, vscale, yoffset); + CalcVTopPart(tex, line, side, topTexZ, bottomTexZ, vscale, yoffset); break; case side_t::bottom: - CalcVBottomPart(tex, line, side, topz, bottomz, unpeggedceil, vscale, yoffset); + CalcVBottomPart(tex, line, side, topTexZ, bottomTexZ, unpeggedceil, vscale, yoffset); break; } int texHeight = tex->GetHeight(); v1 /= texHeight; v2 /= texHeight; + + double texZHeight = (bottomTexZ - topTexZ); + if (texZHeight > 0.0f || texZHeight < -0.0f) + { + double t1 = (topz - topTexZ) / texZHeight; + double t2 = (bottomz - topTexZ) / texZHeight; + double vorig1 = v1; + double vorig2 = v2; + v1 = vorig1 * (1.0f - t1) + vorig2 * t1; + v2 = vorig1 * (1.0f - t2) + vorig2 * t2; + } } -void PolyWallTextureCoords::CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset) +void PolyWallTextureCoordsV::CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset) { bool pegged = (line->flags & ML_DONTPEGTOP) == 0; if (pegged) // bottom to top @@ -434,7 +446,7 @@ void PolyWallTextureCoords::CalcVTopPart(FTexture *tex, const line_t *line, cons } } -void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset) +void PolyWallTextureCoordsV::CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset) { bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0; if (pegged) // top to bottom @@ -450,7 +462,7 @@ void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const line_t *line, cons } } -void PolyWallTextureCoords::CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset) +void PolyWallTextureCoordsV::CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset) { bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0; if (pegged) // top to bottom diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index dda2cdc2a..8a38447c8 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -48,9 +48,10 @@ public: const line_t *Line = nullptr; const side_t *Side = nullptr; side_t::ETexpart Texpart = side_t::mid; - double TopZ = 0.0; - double BottomZ = 0.0; - double UnpeggedCeil = 0.0; + double TopTexZ = 0.0; + double BottomTexZ = 0.0; + double UnpeggedCeil1 = 0.0; + double UnpeggedCeil2 = 0.0; FSWColormap *Colormap = nullptr; bool Masked = false; uint32_t SubsectorDepth = 0; @@ -63,18 +64,22 @@ private: int GetLightLevel(); }; -// Texture coordinates for a wall -class PolyWallTextureCoords +class PolyWallTextureCoordsU { public: - PolyWallTextureCoords(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil); + PolyWallTextureCoordsU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart); double u1, u2; +}; + +class PolyWallTextureCoordsV +{ +public: + PolyWallTextureCoordsV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ); + double v1, v2; private: - void CalcU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart); - void CalcV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil); void CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset); void CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset); void CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset); diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 1354bb679..203ea8955 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -65,6 +65,7 @@ FModule OpenALModule{"OpenAL"}; CVAR (String, snd_aldevice, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, snd_efx, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (String, snd_alresampler, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) #ifdef _WIN32 #define OPENALLIB "openal32.dll" @@ -121,6 +122,32 @@ void I_BuildALDeviceList(FOptionValues *opt) #endif } +void I_BuildALResamplersList(FOptionValues *opt) +{ + opt->mValues.Resize(1); + opt->mValues[0].TextValue = "Default"; + opt->mValues[0].Text = "Default"; + +#ifndef NO_OPENAL + if (!IsOpenALPresent()) + return; + if (!alcGetCurrentContext() || !alIsExtensionPresent("AL_SOFT_source_resampler")) + return; + + LPALGETSTRINGISOFT alGetStringiSOFT = reinterpret_cast(alGetProcAddress("alGetStringiSOFT")); + ALint num_resamplers = alGetInteger(AL_NUM_RESAMPLERS_SOFT); + + unsigned int idx = opt->mValues.Reserve(num_resamplers); + for(ALint i = 0;i < num_resamplers;++i) + { + const ALchar *name = alGetStringiSOFT(AL_RESAMPLER_NAME_SOFT, i); + opt->mValues[idx].TextValue = name; + opt->mValues[idx].Text = name; + ++idx; + } +#endif +} + ReverbContainer *ForcedEnvironment; @@ -788,6 +815,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() AL.EXT_SOURCE_RADIUS = !!alIsExtensionPresent("AL_EXT_SOURCE_RADIUS"); AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates"); AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points"); + AL.SOFT_source_resampler = !!alIsExtensionPresent("AL_SOFT_source_resampler"); alDopplerFactor(0.5f); alSpeedOfSound(343.3f * 96.0f); @@ -806,6 +834,9 @@ OpenALSoundRenderer::OpenALSoundRenderer() alProcessUpdatesSOFT = _wrap_ProcessUpdatesSOFT; } + if(AL.SOFT_source_resampler) + LOAD_FUNC(alGetStringiSOFT); + if(ALC.SOFT_pause_device) { LOAD_DEV_FUNC(Device, alcDevicePauseSOFT); @@ -958,6 +989,26 @@ OpenALSoundRenderer::OpenALSoundRenderer() if(EnvSlot) Printf(" EFX enabled\n"); + + if(AL.SOFT_source_resampler && strcmp(*snd_alresampler, "Default") != 0) + { + const ALint num_resamplers = alGetInteger(AL_NUM_RESAMPLERS_SOFT); + ALint ridx = alGetInteger(AL_DEFAULT_RESAMPLER_SOFT); + ALint i; + + for(i = 0;i < num_resamplers;i++) + { + if(strcmp(alGetStringiSOFT(AL_RESAMPLER_NAME_SOFT, i), *snd_alresampler) == 0) + { + ridx = i; + break; + } + } + if(i == num_resamplers) + Printf(TEXTCOLOR_RED" Failed to find resampler " TEXTCOLOR_ORANGE"%s\n", *snd_alresampler); + else for(ALint src : Sources) + alSourcei(src, AL_SOURCE_RESAMPLER_SOFT, ridx); + } } #undef LOAD_DEV_FUNC #undef LOAD_FUNC diff --git a/src/sound/oalsound.h b/src/sound/oalsound.h index 4a69028dc..6c79707bf 100644 --- a/src/sound/oalsound.h +++ b/src/sound/oalsound.h @@ -97,6 +97,17 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi #define AL_SOURCE_RADIUS 0x1031 #endif +#ifndef AL_SOFT_source_resampler +#define AL_SOFT_source_resampler 1 +#define AL_NUM_RESAMPLERS_SOFT 0x1210 +#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 +#define AL_SOURCE_RESAMPLER_SOFT 0x1212 +#define AL_RESAMPLER_NAME_SOFT 0x1213 +typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); +#ifdef AL_ALEXT_PROTOTYPES +AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); +#endif +#endif class OpenALSoundStream; @@ -172,6 +183,7 @@ private: bool EXT_SOURCE_RADIUS; bool SOFT_deferred_updates; bool SOFT_loop_points; + bool SOFT_source_resampler; } AL; // EFX Extension function pointer variables. Loaded after context creation @@ -217,6 +229,8 @@ private: ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void); ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void); + LPALGETSTRINGISOFT alGetStringiSOFT; + void (ALC_APIENTRY*alcDevicePauseSOFT)(ALCdevice *device); void (ALC_APIENTRY*alcDeviceResumeSOFT)(ALCdevice *device); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 188d2530e..0ee7a585a 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -2671,7 +2671,7 @@ void D3DFB::DoDim (PalEntry color, float amount, int x1, int y1, int w, int h) } if (In2D < 2) { - Super::Dim(color, amount, x1, y1, w, h); + Super::DoDim(color, amount, x1, y1, w, h); return; } if (!InScene) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 93807661e..e11ba449b 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -2,25 +2,25 @@ { // Slightly squash the pillars in the starting room with "stimpacks" // floating on them so that they can be obtained. - sectorflooroffset 62 -8 + setsectoroffset 62 floor -8 setwallyscale 286 front bot 1.090909 setwallyscale 287 front bot 1.090909 setwallyscale 288 front bot 1.090909 setwallyscale 289 front bot 1.090909 - sectorflooroffset 63 -8 + setsectoroffset 63 floor -8 setwallyscale 290 front bot 1.090909 setwallyscale 291 front bot 1.090909 setwallyscale 292 front bot 1.090909 setwallyscale 293 front bot 1.090909 - sectorflooroffset 118 -8 + setsectoroffset 118 floor -8 setwallyscale 710 front bot 1.090909 setwallyscale 711 front bot 1.090909 setwallyscale 712 front bot 1.090909 setwallyscale 713 front bot 1.090909 - sectorflooroffset 119 -8 + setsectoroffset 119 floor -8 setwallyscale 714 front bot 1.090909 setwallyscale 715 front bot 1.090909 setwallyscale 716 front bot 1.090909 @@ -566,3 +566,63 @@ DC96228097DD004C40CCB1DB14A91EAA // unloved.pk3:unlovedmaps.wad map05 clipmidtex } + +// Cosmetic fixes for Heretic: Shadow of the Serpent Riders +D94587625BA779644D58151A87897CF1 // e1m2 +{ + // Missing textures + setwalltexture 477 back top MOSSRCK1 + setwalltexture 478 back top MOSSRCK1 + setwalltexture 479 back top MOSSRCK1 + setwalltexture 1057 front top MOSSRCK1 +} +ADD0FAC41AFB0B3C9B9F3C0006F93805 // e1m3 +{ + // Broken door between the hallway that leads to a Torch + // and the passage that has a Bag of Holding at its end + setsectoroffset 86 floor -128 + setsectoroffset 86 ceil -128 +} +916318D8B06DAC2D83424B23E4B66531 // e1m4 +{ + // Wrong sector offsets + setsectoroffset 0 ceil 8 + setsectoroffset 1 ceil 8 + setsectoroffset 2 ceil 8 + setsectoroffset 3 ceil 8 + setsectoroffset 4 ceil 8 + setsectoroffset 6 ceil 8 + setsectoroffset 6 floor 8 + setsectoroffset 17 ceil 8 + // Yellow key door + setsectoroffset 284 floor -8 + setsectoroffset 284 ceil -8 + // Missing textures + setwalltexture 490 back bot GRSTNPB + setwalltexture 722 front bot WOODWL + setwalltexture 911 front bot WOODWL + setwalltexture 1296 front bot WOODWL +} +397A0E17A39542E4E8294E156FAB0502 // e2m2 +{ + // Missing green door statues on easy and hard difficulties + setthingskills 17 31 + setthingskills 18 31 +} +CA3773ED313E8899311F3DD0CA195A68 // e3m6 +{ + // Quartz flask outside of map + setthingskills 373 0 + // Missing wall torch on hard difficulty + setthingskills 448 31 + // Missing textures + setwalltexture 343 front top MOSSRCK1 + setwalltexture 370 front top MOSSRCK1 +} +5E3FCFDE78310BB89F92B1626A47D0AD // heretic.wad E4M7 +{ + // Missing textures + setwalltexture 1274 front top CSTLRCK + setwalltexture 1277 back top CSTLRCK + setwalltexture 1278 front top CSTLRCK +} diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 62d2805db..7b52d019b 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2137,6 +2137,7 @@ SNDMNU_MODREPLAYER = "Module replayer options"; OPENALMNU_TITLE = "OPENAL OPTIONS"; OPENALMNU_PLAYBACKDEVICE = "Playback device"; OPENALMNU_ENABLEEFX = "Enable EFX"; +OPENALMNU_RESAMPLER = "Resampler"; // Advanced Sound Options ADVSNDMNU_TITLE = "ADVANCED SOUND OPTIONS"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index fb2074862..fe7743148 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1531,6 +1531,11 @@ OptionString ALDevices // filled in by the sound code } +OptionString ALResamplers +{ + // filled in by the sound code +} + OptionString OutputFormats { "PCM-8", "$OPTSTR_PCM8BIT" @@ -1572,8 +1577,9 @@ OptionString SoundBackendsOpenALOnly OptionMenu OpenALSoundItems { Title "$OPENALMNU_TITLE" - Option "$OPENALMNU_PLAYBACKDEVICE", "snd_aldevice", "ALDevices" - Option "$OPENALMNU_ENABLEEFX", "snd_efx", "OnOff" + Option "$OPENALMNU_PLAYBACKDEVICE", "snd_aldevice", "ALDevices" + Option "$OPENALMNU_ENABLEEFX", "snd_efx", "OnOff" + Option "$OPENALMNU_RESAMPLER", "snd_alresampler", "ALResamplers" } diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 380ffd2d8..b799f98c2 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -812,9 +812,13 @@ class PlayerPawn : Actor native side *= SideMove2; } - if (!player.morphTics && Inv != NULL) + if (!player.morphTics) { - double factor = Inv.GetSpeedFactor (); + double factor = 1.; + for(let it = Inv; it != null; it = it.Inv) + { + factor *= Inv.GetSpeedFactor (); + } forward *= factor; side *= factor; } diff --git a/wadsrc/static/zscript/statscreen/statscreen_sp.txt b/wadsrc/static/zscript/statscreen/statscreen_sp.txt index c0af25990..f4def3569 100644 --- a/wadsrc/static/zscript/statscreen/statscreen_sp.txt +++ b/wadsrc/static/zscript/statscreen/statscreen_sp.txt @@ -28,7 +28,7 @@ class DoomStatusScreen : StatusScreen cnt_items[0] = Plrs[me].sitems; cnt_secret[0] = Plrs[me].ssecret; cnt_time = Thinker.Tics2Seconds(Plrs[me].stime); - cnt_par = Thinker.Tics2Seconds(wbs.partime); + cnt_par = wbs.partime / Thinker.TICRATE; cnt_total_time = Thinker.Tics2Seconds(wbs.totaltime); } @@ -100,7 +100,7 @@ class DoomStatusScreen : StatusScreen if (!intermissioncounter || cnt_total_time >= tsec) cnt_total_time = tsec; - int psec = Thinker.Tics2Seconds(wbs.partime); + int psec = wbs.partime / Thinker.TICRATE; if (!intermissioncounter || cnt_par >= psec) { cnt_par = psec; @@ -156,7 +156,7 @@ class DoomStatusScreen : StatusScreen if (wbs.partime) { - screen.DrawTexture (Par, 160 + SP_TIMEX, SP_TIMEY, DTA_Clean, true); + screen.DrawTexture (Par, true, 160 + SP_TIMEX, SP_TIMEY, DTA_Clean, true); drawTime (320 - SP_TIMEX, SP_TIMEY, cnt_par); } }