diff --git a/src/s_environment.cpp b/src/s_environment.cpp index 8c9d61e05..4d83dd2d4 100644 --- a/src/s_environment.cpp +++ b/src/s_environment.cpp @@ -40,6 +40,7 @@ #include "templates.h" #include "w_wad.h" #include "i_system.h" +#include "m_misc.h" #include "c_cvars.h" #include "c_dispatch.h" @@ -55,6 +56,12 @@ REVERB_PROPERTIES SavedProperties; ReverbContainer *CurrentEnv; extern ReverbContainer *ForcedEnvironment; +// These are for internal use only and not supposed to be user-settable +CVAR(String, reverbedit_name, "", CVAR_NOSET); +CVAR(Int, reverbedit_id1, 0, CVAR_NOSET); +CVAR(Int, reverbedit_id2, 0, CVAR_NOSET); +CVAR(String, reverbsavename, "", 0); + struct FReverbField { int Min, Max; @@ -830,7 +837,9 @@ FString SuggestNewName(const ReverbContainer *env) void ExportEnvironments(const char *filename, uint32_t count, const ReverbContainer **envs) { - FileWriter *f = FileWriter::Open("filename"); + FString dest = M_GetDocumentsPath() + filename; + + FileWriter *f = FileWriter::Open(dest); if (f != nullptr) { @@ -992,10 +1001,75 @@ DEFINE_ACTION_FUNCTION(DReverbEdit, FillSelectMenu) return 0; } -// These are for internal use only and not supposed to be user-settable -CVAR(String, reverbedit_name, "", CVAR_NOSET); -CVAR(Int, reverbedit_id1, 0, CVAR_NOSET); -CVAR(Int, reverbedit_id2, 0, CVAR_NOSET); +static TArray> SaveState; + +DEFINE_ACTION_FUNCTION(DReverbEdit, FillSaveMenu) +{ + PARAM_PROLOGUE; + PARAM_OBJECT(desc, DOptionMenuDescriptor); + desc->mItems.Resize(4); + SaveState.Clear(); + for (auto env = Environments; env != nullptr; env = env->Next) + { + if (!env->Builtin) + { + int index = (int)SaveState.Push(std::make_pair(env, false)); + + FStringf text("(%d, %d) %s", HIBYTE(env->ID), LOBYTE(env->ID), env->Name); + PClass *cls = PClass::FindClass("OptionMenuItemReverbSaveSelect"); + if (cls != nullptr && cls->IsDescendantOf("OptionMenuItem")) + { + auto func = dyn_cast(cls->FindSymbol("Init", true)); + if (func != nullptr) + { + DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew(); + VMValue params[] = { item, &text, index, FName("OnOff").GetIndex() }; + VMCall(func->Variants[0].Implementation, params, 4, nullptr, 0); + desc->mItems.Push((DMenuItemBase*)item); + } + } + } + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DReverbEdit, GetSaveSelection) +{ + PARAM_PROLOGUE; + PARAM_INT(index); + bool res = false; + if ((unsigned)index <= SaveState.Size()) + { + res = SaveState[index].second; + } + ACTION_RETURN_BOOL(res); +} + +DEFINE_ACTION_FUNCTION(DReverbEdit, ToggleSaveSelection) +{ + PARAM_PROLOGUE; + PARAM_INT(index); + if ((unsigned)index <= SaveState.Size()) + { + SaveState[index].second = !SaveState[index].second; + } + return 0; +} + + +CCMD(savereverbs) +{ + if (SaveState.Size() == 0) return; + + TArray toSave; + + for (auto &p : SaveState) + { + if (p.second) toSave.Push(p.first); + } + ExportEnvironments(reverbsavename, toSave.Size(), &toSave[0]); + SaveState.Clear(); +} static void SelectEnvironment(const char *envname) { diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 420c0e8c0..d4a4916ae 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -354,8 +354,6 @@ OptionMenu "OptionsMenu" protected Submenu "$OPTMNU_VIDEO", "VideoModeMenu" Submenu "$OPTMNU_CHANGERENDER", "RendererMenu" StaticText " " - Submenu "$OPTMNU_REVERB", "ReverbEdit" - StaticText " " SafeCommand "$OPTMNU_DEFAULTS", "reset2defaults" SafeCommand "$OPTMNU_RESETTOSAVED", "reset2saved" Command "$OPTMNU_CONSOLE", "menuconsole" @@ -1629,6 +1627,8 @@ OptionMenu SoundOptions protected StaticText " " Submenu "$SNDMNU_ADVANCED", "AdvSoundOptions" Submenu "$SNDMNU_MODREPLAYER", "ModReplayerOptions" + StaticText " " + Submenu "$OPTMNU_REVERB", "ReverbEdit" } /*======================================= @@ -2280,4 +2280,15 @@ OptionMenu "ReverbNew" protected NumberField "ID #1", "reverbedit_id1", 0, 255 NumberField "ID #2", "reverbedit_id2", 0, 255 Command "Create", "createenvironment", 0, 1 +} + +OptionMenu "ReverbSave" protected +{ + Class "ReverbSave" + Title "Save Reverb Environments" + Command "Save...", "savereverbs" + TextField "File name", "reverbsavename" + StaticText "" + StaticText "Environments to save" + // Rest is filled in by code. } \ No newline at end of file diff --git a/wadsrc/static/zscript/menu/reverbedit.txt b/wadsrc/static/zscript/menu/reverbedit.txt index 7042d177e..2f372968c 100644 --- a/wadsrc/static/zscript/menu/reverbedit.txt +++ b/wadsrc/static/zscript/menu/reverbedit.txt @@ -6,6 +6,9 @@ class ReverbEdit : OptionMenu static native bool GrayCheck(); static native string, int GetSelectedEnvironment(); static native void FillSelectMenu(String ccmd, OptionMenuDescriptor desc); + static native void FillSaveMenu(OptionMenuDescriptor desc); + static native int GetSaveSelection(int num); + static native void ToggleSaveSelection(int num); override void Init(Menu parent, OptionMenuDescriptor desc) { @@ -64,6 +67,51 @@ class ReverbSelect : OptionMenu } } +class ReverbSave : OptionMenu +{ + //============================================================================= + // + // + // + //============================================================================= + + override void Init(Menu parent, OptionMenuDescriptor desc) + { + ReverbEdit.FillSaveMenu(desc); + super.Init(parent, desc); + } +} + +//============================================================================= +// +// Change a CVAR, command is the CVAR name +// +//============================================================================= + +class OptionMenuItemReverbSaveSelect : OptionMenuItemOptionBase +{ + int mValIndex; + + OptionMenuItemReverbSaveSelect Init(String label, int index, Name values) + { + Super.Init(label, 'None', values, null, 0); + mValIndex = index; + return self; + } + + //============================================================================= + override int GetSelection() + { + return ReverbEdit.GetSaveSelection(mValIndex); + } + + override void SetSelection(int Selection) + { + ReverbEdit.ToggleSaveSelection(mValIndex); + } +} + + //============================================================================= // // opens a submenu, command is a submenu name @@ -170,14 +218,14 @@ class OptionMenuItemSliderReverbEditOption : OptionMenuSliderBase { drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, ReverbEdit.GrayCheck()); - int DrawX = indent + CursorSpace(); + mDrawX = indent + CursorSpace(); if (mEnter) { - screen.DrawText(SmallFont, OptionMenuSettings.mFontColorValue, DrawX, y, Represent(), DTA_CleanNoMove_1, true); + screen.DrawText(SmallFont, OptionMenuSettings.mFontColorValue, mDrawX, y, Represent(), DTA_CleanNoMove_1, true); } else { - DrawSlider (DrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); + DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); } return indent; }