Programming/creating vgui soundscape maker: Difference between revisions
| WadDelz0949 (talk | contribs)  (Added new tutorial for updated options panel for vgui soundscape maker) | WadDelz0949 (talk | contribs)  m (fixed 			Vector vec = g_SoundscapePositions[i]; being                after  			if (g_bUsingVector[i] == false || vec == vec3_origin)) | ||
| (9 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
| This tutorial will show you how to make a vgui soundscape maker panel that allows you to modify, create, and play soundscapes in game. | This tutorial will show you how to make a vgui soundscape maker panel that allows you to modify, create, and play soundscapes in game. | ||
| [[File:Soundscape  | [[File:Vgui Soundscape maker panel in game.png|thumb|alt=All panels for vgui soundscape maker in game|All panels for vgui soundscape maker in game]] | ||
| ==Requirements== | ==Requirements== | ||
| Line 47: | Line 47: | ||
| g_SoundscapeMaker->Destroy(); | g_SoundscapeMaker->Destroy(); | ||
| </source> | </source> | ||
| <br> | |||
| Now go to '''public\tier1\KeyValues.h''' and find: | Now go to '''public\tier1\KeyValues.h''' and find: | ||
| <source lang=cpp> | <source lang=cpp> | ||
| Line 58: | Line 58: | ||
| 	KeyValues( KeyValues& );	// prevent copy constructor being used | 	KeyValues( KeyValues& );	// prevent copy constructor being used | ||
| </source> | </source> | ||
| <br> | |||
| Now go to '''public\vgui_controls\TextEntry.h''' and find: | |||
| <source lang=cpp> | |||
| 	virtual void GetTextRange( char *buf, int from, int numchars );	// copy a portion of the text to the buffer and add zero-termination | |||
| private: | |||
| 	CUtlVector<wchar_t> m_TextStream;		// the text in the text window is stored in this buffer | |||
| </source> | |||
| (should be around line 318) and make that be: | |||
| <source lang=cpp> | |||
| 	virtual void GetTextRange( char *buf, int from, int numchars );	// copy a portion of the text to the buffer and add zero-termination | |||
| public: | |||
| 	CUtlVector<wchar_t> m_TextStream;		// the text in the text window is stored in this buffer | |||
| </source> | |||
| <br> | |||
| Now go to '''client/c_soundscape.cpp'''  and copy: | Now go to '''client/c_soundscape.cpp'''  and copy: | ||
| <source lang=cpp> | <source lang=cpp> | ||
| Line 63: | Line 81: | ||
| extern bool g_IsPlayingSoundscape; | extern bool g_IsPlayingSoundscape; | ||
| extern bool g_bSSMHack; | |||
| //debug stuff | |||
| void SoundscapePrint(Color color, const char* msg, ...); | |||
| void SoundscapeAddLine(Color color, float speed, float width, bool accending); | |||
| int SoundscapeGetLineNum(); | |||
| </source> | </source> | ||
| to be under | to be under | ||
| Line 74: | Line 98: | ||
| </source> | </source> | ||
| now find the function: '''void C_SoundscapeSystem::StartNewSoundscape( KeyValues *pSoundscape )''' and at the very top of it and before '''int i;''' add: | now find the function: '''void C_SoundscapeSystem::StartNewSoundscape( KeyValues *pSoundscape )''' and at the very top of it and before '''int i;''' add: | ||
| <source lang=cpp> | |||
| if (g_IsPlayingSoundscape && !g_bSSMHack) | |||
| 	return; | |||
| </source> | |||
| Now find '''StartSubSoundscape( pSoundscapeKeys, subParams );''' inside '''void C_SoundscapeSystem::ProcessPlaySoundscape( KeyValues *pPlaySoundscape, subsoundscapeparams_t ¶msIn )''' and under it add | |||
| <source lang=cpp> | |||
| if (g_IsPlayingSoundscape) | |||
| 	SoundscapePrint(Color(100, 255, 0, 255), "Playing Sub Soundscape: \"%s\"\n\n", pSoundscapeName); | |||
| </source> | |||
| Now find '''if ( soundSlot < 0 )''' in the function '''int C_SoundscapeSystem::AddLoopingSound( const char *pSoundName, bool isAmbient, float volume, soundlevel_t soundlevel, int pitch, const Vector &position )''' and above it add: | |||
| <source lang=cpp> | <source lang=cpp> | ||
| if (g_IsPlayingSoundscape) | if (g_IsPlayingSoundscape) | ||
| 	return; | { | ||
| 	//get index | |||
| 	int index = Clamp<int>(SoundscapeGetLineNum(), 0, 6); | |||
| 	//color for looping sounds | |||
| 	static Color LoopingSoundColors[] = { | |||
| 		Color(255, 100, 0, 255), | |||
| 		Color(255, 255, 0, 255), | |||
| 		Color(255, 0, 100, 255), | |||
| 		Color(0, 255, 0, 255), | |||
| 		Color(0, 255, 255, 255), | |||
| 		Color(255, 0, 0, 255), | |||
| 		Color(0, 100, 255, 255), | |||
| 	}; | |||
| 	SoundscapePrint(LoopingSoundColors[index], "Fading looping sound \"%s\" in. Volume = %f, Pitch = %d\nPosition = {%.2f %.2f %.2f}\n\n", pSoundName, volume, pitch, position.x, position.y, position.z); | |||
| 	//sound widths | |||
| 	static float LoopingSoundsIn[] = { | |||
| 		0.4f, | |||
| 		0.5f, | |||
| 		0.6f, | |||
| 		0.7f, | |||
| 		0.8f, | |||
| 		0.9f, | |||
| 		1.0f, | |||
| 	}; | |||
| 	//add to graph | |||
| 	SoundscapeAddLine(LoopingSoundColors[index], 3 / soundscape_fadetime.GetFloat(), LoopingSoundsIn[index], true); | |||
| } | |||
| </source> | |||
| Now find '''m_randomSounds[i].nextPlayTime = gameTime + RandomInterval( m_randomSounds[i].time );''' inside '''C_SoundscapeSystem::UpdateRandomSounds( float gameTime )''' and under it add: | |||
| <source lang=cpp> | |||
| if (g_IsPlayingSoundscape) | |||
|     SoundscapePrint(Color(100, 255, 255, 255), "Playing next random sound for RandomSound index \"%d\" In \"%f\" Seconds\n\n", i, m_randomSounds[i].nextPlayTime - gameTime); | |||
| </source> | |||
| Now find '''m_randomSounds[index].nextPlayTime = gpGlobals->curtime + 0.5 * RandomInterval( sound.time );''' inside '''int C_SoundscapeSystem::AddRandomSound( const randomsound_t &sound )''' and under it add: | |||
| <source lang=cpp> | |||
| if (g_IsPlayingSoundscape) | |||
| 	SoundscapePrint(Color(100, 255, 255, 255), "Adding random sounds to soundscape system.\nNumber of sounds = \"%d\" For index \"%d\"\n\n", sound.waveCount, index); | |||
| </source> | |||
| Now you need to find: | |||
| <source lang=cpp> | |||
| if ( !pWaveName ) | |||
| 		return; | |||
| </source> | |||
| inside '''void C_SoundscapeSystem::PlayRandomSound''' and under it add: | |||
| <source lang=cpp> | |||
| int pitch = (int)RandomInterval(sound.pitch); | |||
| float volume = sound.masterVolume * RandomInterval(sound.volume); | |||
| if (sound.isRandom) | |||
| { | |||
| 	sound.position = GenerateRandomSoundPosition(); | |||
| } | |||
| if (g_IsPlayingSoundscape) | |||
| 	SoundscapePrint(Color(100, 255, 255, 255), "Playing Random sound \"%s\", Volume = %f, Pitch = %d\nPosition = {%.2f, %.2f, %.2f}\n", pWaveName, volume, pitch, sound.position.x, sound.position.y, sound.position.z); | |||
| </source> | |||
| Then, in that same function find: | |||
| <source lang=cpp> | |||
| ep.m_flVolume = sound.masterVolume * RandomInterval( sound.volume ); | |||
| ep.m_SoundLevel = (soundlevel_t)(int)RandomInterval( sound.soundlevel ); | |||
| ep.m_nPitch = (int)RandomInterval( sound.pitch ); | |||
| if ( sound.isRandom ) | |||
| { | |||
| 	sound.position = GenerateRandomSoundPosition(); | |||
| } | |||
| ep.m_pOrigin = &sound.position; | |||
| </source> | |||
| And replace that with | |||
| <source lang=cpp> | |||
| ep.m_flVolume = volume; | |||
| ep.m_SoundLevel = (soundlevel_t)(int)RandomInterval( sound.soundlevel ); | |||
| ep.m_nPitch = pitch; | |||
| ep.m_pOrigin = &sound.position; | |||
| </source> | </source> | ||
| <br> | |||
| Then in the same file move | Then in the same file move | ||
| <source lang=cpp> | <source lang=cpp> | ||
| Line 330: | Line 441: | ||
| <source lang=cpp> | <source lang=cpp> | ||
| bool g_bInSoundscapePositionEditor = false; | bool g_bInSoundscapePositionEditor = false; | ||
| int g_SoundscapePositionNumber =  | int g_SoundscapePositionNumber = 0; | ||
| //color based on g_SoundscapePositionNumber | //color based on g_SoundscapePositionNumber | ||
| Line 378: | Line 489: | ||
| CON_COMMAND_F(__ss_maker_set, "", FCVAR_HIDDEN) | CON_COMMAND_F(__ss_maker_set, "", FCVAR_HIDDEN) | ||
| { | { | ||
| 	int index = Clamp<int>(atoi(args.Arg(1)), 0, MAX_SOUNDSCAPES - 1); | |||
| 	g_SoundscapePositions[index] = Vector(atof(args.Arg(2)), atof(args.Arg(3)), atof(args.Arg(4))); | |||
| 	g_bUsingVector[index] = atoi(args.Arg(5)) == 0 ? false : true; | |||
| } | } | ||
| Line 457: | Line 571: | ||
| 		for (int i = 0; i < MAX_SOUNDSCAPES; i++) | 		for (int i = 0; i < MAX_SOUNDSCAPES; i++) | ||
| 		{ | 		{ | ||
| 			Vector vec = g_SoundscapePositions[i]; | |||
| 			//check for invalid vector | 			//check for invalid vector | ||
| 			if (g_bUsingVector[i] == false) | 			if (g_bUsingVector[i] == false || vec == vec3_origin) | ||
| 				continue; | 				continue; | ||
| 			//get box stuff | 			//get box stuff | ||
| 			Color& c = g_SoundscapeColors[i]; | 			Color& c = g_SoundscapeColors[i]; | ||
Latest revision as of 03:22, 12 June 2025

 
This tutorial will show you how to make a vgui soundscape maker panel that allows you to modify, create, and play soundscapes in game.
Requirements
- A mod running on Source SDK 2013
- Knowledge of C++
The main vgui panel
Before you start the tutorial you need to copy and paste both these files into your src/game/client/ directory
 Note:The vgui_soundscape_maker.cpp will have some errors but they will be fixed later when the c_soundscape.cpp and .h files get changed.
Note:The vgui_soundscape_maker.cpp will have some errors but they will be fixed later when the c_soundscape.cpp and .h files get changed.Once that is done you are almost all done. The next thing you are going to want to do is go over to client/vgui_int.cpp and at the top of the file and under
#include <vgui_controls/Controls.h>
add
#include "vgui_soundscape_maker.h"
Then in the same file find:
void VGui_CreateGlobalPanels( void )
{
	VPANEL gameToolParent = enginevgui->GetPanel( PANEL_CLIENTDLL_TOOLS );
	VPANEL toolParent = enginevgui->GetPanel( PANEL_TOOLS );
and under that add
g_SoundscapeMaker->Create(toolParent);
Now find
void VGui_Shutdown()
{
And under it add:
g_SoundscapeMaker->Destroy();
Now go to public\tier1\KeyValues.h and find:
private:
	KeyValues( KeyValues& );	// prevent copy constructor being used
(should be around line 258) and make that be:
public:
	KeyValues( KeyValues& );	// prevent copy constructor being used
Now go to public\vgui_controls\TextEntry.h and find:
	virtual void GetTextRange( char *buf, int from, int numchars );	// copy a portion of the text to the buffer and add zero-termination
private:
	CUtlVector<wchar_t> m_TextStream;		// the text in the text window is stored in this buffer
(should be around line 318) and make that be:
	virtual void GetTextRange( char *buf, int from, int numchars );	// copy a portion of the text to the buffer and add zero-termination
public:
	CUtlVector<wchar_t> m_TextStream;		// the text in the text window is stored in this buffer
Now go to client/c_soundscape.cpp  and copy:
#include "c_soundscape.h"
extern bool g_IsPlayingSoundscape;
extern bool g_bSSMHack;
//debug stuff
void SoundscapePrint(Color color, const char* msg, ...);
void SoundscapeAddLine(Color color, float speed, float width, bool accending);
int SoundscapeGetLineNum();
to be under
#include "tier0/icommandline.h"
Then. find the function: void Soundscape_Update( audioparams_t &audio ) and at the very top of the function and before g_SoundscapeSystem.UpdateAudioParams( audio ); add:
if (g_IsPlayingSoundscape)
		return;
now find the function: void C_SoundscapeSystem::StartNewSoundscape( KeyValues *pSoundscape ) and at the very top of it and before int i; add:
if (g_IsPlayingSoundscape && !g_bSSMHack)
	return;
Now find StartSubSoundscape( pSoundscapeKeys, subParams ); inside void C_SoundscapeSystem::ProcessPlaySoundscape( KeyValues *pPlaySoundscape, subsoundscapeparams_t ¶msIn ) and under it add
if (g_IsPlayingSoundscape)
	SoundscapePrint(Color(100, 255, 0, 255), "Playing Sub Soundscape: \"%s\"\n\n", pSoundscapeName);
Now find if ( soundSlot < 0 ) in the function int C_SoundscapeSystem::AddLoopingSound( const char *pSoundName, bool isAmbient, float volume, soundlevel_t soundlevel, int pitch, const Vector &position ) and above it add:
if (g_IsPlayingSoundscape)
{
	//get index
	int index = Clamp<int>(SoundscapeGetLineNum(), 0, 6);
	//color for looping sounds
	static Color LoopingSoundColors[] = {
		Color(255, 100, 0, 255),
		Color(255, 255, 0, 255),
		Color(255, 0, 100, 255),
		Color(0, 255, 0, 255),
		Color(0, 255, 255, 255),
		Color(255, 0, 0, 255),
		Color(0, 100, 255, 255),
	};
	SoundscapePrint(LoopingSoundColors[index], "Fading looping sound \"%s\" in. Volume = %f, Pitch = %d\nPosition = {%.2f %.2f %.2f}\n\n", pSoundName, volume, pitch, position.x, position.y, position.z);
	//sound widths
	static float LoopingSoundsIn[] = {
		0.4f,
		0.5f,
		0.6f,
		0.7f,
		0.8f,
		0.9f,
		1.0f,
	};
	//add to graph
	SoundscapeAddLine(LoopingSoundColors[index], 3 / soundscape_fadetime.GetFloat(), LoopingSoundsIn[index], true);
}
Now find m_randomSounds[i].nextPlayTime = gameTime + RandomInterval( m_randomSounds[i].time ); inside C_SoundscapeSystem::UpdateRandomSounds( float gameTime ) and under it add:
if (g_IsPlayingSoundscape)
    SoundscapePrint(Color(100, 255, 255, 255), "Playing next random sound for RandomSound index \"%d\" In \"%f\" Seconds\n\n", i, m_randomSounds[i].nextPlayTime - gameTime);
Now find m_randomSounds[index].nextPlayTime = gpGlobals->curtime + 0.5 * RandomInterval( sound.time ); inside int C_SoundscapeSystem::AddRandomSound( const randomsound_t &sound ) and under it add:
if (g_IsPlayingSoundscape)
	SoundscapePrint(Color(100, 255, 255, 255), "Adding random sounds to soundscape system.\nNumber of sounds = \"%d\" For index \"%d\"\n\n", sound.waveCount, index);
Now you need to find:
if ( !pWaveName )
		return;
inside void C_SoundscapeSystem::PlayRandomSound and under it add:
int pitch = (int)RandomInterval(sound.pitch);
float volume = sound.masterVolume * RandomInterval(sound.volume);
if (sound.isRandom)
{
	sound.position = GenerateRandomSoundPosition();
}
if (g_IsPlayingSoundscape)
	SoundscapePrint(Color(100, 255, 255, 255), "Playing Random sound \"%s\", Volume = %f, Pitch = %d\nPosition = {%.2f, %.2f, %.2f}\n", pWaveName, volume, pitch, sound.position.x, sound.position.y, sound.position.z);
Then, in that same function find:
ep.m_flVolume = sound.masterVolume * RandomInterval( sound.volume );
ep.m_SoundLevel = (soundlevel_t)(int)RandomInterval( sound.soundlevel );
ep.m_nPitch = (int)RandomInterval( sound.pitch );
if ( sound.isRandom )
{
	sound.position = GenerateRandomSoundPosition();
}
ep.m_pOrigin = &sound.position;
And replace that with
ep.m_flVolume = volume;
ep.m_SoundLevel = (soundlevel_t)(int)RandomInterval( sound.soundlevel );
ep.m_nPitch = pitch;
ep.m_pOrigin = &sound.position;
Then in the same file move
struct loopingsound_t
{
	Vector		position;		// position (if !isAmbient)
	const char *pWaveName;		// name of the wave file
	float		volumeTarget;	// target volume level (fading towards this)
	float		volumeCurrent;	// current volume level
	soundlevel_t soundlevel;	// sound level (if !isAmbient)
	int			pitch;			// pitch shift
	int			id;				// Used to fade out sounds that don't belong to the most current setting
	bool		isAmbient;		// Ambient sounds have no spatialization - they play from everywhere
};
to be under
#ifdef _WIN32
#pragma once
from c_soundscapes.cpp into the file client/c_soundscapes.h
and finally move:
struct randomsound_t
{
	Vector		position;
	float		nextPlayTime;	// time to play a sound from the set
	interval_t	time;
	interval_t	volume;
	interval_t	pitch;
	interval_t	soundlevel;
	float		masterVolume;
	int			waveCount;
	bool		isAmbient;
	bool		isRandom;
	KeyValues	*pWaves;
	void Init()
	{
		memset( this, 0, sizeof(*this) );
	}
};
struct subsoundscapeparams_t
{
	int		recurseLevel;		// test for infinite loops in the script / circular refs
	float	masterVolume;
	int		startingPosition;
	int		positionOverride;	// forces all sounds to this position
	int		ambientPositionOverride;	// forces all ambient sounds to this position
	bool	allowDSP;
	bool	wroteSoundMixer;
	bool	wroteDSPVolume;
};
class C_SoundscapeSystem : public CBaseGameSystemPerFrame
{
public:
	virtual char const *Name() { return "C_SoundScapeSystem"; }
	C_SoundscapeSystem()
	{
		m_nRestoreFrame = -1;
	}
	~C_SoundscapeSystem() {}
	void OnStopAllSounds()
	{
		m_params.ent.Set( NULL );
		m_params.soundscapeIndex = -1;
		m_loopingSounds.Purge();
		m_randomSounds.Purge();
	}
	// IClientSystem hooks, not needed
	virtual void LevelInitPreEntity()
	{
		Shutdown();
		Init();
		TouchSoundFiles();
	}
	virtual void LevelInitPostEntity() 
	{
		if ( !m_pSoundMixerVar )
		{
			m_pSoundMixerVar = (ConVar *)cvar->FindVar( "snd_soundmixer" );
		}
		if ( !m_pDSPVolumeVar )
		{
			m_pDSPVolumeVar = (ConVar *)cvar->FindVar( "dsp_volume" );
		}
	}
	// The level is shutdown in two parts
	virtual void LevelShutdownPreEntity() {}
	// Entities are deleted / released here...
	virtual void LevelShutdownPostEntity()
	{
		OnStopAllSounds();
	}
	virtual void OnSave() {}
	virtual void OnRestore()
	{
		m_nRestoreFrame = gpGlobals->framecount;
	}
	virtual void SafeRemoveIfDesired() {}
	// Called before rendering
	virtual void PreRender() { }
	// Called after rendering
	virtual void PostRender() { }
	// IClientSystem hooks used
	virtual bool Init();
	virtual void Shutdown();
	// Gets called each frame
	virtual void Update( float frametime );
	void PrintDebugInfo()
	{
		Msg( "\n------- CLIENT SOUNDSCAPES -------\n" );
		for ( int i=0; i < m_soundscapes.Count(); i++ )
		{
			Msg( "- %d: %s\n", i, m_soundscapes[i]->GetName() );
		}
		if ( m_forcedSoundscapeIndex )
		{
			Msg( "- PLAYING DEBUG SOUNDSCAPE: %d [%s]\n", m_forcedSoundscapeIndex, SoundscapeNameByIndex(m_forcedSoundscapeIndex) );
		}
		Msg( "- CURRENT SOUNDSCAPE: %d [%s]\n", m_params.soundscapeIndex.Get(), SoundscapeNameByIndex(m_params.soundscapeIndex) );
		Msg( "----------------------------------\n\n" );
	}
	
	// local functions
	void UpdateAudioParams( audioparams_t &audio );
	void GetAudioParams( audioparams_t &out ) const { out = m_params; }
	int GetCurrentSoundscape() 
	{ 
		if ( m_forcedSoundscapeIndex >= 0 )
			return m_forcedSoundscapeIndex;
		return m_params.soundscapeIndex; 
	}
	void DevReportSoundscapeName( int index );
	void UpdateLoopingSounds( float frametime );
	int AddLoopingAmbient( const char *pSoundName, float volume, int pitch );
	void UpdateLoopingSound( loopingsound_t &loopSound );
	void StopLoopingSound( loopingsound_t &loopSound );
	int AddLoopingSound( const char *pSoundName, bool isAmbient, float volume, 
		soundlevel_t soundLevel, int pitch, const Vector &position );
	int AddRandomSound( const randomsound_t &sound );
	void PlayRandomSound( randomsound_t &sound );
	void UpdateRandomSounds( float gameClock );
	Vector GenerateRandomSoundPosition();
	void ForceSoundscape( const char *pSoundscapeName, float radius );
	int FindSoundscapeByName( const char *pSoundscapeName );
	const char *SoundscapeNameByIndex( int index );
	KeyValues *SoundscapeByIndex( int index );
	
	// main-level soundscape processing, called on new soundscape
	void StartNewSoundscape( KeyValues *pSoundscape );
	void StartSubSoundscape( KeyValues *pSoundscape, subsoundscapeparams_t ¶ms );
	// root level soundscape keys
	// add a process for each new command here
	// "dsp"
	void ProcessDSP( KeyValues *pDSP );
	// "dsp_player"
	void ProcessDSPPlayer( KeyValues *pDSPPlayer );
	// "playlooping"
	void ProcessPlayLooping( KeyValues *pPlayLooping, const subsoundscapeparams_t ¶ms );	
	// "playrandom"
	void ProcessPlayRandom( KeyValues *pPlayRandom, const subsoundscapeparams_t ¶ms );
	// "playsoundscape"
	void ProcessPlaySoundscape( KeyValues *pPlaySoundscape, subsoundscapeparams_t ¶ms );
	// "soundmixer"
	void ProcessSoundMixer( KeyValues *pSoundMixer, subsoundscapeparams_t ¶ms );
	// "dsp_volume"
	void ProcessDSPVolume( KeyValues *pKey, subsoundscapeparams_t ¶ms );
	bool	IsBeingRestored() const
	{
		return gpGlobals->framecount == m_nRestoreFrame ? true : false;
	}
	void	AddSoundScapeFile( const char *filename );
	void		TouchPlayLooping( KeyValues *pAmbient );
	void		TouchPlayRandom( KeyValues *pPlayRandom );
	void		TouchWaveFiles( KeyValues *pSoundScape );
	void		TouchSoundFile( char const *wavefile );
	void		TouchSoundFiles();
	
	int							m_nRestoreFrame;
	CUtlVector< KeyValues * >	m_SoundscapeScripts;	// The whole script file in memory
	CUtlVector<KeyValues *>		m_soundscapes;			// Lookup by index of each root section
	audioparams_t				m_params;				// current player audio params
	CUtlVector<loopingsound_t>	m_loopingSounds;		// list of currently playing sounds
	CUtlVector<randomsound_t>	m_randomSounds;			// list of random sound commands
	float						m_nextRandomTime;		// next time to play a random sound
	int							m_loopingSoundId;		// marks when the sound was issued
	int							m_forcedSoundscapeIndex;// >= 0 if this a "forced" soundscape? i.e. debug mode?
	float						m_forcedSoundscapeRadius;// distance to spatialized sounds
	static ConVar *m_pDSPVolumeVar;
	static ConVar *m_pSoundMixerVar;
};
from c_soundscape.cpp to under the code you added in the c_soundscape.h file. before anything else you need to look for
	void ProcessDSPVolume(KeyValues* pKey, subsoundscapeparams_t& params);
private:
	bool	IsBeingRestored() const
in the .h file you just added the class to. and if you find it then make the private be public.
Then under the class definition add:
extern C_SoundscapeSystem g_SoundscapeSystem;
Now go to shared/hl2/hl2_usermessages.cpp and inside the file find:
usermessages->Register( "AchievementEvent", -1 );
usermessages->Register( "UpdateJalopyRadar", -1 );
(should be around line 47) and under it add
usermessages->Register("SoundscapeMaker_Recieve", -1);
Now for the final part. you need to go to server/player.cpp and just above:
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBasePlayer::PostThink()
(should be around line 4590) add:
bool g_bInSoundscapePositionEditor = false;
int g_SoundscapePositionNumber = 0;
//color based on g_SoundscapePositionNumber
Color g_SoundscapeColors[] = {
	Color(255, 0, 0, 50),
	Color(200, 200, 0, 50),
	Color(200, 0, 255, 50),
	Color(0, 0, 255, 50),
	Color(0, 255, 0, 50),
	Color(200, 100, 0, 50),
	Color(0, 0, 0, 50),
	Color(0, 100, 250, 50),
};
//vector positions
Vector g_SoundscapePositions[] = {
	vec3_origin,
	vec3_origin,
	vec3_origin,
	vec3_origin,
	vec3_origin,
	vec3_origin,
	vec3_origin,
	vec3_origin,
};
bool g_bUsingVector[] = {
	false,
	false,
	false,
	false,
	false,
	false,
	false,
	false,
};
#define MAX_SOUNDSCAPES 8
//hidden commands
CON_COMMAND_F(__ss_maker_start, "", FCVAR_HIDDEN)
{
	g_bInSoundscapePositionEditor = true;
	g_SoundscapePositionNumber = atoi(args.Arg(1));
}
CON_COMMAND_F(__ss_maker_set, "", FCVAR_HIDDEN)
{
	int index = Clamp<int>(atoi(args.Arg(1)), 0, MAX_SOUNDSCAPES - 1);
	g_SoundscapePositions[index] = Vector(atof(args.Arg(2)), atof(args.Arg(3)), atof(args.Arg(4)));
	g_bUsingVector[index] = atoi(args.Arg(5)) == 0 ? false : true;
}
ConVar __ss_draw("__ss_draw", "0", FCVAR_HIDDEN);
CON_COMMAND_F(__ss_maker_stop, "", FCVAR_HIDDEN)
{
	g_bInSoundscapePositionEditor = false;
	if (!__ss_draw.GetBool())
		g_bUsingVector[g_SoundscapePositionNumber] = false;
}
Then finally at the top of the CBasePlayer::PostThink function add:
    if (g_bInSoundscapePositionEditor)
	{
		do {
			//get endpos for player's eye position + forward 150
			//eye position
			Vector EyePos = EyePosition();
			EyePos.z = EyePos.z - 10;
			//forward direction
			Vector ForwardDir;
			AngleVectors(EyeAngles(), &ForwardDir);
			//get endpos
			Vector EndPos = EyePos + (ForwardDir * 75);
			int index = Clamp<int>(g_SoundscapePositionNumber, 0, MAX_SOUNDSCAPES - 1);
			//draw overlay line
			Color& c = g_SoundscapeColors[index];
			NDebugOverlay::Line(EyePos, EndPos, c.r(), c.b(), c.g(), false, NDEBUG_PERSIST_TILL_NEXT_SERVER);
			//set vector at position
			g_SoundscapePositions[index] = EndPos;
			g_bUsingVector[index] = true;
			//check for primary attack
			if (m_afButtonPressed & IN_USE)
			{
				g_bInSoundscapePositionEditor = false;
				//write message for client
				CReliableBroadcastRecipientFilter filter;
				UserMessageBegin(filter, "SoundscapeMaker_Recieve");
					WRITE_BYTE(g_SoundscapePositionNumber);
					WRITE_VEC3COORD(g_SoundscapePositions[g_SoundscapePositionNumber]);
				MessageEnd();
				break;
			}
			
			if (m_afButtonPressed & IN_RELOAD)
			{
				g_bInSoundscapePositionEditor = false;
				g_bUsingVector[index] = false;
				//write that we canceled the thing
				CReliableBroadcastRecipientFilter filter;
				UserMessageBegin(filter, "SoundscapeMaker_Recieve");
					WRITE_BYTE(255);
					WRITE_VEC3COORD(vec3_invalid);
				MessageEnd();
				break;
			}
		} while (false);
	}
	//draw all the positions
	if (g_bInSoundscapePositionEditor || __ss_draw.GetBool())
	{
		//now draw all the positions
		for (int i = 0; i < MAX_SOUNDSCAPES; i++)
		{
			Vector vec = g_SoundscapePositions[i];
			//check for invalid vector
			if (g_bUsingVector[i] == false || vec == vec3_origin)
				continue;
			//get box stuff
			Color& c = g_SoundscapeColors[i];
			//draw all the items
			NDebugOverlay::Box(vec, Vector(-10, -10, -10), Vector(10, 10, 10), c.r(), c.b(), c.g(), c.a(), NDEBUG_PERSIST_TILL_NEXT_SERVER);
			//move vec up 3
			vec.z = vec.z + 3;
			NDebugOverlay::Text(vec, CFmtStr("Origin: %f %f %f", vec.x, vec.y, vec.z), false, NDEBUG_PERSIST_TILL_NEXT_SERVER);
			//move vec down 6
			vec.z = vec.z - 6;
			NDebugOverlay::Text(vec, CFmtStr("Position: %d", i), false, NDEBUG_PERSIST_TILL_NEXT_SERVER);
		}
	}
Now the panel should be all done. to open the panel in game use the modbase_soundscape_panel command and the panel should show.
For information on how to use the vgui panel head over to:
























