diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 49e82117..4239ae3d 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1353,7 +1353,7 @@ static int PatchFrame (int frameNum) if (keylen == 8 && stricmp (Line1, "Duration") == 0) { - tics = clamp (val, -1, 65534); + tics = clamp (val, -1, SHRT_MAX); } else if (keylen == 9 && stricmp (Line1, "Unknown 1") == 0) { diff --git a/src/g_level.cpp b/src/g_level.cpp index e6b8bad9..32acf14c 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -737,7 +737,14 @@ void G_DoCompleted (void) if (mode == FINISH_SameHub) { // Remember the level's state for re-entry. - G_SnapshotLevel (); + if (!(level.flags2 & LEVEL2_FORGETSTATE)) + { + G_SnapshotLevel (); + } + else + { // Make sure we don't have a snapshot lying around from before. + level.info->ClearSnapshot(); + } } else { // Forget the states of all existing levels. diff --git a/src/g_level.h b/src/g_level.h index c246e5b7..488cb3ea 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -213,6 +213,7 @@ enum ELevelFlags LEVEL2_NOSTATISTICS = 0x10000000, // This level should not have statistics collected LEVEL2_ENDGAME = 0x20000000, // This is an epilogue level that cannot be quit. LEVEL2_NOAUTOSAVEHINT = 0x40000000, // tell the game that an autosave for this level does not need to be kept + LEVEL2_FORGETSTATE = 0x80000000, // forget this map's state in a hub }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 1d229267..4614afd3 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1264,6 +1264,8 @@ MapFlagHandlers[] = { "endofgame", MITYPE_SETFLAG2, LEVEL2_ENDGAME, 0 }, { "nostatistics", MITYPE_SETFLAG2, LEVEL2_NOSTATISTICS, 0 }, { "noautosavehint", MITYPE_SETFLAG2, LEVEL2_NOAUTOSAVEHINT, 0 }, + { "forgetstate", MITYPE_SETFLAG2, LEVEL2_FORGETSTATE, 0 }, + { "rememberstate", MITYPE_CLRFLAG2, LEVEL2_FORGETSTATE, 0 }, { "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, diff --git a/src/info.cpp b/src/info.cpp index 69476d29..4d322534 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -55,6 +55,8 @@ extern void LoadActors (); extern void InitBotStuff(); extern void ClearStrifeTypes(); +FRandom FState::pr_statetics; + //========================================================================== // // diff --git a/src/info.h b/src/info.h index c2962512..87e62381 100644 --- a/src/info.h +++ b/src/info.h @@ -45,6 +45,7 @@ #include "doomdef.h" #include "m_fixed.h" +#include "m_random.h" struct Baggage; class FScanner; @@ -61,18 +62,19 @@ enum struct FState { + FState *NextState; + actionf_p ActionFunc; WORD sprite; SWORD Tics; - int Misc1; // Was changed to SBYTE, reverted to long for MBF compat - int Misc2; // Was changed to BYTE, reverted to long for MBF compat + WORD TicRange; BYTE Frame; BYTE DefineFlags; // Unused byte so let's use it during state creation. + int Misc1; // Was changed to SBYTE, reverted to long for MBF compat + int Misc2; // Was changed to BYTE, reverted to long for MBF compat short Light; BYTE Fullbright:1; // State is fullbright BYTE SameFrame:1; // Ignore Frame (except when spawning actor) BYTE Fast:1; - FState *NextState; - actionf_p ActionFunc; int ParameterIndex; inline int GetFrame() const @@ -89,7 +91,11 @@ struct FState } inline int GetTics() const { - return Tics; + if (TicRange == 0) + { + return Tics; + } + return Tics + pr_statetics.GenRand32() % (TicRange + 1); } inline int GetMisc1() const { @@ -134,6 +140,7 @@ struct FState } static const PClass *StaticFindStateOwner (const FState *state); static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info); + static FRandom pr_statetics; }; struct FStateLabels; diff --git a/src/r_defs.h b/src/r_defs.h index a7f7a116..8ad15e76 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -903,11 +903,11 @@ struct side_t void SetTextureXScale(int which, fixed_t scale) { - textures[which].xscale = scale <= 0? FRACUNIT : scale; + textures[which].xscale = scale == 0 ? FRACUNIT : scale; } void SetTextureXScale(fixed_t scale) { - textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale <= 0? FRACUNIT : scale; + textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale == 0 ? FRACUNIT : scale; } fixed_t GetTextureXScale(int which) const { @@ -921,11 +921,11 @@ struct side_t void SetTextureYScale(int which, fixed_t scale) { - textures[which].yscale = scale <= 0? FRACUNIT : scale; + textures[which].yscale = scale == 0 ? FRACUNIT : scale; } void SetTextureYScale(fixed_t scale) { - textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale <= 0? FRACUNIT : scale; + textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale == 0 ? FRACUNIT : scale; } fixed_t GetTextureYScale(int which) const { diff --git a/src/r_segs.cpp b/src/r_segs.cpp index a40a2ce3..bfeab506 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2769,6 +2769,7 @@ int WallMost (short *mostbuf, const secplane_t &plane) static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) { // fix for rounding errors + walxrepeat = abs(walxrepeat); fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; @@ -2803,7 +2804,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) { // swall = scale, lwall = texturecolumn double top, bot, i; - double xrepeat = walxrepeat; + double xrepeat = fabs((double)walxrepeat); i = WallSX1 - centerx; top = WallUoverZorg + WallUoverZstep * i; @@ -2812,7 +2813,14 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) for (int x = WallSX1; x < WallSX2; x++) { double frac = top / bot; - lwall[x] = xs_RoundToInt(frac * xrepeat); + if (walxrepeat < 0) + { + lwall[x] = xs_RoundToInt(xrepeat - frac * xrepeat); + } + else + { + lwall[x] = xs_RoundToInt(frac * xrepeat); + } swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg); top += WallUoverZstep; bot += WallInvZstep; @@ -2823,7 +2831,7 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) { // lwall = texturecolumn double top, bot, i; - double xrepeat = walxrepeat; + double xrepeat = fabs((double)walxrepeat); double topstep; i = WallSX1 - centerx; @@ -2835,7 +2843,14 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) for (int x = WallSX1; x < WallSX2; x++) { - lwall[x] = xs_RoundToInt(top / bot); + if (walxrepeat < 0) + { + lwall[x] = xs_RoundToInt(xrepeat - top / bot); + } + else + { + lwall[x] = xs_RoundToInt(top / bot); + } top += topstep; bot += WallInvZstep; } diff --git a/src/svnrevision.h b/src/svnrevision.h index 3112d44b..a279ba9d 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3845" -#define ZD_SVN_REVISION_NUMBER 3845 +#define ZD_SVN_REVISION_STRING "3851" +#define ZD_SVN_REVISION_NUMBER 3851 diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index 421ff1e8..d4db28e9 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -199,6 +199,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) if (info->NumOwnedStates == 1) { info->OwnedStates->Tics = -1; + info->OwnedStates->TicRange = 0; info->OwnedStates->Misc1 = 0; } else @@ -226,6 +227,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) else { info->OwnedStates[i].Tics = -1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; } @@ -273,6 +275,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) else { info->OwnedStates[i].Tics = -1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; } @@ -307,12 +310,14 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) } info->OwnedStates[i].NextState = &info->OwnedStates[info->NumOwnedStates-1]; info->OwnedStates[i].Tics = 5; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeath")); i = info->NumOwnedStates - 1; info->OwnedStates[i].NextState = &info->OwnedStates[i]; info->OwnedStates[i].Tics = 1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks")); bag.statedef.SetStateLabel("Ice", &info->OwnedStates[extra.IceDeathStart]); @@ -671,6 +676,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray &states, FScanne } state.Tics = rate; + state.TicRange = 0; while (*token) { diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index 31d49db5..5c2d8160 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -56,6 +56,7 @@ #include "colormatcher.h" #include "thingdef_exp.h" #include "version.h" +#include "templates.h" //========================================================================== //*** @@ -237,8 +238,30 @@ do_stop: sc.MustGetString(); statestring = sc.String; - sc.MustGetNumber(); - state.Tics = clamp(sc.Number, -1, 32767); + if (sc.CheckString("RANDOM")) + { + int min, max; + + sc.MustGetStringName("("); + sc.MustGetNumber(); + min = clamp(sc.Number, -1, SHRT_MAX); + sc.MustGetStringName(","); + sc.MustGetNumber(); + max = clamp(sc.Number, -1, SHRT_MAX); + sc.MustGetStringName(")"); + if (min > max) + { + swapvalues(min, max); + } + state.Tics = min; + state.TicRange = max - min; + } + else + { + sc.MustGetNumber(); + state.Tics = clamp(sc.Number, -1, SHRT_MAX); + state.TicRange = 0; + } while (sc.GetString() && !sc.Crossed) { diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 1b843246..38ac1bd7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -651,7 +651,7 @@ OptionMenu "VideoOptions" Submenu "Scoreboard Options", "ScoreboardOptions" StaticText " " Slider "Screen size", "screenblocks", 3.0, 12.0, 1.0, 0 - Slider "Brightness", "Gamma", 1.0, 3.0, 0.1 + Slider "Brightness", "Gamma", 0.75, 3.0, 0.05, 2 Option "Vertical Sync", "vid_vsync", "OnOff" Option "Column render mode", "r_columnmethod", "ColumnMethods" diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index e495e5da..93d88b5f 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -214,7 +214,7 @@ OptionMenu "VideoOptions" StaticText " " Slider "Screen size", "screenblocks", 3.0, 12.0, 1.0, 0 - Slider "Gamma correction", "Gamma", 1.0, 3.0, 0.1 + Slider "Gamma correction", "Gamma", 0.75, 3.0, 0.05, 2 Slider "Brightness", "vid_brightness", -0.8,0.8, 0.05 Slider "Contrast", "vid_contrast", 0.1, 3.0, 0.1