From c76431414a967731c5f951efc9f2cfbe52c49304 Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Fri, 21 Oct 2016 06:54:45 -0400 Subject: [PATCH 01/17] - Implemented r_fullbrightignoresectorcolor from QZDoom --- src/r_bsp.cpp | 5 +++-- src/r_data/colormaps.cpp | 4 ++++ src/r_data/colormaps.h | 1 + src/r_main.cpp | 7 +++++++ src/r_segs.cpp | 11 ++++++----- src/r_things.cpp | 21 ++++++++++++++------- wadsrc/static/language.enu | 1 + wadsrc/static/menudef.txt | 1 + 8 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 934d2d3e5..8d423b3b3 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -105,6 +105,7 @@ TArray WallPortals(1000); // note: this array needs to go away as subsector_t *InSubsector; CVAR (Bool, r_drawflat, false, 0) // [RH] Don't texture segs? +EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); void R_StoreWallRange (int start, int stop); @@ -1108,7 +1109,7 @@ void R_Subsector (subsector_t *sub) } else { - basecolormap = frontsector->ColorMap; + basecolormap = (r_fullbrightignoresectorcolor && fixedlightlev >= 0) ? &FullNormalLight : frontsector->ColorMap; } portal = frontsector->ValidatePortal(sector_t::ceiling); @@ -1142,7 +1143,7 @@ void R_Subsector (subsector_t *sub) } else { - basecolormap = frontsector->ColorMap; + basecolormap = (r_fullbrightignoresectorcolor && fixedlightlev >= 0) ? &FullNormalLight : frontsector->ColorMap; } // killough 3/7/98: Add (x,y) offsets to flats, add deep water check diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index b46342463..73265b20e 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -59,6 +59,7 @@ static bool R_CheckForFixedLights(const BYTE *colormaps); extern "C" { FDynamicColormap NormalLight; +FDynamicColormap FullNormalLight; //[SP] Emulate GZDoom brightness } bool NormalLightHasFixedLights; @@ -551,6 +552,9 @@ void R_InitColormaps () NormalLight.Color = PalEntry (255, 255, 255); NormalLight.Fade = 0; NormalLight.Maps = realcolormaps; + FullNormalLight.Color = PalEntry (255, 255, 255); + FullNormalLight.Fade = 0; + FullNormalLight.Maps = realcolormaps; NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps); numfakecmaps = fakecmaps.Size(); diff --git a/src/r_data/colormaps.h b/src/r_data/colormaps.h index 0764191a3..09006fc1e 100644 --- a/src/r_data/colormaps.h +++ b/src/r_data/colormaps.h @@ -80,6 +80,7 @@ extern BYTE DesaturateColormap[31][256]; extern "C" { extern FDynamicColormap NormalLight; +extern FDynamicColormap FullNormalLight; } extern bool NormalLightHasFixedLights; diff --git a/src/r_main.cpp b/src/r_main.cpp index 1e0de7ecc..6f0ebcb3c 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -455,6 +455,8 @@ void R_CopyStackedViewParameters() // //========================================================================== +EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) + void R_SetupColormap(player_t *player) { realfixedcolormap = NULL; @@ -481,6 +483,11 @@ void R_SetupColormap(player_t *player) else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) { fixedlightlev = player->fixedlightlevel * 256; + // [SP] Emulate GZDoom's light-amp goggles. + if (r_fullbrightignoresectorcolor && fixedlightlev >= 0) + { + fixedcolormap = &FullNormalLight; + } } } // [RH] Inverse light for shooting the Sigil diff --git a/src/r_segs.cpp b/src/r_segs.cpp index edb1949b6..d265d626f 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -57,6 +57,7 @@ CVAR(Bool, r_np2, true, 0) +EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); //CVAR (Int, ty, 8, 0) //CVAR (Int, tx, 8, 0) @@ -313,7 +314,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) rw_scalestep = ds->iscalestep; if (fixedlightlev >= 0) - dc_colormap = basecolormap->Maps + fixedlightlev; + dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -630,7 +631,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) } if (fixedlightlev >= 0) - dc_colormap = basecolormap->Maps + fixedlightlev; + dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -1788,7 +1789,7 @@ void R_RenderSegLoop () fixed_t xoffset = rw_offset; if (fixedlightlev >= 0) - dc_colormap = basecolormap->Maps + fixedlightlev; + dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -3187,11 +3188,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep; if (fixedlightlev >= 0) - dc_colormap = usecolormap->Maps + fixedlightlev; + dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (usecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT)) - dc_colormap = usecolormap->Maps; + dc_colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : usecolormap->Maps; else calclighting = true; diff --git a/src/r_things.cpp b/src/r_things.cpp index 99ca68b60..047ee9295 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -99,6 +99,7 @@ EXTERN_CVAR (Bool, st_scale) EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Int, r_drawfuzz) EXTERN_CVAR(Bool, r_deathcamera); +CVAR(Bool, r_fullbrightignoresectorcolor, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); // // Sprite rotation 0 is facing the viewer, @@ -548,7 +549,7 @@ void R_DrawWallSprite(vissprite_t *spr) else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) - dc_colormap = usecolormap->Maps; + dc_colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : usecolormap->Maps; else calclighting = true; @@ -1066,7 +1067,8 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->deltax = float(pos.X - ViewPos.X); vis->deltay = float(pos.Y - ViewPos.Y); vis->renderflags = renderflags; - if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D + if(thing->flags5 & MF5_BRIGHT) + vis->renderflags |= RF_FULLBRIGHT; // kg3D vis->Style.RenderStyle = thing->RenderStyle; vis->FillColor = thing->fillcolor; vis->Translation = thing->Translation; // [RH] thing translation table @@ -1140,7 +1142,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) { // full bright - vis->Style.colormap = mybasecolormap->Maps; + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; } else { // diminished light @@ -1462,11 +1464,11 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double } if (fixedlightlev >= 0) { - vis->Style.colormap = mybasecolormap->Maps + fixedlightlev; + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (mybasecolormap->Maps + fixedlightlev); } else if (!foggy && pspr->GetState()->GetFullbright()) { // full bright - vis->Style.colormap = mybasecolormap->Maps; // [RH] use basecolormap + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; // [RH] use basecolormap } else { // local light @@ -1516,6 +1518,11 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double { noaccel = true; } + // [SP] If emulating GZDoom fullbright, disable acceleration + if (r_fullbrightignoresectorcolor && fixedlightlev >= 0) + mybasecolormap = &FullNormalLight; + if (r_fullbrightignoresectorcolor && !foggy && pspr->GetState()->GetFullbright()) + mybasecolormap = &FullNormalLight; colormap_to_use = mybasecolormap; } else @@ -2057,7 +2064,7 @@ void R_DrawSprite (vissprite_t *spr) } else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) { // full bright - spr->Style.colormap = mybasecolormap->Maps; + spr->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; } else { // diminished light @@ -2615,7 +2622,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, } else if (particle->bright) { - vis->Style.colormap = map; + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : map; } else { diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 096d0832c..18ff6ce04 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1787,6 +1787,7 @@ DSPLYMNU_PICKUPFADE = "Pickup Flash Intensity"; DSPLYMNU_PALLETEHACK = "DirectDraw palette hack"; // Not used DSPLYMNU_ATTACHEDSURFACES = "Use attached surfaces"; // Not used DSPLYMNU_SKYMODE = "Sky render mode"; +DSPLYMNU_GZDFULLBRIGHT = "Emulate GZDoom FullBright"; DSPLYMNU_DRAWFUZZ = "Use fuzz effect"; DSPLYMNU_TRANSSOUL = "Lost Soul translucency"; DSPLYMNU_FAKECONTRAST = "Use fake contrast"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 7b06a7e7f..765fe6674 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -682,6 +682,7 @@ OptionMenu "VideoOptions" } Option "$DSPLYMNU_SKYMODE", "r_skymode", "SkyModes" + Option "$DSPLYMNU_GZDFULLBRIGHT", "r_fullbrightignoresectorcolor", "OnOff" Option "$DSPLYMNU_DRAWFUZZ", "r_drawfuzz", "Fuzziness" Slider "$DSPLYMNU_TRANSSOUL", "transsouls", 0.25, 1.0, 0.05, 2 Option "$DSPLYMNU_FAKECONTRAST", "r_fakecontrast", "Contrast" From df6214b142cb61dda7604da4c3bf97543248d1af Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Fri, 21 Oct 2016 07:21:56 -0400 Subject: [PATCH 02/17] - Fixes --- src/r_main.cpp | 2 +- src/r_segs.cpp | 10 +++++----- src/r_things.cpp | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index 6f0ebcb3c..4252f4155 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -486,7 +486,7 @@ void R_SetupColormap(player_t *player) // [SP] Emulate GZDoom's light-amp goggles. if (r_fullbrightignoresectorcolor && fixedlightlev >= 0) { - fixedcolormap = &FullNormalLight; + fixedcolormap = FullNormalLight.Maps; } } } diff --git a/src/r_segs.cpp b/src/r_segs.cpp index d265d626f..d1ec04f6d 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -314,7 +314,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) rw_scalestep = ds->iscalestep; if (fixedlightlev >= 0) - dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); + dc_colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -631,7 +631,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) } if (fixedlightlev >= 0) - dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); + dc_colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -1789,7 +1789,7 @@ void R_RenderSegLoop () fixed_t xoffset = rw_offset; if (fixedlightlev >= 0) - dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); + dc_colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (basecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; @@ -3188,11 +3188,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep; if (fixedlightlev >= 0) - dc_colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (usecolormap->Maps + fixedlightlev); + dc_colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (usecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT)) - dc_colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : usecolormap->Maps; + dc_colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : usecolormap->Maps; else calclighting = true; diff --git a/src/r_things.cpp b/src/r_things.cpp index 047ee9295..a88624443 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -549,7 +549,7 @@ void R_DrawWallSprite(vissprite_t *spr) else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) - dc_colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : usecolormap->Maps; + dc_colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : usecolormap->Maps; else calclighting = true; @@ -1142,7 +1142,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) { // full bright - vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps; } else { // diminished light @@ -1464,11 +1464,11 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double } if (fixedlightlev >= 0) { - vis->Style.colormap = (r_fullbrightignoresectorcolor) ? (&FullNormalLight->Maps + fixedlightlev) : (mybasecolormap->Maps + fixedlightlev); + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (mybasecolormap->Maps + fixedlightlev); } else if (!foggy && pspr->GetState()->GetFullbright()) { // full bright - vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; // [RH] use basecolormap + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps; // [RH] use basecolormap } else { // local light @@ -2064,7 +2064,7 @@ void R_DrawSprite (vissprite_t *spr) } else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) { // full bright - spr->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : mybasecolormap->Maps; + spr->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps; } else { // diminished light @@ -2622,7 +2622,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, } else if (particle->bright) { - vis->Style.colormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight->Maps : map; + vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : map; } else { From 8678baf6f589a68635939a1063a28231a0aa01a1 Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Fri, 21 Oct 2016 07:32:18 -0400 Subject: [PATCH 03/17] - Fullbright fixes --- src/r_data/colormaps.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index 73265b20e..2d3c0e49d 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -73,6 +73,7 @@ struct FakeCmap TArray fakecmaps; BYTE *realcolormaps; +BYTE *realfbcolormaps; //[SP] For fullbright use size_t numfakecmaps; @@ -460,6 +461,11 @@ void R_DeinitColormaps () delete[] realcolormaps; realcolormaps = NULL; } + if (realfbcolormaps != NULL) + { + delete[] realfbcolormaps; + realfbcolormaps = NULL; + } FreeSpecialLights(); } @@ -549,12 +555,20 @@ void R_InitColormaps () } } } + + // [SP] Create a copy of the colormap + if (!realfbcolormaps) + { + realfbcolormaps = new BYTE[256*NUMCOLORMAPS*fakecmaps.Size()]; + memcpy(realfbcolormaps, realcolormaps, 256*NUMCOLORMAPS*fakecmaps.Size()); + } + NormalLight.Color = PalEntry (255, 255, 255); NormalLight.Fade = 0; NormalLight.Maps = realcolormaps; FullNormalLight.Color = PalEntry (255, 255, 255); FullNormalLight.Fade = 0; - FullNormalLight.Maps = realcolormaps; + FullNormalLight.Maps = realfbcolormaps; NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps); numfakecmaps = fakecmaps.Size(); From 513f8312b35cc42fd55d73e18ddfae355893c6c8 Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Fri, 21 Oct 2016 08:36:20 -0400 Subject: [PATCH 04/17] - Renamed menu option for r_fullbrightignoresectorcolor --- wadsrc/static/language.enu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 18ff6ce04..01eb692b8 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1787,7 +1787,7 @@ DSPLYMNU_PICKUPFADE = "Pickup Flash Intensity"; DSPLYMNU_PALLETEHACK = "DirectDraw palette hack"; // Not used DSPLYMNU_ATTACHEDSURFACES = "Use attached surfaces"; // Not used DSPLYMNU_SKYMODE = "Sky render mode"; -DSPLYMNU_GZDFULLBRIGHT = "Emulate GZDoom FullBright"; +DSPLYMNU_GZDFULLBRIGHT = "Fullbright overrides sector color"; DSPLYMNU_DRAWFUZZ = "Use fuzz effect"; DSPLYMNU_TRANSSOUL = "Lost Soul translucency"; DSPLYMNU_FAKECONTRAST = "Use fake contrast"; From e0efdd97b378b4a63ebb8c8bc6dce009609e7297 Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Mon, 26 Sep 2016 07:24:37 -0400 Subject: [PATCH 05/17] - Added: PlayerPawn property "Player.ViewBob" which acts as a MoveBob/StillBob multiplier. --- src/d_player.h | 3 +++ src/p_pspr.cpp | 5 +++-- src/p_user.cpp | 8 +++++--- src/thingdef/thingdef_properties.cpp | 20 ++++++++++++++++++++ wadsrc/static/actors/shared/player.txt | 1 + 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index e944d6734..7f57837c7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -168,6 +168,9 @@ public: // [CW] Fades for when you are being damaged. PalEntry DamageFade; + // [SP] ViewBob Multiplier + double ViewBob; + bool UpdateWaterLevel (bool splash); bool ResetAirSupply (bool playgasp = true); diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index e5b076acd..abbd2284e 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -582,8 +582,9 @@ void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) if (curbob != 0) { - float bobx = float(player->bob * Rangex); - float boby = float(player->bob * Rangey); + //[SP] Added in decorate player.viewbob checks + float bobx = float(player->bob * Rangex * (float)player->mo->ViewBob); + float boby = float(player->bob * Rangey * (float)player->mo->ViewBob); switch (bobstyle) { case AWeapon::BobNormal: diff --git a/src/p_user.cpp b/src/p_user.cpp index 0f3b6a516..845cf9a5f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -651,7 +651,8 @@ void APlayerPawn::Serialize(FSerializer &arc) ("fallingscreammaxn", FallingScreamMaxSpeed, def->FallingScreamMaxSpeed) ("userange", UseRange, def->UseRange) ("aircapacity", AirCapacity, def->AirCapacity) - ("viewheight", ViewHeight, def->ViewHeight); + ("viewheight", ViewHeight, def->ViewHeight) + ("viewbob", ViewBob, def->ViewBob); } //=========================================================================== @@ -1844,11 +1845,12 @@ void P_CalcHeight (player_t *player) return; } + //[SP] Added (x*player->mo->ViewBob) to allow DECORATE changes to view bobbing speed. if (still) { if (player->health > 0) { - angle = level.time / (120 * TICRATE / 35.) * 360.; + angle = level.time / (120 * TICRATE / 35.) * 360. * player->mo->ViewBob; bob = player->userinfo.GetStillBob() * angle.Sin(); } else @@ -1858,7 +1860,7 @@ void P_CalcHeight (player_t *player) } else { - angle = level.time / (20 * TICRATE / 35.) * 360.; + angle = level.time / (20 * TICRATE / 35.) * 360. * player->mo->ViewBob; bob = player->bob * angle.Sin() * (player->mo->waterlevel > 1 ? 0.25f : 0.5f); } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 80ee6c22f..6321ebfe9 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -2945,6 +2945,26 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, weaponslot, ISsssssssssssssssssssssssssssss } } +//========================================================================== +// +// [SP] Player.Viewbob +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, viewbob, F, PlayerPawn) +{ + PROP_DOUBLE_PARM(z, 0); + // [SP] Hard limits. This is to prevent terrywads from making players sick. + // Remember - this messes with a user option who probably has it set a + // certain way for a reason. I think a 1.5 limit is pretty generous, but + // it may be safe to increase it. I really need opinions from people who + // could be affected by this. + if (z < 0.0 || z > 1.5) + { + I_Error("ViewBob must be between 0.0 and 1.5."); + } + defaults->ViewBob = z; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/shared/player.txt b/wadsrc/static/actors/shared/player.txt index ac5ceb0a7..08d9a252a 100644 --- a/wadsrc/static/actors/shared/player.txt +++ b/wadsrc/static/actors/shared/player.txt @@ -33,6 +33,7 @@ Actor PlayerPawn : Actor native Player.MugShotMaxHealth 0 Player.FlechetteType "ArtiPoisonBag3" Player.AirCapacity 1 + Player.ViewBob 1 Obituary "$OB_MPDEFAULT" } From 21b690a3c77377e18a3e004d4e556701f93a4ac1 Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Thu, 20 Oct 2016 17:52:32 +0800 Subject: [PATCH 06/17] Fixed: Player.ViewBob should be multiplying the bobbing height in P_CalcHeight, not the velocity of the bobbing. This mimics the act of the user altering their movebob CVar to compensate for non-standard player movement speeds. --- src/p_user.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 845cf9a5f..e48712042 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1845,12 +1845,11 @@ void P_CalcHeight (player_t *player) return; } - //[SP] Added (x*player->mo->ViewBob) to allow DECORATE changes to view bobbing speed. if (still) { if (player->health > 0) { - angle = level.time / (120 * TICRATE / 35.) * 360. * player->mo->ViewBob; + angle = level.time / (120 * TICRATE / 35.) * 360.; bob = player->userinfo.GetStillBob() * angle.Sin(); } else @@ -1860,7 +1859,7 @@ void P_CalcHeight (player_t *player) } else { - angle = level.time / (20 * TICRATE / 35.) * 360. * player->mo->ViewBob; + angle = level.time / (20 * TICRATE / 35.) * 360.; bob = player->bob * angle.Sin() * (player->mo->waterlevel > 1 ? 0.25f : 0.5f); } @@ -1893,7 +1892,7 @@ void P_CalcHeight (player_t *player) { bob = 0; } - player->viewz = player->mo->Z() + player->viewheight + bob; + player->viewz = player->mo->Z() + player->viewheight + (bob * player->mo->ViewBob); // [SP] Allow DECORATE changes to view bobbing speed. if (player->mo->Floorclip && player->playerstate != PST_DEAD && player->mo->Z() <= player->mo->floorz) { From b1289fa783019b9fedb4229be792b5e766d09018 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 21 Oct 2016 18:13:59 +0200 Subject: [PATCH 07/17] - fixed: The serialiter functionfor FDoorAnimation accessed the invalid destination pointer when loading a savegame. --- src/textures/animations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index f46289f07..06c496d9a 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -1002,7 +1002,7 @@ void FTextureManager::UpdateAnimations (DWORD mstime) template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDoorAnimation *&p, FDoorAnimation **def) { - FTextureID tex = p->BaseTexture; + FTextureID tex = p? p->BaseTexture : FNullTextureID(); Serialize(arc, key, tex, def ? &(*def)->BaseTexture : nullptr); if (arc.isReading()) { From 5c596d3797fe5a322485f2b865f02314524b45e1 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 21 Oct 2016 22:08:12 -0500 Subject: [PATCH 08/17] Change VM to increment PC after each instruction rather than before - VC++ generated horribly stupid code for x64 when incrementing pc at the beginning of each instruction by storing hundreds of copies of it for every opcode executed. Incrementing pc at the end avoids this madness. - It is possible I messed something up with this change. Hopefully not. --- src/zscript/vmexec.cpp | 22 +++++++++++----------- src/zscript/vmexec.h | 24 +++++++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index 454f02d03..7ee89329a 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -11,21 +11,21 @@ #if COMPGOTO #define OP(x) x -#define NEXTOP do { unsigned op = pc->op; a = pc->a; pc++; goto *ops[op]; } while(0) +#define NEXTOP do { pc++; unsigned op = pc->op; a = pc->a; goto *ops[op]; } while(0) #else #define OP(x) case OP_##x -#define NEXTOP break +#define NEXTOP pc++; break #endif #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) -#define A (pc[-1].a) -#define B (pc[-1].b) -#define C (pc[-1].c) -#define Cs (pc[-1].cs) -#define BC (pc[-1].i16u) -#define BCs (pc[-1].i16) -#define ABCs (pc[-1].i24) +#define A (pc[0].a) +#define B (pc[0].b) +#define C (pc[0].c) +#define Cs (pc[0].cs) +#define BC (pc[0].i16u) +#define BCs (pc[0].i16) +#define ABCs (pc[0].i24) #define JMPOFS(x) ((x)->i24) #define KC (konstd[C]) @@ -48,8 +48,8 @@ #define CMPJMP(test) \ if ((test) == (a & CMP_CHECK)) { \ - assert(pc->op == OP_JMP); \ - pc += 1 + JMPOFS(pc); \ + assert(pc[1].op == OP_JMP); \ + pc += 1 + JMPOFS(pc+1); \ } else { \ pc += 1; \ } diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index adf2986c5..3637f2c1c 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -52,11 +52,17 @@ begin: { #if !COMPGOTO VM_UBYTE op; - for(;;) switch(op = pc->op, a = pc->a, pc++, op) + for(;;) switch(op = pc->op, a = pc->a, op) #else + pc--; NEXTOP; #endif { +#if !COMPGOTO + default: + assert(0 && "Undefined opcode hit"); + NEXTOP; +#endif OP(LI): ASSERTD(a); reg.d[a] = BCs; @@ -367,13 +373,13 @@ begin: } NEXTOP; OP(JMP): - pc += JMPOFS(pc - 1); + pc += JMPOFS(pc); NEXTOP; OP(IJMP): ASSERTD(a); pc += (BCs + reg.d[a]); - assert(pc->op == OP_JMP); - pc += 1 + JMPOFS(pc); + assert(pc[1].op == OP_JMP); + pc += 1 + JMPOFS(pc+1); NEXTOP; OP(PARAMI): assert(f->NumParam < sfunc->MaxParam); @@ -490,7 +496,7 @@ begin: VMReturn returns[MAX_RETURNS]; int numret; - FillReturns(reg, f, returns, pc, C); + FillReturns(reg, f, returns, pc+1, C); if (call->Native) { numret = static_cast(call)->NativeCall(stack, reg.param + f->NumParam - B, B, returns, C); @@ -603,8 +609,8 @@ begin: { THROW(X_TOO_MANY_TRIES); } - assert((pc + JMPOFS(pc - 1))->op == OP_CATCH); - exception_frames[try_depth++] = pc + JMPOFS(pc - 1); + assert((pc + JMPOFS(pc) + 1)->op == OP_CATCH); + exception_frames[try_depth++] = pc + JMPOFS(pc) + 1; NEXTOP; OP(UNTRY): assert(a <= try_depth); @@ -704,8 +710,8 @@ begin: } if (cmp == (a & CMP_CHECK)) { - assert(pc->op == OP_JMP); - pc += 1 + JMPOFS(pc); + assert(pc[1].op == OP_JMP); + pc += 1 + JMPOFS(pc+1); } else { From 853e49a0779627873a2d52818edf800fc6804991 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 22 Oct 2016 09:57:26 +0200 Subject: [PATCH 09/17] - fixed: R_InitSkyMap must check for the null texture which cannot be used as a sky because it has no bitmap and will cause an access violation in the sky cap color calculation. --- src/r_sky.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 37312cbae..f29929c26 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -76,10 +76,20 @@ void R_InitSkyMap () int skyheight; FTexture *skytex1, *skytex2; + // Do not allow the null texture which has no bitmap and will crash. + if (sky1texture.isNull()) + { + sky1texture = TexMan.CheckForTexture("-noflat-", FTexture::TEX_Any); + } + if (sky2texture.isNull()) + { + sky2texture = TexMan.CheckForTexture("-noflat-", FTexture::TEX_Any); + } + skytex1 = TexMan(sky1texture, true); skytex2 = TexMan(sky2texture, true); - if (skytex1 == NULL) + if (skytex1 == nullptr) return; if ((level.flags & LEVEL_DOUBLESKY) && skytex1->GetHeight() != skytex2->GetHeight()) From 31f01d076e92afb27ef1ed62476c64d68b239c60 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 22 Oct 2016 20:27:02 -0500 Subject: [PATCH 10/17] Fixed: Decals calculated "lighting" wrong - Instead of calculating lighting based from the left edge of the wall segment the decal was on, it was calculated from the left edge of the wall instead. --- src/r_segs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index d1ec04f6d..48d8f1651 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -3186,7 +3186,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep; + rw_light = rw_lightleft + (x1 - savecoord.sx1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (usecolormap->Maps + fixedlightlev); else if (fixedcolormap != NULL) From 5ba5da0dcc3deb9fbce0da00e9a7d804aeb5aea7 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 22 Oct 2016 20:56:31 -0500 Subject: [PATCH 11/17] Fixed: Loading a savegame momentarily left players with undefined pitch limits - This was only visible when using a screen wipe because the initial frame wiped to would clamp the pitch to whatever undefined pitch range the player had before the proper range was received. --- src/p_saveg.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 46cdd767b..c2f79a5c6 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -638,6 +638,12 @@ static void ReadOnePlayer(FSerializer &arc, bool skipload) playerTemp.Serialize(arc); if (!skipload) { + // This temp player has undefined pitch limits, so set them to something + // that should leave the pitch stored in the savegame intact when + // rendering. The real pitch limits will be set by P_SerializePlayers() + // via a net command, but that won't be processed in time for a screen + // wipe, so we need something here. + playerTemp.MaxPitch = playerTemp.MinPitch = playerTemp.mo->Angles.Pitch; CopyPlayer(&players[i], &playerTemp, name); } else From fbe2b76705a8e08a1bf6898780bf9e6b2a2e50e0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2016 19:08:43 +0200 Subject: [PATCH 12/17] - fixed checks in sprite sorting logic. There were some missing parentheses. --- src/gl/scene/gl_drawinfo.cpp | 2 +- src/gl/scene/gl_wall.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index d1dd60c4f..e4722b3db 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -536,7 +536,7 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) const bool drawBillboardFacingCamera = gl_billboard_faces_camera; // [Nash] has +ROLLSPRITE - const bool rotated = (ss->actor != nullptr && ss->actor->renderflags & RF_ROLLSPRITE | RF_WALLSPRITE | RF_FLATSPRITE); + const bool rotated = (ss->actor != nullptr && ss->actor->renderflags & (RF_ROLLSPRITE | RF_WALLSPRITE | RF_FLATSPRITE)); // cannot sort them at the moment. This requires more complex splitting. if (drawWithXYBillboard || drawBillboardFacingCamera || rotated) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 143029ba7..bdee5761f 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -66,7 +66,7 @@ struct GLSeg // we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim float x = y2 - y1; float y = x1 - x2; - float length = sqrt(x*x + y*y); + float length = sqrtf(x*x + y*y); return FVector3(x / length, 0, y / length); } }; From bea625a42c9aa0d854ae98e55a8a55945709730d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2016 20:42:48 +0200 Subject: [PATCH 13/17] - added an ATTENUATE flag to dynamic lights, this is set by default for attached lights. For placed lights this is off, because it'd interfere with many existing maps that depend on unattenuated lights. --- src/gl/dynlights/gl_dynlight.cpp | 1 + src/gl/dynlights/gl_dynlight.h | 1 + src/gl/dynlights/gl_dynlight1.cpp | 2 +- wadsrc/static/shaders/glsl/main.fp | 17 ++++++++++------- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight.cpp b/src/gl/dynlights/gl_dynlight.cpp index ae19ecf60..40008e3ad 100644 --- a/src/gl/dynlights/gl_dynlight.cpp +++ b/src/gl/dynlights/gl_dynlight.cpp @@ -1082,6 +1082,7 @@ void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lig light->target = actor; light->owned = true; light->ObjectFlags |= OF_Transient; + light->flags4 |= MF4_ATTENUATE; actor->dynamiclights.Push(light); } light->flags2&=~MF2_DORMANT; diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index 84965e318..c51e0c79d 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -50,6 +50,7 @@ enum #define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE #define MF4_ADDITIVE MF4_MISSILEMORE #define MF4_DONTLIGHTSELF MF4_SEESDAGGERS +#define MF4_ATTENUATE MF4_INCOMBAT enum ELightType { diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index d20f5c01b..2f8ef44ed 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -116,7 +116,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD data[4] = r; data[5] = g; data[6] = b; - data[7] = 0; + data[7] = !!(light->flags4 & MF4_ATTENUATE); return true; } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index fb1983fc7..36db31f68 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -142,16 +142,19 @@ float diffuseContribution(vec3 lightDirection, vec3 normal) // //=========================================================================== -float pointLightAttenuation(vec4 lightpos) +float pointLightAttenuation(vec4 lightpos, float attenuate) { float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - #if 0 + if (attenuate == 0.0) + { return attenuation; - #else + } + else + { vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz); float diffuseAmount = diffuseContribution(lightDirection, normalize(vWorldNormal.xyz)); return attenuation * diffuseAmount; - #endif + } } //=========================================================================== @@ -229,7 +232,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); dynlight.rgb += lightcolor.rgb; } // @@ -240,7 +243,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); dynlight.rgb -= lightcolor.rgb; } } @@ -322,7 +325,7 @@ void main() vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); addlight.rgb += lightcolor.rgb; } frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0); From 93ec6eb92e4e550ed8b126d6f53acbf933b4f7f3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 22:22:47 +0200 Subject: [PATCH 14/17] - fixed DACSThinker did not save its LastScript member. This was probably responsible for some weird behavior recently, but with the addition of the OF_Transient flag this outright crashed because it left NULL pointers on reload in places where they weren't checked for. --- src/p_acs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fcbff904a..f36aaaf69 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2907,7 +2907,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, SavingRunningscript &r void DACSThinker::Serialize(FSerializer &arc) { Super::Serialize(arc); - arc("scripts", Scripts); + arc("scripts", Scripts) + ("lastscript", LastScript); if (arc.isWriting()) { From 4e4fd97950c8b844a235c890f176c9233590bb18 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 23:35:18 +0200 Subject: [PATCH 15/17] - fixed: Multipatch textures may not set up their patch references until all textures have been loaded. If done earlier they will not be able to detect overrides of sprites and graphics which are not part of the PATCHES lump. There was some fudging code to work around this problem but it was only partially working. Now these textures only collect the texture name and use type during setup and resolve them after all textures have been created. --- src/textures/multipatchtexture.cpp | 187 ++++++++++++++++------------- src/textures/texturemanager.cpp | 4 + src/textures/textures.h | 1 + 3 files changed, 110 insertions(+), 82 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index b0db481a8..741f88a31 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -48,6 +48,7 @@ #include "v_palette.h" #include "v_video.h" #include "v_text.h" +#include "cmdlib.h" #include "m_fixed.h" #include "textures/textures.h" #include "r_data/colormaps.h" @@ -138,7 +139,6 @@ struct strifemaptexture_t struct FPatchLookup { FString Name; - FTexture *Texture; }; @@ -166,6 +166,7 @@ public: int GetSourceLump() { return DefinitionLump; } FTexture *GetRedirect(bool wantwarped); FTexture *GetRawTexture(); + void ResolvePatches(); protected: BYTE *Pixels; @@ -185,8 +186,18 @@ protected: TexPart(); }; + struct TexInit + { + FString TexName; + int UseType = TEX_Null; + bool Silent = false; + bool HasLine = false; + FScriptPosition sc; + }; + int NumParts; TexPart *Parts; + TexInit *Inits; bool bRedirect:1; bool bTranslucentPatches:1; @@ -194,7 +205,7 @@ protected: private: void CheckForHacks (); - void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); + void ParsePatch(FScanner &sc, TexPart & part, TexInit &init); }; //========================================================================== @@ -204,7 +215,7 @@ private: //========================================================================== FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +: Pixels (0), Spans(0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false) { union { @@ -240,7 +251,8 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl } UseType = FTexture::TEX_Wall; - Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; + Parts = NumParts > 0 ? new TexPart[NumParts] : nullptr; + Inits = NumParts > 0 ? new TexInit[NumParts] : nullptr; Width = SAFESHORT(mtexture.d->width); Height = SAFESHORT(mtexture.d->height); Name = (char *)mtexture.d->name; @@ -272,17 +284,9 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl } Parts[i].OriginX = LittleShort(mpatch.d->originx); Parts[i].OriginY = LittleShort(mpatch.d->originy); - Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; - if (Parts[i].Texture == NULL) - { - Printf(TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name.GetChars(), Name.GetChars()); - NumParts--; - i--; - } - else - { - Parts[i].Texture->bKeepAround = true; - } + Parts[i].Texture = nullptr; + Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name; + Inits[i].UseType = TEX_WallPatch; if (strife) mpatch.s++; else @@ -295,17 +299,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl CheckForHacks (); - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height) - { - bRedirect = true; - } - } DefinitionLump = deflumpnum; } @@ -327,6 +320,11 @@ FMultiPatchTexture::~FMultiPatchTexture () delete[] Parts; Parts = NULL; } + if (Inits != nullptr) + { + delete[] Inits; + Inits = nullptr; + } if (Spans != NULL) { FreeSpans (Spans); @@ -863,19 +861,6 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d pnames.Read(pname, 8); pname[8] = '\0'; patchlookup[i].Name = pname; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); - if (j.isValid()) - { - patchlookup[i].Texture = Textures[j.GetIndex()].Texture; - } - else - { - // Shareware Doom has the same PNAMES lump as the registered - // Doom, so printing warnings for patches that don't really - // exist isn't such a good idea. - //Printf ("Patch %s not found.\n", patchlookup[i].Name); - patchlookup[i].Texture = NULL; - } } } @@ -996,35 +981,13 @@ void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) // //========================================================================== -void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) +void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) { FString patchname; + int Mirror = 0; sc.MustGetString(); - FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); - int Mirror = 0; - - if (!texno.isValid()) - { - if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) - { - int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); - if (lumpnum >= 0) - { - part.Texture = FTexture::CreateTexture(lumpnum, usetype); - TexMan.AddTexture(part.Texture); - } - } - } - else - { - part.Texture = TexMan[texno]; - bComplex |= part.Texture->bComplex; - } - if (part.Texture == NULL) - { - if (!silent) sc.ScriptMessage(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name.GetChars()); - } + init.TexName = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginX = sc.Number; @@ -1207,6 +1170,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) : Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) { TArray parts; + TArray inits; bool bSilent = false; bMultiPatch = true; @@ -1267,16 +1231,34 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) else if (sc.Compare("Patch")) { TexPart part; - ParsePatch(sc, part, bSilent, TEX_WallPatch); - if (part.Texture != NULL) parts.Push(part); + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_WallPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } part.Texture = NULL; part.Translation = NULL; } else if (sc.Compare("Graphic")) { TexPart part; - ParsePatch(sc, part, bSilent, TEX_MiscPatch); - if (part.Texture != NULL) parts.Push(part); + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_MiscPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } part.Texture = NULL; part.Translation = NULL; } @@ -1297,21 +1279,10 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) NumParts = parts.Size(); Parts = new TexPart[NumParts]; memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); - - //CalcBitSize (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) + Inits = new TexInit[NumParts]; + for (int i = 0; i < NumParts; i++) { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height && - Parts->Rotate == 0 && - !bComplex) - { - bRedirect = true; - } + Inits[i] = inits[i]; } } @@ -1328,6 +1299,58 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) } +void FMultiPatchTexture::ResolvePatches() +{ + if (Inits != nullptr) + { + for (int i = 0; i < NumParts; i++) + { + FTextureID texno = TexMan.CheckForTexture(Inits[i].TexName, Inits[i].UseType); + + if (!texno.isValid()) + { + if (!Inits[i].Silent) + { + if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); + } + } + else + { + Parts[i].Texture = TexMan[texno]; + bComplex |= Parts[i].Texture->bComplex; + Parts[i].Texture->bKeepAround = true; + } + } + for (int i = 0; i < NumParts; i++) + { + if (Parts[i].Texture == nullptr) + { + memcpy(&Parts[i], &Parts[i + 1], NumParts - i - 1); + i--; + NumParts--; + } + } + } + delete[] Inits; + Inits = nullptr; + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height && + Parts->Rotate == 0 && + !bComplex) + { + bRedirect = true; + } + } +} + void FTextureManager::ParseXTexture(FScanner &sc, int usetype) { diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 3fb01dc6c..07ed71a3b 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -981,6 +981,10 @@ void FTextureManager::Init() { AddTexturesForWad(i); } + for (unsigned i = 0; i < Textures.Size(); i++) + { + Textures[i].Texture->ResolvePatches(); + } // Add one marker so that the last WAD is easier to handle and treat // Build tiles as a completely separate block. diff --git a/src/textures/textures.h b/src/textures/textures.h index ad1d9ba8c..407500f18 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -209,6 +209,7 @@ public: int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; } double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; } + virtual void ResolvePatches() {} virtual void SetFrontSkyLayer(); From 8368272b4d5848d2f6596d5350164b3902194e94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 23:40:37 +0200 Subject: [PATCH 16/17] - just to be thorough, added a 'sprite' keyword to define a patch to give priority to the TEX_Sprite namespace. --- src/textures/multipatchtexture.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 741f88a31..340376a25 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1245,6 +1245,23 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) part.Texture = NULL; part.Translation = NULL; } + else if (sc.Compare("Sprite")) + { + TexPart part; + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_Sprite; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } + part.Texture = NULL; + part.Translation = NULL; + } else if (sc.Compare("Graphic")) { TexPart part; From dad89b07830f649af1e26cba15990328e517ddf6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 25 Oct 2016 01:03:44 +0200 Subject: [PATCH 17/17] - fixed: Portals with disconnected parts were not grouped correctly. --- src/portal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portal.cpp b/src/portal.cpp index cef79820f..f1454cdc6 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -1024,7 +1024,8 @@ void P_CreateLinkedPortals() { if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL && sectors[i].PortalGroup == 0) { - CollectSectors(sectors[i].GetOppositePortalGroup(j), §ors[i]); + auto p = sectors[i].GetPortal(j); + CollectSectors(p->mOrigin->PortalGroup, §ors[i]); } } }