From f91d91d6e81194010dc9838091dc0fd71403ceaa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Feb 2017 00:36:53 +0100 Subject: [PATCH] - all optionmenu items scriptified, but not integrated yet. --- src/c_bind.cpp | 45 + src/c_cvars.cpp | 50 + src/c_dispatch.cpp | 8 + src/menu/colorpickermenu.cpp | 16 +- src/menu/joystickmenu.cpp | 150 ++- src/menu/menu.cpp | 14 + src/menu/menudef.cpp | 105 +- src/menu/messagebox.cpp | 9 + src/menu/optionmenu.cpp | 9 +- src/menu/optionmenuitems.h | 184 +-- src/menu/videomenu.cpp | 27 +- src/scripting/backend/codegen.cpp | 1 + wadsrc/static/zscript.txt | 6 +- wadsrc/static/zscript/base.txt | 47 + .../static/zscript/menu/colorpickermenu.txt | 41 + wadsrc/static/zscript/menu/joystickmenu.txt | 191 +++ wadsrc/static/zscript/menu/menu.txt | 93 +- wadsrc/static/zscript/menu/menuitembase.txt | 12 +- .../static/zscript/menu/optionmenuitems.txt | 1152 +++++++++++++++++ 19 files changed, 1953 insertions(+), 207 deletions(-) create mode 100644 wadsrc/static/zscript/menu/joystickmenu.txt create mode 100644 wadsrc/static/zscript/menu/optionmenuitems.txt diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 5c1b18323..1c3fd5413 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -44,6 +44,7 @@ #include "i_system.h" #include "d_event.h" #include "w_wad.h" +#include "templates.h" #include #include @@ -261,6 +262,21 @@ static const char *ConfigKeyName(int keynum) // //============================================================================= +DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind) +{ + PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); + PARAM_INT(k); + PARAM_STRING(cmd); + self->SetBind(k, cmd); + return 0; +} + +//============================================================================= +// +// +// +//============================================================================= + void C_NameKeys (char *str, int first, int second) { int c = 0; @@ -284,6 +300,16 @@ void C_NameKeys (char *str, int first, int second) *str = '\0'; } +DEFINE_ACTION_FUNCTION(FKeyBindings, NameKeys) +{ + PARAM_PROLOGUE; + PARAM_INT(k1); + PARAM_INT(k2); + char buffer[120]; + C_NameKeys(buffer, k1, k2); + ACTION_RETURN_STRING(buffer); +} + //============================================================================= // // @@ -445,6 +471,17 @@ int FKeyBindings::GetKeysForCommand (const char *cmd, int *first, int *second) return c; } +DEFINE_ACTION_FUNCTION(FKeyBindings, GetKeysForCommand) +{ + PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); + PARAM_STRING(cmd); + int k1, k2, c; + self->GetKeysForCommand(cmd.GetChars(), &k1, &k2); + if (numret > 0) ret[0].SetInt(k1); + if (numret > 1) ret[1].SetInt(k1); + return MIN(numret, 2); +} + //============================================================================= // // @@ -464,6 +501,14 @@ void FKeyBindings::UnbindACommand (const char *str) } } +DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand) +{ + PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); + PARAM_STRING(cmd); + self->UnbindACommand(cmd); + return 0; +} + //============================================================================= // // diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 768392c6c..ed9b0f29a 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -202,6 +202,36 @@ DEFINE_ACTION_FUNCTION(_CVar, GetString) ACTION_RETURN_STRING(v.String); } +DEFINE_ACTION_FUNCTION(_CVar, SetInt) +{ + PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + PARAM_INT(val); + UCVarValue v; + v.Int = val; + self->SetGenericRep(v, CVAR_Int); + return 0; +} + +DEFINE_ACTION_FUNCTION(_CVar, SetFloat) +{ + PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + PARAM_FLOAT(val); + UCVarValue v; + v.Float = val; + self->SetGenericRep(v, CVAR_Float); + return 0; +} + +DEFINE_ACTION_FUNCTION(_CVar, SetString) +{ + PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + PARAM_STRING(val); + UCVarValue v; + v.String = val.GetChars(); + self->SetGenericRep(v, CVAR_String); + return 0; +} + bool FBaseCVar::ToBool (UCVarValue value, ECVarType type) { switch (type) @@ -643,6 +673,12 @@ void FBaseCVar::DisableCallbacks () m_UseCallback = false; } +DEFINE_ACTION_FUNCTION(_CVar, GetRealType) +{ + PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + ACTION_RETURN_INT(self->GetRealType()); +} + // // Boolean cvar implementation // @@ -1082,6 +1118,13 @@ void FBaseCVar::ResetToDefault () } } +DEFINE_ACTION_FUNCTION(_CVar, ResetToDefault) +{ + PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); + self->ResetToDefault(); + return 0; +} + // // Flag cvar implementation // @@ -1487,6 +1530,13 @@ FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev) return var; } +DEFINE_ACTION_FUNCTION(_CVar, FindCVar) +{ + PARAM_PROLOGUE; + PARAM_NAME(name); + ACTION_RETURN_POINTER(FindCVar(name, nullptr)); +} + FBaseCVar *FindCVarSub (const char *var_name, int namelen) { FBaseCVar *var; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 52ea3d63a..8bd83ed15 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -662,6 +662,14 @@ void C_DoCommand (const char *cmd, int keynum) } } +DEFINE_ACTION_FUNCTION(_Console, DoCommand) +{ + PARAM_PROLOGUE; + PARAM_STRING(cmd); + C_DoCommand(cmd); + return 0; +} + void AddCommandString (char *cmd, int keynum) { char *brkpt; diff --git a/src/menu/colorpickermenu.cpp b/src/menu/colorpickermenu.cpp index 7fc3e2ecd..d337eb82a 100644 --- a/src/menu/colorpickermenu.cpp +++ b/src/menu/colorpickermenu.cpp @@ -81,14 +81,14 @@ public: // This menu uses some featurs that are hard to implement in an external control lump // so it creates its own list of menu items. desc->mItems.Resize(mStartItem+8); - desc->mItems[mStartItem+0] = new DOptionMenuItemStaticText(name, false); - desc->mItems[mStartItem+1] = new DOptionMenuItemStaticText(" ", false); - desc->mItems[mStartItem+2] = new DOptionMenuSliderVar("Red", &mRed, 0, 255, 15, 0); - desc->mItems[mStartItem+3] = new DOptionMenuSliderVar("Green", &mGreen, 0, 255, 15, 0); - desc->mItems[mStartItem+4] = new DOptionMenuSliderVar("Blue", &mBlue, 0, 255, 15, 0); - desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText(" ", false); - desc->mItems[mStartItem+6] = new DOptionMenuItemCommand("Undo changes", "undocolorpic"); - desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText(" ", false); + desc->mItems[mStartItem+0] = new DOptionMenuItemStaticText_(name, false); + desc->mItems[mStartItem+1] = new DOptionMenuItemStaticText_(" ", false); + desc->mItems[mStartItem+2] = new DOptionMenuSliderVar_("Red", &mRed, 0, 255, 15, 0); + desc->mItems[mStartItem+3] = new DOptionMenuSliderVar_("Green", &mGreen, 0, 255, 15, 0); + desc->mItems[mStartItem+4] = new DOptionMenuSliderVar_("Blue", &mBlue, 0, 255, 15, 0); + desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText_(" ", false); + desc->mItems[mStartItem+6] = new DOptionMenuItemCommand_("Undo changes", "undocolorpic"); + desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText_(" ", false); for (auto &p : desc->mItems) { GC::WriteBarrier(p); diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 61f81bb60..50f49463c 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -58,6 +58,74 @@ static TArray Joysticks; IJoystickConfig *SELECTED_JOYSTICK; +DEFINE_ACTION_FUNCTION(DMenu, GetCurrentJoystickConfig) +{ + ACTION_RETURN_POINTER(SELECTED_JOYSTICK); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetSensitivity) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + ACTION_RETURN_FLOAT(self->GetSensitivity()); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, SetSensitivity) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_FLOAT(sens); + self->SetSensitivity((float)sens); + return 0; +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisScale) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + ACTION_RETURN_FLOAT(self->GetAxisScale(axis)); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisScale) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + PARAM_FLOAT(sens); + self->SetAxisScale(axis, (float)sens); + return 0; +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisDeadZone) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + ACTION_RETURN_FLOAT(self->GetAxisDeadZone(axis)); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisDeadZone) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + PARAM_FLOAT(dz); + self->SetAxisDeadZone(axis, (float)dz); + return 0; +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisMap) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + ACTION_RETURN_INT(self->GetAxisMap(axis)); +} + +DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisMap) +{ + PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); + PARAM_INT(axis); + PARAM_INT(map); + self->SetAxisMap(axis, (EJoyAxis)map); + return 0; +} + + DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); //============================================================================= @@ -66,11 +134,11 @@ DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); // //============================================================================= -class DOptionMenuSliderJoySensitivity : public DOptionMenuSliderBase +class DOptionMenuSliderJoySensitivity_ : public DOptionMenuSliderBase_ { public: - DOptionMenuSliderJoySensitivity(const char *label, double min, double max, double step, int showval) - : DOptionMenuSliderBase(label, min, max, step, showval) + DOptionMenuSliderJoySensitivity_(const char *label, double min, double max, double step, int showval) + : DOptionMenuSliderBase_(label, min, max, step, showval) { } @@ -91,14 +159,14 @@ public: // //============================================================================= -class DOptionMenuSliderJoyScale : public DOptionMenuSliderBase +class DOptionMenuSliderJoyScale_ : public DOptionMenuSliderBase_ { int mAxis; int mNeg; public: - DOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval) - : DOptionMenuSliderBase(label, min, max, step, showval) + DOptionMenuSliderJoyScale_(const char *label, int axis, double min, double max, double step, int showval) + : DOptionMenuSliderBase_(label, min, max, step, showval) { mAxis = axis; mNeg = 1; @@ -123,14 +191,14 @@ public: // //============================================================================= -class DOptionMenuSliderJoyDeadZone : public DOptionMenuSliderBase +class DOptionMenuSliderJoyDeadZone_ : public DOptionMenuSliderBase_ { int mAxis; int mNeg; public: - DOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval) - : DOptionMenuSliderBase(label, min, max, step, showval) + DOptionMenuSliderJoyDeadZone_(const char *label, int axis, double min, double max, double step, int showval) + : DOptionMenuSliderBase_(label, min, max, step, showval) { mAxis = axis; mNeg = 1; @@ -155,13 +223,13 @@ public: // //============================================================================= -class DOptionMenuItemJoyMap : public DOptionMenuItemOptionBase +class DOptionMenuItemJoyMap_ : public DOptionMenuItemOptionBase_ { int mAxis; public: - DOptionMenuItemJoyMap(const char *label, int axis, const char *values, int center) - : DOptionMenuItemOptionBase(label, "none", values, NULL, center) + DOptionMenuItemJoyMap_(const char *label, int axis, const char *values, int center) + : DOptionMenuItemOptionBase_(label, "none", values, NULL, center) { mAxis = axis; } @@ -206,13 +274,13 @@ public: // //============================================================================= -class DOptionMenuItemInverter : public DOptionMenuItemOptionBase +class DOptionMenuItemInverter_ : public DOptionMenuItemOptionBase_ { int mAxis; public: - DOptionMenuItemInverter(const char *label, int axis, int center) - : DOptionMenuItemOptionBase(label, "none", "YesNo", NULL, center) + DOptionMenuItemInverter_(const char *label, int axis, int center) + : DOptionMenuItemOptionBase_(label, "none", "YesNo", NULL, center) { mAxis = axis; } @@ -244,13 +312,13 @@ IMPLEMENT_CLASS(DJoystickConfigMenu, false, false) // //============================================================================= -class DOptionMenuItemJoyConfigMenu : public DOptionMenuItemSubmenu +class DOptionMenuItemJoyConfigMenu_ : public DOptionMenuItemSubmenu_ { - DECLARE_CLASS(DOptionMenuItemJoyConfigMenu, DOptionMenuItemSubmenu) + DECLARE_CLASS(DOptionMenuItemJoyConfigMenu_, DOptionMenuItemSubmenu_) IJoystickConfig *mJoy; public: - DOptionMenuItemJoyConfigMenu(const char *label = nullptr, IJoystickConfig *joy = nullptr) - : DOptionMenuItemSubmenu(label, "JoystickConfigMenu") + DOptionMenuItemJoyConfigMenu_(const char *label = nullptr, IJoystickConfig *joy = nullptr) + : DOptionMenuItemSubmenu_(label, "JoystickConfigMenu") { mJoy = joy; } @@ -258,11 +326,11 @@ public: bool Activate() { UpdateJoystickConfigMenu(mJoy); - return DOptionMenuItemSubmenu::Activate(); + return DOptionMenuItemSubmenu_::Activate(); } }; -IMPLEMENT_CLASS(DOptionMenuItemJoyConfigMenu, false, false) +IMPLEMENT_CLASS(DOptionMenuItemJoyConfigMenu_, false, false) /*======================================= @@ -282,7 +350,7 @@ DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) if (joy == NULL) { opt->mTitle = "Configure Controller"; - it = new DOptionMenuItemStaticText("Invalid controller specified for menu", false); + it = new DOptionMenuItemStaticText_("Invalid controller specified for menu", false); opt->mItems.Push(it); } else @@ -291,34 +359,34 @@ DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) SELECTED_JOYSTICK = joy; - it = new DOptionMenuSliderJoySensitivity("Overall sensitivity", 0, 2, 0.1, 3); + it = new DOptionMenuSliderJoySensitivity_("Overall sensitivity", 0, 2, 0.1, 3); opt->mItems.Push(it); - it = new DOptionMenuItemStaticText(" ", false); + it = new DOptionMenuItemStaticText_(" ", false); opt->mItems.Push(it); if (joy->GetNumAxes() > 0) { - it = new DOptionMenuItemStaticText("Axis Configuration", true); + it = new DOptionMenuItemStaticText_("Axis Configuration", true); opt->mItems.Push(it); for (int i = 0; i < joy->GetNumAxes(); ++i) { - it = new DOptionMenuItemStaticText(" ", false); + it = new DOptionMenuItemStaticText_(" ", false); opt->mItems.Push(it); - it = new DOptionMenuItemJoyMap(joy->GetAxisName(i), i, "JoyAxisMapNames", false); + it = new DOptionMenuItemJoyMap_(joy->GetAxisName(i), i, "JoyAxisMapNames", false); opt->mItems.Push(it); - it = new DOptionMenuSliderJoyScale("Overall sensitivity", i, 0, 4, 0.1, 3); + it = new DOptionMenuSliderJoyScale_("Overall sensitivity", i, 0, 4, 0.1, 3); opt->mItems.Push(it); - it = new DOptionMenuItemInverter("Invert", i, false); + it = new DOptionMenuItemInverter_("Invert", i, false); opt->mItems.Push(it); - it = new DOptionMenuSliderJoyDeadZone("Dead Zone", i, 0, 0.9, 0.05, 3); + it = new DOptionMenuSliderJoyDeadZone_("Dead Zone", i, 0, 0.9, 0.05, 3); opt->mItems.Push(it); } } else { - it = new DOptionMenuItemStaticText("No configurable axes", false); + it = new DOptionMenuItemStaticText_("No configurable axes", false); opt->mItems.Push(it); } } @@ -368,40 +436,40 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } // Todo: Block joystick for changing this one. - it = new DOptionMenuItemOption("Enable controller support", "use_joystick", "YesNo", NULL, false); + it = new DOptionMenuItemOption_("Enable controller support", "use_joystick", "YesNo", NULL, false); opt->mItems.Push(it); #ifdef _WIN32 - it = new DOptionMenuItemOption("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); + it = new DOptionMenuItemOption_("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); opt->mItems.Push(it); - it = new DOptionMenuItemOption("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); + it = new DOptionMenuItemOption_("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); opt->mItems.Push(it); - it = new DOptionMenuItemOption("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); + it = new DOptionMenuItemOption_("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); opt->mItems.Push(it); #endif - it = new DOptionMenuItemStaticText(" ", false); + it = new DOptionMenuItemStaticText_(" ", false); opt->mItems.Push(it); if (Joysticks.Size() == 0) { - it = new DOptionMenuItemStaticText("No controllers detected", false); + it = new DOptionMenuItemStaticText_("No controllers detected", false); opt->mItems.Push(it); if (!use_joystick) { - it = new DOptionMenuItemStaticText("Controller support must be", false); + it = new DOptionMenuItemStaticText_("Controller support must be", false); opt->mItems.Push(it); - it = new DOptionMenuItemStaticText("enabled to detect any", false); + it = new DOptionMenuItemStaticText_("enabled to detect any", false); opt->mItems.Push(it); } } else { - it = new DOptionMenuItemStaticText("Configure controllers:", false); + it = new DOptionMenuItemStaticText_("Configure controllers:", false); opt->mItems.Push(it); for (int i = 0; i < (int)Joysticks.Size(); ++i) { - it = new DOptionMenuItemJoyConfigMenu(Joysticks[i]->GetName(), Joysticks[i]); + it = new DOptionMenuItemJoyConfigMenu_(Joysticks[i]->GetName(), Joysticks[i]); opt->mItems.Push(it); if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 1f3ac189e..62ea9daa3 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -70,6 +70,12 @@ CVAR(Int, m_use_mouse, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) DMenu *DMenu::CurrentMenu; + +DEFINE_ACTION_FUNCTION(DMenu, GetCurrentMenu) +{ + ACTION_RETURN_POINTER(DMenu::CurrentMenu); +} + int DMenu::MenuTime; FGameStartup GameStartupInfo; @@ -559,6 +565,14 @@ void M_SetMenu(FName menu, int param) M_ClearMenus(); } +DEFINE_ACTION_FUNCTION(DMenu, SetMenu) +{ + PARAM_PROLOGUE; + PARAM_NAME(menu); + PARAM_INT(mparam); + M_SetMenu(menu, mparam); + return 0; +} //============================================================================= // // diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 835189317..1a7657676 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -54,6 +54,8 @@ #include "optionmenuitems.h" + + void ClearSaveGames(); MenuDescriptorList MenuDescriptors; @@ -65,6 +67,71 @@ bool mustPrintErrors; void I_BuildALDeviceList(FOptionValues *opt); +DEFINE_ACTION_FUNCTION(FOptionValues, GetCount) +{ + PARAM_PROLOGUE; + PARAM_NAME(grp); + int cnt = 0; + FOptionValues **pGrp = OptionValues.CheckKey(grp); + if (pGrp != nullptr) + { + cnt = (*pGrp)->mValues.Size(); + } + ACTION_RETURN_INT(cnt); +} + +DEFINE_ACTION_FUNCTION(FOptionValues, GetValue) +{ + PARAM_PROLOGUE; + PARAM_NAME(grp); + PARAM_UINT(index); + double val = 0; + FOptionValues **pGrp = OptionValues.CheckKey(grp); + if (pGrp != nullptr) + { + if (index < (*pGrp)->mValues.Size()) + { + val = (*pGrp)->mValues[index].Value; + } + } + ACTION_RETURN_FLOAT(val); +} + +DEFINE_ACTION_FUNCTION(FOptionValues, GetTextValue) +{ + PARAM_PROLOGUE; + PARAM_NAME(grp); + PARAM_UINT(index); + FString val; + FOptionValues **pGrp = OptionValues.CheckKey(grp); + if (pGrp != nullptr) + { + if (index < (*pGrp)->mValues.Size()) + { + val = (*pGrp)->mValues[index].TextValue; + } + } + ACTION_RETURN_STRING(val); +} + +DEFINE_ACTION_FUNCTION(FOptionValues, GetText) +{ + PARAM_PROLOGUE; + PARAM_NAME(grp); + PARAM_UINT(index); + FString val; + FOptionValues **pGrp = OptionValues.CheckKey(grp); + if (pGrp != nullptr) + { + if (index < (*pGrp)->mValues.Size()) + { + val = (*pGrp)->mValues[index].Text; + } + } + ACTION_RETURN_STRING(val); +} + + static void DeinitMenus() { { @@ -724,7 +791,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemSubmenu(label, sc.String); + DOptionMenuItem *it = new DOptionMenuItemSubmenu_(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("Option")) @@ -749,7 +816,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) center = sc.Number; } } - DOptionMenuItem *it = new DOptionMenuItemOption(label, cvar, values, check, center); + DOptionMenuItem *it = new DOptionMenuItemOption_(label, cvar, values, check, center); desc->mItems.Push(it); } else if (sc.Compare("Command")) @@ -758,7 +825,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemCommand(label, sc.String); + DOptionMenuItem *it = new DOptionMenuItemCommand_(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("SafeCommand")) @@ -775,7 +842,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) sc.MustGetString(); prompt = sc.String; } - DOptionMenuItem *it = new DOptionMenuItemSafeCommand(label, command, prompt); + DOptionMenuItem *it = new DOptionMenuItemSafeCommand_(label, command, prompt); desc->mItems.Push(it); } else if (sc.Compare("Control") || sc.Compare("MapControl")) @@ -785,7 +852,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemControl(label, sc.String, map? &AutomapBindings : &Bindings); + DOptionMenuItem *it = new DOptionMenuItemControl_(label, sc.String, map? &AutomapBindings : &Bindings); desc->mItems.Push(it); } else if (sc.Compare("ColorPicker")) @@ -794,7 +861,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemColorPicker(label, sc.String); + DOptionMenuItem *it = new DOptionMenuItemColorPicker_(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("StaticText")) @@ -802,7 +869,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) sc.MustGetString(); FString label = sc.String; EColorRange cr = ParseOptionColor(sc, desc); - DOptionMenuItem *it = new DOptionMenuItemStaticText(label, cr); + DOptionMenuItem *it = new DOptionMenuItemStaticText_(label, cr); desc->mItems.Push(it); } else if (sc.Compare("StaticTextSwitchable")) @@ -816,7 +883,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) sc.MustGetString(); FName action = sc.String; EColorRange cr = ParseOptionColor(sc, desc); - DOptionMenuItem *it = new DOptionMenuItemStaticTextSwitchable(label, label2, action, cr); + DOptionMenuItem *it = new DOptionMenuItemStaticTextSwitchable_(label, label2, action, cr); desc->mItems.Push(it); } else if (sc.Compare("Slider")) @@ -841,13 +908,13 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) sc.MustGetNumber(); showvalue = sc.Number; } - DOptionMenuItem *it = new DOptionMenuSliderCVar(text, action, min, max, step, showvalue); + DOptionMenuItem *it = new DOptionMenuSliderCVar_(text, action, min, max, step, showvalue); desc->mItems.Push(it); } else if (sc.Compare("screenresolution")) { sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuScreenResolutionLine(sc.String); + DOptionMenuItem *it = new DOptionMenuScreenResolutionLine_(sc.String); desc->mItems.Push(it); } // [TP] -- Text input widget @@ -866,7 +933,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) check = sc.String; } - DOptionMenuItem* it = new DOptionMenuTextField( label, cvar, check ); + DOptionMenuItem* it = new DOptionMenuTextField_( label, cvar, check ); desc->mItems.Push( it ); } // [TP] -- Number input widget @@ -903,7 +970,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) } } - DOptionMenuItem* it = new DOptionMenuNumberField( label, cvar, + DOptionMenuItem* it = new DOptionMenuNumberField_( label, cvar, minimum, maximum, step, check ); desc->mItems.Push( it ); } @@ -1118,7 +1185,7 @@ static void BuildEpisodeMenu() GC::WriteBarrier(od); for(unsigned i = 0; i < AllEpisodes.Size(); i++) { - DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); + DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_(AllEpisodes[i].mEpisodeName, "Skillmenu", i); od->mItems.Push(it); GC::WriteBarrier(od, it); } @@ -1257,13 +1324,13 @@ static void BuildPlayerclassMenu() const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); if (pname != nullptr) { - DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i); + DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_(pname, "Episodemenu", i); od->mItems.Push(it); GC::WriteBarrier(od, it); } } } - DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1); + DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_("Random", "Episodemenu", -1); od->mItems.Push(it); GC::WriteBarrier(od, it); } @@ -1344,14 +1411,14 @@ static void InitKeySections() for (unsigned i = 0; i < KeySections.Size(); i++) { FKeySection *sect = &KeySections[i]; - DOptionMenuItem *item = new DOptionMenuItemStaticText(" ", false); + DOptionMenuItem *item = new DOptionMenuItemStaticText_(" ", false); menu->mItems.Push(item); - item = new DOptionMenuItemStaticText(sect->mTitle, true); + item = new DOptionMenuItemStaticText_(sect->mTitle, true); menu->mItems.Push(item); for (unsigned j = 0; j < sect->mActions.Size(); j++) { FKeyAction *act = §->mActions[j]; - item = new DOptionMenuItemControl(act->mTitle, act->mAction, &Bindings); + item = new DOptionMenuItemControl_(act->mTitle, act->mAction, &Bindings); menu->mItems.Push(item); } } @@ -1542,7 +1609,7 @@ fail: { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } - li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); + li = new DOptionMenuItemSubmenu_(pItemText? *pItemText : skill.MenuName, action, i); od->mItems.Push(li); GC::WriteBarrier(od, li); if (!done) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 8494d2192..a910ad3ad 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -725,3 +725,12 @@ void M_StartMessage(const char *message, int messagemode, FName action) M_ActivateMenu(newmenu); } +DEFINE_ACTION_FUNCTION(DMenu, StartMessage) +{ + PARAM_PROLOGUE; + PARAM_STRING(msg); + PARAM_INT(mode); + PARAM_NAME_DEF(action); + M_StartMessage(msg, mode, action); + return 0; +} \ No newline at end of file diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 40524ac0c..a7f4acc7f 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -64,6 +64,7 @@ void M_DrawConText (int color, int x, int y, const char *str) TAG_DONE); } + IMPLEMENT_CLASS(DOptionMenu, false, false) IMPLEMENT_POINTERS_START(DOptionMenu) @@ -475,13 +476,6 @@ void DOptionMenu::Drawer () Super::Drawer(); } - -//============================================================================= -// -// base class for menu items -// -//============================================================================= - int DOptionMenuItem::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { return indent; @@ -527,7 +521,6 @@ void DOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool graye } - void DOptionMenuDescriptor::CalcIndent() { // calculate the menu indent diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index a7c16ec8c..6b3fd2e26 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -46,15 +46,15 @@ void M_SetVideoMode(); // //============================================================================= -class DOptionMenuItemSubmenu : public DOptionMenuItem +class DOptionMenuItemSubmenu_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuItemSubmenu, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuItemSubmenu_, DOptionMenuItem) int mParam; protected: - DOptionMenuItemSubmenu() { } + DOptionMenuItemSubmenu_() { } public: - DOptionMenuItemSubmenu(const char *label, const char *menu, int param = 0) + DOptionMenuItemSubmenu_(const char *label, const char *menu, int param = 0) : DOptionMenuItem(label, menu) { mParam = param; @@ -75,7 +75,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemSubmenu, false, false) +IMPLEMENT_CLASS(DOptionMenuItemSubmenu_, false, false) #endif //============================================================================= @@ -84,14 +84,14 @@ IMPLEMENT_CLASS(DOptionMenuItemSubmenu, false, false) // //============================================================================= -class DOptionMenuItemCommand : public DOptionMenuItemSubmenu +class DOptionMenuItemCommand_ : public DOptionMenuItemSubmenu_ { - DECLARE_CLASS(DOptionMenuItemCommand, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuItemCommand_, DOptionMenuItem) protected: - DOptionMenuItemCommand() { } + DOptionMenuItemCommand_() { } public: - DOptionMenuItemCommand(const char *label, const char *menu) - : DOptionMenuItemSubmenu(label, menu) + DOptionMenuItemCommand_(const char *label, const char *menu) + : DOptionMenuItemSubmenu_(label, menu) { } @@ -105,7 +105,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemCommand, false, false) +IMPLEMENT_CLASS(DOptionMenuItemCommand_, false, false) #endif //============================================================================= @@ -114,17 +114,17 @@ IMPLEMENT_CLASS(DOptionMenuItemCommand, false, false) // //============================================================================= -class DOptionMenuItemSafeCommand : public DOptionMenuItemCommand +class DOptionMenuItemSafeCommand_ : public DOptionMenuItemCommand_ { - DECLARE_CLASS(DOptionMenuItemSafeCommand, DOptionMenuItemCommand) + DECLARE_CLASS(DOptionMenuItemSafeCommand_, DOptionMenuItemCommand_) // action is a CCMD - DOptionMenuItemSafeCommand() { } + DOptionMenuItemSafeCommand_() { } protected: FString mPrompt; public: - DOptionMenuItemSafeCommand(const char *label, const char *menu, const char *prompt) - : DOptionMenuItemCommand(label, menu) + DOptionMenuItemSafeCommand_(const char *label, const char *menu, const char *prompt) + : DOptionMenuItemCommand_(label, menu) , mPrompt(prompt) { } @@ -136,7 +136,7 @@ public: C_DoCommand(mAction); return true; } - return DOptionMenuItemCommand::MenuEvent(mkey, fromcontroller); + return DOptionMenuItemCommand_::MenuEvent(mkey, fromcontroller); } bool Activate() @@ -165,7 +165,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemSafeCommand, false, false) +IMPLEMENT_CLASS(DOptionMenuItemSafeCommand_, false, false) #endif //============================================================================= @@ -174,16 +174,16 @@ IMPLEMENT_CLASS(DOptionMenuItemSafeCommand, false, false) // //============================================================================= -class DOptionMenuItemOptionBase : public DOptionMenuItem +class DOptionMenuItemOptionBase_ : public DOptionMenuItem { - DECLARE_ABSTRACT_CLASS(DOptionMenuItemOptionBase, DOptionMenuItem) + DECLARE_ABSTRACT_CLASS(DOptionMenuItemOptionBase_, DOptionMenuItem) protected: // action is a CVAR FName mValues; // Entry in OptionValues table FBaseCVar *mGrayCheck; int mCenter; - DOptionMenuItemOptionBase() {} + DOptionMenuItemOptionBase_() {} public: enum @@ -191,7 +191,7 @@ public: OP_VALUES = 0x11001 }; - DOptionMenuItemOptionBase(const char *label, const char *menu, const char *values, const char *graycheck, int center) + DOptionMenuItemOptionBase_(const char *label, const char *menu, const char *values, const char *graycheck, int center) : DOptionMenuItem(label, menu) { mValues = values; @@ -286,7 +286,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemOptionBase, true, false) +IMPLEMENT_CLASS(DOptionMenuItemOptionBase_, true, false) #endif //============================================================================= @@ -295,17 +295,17 @@ IMPLEMENT_CLASS(DOptionMenuItemOptionBase, true, false) // //============================================================================= -class DOptionMenuItemOption : public DOptionMenuItemOptionBase +class DOptionMenuItemOption_ : public DOptionMenuItemOptionBase_ { - DECLARE_CLASS(DOptionMenuItemOption, DOptionMenuItemOptionBase) + DECLARE_CLASS(DOptionMenuItemOption_, DOptionMenuItemOptionBase_) // action is a CVAR FBaseCVar *mCVar; - DOptionMenuItemOption() {} + DOptionMenuItemOption_() {} public: - DOptionMenuItemOption(const char *label, const char *menu, const char *values, const char *graycheck, int center) - : DOptionMenuItemOptionBase(label, menu, values, graycheck, center) + DOptionMenuItemOption_(const char *label, const char *menu, const char *values, const char *graycheck, int center) + : DOptionMenuItemOptionBase_(label, menu, values, graycheck, center) { mCVar = FindCVar(mAction, NULL); } @@ -367,7 +367,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemOption, false, false) +IMPLEMENT_CLASS(DOptionMenuItemOption_, false, false) #endif //============================================================================= @@ -440,17 +440,17 @@ IMPLEMENT_CLASS(DEnterKey, true, false) // //============================================================================= -class DOptionMenuItemControl : public DOptionMenuItem +class DOptionMenuItemControl_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuItemControl, DOptionMenuItemOption) + DECLARE_CLASS(DOptionMenuItemControl_, DOptionMenuItemOption_) FKeyBindings *mBindings; int mInput; bool mWaiting; - DOptionMenuItemControl() {} + DOptionMenuItemControl_() {} public: - DOptionMenuItemControl(const char *label, const char *menu, FKeyBindings *bindings) + DOptionMenuItemControl_(const char *label, const char *menu, FKeyBindings *bindings) : DOptionMenuItem(label, menu) { mBindings = bindings; @@ -514,7 +514,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemControl, false, false) +IMPLEMENT_CLASS(DOptionMenuItemControl_, false, false) #endif //============================================================================= // @@ -522,20 +522,20 @@ IMPLEMENT_CLASS(DOptionMenuItemControl, false, false) // //============================================================================= -class DOptionMenuItemStaticText : public DOptionMenuItem +class DOptionMenuItemStaticText_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuItemStaticText, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuItemStaticText_, DOptionMenuItem) EColorRange mColor; - DOptionMenuItemStaticText() {} + DOptionMenuItemStaticText_() {} public: - DOptionMenuItemStaticText(const char *label, bool header) + DOptionMenuItemStaticText_(const char *label, bool header) : DOptionMenuItem(label, NAME_None, true) { mColor = header ? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; } - DOptionMenuItemStaticText(const char *label, EColorRange cr) + DOptionMenuItemStaticText_(const char *label, EColorRange cr) : DOptionMenuItem(label, NAME_None, true) { mColor = cr; @@ -555,7 +555,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemStaticText, false, false) +IMPLEMENT_CLASS(DOptionMenuItemStaticText_, false, false) #endif //============================================================================= @@ -564,16 +564,16 @@ IMPLEMENT_CLASS(DOptionMenuItemStaticText, false, false) // //============================================================================= -class DOptionMenuItemStaticTextSwitchable : public DOptionMenuItem +class DOptionMenuItemStaticTextSwitchable_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuItemStaticTextSwitchable, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuItemStaticTextSwitchable_, DOptionMenuItem) EColorRange mColor; FString mAltText; int mCurrent; - DOptionMenuItemStaticTextSwitchable() {} + DOptionMenuItemStaticTextSwitchable_() {} public: - DOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, EColorRange cr) + DOptionMenuItemStaticTextSwitchable_(const char *label, const char *label2, FName action, EColorRange cr) : DOptionMenuItem(label, action, true) { mColor = cr; @@ -618,7 +618,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemStaticTextSwitchable, false, false) +IMPLEMENT_CLASS(DOptionMenuItemStaticTextSwitchable_, false, false) #endif //============================================================================= @@ -627,9 +627,9 @@ IMPLEMENT_CLASS(DOptionMenuItemStaticTextSwitchable, false, false) // //============================================================================= -class DOptionMenuSliderBase : public DOptionMenuItem +class DOptionMenuSliderBase_ : public DOptionMenuItem { - DECLARE_ABSTRACT_CLASS(DOptionMenuSliderBase, DOptionMenuItem) + DECLARE_ABSTRACT_CLASS(DOptionMenuSliderBase_, DOptionMenuItem) // action is a CVAR double mMin, mMax, mStep; int mShowValue; @@ -637,9 +637,9 @@ class DOptionMenuSliderBase : public DOptionMenuItem int mSliderShort; protected: - DOptionMenuSliderBase() {} + DOptionMenuSliderBase_() {} public: - DOptionMenuSliderBase(const char *label, double min, double max, double step, int showval) + DOptionMenuSliderBase_(const char *label, double min, double max, double step, int showval) : DOptionMenuItem(label, NAME_None) { mMin = min; @@ -768,7 +768,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderBase, true, false) +IMPLEMENT_CLASS(DOptionMenuSliderBase_, true, false) #endif //============================================================================= @@ -777,15 +777,15 @@ IMPLEMENT_CLASS(DOptionMenuSliderBase, true, false) // //============================================================================= -class DOptionMenuSliderCVar : public DOptionMenuSliderBase +class DOptionMenuSliderCVar_ : public DOptionMenuSliderBase_ { - DECLARE_CLASS(DOptionMenuSliderCVar, DOptionMenuSliderBase) + DECLARE_CLASS(DOptionMenuSliderCVar_, DOptionMenuSliderBase_) FBaseCVar *mCVar; - DOptionMenuSliderCVar() {} + DOptionMenuSliderCVar_() {} public: - DOptionMenuSliderCVar(const char *label, const char *menu, double min, double max, double step, int showval) - : DOptionMenuSliderBase(label, min, max, step, showval) + DOptionMenuSliderCVar_(const char *label, const char *menu, double min, double max, double step, int showval) + : DOptionMenuSliderBase_(label, min, max, step, showval) { mCVar = FindCVar(menu, NULL); } @@ -814,7 +814,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderCVar, false, false) +IMPLEMENT_CLASS(DOptionMenuSliderCVar_, false, false) #endif //============================================================================= @@ -823,16 +823,16 @@ IMPLEMENT_CLASS(DOptionMenuSliderCVar, false, false) // //============================================================================= -class DOptionMenuSliderVar : public DOptionMenuSliderBase +class DOptionMenuSliderVar_ : public DOptionMenuSliderBase_ { - DECLARE_CLASS(DOptionMenuSliderVar, DOptionMenuSliderBase) + DECLARE_CLASS(DOptionMenuSliderVar_, DOptionMenuSliderBase_) float *mPVal; - DOptionMenuSliderVar() {} + DOptionMenuSliderVar_() {} public: - DOptionMenuSliderVar(const char *label, float *pVal, double min, double max, double step, int showval) - : DOptionMenuSliderBase(label, min, max, step, showval) + DOptionMenuSliderVar_(const char *label, float *pVal, double min, double max, double step, int showval) + : DOptionMenuSliderBase_(label, min, max, step, showval) { mPVal = pVal; } @@ -849,7 +849,7 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderVar, false, false) +IMPLEMENT_CLASS(DOptionMenuSliderVar_, false, false) #endif //============================================================================= @@ -858,12 +858,12 @@ IMPLEMENT_CLASS(DOptionMenuSliderVar, false, false) // //============================================================================= -class DOptionMenuItemColorPicker : public DOptionMenuItem +class DOptionMenuItemColorPicker_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuItemColorPicker, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuItemColorPicker_, DOptionMenuItem) FColorCVar *mCVar; - DOptionMenuItemColorPicker() {} + DOptionMenuItemColorPicker_() {} public: enum @@ -871,7 +871,7 @@ public: CPF_RESET = 0x20001, }; - DOptionMenuItemColorPicker(const char *label, const char *menu) + DOptionMenuItemColorPicker_(const char *label, const char *menu) : DOptionMenuItem(label, menu) { FBaseCVar *cv = FindCVar(menu, NULL); @@ -924,19 +924,19 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemColorPicker, false, false) +IMPLEMENT_CLASS(DOptionMenuItemColorPicker_, false, false) #endif -class DOptionMenuScreenResolutionLine : public DOptionMenuItem +class DOptionMenuScreenResolutionLine_ : public DOptionMenuItem { - DECLARE_CLASS(DOptionMenuScreenResolutionLine, DOptionMenuItem) + DECLARE_CLASS(DOptionMenuScreenResolutionLine_, DOptionMenuItem) FString mResTexts[3]; int mSelection; int mHighlight; int mMaxValid; - DOptionMenuScreenResolutionLine() {} + DOptionMenuScreenResolutionLine_() {} public: enum @@ -946,7 +946,7 @@ public: SRL_HIGHLIGHT = 0x30004, }; - DOptionMenuScreenResolutionLine(const char *action) + DOptionMenuScreenResolutionLine_(const char *action) : DOptionMenuItem("", action) { mSelection = 0; @@ -1072,25 +1072,25 @@ public: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuScreenResolutionLine, false, false) +IMPLEMENT_CLASS(DOptionMenuScreenResolutionLine_, false, false) #endif //============================================================================= // -// [TP] DOptionMenuFieldBase +// [TP] DOptionMenuFieldBase_ // // Base class for input fields // //============================================================================= -class DOptionMenuFieldBase : public DOptionMenuItem +class DOptionMenuFieldBase_ : public DOptionMenuItem { - DECLARE_ABSTRACT_CLASS(DOptionMenuFieldBase, DOptionMenuItem) + DECLARE_ABSTRACT_CLASS(DOptionMenuFieldBase_, DOptionMenuItem) protected: - DOptionMenuFieldBase() {} + DOptionMenuFieldBase_() {} public: - DOptionMenuFieldBase ( const char* label, const char* menu, const char* graycheck ) : + DOptionMenuFieldBase_ ( const char* label, const char* menu, const char* graycheck ) : DOptionMenuItem ( label, menu ), mCVar ( FindCVar( mAction, NULL )), mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {} @@ -1155,25 +1155,25 @@ protected: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuFieldBase, true, false) +IMPLEMENT_CLASS(DOptionMenuFieldBase_, true, false) #endif //============================================================================= // -// [TP] DOptionMenuTextField +// [TP] DOptionMenuTextField_ // // A text input field widget, for use with string CVars. // //============================================================================= -class DOptionMenuTextField : public DOptionMenuFieldBase +class DOptionMenuTextField_ : public DOptionMenuFieldBase_ { - DECLARE_CLASS(DOptionMenuTextField, DOptionMenuFieldBase) + DECLARE_CLASS(DOptionMenuTextField_, DOptionMenuFieldBase_) - DOptionMenuTextField() {} + DOptionMenuTextField_() {} public: - DOptionMenuTextField ( const char *label, const char* menu, const char* graycheck ) : - DOptionMenuFieldBase ( label, menu, graycheck ), + DOptionMenuTextField_ ( const char *label, const char* menu, const char* graycheck ) : + DOptionMenuFieldBase_ ( label, menu, graycheck ), mEntering ( false ) {} FString Represent() @@ -1196,7 +1196,7 @@ public: int newindent = screen->GetWidth() - tlen - CURSORSPACE; if (newindent < indent) indent = newindent; } - return DOptionMenuFieldBase::Draw(desc, y, indent, selected); + return DOptionMenuFieldBase_::Draw(desc, y, indent, selected); } bool MenuEvent ( int mkey, bool fromcontroller ) @@ -1237,7 +1237,7 @@ private: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuTextField, false, false) +IMPLEMENT_CLASS(DOptionMenuTextField_, false, false) #endif //============================================================================= @@ -1249,15 +1249,15 @@ IMPLEMENT_CLASS(DOptionMenuTextField, false, false) // //============================================================================= -class DOptionMenuNumberField : public DOptionMenuFieldBase +class DOptionMenuNumberField_ : public DOptionMenuFieldBase_ { - DECLARE_CLASS(DOptionMenuNumberField, DOptionMenuFieldBase) + DECLARE_CLASS(DOptionMenuNumberField_, DOptionMenuFieldBase_) - DOptionMenuNumberField() {} + DOptionMenuNumberField_() {} public: - DOptionMenuNumberField ( const char *label, const char* menu, float minimum, float maximum, + DOptionMenuNumberField_ ( const char *label, const char* menu, float minimum, float maximum, float step, const char* graycheck ) - : DOptionMenuFieldBase ( label, menu, graycheck ), + : DOptionMenuFieldBase_ ( label, menu, graycheck ), mMinimum ( minimum ), mMaximum ( maximum ), mStep ( step ) @@ -1308,5 +1308,5 @@ private: }; #ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuNumberField, false, false) +IMPLEMENT_CLASS(DOptionMenuNumberField_, false, false) #endif diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 6737f832e..882e8b593 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -109,11 +109,11 @@ CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (self) { - it->SetString(DOptionMenuItemOptionBase::OP_VALUES, "RatiosTFT"); + it->SetString(DOptionMenuItemOptionBase_::OP_VALUES, "RatiosTFT"); } else { - it->SetString(DOptionMenuItemOptionBase::OP_VALUES, "Ratios"); + it->SetString(DOptionMenuItemOptionBase_::OP_VALUES, "Ratios"); } } } @@ -148,9 +148,9 @@ public: mDesc->mSelectedItem < (int)mDesc->mItems.Size()) { int sel; - bool selected = mDesc->mItems[mDesc->mSelectedItem]->GetValue(DOptionMenuScreenResolutionLine::SRL_SELECTION, &sel); + bool selected = mDesc->mItems[mDesc->mSelectedItem]->GetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, &sel); bool res = Super::MenuEvent(mkey, fromcontroller); - if (selected) mDesc->mItems[mDesc->mSelectedItem]->SetValue(DOptionMenuScreenResolutionLine::SRL_SELECTION, sel); + if (selected) mDesc->mItems[mDesc->mSelectedItem]->SetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, sel); return res; } return Super::MenuEvent(mkey, fromcontroller); @@ -239,7 +239,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) DOptionMenuItem *it = opt->GetItem((ENamedName)i); if (it != NULL) { - it->SetValue(DOptionMenuScreenResolutionLine::SRL_HIGHLIGHT, -1); + it->SetValue(DOptionMenuScreenResolutionLine_::SRL_HIGHLIGHT, -1); for (c = 0; c < 3; c++) { bool haveMode = false; @@ -260,16 +260,16 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) { if (width == hiwidth && height == hiheight) { - it->SetValue(DOptionMenuScreenResolutionLine::SRL_SELECTION, c); - it->SetValue(DOptionMenuScreenResolutionLine::SRL_HIGHLIGHT, c); + it->SetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, c); + it->SetValue(DOptionMenuScreenResolutionLine_::SRL_HIGHLIGHT, c); } mysnprintf (strtemp, countof(strtemp), "%dx%d%s", width, height, letterbox?TEXTCOLOR_BROWN" LB":""); - it->SetString(DOptionMenuScreenResolutionLine::SRL_INDEX+c, strtemp); + it->SetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+c, strtemp); } else { - it->SetString(DOptionMenuScreenResolutionLine::SRL_INDEX+c, ""); + it->SetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+c, ""); } } } @@ -360,11 +360,11 @@ static bool GetSelectedSize (int *width, int *height) int line = opt->mSelectedItem; int hsel; DOptionMenuItem *it = opt->mItems[line]; - if (it->GetValue(DOptionMenuScreenResolutionLine::SRL_SELECTION, &hsel)) + if (it->GetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, &hsel)) { char buffer[32]; char *breakpt; - if (it->GetString(DOptionMenuScreenResolutionLine::SRL_INDEX+hsel, buffer, sizeof(buffer))) + if (it->GetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+hsel, buffer, sizeof(buffer))) { *width = (int)strtoll (buffer, &breakpt, 10); *height = (int)strtoll (breakpt+1, NULL, 10); @@ -397,6 +397,11 @@ void M_SetVideoMode() SetModesMenu (NewWidth, NewHeight, NewBits); } +DEFINE_ACTION_FUNCTION(DMenu, SetVideoMode) +{ + M_SetVideoMode(); + return 0; +} //============================================================================= // // diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 1307693cf..eb4ed2e47 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -154,6 +154,7 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos) { if (ReturnProto->ReturnTypes[i] != proto->ReturnTypes[i]) { // Incompatible + Printf("Return type %s mismatch with %s\n", ReturnProto->ReturnTypes[i]->DescriptiveName(), proto->ReturnTypes[i]->DescriptiveName()); fail = true; break; } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index ea6d581e1..551d909c5 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -7,8 +7,10 @@ #include "zscript/actor_checks.txt" #include "zscript/menu/menu.txt" -//#include "zscript/menu/menuitembase.txt" -#include "zscript/menu/colorpickermenu.txt" +#include "zscript/menu/menuitembase.txt" +#include "zscript/menu/optionmenuitems.txt" +#include "zscript/menu/optionmenuitems.txt" +#include "zscript/menu/joystickmenu.txt" #include "zscript/inventory/inventory.txt" #include "zscript/inventory/inv_misc.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 8e77c3212..2fe42d31a 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -158,6 +158,37 @@ struct Font native CR_CYAN, NUM_TEXT_COLORS }; + + const TEXTCOLOR_BRICK = "\034A"; + const TEXTCOLOR_TAN = "\034B"; + const TEXTCOLOR_GRAY = "\034C"; + const TEXTCOLOR_GREY = "\034C"; + const TEXTCOLOR_GREEN = "\034D"; + const TEXTCOLOR_BROWN = "\034E"; + const TEXTCOLOR_GOLD = "\034F"; + const TEXTCOLOR_RED = "\034G"; + const TEXTCOLOR_BLUE = "\034H"; + const TEXTCOLOR_ORANGE = "\034I"; + const TEXTCOLOR_WHITE = "\034J"; + const TEXTCOLOR_YELLOW = "\034K"; + const TEXTCOLOR_UNTRANSLATED = "\034L"; + const TEXTCOLOR_BLACK = "\034M"; + const TEXTCOLOR_LIGHTBLUE = "\034N"; + const TEXTCOLOR_CREAM = "\034O"; + const TEXTCOLOR_OLIVE = "\034P"; + const TEXTCOLOR_DARKGREEN = "\034Q"; + const TEXTCOLOR_DARKRED = "\034R"; + const TEXTCOLOR_DARKBROWN = "\034S"; + const TEXTCOLOR_PURPLE = "\034T"; + const TEXTCOLOR_DARKGRAY = "\034U"; + const TEXTCOLOR_CYAN = "\034V"; + + const TEXTCOLOR_NORMAL = "\034-"; + const TEXTCOLOR_BOLD = "\034+"; + + const TEXTCOLOR_CHAT = "\034*"; + const TEXTCOLOR_TEAMCHAT = "\034!"; + native int GetCharWidth(int code); native int StringWidth(String code); @@ -173,6 +204,7 @@ struct Console native { native static void HideConsole(); native static void MidPrint(Font fontname, string textlabel, bool bold = false); + native static void DoCommand(String cmd); } struct DamageTypeDefinition native @@ -182,9 +214,24 @@ struct DamageTypeDefinition native struct CVar native { + enum ECVarType + { + CVAR_Bool, + CVAR_Int, + CVAR_Float, + CVAR_String, + CVAR_Color, + }; + + native static CVar FindCVar(Name name); native int GetInt(); native double GetFloat(); native String GetString(); + native void SetInt(int v); + native void SetFloat(double v); + native void SetString(String s); + native int GetRealType(); + native int ResetToDefault(); } struct GameInfoStruct native diff --git a/wadsrc/static/zscript/menu/colorpickermenu.txt b/wadsrc/static/zscript/menu/colorpickermenu.txt index 30c2a183e..ff21e1b8e 100644 --- a/wadsrc/static/zscript/menu/colorpickermenu.txt +++ b/wadsrc/static/zscript/menu/colorpickermenu.txt @@ -32,6 +32,35 @@ ** */ + +//============================================================================= +// +// This is only used by the color picker +// +//============================================================================= + +class OptionMenuSliderVar : OptionMenuSliderBase +{ + int mIndex; + + void Init(String label, int index, double min, double max, double step, int showval) + { + Super.Init(label, min, max, step, showval); + mIndex = index; + } + + override double GetSliderValue() + { + return ColorpickerMenu(Menu.GetCurrentMenu()).GetColor(mIndex); + } + + override void SetSliderValue(double val) + { + ColorpickerMenu(Menu.GetCurrentMenu()).setColor(mIndex, val); + } +} + + class ColorpickerMenu : Menu native { native float mRed; @@ -45,6 +74,18 @@ class ColorpickerMenu : Menu native native CVar mCVar; + double GetColor(int index) + { + double v = index == 0? mRed : index == 1? mGreen : mBlue; + return v; + } + + void SetColor(int index, double val) + { + if (index == 0) mRed = val; + else if (index == 1) mGreen = val; + else mBlue = val; + } //============================================================================= // // diff --git a/wadsrc/static/zscript/menu/joystickmenu.txt b/wadsrc/static/zscript/menu/joystickmenu.txt new file mode 100644 index 000000000..3d4085467 --- /dev/null +++ b/wadsrc/static/zscript/menu/joystickmenu.txt @@ -0,0 +1,191 @@ +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuSliderJoySensitivity : OptionMenuSliderBase +{ + void Init(String label, double min, double max, double step, int showval) + { + Super.Init(label, min, max, step, showval); + } + + override double GetSliderValue() + { + return Menu.GetCurrentJoystickConfig().GetSensitivity(); + } + + override void SetSliderValue(double val) + { + Menu.GetCurrentJoystickConfig().SetSensitivity(val); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuSliderJoyScale : OptionMenuSliderBase +{ + int mAxis; + int mNeg; + + void Init(String label, int axis, double min, double max, double step, int showval) + { + Super.Init(label, min, max, step, showval); + mAxis = axis; + mNeg = 1; + } + + override double GetSliderValue() + { + double d = Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis); + mNeg = d < 0? -1:1; + return d; + } + + override void SetSliderValue(double val) + { + Menu.GetCurrentJoystickConfig().SetAxisScale(mAxis, val * mNeg); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase +{ + int mAxis; + int mNeg; + + + void Init(String label, int axis, double min, double max, double step, int showval) + { + Super.Init(label, min, max, step, showval); + mAxis = axis; + mNeg = 1; + } + + override double GetSliderValue() + { + double d = Menu.GetCurrentJoystickConfig().GetAxisDeadZone(mAxis); + mNeg = d < 0? -1:1; + return d; + } + + override void SetSliderValue(double val) + { + Menu.GetCurrentJoystickConfig().SetAxisDeadZone(mAxis, val * mNeg); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemJoyMap : OptionMenuItemOptionBase +{ + int mAxis; + + void Init(String label, int axis, String values, int center) + { + Super.Init(label, 'none', values, null, center); + mAxis = axis; + } + + override int GetSelection() + { + double f = Menu.GetCurrentJoystickConfig().GetAxisMap(mAxis); + let opt = OptionValues.GetCount(mValues); + if (opt > 0) + { + // Map from joystick axis to menu selection. + for(int i = 0; i < opt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + return i; + } + } + } + return -1; + } + + override void SetSelection(int selection) + { + let opt = OptionValues.GetCount(mValues); + // Map from menu selection to joystick axis. + if (opt == 0 || selection >= opt) + { + selection = JoystickConfig.JOYAXIS_None; + } + else + { + selection = OptionValues.GetValue(mValues, selection); + } + Menu.GetCurrentJoystickConfig().SetAxisMap(mAxis, selection); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemInverter : OptionMenuItemOptionBase +{ + int mAxis; + + + void Init(String label, int axis, int center) + { + Super.Init(label, "none", "YesNo", NULL, center); + mAxis = axis; + } + + override int GetSelection() + { + float f = Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis); + return f > 0? 0:1; + } + + override void SetSelection(int Selection) + { + let f = abs(Menu.GetCurrentJoystickConfig().GetAxisScale(mAxis)); + if (Selection) f*=-1; + Menu.GetCurrentJoystickConfig().SetAxisScale(mAxis, f); + } +} + +//============================================================================= +// +// Executes a CCMD, action is a CCMD name +// +//============================================================================= + +class OptionMenuItemJoyConfigMenu : OptionMenuItemSubmenu +{ + JoystickConfig mJoy; + + void Init(String label = "", JoystickConfig joy = null) + { + Super.Init(label, "JoystickConfigMenu"); + mJoy = joy; + } + + override bool Activate() + { + //UpdateJoystickConfigMenu(mJoy); + return Super.Activate(); + } +} + diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index c759e8351..85cf747c3 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -1,4 +1,48 @@ +struct KeyBindings native +{ + native static String NameKeys(int k1, int k2); + + native int, int GetKeysForCommand(String cmd); + native void SetBind(int key, String cmd); + native void UnbindACommand (String str); +} + +struct OptionValues native +{ + native static int GetCount(Name group); + native static String GetText(Name group, int index); + native static double GetValue(Name group, int index); + native static String GetTextValue(Name group, int index); +} + +struct JoystickConfig native +{ + enum EJoyAxis + { + JOYAXIS_None = -1, + JOYAXIS_Yaw, + JOYAXIS_Pitch, + JOYAXIS_Forward, + JOYAXIS_Side, + JOYAXIS_Up, + // JOYAXIS_Roll, // Ha ha. No roll for you. + NUM_JOYAXIS, + }; + + native float GetSensitivity(); + native void SetSensitivity(float scale); + + native float GetAxisScale(int axis); + native void SetAxisScale(int axis, float scale); + + native float GetAxisDeadZone(int axis); + native void SetAxisDeadZone(int axis, float zone); + + native int GetAxisMap(int axis); + native void SetAxisMap(int axis, int gameaxis); +} + class Menu : Object native { enum EMenuKey @@ -30,16 +74,27 @@ 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'); + native virtual bool MenuEvent (int mkey, bool fromcontroller); native virtual bool MouseEvent(int type, int mx, int my); native virtual void Drawer(); - void MenuSound(Sound snd) + static void MenuSound(Sound snd) { S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE); } + static void DrawConText (int color, int x, int y, String str) + { + screen.DrawText (ConFont, color, x, y, str, DTA_CellX, 8 * CleanXfac_1, DTA_CellY, 8 * CleanYfac_1); + } + } class MenuDescriptor : Object native @@ -49,17 +104,6 @@ class MenuDescriptor : Object native native Class mClass; } -class MenuItemBase : object native -{ - native int mXpos, mYpos; - native Name mAction; - native bool mEnabled; - - // making this virtual now would require exporting all classes at once. - native /*virtual*/ bool MenuEvent (int mkey, bool fromcontroller); - -} - struct FOptionMenuSettings { int mTitleColor; @@ -96,14 +140,6 @@ class OptionMenuDescriptor : MenuDescriptor native } } -class OptionMenuItem : MenuItemBase native -{ - native String mLabel; - native bool mCentered; - - //native void drawLabel(int indent, int y, EColorRange color, bool grayed = false); -} - class OptionMenu : Menu native { native bool CanScrollUp; @@ -111,5 +147,22 @@ class OptionMenu : Menu native native int VisBottom; native OptionMenuItem mFocusControl; native OptionMenuDescriptor mDesc; + + + void SetFocus(OptionMenuItem fc) + { + mFocusControl = fc; + } + + bool CheckFocus(OptionMenuItem fc) + { + return mFocusControl == fc; + } + + void ReleaseFocus() + { + mFocusControl = null; + } + } diff --git a/wadsrc/static/zscript/menu/menuitembase.txt b/wadsrc/static/zscript/menu/menuitembase.txt index e92f17fcf..9015aa758 100644 --- a/wadsrc/static/zscript/menu/menuitembase.txt +++ b/wadsrc/static/zscript/menu/menuitembase.txt @@ -6,12 +6,11 @@ class MenuItemBase : Object native { - protected int mXpos, mYpos; - protected Name mAction; + protected native int mXpos, mYpos; + protected native Name mAction; + native bool mEnabled; - bool mEnabled; - - protected void Init(int xpos = 0, int ypos = 0, Name actionname = 'None') + void Init(int xpos = 0, int ypos = 0, Name actionname = 'None') { mXpos = xpos; mYpos = ypos; @@ -30,7 +29,8 @@ class MenuItemBase : Object native virtual bool SetValue(int i, int value) { return false; } virtual bool, int GetValue(int i) { return false, 0; } virtual void Enable(bool on) { mEnabled = on; } - virtual bool MenuEvent (int mkey, bool fromcontroller) { return false; } + // this can only be made scripted once all items are converted, because it is called from the colorpicker menu. +native virtual bool MenuEvent (int mkey, bool fromcontroller);// { return false; } virtual bool MouseEvent(int type, int x, int y) { return false; } virtual bool CheckHotkey(int c) { return false; } virtual int GetWidth() { return 0; } diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt new file mode 100644 index 000000000..920576878 --- /dev/null +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -0,0 +1,1152 @@ +/* +** optionmenuitems.txt +** Control items for option menus +** +**--------------------------------------------------------------------------- +** Copyright 2010-2017 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +class OptionMenuItem : MenuItemBase native +{ + + native String mLabel; + native bool mCentered; + + void Init(String label, String command, bool center = false) + { + Super.Init(0, 0, command); + mLabel = label; + mCentered = center; + } + + protected void drawLabel(int indent, int y, int color, bool grayed = false) + { + String label = Stringtable.Localize(mLabel); + int overlay = grayed? Color(96,48,0,0) : 0; + + int x; + int w = SmallFont.StringWidth(label) * CleanXfac_1; + if (!mCentered) x = indent - w; + else x = (screen.GetWidth() - w) / 2; + screen.DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); + } + + virtual int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + return indent; + } + + int CursorSpace() + { + return (14 * CleanXfac_1); + } + + override bool Selectable() + { + return true; + } + + virtual int GetIndent() + { + if (mCentered) return 0; + return SmallFont.StringWidth(Stringtable.Localize(mLabel)); + } + + override bool MouseEvent(int type, int x, int y) + { + if (Selectable() && type == Menu.MOUSE_Release) + { + return Menu.GetCurrentMenu().MenuEvent(Menu.MKEY_Enter, true); + } + return false; + } +} + +//============================================================================= +// +// opens a submenu, command is a submenu name +// +//============================================================================= + +class OptionMenuItemSubmenu : OptionMenuItem +{ + int mParam; + void Init(String label, Name command, int param = 0) + { + Super.init(label, command); + mParam = param; + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + drawLabel(indent, y, selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColorMore); + return indent; + } + + override bool Activate() + { + Menu.MenuSound("menu/choose"); + Menu.SetMenu(mAction, mParam); + return true; + } +} + +//============================================================================= +// +// Executes a CCMD, command is a CCMD name +// +//============================================================================= + +class OptionMenuItemCommand : OptionMenuItemSubmenu +{ + void Init(String label, Name command) + { + Super.Init(label, command); + } + + override bool Activate() + { + Menu.MenuSound("menu/choose"); + Console.DoCommand(mAction); + return true; + } + +} + +//============================================================================= +// +// Executes a CCMD after confirmation, command is a CCMD name +// +//============================================================================= + +class OptionMenuItemSafeCommand : OptionMenuItemCommand +{ + String mPrompt; + + + void Init(String label, Name command, String prompt) + { + Super.Init(label, command); + mPrompt = prompt; + } + + override bool MenuEvent (int mkey, bool fromcontroller) + { + if (mkey == Menu.MKEY_MBYes) + { + Console.DoCommand(mAction); + return true; + } + return Super.MenuEvent(mkey, fromcontroller); + } + + override bool Activate() + { + String msg = mPrompt.Length() > 0 ? mPrompt : "$SAFEMESSAGE"; + msg = StringTable.Localize(msg); + String actionLabel = StringTable.localize(mLabel); + + String FullString; + FullString.Format("%s%s%s\n\n%s", TEXTCOLOR_WHITE, actionLabel, TEXTCOLOR_NORMAL, msg); + + Menu.StartMessage(FullString, 0); + return true; + } +} + +//============================================================================= +// +// Base class for option lists +// +//============================================================================= + +class OptionMenuItemOptionBase : OptionMenuItem +{ + // command is a CVAR + Name mValues; // Entry in OptionValues table + CVar mGrayCheck; + int mCenter; + + const OP_VALUES = 0x11001; + + void Init(String label, Name command, Name values, CVar graycheck, int center) + { + Super.Init(label, command); + mValues = values; + mGrayCheck = graycheck; + mCenter = center; + } + + override bool SetString(int i, String newtext) + { + if (i == OP_VALUES) + { + int cnt = OptionValues.GetCount(mValues); + if (cnt >= 0) + { + mValues = newtext; + int s = GetSelection(); + if (s >= cnt) s = 0; + SetSelection(s); // readjust the CVAR if its value is outside the range now + return true; + } + } + return false; + } + + //============================================================================= + virtual int GetSelection() + { + return 0; + } + + virtual void SetSelection(int Selection) + { + } + + //============================================================================= + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + bool grayed = mGrayCheck != null && !(mGrayCheck.GetInt()); + + if (mCenter) + { + indent = (screen.GetWidth() / 2); + } + drawLabel(indent, y, selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, grayed); + + int overlay = grayed? Color(96,48,0,0) : 0; + int Selection = GetSelection(); + String text = StringTable.Localize(OptionValues.GetText(mValues, Selection)); + if (text.Length() == 0) text = "Unknown"; + screen.DrawText (SmallFont, OptionMenuSettings.mFontColorValue, indent + CursorSpace(), y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); + return indent; + } + + //============================================================================= + override bool MenuEvent (int mkey, bool fromcontroller) + { + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + int Selection = GetSelection(); + if (mkey == Menu.MKEY_Left) + { + if (Selection == -1) Selection = 0; + else if (--Selection < 0) Selection = cnt - 1; + } + else if (mkey == Menu.MKEY_Right || mkey == Menu.MKEY_Enter) + { + if (++Selection >= cnt) Selection = 0; + } + else + { + return Super.MenuEvent(mkey, fromcontroller); + } + SetSelection(Selection); + Menu.MenuSound("menu/change"); + } + else + { + return Super.MenuEvent(mkey, fromcontroller); + } + return true; + } + + override bool Selectable() + { + return mGrayCheck == null || mGrayCheck.GetInt(); + } +} + +//============================================================================= +// +// Change a CVAR, command is the CVAR name +// +//============================================================================= + +class OptionMenuItemOption : OptionMenuItemOptionBase +{ + CVar mCVar; + + void Init(String label, Name command, String values, CVar graycheck, int center) + { + Super.Init(label, command, values, graycheck, center); + mCVar = CVar.FindCVar(mAction); + } + + //============================================================================= + override int GetSelection() + { + int Selection = -1; + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0 && mCVar != null) + { + if (OptionValues.GetText(mValues, 0).Length() > 0) + { + let f = mCVar.GetFloat(); + for(int i = 0; i < cnt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + Selection = i; + break; + } + } + } + else + { + String cv = mCVar.GetString(); + for(int i = 0; i < cnt; i++) + { + if (cv ~== OptionValues.GetTextValue(mValues, i)) + { + Selection = i; + break; + } + } + } + } + return Selection; + } + + override void SetSelection(int Selection) + { + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0 && mCVar != null) + { + if (OptionValues.GetText(mValues, 0).Length() > 0) + { + mCVar.SetFloat(OptionValues.GetValue(mValues, Selection)); + } + else + { + mCVar.SetString(OptionValues.GetTextValue(mValues, Selection)); + } + } + } +} + +//============================================================================= +// +// This class is used to capture the key to be used as the new key binding +// for a control item +// +//============================================================================= + +/* This will have to wait. +class DEnterKey : Menu +{ + DECLARE_CLASS(DEnterKey, Menu) + + int *pKey; + + + DEnterKey(Menu *parent, int *keyptr) + : Menu(parent) + { + pKey = keyptr; + SetMenuMessage(1); + menuactive = MENU_WaitKey; // There should be a better way to disable GUI capture... + } + + bool TranslateKeyboardEvents() + { + return false; + } + + void SetMenuMessage(int which) + { + if (mParentMenu.IsKindOf(RUNTIME_CLASS(OptionMenu))) + { + OptionMenu *m = barrier_cast(mParentMenu); + MenuItemBase *it = m.GetItem(NAME_Controlmessage); + if (it != null) + { + it.SetValue(0, which); + } + } + } + + bool Responder(event_t *ev) + { + if (ev.type == EV_KeyDown) + { + *pKey = ev.data1; + menuactive = MENU_On; + SetMenuMessage(0); + Close(); + mParentMenu.CallMenuEvent((ev.data1 == KEY_ESCAPE)? Menu.MKEY_Abort : Menu.MKEY_Input, 0); + return true; + } + return false; + } + + void Drawer() + { + mParentMenu.CallDrawer(); + } +}; + +#ifndef NO_IMP +IMPLEMENT_CLASS(DEnterKey, true, false) +#endif +*/ + +//============================================================================= +// +// // Edit a key binding, Action is the CCMD to bind +// +//============================================================================= + +class OptionMenuItemControl : OptionMenuItem +{ + KeyBindings mBindings; + int mInput; + bool mWaiting; + + void Init(String label, Name command, KeyBindings bindings) + { + Super.init(label, command); + mBindings = bindings; + mWaiting = false; + } + + //============================================================================= + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + drawLabel(indent, y, mWaiting? OptionMenuSettings.mFontColorHighlight: + (selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor)); + + String description; + int Key1, Key2; + + [Key1, Key2] = mBindings.GetKeysForCommand(mAction); + description = KeyBindings.NameKeys (Key1, Key2); + if (description.Length() > 0) + { + Menu.DrawConText(Font.CR_WHITE, indent + CursorSpace(), y + (OptionMenuSettings.mLinespacing-8)*CleanYfac_1, description); + } + else + { + screen.DrawText(SmallFont, Font.CR_BLACK, indent + CursorSpace(), y + (OptionMenuSettings.mLinespacing-8)*CleanYfac_1, "---", DTA_CleanNoMove_1, true); + } + return indent; + } + + //============================================================================= + override bool MenuEvent(int mkey, bool fromcontroller) + { + if (mkey == Menu.MKEY_Input) + { + mWaiting = false; + mBindings.SetBind(mInput, mAction); + return true; + } + else if (mkey == Menu.MKEY_Clear) + { + mBindings.UnbindACommand(mAction); + return true; + } + else if (mkey == Menu.MKEY_Abort) + { + mWaiting = false; + return true; + } + return false; + } + + override bool Activate() + { + Menu.MenuSound("menu/choose"); + mWaiting = true; + //Menu *input = new DEnterKey(Menu.CurrentMenu, &mInput); + //M_ActivateMenu(input); + return true; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemStaticText : OptionMenuItem +{ + int mColor; + + void Init(String label, int cr = -1, bool header = false) + { + Super.Init(label, 'None', true); + mColor = cr >= 0? cr : header ? OptionMenuSettings.mFontColorHeader : OptionMenuSettings.mFontColor; + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + drawLabel(indent, y, mColor); + return -1; + } + + override bool Selectable() + { + return false; + } + +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemStaticTextSwitchable : OptionMenuItem +{ + int mColor; + String mAltText; + int mCurrent; + + void Init(String label, String label2, Name command, int cr) + { + Super.Init(label, command, true); + mColor = cr; + mAltText = label2; + mCurrent = 0; + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + String txt = StringTable.Localize(mCurrent? mAltText : mLabel); + int w = SmallFont.StringWidth(txt) * CleanXfac_1; + int x = (screen.GetWidth() - w) / 2; + screen.DrawText (SmallFont, mColor, x, y, txt, DTA_CleanNoMove_1, true); + return -1; + } + + override bool SetValue(int i, int val) + { + if (i == 0) + { + mCurrent = val; + return true; + } + return false; + } + + override bool SetString(int i, String newtext) + { + if (i == 0) + { + mAltText = newtext; + return true; + } + return false; + } + + override bool Selectable() + { + return false; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuSliderBase : OptionMenuItem +{ + // command is a CVAR + double mMin, mMax, mStep; + int mShowValue; + int mDrawX; + int mSliderShort; + + void Init(String label, double min, double max, double step, int showval) + { + Super.Init(label, 'None'); + mMin = min; + mMax = max; + mStep = step; + mShowValue = showval; + mDrawX = 0; + mSliderShort = 0; + } + + virtual double GetSliderValue() + { + return 0; + } + + virtual void SetSliderValue(double val) + { + } + + //============================================================================= + // + // Draw a slider. Set fracdigits negative to not display the current value numerically. + // + //============================================================================= + + private void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) + { + String formater = String.format("%%.%f", fracdigits); // The format function cannot do the '%.*f' syntax. + String textbuf; + double range; + int maxlen = 0; + int right = x + (12*8 + 4) * CleanXfac_1; + int cy = y + (OptionMenuSettings.mLinespacing-8)*CleanYfac_1; + + range = max - min; + double ccur = clamp(cur, min, max) - min; + + if (fracdigits >= 0) + { + textbuf = String.format(formater, max); + maxlen = SmallFont.StringWidth(textbuf) * CleanXfac_1; + } + + mSliderShort = right + maxlen > screen.GetWidth(); + + if (!mSliderShort) + { + Menu.DrawConText(Font.CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); + Menu.DrawConText(Font.CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); + } + else + { + // On 320x200 we need a shorter slider + Menu.DrawConText(Font.CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); + Menu.DrawConText(Font.CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); + right -= 5*8*CleanXfac_1; + } + + if (fracdigits >= 0 && right + maxlen <= screen.GetWidth()) + { + textbuf = String.format(formater, cur); + screen.DrawText(SmallFont, Font.CR_DARKGRAY, right, y, textbuf, DTA_CleanNoMove_1, true); + } + } + + + //============================================================================= + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + drawLabel(indent, y, selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor); + mDrawX = indent + CursorSpace(); + DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); + return indent; + } + + //============================================================================= + override bool MenuEvent (int mkey, bool fromcontroller) + { + double value = GetSliderValue(); + + if (mkey == Menu.MKEY_Left) + { + value -= mStep; + } + else if (mkey == Menu.MKEY_Right) + { + value += mStep; + } + else + { + return OptionMenuItem.MenuEvent(mkey, fromcontroller); + } + if (value ~== 0) value = 0; // This is to prevent formatting anomalies with very small values + SetSliderValue(clamp(value, mMin, mMax)); + Menu.MenuSound("menu/change"); + return true; + } + + override bool MouseEvent(int type, int x, int y) + { + let lm = OptionMenu(Menu.GetCurrentMenu()); + if (type != Menu.MOUSE_Click) + { + if (!lm.CheckFocus(self)) return false; + } + if (type == Menu.MOUSE_Release) + { + lm.ReleaseFocus(); + } + + int slide_left = mDrawX+8*CleanXfac_1; + int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 12 char cells with 8 pixels each. + + if (type == Menu.MOUSE_Click) + { + if (x < slide_left || x >= slide_right) return true; + } + + x = clamp(x, slide_left, slide_right); + double v = mMin + ((x - slide_left) * (mMax - mMin)) / (slide_right - slide_left); + if (v != GetSliderValue()) + { + SetSliderValue(v); + //Menu.MenuSound("menu/change"); + } + if (type == Menu.MOUSE_Click) + { + lm.SetFocus(self); + } + return true; + } + +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuSliderCVar : OptionMenuSliderBase +{ + CVar mCVar; + + void Init(String label, Name command, double min, double max, double step, int showval) + { + Super.Init(label, min, max, step, showval); + mCVar =CVar.FindCVar(command); + } + + override double GetSliderValue() + { + if (mCVar != null) + { + return mCVar.GetFloat(); + } + else + { + return 0; + } + } + + override void SetSliderValue(double val) + { + if (mCVar != null) + { + mCVar.SetFloat(val); + } + } +} + +//============================================================================= +// +// // Edit a key binding, Action is the CCMD to bind +// +//============================================================================= + +class OptionMenuItemColorPicker : OptionMenuItem +{ + CVar mCVar; + + const CPF_RESET = 0x20001; + + void Init(String label, Name command) + { + Super.Init(label, command); + CVar cv = CVar.FindCVar(command); + if (cv != null && cv.GetRealType() == CVar.CVAR_Color) cv = null; + mCVar = cv; + } + + //============================================================================= + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + drawLabel(indent, y, selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor); + + if (mCVar != null) + { + int box_x = indent + CursorSpace(); + int box_y = y + CleanYfac_1; + screen.Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + OptionMenuSettings.mLinespacing*CleanYfac_1, -1, mCVar.GetInt() | 0xff000000); + } + return indent; + } + + override bool SetValue(int i, int v) + { + if (i == CPF_RESET && mCVar != null) + { + mCVar.ResetToDefault(); + return true; + } + return false; + } + + override bool Activate() + { + if (mCVar != null) + { + Menu.MenuSound("menu/choose"); + /* + Menu *picker = StartPickerMenu(Menu.CurrentMenu, mLabel, mCVar); + if (picker != null) + { + M_ActivateMenu(picker); + return true; + } + */ + } + return false; + } +} + + +class OptionMenuScreenResolutionLine : OptionMenuItem +{ + String mResTexts[3]; + int mSelection; + int mHighlight; + int mMaxValid; + + enum EValues + { + SRL_INDEX = 0x30000, + SRL_SELECTION = 0x30003, + SRL_HIGHLIGHT = 0x30004, + }; + + void Init(String command) + { + Super.Init("", command); + mSelection = 0; + mHighlight = -1; + } + + override bool SetValue(int i, int v) + { + if (i == SRL_SELECTION) + { + mSelection = v; + return true; + } + else if (i == SRL_HIGHLIGHT) + { + mHighlight = v; + return true; + } + return false; + } + + override bool, int GetValue(int i) + { + if (i == SRL_SELECTION) + { + return true, mSelection; + } + return false, 0; + } + + override bool SetString(int i, String newtext) + { + if (i >= SRL_INDEX && i <= SRL_INDEX+2) + { + mResTexts[i-SRL_INDEX] = newtext; + if (mResTexts[0].Length() == 0) mMaxValid = -1; + else if (mResTexts[1].Length() == 0) mMaxValid = 0; + else if (mResTexts[2].Length() == 0) mMaxValid = 1; + else mMaxValid = 2; + return true; + } + return false; + } + + override bool, String GetString(int i) + { + if (i >= SRL_INDEX && i <= SRL_INDEX+2) + { + return true, mResTexts[i-SRL_INDEX]; + } + return false, ""; + } + + override bool MenuEvent (int mkey, bool fromcontroller) + { + if (mkey == Menu.MKEY_Left) + { + if (--mSelection < 0) mSelection = mMaxValid; + Menu.MenuSound ("menu/cursor"); + return true; + } + else if (mkey == Menu.MKEY_Right) + { + if (++mSelection > mMaxValid) mSelection = 0; + Menu.MenuSound ("menu/cursor"); + return true; + } + else + { + return Super.MenuEvent(mkey, fromcontroller); + } + return false; + } + + override bool MouseEvent(int type, int x, int y) + { + int colwidth = screen.GetWidth() / 3; + mSelection = x / colwidth; + return Super.MouseEvent(type, x, y); + } + + override bool Activate() + { + Menu.MenuSound("menu/choose"); + Menu.SetVideoMode(); + return true; + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + int colwidth = screen.GetWidth() / 3; + int col; + + for (int x = 0; x < 3; x++) + { + if (selected && mSelection == x) + col = OptionMenuSettings.mFontColorSelection; + else if (x == mHighlight) + col = OptionMenuSettings.mFontColorHighlight; + else + col = OptionMenuSettings.mFontColorValue; + + screen.DrawText (SmallFont, col, colwidth * x + 20 * CleanXfac_1, y, mResTexts[x], DTA_CleanNoMove_1, true); + } + return colwidth * mSelection + 20 * CleanXfac_1 - CursorSpace(); + } + + override bool Selectable() + { + return mMaxValid >= 0; + } + + override void Ticker() + { + if (Selectable() && mSelection > mMaxValid) + { + mSelection = mMaxValid; + } + } +} + +//============================================================================= +// +// [TP] OptionMenuFieldBase +// +// Base class for input fields +// +//============================================================================= + +class OptionMenuFieldBase : OptionMenuItem +{ + void Init (String label, Name command, CVar graycheck = null) + { + Super.Init(label, command); + mCVar = CVar.FindCVar(mAction); + mGrayCheck = graycheck; + } + + String GetCVarString() + { + if (mCVar == null) + return ""; + + return mCVar.GetString(); + } + + virtual String Represent() + { + return GetCVarString(); + } + + override int Draw (OptionMenuDescriptor d, int y, int indent, bool selected) + { + bool grayed = mGrayCheck != null && !mGrayCheck.GetInt(); + drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, grayed); + int overlay = grayed? Color(96, 48, 0, 0) : 0; + + screen.DrawText(SmallFont, OptionMenuSettings.mFontColorValue, indent + CursorSpace(), y, Represent(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); + return indent; + } + + override bool, String GetString (int i) + { + if (i == 0) + { + return true, GetCVarString(); + } + return false, ""; + } + + override bool SetString (int i, String s) + { + if (i == 0) + { + if (mCVar) mCVar.SetString(s); + return true; + } + return false; + } + + + CVar mCVar; + CVar mGrayCheck; +} + +//============================================================================= +// +// [TP] OptionMenuTextField +// +// A text input field widget, for use with string CVars. +// +//============================================================================= + +class OptionMenuTextField : OptionMenuFieldBase +{ + void Init (String label, Name command, CVar graycheck = null) + { + Super.Init(label, command, graycheck); + mEntering = false; + } + + override String Represent() + { + if (mEntering) return mEditName .. ((gameinfo.gametype & GAME_DoomStrifeChex) ? "_" : "["); + else return GetCVarString(); + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + if (mEntering) + { + // reposition the text so that the cursor is visible when in entering mode. + String text = Represent(); + int tlen = SmallFont.StringWidth(text) * CleanXfac_1; + int newindent = screen.GetWidth() - tlen - CursorSpace(); + if (newindent < indent) indent = newindent; + } + return Super.Draw(desc, y, indent, selected); + } + + override bool MenuEvent (int mkey, bool fromcontroller) + { + if (mkey == Menu.MKEY_Enter) + { + Menu.MenuSound("menu/choose"); + mEditName = GetCVarString(); + mEntering = true; + + //Menu* input = new DTextEnterMenu (Menu.CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller); + //M_ActivateMenu(input); + //OpenTextEnterMenu(mEditName, 2, fromcontroller); // needs a native workaround until menu creation is scriptable. + return true; + } + else if (mkey == Menu.MKEY_Input) + { + if (mCVar) mCVar.SetString(mEditName); + mEntering = false; + return true; + } + else if (mkey == Menu.MKEY_Abort) + { + mEntering = false; + return true; + } + + return Super.MenuEvent(mkey, fromcontroller); + } + + bool mEntering; + String mEditName; +} + + +//============================================================================= +// +// [TP] FOptionMenuNumberField +// +// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e. +// where the user is interested in the exact value specifically) +// +//============================================================================= + +class OptionMenuNumberField : OptionMenuFieldBase +{ + void Init (String label, Name command, float minimum, float maximum, float step, CVar graycheck = null) + { + Super.Init(label, command, graycheck); + mMinimum = min(minimum, maximum); + mMaximum = max(minimum, maximum); + mStep = max(1, step); + } + + override String Represent() + { + if (mCVar == null) return ""; + return String.format("%.3f", mCVar.GetFloat()); + } + + + override bool MenuEvent (int mkey, bool fromcontroller) + { + if (mCVar) + { + float value = mCVar.GetFloat(); + + if (mkey == Menu.MKEY_Left) + { + value -= mStep; + if (value < mMinimum) value = mMaximum; + } + else if (mkey == Menu.MKEY_Right || mkey == Menu.MKEY_Enter) + { + value += mStep; + if (value > mMaximum) value = mMinimum; + } + else + return Super.MenuEvent(mkey, fromcontroller); + + mCVar.SetFloat(value); + Menu.MenuSound("menu/change"); + } + + return true; + } + + float mMinimum; + float mMaximum; + float mStep; +} +