Programming/vgui soundscape maker.cpp
Jump to navigation
Jump to search
This page contains the .cpp file needed for creating the vgui_soundscape_maker
//========= Created by Waddelz. https://www.youtube.com/@WadDeIz_Real. ============//
//
// Purpose: a vgui panel that allows you to create and test soundscapes in game
//
// $NoKeywords: $
//
//=================================================================================//
#include "cbase.h"
#include "c_soundscape.h"
#include "vgui_soundscape_maker.h"
#include <vgui_controls/Frame.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Divider.h>
#include <vgui_controls/FileOpenDialog.h>
#include <vgui_controls/QueryBox.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/Menu.h>
#include <vgui_controls/MenuItem.h>
#include <engine/IEngineSound.h>
#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include <filesystem.h>
#include <fmtstr.h>
//selected text mode
enum class SoundscapeMode
{
Mode_Random,
Mode_Soundscape,
Mode_Looping,
};
//dsp effects
static const char* g_DspEffects[] = {
"Normal (off)",
"Generic",
"Metal Small",
"Metal Medium",
"Metal Large",
"Tunnel Small",
"Tunnel Medium",
"Tunnel Large",
"Chamber Small",
"Chamber Medium",
"Chamber Large",
"Bright Small",
"Bright Medium",
"Bright Large",
"Water 1",
"Water 2",
"Water 3",
"Concrete Small",
"Concrete Medium",
"Concrete Large",
"Big 1",
"Big 2",
"Big 3",
"Cavern Small",
"Cavern Medium",
"Cavern Large",
"Weirdo 1",
"Weirdo 2",
"Weirdo 3",
};
//sound levels
static const char* g_SoundLevels[] = {
"SNDLVL_50dB",
"SNDLVL_55dB",
"SNDLVL_IDLE",
"SNDLVL_TALKING",
"SNDLVL_60dB",
"SNDLVL_65dB",
"SNDLVL_STATIC",
"SNDLVL_70dB",
"SNDLVL_NORM",
"SNDLVL_75dB",
"SNDLVL_80dB",
"SNDLVL_85dB",
"SNDLVL_90dB",
"SNDLVL_95dB",
"SNDLVL_100dB",
"SNDLVL_105dB",
"SNDLVL_120dB",
"SNDLVL_130dB",
"SNDLVL_GUNFIRE",
"SNDLVL_140dB",
"SNDLVL_150dB"
};
//holds all the sound names
static CUtlVector<char*> g_SoundDirectories;
//-----------------------------------------------------------------------------
// Purpose: Sort function for utl vector
//-----------------------------------------------------------------------------
static int VectorSortFunc(char* const* p1, char* const* p2)
{
return Q_stricmp(*p1, *p2);
}
//-----------------------------------------------------------------------------
// Purpose: Gets all the sound names and stores them into g_SoundDirectories
//-----------------------------------------------------------------------------
static void GetSoundNames()
{
//first off clear the sound array first
for (int i = 0; i < g_SoundDirectories.Count(); i++)
free(g_SoundDirectories[i]);
g_SoundDirectories.RemoveAll();
//directories to search
CUtlVector<char*> directoriesToSearch;
directoriesToSearch.AddToTail(strdup("sound"));
//loop until all directories have been processed
while (directoriesToSearch.Count() > 0)
{
//take the last added directory (depth-first search)
char* currentDir = directoriesToSearch[directoriesToSearch.Count() - 1];
directoriesToSearch.Remove(directoriesToSearch.Count() - 1);
//create a wildcard path to search all files and subdirs
char searchPath[MAX_PATH];
Q_snprintf(searchPath, sizeof(searchPath), "%s/*", currentDir);
FileFindHandle_t findHandle;
const char* filename = g_pFullFileSystem->FindFirst(searchPath, &findHandle);
while (filename)
{
//ignore special directories
if (Q_strcmp(filename, ".") != 0 && Q_strcmp(filename, "..") != 0)
{
char fullPath[MAX_PATH];
Q_snprintf(fullPath, sizeof(fullPath), "%s/%s", currentDir, filename);
//if it's a directory, add it to the list for later processing
if (g_pFullFileSystem->FindIsDirectory(findHandle))
{
directoriesToSearch.AddToTail(strdup(fullPath));
}
else
{
//check file extension and print if it's .wav or .mp3
const char* ext = V_GetFileExtension(filename);
if (ext && (!Q_stricmp(ext, "wav") || !Q_stricmp(ext, "mp3")))
{
g_SoundDirectories.AddToTail(strdup(fullPath + 6));
}
}
}
// Move to next file
filename = g_pFullFileSystem->FindNext(findHandle);
}
//free the memory
g_pFullFileSystem->FindClose(findHandle);
free(currentDir);
}
//
g_SoundDirectories.Sort(VectorSortFunc);
}
//sounds list panel
#define SOUND_LIST_PANEL_WIDTH 325
#define SOUND_LIST_PANEL_HEIGHT 155
#define SOUND_LIST_PLAY_COMMAND "PlaySound"
#define SOUND_LIST_STOP_COMMAND "StopSound"
#define SOUND_LIST_INSERT_COMMAND "Insert"
#define SOUND_LIST_RELOAD_COMMAND "Reload"
class CSoundListPanel : public vgui::Frame
{
public:
DECLARE_CLASS(CSoundListPanel, vgui::Frame);
CSoundListPanel(vgui::VPANEL parent, const char* name);
//initalizes sound combo box
void InitalizeSounds();
//other
void OnCommand(const char* pszCommand);
void OnClose();
private:
vgui::ComboBox* m_SoundsList;
vgui::Button* m_PlayButton;
vgui::Button* m_StopSoundButton;
vgui::Button* m_InsertButton;
vgui::Button* m_ReloadSounds;
//current sound guid
int m_iSongGuid = -1;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSoundListPanel::CSoundListPanel(vgui::VPANEL parent, const char* name)
: BaseClass(nullptr, name)
{
SetParent(parent);
SetKeyBoardInputEnabled(true);
SetMouseInputEnabled(true);
SetProportional(false);
SetTitleBarVisible(true);
SetMinimizeButtonVisible(false);
SetMaximizeButtonVisible(false);
SetCloseButtonVisible(true);
SetSizeable(false);
SetMoveable(true);
SetVisible(false);
//set the size and pos
int ScreenWide, ScreenTall;
vgui::surface()->GetScreenSize(ScreenWide, ScreenTall);
SetTitle("Sounds List", true);
SetSize(SOUND_LIST_PANEL_WIDTH, SOUND_LIST_PANEL_HEIGHT);
SetPos((ScreenWide - SOUND_LIST_PANEL_WIDTH) / 2, (ScreenTall - SOUND_LIST_PANEL_HEIGHT) / 2);
SetScheme(vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "SourceScheme"));
//create combo box
m_SoundsList = new vgui::ComboBox(this, "SoundsList", 20, true);
m_SoundsList->SetBounds(5, 25, SOUND_LIST_PANEL_WIDTH - 15, 20);
//create play button
m_PlayButton = new vgui::Button(this, "PlayButton", "Play Sound", this);
m_PlayButton ->SetBounds(5, 50, SOUND_LIST_PANEL_WIDTH - 15, 20);
m_PlayButton->SetCommand(SOUND_LIST_PLAY_COMMAND);
//create stop sound button
m_StopSoundButton = new vgui::Button(this, "StopSound", "Stop Sound", this);
m_StopSoundButton ->SetBounds(5, 75, SOUND_LIST_PANEL_WIDTH - 15, 20);
m_StopSoundButton->SetCommand(SOUND_LIST_STOP_COMMAND);
//create sound insert button
m_InsertButton = new vgui::Button(this, "InsertSound", "Insert Sound", this);
m_InsertButton ->SetBounds(5, 100, SOUND_LIST_PANEL_WIDTH - 15, 20);
m_InsertButton->SetCommand(SOUND_LIST_INSERT_COMMAND);
//create reload sounds button
m_ReloadSounds = new vgui::Button(this, "ReloadSounds", "Reload Sounds", this);
m_ReloadSounds ->SetBounds(5, 125, SOUND_LIST_PANEL_WIDTH - 15, 20);
m_ReloadSounds->SetCommand(SOUND_LIST_RELOAD_COMMAND);
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
void CSoundListPanel::OnCommand(const char* pszCommand)
{
if (!Q_strcmp(pszCommand, SOUND_LIST_PLAY_COMMAND))
{
//get the sound
char buf[512];
m_SoundsList->GetText(buf, sizeof(buf));
//stop the sound
if (enginesound->IsSoundStillPlaying(m_iSongGuid))
{
enginesound->StopSoundByGuid(m_iSongGuid);
m_iSongGuid = -1;
}
//precache and play the sound
if (!enginesound->IsSoundPrecached(buf))
enginesound->PrecacheSound(buf);
enginesound->EmitAmbientSound(buf, 1, 100);
m_iSongGuid = enginesound->GetGuidForLastSoundEmitted();
return;
}
else if (!Q_strcmp(pszCommand, SOUND_LIST_STOP_COMMAND))
{
//stop the sound
if (m_iSongGuid != -1 && enginesound->IsSoundStillPlaying(m_iSongGuid))
{
enginesound->StopSoundByGuid(m_iSongGuid);
m_iSongGuid = -1;
}
return;
}
else if (!Q_strcmp(pszCommand, SOUND_LIST_INSERT_COMMAND))
{
//make not visible
SetVisible(false);
//stop the sound
if (enginesound->IsSoundStillPlaying(m_iSongGuid))
{
enginesound->StopSoundByGuid(m_iSongGuid);
m_iSongGuid = -1;
}
//get the sound
char buf[512];
m_SoundsList->GetText(buf, sizeof(buf));
//set the sound text
g_SoundscapeMaker->SetSoundText(buf);
return;
}
else if (!Q_strcmp(pszCommand, SOUND_LIST_RELOAD_COMMAND))
{
//clear everything for the combo box and reload it
m_SoundsList->RemoveAll();
InitalizeSounds();
return;
}
BaseClass::OnCommand(pszCommand);
}
//-----------------------------------------------------------------------------
// Purpose: Called on panel close
//-----------------------------------------------------------------------------
void CSoundListPanel::OnClose()
{
OnCommand(SOUND_LIST_STOP_COMMAND);
BaseClass::OnClose();
}
//-----------------------------------------------------------------------------
// Purpose: Initalizes the sounds list
//-----------------------------------------------------------------------------
void CSoundListPanel::InitalizeSounds()
{
//get the sound array
GetSoundNames();
//add all the sounds
for (int i = 0; i < g_SoundDirectories.Size(); i++)
m_SoundsList->AddItem(g_SoundDirectories[i], nullptr);
m_SoundsList->ActivateItem(0);
}
//static sound list instance
static CSoundListPanel* g_SoundPanel = nullptr;
static bool g_SoundPanelInitalized = false;
//soundscape list
#define ADD_SOUNDSCAPE_COMMAND "AddSoundscape"
//soundscape list class
class CSoundscapeList : public vgui::Divider
{
public:
DECLARE_CLASS_SIMPLE(CSoundscapeList, vgui::Divider);
//constructor
CSoundscapeList(vgui::Panel* parent, const char* name, const char* text, int text_x_pos, int max, int width, int height);
//menu item stuff
virtual void AddButton(const char* name, const char* text, const char* command, vgui::Panel* parent);
virtual void Clear();
//other
virtual void OnMouseWheeled(int delta);
virtual void OnMouseReleased(vgui::MouseCode code);
virtual void OnCommand(const char* pszCommand);
virtual void ApplySchemeSettings(vgui::IScheme* scheme);
//message funcs
MESSAGE_FUNC_INT(ScrollBarMoved, "ScrollBarSliderMoved", position);
protected:
friend class CSoundscapeMaker;
//keyvalue list.
KeyValues* m_Keyvalues;
//says "Soundscapes List"
vgui::Label* m_pLabel;
vgui::ScrollBar* m_pSideSlider;
//menu button stuff
CUtlVector<vgui::Button*> m_MenuButtons;
int m_iCurrentY;
int m_iMax;
int m_AmtAdded;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor for soundscape list panel
//-----------------------------------------------------------------------------
CSoundscapeList::CSoundscapeList(vgui::Panel* parent, const char* name, const char* text, int text_x_pos, int max, int width, int height)
: BaseClass(parent, name)
{
//create the text
m_pLabel = new vgui::Label(this, "ListsText", text);
m_pLabel->SetVisible(true);
m_pLabel->SetBounds(text_x_pos, 2, 150, 20);
//create the side slider
m_pSideSlider = new vgui::ScrollBar(this, "ListsSlider", true);
m_pSideSlider->SetBounds(width - 20, 0, 20, height - 2);
m_pSideSlider->SetValue(0);
m_pSideSlider->SetEnabled(false);
m_pSideSlider->SetRange(0, 0);
m_pSideSlider->SetButtonPressedScrollValue(1);
m_pSideSlider->SetRangeWindow(0);
m_pSideSlider->AddActionSignalTarget(this);
m_iCurrentY = 22;
m_iMax = max;
m_Keyvalues = nullptr;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor for soundscape list panel
//-----------------------------------------------------------------------------
void CSoundscapeList::AddButton(const char* name, const char* text, const char* command, vgui::Panel* parent)
{
//create a new button
vgui::Button* button = new vgui::Button(this, name, text, parent, command);
button->SetBounds(5, m_iCurrentY, GetWide() - 30, 20);
//increment current y
m_iCurrentY = m_iCurrentY + 22;
//add button to array
m_MenuButtons.AddToTail(button);
//if the count is more then m_iMax then set slider value
if (m_MenuButtons.Count() > m_iMax)
{
int max = m_MenuButtons.Count() - m_iMax;
m_pSideSlider->SetRange(0, max);
m_pSideSlider->SetRangeWindow(1);
m_pSideSlider->SetEnabled(true);
}
m_AmtAdded++;
//check to see if we need to scroll down
if (m_MenuButtons.Count() >= m_iMax)
OnMouseWheeled(-1);
}
//-----------------------------------------------------------------------------
// Purpose: Clears everything for this list
//-----------------------------------------------------------------------------
void CSoundscapeList::Clear()
{
//reset the slider
m_pSideSlider->SetValue(0);
m_pSideSlider->SetEnabled(false);
m_pSideSlider->SetRange(0, 0);
m_pSideSlider->SetButtonPressedScrollValue(1);
m_pSideSlider->SetRangeWindow(0);
//delete and clear the buttons
for (int i = 0; i < m_MenuButtons.Count(); i++)
m_MenuButtons[i]->DeletePanel();
m_MenuButtons.RemoveAll();
//reset current y
m_iCurrentY = 22;
m_AmtAdded = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Clears everything for this list
//-----------------------------------------------------------------------------
void CSoundscapeList::OnMouseWheeled(int delta)
{
//check for scroll down
if (delta == -1)
m_pSideSlider->SetValue(m_pSideSlider->GetValue() + 1);
//check for scroll up
else if (delta == 1)
m_pSideSlider->SetValue(m_pSideSlider->GetValue() - 1);
}
//-----------------------------------------------------------------------------
// Purpose: Called when a mouse code is released
//-----------------------------------------------------------------------------
void CSoundscapeList::OnMouseReleased(vgui::MouseCode code)
{
if (code != vgui::MouseCode::MOUSE_RIGHT)
return;
//get cursor pos
int x, y;
vgui::surface()->SurfaceGetCursorPos(x, y);
//create menu
vgui::Menu* menu = new vgui::Menu(this, "Menu");
menu->AddMenuItem("AddSoundscape", "Add Soundscape", ADD_SOUNDSCAPE_COMMAND, this);
menu->SetBounds(x, y, 200, 50);
menu->SetVisible(true);
}
//-----------------------------------------------------------------------------
// Purpose: Called on command
//-----------------------------------------------------------------------------
void CSoundscapeList::OnCommand(const char* pszCommand)
{
if (!Q_strcmp(pszCommand, ADD_SOUNDSCAPE_COMMAND))
{
const char* name = CFmtStr("New Soundscape %d", m_AmtAdded);
AddButton(name, name, name, GetParent());
//add to keyvalues file
KeyValues* kv = new KeyValues(name);
KeyValues* tmp = m_Keyvalues;
KeyValues* tmp2 = tmp;
//get last subkey
while (tmp != nullptr)
{
tmp2 = tmp;
tmp = tmp->GetNextTrueSubKey();
}
//add to last subkey
tmp2->SetNextKey(kv);
GetParent()->OnCommand(name);
return;
}
BaseClass::OnCommand(pszCommand);
}
//-----------------------------------------------------------------------------
// Purpose: Called on command
//-----------------------------------------------------------------------------
void CSoundscapeList::ApplySchemeSettings(vgui::IScheme* scheme)
{
BaseClass::ApplySchemeSettings(scheme);
SetBgColor(Color(100, 100, 100, 200));
}
//-----------------------------------------------------------------------------
// Purpose: Called on scroll bar moved
//-----------------------------------------------------------------------------
void CSoundscapeList::ScrollBarMoved(int delta)
{
int position = m_pSideSlider->GetValue();
//move everything down (if needed)
for (int i = 0; i < m_MenuButtons.Count(); i++)
{
//make not visible if i < position
if (i < position)
{
m_MenuButtons[i]->SetVisible(false);
continue;
}
m_MenuButtons[i]->SetPos(5, 22 * ((i - position) + 1));
m_MenuButtons[i]->SetVisible(true);
}
}
//soundscape data list
#define NEW_PLAYLOOPING_COMMAND "NewLooping"
#define NEW_SOUNDSCAPE_COMMAND "NewSoundscape"
#define NEW_RANDOM_COMMAND "NewRandom"
class CSoundscapeDataList : public CSoundscapeList
{
public:
DECLARE_CLASS_SIMPLE(CSoundscapeDataList, CSoundscapeList);
CSoundscapeDataList(vgui::Panel* parent, const char* name, const char* text, int text_x_pos, int max, int width, int height)
: CSoundscapeList(parent, name, text, text_x_pos, max, width, height)
{}
//override right click functionality
virtual void OnMouseReleased(vgui::MouseCode code);
void OnCommand(const char* pszCommand);
private:
friend class CSoundscapeMaker;
};
//-----------------------------------------------------------------------------
// Purpose: Called when a mouse code is released
//-----------------------------------------------------------------------------
void CSoundscapeDataList::OnMouseReleased(vgui::MouseCode code)
{
//if no soundscape is selected or mouse code != right then return
if (code != vgui::MouseCode::MOUSE_RIGHT || !m_Keyvalues)
return;
//get cursor pos
int x, y;
vgui::surface()->SurfaceGetCursorPos(x, y);
//create menu
vgui::Menu* menu = new vgui::Menu(this, "Menu");
menu->AddMenuItem("AddLooping", "Add Looping Sound", NEW_PLAYLOOPING_COMMAND, this);
menu->AddMenuItem("AddSoundscape", "Add Soundscape", NEW_SOUNDSCAPE_COMMAND, this);
menu->AddMenuItem("AddSoundscape", "Add Random Sounds", NEW_RANDOM_COMMAND, this);
menu->SetBounds(x, y, 200, 50);
menu->SetVisible(true);
}
//-----------------------------------------------------------------------------
// Purpose: Called on command
//-----------------------------------------------------------------------------
void CSoundscapeDataList::OnCommand(const char* pszCommand)
{
if (!Q_strcmp(pszCommand, NEW_PLAYLOOPING_COMMAND))
{
int LoopingNum = 0;
FOR_EACH_TRUE_SUBKEY(m_Keyvalues, data)
{
//store data name
const char* name = data->GetName();
//increment variables based on name
if (!Q_strcasecmp(name, "playlooping"))
LoopingNum++;
}
//add the keyvalue to both this and the keyvalues
AddButton("playlooping", "playlooping", CFmtStr("$playlooping%d", LoopingNum + 1), GetParent());
//add the keyvalues
KeyValues* kv = new KeyValues("playlooping");
kv->SetFloat("volume", 1);
kv->SetInt("pitch", 100);
m_Keyvalues->AddSubKey(kv);
GetParent()->OnCommand(CFmtStr("$playlooping%d", LoopingNum + 1));
return;
}
else if (!Q_strcmp(pszCommand, NEW_SOUNDSCAPE_COMMAND))
{
int SoundscapeNum = 0;
FOR_EACH_TRUE_SUBKEY(m_Keyvalues, data)
{
//store data name
const char* name = data->GetName();
//increment variables based on name
if (!Q_strcasecmp(name, "playsoundscape"))
SoundscapeNum++;
}
AddButton("playsoundscape", "playsoundscape", CFmtStr("$playsoundscape%d", SoundscapeNum + 1), GetParent());
//add the keyvalues
KeyValues* kv = new KeyValues("playsoundscape");
kv->SetFloat("volume", 1);
kv->SetInt("pitch", 100);
//add the keyvalue to both this and the keyvalues
m_Keyvalues->AddSubKey(kv);
GetParent()->OnCommand(CFmtStr("$playsoundscape%d", SoundscapeNum + 1));
return;
}
else if (!Q_strcmp(pszCommand, NEW_RANDOM_COMMAND))
{
int RandomNum = 0;
FOR_EACH_TRUE_SUBKEY(m_Keyvalues, data)
{
//store data name
const char* name = data->GetName();
//increment variables based on name
if (!Q_strcasecmp(name, "playrandom"))
RandomNum++;
}
AddButton("playrandom", "playrandom", CFmtStr("$playrandom%d", RandomNum + 1), GetParent());
//add the keyvalues
KeyValues* kv = new KeyValues("playrandom");
kv->SetString("volume", "0.5,0.8");
kv->SetInt("pitch", 100);
kv->SetString("time", "10,20");
//make rndwave subkey
KeyValues* rndwave = new KeyValues("rndwave");
kv->AddSubKey(rndwave);
//add the keyvalue to both this and the keyvalues
m_Keyvalues->AddSubKey(kv);
//make the parent show the new item
GetParent()->OnCommand(CFmtStr("$playrandom%d", RandomNum + 1));
return;
}
BaseClass::OnCommand(pszCommand);
}
//soundscape rndwave data list
#define NEW_RNDWAVE_WAVE_COMMAND "NewRNDWave"
class CSoundscapeRndwaveList : public CSoundscapeList
{
public:
DECLARE_CLASS_SIMPLE(CSoundscapeDataList, CSoundscapeList);
CSoundscapeRndwaveList(vgui::Panel* parent, const char* name, const char* text, int text_x_pos, int max, int width, int height)
: CSoundscapeList(parent, name, text, text_x_pos, max, width, height)
{}
//override right click functionality
virtual void OnMouseReleased(vgui::MouseCode code);
void OnCommand(const char* pszCommand);
private:
friend class CSoundscapeMaker;
};
//-----------------------------------------------------------------------------
// Purpose: Called when a mouse code is released
//-----------------------------------------------------------------------------
void CSoundscapeRndwaveList::OnMouseReleased(vgui::MouseCode code)
{
//if no soundscape is selected or mouse code != right then return
if (code != vgui::MouseCode::MOUSE_RIGHT || !m_Keyvalues)
return;
//get cursor pos
int x, y;
vgui::surface()->SurfaceGetCursorPos(x, y);
//create menu
vgui::Menu* menu = new vgui::Menu(this, "Menu");
menu->AddMenuItem("AddRandom", "Add Random Wave", NEW_RNDWAVE_WAVE_COMMAND, this);
menu->SetBounds(x, y, 200, 50);
menu->SetVisible(true);
}
//-----------------------------------------------------------------------------
// Purpose: Called on command
//-----------------------------------------------------------------------------
void CSoundscapeRndwaveList::OnCommand(const char* pszCommand)
{
if (!Q_strcmp(pszCommand, NEW_RNDWAVE_WAVE_COMMAND))
{
//get number of keyvalues
int num = 0;
FOR_EACH_VALUE(m_Keyvalues, kv)
num++;
//add keyvalues and button
AddButton("Rndwave", "", CFmtStr("$rndwave%d", num + 1), GetParent());
KeyValues* add = new KeyValues("wave");
add->SetString(nullptr, "");
m_Keyvalues->AddSubKey(add);
//forward command to parent
GetParent()->OnCommand(CFmtStr("$rndwave%d", num + 1));
return;
}
BaseClass::OnCommand(pszCommand);
}
//soundscape panel
#define SOUNDSCAPE_PANEL_WIDTH 760
#define SOUNDSCAPE_PANEL_HEIGHT 600
#define NEW_BUTTON_COMMAND "NewSoundscape"
#define SAVE_BUTTON_COMMAND "SaveSoundscape"
#define LOAD_BUTTON_COMMAND "LoadSoundscape"
#define RESET_BUTTON_COMMAND "ResetSoundscapes"
#define SOUNDS_LIST_BUTTON_COMMAND "ShowSoundsList"
#define PLAY_SOUNDSCAPE_COMMAND "PlaySoundscape"
#define RESET_SOUNDSCAPE_BUTTON_COMMAND "ResetSoundscape"
#define DELETE_CURRENT_ITEM_COMMAND "DeleteItem"
//static bool to determin if the soundscape panel should show or not
bool g_ShowSoundscapePanel = true;
bool g_IsPlayingSoundscape = false;
//soundscape maker panel
class CSoundscapeMaker : public vgui::Frame, CAutoGameSystem
{
public:
DECLARE_CLASS_SIMPLE(CSoundscapeMaker, vgui::Frame)
CSoundscapeMaker(vgui::VPANEL parent);
//tick functions
void OnTick();
//other functions
void OnClose();
void OnCommand(const char* pszCommand);
void PlaySelectedSoundscape();
void LoadFile(KeyValues* file);
void OnKeyCodePressed(vgui::KeyCode code);
void SetSoundText(const char* text);
//to play the soundscape on map spawn
void LevelInitPostEntity();
//message pointer funcs
MESSAGE_FUNC_CHARPTR(OnFileSelected, "FileSelected", fullpath);
MESSAGE_FUNC_PARAMS(OnTextChanged, "TextChanged", data);
~CSoundscapeMaker();
private:
//the soundscape keyvalues file
KeyValues* m_KeyValues = nullptr;
private:
void CreateEverything();
private:
//lists all the soundscapes
CSoundscapeList* m_SoundscapesList;
CSoundscapeDataList* m_pDataList;
CSoundscapeRndwaveList* m_pSoundList;
//buttons
vgui::Button* m_ButtonNew = nullptr;
vgui::Button* m_ButtonSave = nullptr;
vgui::Button* m_ButtonLoad = nullptr;
//file load and save dialogs
vgui::FileOpenDialog* m_FileSave = nullptr;
vgui::FileOpenDialog* m_FileLoad = nullptr;
bool m_bWasFileLoad = false;
//text entry for name
vgui::TextEntry* m_TextEntryName;
//combo box for dsp effects
vgui::ComboBox* m_DspEffects;
vgui::ComboBox* m_SoundLevels;
//sound data text entry
vgui::TextEntry* m_TimeTextEntry;
vgui::TextEntry* m_VolumeTextEntry;
vgui::TextEntry* m_PitchTextEntry;
vgui::TextEntry* m_PositionTextEntry;
vgui::TextEntry* m_SoundNameTextEntry;
//play sound button
vgui::Button* m_SoundNamePlay;
//play/reset soundscape buttons
vgui::CheckButton* m_PlaySoundscapeButton;
vgui::Button* m_ResetSoundscapeButton;
vgui::Button* m_DeleteCurrentButton;
//current selected soundscape
vgui::Button* m_pCurrentSelected = nullptr;
KeyValues* m_kvCurrSelected = nullptr;
KeyValues* m_kvCurrSound = nullptr;
KeyValues* m_kvCurrRndwave = nullptr;
int m_iCurrRndWave = 0;
//currently in non randomwave thing
SoundscapeMode m_iSoundscapeMode = SoundscapeMode::Mode_Random;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor for soundscape maker panel
//-----------------------------------------------------------------------------
CSoundscapeMaker::CSoundscapeMaker(vgui::VPANEL parent)
: BaseClass(nullptr, "SoundscapeMaker")
{
//set variables
m_pCurrentSelected = nullptr;
SetParent(parent);
SetKeyBoardInputEnabled(true);
SetMouseInputEnabled(true);
SetProportional(false);
SetTitleBarVisible(true);
SetMinimizeButtonVisible(false);
SetMaximizeButtonVisible(false);
SetCloseButtonVisible(true);
SetSizeable(false);
SetMoveable(true);
SetVisible(g_ShowSoundscapePanel);
int ScreenWide, ScreenTall;
vgui::surface()->GetScreenSize(ScreenWide, ScreenTall);
SetTitle("Soundscape Maker (New File)", true);
SetSize(SOUNDSCAPE_PANEL_WIDTH, SOUNDSCAPE_PANEL_HEIGHT);
SetPos((ScreenWide - SOUNDSCAPE_PANEL_WIDTH) / 2, (ScreenTall - SOUNDSCAPE_PANEL_HEIGHT) / 2);
SetScheme(vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "SourceScheme"));
//add a tick signal for every 50 ms
vgui::ivgui()->AddTickSignal(GetVPanel(), 50);
CreateEverything();
}
//-----------------------------------------------------------------------------
// Purpose: Called every tick for the soundscape maker
//-----------------------------------------------------------------------------
void CSoundscapeMaker::CreateEverything()
{
//create the divider that will be the outline for the inside of the panel
vgui::Divider* PanelOutline = new vgui::Divider(this, "InsideOutline");
PanelOutline->SetEnabled(false);
PanelOutline->SetBounds(5, 25, SOUNDSCAPE_PANEL_WIDTH - 10, SOUNDSCAPE_PANEL_HEIGHT - 30);
//create the buttons
m_ButtonNew = new vgui::Button(this, "NewButton", "New Soundscape File");
m_ButtonNew->SetVisible(true);
m_ButtonNew->SetBounds(325, 566, 165, 25);
m_ButtonNew->SetCommand(NEW_BUTTON_COMMAND);
m_ButtonNew->SetDepressedSound("ui/buttonclickrelease.wav");
m_ButtonSave = new vgui::Button(this, "SaveButton", "Save Soundscapes");
m_ButtonSave->SetVisible(true);
m_ButtonSave->SetBounds(495, 566, 125, 25);
m_ButtonSave->SetCommand(SAVE_BUTTON_COMMAND);
m_ButtonSave->SetDepressedSound("ui/buttonclickrelease.wav");
m_ButtonLoad = new vgui::Button(this, "LoadButton", "Load Soundscapes");
m_ButtonLoad->SetVisible(true);
m_ButtonLoad->SetBounds(625, 566, 125, 25);
m_ButtonLoad->SetCommand(LOAD_BUTTON_COMMAND);
m_ButtonLoad->SetDepressedSound("ui/buttonclickrelease.wav");
//create the soundscapes menu
m_SoundscapesList = new CSoundscapeList(this, "SoundscapesList", "Soundscapes:", 90, 22, 300, 550);
m_SoundscapesList->SetBounds(15, 35, 300, 550);
m_SoundscapesList->SetVisible(true);
//create data list
m_pDataList = new CSoundscapeDataList(this, "SoudscapeDataList", "Soundscape Data:", 35, 10, 200, 280);
m_pDataList->SetBounds(327, 275, 200, 280);
m_pDataList->SetVisible(true);
//create sound list
m_pSoundList = new CSoundscapeRndwaveList(this, "SoudscapeDataList", "Random Sounds:", 40, 10, 200, 280);
m_pSoundList->SetBounds(542, 275, 200, 280);
m_pSoundList->SetVisible(true);
//name text entry
m_TextEntryName = new vgui::TextEntry(this, "NameTextEntry");
m_TextEntryName->SetEnabled(false);
m_TextEntryName->SetBounds(325, 40, 295, 20);
m_TextEntryName->SetMaximumCharCount(50);
//dsp effects combo box
m_DspEffects = new vgui::ComboBox(this, "DspEffects", sizeof(g_DspEffects) / sizeof(g_DspEffects[0]), false);
m_DspEffects->SetEnabled(false);
m_DspEffects->SetBounds(325, 65, 295, 20);
m_DspEffects->SetText("");
m_DspEffects->AddActionSignalTarget(this);
for (int i = 0; i < sizeof(g_DspEffects) / sizeof(g_DspEffects[i]); i++)
m_DspEffects->AddItem(g_DspEffects[i], nullptr);
//time text entry
m_TimeTextEntry = new vgui::TextEntry(this, "TimeTextEntry");
m_TimeTextEntry->SetBounds(325, 90, 295, 20);
m_TimeTextEntry->SetEnabled(false);
m_TimeTextEntry->SetVisible(true);
//volume text entry
m_VolumeTextEntry = new vgui::TextEntry(this, "VolumeTextEntry");
m_VolumeTextEntry->SetBounds(325, 115, 295, 20);
m_VolumeTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetVisible(true);
//pitch text entry
m_PitchTextEntry = new vgui::TextEntry(this, "PitchTextEntry");
m_PitchTextEntry->SetBounds(325, 140, 295, 20);
m_PitchTextEntry->SetEnabled(false);
m_PitchTextEntry->SetVisible(true);
//position text entry
m_PositionTextEntry = new vgui::TextEntry(this, "PositionTextEntry");
m_PositionTextEntry->SetBounds(325, 165, 295, 20);
m_PositionTextEntry->SetEnabled(false);
m_PositionTextEntry->SetVisible(true);
//sound levels
m_SoundLevels = new vgui::ComboBox(this, "SoundLevels", sizeof(g_SoundLevels) / sizeof(g_SoundLevels[0]), false);
m_SoundLevels->SetEnabled(false);
m_SoundLevels->SetBounds(325, 190, 295, 20);
m_SoundLevels->SetText("");
m_SoundLevels->AddActionSignalTarget(this);
for (int i = 0; i < sizeof(g_SoundLevels) / sizeof(g_SoundLevels[i]); i++)
m_SoundLevels->AddItem(g_SoundLevels[i], nullptr);
//sound name
m_SoundNameTextEntry = new vgui::TextEntry(this, "SoundName");
m_SoundNameTextEntry->SetBounds(325, 215, 215, 20);
m_SoundNameTextEntry->SetEnabled(false);
m_SoundNameTextEntry->SetVisible(true);
//play sound button
m_SoundNamePlay = new vgui::Button(this, "SoundPlayButton", "Sounds List");
m_SoundNamePlay->SetBounds(545, 215, 75, 20);
m_SoundNamePlay->SetCommand(SOUNDS_LIST_BUTTON_COMMAND);
m_SoundNamePlay->SetEnabled(false);
//starts the soundscape
m_PlaySoundscapeButton = new vgui::CheckButton(this, "PlaySoundscape", "Play Soundscape");
m_PlaySoundscapeButton->SetBounds(330, 243, 125, 20);
m_PlaySoundscapeButton->SetCommand(PLAY_SOUNDSCAPE_COMMAND);
m_PlaySoundscapeButton->SetEnabled(false);
m_PlaySoundscapeButton->SetSelected(false);
//reset soundscape button
m_ResetSoundscapeButton = new vgui::Button(this, "ResetSoundscape", "Restart Soundscape");
m_ResetSoundscapeButton->SetBounds(465, 243, 125, 20);
m_ResetSoundscapeButton->SetCommand(RESET_SOUNDSCAPE_BUTTON_COMMAND);
m_ResetSoundscapeButton->SetEnabled(false);
//delete this item
m_DeleteCurrentButton = new vgui::Button(this, "DeleteItem", "Delete Current Item");
m_DeleteCurrentButton->SetBounds(595, 243, 135, 20);
m_DeleteCurrentButton->SetCommand(DELETE_CURRENT_ITEM_COMMAND);
m_DeleteCurrentButton->SetEnabled(false);
//create the soundscape name text
vgui::Label* NameLabel = new vgui::Label(this, "NameLabel", "Soundscape Name");
NameLabel->SetBounds(635, 40, 125, 20);
//create the soundscape dsp text
vgui::Label* DspLabel = new vgui::Label(this, "DspLabel", "Soundscape Dsp");
DspLabel->SetBounds(635, 65, 125, 20);
//create the soundscape time text
vgui::Label* TimeLabel = new vgui::Label(this, "TimeLabel", "Sound Time");
TimeLabel->SetBounds(635, 90, 125, 20);
//create the soundscape volumn text
vgui::Label* VolumeLabel = new vgui::Label(this, "VolumeLabel", "Sound Volume");
VolumeLabel->SetBounds(635, 115, 125, 20);
//create the soundscape pitch text
vgui::Label* PitchLabel = new vgui::Label(this, "PitchLabel", "Sound Pitch");
PitchLabel->SetBounds(635, 140, 125, 20);
//create the soundscape position text
vgui::Label* PositionLabel = new vgui::Label(this, "PositionLabel", "Sound Position");
PositionLabel->SetBounds(635, 165, 125, 20);
//create the soundscape sound level text
vgui::Label* SoundLevelLabel = new vgui::Label(this, "SoundLevelLabel", "Sound Level");
SoundLevelLabel ->SetBounds(635, 190, 125, 20);
//create the soundscape sound name text
vgui::Label* SoundName = new vgui::Label(this, "SoundName", "Sound Name");
SoundName->SetBounds(635, 215, 125, 20);
//create the soundscape keyvalues and load it
m_KeyValues = new KeyValues("Empty Soundscape");
LoadFile(m_KeyValues);
}
//-----------------------------------------------------------------------------
// Purpose: Called every tick for the soundscape maker
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnTick()
{
//set the visibility
static bool bPrevVisible = g_ShowSoundscapePanel;
if (g_ShowSoundscapePanel != bPrevVisible)
SetVisible(g_ShowSoundscapePanel);
//set the old visibility
bPrevVisible = g_ShowSoundscapePanel;
}
//-----------------------------------------------------------------------------
// Purpose: Called when the close button is pressed
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnClose()
{
//hide the sound panel
g_SoundPanel->OnClose();
g_ShowSoundscapePanel = false;
}
//-----------------------------------------------------------------------------
// Purpose: Play the selected soundscape
//-----------------------------------------------------------------------------
void CSoundscapeMaker::PlaySelectedSoundscape()
{
g_IsPlayingSoundscape = false;
//stop all sounds
enginesound->StopAllSounds(true);
//stop the current soundscape and start a new soundscape
g_SoundscapeSystem.StartNewSoundscape(nullptr);
g_SoundscapeSystem.StartNewSoundscape(m_kvCurrSelected);
g_IsPlayingSoundscape = true;
}
//-----------------------------------------------------------------------------
// Purpose: Called when a button or something else gets pressed
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnCommand(const char* pszCommand)
{
//check for close command first
if (!Q_strcmp(pszCommand, "Close"))
{
BaseClass::OnCommand(pszCommand);
return;
}
//check for the save button command
else if (!Q_strcmp(pszCommand, SAVE_BUTTON_COMMAND))
{
//initalize the file save dialog
if (!m_FileSave)
{
//get the current game directory
char buf[512];
filesystem->RelativePathToFullPath("scripts", "MOD", buf, sizeof(buf));
//create the save dialog
m_FileSave = new vgui::FileOpenDialog(this, "Save Soundscape File", false);
m_FileSave->AddFilter("*.txt", "Soundscape Text File", true);
m_FileSave->AddFilter("*.*", "All Files (*.*)", false);
m_FileSave->SetStartDirectory(buf);
m_FileSave->AddActionSignalTarget(this);
}
//show the dialog
m_FileSave->DoModal(false);
m_FileSave->Activate();
//file wasnt loadad
m_bWasFileLoad = false;
return;
}
//check for load button command
else if (!Q_strcmp(pszCommand, LOAD_BUTTON_COMMAND))
{
//initalize the file save dialog
if (!m_FileLoad)
{
//get the current game directory
char buf[512];
filesystem->RelativePathToFullPath("scripts", "MOD", buf, sizeof(buf));
//create the load dialog
m_FileLoad = new vgui::FileOpenDialog(this, "Load Soundscape File", true);
m_FileLoad->AddFilter("*.txt", "Soundscape Text File", true);
m_FileLoad->AddFilter("*.*", "All Files (*.*)", false);
m_FileLoad->SetStartDirectory(buf);
m_FileLoad->AddActionSignalTarget(this);
}
//show the file load dialog
m_FileLoad->DoModal(false);
m_FileLoad->Activate();
//file was loadad
m_bWasFileLoad = true;
return;
}
//check for new soundscape
else if (!Q_strcmp(pszCommand, NEW_BUTTON_COMMAND))
{
//make sure you want to create a new soundscape file
vgui::QueryBox* popup = new vgui::QueryBox("New File?", "Are you sure you want to create a new soundscape file?", this);
popup->SetOKCommand(new KeyValues("Command", "command", RESET_BUTTON_COMMAND));
popup->SetCancelButtonVisible(false);
popup->AddActionSignalTarget(this);
popup->DoModal(this);
return;
}
//check for reset soundscape
else if (!Q_strcmp(pszCommand, RESET_BUTTON_COMMAND))
{
m_KeyValues->deleteThis();
m_KeyValues = new KeyValues("Empty Soundscape");
LoadFile(m_KeyValues);
return;
}
//check for play sound
else if (!Q_strcmp(pszCommand, SOUNDS_LIST_BUTTON_COMMAND))
{
//initalize the sounds
if (!g_SoundPanelInitalized)
{
g_SoundPanelInitalized = true;
g_SoundPanel->InitalizeSounds();
}
g_SoundPanel->SetVisible(true);
g_SoundPanel->MoveToFront();
g_SoundPanel->RequestFocus();
return;
}
//check for play soundscape
else if (!Q_strcmp(pszCommand, PLAY_SOUNDSCAPE_COMMAND))
{
if (m_PlaySoundscapeButton->IsSelected())
{
//enable the reset soundscape button
m_ResetSoundscapeButton->SetEnabled(true);
//play the soundscape
PlaySelectedSoundscape();
}
else
{
//disable the reset soundscape button
m_ResetSoundscapeButton->SetEnabled(false);
g_IsPlayingSoundscape = false;
//stop all sounds and soundscapes
enginesound->StopAllSounds(true);
g_SoundscapeSystem.StartNewSoundscape(nullptr);
}
return;
}
//check for play soundscape
else if (!Q_strcmp(pszCommand, RESET_SOUNDSCAPE_BUTTON_COMMAND))
{
PlaySelectedSoundscape();
return;
}
//check for delete item
else if (!Q_strcmp(pszCommand, DELETE_CURRENT_ITEM_COMMAND))
{
//check for current rndwave
if (m_kvCurrRndwave && m_SoundNameTextEntry->IsEnabled())
{
if (!m_kvCurrRndwave || m_iCurrRndWave <= 0)
return;
//get the keyvalues by the index
int curr = 0;
KeyValues* prev = nullptr;
FOR_EACH_VALUE(m_kvCurrRndwave, keyvalues)
{
if (++curr == m_iCurrRndWave)
{
//delete
if (prev)
prev->SetNextKey(keyvalues->GetNextValue());
else
{
m_kvCurrRndwave->m_pSub = keyvalues->GetNextValue();
m_iCurrRndWave = -1;
}
curr = curr - 1;
keyvalues->SetNextKey(nullptr);
keyvalues->deleteThis();
break;
}
prev = keyvalues;
}
//reset everything
m_SoundNameTextEntry->SetText("");
m_SoundNameTextEntry->SetEnabled(false);
m_SoundNamePlay->SetEnabled(false);
//store vector
auto& vec = m_pSoundList->m_MenuButtons;
//remove it
delete vec[curr];
vec.Remove(curr);
//move everything down
m_pSoundList->m_iCurrentY = m_pSoundList->m_iCurrentY - 22;
m_pSoundList->m_Keyvalues = m_kvCurrRndwave;
if (vec.Count() >= m_pSoundList->m_iMax)
{
m_pSoundList->OnMouseWheeled(1);
int min, max;
m_pSoundList->m_pSideSlider->GetRange(min, max);
m_pSoundList->m_pSideSlider->SetRange(0, max - 1);
}
for (int i = curr; i < vec.Count(); i++)
{
//move everything down
int x, y = 0;
vec[i]->GetPos(x, y);
vec[i]->SetPos(x, y - 22);
}
//reset every command
int WaveAmount = 0;
for (int i = 0; i < vec.Count(); i++)
{
//store data name
const char* name = vec[i]->GetCommand()->GetString("command");
//increment variables based on name
if (Q_stristr(name, "$rndwave") == name)
{
WaveAmount++;
vec[i]->SetCommand(CFmtStr("$rndwave%d", WaveAmount));
}
}
//bounds check
if (vec.Count() <= 0)
return;
//select next item
if (m_iCurrRndWave <= vec.Count())
OnCommand(CFmtStr("$rndwave%d", curr + 1));
else
OnCommand(CFmtStr("$rndwave%d", curr));
}
else if (m_kvCurrSound)
{
if (!m_kvCurrSelected)
return;
//find keyvalue with same pointer and get the index
int tmpindex = 0;
int index = -1;
KeyValues* prev = nullptr;
FOR_EACH_TRUE_SUBKEY(m_kvCurrSelected, keyvalues)
{
if (m_kvCurrSound == keyvalues)
{
//remove it
if (prev)
prev->SetNextKey(keyvalues->GetNextTrueSubKey());
else
m_kvCurrSelected->m_pSub = keyvalues->GetNextTrueSubKey();
keyvalues->SetNextKey(nullptr);
keyvalues->deleteThis();
//get index
index = tmpindex;
break;
}
prev = keyvalues;
//increment
tmpindex++;
}
//error
if (index == -1)
return;
//store vector
auto& vec = m_pDataList->m_MenuButtons;
//remove it
delete vec[index];
vec.Remove(index);
//move everything down
m_pDataList->m_iCurrentY = m_pDataList->m_iCurrentY - 22;
m_pDataList->m_Keyvalues = m_kvCurrSelected;
for (int i = index; i < vec.Count(); i++)
{
//move everything down
int x, y = 0;
vec[i]->GetPos(x, y);
vec[i]->SetPos(x, y - 22);
}
if (vec.Count() >= m_pDataList->m_iMax)
{
m_pDataList->OnMouseWheeled(1);
int min, max;
m_pDataList->m_pSideSlider->GetRange(min, max);
m_pDataList->m_pSideSlider->SetRange(0, max - 1);
}
//reset the names of each button
int RandomNum = 0;
int LoopingNum = 0;
int SoundscapeNum = 0;
for (int i = 0; i < vec.Count(); i++)
{
//store data name
const char* name = vec[i]->GetCommand()->GetString("command");
//increment variables based on name
if (Q_stristr(name, "$playrandom") == name)
{
RandomNum++;
vec[i]->SetCommand(CFmtStr("$playrandom%d", RandomNum));
}
if (Q_stristr(name, "$playlooping") == name)
{
LoopingNum++;
vec[i]->SetCommand(CFmtStr("$playlooping%d", LoopingNum));
}
if (Q_stristr(name, "$playsoundscape") == name)
{
SoundscapeNum++;
vec[i]->SetCommand(CFmtStr("$playsoundscape%d", SoundscapeNum));
}
}
//reset everything
m_SoundLevels->SetText("");
m_SoundNameTextEntry->SetText("");
m_TimeTextEntry->SetText("");
m_PitchTextEntry->SetText("");
m_PositionTextEntry->SetText("");
m_VolumeTextEntry->SetText("");
m_SoundLevels->SetEnabled(false);
m_SoundNameTextEntry->SetEnabled(false);
m_TimeTextEntry->SetEnabled(false);
m_PitchTextEntry->SetEnabled(false);
m_PositionTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetEnabled(false);
m_SoundNamePlay->SetEnabled(false);
m_pSoundList->Clear();
m_kvCurrSound = nullptr;
m_pSoundList->m_Keyvalues = nullptr;
}
else if (m_kvCurrSelected)
{
if (m_KeyValues == m_kvCurrSelected)
{
//play an error sound
vgui::surface()->PlaySound("resource/warning.wav");
//show an error
vgui::QueryBox* popup = new vgui::QueryBox("Error", "Can not delete base soundscape!", this);
popup->SetOKButtonText("Ok");
popup->SetCancelButtonVisible(false);
popup->AddActionSignalTarget(this);
popup->DoModal(this);
return;
}
//find keyvalue with same pointer and get the index
int tmpindex = 0;
int index = -1;
KeyValues* prev = nullptr;
for (KeyValues* keyvalues = m_KeyValues; keyvalues != nullptr; keyvalues = keyvalues->GetNextTrueSubKey())
{
if (m_kvCurrSelected == keyvalues)
{
//remove it
if (!prev)
break;
prev->SetNextKey(keyvalues->GetNextTrueSubKey());
keyvalues->SetNextKey(nullptr);
keyvalues->deleteThis();
//get index
index = tmpindex;
break;
}
prev = keyvalues;
//increment
tmpindex++;
}
//error
if (index == -1)
return;
//store vector
auto& vec = m_SoundscapesList->m_MenuButtons;
//remove it
delete vec[index];
vec.Remove(index);
//move everything down
m_SoundscapesList->m_iCurrentY = m_SoundscapesList->m_iCurrentY - 22;
for (int i = index; i < vec.Count(); i++)
{
//move everything down
int x, y = 0;
vec[i]->GetPos(x, y);
vec[i]->SetPos(x, y - 22);
}
if (vec.Count() >= m_SoundscapesList->m_iMax)
{
m_SoundscapesList->OnMouseWheeled(1);
int min, max;
m_SoundscapesList->m_pSideSlider->GetRange(min, max);
m_SoundscapesList->m_pSideSlider->SetRange(0, max - 1);
}
//reset everything
m_DspEffects->SetText("");
m_SoundLevels->SetText("");
m_TextEntryName->SetText("");
m_SoundNameTextEntry->SetText("");
m_TimeTextEntry->SetText("");
m_PitchTextEntry->SetText("");
m_PositionTextEntry->SetText("");
m_VolumeTextEntry->SetText("");
m_DspEffects->SetEnabled(false);
m_SoundLevels->SetEnabled(false);
m_TextEntryName->SetEnabled(false);
m_SoundNameTextEntry->SetEnabled(false);
m_TimeTextEntry->SetEnabled(false);
m_PitchTextEntry->SetEnabled(false);
m_PositionTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetEnabled(false);
m_SoundNamePlay->SetEnabled(false);
m_pDataList->Clear();
m_pSoundList->Clear();
m_kvCurrSound = nullptr;
m_pDataList->m_Keyvalues = nullptr;
//go to next soundscape
if (!prev)
return;
if (prev->GetNextTrueSubKey())
OnCommand(prev->GetNextTrueSubKey()->GetName());
else
OnCommand(prev->GetName());
}
return;
}
//check for "playrandom", "playsoundscape" or "playlooping"
if (Q_stristr(pszCommand, "$playrandom") == pszCommand)
{
//get the selected number
char* str_number = (char*)(pszCommand + 11);
int number = atoi(str_number);
if (number != 0)
{
//clear the m_pSoundList
m_pSoundList->Clear();
m_pSoundList->m_Keyvalues = nullptr;
//store variables
KeyValues* data = nullptr;
int curr = 0;
//get subkey
FOR_EACH_TRUE_SUBKEY(m_kvCurrSelected, sounds)
{
if (Q_strcasecmp(sounds->GetName(), "playrandom"))
continue;
if (++curr == number)
{
data = sounds;
break;
}
}
//no data
if (!data)
return;
m_kvCurrSound = data;
m_kvCurrRndwave = nullptr;
//set the random times
m_TimeTextEntry->SetText(data->GetString("time", "10,20"));
m_VolumeTextEntry->SetText(data->GetString("volume", "0.5,0.8"));
m_PitchTextEntry->SetText(data->GetString("pitch", "100"));
m_PositionTextEntry->SetText(data->GetString("position", ""));
m_SoundNameTextEntry->SetText("");
//get snd level index
int index = 8; //8 = SNDLVL_NORM
const char* name = data->GetString("soundlevel", nullptr);
//check for the name
if (name)
{
//loop through the sound levels to find the right one
for (int i = 0; i < sizeof(g_SoundLevels) / sizeof(g_SoundLevels[i]); i++)
{
if (!Q_strcmp(name, g_SoundLevels[i]))
{
index = i;
break;
}
}
}
//select the index
m_SoundLevels->ActivateItem(index);
//enable the text entries
m_TimeTextEntry->SetEnabled(true);
m_VolumeTextEntry->SetEnabled(true);
m_PitchTextEntry->SetEnabled(true);
m_PositionTextEntry->SetEnabled(true);
m_SoundLevels->SetEnabled(true);
m_SoundNameTextEntry->SetEnabled(false);
m_SoundNamePlay->SetEnabled(false);
g_SoundPanel->OnCommand(SOUND_LIST_STOP_COMMAND);
g_SoundPanel->SetVisible(false);
//check for randomwave subkey
if ((data = data->FindKey("rndwave")) == nullptr)
return;
m_kvCurrRndwave = data;
m_pSoundList->m_Keyvalues = data;
//add all the data
int i = 0;
FOR_EACH_VALUE(data, sound)
{
const char* name = sound->GetName();
m_pSoundList->AddButton(name, sound->GetString(), CFmtStr("$rndwave%d", ++i), this);
}
m_iSoundscapeMode = SoundscapeMode::Mode_Random;
return;
}
}
else if (Q_stristr(pszCommand, "$playlooping") == pszCommand)
{
//get the selected number
char* str_number = (char*)(pszCommand + 12);
int number = atoi(str_number);
if (number != 0)
{
//clear the m_pSoundList
m_pSoundList->Clear();
m_pSoundList->m_Keyvalues = nullptr;
//store variables
KeyValues* data = nullptr;
int curr = 0;
//get subkey
FOR_EACH_TRUE_SUBKEY(m_kvCurrSelected, sounds)
{
if (Q_strcasecmp(sounds->GetName(), "playlooping"))
continue;
if (++curr == number)
{
data = sounds;
break;
}
}
//no data
if (!data)
return;
m_kvCurrSound = data;
m_kvCurrRndwave = nullptr;
//set the random times
m_TimeTextEntry->SetText("");
m_VolumeTextEntry->SetText(data->GetString("volume", "1"));
m_PitchTextEntry->SetText(data->GetString("pitch", "100"));
m_PositionTextEntry->SetText(data->GetString("position", ""));
m_SoundNameTextEntry->SetText(data->GetString("wave", ""));
//get snd level index
int index = 8; //8 = SNDLVL_NORM
const char* name = data->GetString("soundlevel", nullptr);
//check for the name
if (name)
{
//loop through the sound levels to find the right one
for (int i = 0; i < sizeof(g_SoundLevels) / sizeof(g_SoundLevels[i]); i++)
{
if (!Q_strcmp(name, g_SoundLevels[i]))
{
index = i;
break;
}
}
}
//select the index
m_SoundLevels->ActivateItem(index);
//enable the text entries
m_TimeTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetEnabled(true);
m_PitchTextEntry->SetEnabled(true);
m_PositionTextEntry->SetEnabled(true);
m_SoundLevels->SetEnabled(true);
m_SoundNameTextEntry->SetEnabled(true);
m_SoundNamePlay->SetEnabled(true);
g_SoundPanel->SetVisible(false);
m_iSoundscapeMode = SoundscapeMode::Mode_Looping;
return;
}
}
else if (Q_stristr(pszCommand, "$playsoundscape") == pszCommand)
{
//get the selected number
char* str_number = (char*)(pszCommand + 15);
int number = atoi(str_number);
if (number != 0)
{
//clear the m_pSoundList
m_pSoundList->Clear();
m_pSoundList->m_Keyvalues = nullptr;
//store variables
KeyValues* data = nullptr;
int curr = 0;
//get subkey
FOR_EACH_TRUE_SUBKEY(m_kvCurrSelected, sounds)
{
if (Q_strcasecmp(sounds->GetName(), "playsoundscape"))
continue;
if (++curr == number)
{
data = sounds;
break;
}
}
//no data
if (!data)
return;
m_kvCurrSound = data;
m_kvCurrRndwave = nullptr;
//set the random times
m_TimeTextEntry->SetText("");
m_VolumeTextEntry->SetText(data->GetString("volume", "1"));
m_PitchTextEntry->SetText(data->GetString("pitch", "100"));
m_PositionTextEntry->SetText(data->GetString("positionoverride", ""));
m_SoundNameTextEntry->SetText(data->GetString("name", ""));
//get snd level index
int index = 8; //8 = SNDLVL_NORM
const char* name = data->GetString("soundlevel", nullptr);
//check for the name
if (name)
{
//loop through the sound levels to find the right one
for (int i = 0; i < sizeof(g_SoundLevels) / sizeof(g_SoundLevels[i]); i++)
{
if (!Q_strcmp(name, g_SoundLevels[i]))
{
index = i;
break;
}
}
}
//select the index
m_SoundLevels->ActivateItem(index);
//enable the text entries
m_TimeTextEntry->SetEnabled(true);
m_VolumeTextEntry->SetEnabled(true);
m_PitchTextEntry->SetEnabled(true);
m_PositionTextEntry->SetEnabled(true);
m_SoundLevels->SetEnabled(true);
m_SoundNameTextEntry->SetEnabled(true);
m_TimeTextEntry->SetEnabled(false);
m_SoundNamePlay->SetEnabled(false);
g_SoundPanel->OnCommand(SOUND_LIST_STOP_COMMAND);
g_SoundPanel->SetVisible(false);
m_iSoundscapeMode = SoundscapeMode::Mode_Soundscape;
return;
}
}
else if (Q_stristr(pszCommand, "$rndwave") == pszCommand)
{
if (!m_kvCurrRndwave)
return;
//get the selected number
char* str_number = (char*)(pszCommand + 8);
m_iCurrRndWave = atoi(str_number);
if (m_iCurrRndWave != 0)
{
int i = 0;
//get value
KeyValues* curr = nullptr;
FOR_EACH_VALUE(m_kvCurrRndwave, wave)
{
if (++i == m_iCurrRndWave)
{
curr = wave;
break;
}
}
//if no curr then throw an error
if (!curr)
{
//play an error sound
vgui::surface()->PlaySound("resource/warning.wav");
//show error
char buf[1028];
Q_snprintf(buf, sizeof(buf), "Failed to get rndwave '%d' for subkey \"%s\"\nfor current soundscape file!", i, m_kvCurrSelected->GetName());
//show an error
vgui::QueryBox* popup = new vgui::QueryBox("Error", buf, this);
popup->SetOKButtonText("Ok");
popup->SetCancelButtonVisible(false);
popup->AddActionSignalTarget(this);
popup->DoModal(this);
return;
}
m_SoundNameTextEntry->SetEnabled(true);
m_SoundNameTextEntry->SetText(curr->GetString());
m_SoundNamePlay->SetEnabled(true);
m_iSoundscapeMode = SoundscapeMode::Mode_Random;
return;
}
}
//look for button with the same name as the command
{
//store vars
CUtlVector<vgui::Button*>& array = m_SoundscapesList->m_MenuButtons;
//check for name
for (int i = 0; i < m_SoundscapesList->m_MenuButtons.Size(); i++)
{
//check button name
if (!Q_strcmp(array[i]->GetName(), pszCommand))
{
//found it
m_pCurrentSelected = array[i];
break;
}
}
//find selected keyvalue
//set needed stuff
if (m_pCurrentSelected)
{
m_DeleteCurrentButton->SetEnabled(false);
//reset the selected kv
m_kvCurrSelected = nullptr;
//find selected keyvalues
for (KeyValues* kv = m_KeyValues; kv != nullptr; kv = kv->GetNextTrueSubKey())
{
if (!Q_strcmp(kv->GetName(), pszCommand))
{
m_kvCurrSelected = kv;
break;
}
}
//if no selected then add it
if (!m_kvCurrSelected)
{
KeyValues* kv = new KeyValues(pszCommand);
//add to last subkey
KeyValues* tmp = m_KeyValues;
KeyValues* tmp2 = tmp;
while (tmp != nullptr)
{
tmp2 = tmp;
tmp = tmp->GetNextTrueSubKey();
}
tmp2->SetNextKey(kv);
m_kvCurrSelected = kv;
}
//set
m_kvCurrSound = nullptr;
m_kvCurrRndwave = nullptr;
m_TimeTextEntry->SetEnabled(false);
m_TimeTextEntry->SetText("");
m_VolumeTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetText("");
m_PitchTextEntry->SetEnabled(false);
m_PitchTextEntry->SetText("");
m_PositionTextEntry->SetEnabled(false);
m_PositionTextEntry->SetText("");
m_SoundLevels->SetEnabled(false);
m_SoundLevels->SetText("");
m_SoundNameTextEntry->SetEnabled(false);
m_SoundNameTextEntry->SetText("");
m_SoundNamePlay->SetEnabled(false);
if (g_SoundPanel)
{
g_SoundPanel->OnCommand(SOUND_LIST_STOP_COMMAND);
g_SoundPanel->SetVisible(false);
}
//check for current keyvalues. should never bee nullptr but could be
if (!m_kvCurrSelected)
{
//play an error sound
vgui::surface()->PlaySound("resource/warning.wav");
//show error
char buf[1028];
Q_snprintf(buf, sizeof(buf), "Failed to find KeyValue subkey \"%s\"\nfor current soundscape file!", pszCommand);
//show an error
vgui::QueryBox* popup = new vgui::QueryBox("Error", buf, this);
popup->SetOKButtonText("Ok");
popup->SetCancelButtonVisible(false);
popup->AddActionSignalTarget(this);
popup->DoModal(this);
//reset vars
m_pCurrentSelected = nullptr;
m_TextEntryName->SetEnabled(false);
m_TextEntryName->SetText("");
m_DspEffects->SetEnabled(false);
m_DspEffects->SetText("");
return;
}
if (g_IsPlayingSoundscape)
PlaySelectedSoundscape();
m_DeleteCurrentButton->SetEnabled(true);
//set current soundscape name
m_TextEntryName->SetText(pszCommand);
m_TextEntryName->SetEnabled(true);
m_pDataList->m_Keyvalues = m_kvCurrSelected;
//set dsp effect
int dsp = Clamp<int>(m_kvCurrSelected->GetInt("dsp"), 0, 29);
m_PlaySoundscapeButton->SetEnabled(true);
m_DspEffects->SetEnabled(true);
m_DspEffects->ActivateItem(dsp);
//clear these
m_pDataList->Clear();
m_pSoundList->Clear();
m_pSoundList->m_Keyvalues = nullptr;
//set variables
int RandomNum = 0;
int LoopingNum = 0;
int SoundscapeNum = 0;
FOR_EACH_TRUE_SUBKEY(m_kvCurrSelected, data)
{
//store data name
const char* name = data->GetName();
//increment variables based on name
if (!Q_strcasecmp(name, "playrandom"))
{
RandomNum++;
m_pDataList->AddButton(data->GetName(), data->GetName(), CFmtStr("$playrandom%d", RandomNum), this);
}
if (!Q_strcasecmp(name, "playlooping"))
{
LoopingNum++;
m_pDataList->AddButton(data->GetName(), data->GetName(), CFmtStr("$playlooping%d", LoopingNum), this);
}
if (!Q_strcasecmp(name, "playsoundscape"))
{
SoundscapeNum++;
m_pDataList->AddButton(data->GetName(), data->GetName(), CFmtStr("$playsoundscape%d", SoundscapeNum), this);
}
}
}
}
BaseClass::OnCommand(pszCommand);
}
//-----------------------------------------------------------------------------
// Purpose: Called when a file gets opened/closed
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnFileSelected(const char* pszFileName)
{
//check for null or empty string
if (!pszFileName || pszFileName[0] == '\0')
return;
//check for file save
if (!m_bWasFileLoad)
{
//save the file
if (m_KeyValues)
{
//write everything into a buffer
CUtlBuffer buf(0, 0, CUtlBuffer::TEXT_BUFFER);
buf.PutString("//------------------------------------------------------------------------------------\n");
buf.PutString("//\n");
buf.PutString("// Auto-generated soundscape file created with WadDelz's soundscape tool'\n");
buf.PutString("//\n");
buf.PutString("//------------------------------------------------------------------------------------\n");
//now write the keyvalues
KeyValues* pCurrent = m_KeyValues;
while (pCurrent)
{
pCurrent->RecursiveSaveToFile(buf, 0);
pCurrent = pCurrent->GetNextKey();
//put a newline
buf.PutChar('\n');
}
g_pFullFileSystem->WriteFile(pszFileName, "MOD", buf);
}
//store vars
const char* last = pszFileName;
const char* tmp = nullptr;
//get the last /
while ((last = Q_strstr(last, "\\")) != nullptr)
tmp = ++last; //move past the backslash
//check tmp
if (!tmp || !*tmp)
tmp = pszFileName;
//set new title
char buf[1028];
Q_snprintf(buf, sizeof(buf), "Soundscape Maker (%s)", tmp);
SetTitle(buf, true);
return;
}
//try and load the keyvalues file first
KeyValues* temp = new KeyValues("SoundscapeFile");
if (!temp->LoadFromFile(filesystem, pszFileName))
{
//play an error sound
vgui::surface()->PlaySound("resource/warning.wav");
//get the error first
char buf[1028];
Q_snprintf(buf, sizeof(buf), "Failed to open keyvalues file \"%s\"", pszFileName);
//show an error
vgui::QueryBox* popup = new vgui::QueryBox("Error", buf, this);
popup->SetOKButtonText("Ok");
popup->SetCancelButtonVisible(false);
popup->AddActionSignalTarget(this);
popup->DoModal(this);
temp->deleteThis();
return;
}
//set the new title
{
//store vars
const char* last = pszFileName;
const char* tmp = nullptr;
//get the last /
while ((last = Q_strstr(last, "\\")) != nullptr)
tmp = ++last; //move past the backslash
//check tmp
if (!tmp || !*tmp)
tmp = pszFileName;
//create the new new title
char buf[1028];
Q_snprintf(buf, sizeof(buf), "Soundscape Maker (%s)", tmp);
SetTitle(buf, true);
}
//delete and set the old keyvalues
if (m_KeyValues)
m_KeyValues->deleteThis();
m_KeyValues = temp;
//load the file
LoadFile(m_KeyValues);
}
//-----------------------------------------------------------------------------
// Purpose: Called when a text thing changes
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnTextChanged(KeyValues* keyvalues)
{
//check for these things
if (!m_pCurrentSelected || !m_kvCurrSelected)
return;
//check to see if the current focus is the text text entry
if (m_TextEntryName->HasFocus())
{
//get text
char buf[50];
m_TextEntryName->GetText(buf, sizeof(buf));
//set current text and keyvalue name
m_pCurrentSelected->SetText(buf);
m_kvCurrSelected->SetName(buf);
return;
}
//set dsp
m_kvCurrSelected->SetInt("dsp", Clamp<int>(m_DspEffects->GetActiveItem(), 0, 28));
//if the m_kvCurrSound is nullptr then dont do the rest of the stuff
if (!m_kvCurrSound)
return;
//set the curr sound and stuff
if (m_TimeTextEntry->HasFocus())
{
//get text
char buf[38];
m_TimeTextEntry->GetText(buf, sizeof(buf));
m_kvCurrSound->SetString("time", buf);
return;
}
else if (m_VolumeTextEntry->HasFocus())
{
//get text
char buf[38];
m_VolumeTextEntry->GetText(buf, sizeof(buf));
m_kvCurrSound->SetString("volume", buf);
return;
}
else if (m_PitchTextEntry->HasFocus())
{
//get text
char buf[38];
m_PitchTextEntry->GetText(buf, sizeof(buf));
m_kvCurrSound->SetString("pitch", buf);
return;
}
else if (m_PositionTextEntry->HasFocus())
{
//get text
char buf[38];
m_PositionTextEntry->GetText(buf, sizeof(buf));
//if the string is empty then remove the position instead
if (!buf[0])
{
if (m_iSoundscapeMode == SoundscapeMode::Mode_Soundscape)
m_kvCurrSound->RemoveSubKey(m_kvCurrSound->FindKey("positionoverride"));
else
m_kvCurrSound->RemoveSubKey(m_kvCurrSound->FindKey("position"));
}
else
{
if (m_iSoundscapeMode == SoundscapeMode::Mode_Soundscape)
m_kvCurrSound->SetString("positionoverride", buf);
else
m_kvCurrSound->SetString("position", buf);
}
return;
}
//get the sound level amount
int sndlevel = Clamp<int>(m_SoundLevels->GetActiveItem(), 0, 20);
m_kvCurrSound->SetString("soundlevel", g_SoundLevels[sndlevel]);
//set soundscape name/wave
if (m_SoundNameTextEntry->HasFocus())
{
//get text
char buf[512];
m_SoundNameTextEntry->GetText(buf, sizeof(buf));
if (m_iSoundscapeMode == SoundscapeMode::Mode_Looping)
m_kvCurrSound->SetString("wave", buf);
else if (m_iSoundscapeMode == SoundscapeMode::Mode_Soundscape)
m_kvCurrSound->SetString("name", buf);
else if (m_iSoundscapeMode == SoundscapeMode::Mode_Random && m_kvCurrRndwave)
{
//get value
int i = 0;
FOR_EACH_VALUE(m_kvCurrRndwave, wave)
{
if (++i == m_iCurrRndWave)
{
wave->SetStringValue(buf);
//set text on the sounds panel
vgui::Button* button = m_pSoundList->m_MenuButtons[i - 1];
if (button)
button->SetText(buf);
break;
}
}
}
return;
}
}
//-----------------------------------------------------------------------------
// Purpose: Destructor for soundscape maker panel
//-----------------------------------------------------------------------------
void CSoundscapeMaker::LoadFile(KeyValues* file)
{
//clear all the text's
m_TextEntryName->SetEnabled(false);
m_TextEntryName->SetText("");
m_DspEffects->SetEnabled(false);
m_DspEffects->SetText("");
m_TimeTextEntry->SetEnabled(false);
m_TimeTextEntry->SetText("");
m_VolumeTextEntry->SetEnabled(false);
m_VolumeTextEntry->SetText("");
m_PitchTextEntry->SetEnabled(false);
m_PitchTextEntry->SetText("");
m_PositionTextEntry->SetEnabled(false);
m_PositionTextEntry->SetText("");
m_SoundNameTextEntry->SetEnabled(false);
m_SoundNameTextEntry->SetText("");
m_SoundNamePlay->SetEnabled(false);
if (g_SoundPanel)
{
g_SoundPanel->OnCommand(SOUND_LIST_STOP_COMMAND);
g_SoundPanel->SetVisible(false);
}
m_PlaySoundscapeButton->SetEnabled(false);
m_PlaySoundscapeButton->SetSelected(false);
m_ResetSoundscapeButton->SetEnabled(false);
m_DeleteCurrentButton->SetEnabled(false);
//clear current file
m_pCurrentSelected = nullptr;
m_kvCurrSelected = nullptr;
m_kvCurrSound = nullptr;
m_kvCurrRndwave = nullptr;
//clear the menu items
m_SoundscapesList->Clear();
m_pSoundList->Clear();
m_pDataList->Clear();
m_SoundscapesList->m_Keyvalues = file;
m_pDataList->m_Keyvalues = nullptr;
m_pSoundList->m_Keyvalues = nullptr;
//stop all soundscapes
if (g_IsPlayingSoundscape)
PlaySelectedSoundscape();
g_IsPlayingSoundscape = false;
//temp soundscapes list
CUtlVector<const char*> Added;
//add all the menu items
for (KeyValues* soundscape = file; soundscape != nullptr; soundscape = soundscape->GetNextTrueSubKey())
{
//add the menu buttons
const char* name = soundscape->GetName();
//check for the soundscape first
if (Added.Find(name) != Added.InvalidIndex())
{
ConWarning("CSoundscapePanel: Failed to add repeated soundscape '%s'\n", name);
continue;
}
Added.AddToTail(name);
m_SoundscapesList->AddButton(name, name, name, this);
}
//
OnCommand(file->GetName());
}
//-----------------------------------------------------------------------------
// Purpose: Sets the sounds text
//-----------------------------------------------------------------------------
void CSoundscapeMaker::SetSoundText(const char* text)
{
m_SoundNameTextEntry->SetText(text);
//set soundscape name/wave
if (m_iSoundscapeMode != SoundscapeMode::Mode_Random)
{
m_kvCurrSound->SetString("wave", text);
}
else
{
//get value
int i = 0;
FOR_EACH_VALUE(m_kvCurrRndwave, wave)
{
if (++i == m_iCurrRndWave)
{
wave->SetStringValue(text);
//set text on the sounds panel
vgui::Button* button = m_pSoundList->m_MenuButtons[i - 1];
if (button)
button->SetText(text);
break;
}
}
}
return;
}
//-----------------------------------------------------------------------------
// Purpose: Called when a keyboard key is pressed
//-----------------------------------------------------------------------------
void CSoundscapeMaker::OnKeyCodePressed(vgui::KeyCode code)
{
//check for ctrl o or ctrl s
if (vgui::input()->IsKeyDown(vgui::KeyCode::KEY_LCONTROL))
{
if (code == vgui::KeyCode::KEY_O)
OnCommand(LOAD_BUTTON_COMMAND);
else if (code == vgui::KeyCode::KEY_S)
OnCommand(SAVE_BUTTON_COMMAND);
else if (code == vgui::KeyCode::KEY_N)
OnCommand(NEW_BUTTON_COMMAND);
return;
}
//get key bound to this
const char* key = engine->Key_LookupBinding("modbase_soundscape_panel");
if (!key)
return;
//convert the key to a keyboard code
const char* keystring = KeyCodeToString(code);
//remove the KEY_ if found
if (Q_strstr(keystring, "KEY_") == keystring)
keystring = keystring + 4;
//check both strings
if (!Q_strcasecmp(key, keystring))
OnClose();
}
//-----------------------------------------------------------------------------
// Purpose: Starts the soundscape on map spawn
//-----------------------------------------------------------------------------
void CSoundscapeMaker::LevelInitPostEntity()
{
if (g_IsPlayingSoundscape)
PlaySelectedSoundscape();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor for soundscape maker panel
//-----------------------------------------------------------------------------
CSoundscapeMaker::~CSoundscapeMaker()
{
//delete the keyvalue files if needed
if (m_KeyValues)
m_KeyValues->deleteThis();
}
//interface class
class CSoundscapeMakerInterface : public ISoundscapeMaker
{
public:
void Create(vgui::VPANEL parent)
{
m_Panel = new CSoundscapeMaker(parent);
g_SoundPanel = new CSoundListPanel(parent, "SoundListPanel");
}
void SetVisible(bool bVisible)
{
if (m_Panel)
m_Panel->SetVisible(bVisible);
}
void Destroy()
{
if (m_Panel)
m_Panel->DeletePanel();
if (g_SoundPanel)
g_SoundPanel->DeletePanel();
m_Panel = nullptr;
g_SoundPanel = nullptr;
}
void SetSoundText(const char* text)
{
m_Panel->SetSoundText(text);
m_Panel->RequestFocus();
m_Panel->MoveToFront();
}
private:
CSoundscapeMaker* m_Panel;
};
CSoundscapeMakerInterface SoundscapeMaker;
ISoundscapeMaker* g_SoundscapeMaker = &SoundscapeMaker;
//-----------------------------------------------------------------------------
// Purpose: Command to toggle the soundscape panel
//-----------------------------------------------------------------------------
CON_COMMAND(modbase_soundscape_panel, "Toggles the modebase soundscape panel")
{
g_ShowSoundscapePanel = !g_ShowSoundscapePanel;
SoundscapeMaker.SetVisible(g_ShowSoundscapePanel);
}