diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 0b99fd73d..3504c5874 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -70,6 +70,7 @@ CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Bool, neverswitchonpickup, false, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, movebob, 0.25f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, stillbob, 0.f, CVAR_USERINFO | CVAR_ARCHIVE); +CVAR (Float, wbobspeed, 1.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, playerclass, "Fighter", CVAR_USERINFO | CVAR_ARCHIVE); enum @@ -83,6 +84,7 @@ enum INFO_NeverSwitchOnPickup, INFO_MoveBob, INFO_StillBob, + INFO_WBobSpeed, INFO_PlayerClass, INFO_ColorSet, }; diff --git a/src/d_player.h b/src/d_player.h index e932223aa..5206fd770 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -337,6 +337,10 @@ struct userinfo_t : TMap { return *static_cast(*CheckKey(NAME_StillBob)); } + float GetWBobSpeed() const + { + return *static_cast(*CheckKey(NAME_WBobSpeed)); + } int GetPlayerClassNum() const { return *static_cast(*CheckKey(NAME_PlayerClass)); diff --git a/src/files.cpp b/src/files.cpp index 0b7203236..93a8c9729 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -527,7 +527,7 @@ long MemoryReader::Seek (long offset, int origin) break; } - FilePos=clamp(offset,0,Length-1); + FilePos=clamp(offset,0,Length); return 0; } @@ -583,7 +583,7 @@ long MemoryArrayReader::Seek (long offset, int origin) break; } - FilePos=clamp(offset,0,Length-1); + FilePos=clamp(offset,0,Length); return 0; } diff --git a/src/g_level.cpp b/src/g_level.cpp index 43ec4bdc4..b09163c8a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1291,6 +1291,9 @@ void G_FinishTravel () if (level.FromSnapshot) { FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true); + + // [Nash] run REOPEN scripts upon map re-entry + FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false); } } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index b5ac970ca..72ad84c2d 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1668,7 +1668,7 @@ void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bo newdam = damage * 4; } if (Owner != NULL && newdam > damage) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE); - newdamage = newdam; + newdamage = damage = newdam; } if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive); } @@ -1743,7 +1743,7 @@ void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage newdam = damage / 4; } if (Owner != NULL && newdam < damage) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE); - newdamage = newdam; + newdamage = damage = newdam; } if (Inventory != NULL) { diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 575914fe8..6143f5206 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -222,6 +222,10 @@ bool AWeapon::HandlePickup (AInventory *item) { item->ItemFlags |= IF_PICKUPGOOD; } + if (MaxAmount > 1) //[SP] If amountuserinfo.GetWBobSpeed() * 35 / + TICRATE*(level.time - 1 + i)) * (360.f / 8192.f); // [RH] Smooth transitions between bobbing and not-bobbing frames. // This also fixes the bug where you can "stick" a weapon off-center by diff --git a/src/posix/osx/zdoom-info.plist b/src/posix/osx/zdoom-info.plist index 73be09aa8..e2f896560 100644 --- a/src/posix/osx/zdoom-info.plist +++ b/src/posix/osx/zdoom-info.plist @@ -44,6 +44,6 @@ NSPrincipalClass NSApplication NSSupportsAutomaticGraphicsSwitching - YES + diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index b3f7b7d45..fd0bab645 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -59,7 +59,11 @@ #else #include +#ifdef __APPLE__ +#define FLUIDSYNTHLIB "libfluidsynth.1.dylib" +#else // !__APPLE__ #define FLUIDSYNTHLIB "libfluidsynth.so.1" +#endif // __APPLE__ #endif #define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f @@ -92,6 +96,8 @@ // PUBLIC DATA DEFINITIONS ------------------------------------------------- +CVAR(String, fluid_lib, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + CVAR(String, fluid_patchset, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -689,22 +695,54 @@ bool FluidSynthMIDIDevice::LoadFluidSynth() const char *libname; #ifdef _WIN32 - FluidSynthDLL = LoadLibrary((libname = FLUIDSYNTHLIB1)); - if (FluidSynthDLL == NULL) + if (strlen(fluid_lib) > 0) { - FluidSynthDLL = LoadLibrary((libname = FLUIDSYNTHLIB2)); - if (FluidSynthDLL == NULL) + FluidSynthDLL = LoadLibrary(libname = fluid_lib); + if (nullptr == FluidSynthDLL) { - Printf(TEXTCOLOR_RED"Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n"); - return false; + Printf(TEXTCOLOR_RED "Could not load %s\n", libname); + } + } + else + { + FluidSynthDLL = nullptr; + } + + if (nullptr == FluidSynthDLL) + { + FluidSynthDLL = LoadLibrary(libname = FLUIDSYNTHLIB1); + if (nullptr == FluidSynthDLL) + { + FluidSynthDLL = LoadLibrary(libname = FLUIDSYNTHLIB2); + if (nullptr == FluidSynthDLL) + { + Printf(TEXTCOLOR_RED "Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n"); + return false; + } } } #else - FluidSynthSO = dlopen((libname = FLUIDSYNTHLIB), RTLD_LAZY); - if (FluidSynthSO == NULL) + if (strlen(fluid_lib) > 0) { - Printf(TEXTCOLOR_RED"Could not load " FLUIDSYNTHLIB ": %s\n", dlerror()); - return false; + FluidSynthSO = dlopen(libname = fluid_lib, RTLD_LAZY); + if (nullptr == FluidSynthSO) + { + Printf(TEXTCOLOR_RED "Could not load %s: %s\n", libname, dlerror()); + } + } + else + { + FluidSynthSO = nullptr; + } + + if (nullptr == FluidSynthSO) + { + FluidSynthSO = dlopen(libname = FLUIDSYNTHLIB, RTLD_LAZY); + if (nullptr == FluidSynthSO) + { + Printf(TEXTCOLOR_RED "Could not load " FLUIDSYNTHLIB ": %s\n", dlerror()); + return false; + } } #endif diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index ce603f261..695b12799 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -3373,6 +3373,19 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx) ExpEmit FxClassMember::Emit(VMFunctionBuilder *build) { + if (~membervar->Flags & VARF_Native) + { // Check if this is a user-defined variable. + // As of right now, FxClassMember is only ever used with FxSelf. + // This very user variable was defined in stateowner so if + // self (a0) != stateowner (a1) then the offset is most likely + // going to end up being totally wrong even if the variable was + // redefined in self which means we have to abort to avoid reading + // or writing to a random address and possibly crash. + build->Emit(OP_EQA_R, 1, 0, 1); + build->Emit(OP_JMP, 1); + build->Emit(OP_THROW, 2, X_BAD_SELF); + } + ExpEmit obj = classx->Emit(build); assert(obj.RegType == REGT_POINTER); diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 52194435b..3cb424ea3 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1576,10 +1576,6 @@ DEFINE_PROPERTY(telefogdesttype, S, Actor) DEFINE_PROPERTY(ripperlevel, I, Actor) { PROP_INT_PARM(id, 0); - if (id < 0) - { - I_Error ("RipperLevel must not be negative"); - } defaults->RipperLevel = id; } @@ -1589,10 +1585,6 @@ DEFINE_PROPERTY(ripperlevel, I, Actor) DEFINE_PROPERTY(riplevelmin, I, Actor) { PROP_INT_PARM(id, 0); - if (id < 0) - { - I_Error ("RipLevelMin must not be negative"); - } defaults->RipLevelMin = id; } @@ -1602,10 +1594,6 @@ DEFINE_PROPERTY(riplevelmin, I, Actor) DEFINE_PROPERTY(riplevelmax, I, Actor) { PROP_INT_PARM(id, 0); - if (id < 0) - { - I_Error ("RipLevelMax must not be negative"); - } defaults->RipLevelMax = id; } diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 0d45ad90a..a000e9533 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -163,6 +163,7 @@ enum EVMAbortException X_TOO_MANY_TRIES, X_ARRAY_OUT_OF_BOUNDS, X_DIVISION_BY_ZERO, + X_BAD_SELF, }; class VMFunction : public DObject diff --git a/src/zscript/vmdisasm.cpp b/src/zscript/vmdisasm.cpp index 35eb6085d..4e6f33ec7 100644 --- a/src/zscript/vmdisasm.cpp +++ b/src/zscript/vmdisasm.cpp @@ -371,7 +371,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction col = print_reg(out, 0, a, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func); if ((mode & MODE_BCTYPE) == MODE_BCTHROW) { - mode = (code[i].a == 0) ? (MODE_BP | MODE_CUNUSED) : (MODE_BKP | MODE_CUNUSED); + if (code[i].a == 0) + { + mode = (MODE_BP | MODE_CUNUSED); + } + else if (code[i].a == 1) + { + mode = (MODE_BKP | MODE_CUNUSED); + } + else + { + mode = (MODE_BCJOINT | MODE_BCIMMS); + } } else if ((mode & MODE_BCTYPE) == MODE_BCCATCH) { diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index 42a374030..adf2986c5 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -616,12 +616,16 @@ begin: ASSERTA(B); throw((VMException *)reg.a[B]); } - else + else if (a == 1) { ASSERTKA(B); assert(konstatag[B] == ATAG_OBJECT); throw((VMException *)konsta[B].o); } + else + { + THROW(BC); + } NEXTOP; OP(CATCH): // This instruction is handled by our own catch handler and should diff --git a/src/zscript/vmframe.cpp b/src/zscript/vmframe.cpp index 29da0c5b9..50c7d78d9 100644 --- a/src/zscript/vmframe.cpp +++ b/src/zscript/vmframe.cpp @@ -440,6 +440,10 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur case X_DIVISION_BY_ZERO: Printf("division by zero."); break; + + case X_BAD_SELF: + Printf("invalid self pointer."); + break; } Printf("\n"); diff --git a/src/zscript/vmops.h b/src/zscript/vmops.h index decb0b93d..39d224f5c 100644 --- a/src/zscript/vmops.h +++ b/src/zscript/vmops.h @@ -83,7 +83,8 @@ xx(RETI, reti, I8I16), // Copy immediate from BC to return value A, possibly re xx(TRY, try, I24), // When an exception is thrown, start searching for a handler at pc + ABC xx(UNTRY, untry, I8), // Pop A entries off the exception stack xx(THROW, throw, THROW), // A == 0: Throw exception object pB - // A != 0: Throw exception object pkB + // A == 1: Throw exception object pkB + // A >= 2: Throw VM exception of type BC xx(CATCH, catch, CATCH), // A == 0: continue search on next try // A == 1: continue execution at instruction immediately following CATCH (catches any exception) // A == 2: (pB == ) then pc++ ; next instruction must JMP to another CATCH diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 757d7bf93..e3fbb16ca 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1802,6 +1802,7 @@ DSPLYMNU_MENUDIM = "Menu dim"; DSPLYMNU_DIMCOLOR = "Dim color"; DSPLYMNU_MOVEBOB = "View bob amount while moving"; DSPLYMNU_STILLBOB = "View bob amount while not moving"; +DSPLYMNU_BOBSPEED = "Weapon bob speed"; // HUD Options HUDMNU_TITLE = "HUD Options"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index dcdaa90b3..adcc2d29c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -703,6 +703,7 @@ OptionMenu "VideoOptions" ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor" Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2 Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2 + Slider "$DSPLYMNU_BOBSPEED", "wbobspeed", 0, 2.0, 0.1, 2 } //-------------------------------------------------------------------------------------------