From f103e333002317d073af902502780885b3aefa25 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@users.noreply.github.com>
Date: Thu, 24 Nov 2022 21:27:08 +0100
Subject: [PATCH] - fixed code up to the point where everything compiles again.
 Duke sounds are currently non-functional.

All Duke script code has been changed to use strings as sound names now, just like GZDoom these will be looked up at compile time.
Original Duke sound indices still exist but are now being managed as resource IDs, not sound engine indices anymore.
---
 source/common/audio/sound/s_sound.cpp         |   8 +
 source/common/audio/sound/s_soundinternal.h   |   4 +
 source/core/gamecontrol.cpp                   |   1 +
 source/core/gamestruct.h                      |   1 +
 source/core/music/s_advsound.cpp              |  11 +-
 source/core/raze_sound.h                      |   5 +
 source/games/blood/src/blood.h                |   1 +
 source/games/blood/src/sound.cpp              |   6 +-
 source/games/duke/src/duke3d.h                |   1 +
 source/games/duke/src/game.cpp                |   4 +-
 source/games/duke/src/gamedef.cpp             |   1 +
 source/games/duke/src/sounds.cpp              |  87 +-
 source/games/duke/src/sounds.h                |  62 +-
 source/games/duke/src/vmexports.cpp           |  38 +-
 source/games/exhumed/src/exhumed.h            |   1 +
 source/games/exhumed/src/sound.cpp            |   7 +-
 source/games/sw/src/game.h                    |   1 +
 source/games/sw/src/sounds.cpp                |   6 +-
 wadsrc/static/filter/duke/sndinfo.txt         | 402 ++++++++
 wadsrc/static/filter/redneck/sndinfo.txt      | 508 ++++++++++
 .../static/zscript/games/duke/actors/bolt.zs  |   4 +-
 .../zscript/games/duke/actors/cactus.zs       |   2 +-
 .../games/duke/actors/canwithsomething.zs     |   2 +-
 .../zscript/games/duke/actors/chickenplant.zs |   2 +-
 .../static/zscript/games/duke/actors/crane.zs |   6 +-
 .../zscript/games/duke/actors/fireext.zs      |   6 +-
 .../zscript/games/duke/actors/lumberblade.zs  |   4 +-
 .../zscript/games/duke/actors/rrcactus.zs     |   8 +-
 .../zscript/games/duke/actors/tripbomb.zs     |   6 +-
 .../zscript/games/duke/actors/viewscreen.zs   |   2 +-
 .../zscript/games/duke/actors/waterdrip.zs    |   2 +-
 .../games/duke/actors/waterfountain.zs        |   6 +-
 wadsrc/static/zscript/games/duke/dukeactor.zs |   4 +-
 wadsrc/static/zscript/games/duke/dukegame.zs  | 930 +-----------------
 .../static/zscript/games/duke/ui/cutscenes.zs |  84 +-
 .../static/zscript/games/duke/ui/screens.zs   |  84 +-
 36 files changed, 1184 insertions(+), 1123 deletions(-)
 create mode 100644 wadsrc/static/filter/duke/sndinfo.txt
 create mode 100644 wadsrc/static/filter/redneck/sndinfo.txt

diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp
index a9f12d8d2..51396a378 100644
--- a/source/common/audio/sound/s_sound.cpp
+++ b/source/common/audio/sound/s_sound.cpp
@@ -1681,6 +1681,7 @@ void SoundEngine::HashSounds()
 
 	S_sfx.ShrinkToFit();
 	size = S_sfx.Size();
+	ResIdMap.Clear();
 
 	// Mark all buckets as empty
 	for (i = 0; i < size; i++)
@@ -1692,8 +1693,15 @@ void SoundEngine::HashSounds()
 		j = MakeKey(S_sfx[i].name) % size;
 		S_sfx[i].next = S_sfx[j].index;
 		S_sfx[j].index = i;
+
+		if (S_sfx[j].ResourceId != -1)
+		{
+			ResIdMap.Insert(S_sfx[j].ResourceId, FSoundID::fromInt(i));
+		}
 	}
 	S_rnd.ShrinkToFit();
+
+
 }
 
 void SoundEngine::AddRandomSound(FSoundID Owner, TArray<FSoundID> list)
diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h
index c38f8d4ce..95faa99c9 100644
--- a/source/common/audio/sound/s_soundinternal.h
+++ b/source/common/audio/sound/s_soundinternal.h
@@ -398,6 +398,10 @@ public:
 	FSoundID PickReplacement(FSoundID refid);
 	void HashSounds();
 	void AddRandomSound(FSoundID Owner, TArray<FSoundID> list);
+	void RemoveResourceID(int id)
+	{
+		ResIdMap.Remove(id);
+	}
 
 	TArray<sfxinfo_t>& GetSounds()	//We still need this for a short time...
 	{
diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp
index 84753d9d4..d9d3d263b 100644
--- a/source/core/gamecontrol.cpp
+++ b/source/core/gamecontrol.cpp
@@ -1111,6 +1111,7 @@ int RunGame()
 
 	StartWindow->Progress();
 	I_InitSound();
+	gi->StartSoundEngine();
 	StartWindow->Progress();
 	Mus_InitMusic();
 	S_ParseSndInfo();
diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h
index 0acac2249..b22f74524 100644
--- a/source/core/gamestruct.h
+++ b/source/core/gamestruct.h
@@ -127,6 +127,7 @@ struct GameInterface
 	virtual void AddQAVInterpProps(const int res_id, const FString& interptype, const bool loopable, const TMap<int, TArray<int>>&& ignoredata) { }
 	virtual void RemoveQAVInterpProps(const int res_id) { }
 	virtual bool WantEscape() { return false; }
+	virtual void StartSoundEngine() = 0;
 
 	virtual FString statFPS()
 	{
diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp
index 69ae064f4..1e65d4f96 100644
--- a/source/core/music/s_advsound.cpp
+++ b/source/core/music/s_advsound.cpp
@@ -97,16 +97,15 @@ static const char *SICommandStrings[] =
 // 
 //==========================================================================
 
-int S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6)
+FSoundID S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6)
 {
 	auto& S_sfx = soundEngine->GetSounds();
-	int sfxid;
 
-	sfxid = soundEngine->FindSoundNoHash(logicalname);
+	auto sfxid = soundEngine->FindSoundNoHash(logicalname);
 
-	if (sfxid > 0 && (unsigned int)sfxid < S_sfx.Size())
+	if (soundEngine->isValidSoundId(sfxid))
 	{ // If the sound has already been defined, change the old definition
-		sfxinfo_t* sfx = &S_sfx[sfxid];
+		sfxinfo_t* sfx = soundEngine->GetWritableSfx(sfxid);
 
 		if (sfx->ResourceId != -1)
 		{
@@ -117,7 +116,7 @@ int S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6)
 		{
 			FRandomSoundList* rnd = soundEngine->ResolveRandomSound(sfx);
 			rnd->Choices.Reset();
-			rnd->Owner = 0;
+			rnd->Owner = NO_SOUND;
 		}
 		sfx->ResourceId = slotnum;
 		sfx->lumpnum = sfx_empty;
diff --git a/source/core/raze_sound.h b/source/core/raze_sound.h
index 0c6b7170c..3fe2674c2 100644
--- a/source/core/raze_sound.h
+++ b/source/core/raze_sound.h
@@ -38,6 +38,11 @@ int S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6);
 class RazeSoundEngine : public SoundEngine
 {
 public:
+	RazeSoundEngine()
+	{
+		// add the empty sound right now.
+		AddSoundLump("no_sound", fileSystem.CheckNumForFullName("engine/dsempty.lmp"), 0);
+	}
 	virtual bool SourceIsActor(FSoundChan* chan) { return chan->SourceType == SOURCE_Actor; }
 	virtual int SoundSourceIndex(FSoundChan* chan) { return 0; }
 	virtual void SetSource(FSoundChan* chan, int index) {}
diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h
index 4cd9cf5eb..594f7ba10 100644
--- a/source/games/blood/src/blood.h
+++ b/source/games/blood/src/blood.h
@@ -147,6 +147,7 @@ struct GameInterface : public ::GameInterface
 	bool IsQAVInterpTypeValid(const FString& type) override;
 	void AddQAVInterpProps(const int res_id, const FString& interptype, const bool loopable, const TMap<int, TArray<int>>&& ignoredata) override;
 	void RemoveQAVInterpProps(const int res_id) override;
+	void StartSoundEngine() override;
 
 	GameStats getStats() override;
 };
diff --git a/source/games/blood/src/sound.cpp b/source/games/blood/src/sound.cpp
index 61faa4d22..76ed757ad 100644
--- a/source/games/blood/src/sound.cpp
+++ b/source/games/blood/src/sound.cpp
@@ -109,9 +109,13 @@ static void S_AddBloodSFX(int lumpnum)
 //
 //---------------------------------------------------------------------------
 
-void sndInit(void)
+void GameInterface::StartSoundEngine()
 {
 	soundEngine = new BloodSoundEngine;
+}
+
+void sndInit(void)
+{
 	soundEngine->AddSoundLump("", 0, 0, -1, 6); // add a dummy entry at index #0
 	for (int i = fileSystem.GetNumEntries() - 1; i >= 0; i--)
 	{
diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h
index dbd4aa30b..57e2867e6 100644
--- a/source/games/duke/src/duke3d.h
+++ b/source/games/duke/src/duke3d.h
@@ -63,6 +63,7 @@ struct GameInterface : public ::GameInterface
 	void AddExcludedEpisode(const FString& episode) override;
 	int GetCurrentSkill() override;
 	bool WantEscape() override;
+	void StartSoundEngine() override;
 
 };
 
diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp
index be4aa6721..9a5056a31 100644
--- a/source/games/duke/src/game.cpp
+++ b/source/games/duke/src/game.cpp
@@ -364,9 +364,7 @@ void GameInterface::app_init()
 	connectpoint2[0] = -1;
 
 	SetDispatcher();
-	S_InitSound();
-
-
+	
 	loadcons();
 	fi.initactorflags();
 	duke_menufont->Callback(); // depends on the .CON files so it must be after loadcons
diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp
index a4fb32699..148d1f930 100644
--- a/source/games/duke/src/gamedef.cpp
+++ b/source/games/duke/src/gamedef.cpp
@@ -3239,6 +3239,7 @@ void loadcons()
 	// These can only be retrieved AFTER loading the scripts.
 	FinalizeGameVars();
 	S_WorldTourMappingsForOldSounds(); // create a sound mapping for World Tour.
+	soundEngine->HashSounds();
 	S_CacheAllSounds();
 	comp.setmusic();
 
diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp
index 56815c9e4..501298ef8 100644
--- a/source/games/duke/src/sounds.cpp
+++ b/source/games/duke/src/sounds.cpp
@@ -92,8 +92,8 @@ public:
 		S_Rolloff.RolloffType = ROLLOFF_Doom;   // Seems like Duke uses the same rolloff type as Doom.
 		S_Rolloff.MinDistance = 144;            // was originally 576 which looks like a bug and sounds like crap.
 		S_Rolloff.MaxDistance = 1088;
-	}
 
+	}
 	void StopChannel(FSoundChan* chan) override
  	{
 		if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor)
@@ -122,18 +122,18 @@ public:
 
 };
 
-void S_InitSound()
+void GameInterface::StartSoundEngine()
 {
 	soundEngine = new DukeSoundEngine;
 }
 
-static int GetReplacementSound(int soundNum)
+static FSoundID GetReplacementSound(FSoundID soundNum)
 {
-	if (wt_forcevoc && isWorldTour() && soundEngine->isValidSoundId(FSoundID::fromInt(soundNum+1)))
+	if (wt_forcevoc && isWorldTour() && soundEngine->isValidSoundId(soundNum))
 	{
-		auto const* snd = soundEngine->GetUserData(FSoundID::fromInt(soundNum + 1));
+		auto const* snd = soundEngine->GetUserData(soundNum);
 		int sndx = snd[kWorldTourMapping];
-		if (sndx > 0) soundNum = sndx-1;
+		if (sndx > 0) soundNum = FSoundID::fromInt(sndx);
 	}
 	return soundNum;
 }
@@ -172,9 +172,8 @@ void S_CacheAllSounds(void)
 //
 //==========================================================================
 
-static inline int S_GetPitch(FSoundID num)
+static inline int S_GetPitch(FSoundID soundid)
 {
-	auto soundid = FSoundID::fromInt(num + 1);
 	auto const* snd = soundEngine->GetUserData(soundid);
 	if (!snd) return 0;
 	int const   range = abs(snd[kPitchEnd] - snd[kPitchStart]);
@@ -186,9 +185,8 @@ float S_ConvertPitch(int lpitch)
 	return powf(2, lpitch / 1200.f);   // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
 }
 
-int S_GetUserFlags(int num)
+int S_GetUserFlags(FSoundID soundid)
 {
-	auto soundid = FSoundID::fromInt(num + 1);
 	if (!soundEngine->isValidSoundId(soundid)) return 0;
 	auto const* snd = soundEngine->GetUserData(soundid);
 	if (!snd) return 0;
@@ -203,14 +201,17 @@ int S_GetUserFlags(int num)
 
 int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpitch, int priority, int type, int distance, float volume)
 {
-	int s_index = soundEngine->FindSoundByResID(index);
-	if (s_index == 0)
+	FSoundID s_index = soundEngine->FindSoundByResID(index);
+	sfxinfo_t* sfx;
+	if (!s_index.isvalid())
 	{
 		// If the slot isn't defined, give it a meaningful name containing the index.
-		s_index = S_ReserveSoundSlot(FStringf("ConSound@%04d", index), index, 6);
+		sfx = soundEngine->AllocateSound();
+		sfx->name.Format("ConSound@%04d", index);
+		sfx->ResourceId = index;
 	}
+	else sfx = soundEngine->GetWritableSfx(s_index);
 
-	auto sfx = &soundEngine->GetSounds()[s_index];
 	sfx->UserData.Resize(kMaxUserData);
 	auto sndinf = sfx->UserData.Data();
 	sndinf[kFlags] = type & ~SF_ONEINST_INTERNAL;
@@ -254,13 +255,12 @@ inline bool S_IsAmbientSFX(DDukeActor* actor)
 //
 //==========================================================================
 
-static int GetPositionInfo(DDukeActor* actor, FSoundID soundID, sectortype* sect,
+static int GetPositionInfo(DDukeActor* actor, FSoundID soundid, sectortype* sect,
 							 const DVector3 &cam, const DVector3 &pos, int *distPtr, FVector3 *sndPos)
 {
 	// There's a lot of hackery going on here that could be mapped to rolloff and attenuation parameters.
 	// However, ultimately rolloff would also just reposition the sound source so this can remain as it is.
 
-	auto soundid = FSoundID::fromInt(soundNum + 1);
 	int orgsndist = 0, sndist = 0;
 	auto const* snd = soundEngine->GetUserData(soundid);
 	int userflags = snd ? snd[kFlags] : 0;
@@ -364,7 +364,7 @@ void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3]
 			auto aactor = (DDukeActor*)source;
 			if (aactor != nullptr)
 			{
-				GetPositionInfo(aactor, chanSound.index() - 1, camsect, campos, aactor->spr.pos, nullptr, pos);
+				GetPositionInfo(aactor, chanSound, camsect, campos, aactor->spr.pos, nullptr, pos);
 				/*
 				if (vel) // DN3D does not properly maintain this.
 				{
@@ -422,21 +422,19 @@ void GameInterface::UpdateSounds(void)
 //
 //==========================================================================
 
-int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channel, EChanFlags flags)
+int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int channel, EChanFlags flags)
 {
-	auto soundid = FSoundID::fromInt(sndnum + 1);
 	auto const pl = &ps[myconnectindex];
 	if (!soundEngine->isValidSoundId(soundid) || !SoundEnabled() || actor == nullptr || !playrunning() ||
 		(pl->timebeforeexit > 0 && pl->timebeforeexit <= REALGAMETICSPERSEC * 3)) return -1;
 
-	sndnum = GetReplacementSound(sndnum);
-	soundid = FSoundID::fromInt(sndnum + 1);
-	int userflags = S_GetUserFlags(sndnum);
+	soundid = GetReplacementSound(soundid);
+	int userflags = S_GetUserFlags(soundid);
 
 	if ((userflags & (SF_DTAG | SF_GLOBAL)) == SF_DTAG)
 	{
 		// Duke-Tag sound does not play in 3D.
-		return S_PlaySound(sndnum);
+		return S_PlaySound(soundid);
 	}
 
 	if (userflags & SF_TALK)
@@ -445,7 +443,7 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe
 		bool foundone =  soundEngine->EnumerateChannels([&](FSoundChan* chan)
 			{
 				auto sid = chan->OrgID;
-				auto flags = S_GetUserFlags(sid.index() - 1);
+				auto flags = S_GetUserFlags(sid);
 				return !!(flags & SF_TALK);
 			});
 		// don't play if any Duke talk sounds are already playing
@@ -466,10 +464,12 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe
 	sectortype* camsect;
 
 	S_GetCamera(&campos, nullptr, &camsect);
-	GetPositionInfo(actor, sndnum, camsect, campos, pos, &sndist, &sndpos);
-	int pitch = S_GetPitch(sndnum);
+	GetPositionInfo(actor, soundid, camsect, campos, pos, &sndist, &sndpos);
+	int pitch = S_GetPitch(soundid);
 
-	bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || ((sndnum == PIPEBOMB_EXPLODE || sndnum == LASERTRIP_EXPLODE || sndnum == RPG_EXPLODE));
+	auto sfx = soundEngine->GetSfx(soundid);
+	bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || 
+		((sfx->ResourceId == PIPEBOMB_EXPLODE || sfx->ResourceId == LASERTRIP_EXPLODE || sfx->ResourceId == RPG_EXPLODE));
 
 	bool underwater = ps[screenpeek].insector() && ps[screenpeek].cursector->lotag == ST_2_UNDERWATER;
 	if (explosion)
@@ -488,7 +488,7 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe
 
 	bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid);
 	if (is_playing && !issoundcontroller(actor))
-		S_StopSound(sndnum, actor);
+		S_StopSound(soundid, actor);
 
 	int const repeatp = (userflags & SF_LOOP);
 
@@ -518,19 +518,17 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe
 //
 //==========================================================================
 
-int S_PlaySound(int sndnum, int channel, EChanFlags flags, float vol)
+int S_PlaySound(FSoundID soundid, int channel, EChanFlags flags, float vol)
 {
-	auto soundid = FSoundID::fromInt(sndnum + 1);
 	if (!soundEngine->isValidSoundId(soundid) || !SoundEnabled()) return -1;
 
-	sndnum = GetReplacementSound(sndnum);
-	soundid = FSoundID::fromInt(sndnum + 1);
+	soundid = GetReplacementSound(soundid);
 
-	int userflags = S_GetUserFlags(sndnum);
+	int userflags = S_GetUserFlags(soundid);
 	if ((!(snd_speech & 1) && (userflags & SF_TALK)))
 		return -1;
 
-	int const pitch = S_GetPitch(sndnum);
+	int const pitch = S_GetPitch(soundid);
 
 	if (userflags & SF_LOOP) flags |= CHANF_LOOP;
 	if (currentCommentarySound != NO_SOUND) vol *= 0.25f;
@@ -545,17 +543,16 @@ int S_PlaySound(int sndnum, int channel, EChanFlags flags, float vol)
 //
 //==========================================================================
 
-int S_PlayActorSound(int soundNum, DDukeActor* actor, int channel, EChanFlags flags)
+int S_PlayActorSound(FSoundID soundNum, DDukeActor* actor, int channel, EChanFlags flags)
 {
 	return (actor == nullptr ? S_PlaySound(soundNum, channel, flags) :
 		S_PlaySound3D(soundNum, actor, actor->spr.pos, channel, flags));
 }
 
-void S_StopSound(int sndNum, DDukeActor* actor, int channel)
+void S_StopSound(FSoundID soundid, DDukeActor* actor, int channel)
 {
-	sndNum = GetReplacementSound(sndNum);
+	soundid = GetReplacementSound(soundid);
 
-	auto soundid = FSoundID::fromInt(sndNum + 1);
 	if (!actor) soundEngine->StopSoundID(soundid);
 	else
 	{
@@ -568,11 +565,8 @@ void S_StopSound(int sndNum, DDukeActor* actor, int channel)
 	}
 }
 
-void S_ChangeSoundPitch(int soundNum, DDukeActor* actor, int pitchoffset)
+void S_ChangeSoundPitch(FSoundID soundid, DDukeActor* actor, int pitchoffset)
 {
-	soundNum = GetReplacementSound(soundNum);
-	auto soundid = FSoundID::fromInt(soundNum + 1);
-
 	double expitch = pow(2, pitchoffset / 1200.);   // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
 	if (!actor)
 	{
@@ -590,10 +584,9 @@ void S_ChangeSoundPitch(int soundNum, DDukeActor* actor, int pitchoffset)
 //
 //==========================================================================
 
-int S_CheckActorSoundPlaying(DDukeActor* actor, int soundNum, int channel)
+int S_CheckActorSoundPlaying(DDukeActor* actor, FSoundID soundid, int channel)
 {
-	soundNum = GetReplacementSound(soundNum);
-	auto soundid = FSoundID::fromInt(soundNum + 1);
+	soundid = GetReplacementSound(soundid);
 
 	if (actor == nullptr) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid);
 	return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, channel, soundid);
@@ -606,10 +599,8 @@ int S_CheckAnyActorSoundPlaying(DDukeActor* actor)
 	return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, CHAN_AUTO);
 }
 
-int S_CheckSoundPlaying(int soundNum)
+int S_CheckSoundPlaying(FSoundID soundid)
 {
-	soundNum = GetReplacementSound(soundNum);
-	auto soundid = FSoundID::fromInt(soundNum + 1);
 	return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid);
 }
 
diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h
index b6cd4226a..37673b041 100644
--- a/source/games/duke/src/sounds.h
+++ b/source/games/duke/src/sounds.h
@@ -34,29 +34,67 @@ enum esound_t
 	kMaxUserData
 };
 
-void S_InitSound();
+int S_PlaySound(FSoundID num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol = 0.8f);
+int S_PlaySound3D(FSoundID num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
+int S_PlayActorSound(FSoundID soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
+void S_StopSound(FSoundID sndNum, DDukeActor* spr = nullptr, int flags = -1);
+void S_ChangeSoundPitch(FSoundID soundNum, DDukeActor* spriteNum, int pitchoffset);
+int S_CheckActorSoundPlaying(DDukeActor* spriteNum, FSoundID soundNum, int channel = 0);
+int S_CheckSoundPlaying(FSoundID soundNum);
+
 void S_CacheAllSounds(void);
 int S_DefineSound(unsigned index, const char* filename, int ps, int pe, int pr, int m, int vo, float vol);
 void S_WorldTourMappingsForOldSounds();
-
-int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol =0.8f);
-int S_PlaySound3D(int num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
-
-int S_PlayActorSound(int soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
 void S_MenuSound(void);
 
-void S_StopSound(int sndNum, DDukeActor* spr = nullptr, int flags = -1);
 
-int S_CheckSoundPlaying(int soundNum);
-int S_CheckActorSoundPlaying(DDukeActor* spriteNum, int soundNum, int channel = 0);
 int S_CheckAnyActorSoundPlaying(DDukeActor* spriteNum);
 
-void S_ChangeSoundPitch(int soundNum, DDukeActor* spriteNum, int pitchoffset);
-int S_GetUserFlags(int sndnum);
+int S_GetUserFlags(FSoundID sndnum);
 
 inline bool S_IsSoundValid(int num)
 {
-	return (!soundEngine->isValidSoundId(FSoundID::fromInt(num + 1)));
+	return !soundEngine->isValidSoundId(S_FindSoundByResID(num));
+}
+
+inline int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol = 0.8f)
+{
+	return S_PlaySound(S_FindSoundByResID(num), channel, flags, vol);
+}
+
+inline int S_PlaySound3D(int num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0)
+{
+	return S_PlaySound3D(S_FindSoundByResID(num), spriteNum, pos, channel, flags);
+}
+
+inline int S_PlayActorSound(int soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0)
+{
+	return S_PlayActorSound(S_FindSoundByResID(soundNum), spriteNum, channel, flags);
+}
+
+inline void S_StopSound(int sndNum, DDukeActor* spr = nullptr, int flags = -1)
+{
+	return S_StopSound(S_FindSoundByResID(sndNum), spr, flags);
+}
+
+inline void S_ChangeSoundPitch(int soundNum, DDukeActor* spriteNum, int pitchoffset)
+{
+	S_ChangeSoundPitch(S_FindSoundByResID(soundNum), spriteNum, pitchoffset);
+}
+
+inline int S_CheckActorSoundPlaying(DDukeActor* spriteNum, int soundNum, int channel = 0)
+{
+	return S_CheckActorSoundPlaying(spriteNum, S_FindSoundByResID(soundNum), channel);
+}
+
+inline int S_CheckSoundPlaying(int soundNum)
+{
+	return S_CheckSoundPlaying(S_FindSoundByResID(soundNum));
+}
+
+inline int S_GetUserFlags(int soundNum)
+{
+	return S_GetUserFlags(S_FindSoundByResID(soundNum));
 }
 
 
diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp
index 11a073998..b4c38abd7 100644
--- a/source/games/duke/src/vmexports.cpp
+++ b/source/games/duke/src/vmexports.cpp
@@ -99,39 +99,48 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySpecialMusic, S_PlaySpecialMusic)
 	return 0;
 }
 
-static int PlaySound(int num, int chan, int flags, double vol)
+static int duke_PlaySound(int num, int chan, int flags, double vol)
 {
-	return S_PlaySound(num, chan, EChanFlags::FromInt(flags), float(vol));
+	return S_PlaySound(FSoundID::fromInt(num), chan, EChanFlags::FromInt(flags), float(vol));
 }
 
-DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySound, PlaySound)
+DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySound, duke_PlaySound)
 {
 	PARAM_PROLOGUE;
 	PARAM_INT(snd);
 	PARAM_INT(chan);
 	PARAM_INT(flags);
 	PARAM_FLOAT(vol);
-	ACTION_RETURN_INT(PlaySound(snd, chan, flags, vol));
+	ACTION_RETURN_INT(duke_PlaySound(snd, chan, flags, vol));
 }
 static void StopSound(int num)
 {
 	S_StopSound(num);
 }
 
+void duke_StopSound(int snd)
+{
+	S_StopSound(FSoundID::fromInt(snd));
+}
 
-DEFINE_ACTION_FUNCTION_NATIVE(_Duke, StopSound, StopSound)
+DEFINE_ACTION_FUNCTION_NATIVE(_Duke, StopSound, duke_StopSound)
 {
 	PARAM_PROLOGUE;
 	PARAM_INT(snd);
-	StopSound(snd);
+	duke_StopSound(snd);
 	return 0;
 }
 
-DEFINE_ACTION_FUNCTION_NATIVE(_Duke, CheckSoundPlaying, S_CheckSoundPlaying)
+int duke_CheckSoundPlaying(int snd)
+{
+	return S_CheckSoundPlaying(FSoundID::fromInt(snd));
+}
+
+DEFINE_ACTION_FUNCTION_NATIVE(_Duke, CheckSoundPlaying, duke_CheckSoundPlaying)
 {
 	PARAM_PROLOGUE;
 	PARAM_INT(snd);
-	ACTION_RETURN_INT(S_CheckSoundPlaying(snd));
+	ACTION_RETURN_INT(duke_CheckSoundPlaying(snd));
 }
 
 player_struct* duke_checkcursectnums(sectortype* sector)
@@ -159,11 +168,16 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, global_random, duke_global_random)
 	ACTION_RETURN_INT(global_random);
 }
 
-DEFINE_ACTION_FUNCTION_NATIVE(_Duke, GetSoundFlags, S_GetUserFlags)
+int duke_GetSoundFlags(int sndid)
+{
+	return S_GetUserFlags(FSoundID::fromInt(sndid));
+}
+
+DEFINE_ACTION_FUNCTION_NATIVE(_Duke, GetSoundFlags, duke_GetSoundFlags)
 {
 	PARAM_PROLOGUE;
 	PARAM_INT(snd);
-	ACTION_RETURN_INT(S_GetUserFlags(snd));
+	ACTION_RETURN_INT(duke_GetSoundFlags(snd));
 }
 
 DEFINE_ACTION_FUNCTION_NATIVE(_Duke, badguyID, badguypic)
@@ -285,7 +299,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, domove, ssp)
 
 int DukeActor_PlayActorSound(DDukeActor* self, int snd, int chan, int flags)
 {
-	return S_PlayActorSound(snd, self, chan, EChanFlags::FromInt(flags));
+	return S_PlayActorSound(FSoundID::fromInt(snd), self, chan, EChanFlags::FromInt(flags));
 }
 
 DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, PlayActorSound, DukeActor_PlayActorSound)
@@ -299,7 +313,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, PlayActorSound, DukeActor_PlayActorSou
 
 void DukeActor_StopSound(DDukeActor* self, int snd, int flags)
 {
-	S_StopSound(snd, self, flags);
+	S_StopSound(FSoundID::fromInt(snd), self, flags);
 }
 
 DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, StopSound, DukeActor_StopSound)
diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h
index 5dbb7aa57..3a28a5bcb 100644
--- a/source/games/exhumed/src/exhumed.h
+++ b/source/games/exhumed/src/exhumed.h
@@ -238,6 +238,7 @@ struct GameInterface : public ::GameInterface
     void processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double interpfrac) override;
     int GetCurrentSkill() override;
     std::pair<DVector3, DAngle> GetCoordinates() override;
+    void StartSoundEngine() override;
 
 	::GameStats getStats() override;
 };
diff --git a/source/games/exhumed/src/sound.cpp b/source/games/exhumed/src/sound.cpp
index 135714fc7..04e5ad0fc 100644
--- a/source/games/exhumed/src/sound.cpp
+++ b/source/games/exhumed/src/sound.cpp
@@ -213,12 +213,13 @@ int LoadSound(const char* name)
 //
 //
 //==========================================================================
+void GameInterface::StartSoundEngine()
+{
+    soundEngine = new EXSoundEngine;
+}
 
 void InitFX(void)
 {
-    if (soundEngine) return; // just in case.
-    soundEngine = new EXSoundEngine;
-
     auto& S_sfx = soundEngine->GetSounds();
     S_sfx.Resize(1);
     for (size_t i = 0; i < kMaxSoundFiles; i++)
diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h
index 5c1bf77b9..414d4dc6d 100644
--- a/source/games/sw/src/game.h
+++ b/source/games/sw/src/game.h
@@ -1694,6 +1694,7 @@ struct GameInterface : public ::GameInterface
     int Voxelize(int sprnum);
     void ExitFromMenu() override;
     int GetCurrentSkill() override;
+    void StartSoundEngine() override;
 
 
     GameStats getStats() override;
diff --git a/source/games/sw/src/sounds.cpp b/source/games/sw/src/sounds.cpp
index 5a23e3063..19ef2ee94 100644
--- a/source/games/sw/src/sounds.cpp
+++ b/source/games/sw/src/sounds.cpp
@@ -472,11 +472,13 @@ TArray<uint8_t> SWSoundEngine::ReadSound(int lumpnum)
 //
 //
 //==========================================================================
+void GameInterface::StartSoundEngine()
+{
+    soundEngine = new SWSoundEngine;
+}
 
 void InitFX(void)
 {
-    if (soundEngine) return; // just in case.
-    soundEngine = new SWSoundEngine;
 
     auto &S_sfx = soundEngine->GetSounds();
     S_sfx.Resize(countof(voc));
diff --git a/wadsrc/static/filter/duke/sndinfo.txt b/wadsrc/static/filter/duke/sndinfo.txt
new file mode 100644
index 000000000..564431c98
--- /dev/null
+++ b/wadsrc/static/filter/duke/sndinfo.txt
@@ -0,0 +1,402 @@
+$conreserve KICK_HIT             0
+$conreserve PISTOL_RICOCHET      1
+$conreserve PISTOL_BODYHIT       2
+$conreserve PISTOL_FIRE          3
+$conreserve EJECT_CLIP           4
+$conreserve INSERT_CLIP          5
+$conreserve CHAINGUN_FIRE        6
+$conreserve RPG_SHOOT            7
+$conreserve POOLBALLHIT          8
+$conreserve RPG_EXPLODE          9
+$conreserve CAT_FIRE            10
+$conreserve SHRINKER_FIRE       11
+$conreserve ACTOR_SHRINKING     12
+$conreserve PIPEBOMB_BOUNCE     13
+$conreserve PIPEBOMB_EXPLODE    14
+$conreserve LASERTRIP_ONWALL    15
+$conreserve LASERTRIP_ARMING    16
+$conreserve LASERTRIP_EXPLODE   17
+$conreserve VENT_BUST           18
+$conreserve GLASS_BREAKING      19
+$conreserve GLASS_HEAVYBREAK    20
+$conreserve SHORT_CIRCUIT       21
+$conreserve ITEM_SPLASH         22
+$conreserve PLAYER_BREATHING      23
+$conreserve PLAYER_EXHALING       24
+$conreserve PLAYER_GASP           25
+$conreserve SLIM_RECOG          26
+$conreserve SOUND_27            27			
+$conreserve PLAYER_URINATE        28
+$conreserve ENDSEQVOL3SND2      29
+$conreserve ENDSEQVOL3SND3      30
+$conreserve PLAYER_PASSWIND       32
+$conreserve PLAYER_CRACK          33
+$conreserve SLIM_ATTACK         34
+$conreserve SOMETHINGHITFORCE   35
+$conreserve PLAYER_DRINKING       36
+$conreserve PLAYER_KILLED1        37
+$conreserve PLAYER_GRUNT          38
+$conreserve PLAYER_HARTBEAT       39
+$conreserve PLAYER_ONWATER        40
+$conreserve PLAYER_DEAD           41
+$conreserve PLAYER_LAND           42
+$conreserve PLAYER_WALKINDUCTS    43
+$conreserve PLAYER_GLAD           44
+$conreserve PLAYER_YES            45
+$conreserve PLAYER_HEHE           46
+$conreserve PLAYER_SHUCKS         47
+$conreserve PLAYER_UNDERWATER     48
+$conreserve PLAYER_JETPACK_ON     49
+$conreserve PLAYER_JETPACK_IDLE   50
+$conreserve PLAYER_JETPACK_OFF    51
+$conreserve LIZTROOP_GROWL      52
+$conreserve LIZTROOP_TALK1      53
+$conreserve LIZTROOP_TALK2      54
+$conreserve LIZTROOP_TALK3      55
+$conreserve DUKETALKTOBOSS      56
+$conreserve LIZCAPT_GROWL       57
+$conreserve LIZCAPT_TALK1       58
+$conreserve LIZCAPT_TALK2       59
+$conreserve LIZCAPT_TALK3       60
+$conreserve LIZARD_BEG          61
+$conreserve LIZARD_PAIN         62
+$conreserve LIZARD_DEATH        63
+$conreserve LIZARD_SPIT         64
+$conreserve DRONE1_HISSRATTLE   65
+$conreserve DRONE1_HISSSCREECH  66
+$conreserve PLAYER_TIP2           67
+$conreserve FLESH_BURNING       68
+$conreserve SQUISHED            69
+$conreserve TELEPORTER          70
+$conreserve ELEVATOR_ON         71
+$conreserve PLAYER_KILLED3        72
+$conreserve ELEVATOR_OFF        73
+$conreserve DOOR_OPERATE1       74
+$conreserve SUBWAY              75
+$conreserve SWITCH_ON           76
+$conreserve FAN                 77
+$conreserve PLAYER_GETWEAPON3     78
+$conreserve FLUSH_TOILET        79
+$conreserve HOVER_CRAFT         80
+$conreserve EARTHQUAKE          81
+$conreserve INTRUDER_ALERT      82
+$conreserve END_OF_LEVEL_WARN   83
+$conreserve ENGINE_OPERATING    84
+$conreserve REACTOR_ON          85
+$conreserve COMPUTER_AMBIENCE   86
+$conreserve GEARS_GRINDING      87
+$conreserve BUBBLE_AMBIENCE     88
+$conreserve MACHINE_AMBIENCE    89
+$conreserve SEWER_AMBIENCE      90
+$conreserve WIND_AMBIENCE       91
+$conreserve SOMETHING_DRIPPING  92
+$conreserve STEAM_HISSING       93
+$conreserve THEATER_BREATH      94
+$conreserve BAR_MUSIC           95
+$conreserve BOS1_ROAM           96
+$conreserve BOS1_RECOG          97
+$conreserve BOS1_ATTACK1        98
+$conreserve BOS1_PAIN           99
+$conreserve BOS1_DYING         100
+$conreserve BOS2_ROAM          101
+$conreserve BOS2_RECOG         102
+$conreserve BOS2_ATTACK        103
+$conreserve BOS2_PAIN          104
+$conreserve BOS2_DYING         105
+$conreserve GETATOMICHEALTH    106
+$conreserve PLAYER_GETWEAPON2    107
+$conreserve BOS3_DYING         108
+$conreserve SHOTGUN_FIRE       109
+$conreserve PRED_ROAM          110
+$conreserve PRED_RECOG         111
+$conreserve PRED_ATTACK        112
+$conreserve PRED_PAIN          113
+$conreserve PRED_DYING         114
+$conreserve CAPT_ROAM          115
+$conreserve CAPT_ATTACK        116
+$conreserve CAPT_RECOG         117
+$conreserve CAPT_PAIN          118
+$conreserve CAPT_DYING         119
+$conreserve PIG_ROAM           120
+$conreserve PIG_RECOG          121
+$conreserve PIG_ATTACK         122
+$conreserve PIG_PAIN           123
+$conreserve PIG_DYING          124
+$conreserve RECO_ROAM          125
+$conreserve RECO_RECOG         126
+$conreserve RECO_ATTACK        127
+$conreserve RECO_PAIN          128
+$conreserve RECO_DYING         129
+$conreserve DRON_ROAM          130
+$conreserve DRON_RECOG         131
+$conreserve DRON_ATTACK1       132
+$conreserve DRON_PAIN          133
+$conreserve DRON_DYING         134
+$conreserve COMM_ROAM          135
+$conreserve COMM_RECOG         136
+$conreserve COMM_ATTACK        137
+$conreserve COMM_PAIN          138
+$conreserve COMM_DYING         139
+$conreserve OCTA_ROAM          140
+$conreserve OCTA_RECOG         141
+$conreserve OCTA_ATTACK1       142
+$conreserve OCTA_PAIN          143
+$conreserve OCTA_DYING         144
+$conreserve TURR_ROAM          145
+$conreserve TURR_RECOG         146
+$conreserve TURR_ATTACK        147
+$conreserve DUMPSTER_MOVE      148
+$conreserve SLIM_DYING         149
+$conreserve BOS3_ROAM          150
+$conreserve BOS3_RECOG         151
+$conreserve BOS3_ATTACK1       152
+$conreserve BOS3_PAIN          153
+$conreserve BOS1_ATTACK2       154
+$conreserve COMM_SPIN          155
+$conreserve BOS1_WALK          156
+$conreserve DRON_ATTACK2       157
+$conreserve THUD               158
+$conreserve OCTA_ATTACK2       159
+$conreserve WIERDSHOT_FLY      160
+$conreserve TURR_PAIN          161
+$conreserve TURR_DYING         162
+$conreserve SLIM_ROAM          163
+$conreserve LADY_SCREAM        164
+$conreserve DOOR_OPERATE2      165
+$conreserve DOOR_OPERATE3      166
+$conreserve DOOR_OPERATE4      167
+$conreserve BORNTOBEWILDSND    168
+$conreserve SHOTGUN_COCK       169
+$conreserve GENERIC_AMBIENCE1  170
+$conreserve GENERIC_AMBIENCE2  171
+$conreserve GENERIC_AMBIENCE3  172
+$conreserve GENERIC_AMBIENCE4  173
+$conreserve GENERIC_AMBIENCE5  174
+$conreserve GENERIC_AMBIENCE6  175
+$conreserve BOS3_ATTACK2       176
+$conreserve GENERIC_AMBIENCE17 177
+$conreserve GENERIC_AMBIENCE18 178
+$conreserve GENERIC_AMBIENCE19 179
+$conreserve GENERIC_AMBIENCE20 180
+$conreserve GENERIC_AMBIENCE21 181
+$conreserve GENERIC_AMBIENCE22 182
+$conreserve SECRETLEVELSND     183
+$conreserve GENERIC_AMBIENCE8  184
+$conreserve GENERIC_AMBIENCE9  185
+$conreserve GENERIC_AMBIENCE10 186
+$conreserve GENERIC_AMBIENCE11 187
+$conreserve GENERIC_AMBIENCE12 188
+$conreserve GENERIC_AMBIENCE13 189
+$conreserve GENERIC_AMBIENCE14 190
+$conreserve GENERIC_AMBIENCE15 192
+$conreserve GENERIC_AMBIENCE16 193
+$conreserve FIRE_CRACKLE       194
+$conreserve BONUS_SPEECH1      195
+$conreserve BONUS_SPEECH2      196
+$conreserve BONUS_SPEECH3      197
+$conreserve PIG_CAPTURE_DUKE   198
+$conreserve BONUS_SPEECH4      199
+$conreserve PLAYER_LAND_HURT     200
+$conreserve PLAYER_HIT_STRIPPER1 201
+$conreserve PLAYER_TIP1          202
+$conreserve PLAYER_KILLED2       203
+$conreserve PRED_ROAM2         204
+$conreserve PIG_ROAM2          205
+$conreserve PLAYER_GETWEAPON1    206
+$conreserve PLAYER_SEARCH2       207
+$conreserve PLAYER_CRACK2        208
+$conreserve PLAYER_SEARCH        209
+$conreserve PLAYER_GET           210
+$conreserve PLAYER_LONGTERM_PAIN 211
+$conreserve MONITOR_ACTIVE     212
+$conreserve NITEVISION_ONOFF   213
+$conreserve PLAYER_HIT_STRIPPER2 214
+$conreserve PLAYER_CRACK_FIRST   215
+$conreserve PLAYER_USEMEDKIT     216
+$conreserve PLAYER_TAKEPILLS     217
+$conreserve PLAYER_PISSRELIEF    218
+$conreserve SELECT_WEAPON      219
+$conreserve WATER_GURGLE       220
+$conreserve PLAYER_GETWEAPON4    221
+$conreserve JIBBED_ACTOR1      222
+$conreserve JIBBED_ACTOR2      223
+$conreserve JIBBED_ACTOR3      224
+$conreserve JIBBED_ACTOR4      225
+$conreserve JIBBED_ACTOR5      226
+$conreserve JIBBED_ACTOR6      227
+$conreserve JIBBED_ACTOR7      228
+$conreserve PLAYER_GOTHEALTHATLOW229
+$conreserve BOSSTALKTODUKE     230
+$conreserve WAR_AMBIENCE1      231
+$conreserve WAR_AMBIENCE2      232
+$conreserve WAR_AMBIENCE3      233
+$conreserve WAR_AMBIENCE4      234
+$conreserve WAR_AMBIENCE5      235
+$conreserve WAR_AMBIENCE6      236
+$conreserve WAR_AMBIENCE7      237
+$conreserve WAR_AMBIENCE8      238
+$conreserve WAR_AMBIENCE9      239
+$conreserve WAR_AMBIENCE10     240
+$conreserve ALIEN_TALK1        241
+$conreserve ALIEN_TALK2        242
+$conreserve EXITMENUSOUND      243
+$conreserve FLY_BY             244
+$conreserve PLAYER_SCREAM        245
+$conreserve SHRINKER_HIT       246
+$conreserve RATTY              247
+$conreserve INTO_MENU          248
+$conreserve BONUSMUSIC         249
+$conreserve PLAYER_BOOBY         250
+$conreserve PLAYER_TALKTOBOSSFALL251
+$conreserve PLAYER_LOOKINTOMIRROR252
+$conreserve PIG_ROAM3          253
+$conreserve KILLME             254
+$conreserve DRON_JETSND        255
+$conreserve SPACE_DOOR1        256
+$conreserve SPACE_DOOR2        257
+$conreserve SPACE_DOOR3        258
+$conreserve SPACE_DOOR4        259
+$conreserve SPACE_DOOR5        260
+$conreserve ALIEN_ELEVATOR1    261
+$conreserve VAULT_DOOR         262
+$conreserve JIBBED_ACTOR13     263
+$conreserve PLAYER_GETWEAPON6    264
+$conreserve JIBBED_ACTOR8      265
+$conreserve JIBBED_ACTOR9      266
+$conreserve JIBBED_ACTOR10     267
+$conreserve JIBBED_ACTOR11     268
+$conreserve JIBBED_ACTOR12     269
+$conreserve PLAYER_KILLED4       270
+$conreserve PLAYER_KILLED5       271
+$conreserve ALIEN_SWITCH1      272
+$conreserve PLAYER_STEPONFECES   273
+$conreserve PLAYER_LONGTERM_PAIN2274
+$conreserve PLAYER_LONGTERM_PAIN3275
+$conreserve PLAYER_LONGTERM_PAIN4276
+$conreserve COMPANB2           277
+$conreserve KTIT               278
+$conreserve HELICOP_IDLE       279
+$conreserve STEPNIT            280
+$conreserve SPACE_AMBIENCE1    281
+$conreserve SPACE_AMBIENCE2    282
+$conreserve SLIM_HATCH         283
+$conreserve RIPHEADNECK        284
+$conreserve FOUNDJONES         285
+$conreserve ALIEN_DOOR1        286
+$conreserve ALIEN_DOOR2        287
+$conreserve ENDSEQVOL3SND4     288
+$conreserve ENDSEQVOL3SND5     289
+$conreserve ENDSEQVOL3SND6     290
+$conreserve ENDSEQVOL3SND7     291
+$conreserve ENDSEQVOL3SND8     292
+$conreserve ENDSEQVOL3SND9     293
+$conreserve WHIPYOURASS        294
+$conreserve ENDSEQVOL2SND1     295
+$conreserve ENDSEQVOL2SND2     296
+$conreserve ENDSEQVOL2SND3     297
+$conreserve ENDSEQVOL2SND4     298
+$conreserve ENDSEQVOL2SND5     299
+$conreserve ENDSEQVOL2SND6     300
+$conreserve ENDSEQVOL2SND7     301
+$conreserve GENERIC_AMBIENCE23 302
+$conreserve SOMETHINGFROZE     303
+$conreserve PLAYER_LONGTERM_PAIN5304
+$conreserve PLAYER_LONGTERM_PAIN6305
+$conreserve PLAYER_LONGTERM_PAIN7306
+$conreserve PLAYER_LONGTERM_PAIN8307
+$conreserve WIND_REPEAT        308
+$conreserve MYENEMY_ROAM       309
+$conreserve MYENEMY_HURT       310
+$conreserve MYENEMY_DEAD       311
+$conreserve MYENEMY_SHOOT      312
+$conreserve STORE_MUSIC        313
+$conreserve STORE_MUSIC_BROKE  314
+$conreserve ACTOR_GROWING      315
+$conreserve NEWBEAST_ROAM      316
+$conreserve NEWBEAST_RECOG     317
+$conreserve NEWBEAST_ATTACK    318
+$conreserve NEWBEAST_PAIN      319
+$conreserve NEWBEAST_DYING     320
+$conreserve NEWBEAST_SPIT      321
+$conreserve VOL4_1             322
+$conreserve SUPERMARKET        323
+$conreserve MOUSEANNOY         324
+$conreserve BOOKEM             325
+$conreserve SUPERMARKETCRY     326
+$conreserve DESTRUCT           327
+$conreserve EATFOOD            328
+$conreserve MAKEMYDAY          329
+$conreserve WITNESSSTAND       330
+$conreserve VACATIONSPEECH     331
+$conreserve YIPPEE1            332
+$conreserve YOHOO1             333
+$conreserve YOHOO2             334
+$conreserve DOLPHINSND         335
+$conreserve TOUGHGALSND1       336
+$conreserve TOUGHGALSND2       337
+$conreserve TOUGHGALSND3       338
+$conreserve TOUGHGALSND4       339
+$conreserve TANK_ROAM          340
+$conreserve BOS4_ROAM          341
+$conreserve BOS4_RECOG         342
+$conreserve BOS4_ATTACK        343
+$conreserve BOS4_PAIN          344
+$conreserve BOS4_DYING         345
+$conreserve NEWBEAST_ATTACKMISS346
+$conreserve VOL4_2             347
+$conreserve COOKINGDEEPFRIER   348
+$conreserve WHINING_DOG        349
+$conreserve DEAD_DOG           350
+$conreserve LIGHTNING_SLAP     351
+$conreserve THUNDER            352
+$conreserve HAPPYMOUSESND1     353
+$conreserve HAPPYMOUSESND2     354
+$conreserve HAPPYMOUSESND3     355
+$conreserve HAPPYMOUSESND4     356
+$conreserve ALARM              357
+$conreserve RAIN               358
+$conreserve DTAG_GREENRUN      359
+$conreserve DTAG_BROWNRUN      360
+$conreserve DTAG_GREENSCORE    361
+$conreserve DTAG_BROWNSCORE    362
+$conreserve INTRO4_1           363
+$conreserve INTRO4_2           364
+$conreserve INTRO4_3           365
+$conreserve INTRO4_4           366
+$conreserve INTRO4_5           367
+$conreserve INTRO4_6           368
+$conreserve SCREECH            369
+$conreserve BOSS4_DEADSPEECH   370
+$conreserve BOSS4_FIRSTSEE     371
+$conreserve PARTY_SPEECH       372
+$conreserve POSTAL_SPEECH      373
+$conreserve TGSPEECH           374
+$conreserve DOGROOMSPEECH      375
+$conreserve SMACKED            376
+$conreserve MDEVSPEECH         377
+$conreserve AREA51SPEECH       378
+$conreserve JEEPSOUND          379
+$conreserve BIGDOORSLAM        380
+$conreserve BOS4_LAY           381
+$conreserve WAVESOUND          382
+$conreserve ILLBEBACK          383
+$conreserve VOL4ENDSND1        384
+$conreserve VOL4ENDSND2        385
+$conreserve EXPANDERHIT        386
+$conreserve SNAKESPEECH        387
+$conreserve EXPANDERSHOOT      388
+$conreserve GETBACKTOWORK      389
+$conreserve JIBBED_ACTOR14     390
+$conreserve JIBBED_ACTOR15     391
+$conreserve INTRO4_B           392
+$conreserve BIGBANG            393
+$conreserve SMACKIT            394
+$conreserve BELLSND            395
+$conreserve GOAWAY             396
+$conreserve JOKE               397
+$conreserve FLAMETHROWER_INTRO 398
+$conreserve FLAMETHROWER_LOOP  399
+$conreserve FLAMETHROWER_END   400
+$conreserve E5L7_PLAYER_QUIT_YOU 401
+
+$alias CRANEGRAB PLAYER_GRUNT
diff --git a/wadsrc/static/filter/redneck/sndinfo.txt b/wadsrc/static/filter/redneck/sndinfo.txt
new file mode 100644
index 000000000..98a17e2ae
--- /dev/null
+++ b/wadsrc/static/filter/redneck/sndinfo.txt
@@ -0,0 +1,508 @@
+$conreserve KICK_HIT            0
+$conreserve PISTOL_RICOCHET     1
+$conreserve PISTOL_BODYHIT      2
+$conreserve PISTOL_FIRE         3
+$conreserve EJECT_CLIP          4
+$conreserve INSERT_CLIP         5
+$conreserve CHAINGUN_FIRE       6
+$conreserve RPG_SHOOT           7
+$conreserve BUB_HRT1     8 
+$conreserve RPG_EXPLODE         9
+$conreserve LASERA       10
+$conreserve SHRINKER     11
+$conreserve CRAPFLOW     12
+$conreserve DYNOCLMP     13
+$conreserve DYNEW        14
+$conreserve CRAPSTIR     15
+$conreserve BRICDOOR     16
+$conreserve BOMBEXPL     17
+$conreserve VENT_BUST          18
+$conreserve GLASS_BREAKING     19
+$conreserve GLASS_HEAVYBREAK   20
+$conreserve BUBBLES      21
+$conreserve SPLASH       22
+$conreserve BUB_HRT2     23
+$conreserve BUB_HRT3     24
+$conreserve PLAYER_GASP          25
+$conreserve BUB_HRT4     26
+
+$conreserve ONECART      27 // RR
+$conreserve MINEWIND     28
+$conreserve URANUS       29					// !!!
+
+//$conreserve MIRROR1      27 // RRRA
+//$conreserve MIRROR2      28
+//$conreserve MIRROR3      29
+
+$conreserve COMPUTER     30
+$conreserve NEON         31
+$conreserve VX_FINAL     32
+$conreserve LN_WAIT      33
+$conreserve BUB_LN1      34
+$conreserve LN_FINAL     35					// !!!
+$conreserve CLOCKTK      36
+$conreserve LN_STANK     37
+$conreserve LNRD_GRUNT   38
+$conreserve CLOCKCHM     39
+$conreserve WETFEET      40
+$conreserve LNRD_DEAD    41
+$conreserve LAND         42
+$conreserve END_PIPE     43
+$conreserve ICARUMBA     44
+$conreserve BUB_LN2      45
+$conreserve LN_CRAP      46
+$conreserve WOODBREK     47
+$conreserve SCUBA        48
+$conreserve TRUCK_LP2    49
+$conreserve COW1         50
+$conreserve COW2         51
+$conreserve COW3         52
+$conreserve COW4         53
+$conreserve COW5         54
+$conreserve BUB_LN3      55
+$conreserve LATCH        56
+$conreserve BUB_LN5      57
+$conreserve BUB_LN6      58
+$conreserve BUB_LN7      59
+$conreserve BUB_PIK1     60
+$conreserve BUB_PIK2     61
+$conreserve BUB_PISS     62
+$conreserve E1L1         63
+$conreserve E1L2         64
+$conreserve UFOINSID     65
+$conreserve LN_RODE      66
+$conreserve CURTAIN      67
+$conreserve FIRE09       68
+$conreserve SQUISHED     69
+$conreserve TELEPORT     70
+$conreserve GBELEV01     71
+$conreserve LN_BNCH      72
+$conreserve GBELEV02     73
+$conreserve FROG1        74
+$conreserve TRUCK_LP     75
+$conreserve SWITCH1      76
+$conreserve E1L3         77
+$conreserve LN_HOTDM     78
+$conreserve FLUSH        79
+$conreserve E1L4         80
+$conreserve QUAKE        81
+$conreserve CHKAMMO      82
+$conreserve MONITORA     83
+$conreserve FROG2        84
+$conreserve AS_AMB2      85
+$conreserve AS_AMB1      86
+$conreserve FBOATIDL     87
+$conreserve FBOATRUN     88
+$conreserve FBOATUP      89
+$conreserve FBOATDN      90
+$conreserve FBOATTRN     91
+$conreserve SOMETHING_DRIPPING 92
+$conreserve SWAMPAMB     93
+$conreserve MORTAR       94
+$conreserve JUKEBOX      95
+$conreserve AS_DROPN     96
+$conreserve AS_CRYPT     97
+$conreserve AS_DRCLS     98
+$conreserve LOKGATE      99
+$conreserve METLGAT2     100
+$conreserve METLGAT1     101
+$conreserve E1L5         102
+$conreserve E1L6         103
+$conreserve E1L7         104
+$conreserve E2L1         105
+$conreserve PADDLE       106
+$conreserve LN_HOLD      107
+$conreserve VX_TAKIT     108
+$conreserve SHOT6        109
+$conreserve CT_LAF2      110
+$conreserve CT_GET       111
+$conreserve CT_LAF       112
+$conreserve CT_PAIN      113
+$conreserve CT_DIE       114
+$conreserve PIGSOUND1    115
+$conreserve PIGSOUND2    116
+$conreserve PIGSOUND3    117
+$conreserve PIGSOUND4    118
+$conreserve PIGSOUND5    119
+$conreserve BR_ROAM1     120
+$conreserve BR_RECOG     121
+$conreserve WHISTLE      122
+$conreserve BR_PAIN      123
+$conreserve BR_DTH       124
+$conreserve VX_ISTHT     125
+$conreserve LASERH       126
+$conreserve PIGSOUND6    127
+$conreserve PIGSOUND7    128
+$conreserve VX_DIE1      129
+$conreserve MJ_JIB1      130
+$conreserve VX_DIE4      131
+$conreserve VX_DIE5      132
+$conreserve VX_DIE6      133
+$conreserve VX_DIE7      134
+$conreserve VX_OOH       135
+$conreserve VX_PAIN1     136
+$conreserve VX_SEX1      137
+$conreserve VX_SEX2      138
+$conreserve VX_SEX3      139
+$conreserve VX_GRNT      140
+$conreserve RENO         141
+$conreserve BK_MAKE1     142
+$conreserve BK_MAKE2     143
+$conreserve VX_BRNG3     144
+$conreserve VX_CLSR1     145
+$conreserve VX_CLSR2     146
+$conreserve VX_2FAR      147
+$conreserve KINGHUH      148
+$conreserve VX_BRING     149
+$conreserve VX_BITE      150
+$conreserve MJ_FART      151
+$conreserve VX_LAFF2     152
+$conreserve VX_LAFF3     153
+$conreserve VX_HMMM2     154
+$conreserve VX_HURT2     155
+$conreserve VX_BABY2     156
+$conreserve VX_MHMM      157
+$conreserve THUD         158
+$conreserve VX_ITSOK     159
+$conreserve MJ_RECO2     160
+$conreserve VX_TPOT1  161
+$conreserve VX_TPOT4     162
+$conreserve VX_TPIN1  163
+$conreserve ROPECRK      164
+$conreserve DR_CRK8      165
+$conreserve DR_ROLL      166
+$conreserve STEELAMB     167
+$conreserve ROULETTE     168
+$conreserve GUNCHANG     169
+$conreserve FLIES        170
+$conreserve AMB_1        171
+$conreserve GRAVAMB      172
+$conreserve HOOTOWL      173
+$conreserve WOODS2       174
+$conreserve CATAMB       175
+$conreserve E2L2         176
+$conreserve E2L3         177
+$conreserve FBOATX_1     178
+$conreserve FBOATX_2     179
+$conreserve FBOATX_3     180
+$conreserve FBOATX_4     181
+$conreserve FBOATSLW     182
+$conreserve PLANE        183
+$conreserve CNTAMB       184
+$conreserve JUNKAMB2     185
+$conreserve BIKESTRT     186
+$conreserve BIKEIDLE     187
+$conreserve BIKELOOP     188
+$conreserve BIKEJMPS     189
+$conreserve BIKEJMPL     190
+$conreserve BIKELAND     191
+$conreserve JACKJMP1     192
+$conreserve JACKJMP2     193
+$conreserve FIRE_CRACKLE       =194
+$conreserve BONUS_SPEECH1      =195
+$conreserve BONUS_SPEECH2      =196
+$conreserve BONUS_SPEECH3      =197
+$conreserve E2L4         198
+$conreserve BONUS_SPEECH4      =199
+$conreserve PLAYER_LAND_HURT     =200
+$conreserve JACKATK2     201
+$conreserve JACKPAIN     202
+$conreserve LN_BITCH     203
+$conreserve CT_LAND      204
+$conreserve BR_ROAM2     205
+$conreserve LN_HUSH      206
+$conreserve LN_PAIN4     207
+$conreserve LN_SLOW      208
+$conreserve LN_PAIN4A    209
+$conreserve JUG          210
+$conreserve PLAYER_LONGTERM_PAIN =211
+$conreserve MONITOR      212
+$conreserve JACKATK1     213
+$conreserve BIKEUP       214
+$conreserve PLANEXP      215
+$conreserve JUGALUG7     216
+$conreserve DIDDLP       217
+$conreserve ELVISMOD     218
+// PISCOCK   219
+$conreserve BIKESKID     220
+$conreserve LN_STINK     221
+$conreserve JIBBED1      222
+$conreserve JIBBED2      223
+$conreserve JIBBED3      224
+$conreserve JIBBED4      225
+$conreserve JIBBED5      226
+$conreserve JIBBED6      227
+$conreserve JIBBED7      228
+$conreserve LN_BACON     229
+$conreserve E2L5         230
+$conreserve REGISTER     231
+$conreserve BBQGRILL     232
+$conreserve CRSSBELL     233
+$conreserve TRAIN        234
+$conreserve SLOTS        235
+$conreserve INDIANS      236
+$conreserve RADIO        237
+$conreserve BIKEX_1      238
+$conreserve BIKEX_2      239
+$conreserve BIKEX_3      240
+$conreserve TVSNOW       241
+$conreserve WINDLITE     242
+$conreserve EXITMENU     243
+$conreserve CHKBOWFR     244
+$conreserve DSCREM04     245
+$conreserve SHRNK_HIT    246
+$conreserve CHKBOWEX     247
+$conreserve INTOMENU     248
+$conreserve LAVAFLOW     249
+$conreserve LAVA_RK      250
+$conreserve BIKELOO2     251
+$conreserve SLINGBL      252
+$conreserve BR_ROAM3     253
+$conreserve KILLME       254
+$conreserve E2L6         255
+$conreserve RINTRO       256
+$conreserve MIRROR4      257
+$conreserve MIRROR5      258
+$conreserve GAMBELEV     259
+$conreserve SLINGHIT     260
+$conreserve PIANO_P1     261
+$conreserve BANJO1       262
+$conreserve JIBBED13     263
+$conreserve LN_BBQ       264
+$conreserve JIBBED8      265
+$conreserve JIBBED9      266
+$conreserve JIBBED10     267
+$conreserve JIBBED11     268
+$conreserve JIBBED12     269
+$conreserve LNRD_KILLED4 270
+$conreserve LNRD_KILLED5 271
+$conreserve BANJO2       272
+$conreserve BANJO3       273
+$conreserve LN_PAIN2     274
+$conreserve LN_PAIN3     275
+$conreserve BK_ALIVE     276
+$conreserve BK_BOURB     277
+$conreserve BK_CHEER     278
+$conreserve BK_DIENB     279
+$conreserve BK_DNTLK     280
+$conreserve BK_FUN       281
+$conreserve BK_HEY       282
+$conreserve E2L7         283
+$conreserve BK_HEYNB     284
+$conreserve BK_JOYRD     285
+$conreserve BK_KEEPA     286
+$conreserve BK_PLEAS     287
+$conreserve BK_RIDE      288
+$conreserve BK_ROAD      289
+$conreserve BK_SCRAT     290
+$conreserve BK_SHTUP     291
+$conreserve BK_SNORT     292
+$conreserve BK_TOHEL     293
+$conreserve WHIPYOU      294
+$conreserve BK_TRYIN     295
+$conreserve BK_PAIN1     296
+$conreserve BK_PAIN2     297
+$conreserve BK_PAIN3     298
+$conreserve CH_BALD      299
+$conreserve CH_TEAS1     300
+$conreserve CH_TEAS2     301
+$conreserve CH_TEAS3     302
+$conreserve CH_SANDP     303
+$conreserve LN_PAIN5     304
+$conreserve LN_PAIN6     305
+$conreserve LN_PAIN7     306
+$conreserve CH_DONIT     307
+$conreserve CH_WHOOP     308
+$conreserve CH_NIPPL     309
+$conreserve CH_BARN      310
+$conreserve CH_GTEAM     311
+$conreserve CH_GOGOG     312
+$conreserve CH_REDOK     313
+$conreserve CH_2468      314
+$conreserve CH_BIGON     315
+$conreserve HULK_ROAM    316
+$conreserve HULK_RECOG   317
+$conreserve HULK_ATTACK  318
+$conreserve HULK_PAIN    319
+$conreserve HULK_DYING   320
+$conreserve HULK_SPIT    321
+$conreserve CH_PAIN1     322
+$conreserve CH_PAIN2     323
+$conreserve CH_PAIN3     324
+$conreserve CH_HURT      325
+$conreserve AK4          326
+$conreserve CHKSCR1      327
+$conreserve SHIPWREK     328
+$conreserve HYDROGLY     329
+$conreserve PIANO_P2     330
+$conreserve FROGTOSS     331
+$conreserve TRAIN2       332
+$conreserve CRICKET1     333
+$conreserve CRICKET2     334
+$conreserve PIGRUNT      335
+$conreserve GOCATGO      336
+$conreserve ANNOUNC1     337
+$conreserve ANNOUNC2     338
+$conreserve TRACTOR      339
+$conreserve PIANO_P3     340
+$conreserve RESIZE       341
+$conreserve VX_TPIN2     342
+$conreserve VX_TPIN4     343
+$conreserve VX_HLPME     344
+$conreserve ATFSPEAK     345
+$conreserve WINDCAVE     346
+$conreserve ALARM        347
+$conreserve SF_THLAW     348
+$conreserve SF_TLAW2     349
+$conreserve LN_SCREW     350
+$conreserve THUNDER1     351
+$conreserve THUNDER2     352
+$conreserve THUNDER3     353
+$conreserve BOWLSTRT     354
+$conreserve BOWLPIN      355
+$conreserve BOWLLOOP     356
+$conreserve MJ_JIB2      357
+$conreserve VX_KICK2     358
+$conreserve VX_KICK3     359
+$conreserve MJ_RECO1     360
+$conreserve VX_HIYA      361
+$conreserve VX_HIYA2     362
+$conreserve SF_ATTN      363
+$conreserve SF_DETH1     364
+$conreserve SF_DETH2     365
+$conreserve SF_DETH3     366
+$conreserve TEDOUT       367
+$conreserve SF_FREZ2     368
+$conreserve SF_GETYA     369
+$conreserve SF_HANDS     370
+$conreserve STEELAM2     371
+$conreserve STEELAM3     372
+$conreserve SF_HEY       373
+$conreserve SF_HOLD      374
+$conreserve SF_LAFF1     375
+$conreserve LN_FLYOP     376
+$conreserve LN_SHTHD     377
+$conreserve SF_NAME      378
+$conreserve SF_OVER      379
+$conreserve SF_PAIN1     380
+$conreserve SF_PAIN2     381
+$conreserve SF_PAIN3     382
+$conreserve SF_RLOAD     383
+$conreserve SF_RLOD2     384
+$conreserve SF_SHOOT     385
+$conreserve JAWHARP      386
+$conreserve LN_TIGHT     387
+$conreserve DR_CLS       388
+$conreserve SCRAPE_1     389
+$conreserve YEHAA16      390
+$conreserve LN_WHUP      391
+$conreserve CHKNFLAP     392
+$conreserve CHKN_1       393
+$conreserve CHKN_2       394
+$conreserve CHIKDETH     395
+$conreserve AMB_ROOM     396
+$conreserve BR_ITCH      397
+$conreserve BR_SCRTH     398
+$conreserve BR_SNIFF     399
+$conreserve TRUKDIE      400
+$conreserve ZIPOPEN      401
+$conreserve ZIPPSTRK     402
+$conreserve MOSQUI4      403
+$conreserve FART1        404				
+$conreserve SWITCH2      405
+$conreserve SQUEAKY      406
+$conreserve CATDOOR      407
+$conreserve JUNKSWCH     408
+$conreserve CONVEYR      409
+$conreserve SWITCH3      410
+$conreserve BIKEENEM     411
+$conreserve BIGDOOR      412
+$conreserve FLOODGAT     413
+$conreserve JACK_RM1     414
+$conreserve MN_FREAK     415
+$conreserve MN_PN        416
+$conreserve MN_REC       417
+$conreserve MN_AMB       418
+$conreserve LOKDOOR      419
+$conreserve VOMIT        420
+$conreserve TOSS         421
+$conreserve FART2        422
+$conreserve FART3        423
+$conreserve FART4        424
+$conreserve CHUG         425
+$conreserve CROWUSH      426
+$conreserve WUSSLAF      427
+$conreserve LN_CITY      428
+$conreserve MUNCH2       429
+$conreserve TESLARC      430
+$conreserve BUZSAWSND    431
+$conreserve ELEVLOOP     432
+$conreserve PISSEND      433
+$conreserve PISSLOOP     434
+$conreserve PISSSTRT     435
+$conreserve CRAP         436
+$conreserve PEE          437
+$conreserve JACK_RM2     438
+$conreserve BELL         439
+$conreserve TRAINWRK     440
+$conreserve DOOR_PKT     441
+$conreserve GAMBDOOR     442
+$conreserve OVEN         443
+$conreserve CREMATOR     444
+$conreserve JOE9000A     445
+$conreserve JOE9000B     446
+$conreserve JOE9000C     447
+$conreserve CHINESE      448
+$conreserve SIGNROT      449
+$conreserve XBOWCOCK     450
+$conreserve PWDERKEG     451
+$conreserve DG_BARK1     452
+$conreserve DG_GRWL1     453
+$conreserve DG_YELP      454
+$conreserve DG_DIE       455
+$conreserve UFO          456
+$conreserve UFOLET       457
+$conreserve JACKJIB1     458
+$conreserve JACKJIB2     459
+$conreserve JACKJIB3     460
+$conreserve JACKJIB4     461
+$conreserve JACKJIB5     462
+$conreserve WTRFALL      463
+$conreserve BK_JIB1      464
+$conreserve FRIDGEOP     465
+$conreserve FRIDGECL     466
+$conreserve DG_LUNGE     467
+$conreserve DRIVTHRU     468
+$conreserve FAN          469
+$conreserve CRUSHER      470
+$conreserve BALLOON      471
+$conreserve POOLBUD      472
+$conreserve STAMPER      473
+$conreserve BK_JIB2      474
+$conreserve MORNING      475
+$conreserve DG_BARK2     476
+$conreserve DG_GRWL2     477
+$conreserve REDNECK2     478
+$conreserve XATRIX       479
+$conreserve MJ_ATTK1     480
+$conreserve MJ_JUMP      485
+$conreserve MJ_PAIN1     481
+$conreserve MJ_PAIN2     482
+$conreserve MJ_ROAM1     483
+$conreserve MJ_ROAM2     484
+$conreserve MJ_ROLL      486
+$conreserve DISHES       487
+$conreserve BUB_ELV1     488
+$conreserve BUB_ELV2     489
+$conreserve BUB_ELV3     490
+$conreserve BK_JIB3      491
+$conreserve CH_JIB1      492
+$conreserve CH_JIB2      493
+$conreserve CH_JIB3      494
+$conreserve SIGNHIT      495
+$conreserve UMHUM        496
+$conreserve COYOTE       497
+$conreserve BUB_HEY1     498
+$conreserve BUB_HEY2     499
+
+$alias CRANEGRAB YEHAA16
diff --git a/wadsrc/static/zscript/games/duke/actors/bolt.zs b/wadsrc/static/zscript/games/duke/actors/bolt.zs
index 4729a3adc..798a907d9 100644
--- a/wadsrc/static/zscript/games/duke/actors/bolt.zs
+++ b/wadsrc/static/zscript/games/duke/actors/bolt.zs
@@ -54,7 +54,7 @@ class DukeBolt1 : DukeActor
 		if (l & 1) self.cstat ^= CSTAT_SPRITE_TRANSLUCENT;
 
 		if (self.spritesetindex == 1 && random(0, 7) == 0 && (dlevel.floorflags(sectp) & Duke.TFLAG_ELECTRIC))
-			self.PlayActorSound(DukeSnd.SHORT_CIRCUIT);
+			self.PlayActorSound("SHORT_CIRCUIT");
 
 		if (self.spritesetindex & 1)
 		{
@@ -133,7 +133,7 @@ class DukeSideBolt1 : DukeBolt1
 		self.SetSpriteSetImage((self.spritesetindex + 1) % self.GetSpriteSetSize());
 
 		if (random(0, 1) && (dlevel.floorflags(sectp) & Duke.TFLAG_ELECTRIC))
-			self.PlayActorSound(DukeSnd.SHORT_CIRCUIT);
+			self.PlayActorSound("SHORT_CIRCUIT");
 	}
 	
 }
diff --git a/wadsrc/static/zscript/games/duke/actors/cactus.zs b/wadsrc/static/zscript/games/duke/actors/cactus.zs
index a06e971db..0981cc347 100644
--- a/wadsrc/static/zscript/games/duke/actors/cactus.zs
+++ b/wadsrc/static/zscript/games/duke/actors/cactus.zs
@@ -56,7 +56,7 @@ class DukeCactus : DukeCactusBroke
 			p.actor.extra -= 5;
 			p.hurt_delay = 16;
 			p.pals = Color(32, 32, 0, 0);
-			p.actor.PlayActorSound(DukeSnd.DUKE_LONGTERM_PAIN);
+			p.actor.PlayActorSound("PLAYER_LONGTERM_PAIN");
 		}
 	}
 }
diff --git a/wadsrc/static/zscript/games/duke/actors/canwithsomething.zs b/wadsrc/static/zscript/games/duke/actors/canwithsomething.zs
index 9742a09ba..172c94d38 100644
--- a/wadsrc/static/zscript/games/duke/actors/canwithsomething.zs
+++ b/wadsrc/static/zscript/games/duke/actors/canwithsomething.zs
@@ -24,7 +24,7 @@ class DukeCanWithSomething : DukeActor
 		int j = self.ifhitbyweapon();
 		if (j >= 0)
 		{
-			self.PlayActorSound(DukeSnd.VENT_BUST);
+			self.PlayActorSound("VENT_BUST");
 			for (j = 0; j < 10; j++)
 				self.RANDOMSCRAP();
 
diff --git a/wadsrc/static/zscript/games/duke/actors/chickenplant.zs b/wadsrc/static/zscript/games/duke/actors/chickenplant.zs
index 5e3c17472..e760efe23 100644
--- a/wadsrc/static/zscript/games/duke/actors/chickenplant.zs
+++ b/wadsrc/static/zscript/games/duke/actors/chickenplant.zs
@@ -79,7 +79,7 @@ class RedneckChickenHeadSpawner : RedneckChickenSpawner1
 		{
 			let spawned = self.spawn('RedneckChickenHead');
 			self.lotag = 96;
-			if (spawned && !Raze.isRRRA()) self.PlayActorSound(RRSnd.POOLBUD);
+			if (spawned && !Raze.isRRRA()) self.PlayActorSound("POOLBUD");
 		}
 	}
 }
diff --git a/wadsrc/static/zscript/games/duke/actors/crane.zs b/wadsrc/static/zscript/games/duke/actors/crane.zs
index 26236c0d7..ec64916a9 100644
--- a/wadsrc/static/zscript/games/duke/actors/crane.zs
+++ b/wadsrc/static/zscript/games/duke/actors/crane.zs
@@ -127,8 +127,7 @@ class DukeCrane : DukeActor
 						if (self.isactive)
 						{
 							let pp = findplayer();
-							// fixme: Sounds really need to be better abstracted...
-							pp.actor.PlayActorSound(Raze.isRR() ? RRSnd.YEHAA16 : DukeSnd.DUKE_GRUNT);
+							pp.actor.PlayActorSound("CRANEGRAB");
 							if (pp.on_crane == self)
 								pp.on_crane = null;
 						}
@@ -150,8 +149,7 @@ class DukeCrane : DukeActor
 					self.isactive = true;
 					self.ownerActor = null;
 					plr.on_crane = self;
-					// fixme: Sounds really need to be better abstracted...
-					plr.actor.PlayActorSound(Raze.isRR() ? RRSnd.YEHAA16 : DukeSnd.DUKE_GRUNT);
+					plr.actor.PlayActorSound("CRANEGRAB");
 					plr.settargetangle(self.angle + 180);
 				}
 				else
diff --git a/wadsrc/static/zscript/games/duke/actors/fireext.zs b/wadsrc/static/zscript/games/duke/actors/fireext.zs
index dc145a260..04ce4ecc0 100644
--- a/wadsrc/static/zscript/games/duke/actors/fireext.zs
+++ b/wadsrc/static/zscript/games/duke/actors/fireext.zs
@@ -44,8 +44,8 @@ class DukeFireext : DukeActor
 		}
 
 		self.spawn("DukeExplosion2");
-		self.PlayActorSound(DukeSnd.PIPEBOMB_EXPLODE);
-		self.PlayActorSound(DukeSnd.GLASS_HEAVYBREAK);
+		self.PlayActorSound("PIPEBOMB_EXPLODE");
+		self.PlayActorSound("GLASS_HEAVYBREAK");
 
 		if (self.hitag > 0)
 		{
@@ -60,7 +60,7 @@ class DukeFireext : DukeActor
 			int x = self.extra;
 			self.spawn("DukeExplosion2");
 			self.hitradius(gs.pipebombblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x);
-			self.PlayActorSound(DukeSnd.PIPEBOMB_EXPLODE);
+			self.PlayActorSound("PIPEBOMB_EXPLODE");
 			self.detonate("DukeExplosion2");
 		}
 		else
diff --git a/wadsrc/static/zscript/games/duke/actors/lumberblade.zs b/wadsrc/static/zscript/games/duke/actors/lumberblade.zs
index ebd05bc20..a265365e5 100644
--- a/wadsrc/static/zscript/games/duke/actors/lumberblade.zs
+++ b/wadsrc/static/zscript/games/duke/actors/lumberblade.zs
@@ -38,7 +38,7 @@ class RedneckLumberBlade : DukeActor
 			self.setSpritesetImage(1);
 			self.hitag = 100;
 			self.extra = 0;
-			self.PlayActorSound(RRSnd.BK_JIB2);
+			self.PlayActorSound("BK_JIB2");
 			return true;
 		}
 		return false;
@@ -49,7 +49,7 @@ class RedneckLumberBlade : DukeActor
 		if (self.spritesetindex == 0)
 		{
 			user.quickkill();
-			user.actor.PlayActorSound(RRSnd.JOE9000B);
+			user.actor.PlayActorSound("JOE9000B");
 		}
 	}
 }
diff --git a/wadsrc/static/zscript/games/duke/actors/rrcactus.zs b/wadsrc/static/zscript/games/duke/actors/rrcactus.zs
index ad4642db8..1482364a0 100644
--- a/wadsrc/static/zscript/games/duke/actors/rrcactus.zs
+++ b/wadsrc/static/zscript/games/duke/actors/rrcactus.zs
@@ -14,7 +14,7 @@ class RedneckCactusLargeYellow : DukeActor
 			p.actor.extra -= 2;
 			p.hurt_delay2 = 16;
 			p.pals = Color(32, 32, 0, 0);
-			p.actor.PlayActorSound(RRSnd.LN_PAIN8);
+			p.actor.PlayActorSound("PLAYER_LONGTERM_PAIN");
 		}
 	}
 
@@ -68,7 +68,7 @@ class RedneckCactusLargeGreen : RedneckCactusLargeYellow
 		{
 			if (self.pal != 4)
 			{
-				self.PlayActorSound(DukeSnd.SQUISHED);
+				self.PlayActorSound("SQUISHED");
 				if (self.lotag != 0)
 				{
 					DukeSpriteIterator it;
@@ -98,7 +98,7 @@ class RedneckCactusLargeGreen : RedneckCactusLargeYellow
 	
 	override void OnMotoSmash(DukePlayer hitter)
 	{
-		self.PlayActorSound(DukeSnd.SQUISHED);
+		self.PlayActorSound("SQUISHED");
 		if (self.lotag != 0)
 		{
 			DukeSpriteIterator it;
@@ -143,7 +143,7 @@ class RedneckCactusDrug : RedneckCactusLargeYellow
 		}
 		else if (self.spritesetIndex == 1)
 		{
-			self.PlayActorSound(DukeSnd.SQUISHED);
+			self.PlayActorSound("SQUISHED");
 			self.spawnguts('RedneckCactusDebris2', 3);
 			self.Destroy();
 		}
diff --git a/wadsrc/static/zscript/games/duke/actors/tripbomb.zs b/wadsrc/static/zscript/games/duke/actors/tripbomb.zs
index 0276f6d8d..e69e973e4 100644
--- a/wadsrc/static/zscript/games/duke/actors/tripbomb.zs
+++ b/wadsrc/static/zscript/games/duke/actors/tripbomb.zs
@@ -44,7 +44,7 @@ class DukeTripBomb : DukeActor
 				if (self.extra == 0)
 				{
 					self.temp_data[2] = 16;
-					self.PlayActorSound(DukeSnd.LASERTRIP_ARMING);
+					self.PlayActorSound("LASERTRIP_ARMING");
 				}
 			}
 		}
@@ -161,7 +161,7 @@ class DukeTripBomb : DukeActor
 			if (hit && lTripBombControl & TRIPBOMB_TRIPWIRE)
 			{
 				self.temp_data[2] = 13;
-				self.PlayActorSound(DukeSnd.LASERTRIP_ARMING);
+				self.PlayActorSound("LASERTRIP_ARMING");
 			}
 			else self.temp_data[2] = 0;
 		}
@@ -184,7 +184,7 @@ class DukeTripBomb : DukeActor
 			if (self.temp_pos2.X != x && lTripBombControl & TRIPBOMB_TRIPWIRE)
 			{
 				self.temp_data[2] = 13;
-				self.PlayActorSound(DukeSnd.LASERTRIP_ARMING);
+				self.PlayActorSound("LASERTRIP_ARMING");
 			}
 		}
 	}
diff --git a/wadsrc/static/zscript/games/duke/actors/viewscreen.zs b/wadsrc/static/zscript/games/duke/actors/viewscreen.zs
index 2809381b4..b33e3f7ae 100644
--- a/wadsrc/static/zscript/games/duke/actors/viewscreen.zs
+++ b/wadsrc/static/zscript/games/duke/actors/viewscreen.zs
@@ -40,7 +40,7 @@ class DukeViewscreen : DukeActor
 			if (acti.actorflag2(SFLAG2_CAMERA) && acti.yint == 0 && self.hitag == acti.lotag)
 			{
 				acti.yint = 1; //Using this camera
-				if (user == Duke.GetViewPlayer()) Duke.PlaySound(DukeSnd.MONITOR_ACTIVE);
+				if (user == Duke.GetViewPlayer()) Duke.PlaySound("MONITOR_ACTIVE");
 
 				self.ownerActor = acti;
 				self.yint = 1;
diff --git a/wadsrc/static/zscript/games/duke/actors/waterdrip.zs b/wadsrc/static/zscript/games/duke/actors/waterdrip.zs
index d374634f0..5bfa8f052 100644
--- a/wadsrc/static/zscript/games/duke/actors/waterdrip.zs
+++ b/wadsrc/static/zscript/games/duke/actors/waterdrip.zs
@@ -51,7 +51,7 @@ class DukeWaterDrip : DukeActor
 				self.cstat |= CSTAT_SPRITE_INVISIBLE;
 
 				if (self.pal != 2 && (self.hitag == 0 || Raze.isRR()))
-					self.PlayActorSound(DukeSnd.SOMETHING_DRIPPING);
+					self.PlayActorSound("SOMETHING_DRIPPING");
 
 				if (self.ownerActor != self)
 				{
diff --git a/wadsrc/static/zscript/games/duke/actors/waterfountain.zs b/wadsrc/static/zscript/games/duke/actors/waterfountain.zs
index 9c6820fe6..5c7462941 100644
--- a/wadsrc/static/zscript/games/duke/actors/waterfountain.zs
+++ b/wadsrc/static/zscript/games/duke/actors/waterfountain.zs
@@ -62,7 +62,7 @@ class DukeWaterFountain : DukeActor
 		}
 		else
 		{
-			self.PlayActorSound(DukeSnd.GLASS_BREAKING);
+			self.PlayActorSound("GLASS_BREAKING");
 			self.angle = FRandom(0., 360.);
 			self.lotsofglass(8);
 			self.Destroy();
@@ -80,7 +80,7 @@ class DukeWaterFountain : DukeActor
 			if (act.extra < gs.max_player_health)
 			{
 				act.extra++;
-				act.PlayActorSound(DukeSnd.DUKE_DRINKING);
+				act.PlayActorSound("PLAYER_DRINKING");
 			}
 		}
 		return true;
@@ -104,7 +104,7 @@ class DukeWaterFountainBroke : DukeActor
 
 	override void onHit(DukeActor hitter)
 	{
-		self.PlayActorSound(DukeSnd.GLASS_BREAKING);
+		self.PlayActorSound("GLASS_BREAKING");
 		self.angle = FRandom(0., 360.);
 		self.lotsofglass(8);
 		self.Destroy();
diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs
index d098f1406..c54857fa8 100644
--- a/wadsrc/static/zscript/games/duke/dukeactor.zs
+++ b/wadsrc/static/zscript/games/duke/dukeactor.zs
@@ -159,8 +159,8 @@ class DukeActor : CoreActor native
 	native DukePlayer, double findplayer();
 	native int ifhitbyweapon();
 	native int domove(int clipmask);
-	native int PlayActorSound(int snd, int chan = CHAN_AUTO, int flags = 0);
-	native void StopSound(int snd, int flags = 0);
+	native int PlayActorSound(Sound snd, int chan = CHAN_AUTO, int flags = 0);
+	native void StopSound(Sound snd, int flags = 0);
 	native DukeActor spawn(Name type);
 	native DukeActor spawnsprite(int type);	// for cases where the map has a picnum stored. Avoid when possible.
 	native DukeActor spawnweaponorammo(int type);
diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs
index 6c0bcfa8e..014dcc568 100644
--- a/wadsrc/static/zscript/games/duke/dukegame.zs
+++ b/wadsrc/static/zscript/games/duke/dukegame.zs
@@ -91,20 +91,20 @@ struct Duke native
 
 
 	native static void PlaySpecialMusic(int which);
-	native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f);
-	native static void StopSound(int num);
-	native static bool CheckSoundPlaying(int num);
+	native static int PlaySound(Sound num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f);
+	native static void StopSound(Sound num);
+	native static bool CheckSoundPlaying(Sound num);
 	native static DukePlayer GetViewPlayer();
 	native static int MaxAmmoAmount(int weap);
 	native static DukePlayer checkcursectnums(sectortype sect);
 	native static int global_random();
-	native static int GetSoundFlags(int sound);
+	native static int GetSoundFlags(Sound snd);
 	native static int badguyID(int id);
 
 	static void PlayBonusMusic()
 	{
 		if (System.MusicEnabled())
-			PlaySound(DukeSnd.BONUSMUSIC, CHAN_AUTO, CHANF_UI);
+			PlaySound("BONUSMUSIC", CHAN_AUTO, CHANF_UI);
 	}
 
 	//==========================================================================
@@ -348,926 +348,6 @@ struct RRWpn
 	}
 }
 
-struct DukeSnd native
-{
-	// This really needs to be done better...
-	enum EDukeSounds
-	{
-		KICK_HIT                   =  0,
-		PISTOL_RICOCHET            =  1,
-		PISTOL_BODYHIT             =  2,
-		PISTOL_FIRE                =  3,
-		EJECT_CLIP                 =  4,
-		INSERT_CLIP                =  5,
-		CHAINGUN_FIRE              =  6,
-		RPG_SHOOT                  =  7,
-		POOLBALLHIT                =  8,
-		RPG_EXPLODE                =  9,
-		CAT_FIRE                   = 10,
-		SHRINKER_FIRE              = 11,
-		ACTOR_SHRINKING            = 12,
-		PIPEBOMB_BOUNCE            = 13,
-		PIPEBOMB_EXPLODE           = 14,
-		LASERTRIP_ONWALL           = 15,
-		LASERTRIP_ARMING           = 16,
-		LASERTRIP_EXPLODE          = 17,
-		VENT_BUST                  = 18,
-		GLASS_BREAKING             = 19,
-		GLASS_HEAVYBREAK           = 20,
-		SHORT_CIRCUIT              = 21,
-		ITEM_SPLASH                = 22,
-		DUKE_BREATHING             = 23,
-		DUKE_EXHALING              = 24,
-		DUKE_GASP                  = 25,
-		SLIM_RECOG                 = 26,
-
-		DUKE_URINATE               = 28,
-		ENDSEQVOL3SND2             = 29,
-		ENDSEQVOL3SND3             = 30,
-		DUKE_PASSWIND              = 32,
-		DUKE_CRACK                 = 33,
-		SLIM_ATTACK                = 34,
-		SOMETHINGHITFORCE          = 35,
-		DUKE_DRINKING              = 36,
-		DUKE_KILLED1               = 37,
-		DUKE_GRUNT                 = 38,
-		DUKE_HARTBEAT              = 39,
-		DUKE_ONWATER               = 40,
-		DUKE_DEAD                  = 41,
-		DUKE_LAND                  = 42,
-		DUKE_WALKINDUCTS           = 43,
-		DUKE_GLAD                  = 44,
-		DUKE_YES                   = 45,
-		DUKE_HEHE                  = 46,
-		DUKE_SHUCKS                = 47,
-		DUKE_UNDERWATER            = 48,
-		DUKE_JETPACK_ON            = 49,
-		DUKE_JETPACK_IDLE          = 50,
-		DUKE_JETPACK_OFF           = 51,
-		LIZTROOP_GROWL             = 52,
-		LIZTROOP_TALK1             = 53,
-		LIZTROOP_TALK2             = 54,
-		LIZTROOP_TALK3             = 55,
-		DUKETALKTOBOSS             = 56,
-		LIZCAPT_GROWL              = 57,
-		LIZCAPT_TALK1              = 58,
-		LIZCAPT_TALK2              = 59,
-		LIZCAPT_TALK3              = 60,
-		LIZARD_BEG                 = 61,
-		LIZARD_PAIN                = 62,
-		LIZARD_DEATH               = 63,
-		LIZARD_SPIT                = 64,
-		DRONE1_HISSRATTLE          = 65,
-		DRONE1_HISSSCREECH         = 66,
-		DUKE_TIP2                  = 67,
-		FLESH_BURNING              = 68,
-		SQUISHED                   = 69,
-		TELEPORTER                 = 70,
-		ELEVATOR_ON                = 71,
-		DUKE_KILLED3               = 72,
-		ELEVATOR_OFF               = 73,
-		DOOR_OPERATE1              = 74,
-		SUBWAY                     = 75,
-		SWITCH_ON                  = 76,
-		FAN                        = 77,
-		DUKE_GETWEAPON3            = 78,
-		FLUSH_TOILET               = 79,
-		HOVER_CRAFT                = 80,
-		EARTHQUAKE                 = 81,
-		INTRUDER_ALERT             = 82,
-		END_OF_LEVEL_WARN          = 83,
-		ENGINE_OPERATING           = 84,
-		REACTOR_ON                 = 85,
-		COMPUTER_AMBIENCE          = 86,
-		GEARS_GRINDING             = 87,
-		BUBBLE_AMBIENCE            = 88,
-		MACHINE_AMBIENCE           = 89,
-		SEWER_AMBIENCE             = 90,
-		WIND_AMBIENCE              = 91,
-		SOMETHING_DRIPPING         = 92,
-		STEAM_HISSING              = 93,
-		THEATER_BREATH             = 94,
-		BAR_MUSIC                  = 95,
-		BOS1_ROAM                  = 96,
-		BOS1_RECOG                 = 97,
-		BOS1_ATTACK1               = 98,
-		BOS1_PAIN                  = 99,
-		BOS1_DYING                 =100,
-		BOS2_ROAM                  =101,
-		BOS2_RECOG                 =102,
-		BOS2_ATTACK                =103,
-		BOS2_PAIN                  =104,
-		BOS2_DYING                 =105,
-		GETATOMICHEALTH            =106,
-		DUKE_GETWEAPON2            =107,
-		BOS3_DYING                 =108,
-		SHOTGUN_FIRE               =109,
-		PRED_ROAM                  =110,
-		PRED_RECOG                 =111,
-		PRED_ATTACK                =112,
-		PRED_PAIN                  =113,
-		PRED_DYING                 =114,
-		CAPT_ROAM                  =115,
-		CAPT_ATTACK                =116,
-		CAPT_RECOG                 =117,
-		CAPT_PAIN                  =118,
-		CAPT_DYING                 =119,
-		PIG_ROAM                   =120,
-		PIG_RECOG                  =121,
-		PIG_ATTACK                 =122,
-		PIG_PAIN                   =123,
-		PIG_DYING                  =124,
-		RECO_ROAM                  =125,
-		RECO_RECOG                 =126,
-		RECO_ATTACK                =127,
-		RECO_PAIN                  =128,
-		RECO_DYING                 =129,
-		DRON_ROAM                  =130,
-		DRON_RECOG                 =131,
-		DRON_ATTACK1               =132,
-		DRON_PAIN                  =133,
-		DRON_DYING                 =134,
-		COMM_ROAM                  =135,
-		COMM_RECOG                 =136,
-		COMM_ATTACK                =137,
-		COMM_PAIN                  =138,
-		COMM_DYING                 =139,
-		OCTA_ROAM                  =140,
-		OCTA_RECOG                 =141,
-		OCTA_ATTACK1               =142,
-		OCTA_PAIN                  =143,
-		OCTA_DYING                 =144,
-		TURR_ROAM                  =145,
-		TURR_RECOG                 =146,
-		TURR_ATTACK                =147,
-		DUMPSTER_MOVE              =148,
-		SLIM_DYING                 =149,
-		BOS3_ROAM                  =150,
-		BOS3_RECOG                 =151,
-		BOS3_ATTACK1               =152,
-		BOS3_PAIN                  =153,
-		BOS1_ATTACK2               =154,
-		COMM_SPIN                  =155,
-		BOS1_WALK                  =156,
-		DRON_ATTACK2               =157,
-		THUD                       =158,
-		OCTA_ATTACK2               =159,
-		WIERDSHOT_FLY              =160,
-		TURR_PAIN                  =161,
-		TURR_DYING                 =162,
-		SLIM_ROAM                  =163,
-		LADY_SCREAM                =164,
-		DOOR_OPERATE2              =165,
-		DOOR_OPERATE3              =166,
-		DOOR_OPERATE4              =167,
-		BORNTOBEWILDSND            =168,
-		SHOTGUN_COCK               =169,
-		GENERIC_AMBIENCE1          =170,
-		GENERIC_AMBIENCE2          =171,
-		GENERIC_AMBIENCE3          =172,
-		GENERIC_AMBIENCE4          =173,
-		GENERIC_AMBIENCE5          =174,
-		GENERIC_AMBIENCE6          =175,
-		BOS3_ATTACK2               =176,
-		GENERIC_AMBIENCE17         =177,
-		GENERIC_AMBIENCE18         =178,
-		GENERIC_AMBIENCE19         =179,
-		GENERIC_AMBIENCE20         =180,
-		GENERIC_AMBIENCE21         =181,
-		GENERIC_AMBIENCE22         =182,
-		SECRETLEVELSND             =183,
-		GENERIC_AMBIENCE8          =184,
-		GENERIC_AMBIENCE9          =185,
-		GENERIC_AMBIENCE10         =186,
-		GENERIC_AMBIENCE11         =187,
-		GENERIC_AMBIENCE12         =188,
-		GENERIC_AMBIENCE13         =189,
-		GENERIC_AMBIENCE14         =190,
-		GENERIC_AMBIENCE15         =192,
-		GENERIC_AMBIENCE16         =193,
-		FIRE_CRACKLE               =194,
-		BONUS_SPEECH1              =195,
-		BONUS_SPEECH2              =196,
-		BONUS_SPEECH3              =197,
-		PIG_CAPTURE_DUKE           =198,
-		BONUS_SPEECH4              =199,
-		DUKE_LAND_HURT             =200,
-		DUKE_HIT_STRIPPER1         =201,
-		DUKE_TIP1                  =202,
-		DUKE_KILLED2               =203,
-		PRED_ROAM2                 =204,
-		PIG_ROAM2                  =205,
-		DUKE_GETWEAPON1            =206,
-		DUKE_SEARCH2               =207,
-		DUKE_CRACK2                =208,
-		DUKE_SEARCH                =209,
-		DUKE_GET                   =210,
-		DUKE_LONGTERM_PAIN         =211,
-		MONITOR_ACTIVE             =212,
-		NITEVISION_ONOFF           =213,
-		DUKE_HIT_STRIPPER2         =214,
-		DUKE_CRACK_FIRST           =215,
-		DUKE_USEMEDKIT             =216,
-		DUKE_TAKEPILLS             =217,
-		DUKE_PISSRELIEF            =218,
-		SELECT_WEAPON              =219,
-		WATER_GURGLE               =220,
-		DUKE_GETWEAPON4            =221,
-		JIBBED_ACTOR1              =222,
-		JIBBED_ACTOR2              =223,
-		JIBBED_ACTOR3              =224,
-		JIBBED_ACTOR4              =225,
-		JIBBED_ACTOR5              =226,
-		JIBBED_ACTOR6              =227,
-		JIBBED_ACTOR7              =228,
-		DUKE_GOTHEALTHATLOW        =229,
-		BOSSTALKTODUKE             =230,
-		WAR_AMBIENCE1              =231,
-		WAR_AMBIENCE2              =232,
-		WAR_AMBIENCE3              =233,
-		WAR_AMBIENCE4              =234,
-		WAR_AMBIENCE5              =235,
-		WAR_AMBIENCE6              =236,
-		WAR_AMBIENCE7              =237,
-		WAR_AMBIENCE8              =238,
-		WAR_AMBIENCE9              =239,
-		WAR_AMBIENCE10             =240,
-		ALIEN_TALK1                =241,
-		ALIEN_TALK2                =242,
-		EXITMENUSOUND              =243,
-		FLY_BY                     =244,
-		DUKE_SCREAM                =245,
-		SHRINKER_HIT               =246,
-		RATTY                      =247,
-		INTO_MENU                  =248,
-		BONUSMUSIC                 =249,
-		DUKE_BOOBY                 =250,
-		DUKE_TALKTOBOSSFALL        =251,
-		DUKE_LOOKINTOMIRROR        =252,
-		PIG_ROAM3                  =253,
-		KILLME                     =254,
-		DRON_JETSND                =255,
-		SPACE_DOOR1                =256,
-		SPACE_DOOR2                =257,
-		SPACE_DOOR3                =258,
-		SPACE_DOOR4                =259,
-		SPACE_DOOR5                =260,
-		ALIEN_ELEVATOR1            =261,
-		VAULT_DOOR                 =262,
-		JIBBED_ACTOR13             =263,
-		DUKE_GETWEAPON6            =264,
-		JIBBED_ACTOR8              =265,
-		JIBBED_ACTOR9              =266,
-		JIBBED_ACTOR10             =267,
-		JIBBED_ACTOR11             =268,
-		JIBBED_ACTOR12             =269,
-		DUKE_KILLED4               =270,
-		DUKE_KILLED5               =271,
-		ALIEN_SWITCH1              =272,
-		DUKE_STEPONFECES           =273,
-		DUKE_LONGTERM_PAIN2        =274,
-		DUKE_LONGTERM_PAIN3        =275,
-		DUKE_LONGTERM_PAIN4        =276,
-		COMPANB2                   =277,
-		KTIT                       =278,
-		HELICOP_IDLE               =279,
-		STEPNIT                    =280,
-		SPACE_AMBIENCE1            =281,
-		SPACE_AMBIENCE2            =282,
-		SLIM_HATCH                 =283,
-		RIPHEADNECK                =284,
-		FOUNDJONES                 =285,
-		ALIEN_DOOR1                =286,
-		ALIEN_DOOR2                =287,
-		ENDSEQVOL3SND4             =288,
-		ENDSEQVOL3SND5             =289,
-		ENDSEQVOL3SND6             =290,
-		ENDSEQVOL3SND7             =291,
-		ENDSEQVOL3SND8             =292,
-		ENDSEQVOL3SND9             =293,
-		WHIPYOURASS                =294,
-		ENDSEQVOL2SND1             =295,
-		ENDSEQVOL2SND2             =296,
-		ENDSEQVOL2SND3             =297,
-		ENDSEQVOL2SND4             =298,
-		ENDSEQVOL2SND5             =299,
-		ENDSEQVOL2SND6             =300,
-		ENDSEQVOL2SND7             =301,
-		GENERIC_AMBIENCE23         =302,
-		SOMETHINGFROZE             =303,
-		DUKE_LONGTERM_PAIN5        =304,
-		DUKE_LONGTERM_PAIN6        =305,
-		DUKE_LONGTERM_PAIN7        =306,
-		DUKE_LONGTERM_PAIN8        =307,
-		WIND_REPEAT                =308,
-		MYENEMY_ROAM               =309,
-		MYENEMY_HURT               =310,
-		MYENEMY_DEAD               =311,
-		MYENEMY_SHOOT              =312,
-		STORE_MUSIC                =313,
-		STORE_MUSIC_BROKE          =314,
-		ACTOR_GROWING              =315,
-		NEWBEAST_ROAM              =316,
-		NEWBEAST_RECOG             =317,
-		NEWBEAST_ATTACK            =318,
-		NEWBEAST_PAIN              =319,
-		NEWBEAST_DYING             =320,
-		NEWBEAST_SPIT              =321,
-		VOL4_1                     =322,
-		SUPERMARKET                =323,
-		MOUSEANNOY                 =324,
-		BOOKEM                     =325,
-		SUPERMARKETCRY             =326,
-		DESTRUCT                   =327,
-		EATFOOD                    =328,
-		MAKEMYDAY                  =329,
-		WITNESSSTAND               =330,
-		VACATIONSPEECH             =331,
-		YIPPEE1                    =332,
-		YOHOO1                     =333,
-		YOHOO2                     =334,
-		DOLPHINSND                 =335,
-		TOUGHGALSND1               =336,
-		TOUGHGALSND2               =337,
-		TOUGHGALSND3               =338,
-		TOUGHGALSND4               =339,
-		TANK_ROAM                  =340,
-		BOS4_ROAM                  =341,
-		BOS4_RECOG                 =342,
-		BOS4_ATTACK                =343,
-		BOS4_PAIN                  =344,
-		BOS4_DYING                 =345,
-		NEWBEAST_ATTACKMISS        =346,
-		VOL4_2                     =347,
-		COOKINGDEEPFRIER           =348,
-		WHINING_DOG                =349,
-		DEAD_DOG                   =350,
-		LIGHTNING_SLAP             =351,
-		THUNDER                    =352,
-		HAPPYMOUSESND1             =353,
-		HAPPYMOUSESND2             =354,
-		HAPPYMOUSESND3             =355,
-		HAPPYMOUSESND4             =356,
-		ALARM                      =357,
-		RAIN                       =358,
-		DTAG_GREENRUN              =359,
-		DTAG_BROWNRUN              =360,
-		DTAG_GREENSCORE            =361,
-		DTAG_BROWNSCORE            =362,
-		INTRO4_1                   =363,
-		INTRO4_2                   =364,
-		INTRO4_3                   =365,
-		INTRO4_4                   =366,
-		INTRO4_5                   =367,
-		INTRO4_6                   =368,
-		SCREECH                    =369,
-		BOSS4_DEADSPEECH           =370,
-		BOSS4_FIRSTSEE             =371,
-		PARTY_SPEECH               =372,
-		POSTAL_SPEECH              =373,
-		TGSPEECH                   =374,
-		DOGROOMSPEECH              =375,
-		SMACKED                    =376,
-		MDEVSPEECH                 =377,
-		AREA51SPEECH               =378,
-		JEEPSOUND                  =379,
-		BIGDOORSLAM                =380,
-		BOS4_LAY                   =381,
-		WAVESOUND                  =382,
-		ILLBEBACK                  =383,
-		VOL4ENDSND1                =384,
-		VOL4ENDSND2                =385,
-		EXPANDERHIT                =386,
-		SNAKESPEECH                =387,
-		EXPANDERSHOOT              =388,
-		GETBACKTOWORK              =389,
-		JIBBED_ACTOR14             =390,
-		JIBBED_ACTOR15             =391,
-		INTRO4_B                   =392,
-		BIGBANG                    =393,
-		SMACKIT                    =394,
-		BELLSND                    =395,
-		GOAWAY                     =396,
-		JOKE                       =397,
-		FLAMETHROWER_INTRO         =398,
-		FLAMETHROWER_LOOP          =399,
-		FLAMETHROWER_END           =400,
-		E5L7_DUKE_QUIT_YOU         =401,
-	}
-}
-
-struct RRSnd native
-{
-	enum ESnd
-	{
-		KICK_HIT     = 0  ,
-		RICOCHET     = 1  ,
-		BULITHIT     = 2  ,
-		CASUL_FIRE   = 3  ,
-		PISCOCK      = 4  ,
-		PISLOAD      = 5  ,
-		AK3          = 6  ,
-		XBOWFIRE     = 7  ,
-		BUB_HRT1     = 8  ,
-		XBOWEXPL     = 9  ,
-		LASERA       = 10 ,
-		SHRINKER     = 11 ,
-		CRAPFLOW     = 12 ,
-		DYNOCLMP     = 13 ,
-		DYNEW        = 14 ,
-		CRAPSTIR     = 15 ,
-		BRICDOOR     = 16 ,
-		BOMBEXPL     = 17 ,
-		VENTBUST     = 18 ,
-		GLASSSND     = 19 ,
-		GLASSHVY     = 20 ,
-		BUBBLES      = 21 ,
-		SPLASH       = 22 ,
-		BUB_HRT2     = 23 ,
-		BUB_HRT3     = 24 ,
-		GASP         = 25 ,
-		BUB_HRT4     = 26 ,
-
-		ONECART      = 27 , // RR
-		MINEWIND     = 28 ,
-		URANUS       = 29 ,
-
-		MIRROR1      = 27 , // RRRA
-		MIRROR2      = 28 ,
-		MIRROR3      = 29 ,
-
-		COMPUTER     = 30 ,
-		NEON         = 31 ,
-		VX_FINAL     = 32 ,
-		LN_WAIT      = 33 ,
-		BUB_LN1      = 34 ,
-		LN_FINAL     = 35 ,
-		CLOCKTK      = 36 ,
-		LN_STANK     = 37 ,
-		LNRD_GRUNT   = 38 ,
-		CLOCKCHM     = 39 ,
-		WETFEET      = 40 ,
-		LNRD_DEAD    = 41 ,
-		LAND         = 42 ,
-		END_PIPE     = 43 ,
-		ICARUMBA     = 44 ,
-		BUB_LN2      = 45 ,
-		LN_CRAP      = 46 ,
-		WOODBREK     = 47 ,
-		SCUBA        = 48 ,
-		TRUCK_LP2    = 49 ,
-		COW1         = 50 ,
-		COW2         = 51 ,
-		COW3         = 52 ,
-		COW4         = 53 ,
-		COW5         = 54 ,
-		BUB_LN3      = 55 ,
-		LATCH        = 56 ,
-		BUB_LN5      = 57 ,
-		BUB_LN6      = 58 ,
-		BUB_LN7      = 59 ,
-		BUB_PIK1     = 60 ,
-		BUB_PIK2     = 61 ,
-		BUB_PISS     = 62 ,
-		E1L1         = 63 ,
-		E1L2         = 64 ,
-		UFOINSID     = 65 ,
-		LN_RODE      = 66 ,
-		CURTAIN      = 67 ,
-		FIRE09       = 68 ,
-		SQUISHED     = 69 ,
-		TELEPORT     = 70 ,
-		GBELEV01     = 71 ,
-		LN_BNCH      = 72 ,
-		GBELEV02     = 73 ,
-		FROG1        = 74 ,
-		TRUCK_LP     = 75 ,
-		SWITCH1      = 76 ,
-		E1L3         = 77 ,
-		LN_HOTDM     = 78 ,
-		FLUSH        = 79 ,
-		E1L4         = 80 ,
-		QUAKE        = 81 ,
-		CHKAMMO      = 82 ,
-		MONITORA     = 83 ,
-		FROG2        = 84 ,
-		AS_AMB2      = 85 ,
-		AS_AMB1      = 86 ,
-		FBOATIDL     = 87 ,
-		FBOATRUN     = 88 ,
-		FBOATUP      = 89 ,
-		FBOATDN      = 90 ,
-		FBOATTRN     = 91 ,
-		DRIP3        = 92 ,
-		SWAMPAMB     = 93 ,
-		MORTAR       = 94 ,
-		JUKEBOX      = 95 ,
-		AS_DROPN     = 96 ,
-		AS_CRYPT     = 97 ,
-		AS_DRCLS     = 98 ,
-		LOKGATE      = 99 ,
-		METLGAT2     = 100,
-		METLGAT1     = 101,
-		E1L5         = 102,
-		E1L6         = 103,
-		E1L7         = 104,
-		E2L1         = 105,
-		PADDLE       = 106,
-		LN_HOLD      = 107,
-		VX_TAKIT     = 108,
-		SHOT6        = 109,
-		CT_LAF2      = 110,
-		CT_GET       = 111,
-		CT_LAF       = 112,
-		CT_PAIN      = 113,
-		CT_DIE       = 114,
-		PIGSOUND1    = 115,
-		PIGSOUND2    = 116,
-		PIGSOUND3    = 117,
-		PIGSOUND4    = 118,
-		PIGSOUND5    = 119,
-		BR_ROAM1     = 120,
-		BR_RECOG     = 121,
-		WHISTLE      = 122,
-		BR_PAIN      = 123,
-		BR_DTH       = 124,
-		VX_ISTHT     = 125,
-		LASERH       = 126,
-		PIGSOUND6    = 127,
-		PIGSOUND7    = 128,
-		VX_DIE1      = 129,
-		MJ_JIB1      = 130,
-		VX_DIE4      = 131,
-		VX_DIE5      = 132,
-		VX_DIE6      = 133,
-		VX_DIE7      = 134,
-		VX_OOH       = 135,
-		VX_PAIN1     = 136,
-		VX_SEX1      = 137,
-		VX_SEX2      = 138,
-		VX_SEX3      = 139,
-		VX_GRNT      = 140,
-		RENO         = 141,
-		BK_MAKE1     = 142,
-		BK_MAKE2     = 143,
-		VX_BRNG3     = 144,
-		VX_CLSR1     = 145,
-		VX_CLSR2     = 146,
-		VX_2FAR      = 147,
-		KINGHUH      = 148,
-		VX_BRING     = 149,
-		VX_BITE      = 150,
-		MJ_FART      = 151,
-		VX_LAFF2     = 152,
-		VX_LAFF3     = 153,
-		VX_HMMM2     = 154,
-		VX_HURT2     = 155,
-		VX_BABY2     = 156,
-		VX_MHMM      = 157,
-		THUD         = 158,
-		VX_ITSOK     = 159,
-		MJ_RECO2     = 160,
-		// VX_TPOT1  = 161,
-		VX_TPOT4     = 162,
-		// VX_TPIN1  = 163,
-		ROPECRK      = 164,
-		DR_CRK8      = 165,
-		DR_ROLL      = 166,
-		STEELAMB     = 167,
-		ROULETTE     = 168,
-		GUNCHANG     = 169,
-		FLIES        = 170,
-		AMB_1        = 171,
-		GRAVAMB      = 172,
-		HOOTOWL      = 173,
-		WOODS2       = 174,
-		CATAMB       = 175,
-		E2L2         = 176,
-		E2L3         = 177,
-		FBOATX_1     = 178,
-		FBOATX_2     = 179,
-		FBOATX_3     = 180,
-		FBOATX_4     = 181,
-		FBOATSLW     = 182,
-		PLANE        = 183,
-		CNTAMB       = 184,
-		JUNKAMB2     = 185,
-		BIKESTRT     = 186,
-		BIKEIDLE     = 187,
-		BIKELOOP     = 188,
-		BIKEJMPS     = 189,
-		BIKEJMPL     = 190,
-		BIKELAND     = 191,
-		JACKJMP1     = 192,
-		JACKJMP2     = 193,
-		FIRE_CRACKLE = 194,
-		BNS_SPCH1    = 195,
-		BNS_SPCH2    = 196,
-		BNS_SPCH3    = 197,
-		E2L4         = 198,
-		BNS_SPCH4    = 199,
-		LN_LNDHT     = 200,
-		JACKATK2     = 201,
-		JACKPAIN     = 202,
-		LN_BITCH     = 203,
-		CT_LAND      = 204,
-		BR_ROAM2     = 205,
-		LN_HUSH      = 206,
-		LN_PAIN4     = 207,
-		LN_SLOW      = 208,
-		LN_PAIN4A    = 209,
-		JUG          = 210,
-		LN_PAIN8     = 211,
-		MONITOR      = 212,
-		JACKATK1     = 213,
-		BIKEUP       = 214,
-		PLANEXP      = 215,
-		JUGALUG7     = 216,
-		DIDDLP       = 217,
-		ELVISMOD     = 218,
-		// PISCOCK  =  219,
-		BIKESKID     = 220,
-		LN_STINK     = 221,
-		JIBBED1      = 222,
-		JIBBED2      = 223,
-		JIBBED3      = 224,
-		JIBBED4      = 225,
-		JIBBED5      = 226,
-		JIBBED6      = 227,
-		JIBBED7      = 228,
-		LN_BACON     = 229,
-		E2L5         = 230,
-		REGISTER     = 231,
-		BBQGRILL     = 232,
-		CRSSBELL     = 233,
-		TRAIN        = 234,
-		SLOTS        = 235,
-		INDIANS      = 236,
-		RADIO        = 237,
-		BIKEX_1      = 238,
-		BIKEX_2      = 239,
-		BIKEX_3      = 240,
-		TVSNOW       = 241,
-		WINDLITE     = 242,
-		EXITMENU     = 243,
-		CHKBOWFR     = 244,
-		DSCREM04     = 245,
-		SHRNK_HIT    = 246,
-		CHKBOWEX     = 247,
-		INTOMENU     = 248,
-		LAVAFLOW     = 249,
-		LAVA_RK      = 250,
-		BIKELOO2     = 251,
-		SLINGBL      = 252,
-		BR_ROAM3     = 253,
-		KILLME       = 254,
-		E2L6         = 255,
-		RINTRO       = 256,
-		MIRROR4      = 257,
-		MIRROR5      = 258,
-		GAMBELEV     = 259,
-		SLINGHIT     = 260,
-		PIANO_P1     = 261,
-		BANJO1       = 262,
-		JIBBED13     = 263,
-		LN_BBQ       = 264,
-		JIBBED8      = 265,
-		JIBBED9      = 266,
-		JIBBED10     = 267,
-		JIBBED11     = 268,
-		JIBBED12     = 269,
-		LNRD_KILLED4 = 270,
-		LNRD_KILLED5 = 271,
-		BANJO2       = 272,
-		BANJO3       = 273,
-		LN_PAIN2     = 274,
-		LN_PAIN3     = 275,
-		BK_ALIVE     = 276,
-		BK_BOURB     = 277,
-		BK_CHEER     = 278,
-		BK_DIENB     = 279,
-		BK_DNTLK     = 280,
-		BK_FUN       = 281,
-		BK_HEY       = 282,
-		E2L7         = 283,
-		BK_HEYNB     = 284,
-		BK_JOYRD     = 285,
-		BK_KEEPA     = 286,
-		BK_PLEAS     = 287,
-		BK_RIDE      = 288,
-		BK_ROAD      = 289,
-		BK_SCRAT     = 290,
-		BK_SHTUP     = 291,
-		BK_SNORT     = 292,
-		BK_TOHEL     = 293,
-		WHIPYOU      = 294,
-		BK_TRYIN     = 295,
-		BK_PAIN1     = 296,
-		BK_PAIN2     = 297,
-		BK_PAIN3     = 298,
-		CH_BALD      = 299,
-		CH_TEAS1     = 300,
-		CH_TEAS2     = 301,
-		CH_TEAS3     = 302,
-		CH_SANDP     = 303,
-		LN_PAIN5     = 304,
-		LN_PAIN6     = 305,
-		LN_PAIN7     = 306,
-		CH_DONIT     = 307,
-		CH_WHOOP     = 308,
-		CH_NIPPL     = 309,
-		CH_BARN      = 310,
-		CH_GTEAM     = 311,
-		CH_GOGOG     = 312,
-		CH_REDOK     = 313,
-		CH_2468      = 314,
-		CH_BIGON     = 315,
-		HULK_ROAM    = 316,
-		HULK_RECOG   = 317,
-		HULK_ATTACK  = 318,
-		HULK_PAIN    = 319,
-		HULK_DYING   = 320,
-		HULK_SPIT    = 321,
-		CH_PAIN1     = 322,
-		CH_PAIN2     = 323,
-		CH_PAIN3     = 324,
-		CH_HURT      = 325,
-		AK4          = 326,
-		CHKSCR1      = 327,
-		SHIPWREK     = 328,
-		HYDROGLY     = 329,
-		PIANO_P2     = 330,
-		FROGTOSS     = 331,
-		TRAIN2       = 332,
-		CRICKET1     = 333,
-		CRICKET2     = 334,
-		PIGRUNT      = 335,
-		GOCATGO      = 336,
-		ANNOUNC1     = 337,
-		ANNOUNC2     = 338,
-		TRACTOR      = 339,
-		PIANO_P3     = 340,
-		RESIZE       = 341,
-		VX_TPIN2     = 342,
-		VX_TPIN4     = 343,
-		VX_HLPME     = 344,
-		ATFSPEAK     = 345,
-		WINDCAVE     = 346,
-		ALARM        = 347,
-		SF_THLAW     = 348,
-		SF_TLAW2     = 349,
-		LN_SCREW     = 350,
-		THUNDER1     = 351,
-		THUNDER2     = 352,
-		THUNDER3     = 353,
-		BOWLSTRT     = 354,
-		BOWLPIN      = 355,
-		BOWLLOOP     = 356,
-		MJ_JIB2      = 357,
-		VX_KICK2     = 358,
-		VX_KICK3     = 359,
-		MJ_RECO1     = 360,
-		VX_HIYA      = 361,
-		VX_HIYA2     = 362,
-		SF_ATTN      = 363,
-		SF_DETH1     = 364,
-		SF_DETH2     = 365,
-		SF_DETH3     = 366,
-		TEDOUT       = 367,
-		SF_FREZ2     = 368,
-		SF_GETYA     = 369,
-		SF_HANDS     = 370,
-		STEELAM2     = 371,
-		STEELAM3     = 372,
-		SF_HEY       = 373,
-		SF_HOLD      = 374,
-		SF_LAFF1     = 375,
-		LN_FLYOP     = 376,
-		LN_SHTHD     = 377,
-		SF_NAME      = 378,
-		SF_OVER      = 379,
-		SF_PAIN1     = 380,
-		SF_PAIN2     = 381,
-		SF_PAIN3     = 382,
-		SF_RLOAD     = 383,
-		SF_RLOD2     = 384,
-		SF_SHOOT     = 385,
-		JAWHARP      = 386,
-		LN_TIGHT     = 387,
-		DR_CLS       = 388,
-		SCRAPE_1     = 389,
-		YEHAA16      = 390,
-		LN_WHUP      = 391,
-		CHKNFLAP     = 392,
-		CHKN_1       = 393,
-		CHKN_2       = 394,
-		CHIKDETH     = 395,
-		AMB_ROOM     = 396,
-		BR_ITCH      = 397,
-		BR_SCRTH     = 398,
-		BR_SNIFF     = 399,
-		TRUKDIE      = 400,
-		ZIPOPEN      = 401,
-		ZIPPSTRK     = 402,
-		MOSQUI4      = 403,
-		FART1        = 404,
-		SWITCH2      = 405,
-		SQUEAKY      = 406,
-		CATDOOR      = 407,
-		JUNKSWCH     = 408,
-		CONVEYR      = 409,
-		SWITCH3      = 410,
-		BIKEENEM     = 411,
-		BIGDOOR      = 412,
-		FLOODGAT     = 413,
-		JACK_RM1     = 414,
-		MN_FREAK     = 415,
-		MN_PN        = 416,
-		MN_REC       = 417,
-		MN_AMB       = 418,
-		LOKDOOR      = 419,
-		VOMIT        = 420,
-		TOSS         = 421,
-		FART2        = 422,
-		FART3        = 423,
-		FART4        = 424,
-		CHUG         = 425,
-		CROWUSH      = 426,
-		WUSSLAF      = 427,
-		LN_CITY      = 428,
-		MUNCH2       = 429,
-		TESLARC      = 430,
-		BUZSAWSND    = 431,
-		ELEVLOOP     = 432,
-		PISSEND      = 433,
-		PISSLOOP     = 434,
-		PISSSTRT     = 435,
-		CRAP         = 436,
-		PEE          = 437,
-		JACK_RM2     = 438,
-		BELL         = 439,
-		TRAINWRK     = 440,
-		DOOR_PKT     = 441,
-		GAMBDOOR     = 442,
-		OVEN         = 443,
-		CREMATOR     = 444,
-		JOE9000A     = 445,
-		JOE9000B     = 446,
-		JOE9000C     = 447,
-		CHINESE      = 448,
-		SIGNROT      = 449,
-		XBOWCOCK     = 450,
-		PWDERKEG     = 451,
-		DG_BARK1     = 452,
-		DG_GRWL1     = 453,
-		DG_YELP      = 454,
-		DG_DIE       = 455,
-		UFO          = 456,
-		UFOLET       = 457,
-		JACKJIB1     = 458,
-		JACKJIB2     = 459,
-		JACKJIB3     = 460,
-		JACKJIB4     = 461,
-		JACKJIB5     = 462,
-		WTRFALL      = 463,
-		BK_JIB1      = 464,
-		FRIDGEOP     = 465,
-		FRIDGECL     = 466,
-		DG_LUNGE     = 467,
-		DRIVTHRU     = 468,
-		FAN          = 469,
-		CRUSHER      = 470,
-		BALLOON      = 471,
-		POOLBUD      = 472,
-		STAMPER      = 473,
-		BK_JIB2      = 474,
-		MORNING      = 475,
-		DG_BARK2     = 476,
-		DG_GRWL2     = 477,
-		REDNECK2     = 478,
-		XATRIX       = 479,
-		MJ_ATTK1     = 480,
-		MJ_JUMP      = 485,
-		MJ_PAIN1     = 481,
-		MJ_PAIN2     = 482,
-		MJ_ROAM1     = 483,
-		MJ_ROAM2     = 484,
-		MJ_ROLL      = 486,
-		DISHES       = 487,
-		BUB_ELV1     = 488,
-		BUB_ELV2     = 489,
-		BUB_ELV3     = 490,
-		BK_JIB3      = 491,
-		CH_JIB1      = 492,
-		CH_JIB2      = 493,
-		CH_JIB3      = 494,
-		SIGNHIT      = 495,
-		UMHUM        = 496,
-		COYOTE       = 497,
-		BUB_HEY1     = 498,
-		BUB_HEY2     = 499,
-	}
-}
 
 
 struct DukeGameInfo native
diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs
index 3fbeb90bf..6b4cb6653 100644
--- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs
+++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs
@@ -42,8 +42,8 @@ class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot e
 			{
 				Array<int> soundinfo;
 				soundinfo.Pushv(
-					1, DukeSnd.FLY_BY+1,
-					19, DukeSnd.PIPEBOMB_EXPLODE+1);
+					1, int(Sound("FLY_BY")),
+					19, int(Sound("PIPEBOMB_EXPLODE")));
 				runner.Append(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 0, 9, 9, 9));
 			}
 			if (!Raze.isNam()) runner.Append(new("DRealmsScreen").Init());
@@ -73,15 +73,15 @@ class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot e
 	{
 		Array<int> soundinfo;
 		soundinfo.Pushv(
-			1, DukeSnd.WIND_AMBIENCE+1,
-			26, DukeSnd.ENDSEQVOL2SND1+1,
-			36, DukeSnd.ENDSEQVOL2SND2+1,
-			54, DukeSnd.THUD+1,
-			62, DukeSnd.ENDSEQVOL2SND3+1,
-			75, DukeSnd.ENDSEQVOL2SND4 + 1,
-			81, DukeSnd.ENDSEQVOL2SND5 + 1,
-			115, DukeSnd.ENDSEQVOL2SND6 + 1,
-			124, DukeSnd.ENDSEQVOL2SND7 + 1);
+			1, int(Sound("WIND_AMBIENCE")),
+			26, int(Sound("ENDSEQVOL2SND1")),
+			36, int(Sound("ENDSEQVOL2SND2")),
+			54, int(Sound("THUD")),
+			62, int(Sound("ENDSEQVOL2SND3")),
+			75, int(Sound("ENDSEQVOL2SND4")),
+			81, int(Sound("ENDSEQVOL2SND5")),
+			115, int(Sound("ENDSEQVOL2SND6")),
+			124, int(Sound("ENDSEQVOL2SND7")));
 
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov2.anm", soundinfo, 0, 18, 18, 18));
 		runner.Append(new("E2EndScreen").Init());
@@ -98,20 +98,20 @@ class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot e
 		if (gameinfo.gameType & GAMEFLAG_DUKEDC)
 		{
 			Array<int> soundinfo;
-			soundinfo.Pushv(144, DukeSnd.ENDSEQVOL3SND3 + 1);
+			soundinfo.Pushv(144, int(Sound("ENDSEQVOL3SND3")));
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10));
 		}
 		else
 		{
 			Array<int> soundinfo;
 			soundinfo.Pushv(
-				1, DukeSnd.WIND_REPEAT + 1,
-				98, DukeSnd.DUKE_GRUNT + 1,
-				102, DukeSnd.THUD + 1,
-				102, DukeSnd.SQUISHED + 1,
-				124, DukeSnd.ENDSEQVOL3SND3 + 1,
-				134, DukeSnd.ENDSEQVOL3SND2 + 1,
-				158, DukeSnd.PIPEBOMB_EXPLODE + 1);
+				1, int(Sound("WIND_REPEAT")),
+				98, int(Sound("PLAYER_GRUNT")),
+				102, int(Sound("THUD")),
+				102, int(Sound("SQUISHED")),
+				124, int(Sound("ENDSEQVOL3SND3")),
+				134, int(Sound("ENDSEQVOL3SND2")),
+				158, int(Sound("PIPEBOMB_EXPLODE")));
 
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10));
 			runner.Append(BlackScreen.Create(200, ScreenJob.stopsound));
@@ -131,22 +131,22 @@ class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot e
 		Array<int> soundinfo;
 
 		soundinfo.Pushv(
-			3, DukeSnd.DUKE_UNDERWATER+1,
-			35, DukeSnd.VOL4ENDSND1+1);
+			3, int(Sound("PLAYER_UNDERWATER")),
+			35, int(Sound("VOL4ENDSND1")));
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e1.anm", soundinfo, 0, 10, 10, 10));
 
 		soundinfo.Pushv(
-			11, DukeSnd.DUKE_UNDERWATER+1,
-			20, DukeSnd.VOL4ENDSND1+1,
-			39, DukeSnd.VOL4ENDSND2+1,
+			11, int(Sound("PLAYER_UNDERWATER")),
+			20, int(Sound("VOL4ENDSND1")),
+			39, int(Sound("VOL4ENDSND2")),
 			50, -1);
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e2.anm", soundinfo, 0, 14, 14, 14));
 
 		soundinfo.Pushv(
-			1, DukeSnd.BOSS4_DEADSPEECH+1,
-			40, DukeSnd.VOL4ENDSND1+1,
-			40, DukeSnd.DUKE_UNDERWATER+1,
-			50, DukeSnd.BIGBANG+1);
+			1, int(Sound("BOSS4_DEADSPEECH")),
+			40, int(Sound("VOL4ENDSND1")),
+			40, int(Sound("PLAYER_UNDERWATER")),
+			50, int(Sound("BIGBANG")));
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e3.anm", soundinfo, 0, 10, 10, 10));
 
 		runner.Append(new("Episode4Text").Init());
@@ -177,23 +177,23 @@ class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot e
 
 		Duke.PlaySpecialMusic(Duke.MUS_BRIEFING);
 		soundinfo.Pushv(
-			1, DukeSnd.INTRO4_1 + 1,
-			7, DukeSnd.INTRO4_3 + 1,
-			12, DukeSnd.INTRO4_2 + 1,
-			26, DukeSnd.INTRO4_4 + 1);
+			1, int(Sound("INTRO4_1")),
+			7, int(Sound("INTRO4_3")),
+			12, int(Sound("INTRO4_2")),
+			26, int(Sound("INTRO4_4")));
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol41a.anm", soundinfo, MoviePlayer.NOSOUNDCUTOFF, 14, 14, 14));
 
 		soundinfo.Pushv(
-			1, DukeSnd.INTRO4_B + 1,
-			12, DukeSnd.SHORT_CIRCUIT + 1,
-			18, DukeSnd.INTRO4_5 + 1,
-			34, DukeSnd.SHORT_CIRCUIT + 1);
+			1, int(Sound("INTRO4_B")),
+			12, int(Sound("SHORT_CIRCUIT")),
+			18, int(Sound("INTRO4_5")),
+			34, int(Sound("SHORT_CIRCUIT")));
 		let m = MoviePlayerJob.CreateWithSoundinfo("vol42a.anm", soundinfo, MoviePlayer.NOSOUNDCUTOFF, 18, 18, 18);
 		if (m) m.skipover = true;
 		runner.Append(m);
 
 		soundinfo.Pushv(
-			10, DukeSnd.INTRO4_6 + 1);
+			10, int(Sound("INTRO4_6")));
 		m = MoviePlayerJob.CreateWithSoundinfo("vol43a.anm", soundinfo, 0, 10, 10, 10);
 		if (m) m.skipover = true;
 		runner.Append(m);
@@ -275,13 +275,13 @@ class RRCutscenes ui
 		if (!userConfig.nologo)
 		{
 			Array<int> soundinfo;
-			soundinfo.Pushv(1, RRSnd.URANUS + 1);
+			soundinfo.Pushv(1, int(Sound("URANUS")));
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_intro.anm", soundinfo, 0, 9, 9, 9));
 
-			soundinfo.Pushv(1, RRSnd.REDNECK2 + 1);
+			soundinfo.Pushv(1, int(Sound("REDNECK2")));
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("redneck.anm", soundinfo, 0, 9, 9, 9));
 
-			soundinfo.Pushv(1, RRSnd.XATRIX + 1);
+			soundinfo.Pushv(1, int(Sound("XATRIX")));
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("xatlogo.anm", soundinfo, 0, 9, 9, 9));
 		}
 	}
@@ -313,7 +313,7 @@ class RRCutscenes ui
 		if (!Raze.isRRRA())
 		{
 			Array<int> soundinfo;
-			soundinfo.Pushv(1, RRSnd.CHKAMMO + 1);
+			soundinfo.Pushv(1, int(Sound("CHKAMMO")));
 			runner.Append(MoviePlayerJob.CreateWithSoundinfo("turdmov.anm", soundinfo, 0, 9, 9, 9));
 		} 
 	}
@@ -328,7 +328,7 @@ class RRCutscenes ui
 	static void BuildE2End(ScreenJobRunner runner)
     {
 		Array<int> soundinfo;
-		soundinfo.Pushv(1, RRSnd.LN_FINAL + 1);
+		soundinfo.Pushv(1, int(Sound("LN_FINAL")));
 		runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_outro.anm", soundinfo, MoviePlayer.NOSOUNDCUTOFF, 9, 9, 9));
 		runner.Append(ImageScreen.CreateNamed("TENSCREEN"));
 	}
diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs
index 80fc75d94..e6efb496c 100644
--- a/wadsrc/static/zscript/games/duke/ui/screens.zs
+++ b/wadsrc/static/zscript/games/duke/ui/screens.zs
@@ -89,22 +89,22 @@ class DukeTitleScreen : SkippableScreenJob
 		if (soundanm == 0 && clock >= 120 && clock < 120 + 60)
 		{
 			soundanm = 1;
-			Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+			Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 		}
 		if (soundanm == 1 && clock > 220 && clock < (220 + 30))
 		{
 			soundanm = 2;
-			Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+			Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 		}
 		if (soundanm == 2 && clock >= 280 && clock < 395)
 		{
 			soundanm = 3;
-			if (Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI);
+			if (Raze.isPlutoPak()) Duke.PlaySound("FLY_BY", CHAN_AUTO, CHANF_UI);
 		}
 		else if (soundanm == 3 && clock >= 395)
 		{
 			soundanm = 4;
-			if (Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+			if (Raze.isPlutoPak()) Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 		}
 
 		if (clock > (860 + 120))
@@ -159,7 +159,7 @@ class DukeTitleScreen : SkippableScreenJob
 
 	override void OnDestroy()
 	{
-		Duke.PlaySound(DukeSnd.NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI);
+		Duke.PlaySound("NITEVISION_ONOFF", CHAN_AUTO, CHANF_UI);
 	}
 }
 
@@ -215,8 +215,8 @@ class Episode1End1 : SkippableScreenJob
 			{
 				if (t == 10 && bonuscnt == 1)
 				{
-					Duke.PlaySound(DukeSnd.SHOTGUN_FIRE, CHAN_AUTO, CHANF_UI);
-					Duke.PlaySound(DukeSnd.SQUISHED, CHAN_AUTO, CHANF_UI);
+					Duke.PlaySound("SHOTGUN_FIRE", CHAN_AUTO, CHANF_UI);
+					Duke.PlaySound("SQUISHED", CHAN_AUTO, CHANF_UI);
 					bonuscnt++;
 				}
 				bossani = TexMan.CheckForTexture(boss_tile[tt]);
@@ -231,7 +231,7 @@ class Episode1End1 : SkippableScreenJob
 				breathebg = true;
 				if (currentclock >= 750 && bonuscnt == 2)
 				{
-					Duke.PlaySound(DukeSnd.DUKETALKTOBOSS, CHAN_AUTO, CHANF_UI);
+					Duke.PlaySound("DUKETALKTOBOSS", CHAN_AUTO, CHANF_UI);
 					bonuscnt++;
 				}
 			}
@@ -240,7 +240,7 @@ class Episode1End1 : SkippableScreenJob
 				{
 					if (t == 5 && bonuscnt == 0)
 					{
-						Duke.PlaySound(DukeSnd.BOSSTALKTODUKE, CHAN_AUTO, CHANF_UI);
+						Duke.PlaySound("BOSSTALKTODUKE", CHAN_AUTO, CHANF_UI);
 						bonuscnt++;
 					}
 					breatheani = TexMan.CheckForTexture(breathe_tile[tt]);
@@ -294,7 +294,7 @@ class E2EndScreen : ImageScreen
 
 	override void Start()
 	{
-		Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+		Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 	}
 }
 
@@ -327,44 +327,45 @@ class Episode3End : ImageScreen
 		switch (soundstate)
 		{
 		case 0:
-			Duke.PlaySound(DukeSnd.ENDSEQVOL3SND5, CHAN_AUTO, CHANF_UI);
+			Duke.PlaySound("ENDSEQVOL3SND5", CHAN_AUTO, CHANF_UI);
 			soundstate++;
 			break;
 
+		/*
 		case 1:
-			if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND5))
+			if (!Duke.CheckSoundPlaying("ENDSEQVOL3SND5"))
 			{
-				Duke.PlaySound(DukeSnd.ENDSEQVOL3SND6, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("ENDSEQVOL3SND6", CHAN_AUTO, CHANF_UI);
 				soundstate++;
 			}
 			break;
 
 		case 2:
-			if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND6))
+			if (!Duke.CheckSoundPlaying("ENDSEQVOL3SND6"))
 			{
-				Duke.PlaySound(DukeSnd.ENDSEQVOL3SND7, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("ENDSEQVOL3SND7", CHAN_AUTO, CHANF_UI);
 				soundstate++;
 			}
 			break;
 
 		case 3:
-			if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND7))
+			if (!Duke.CheckSoundPlaying("ENDSEQVOL3SND7"))
 			{
-				Duke.PlaySound(DukeSnd.ENDSEQVOL3SND8, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("ENDSEQVOL3SND8", CHAN_AUTO, CHANF_UI);
 				soundstate++;
 			}
 			break;
 
 		case 4:
-			if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND8))
+			if (!Duke.CheckSoundPlaying("ENDSEQVOL3SND8"))
 			{
-				Duke.PlaySound(DukeSnd.ENDSEQVOL3SND9, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("ENDSEQVOL3SND92, CHAN_AUTO, CHANF_UI);
 				soundstate++;
 			}
 			break;
 
 		case 5:
-			if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND9))
+			if (!Duke.CheckSoundPlaying("ENDSEQVOL3SND9"))
 			{
 				soundstate++;
 				finishtime = ticks + GameTicRate * (System.SoundEnabled() ? 1 : 5);	// if sound is off this wouldn't wait without a longer delay here.
@@ -377,6 +378,7 @@ class Episode3End : ImageScreen
 				if (ticks > finishtime) jobstate = finished;
 			}
 			break;
+		*/
 
 		default:
 			break;
@@ -386,7 +388,7 @@ class Episode3End : ImageScreen
 
 	override void OnDestroy()
 	{
-		if (!Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI);
+		if (!Raze.isPlutoPak()) Duke.PlaySound("ENDSEQVOL3SND4", CHAN_AUTO, CHANF_UI);
 	}
 }
 
@@ -416,7 +418,7 @@ class Episode4Text : SkippableScreenJob
 
 	override void Start()
 	{
-		Duke.PlaySound(DukeSnd.ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI);
+		Duke.PlaySound("ENDSEQVOL3SND4", CHAN_AUTO, CHANF_UI);
 	}
 }
 
@@ -436,7 +438,7 @@ class Episode5End : ImageScreen
 
 	override void OnTick()
 	{
-		if (ticks == 1) Duke.PlaySound(DukeSnd.E5L7_DUKE_QUIT_YOU, CHAN_AUTO, CHANF_UI);
+		if (ticks == 1) Duke.PlaySound("E5L7_DUKE_QUIT_YOU", CHAN_AUTO, CHANF_UI);
 	}
 }
 
@@ -486,7 +488,7 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob
 class DukeLevelSummaryScreen : SummaryScreenBase
 {
 	String lastmapname;
-	int speech;
+	Sound speech;
 	int displaystate;
 	int dukeAnimStart;
 
@@ -536,15 +538,15 @@ class DukeLevelSummaryScreen : SummaryScreenBase
 		{
 			if ((displaystate & printStatsAll) != printStatsAll)
 			{
-				Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 				displaystate = printStatsAll;
 			}
 			else if (!(displaystate & dukeAnim))
 			{
 				displaystate |= dukeAnim;
 				dukeAnimStart = ticks;
-				Duke.PlaySound(DukeSnd.SHOTGUN_COCK, CHAN_AUTO, CHANF_UI);
-				static const int speeches[] = { DukeSnd.BONUS_SPEECH1, DukeSnd.BONUS_SPEECH2, DukeSnd.BONUS_SPEECH3, DukeSnd.BONUS_SPEECH4 };
+				Duke.PlaySound("SHOTGUN_COCK", CHAN_AUTO, CHANF_UI);
+				static const Sound speeches[] = { "BONUS_SPEECH1", "BONUS_SPEECH2", "BONUS_SPEECH3", "BONUS_SPEECH4" };
 				speech = speeches[random(0, 3)];
 				Duke.PlaySound(speech, CHAN_AUTO, CHANF_UI, 1);
 			}
@@ -569,17 +571,17 @@ class DukeLevelSummaryScreen : SummaryScreenBase
 			else if (ticks == 15 * 4)
 			{
 				displaystate |= printTimeVal;
-				Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 			}
 			else if (ticks == 15 * 6)
 			{
 				displaystate |= printKillsText;
-				Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("FLY_BY", CHAN_AUTO, CHANF_UI);
 			}
 			else if (ticks == 15 * 7)
 			{
 				displaystate |= printKillsVal;
-				Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 			}
 			else if (ticks == 15 * 9)
 			{
@@ -588,7 +590,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase
 			else if (ticks == 15 * 10)
 			{
 				displaystate |= printSecretsVal;
-				Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("PIPEBOMB_EXPLODE", CHAN_AUTO, CHANF_UI);
 			}
 		}
 		if (displaystate & dukeAnim)
@@ -731,7 +733,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase
 class RRLevelSummaryScreen : SummaryScreenBase
 {
 	String lastmapname;
-	int speech;
+	Sound speech;
 	int displaystate;
 	int exitSoundStart;
 	TextureID texBg;
@@ -773,15 +775,15 @@ class RRLevelSummaryScreen : SummaryScreenBase
 		{
 			if ((displaystate & printStatsAll) != printStatsAll)
 			{
-				Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("FART1", CHAN_AUTO, CHANF_UI);
 				displaystate = printStatsAll;
 			}
 			else if (!(displaystate & exitSound))
 			{
 				displaystate |= exitSound;
 				exitSoundStart = ticks;
-				Duke.PlaySound(RRSnd.CHUG, CHAN_AUTO, CHANF_UI);
-				static const int speeches[] = { RRSnd.BNS_SPCH1, RRSnd.BNS_SPCH2, RRSnd.BNS_SPCH3, RRSnd.BNS_SPCH4 };
+				Duke.PlaySound("CHUG", CHAN_AUTO, CHANF_UI);
+				static const Sound speeches[] = { "BONUS_SPEECH1", "BONUS_SPEECH2", "BONUS_SPEECH3", "BONUS_SPEECH4" };
 				speech = speeches[random(0, 3)];
 				Duke.PlaySound(speech, CHAN_AUTO, CHANF_UI);
 			}
@@ -801,7 +803,7 @@ class RRLevelSummaryScreen : SummaryScreenBase
 			else if (ticks == 15 * 4)
 			{
 				displaystate |= printTimeVal;
-				Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("FART1", CHAN_AUTO, CHANF_UI);
 			}
 			else if (ticks == 15 * 6)
 			{
@@ -810,7 +812,7 @@ class RRLevelSummaryScreen : SummaryScreenBase
 			else if (ticks == 15 * 7)
 			{
 				displaystate |= printKillsVal;
-				Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("FART1", CHAN_AUTO, CHANF_UI);
 			}
 			else if (ticks == 15 * 9)
 			{
@@ -819,7 +821,7 @@ class RRLevelSummaryScreen : SummaryScreenBase
 			else if (ticks == 15 * 10)
 			{
 				displaystate |= printSecretsVal;
-				Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI);
+				Duke.PlaySound("FART1", CHAN_AUTO, CHANF_UI);
 			}
 		}
 		if (displaystate & exitSound)
@@ -931,17 +933,17 @@ class RRRAEndOfGame : SkippableScreenJob
 
 	override void OnSkip()
 	{
-		Duke.StopSound(RRSnd.LN_FINAL);
+		Duke.StopSound("LN_FINAL");
 	}
 
 	override void Start()
 	{
-		Duke.PlaySound(RRSnd.LN_FINAL, CHAN_AUTO, CHANF_UI);
+		Duke.PlaySound("LN_FINAL", CHAN_AUTO, CHANF_UI);
 	}
 
 	override void OnTick()
 	{
-		if (!Duke.CheckSoundPlaying(RRSnd.LN_FINAL) && ticks > 15 * GameTicRate) jobstate = finished; // make sure it stays, even if sound is off.
+		if (!Duke.CheckSoundPlaying("LN_FINAL") && ticks > 15 * GameTicRate) jobstate = finished; // make sure it stays, even if sound is off.
 	}
 
 	override void Draw(double sr)