diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index c79a76fb3..cd48e304e 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -51,6 +51,7 @@ #include "v_palette.h" #include "v_video.h" #include "colormatcher.h" +#include "menu/menu.h" struct FLatchedValue { @@ -204,7 +205,9 @@ DEFINE_ACTION_FUNCTION(_CVar, GetString) DEFINE_ACTION_FUNCTION(_CVar, SetInt) { + // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; PARAM_INT(val); UCVarValue v; v.Int = val; @@ -214,17 +217,21 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt) DEFINE_ACTION_FUNCTION(_CVar, SetFloat) { + // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; PARAM_FLOAT(val); UCVarValue v; - v.Float = val; + v.Float = (float)val; self->SetGenericRep(v, CVAR_Float); return 0; } DEFINE_ACTION_FUNCTION(_CVar, SetString) { + // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; PARAM_STRING(val); UCVarValue v; v.String = val.GetChars(); diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 8bd83ed15..343903495 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -54,6 +54,7 @@ #include "d_net.h" #include "d_main.h" #include "serializer.h" +#include "menu/menu.h" // MACROS ------------------------------------------------------------------ @@ -662,8 +663,10 @@ void C_DoCommand (const char *cmd, int keynum) } } -DEFINE_ACTION_FUNCTION(_Console, DoCommand) +// This is only accessible to the special menu item to run CCMDs. +DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand) { + if (DMenu::CurrentMenu == nullptr) return 0; PARAM_PROLOGUE; PARAM_STRING(cmd); C_DoCommand(cmd); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 53ca1f335..5d4ec59c9 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3513,7 +3513,7 @@ const PClass *PClass::NativeClass() const VMFunction *PClass::FindFunction(FName clsname, FName funcname) { - auto cls = PClass::FindActor(clsname); + auto cls = PClass::FindClass(clsname); if (!cls) return nullptr; auto func = dyn_cast(cls->Symbols.FindSymbol(funcname, true)); if (!func) return nullptr; @@ -3522,7 +3522,7 @@ VMFunction *PClass::FindFunction(FName clsname, FName funcname) void PClass::FindFunction(VMFunction **pptr, FName clsname, FName funcname) { - auto cls = PClass::FindActor(clsname); + auto cls = PClass::FindClass(clsname); if (!cls) return; auto func = dyn_cast(cls->Symbols.FindSymbol(funcname, true)); if (!func) return; diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index bb73ad3ae..bd185f76f 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -212,6 +212,7 @@ struct FGLROptions : public FOptionalMapinfoData lightmode = -1; attenuate = -1; nocoloredspritelighting = -1; + nolightfade = false; notexturefill = -1; skyrotatevector = FVector3(0,0,1); skyrotatevector2 = FVector3(0,0,1); @@ -228,6 +229,7 @@ struct FGLROptions : public FOptionalMapinfoData newopt->lightmode = lightmode; newopt->attenuate = attenuate; newopt->nocoloredspritelighting = nocoloredspritelighting; + newopt->nolightfade = nolightfade; newopt->notexturefill = notexturefill; newopt->skyrotatevector = skyrotatevector; newopt->skyrotatevector2 = skyrotatevector2; @@ -244,6 +246,7 @@ struct FGLROptions : public FOptionalMapinfoData int8_t lightadditivesurfaces; int8_t nocoloredspritelighting; int8_t notexturefill; + bool nolightfade; FVector3 skyrotatevector; FVector3 skyrotatevector2; float pixelstretch; @@ -303,6 +306,20 @@ DEFINE_MAP_OPTION(nocoloredspritelighting, false) } } +DEFINE_MAP_OPTION(nolightfade, false) +{ + FGLROptions *opt = info->GetOptData("gl_renderer"); + if (parse.CheckAssign()) + { + parse.sc.MustGetNumber(); + opt->nolightfade = !!parse.sc.Number; + } + else + { + opt->nolightfade = true; + } +} + DEFINE_MAP_OPTION(notexturefill, false) { FGLROptions *opt = info->GetOptData("gl_renderer"); @@ -423,6 +440,7 @@ void InitGLRMapinfoData() glset.skyrotatevector = opt->skyrotatevector; glset.skyrotatevector2 = opt->skyrotatevector2; glset.pixelstretch = opt->pixelstretch; + glset.nolightfade = opt->nolightfade; } else { @@ -436,6 +454,7 @@ void InitGLRMapinfoData() glset.skyrotatevector = FVector3(0, 0, 1); glset.skyrotatevector2 = FVector3(0, 0, 1); glset.pixelstretch = 1.2f; + glset.nolightfade = false; } ResetOpts(); } diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index d5bdeb46a..cf79fe138 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -10,6 +10,7 @@ struct GLRenderSettings SBYTE lightmode; bool nocoloredspritelighting; + bool nolightfade; bool notexturefill; bool brightfog; bool lightadditivesurfaces; diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index b4912f825..c017453bd 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -312,7 +312,7 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if (glset.lightmode != 8) + if (glset.lightmode != 8 && !glset.nolightfade) { density = distfogtable[glset.lightmode != 0][gl_ClampLight(lightlevel)]; } diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 040066deb..1ebc1c488 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -352,15 +352,18 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla float FTexCoordInfo::RowOffset(float rowoffset) const { - if (mTempScale.Y == 1.f) + float tscale = fabs(mTempScale.Y); + float scale = fabs(mScale.Y); + + if (tscale == 1.f) { - if (mScale.Y == 1.f || mWorldPanning) return rowoffset; - else return rowoffset / mScale.Y; + if (scale == 1.f || mWorldPanning) return rowoffset; + else return rowoffset / scale; } else { - if (mWorldPanning) return rowoffset / mTempScale.Y; - else return rowoffset / mScale.Y; + if (mWorldPanning) return rowoffset / tscale; + else return rowoffset / scale; } } @@ -372,15 +375,17 @@ float FTexCoordInfo::RowOffset(float rowoffset) const float FTexCoordInfo::TextureOffset(float textureoffset) const { - if (mTempScale.X == 1.f) + float tscale = fabs(mTempScale.X); + float scale = fabs(mScale.X); + if (tscale == 1.f) { - if (mScale.X == 1.f || mWorldPanning) return textureoffset; - else return textureoffset / mScale.X; + if (scale == 1.f || mWorldPanning) return textureoffset; + else return textureoffset / scale; } else { - if (mWorldPanning) return textureoffset / mTempScale.X; - else return textureoffset / mScale.X; + if (mWorldPanning) return textureoffset / tscale; + else return textureoffset / scale; } } @@ -394,8 +399,9 @@ float FTexCoordInfo::TextureAdjustWidth() const { if (mWorldPanning) { - if (mTempScale.X == 1.f) return mRenderWidth; - else return mWidth / mTempScale.X; + float tscale = fabs(mTempScale.X); + if (tscale == 1.f) return mRenderWidth; + else return mWidth / fabs(tscale); } else return mWidth; } diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index eef4aa3bf..f1015b79c 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -52,12 +52,6 @@ #include "m_joy.h" static TArray Joysticks; -IJoystickConfig *SELECTED_JOYSTICK; - -DEFINE_ACTION_FUNCTION(DMenu, GetCurrentJoystickConfig) -{ - ACTION_RETURN_POINTER(SELECTED_JOYSTICK); -} DEFINE_ACTION_FUNCTION(IJoystickConfig, GetSensitivity) { @@ -121,80 +115,24 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisMap) return 0; } - -DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); - -/*======================================= - * - * Joystick Menu - * - *=======================================*/ - -DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetName) { - DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu); - if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) - { - DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; - DMenuItemBase *it; - opt->mItems.Clear(); - if (joy == NULL) - { - opt->mTitle = "Configure Controller"; - it = CreateOptionMenuItemStaticText("Invalid controller specified for menu", false); - opt->mItems.Push(it); - } - else - { - opt->mTitle.Format("Configure %s", joy->GetName().GetChars()); - - SELECTED_JOYSTICK = joy; - - it = CreateOptionMenuSliderJoySensitivity("Overall sensitivity", 0, 2, 0.1, 3); - opt->mItems.Push(it); - it = CreateOptionMenuItemStaticText(" ", false); - opt->mItems.Push(it); - - if (joy->GetNumAxes() > 0) - { - it = CreateOptionMenuItemStaticText("Axis Configuration", true); - opt->mItems.Push(it); - - for (int i = 0; i < joy->GetNumAxes(); ++i) - { - it = CreateOptionMenuItemStaticText(" ", false); - opt->mItems.Push(it); - - it = CreateOptionMenuItemJoyMap(joy->GetAxisName(i), i, "JoyAxisMapNames", false); - opt->mItems.Push(it); - it = CreateOptionMenuSliderJoyScale("Overall sensitivity", i, 0, 4, 0.1, 3); - opt->mItems.Push(it); - it = CreateOptionMenuItemInverter("Invert", i, false); - opt->mItems.Push(it); - it = CreateOptionMenuSliderJoyDeadZone("Dead Zone", i, 0, 0.9, 0.05, 3); - opt->mItems.Push(it); - } - } - else - { - it = CreateOptionMenuItemStaticText("No configurable axes", false); - opt->mItems.Push(it); - } - } - for (auto &p : opt->mItems) - { - GC::WriteBarrier(p); - } - opt->mScrollPos = 0; - opt->mSelectedItem = -1; - opt->mIndent = 0; - opt->mPosition = -25; - opt->CalcIndent(); - return opt; - } - return NULL; + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + ACTION_RETURN_STRING(self->GetName()); } +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisName) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + ACTION_RETURN_STRING(self->GetAxisName(axis)); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetNumAxes) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + ACTION_RETURN_INT(self->GetNumAxes()); +} void UpdateJoystickMenu(IJoystickConfig *selected) @@ -204,7 +142,6 @@ void UpdateJoystickMenu(IJoystickConfig *selected) { DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; DMenuItemBase *it; - opt->mItems.Clear(); int i; int itemnum = -1; @@ -225,72 +162,50 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } } } +#ifdef _WIN32 + opt->mItems.Resize(8); +#else + opt->mItems.Resize(5); +#endif - // Todo: Block joystick for changing this one. - it = CreateOptionMenuItemOption("Enable controller support", "use_joystick", "YesNo", NULL, false); - opt->mItems.Push(it); - #ifdef _WIN32 - it = CreateOptionMenuItemOption("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); - opt->mItems.Push(it); - it = CreateOptionMenuItemOption("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); - opt->mItems.Push(it); - it = CreateOptionMenuItemOption("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); - opt->mItems.Push(it); - #endif + it = opt->GetItem("ConfigureMessage"); + if (it != nullptr) it->SetValue(0, !!Joysticks.Size()); + it = opt->GetItem("ConnectMessage1"); + if (it != nullptr) it->SetValue(0, !use_joystick); + it = opt->GetItem("ConnectMessage2"); + if (it != nullptr) it->SetValue(0, !use_joystick); - it = CreateOptionMenuItemStaticText(" ", false); - opt->mItems.Push(it); - - if (Joysticks.Size() == 0) + for (int i = 0; i < (int)Joysticks.Size(); ++i) { - it = CreateOptionMenuItemStaticText("No controllers detected", false); + it = CreateOptionMenuItemJoyConfigMenu(Joysticks[i]->GetName(), Joysticks[i]); + GC::WriteBarrier(opt, it); opt->mItems.Push(it); - if (!use_joystick) - { - it = CreateOptionMenuItemStaticText("Controller support must be", false); - opt->mItems.Push(it); - it = CreateOptionMenuItemStaticText("enabled to detect any", false); - opt->mItems.Push(it); - } - } - else - { - it = CreateOptionMenuItemStaticText("Configure controllers:", false); - opt->mItems.Push(it); - - for (int i = 0; i < (int)Joysticks.Size(); ++i) - { - it = CreateOptionMenuItemJoyConfigMenu(Joysticks[i]->GetName(), Joysticks[i]); - opt->mItems.Push(it); - if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); - } - } - for (auto &p : opt->mItems) - { - GC::WriteBarrier(p); + if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); } if (opt->mSelectedItem >= (int)opt->mItems.Size()) { opt->mSelectedItem = opt->mItems.Size() - 1; } - opt->CalcIndent(); - // If the joystick config menu is open, close it if the device it's - // open for is gone. - for (i = 0; (unsigned)i < Joysticks.Size(); ++i) + // If the joystick config menu is open, close it if the device it's open for is gone. + if (DMenu::CurrentMenu != nullptr && (DMenu::CurrentMenu->IsKindOf("JoystickConfigMenu"))) { - if (Joysticks[i] == SELECTED_JOYSTICK) + auto p = DMenu::CurrentMenu->PointerVar("mJoy"); + if (p != nullptr) { - break; - } - } - if (i == (int)Joysticks.Size()) - { - SELECTED_JOYSTICK = NULL; - if (DMenu::CurrentMenu != NULL && DMenu::CurrentMenu->IsKindOf("JoystickConfigMenu")) - { - DMenu::CurrentMenu->Close(); + unsigned i; + for (i = 0; i < Joysticks.Size(); ++i) + { + if (Joysticks[i] == p) + { + break; + } + } + if (i == Joysticks.Size()) + { + DMenu::CurrentMenu->Close(); + } } } } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 46a0978af..041b1195e 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -1203,6 +1203,9 @@ DEFINE_FIELD(DMenuItemBase, mYpos) DEFINE_FIELD(DMenuItemBase, mAction) DEFINE_FIELD(DMenuItemBase, mEnabled) +DEFINE_FIELD(DListMenu, mDesc) +DEFINE_FIELD(DListMenu, mFocusControl) + DEFINE_FIELD(DListMenuDescriptor, mItems) DEFINE_FIELD(DListMenuDescriptor, mSelectedItem) DEFINE_FIELD(DListMenuDescriptor, mSelectOfsX) @@ -1241,6 +1244,7 @@ DEFINE_FIELD(FOptionMenuSettings, mLinespacing) struct IJoystickConfig; +// These functions are used by dynamic menu creation. DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v) { auto c = PClass::FindClass("OptionMenuItemStaticText"); @@ -1251,36 +1255,6 @@ DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v) return (DMenuItemBase*)p; } -DMenuItemBase * CreateOptionMenuSliderVar(const char *name, int index, double min, double max, double step, int showval) -{ - auto c = PClass::FindClass("OptionMenuItemSliderVar"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(name), index, min, max, step, showval }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuItemCommand(const char * label, FName cmd) -{ - auto c = PClass::FindClass("OptionMenuItemCommand"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), cmd.GetIndex() }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuItemOption(const char * label, FName cmd, FName values, FBaseCVar *graycheck, bool center) -{ - auto c = PClass::FindClass("OptionMenuItemOption"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), cmd.GetIndex(), values.GetIndex(), graycheck, center }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy) { auto c = PClass::FindClass("OptionMenuItemJoyConfigMenu"); @@ -1291,56 +1265,6 @@ DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickCo return (DMenuItemBase*)p; } -DMenuItemBase * CreateOptionMenuItemJoyMap(const char *label, int axis, FName values, bool center) -{ - auto c = PClass::FindClass("OptionMenuItemJoyMap"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), axis, values.GetIndex(), center }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuSliderJoySensitivity(const char * label, double min, double max, double step, int showval) -{ - auto c = PClass::FindClass("OptionMenuSliderJoySensitivity"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), min, max, step, showval }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval) -{ - auto c = PClass::FindClass("OptionMenuSliderJoyScale"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), min, max, step, showval }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuItemInverter(const char *label, int axis, int center) -{ - auto c = PClass::FindClass("OptionMenuItemInverter"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), axis, center }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - -DMenuItemBase * CreateOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval) -{ - auto c = PClass::FindClass("OptionMenuSliderJoyDeadZone"); - auto p = c->CreateNew(); - VMValue params[] = { p, FString(label), min, max, step, showval }; - auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); - GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenuItemBase*)p; -} - DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center) { auto c = PClass::FindClass("OptionMenuItemSubmenu"); @@ -1533,7 +1457,7 @@ bool DMenuItemBase::MouseEvent(int type, int x, int y) { IFVIRTUAL(DMenuItemBase, MouseEvent) { - VMValue params[] = { (DObject*)this, x, y }; + VMValue params[] = { (DObject*)this, type, x, y }; int retval; VMReturn ret(&retval); GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); diff --git a/src/menu/menu.h b/src/menu/menu.h index d6edb861b..ffc15e880 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -344,12 +344,11 @@ class DListMenu : public DMenu { DECLARE_CLASS(DListMenu, DMenu) HAS_OBJECT_POINTERS; +public: -protected: DListMenuDescriptor *mDesc; DMenuItemBase *mFocusControl; -public: DListMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); DMenuItemBase *GetItem(FName name); @@ -455,17 +454,9 @@ void M_MarkMenus(); struct IJoystickConfig; DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v); -DMenuItemBase * CreateOptionMenuSliderVar(const char *name, int index, double min, double max, double step, int showval); -DMenuItemBase * CreateOptionMenuItemCommand(const char * label, FName cmd); -DMenuItemBase * CreateOptionMenuItemOption(const char * label, FName cmd, FName values, FBaseCVar *graycheck, bool center); DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center); DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings); DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy); -DMenuItemBase * CreateOptionMenuItemJoyMap(const char *label, int axis, FName values, bool center); -DMenuItemBase * CreateOptionMenuSliderJoySensitivity(const char * label, double min, double max, double step, int showval); -DMenuItemBase * CreateOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval); -DMenuItemBase * CreateOptionMenuItemInverter(const char *label, int axis, int center); -DMenuItemBase * CreateOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval); DMenuItemBase * CreateListMenuItemPatch(int x, int y, int height, int hotkey, FTextureID tex, FName command, int param); DMenuItemBase * CreateListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, PalEntry color1, PalEntry color2, FName command, int param); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 2d9a69417..13e9e7877 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -792,7 +792,10 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) auto cv = FindCVar(sc.String, nullptr); if (cv == nullptr && *sc.String) { - sc.ScriptError("Unknown CVar %s", sc.String); + if (func->Variants[0].ArgFlags[i] & VARF_Optional) + sc.ScriptMessage("Unknown CVar %s", sc.String); + else + sc.ScriptError("Unknown CVar %s", sc.String); } params.Push(cv); } diff --git a/src/p_map.cpp b/src/p_map.cpp index 0c44659ca..80830f598 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3533,6 +3533,10 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) || ((mo->flags6 & MF6_NOBOSSRIP) && (BlockingMobj->flags2 & MF2_BOSS))) && (BlockingMobj->flags2 & MF2_REFLECTIVE)) || ((BlockingMobj->player == NULL) && (!(BlockingMobj->flags3 & MF3_ISMONSTER))))) { + // Rippers should not bounce off shootable actors, since they rip through them. + if ((mo->flags & MF_MISSILE) && (mo->flags2 & MF2_RIP) && BlockingMobj->flags & MF_SHOOTABLE) + return true; + if (mo->bouncecount>0 && --mo->bouncecount == 0) { if (mo->flags & MF_MISSILE) @@ -3550,6 +3554,7 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) { DAngle angle = BlockingMobj->AngleTo(mo) + ((pr_bounce() % 16) - 8); double speed = mo->VelXYToSpeed() * mo->wallbouncefactor; // [GZ] was 0.75, using wallbouncefactor seems more consistent + if (fabs(speed) < EQUAL_EPSILON) speed = 0; mo->Angles.Yaw = angle; mo->VelFromAngle(speed); mo->PlayBounceSound(true); @@ -3576,7 +3581,7 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) if (mo->BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - mo->Vel.Z -= 2. / dot; + mo->Vel.Z -= 2. * dot; if (!(mo->BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { mo->flags |= MF_INBOUNCE; @@ -3592,7 +3597,7 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) else // Don't run through this for MBF-style bounces { // The reflected velocity keeps only about 70% of its original speed - mo->Vel.Z = (mo->Vel.Z - 2. / dot) * mo->bouncefactor; + mo->Vel.Z = (mo->Vel.Z - 2. * dot) * mo->bouncefactor; } mo->PlayBounceSound(true); diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index a43c741ce..d0b7df449 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -434,8 +434,6 @@ void LoadActors() // PASSMOBJ is irrelevant for normal missiles, but not for bouncers. defaults->flags2 |= MF2_PASSMOBJ; } - - } if (FScriptPosition::ErrorCounter > 0) { diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 4d567d3ca..b1a8172d7 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2170,6 +2170,23 @@ NETMNU_HOSTOPTIONS = "Host options"; NETMNU_EXTRATICS = "Extra Tics"; NETMNU_TICBALANCE = "Latency balancing"; +// Joystick menu + +JOYMNU_ENABLE = "Enable controller support"; +JOYMNU_DINPUT = "Enable DirectInput controllers"; +JOYMNU_XINPUT = "Enable XInput controllers"; +JOYMNU_PS2 = "Enable raw PlayStation 2 adapters"; +JOYMNU_NOCON = "No controllers detected"; +JOYMNU_CONFIG = "Configure controllers:"; +JOYMNU_DISABLED1 = "Controller support must be"; +JOYMNU_DISABLED2 = "enabled to detect any"; +JOYMNU_INVALID = "Invalid controller specified for menu"; +JOYMNU_OVRSENS = "Overall sensitivity"; +JOYMNU_AXIS = "Axis Configuration"; +JOYMNU_INVERT = "Invert"; +JOYMNU_DEADZONE = "Dead zone"; +JOYMNU_NOAXES = "No configurable axes"; + // Option Values OPTVAL_OFF = "Off"; OPTVAL_ON = "On"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 73c19201e..b75e33ead 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -561,7 +561,19 @@ OptionMenu "MouseOptions" OptionMenu "JoystickOptions" { Title "$JOYMNU_OPTIONS" - // Will be filled in by joystick code. + Option "$JOYMNU_ENABLE", "use_joystick", "YesNo" + IfOption(Windows) + { + Option "$JOYMNU_DINPUT", "joy_dinput", "YesNo" + Option "$JOYMNU_XINPUT", "joy_xinput", "YesNo" + Option "$JOYMNU_PS2", "joy_ps2raw", "YesNo" + } + StaticText "" + StaticTextSwitchable "$JOYMNU_NOCON", "$JOYMNU_CONFIG", "ConfigureMessage" + StaticTextSwitchable " ", "$JOYMNU_DISABLED1", "ConnectMessage1" + StaticTextSwitchable " ", "$JOYMNU_DISABLED2", "ConnectMessage2" + + // The rest will be filled in by joystick code if devices get connected or disconnected } OptionValue "JoyAxisMapNames" diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index f0f462880..b423abae6 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -8,13 +8,14 @@ #include "zscript/menu/menuitembase.txt" #include "zscript/menu/menu.txt" +#include "zscript/menu/listmenu.txt" #include "zscript/menu/listmenuitems.txt" #include "zscript/menu/optionmenu.txt" #include "zscript/menu/optionmenuitems.txt" #include "zscript/menu/colorpickermenu.txt" #include "zscript/menu/joystickmenu.txt" #include "zscript/menu/playerdisplay.txt" -#include "zscript/menu/playermenu.txt" +#include "zscript/menu/playercontrols.txt" #include "zscript/menu/textentermenu.txt" #include "zscript/menu/videomenu.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index eee20a04f..e354fe594 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -272,7 +272,6 @@ struct Console native native static void HideConsole(); native static void MidPrint(Font fontname, string textlabel, bool bold = false); native static vararg void Printf(string fmt, ...); - native static void DoCommand(String cmd); } struct DamageTypeDefinition native diff --git a/wadsrc/static/zscript/menu/colorpickermenu.txt b/wadsrc/static/zscript/menu/colorpickermenu.txt index 93a2399a5..d7ed52057 100644 --- a/wadsrc/static/zscript/menu/colorpickermenu.txt +++ b/wadsrc/static/zscript/menu/colorpickermenu.txt @@ -336,7 +336,10 @@ class ColorpickerMenu : OptionMenu if (mStartItem >= 0) { mDesc.mItems.Resize(mStartItem); - if (mCVar != null) mCVar.SetInt(Color(int(mRed), int(mGreen), int(mBlue))); + if (mCVar != null) + { + mCVar.SetInt(Color(int(mRed), int(mGreen), int(mBlue))); + } mStartItem = -1; } } diff --git a/wadsrc/static/zscript/menu/joystickmenu.txt b/wadsrc/static/zscript/menu/joystickmenu.txt index 2e37aadf6..48b5840e7 100644 --- a/wadsrc/static/zscript/menu/joystickmenu.txt +++ b/wadsrc/static/zscript/menu/joystickmenu.txt @@ -40,19 +40,23 @@ class OptionMenuSliderJoySensitivity : OptionMenuSliderBase { - void Init(String label, double min, double max, double step, int showval) + JoystickConfig mJoy; + + OptionMenuSliderJoySensitivity Init(String label, double min, double max, double step, int showval, JoystickConfig joy) { Super.Init(label, min, max, step, showval); + mJoy = joy; + return self; } override double GetSliderValue() { - return Menu.GetCurrentJoystickConfig().GetSensitivity(); + return mJoy.GetSensitivity(); } override void SetSliderValue(double val) { - Menu.GetCurrentJoystickConfig().SetSensitivity(val); + mJoy.SetSensitivity(val); } } @@ -66,24 +70,27 @@ class OptionMenuSliderJoyScale : OptionMenuSliderBase { int mAxis; int mNeg; - - void Init(String label, int axis, double min, double max, double step, int showval) + JoystickConfig mJoy; + + OptionMenuSliderJoyScale Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy) { Super.Init(label, min, max, step, showval); mAxis = axis; mNeg = 1; + mJoy = joy; + return self; } override double GetSliderValue() { - double d = Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis); + double d = mJoy.GetAxisScale(mAxis); mNeg = d < 0? -1:1; return d; } override void SetSliderValue(double val) { - Menu.GetCurrentJoystickConfig().SetAxisScale(mAxis, val * mNeg); + mJoy.SetAxisScale(mAxis, val * mNeg); } } @@ -97,25 +104,27 @@ class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase { int mAxis; int mNeg; - + JoystickConfig mJoy; - void Init(String label, int axis, double min, double max, double step, int showval) + OptionMenuSliderJoyDeadZone Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy) { Super.Init(label, min, max, step, showval); mAxis = axis; mNeg = 1; + mJoy = joy; + return self; } override double GetSliderValue() { - double d = Menu.GetCurrentJoystickConfig().GetAxisDeadZone(mAxis); + double d = mJoy.GetAxisDeadZone(mAxis); mNeg = d < 0? -1:1; return d; } override void SetSliderValue(double val) { - Menu.GetCurrentJoystickConfig().SetAxisDeadZone(mAxis, val * mNeg); + mJoy.SetAxisDeadZone(mAxis, val * mNeg); } } @@ -128,16 +137,19 @@ class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase class OptionMenuItemJoyMap : OptionMenuItemOptionBase { int mAxis; - - void Init(String label, int axis, Name values, int center) + JoystickConfig mJoy; + + OptionMenuItemJoyMap Init(String label, int axis, Name values, int center, JoystickConfig joy) { Super.Init(label, 'none', values, null, center); mAxis = axis; + mJoy = joy; + return self; } override int GetSelection() { - double f = Menu.GetCurrentJoystickConfig().GetAxisMap(mAxis); + double f = mJoy.GetAxisMap(mAxis); let opt = OptionValues.GetCount(mValues); if (opt > 0) { @@ -165,7 +177,7 @@ class OptionMenuItemJoyMap : OptionMenuItemOptionBase { selection = int(OptionValues.GetValue(mValues, selection)); } - Menu.GetCurrentJoystickConfig().SetAxisMap(mAxis, selection); + mJoy.SetAxisMap(mAxis, selection); } } @@ -178,25 +190,27 @@ class OptionMenuItemJoyMap : OptionMenuItemOptionBase class OptionMenuItemInverter : OptionMenuItemOptionBase { int mAxis; - - - void Init(String label, int axis, int center) + JoystickConfig mJoy; + + OptionMenuItemInverter Init(String label, int axis, int center, JoystickConfig joy) { Super.Init(label, "none", "YesNo", NULL, center); mAxis = axis; + mJoy = joy; + return self; } override int GetSelection() { - float f = Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis); + float f = mJoy.GetAxisScale(mAxis); return f > 0? 0:1; } override void SetSelection(int Selection) { - let f = abs(Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis)); + let f = abs(mJoy.GetAxisScale(mAxis)); if (Selection) f*=-1; - Menu.GetCurrentJoystickConfig().SetAxisScale(mAxis, f); + mJoy.SetAxisScale(mAxis, f); } } @@ -209,17 +223,90 @@ class OptionMenuItemInverter : OptionMenuItemOptionBase class OptionMenuItemJoyConfigMenu : OptionMenuItemSubmenu { JoystickConfig mJoy; - - void Init(String label = "", JoystickConfig joy = null) + + OptionMenuItemJoyConfigMenu Init(String label, JoystickConfig joy) { Super.Init(label, "JoystickConfigMenu"); mJoy = joy; + return self; } override bool Activate() { - //UpdateJoystickConfigMenu(mJoy); - return Super.Activate(); + let desc = OptionMenuDescriptor(MenuDescriptor.GetDescriptor('JoystickConfigMenu')); + if (desc != NULL) + { + SetController(OptionMenuDescriptor(desc), mJoy); + } + let res = Super.Activate(); + let joymenu = JoystickConfigMenu(Menu.GetCurrentMenu()); + if (res && joymenu != null) joymenu.mJoy = mJoy; + return res; } + + static void SetController(OptionMenuDescriptor opt, JoystickConfig joy) + { + OptionMenuItem it; + opt.mItems.Clear(); + if (joy == NULL) + { + opt.mTitle = "$JOYMNU_CONFIG"; + it = new("OptionMenuItemStaticText").Init("$JOYMNU_INVALID", false); + opt.mItems.Push(it); + } + else + { + it = new("OptionMenuItemStaticText").Init(joy.GetName(), false); + it = new("OptionMenuItemStaticText").Init("", false); + + it = new("OptionMenuSliderJoySensitivity").Init("$JOYMNU_OVRSENS", 0, 2, 0.1, 3, joy); + opt.mItems.Push(it); + it = new("OptionMenuItemStaticText").Init(" ", false); + opt.mItems.Push(it); + + if (joy.GetNumAxes() > 0) + { + it = new("OptionMenuItemStaticText").Init("$JOYMNU_AXIS", true); + opt.mItems.Push(it); + + for (int i = 0; i < joy.GetNumAxes(); ++i) + { + it = new("OptionMenuItemStaticText").Init(" ", false); + opt.mItems.Push(it); + + it = new("OptionMenuItemJoyMap").Init(joy.GetAxisName(i), i, "JoyAxisMapNames", false, joy); + opt.mItems.Push(it); + it = new("OptionMenuSliderJoyScale").Init("$JOYMNU_OVRSENS", i, 0, 4, 0.1, 3, joy); + opt.mItems.Push(it); + it = new("OptionMenuItemInverter").Init("$JOYMNU_INVERT", i, false, joy); + opt.mItems.Push(it); + it = new("OptionMenuSliderJoyDeadZone").Init("$JOYMNU_DEADZONE", i, 0, 0.9, 0.05, 3, joy); + opt.mItems.Push(it); + } + } + else + { + it = new("OptionMenuItemStaticText").Init("$JOYMNU_NOAXES", false); + opt.mItems.Push(it); + } + } + opt.mScrollPos = 0; + opt.mSelectedItem = -1; + opt.mIndent = 0; + opt.mPosition = -25; + opt.CalcIndent(); + } + +} + +//============================================================================= +// +// +// +//============================================================================= + +class JoystickConfigMenu : OptionMenu +{ + JoystickConfig mJoy; } diff --git a/wadsrc/static/zscript/menu/listmenu.txt b/wadsrc/static/zscript/menu/listmenu.txt new file mode 100644 index 000000000..742089a39 --- /dev/null +++ b/wadsrc/static/zscript/menu/listmenu.txt @@ -0,0 +1,108 @@ + + +class ListMenuDescriptor : MenuDescriptor native +{ + native Array mItems; + native int mSelectedItem; + native int mSelectOfsX; + native int mSelectOfsY; + native TextureID mSelector; + native int mDisplayTop; + native int mXpos, mYpos; + native int mWLeft, mWRight; + native int mLinespacing; // needs to be stored for dynamically created menus + native int mAutoselect; // this can only be set by internal menu creation functions + native Font mFont; + native int mFontColor; + native int mFontColor2; + native bool mCenter; + + void Reset() + { + // Reset the default settings (ignore all other values in the struct) + mSelectOfsX = 0; + mSelectOfsY = 0; + mSelector.SetInvalid(); + mDisplayTop = 0; + mXpos = 0; + mYpos = 0; + mLinespacing = 0; + mNetgameMessage = ""; + mFont = NULL; + mFontColor = Font.CR_UNTRANSLATED; + mFontColor2 = Font.CR_UNTRANSLATED; + } +} + +//============================================================================= +// +// list menu class runs a menu described by a DListMenuDescriptor +// +//============================================================================= + +class ListMenu : Menu native +{ + native ListMenuDescriptor mDesc; + native MenuItemBase mFocusControl; + + virtual void Init(Menu parent = NULL, ListMenuDescriptor desc = NULL) + { + mParentMenu = parent; + mDesc = desc; + if (desc.mCenter) + { + int center = 160; + for(int i=0; i < mDesc.mItems.Size(); i++) + { + int xpos = mDesc.mItems[i].GetX(); + int width = mDesc.mItems[i].GetWidth(); + int curx = mDesc.mSelectOfsX; + + if (width > 0 && mDesc.mItems[i].Selectable()) + { + int left = 160 - (width - curx) / 2 - curx; + if (left < center) center = left; + } + } + for(int i=0;i 0) + { + mDesc.mItems[i].SetX(center); + } + } + } + } + + MenuItemBase GetItem(Name name) + { + for(int i = 0; i < mDesc.mItems.Size(); i++) + { + Name nm = mDesc.mItems[i].GetAction(); + if (nm == name) return mDesc.mItems[i]; + } + return NULL; + } + + //bool Responder (InputEvent ev); + //bool MenuEvent (int mkey, bool fromcontroller); + //bool MouseEvent(int type, int x, int y); + //void Ticker (); + //void Drawer (); + + override void SetFocus(MenuItemBase fc) + { + mFocusControl = fc; + } + override bool CheckFocus(MenuItemBase fc) + { + return mFocusControl == fc; + } + override void ReleaseFocus() + { + mFocusControl = NULL; + } +} + diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index 1d878e112..f0dacb017 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -41,6 +41,11 @@ struct JoystickConfig native native int GetAxisMap(int axis); native void SetAxisMap(int axis, int gameaxis); + + native String GetName(); + native int GetNumAxes(); + native String GetAxisName(int axis); + } class Menu : Object native @@ -91,7 +96,6 @@ class Menu : Object native native static int MenuTime(); native static void SetVideoMode(); native static Menu GetCurrentMenu(); - native static JoystickConfig GetCurrentJoystickConfig(); native static void SetMenu(Name mnu, int param = 0); native static void StartMessage(String msg, int mode = 0, Name command = 'none'); @@ -131,73 +135,3 @@ class MenuDescriptor : Object native native static MenuDescriptor GetDescriptor(Name n); } -class ListMenuDescriptor : MenuDescriptor native -{ - native Array mItems; - native int mSelectedItem; - native int mSelectOfsX; - native int mSelectOfsY; - native TextureID mSelector; - native int mDisplayTop; - native int mXpos, mYpos; - native int mWLeft, mWRight; - native int mLinespacing; // needs to be stored for dynamically created menus - native int mAutoselect; // this can only be set by internal menu creation functions - native Font mFont; - native int mFontColor; - native int mFontColor2; - native bool mCenter; - - void Reset() - { - // Reset the default settings (ignore all other values in the struct) - mSelectOfsX = 0; - mSelectOfsY = 0; - mSelector.SetInvalid(); - mDisplayTop = 0; - mXpos = 0; - mYpos = 0; - mLinespacing = 0; - mNetgameMessage = ""; - mFont = NULL; - mFontColor = Font.CR_UNTRANSLATED; - mFontColor2 = Font.CR_UNTRANSLATED; - } -} - -struct FOptionMenuSettings -{ - int mTitleColor; - int mFontColor; - int mFontColorValue; - int mFontColorMore; - int mFontColorHeader; - int mFontColorHighlight; - int mFontColorSelection; - int mLinespacing; -} - -class OptionMenuDescriptor : MenuDescriptor native -{ - native Array mItems; - native String mTitle; - native int mSelectedItem; - native int mDrawTop; - native int mScrollTop; - native int mScrollPos; - native int mIndent; - native int mPosition; - native bool mDontDim; - - native void CalcIndent(); - //native OptionMenuItem GetItem(Name iname); - void Reset() - { - // Reset the default settings (ignore all other values in the struct) - mPosition = 0; - mScrollTop = 0; - mIndent = 0; - mDontDim = 0; - } -} - diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index 7d2f34c77..5e5b888b1 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -32,6 +32,43 @@ ** */ +struct FOptionMenuSettings +{ + int mTitleColor; + int mFontColor; + int mFontColorValue; + int mFontColorMore; + int mFontColorHeader; + int mFontColorHighlight; + int mFontColorSelection; + int mLinespacing; +} + +class OptionMenuDescriptor : MenuDescriptor native +{ + native Array mItems; + native String mTitle; + native int mSelectedItem; + native int mDrawTop; + native int mScrollTop; + native int mScrollPos; + native int mIndent; + native int mPosition; + native bool mDontDim; + + native void CalcIndent(); + //native OptionMenuItem GetItem(Name iname); + void Reset() + { + // Reset the default settings (ignore all other values in the struct) + mPosition = 0; + mScrollTop = 0; + mIndent = 0; + mDontDim = 0; + } +} + + class OptionMenu : Menu { OptionMenuDescriptor mDesc; @@ -461,9 +498,3 @@ class CompatibilityMenu : OptionMenu DTA_CleanNoMove_1, true); } } - -class JoystickConfigMenu : OptionMenu -{ - // This is not really needed anymore but needs to be kept for old MENUDEFs that keep the entry -} - diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index 4796ce4c9..03aac8f61 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -127,10 +127,18 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu return self; } + private native static void DoCommand(String cmd); // This is very intentionally limited to this menu item to prevent abuse. + override bool Activate() { + // This needs to perform a few checks to prevent abuse by malicious modders. + let m = Menu.GetCurrentMenu(); + // don't execute if no menu is active + if (m == null) return false; + // don't execute if this item cannot be found in the current menu. + if (m.GetItem(mAction) != self) return false; Menu.MenuSound("menu/choose"); - Console.DoCommand(mAction); + DoCommand(mAction); return true; } @@ -158,7 +166,7 @@ class OptionMenuItemSafeCommand : OptionMenuItemCommand { if (mkey == Menu.MKEY_MBYes) { - Console.DoCommand(mAction); + Super.Activate(); return true; } return Super.MenuEvent(mkey, fromcontroller); diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playercontrols.txt similarity index 100% rename from wadsrc/static/zscript/menu/playermenu.txt rename to wadsrc/static/zscript/menu/playercontrols.txt