Quake 4 integrated with DoomRTX

This commit is contained in:
Justin Marshall
2026-05-09 22:10:40 -07:00
parent 8c4a087aa9
commit d37f87e493
436 changed files with 277587 additions and 10254 deletions
+138 -7
View File
@@ -159,12 +159,31 @@ bool idSoundShader::ParseShader(idLexer& src) {
int i;
idToken token;
#ifdef QUAKE4
parms.minDistance = 40.0f;
parms.maxDistance = 400.0f;
parms.volume = 1.0f;
parms.attenuatedVolume = 0.0f;
parms.shakes = 0.0f;
parms.soundShaderFlags = 0;
parms.soundClass = 0;
parms.frequencyShift = 1.0f;
parms.wetLevel = 0.0f;
parms.dryLevel = 0.0f;
minFrequencyShift = 1.0f;
maxFrequencyShift = 1.0f;
noShakes = false;
frequentlyUsed = false;
#else
parms.minDistance = 1;
parms.maxDistance = 10;
parms.volume = 1;
parms.shakes = 0;
parms.soundShaderFlags = 0;
parms.soundClass = 0;
#endif
#ifdef PREY
parms.subIndex = 0;
@@ -201,9 +220,34 @@ bool idSoundShader::ParseShader(idLexer& src) {
// minimum number of sounds
else if (!token.Icmp("minSamples")) {
#ifdef QUAKE4
const int requestedSamples = src.ParseInt();
if (maxSamples < requestedSamples) {
maxSamples = requestedSamples;
}
if (maxSamples > SOUND_MAX_LIST_WAVS) {
maxSamples = SOUND_MAX_LIST_WAVS;
}
#else
maxSamples = idMath::ClampInt(src.ParseInt(), SOUND_MAX_LIST_WAVS, maxSamples);
#endif
}
#ifdef QUAKE4
// Raven: frequency shift range
else if (!token.Icmp("frequencyshift")) {
minFrequencyShift = src.ParseFloat();
if (!src.ExpectTokenString(",")) {
src.FreeSource();
return false;
}
maxFrequencyShift = src.ParseFloat();
parms.frequencyShift = minFrequencyShift;
}
#endif
// description
else if (!token.Icmp("description")) {
src.ReadTokenOnLine(&token);
@@ -232,6 +276,23 @@ bool idSoundShader::ParseShader(idLexer& src) {
}
}
#ifdef QUAKE4
// Raven: indexed shake amplitude data
else if (!token.Icmp("shakeData")) {
if (!src.ExpectAnyToken(&token)) {
return false;
}
const int shakeIndex = atoi(token.c_str());
if (!src.ExpectAnyToken(&token)) {
return false;
}
//SetShakeData(shakeIndex, token.c_str());
}
#endif
// reverb -- parsed but unsupported
else if (!token.Icmp("reverb")) {
src.ParseFloat();
@@ -249,6 +310,20 @@ bool idSoundShader::ParseShader(idLexer& src) {
parms.volume = src.ParseFloat();
}
#ifdef QUAKE4
// Raven: volume specified in decibels, clamped to +10dB
else if (!token.Icmp("volumeDb")) {
float volumeDb = src.ParseFloat();
if (volumeDb > 10.0f) {
common->Warning("Clamping volume of '%s' to +10dB (3 times louder)", GetName());
volumeDb = 10.0f;
}
parms.volume = idMath::dBToScale(volumeDb);
}
#endif
// leadinVolume is used to allow light breaking leadin sounds to be much louder than the broken loop
else if (!token.Icmp("leadinVolume")) {
leadinVolume = src.ParseFloat();
@@ -400,6 +475,33 @@ bool idSoundShader::ParseShader(idLexer& src) {
parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL;
}
#ifdef QUAKE4
// Raven: allow doppler pitch shifting
else if (!token.Icmp("useDoppler")) {
parms.soundShaderFlags |= SSF_USEDOPPLER;
}
// Raven: don't randomly seek into looping sounds
else if (!token.Icmp("noRandomStart")) {
parms.soundShaderFlags |= SSF_NO_RANDOMSTART;
}
// Raven: marks VO directed at player/radio chatter
else if (!token.Icmp("voForPlayer")) {
parms.soundShaderFlags |= SSF_VO_FOR_PLAYER;
}
// Raven: disable generated shake data
else if (!token.Icmp("no_shakes")) {
noShakes = true;
}
// Raven: force expansion / keep hot
else if (!token.Icmp("frequentlyUsed")) {
frequentlyUsed = true;
}
#endif
// onDemand can't be a parms, because we must track all references and overrides would confuse it
else if (!token.Icmp("onDemand")) {
// no longer loading sounds on demand
@@ -415,12 +517,6 @@ bool idSoundShader::ParseShader(idLexer& src) {
}
// HumanHead/Prey: subtitle / subtitlecombat parser
//
// Supported examples based on the decompiled parser:
// subtitle 1.5 "text"
// subtitle2 c1 1.5 "text"
// subtitlecombat c2 0.25 "combat text"
// subtitlecombat3 c4 2.0 "combat text"
else if (!token.Icmpn("subtitle", 8)) {
const bool combatSubtitle = (token.Icmpn("subtitlecombat", 14) == 0);
@@ -482,19 +578,35 @@ bool idSoundShader::ParseShader(idLexer& src) {
return false;
}
#ifdef QUAKE4
if (soundSystemLocal.soundCache && numLeadins < maxSamples) {
leadins[numLeadins] = soundSystem->FindSample(token.c_str());
numLeadins++;
}
#else
if (soundSystemLocal.soundCache && numLeadins < maxSamples) {
#ifdef PREY
// Prey behavior: do not run the Doom 3 VO language substitution path here.
leadins[numLeadins] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
#else
leadins[numLeadins] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
#endif
numLeadins++;
}
#endif
}
// the regular wave files
else if (token.Find(".wav", false) != -1 || token.Find(".ogg", false) != -1) {
#ifdef QUAKE4
if (soundSystemLocal.soundCache && numEntries < maxSamples) {
token.BackSlashesToSlashes();
entries[numEntries] = soundSystem->FindSample(token.c_str());
if (entries[numEntries]) {
numEntries++;
}
}
#else
if (soundSystemLocal.soundCache && numEntries < maxSamples) {
token.BackSlashesToSlashes();
@@ -526,6 +638,7 @@ bool idSoundShader::ParseShader(idLexer& src) {
entries[numEntries] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
numEntries++;
}
#endif
}
else {
@@ -534,9 +647,15 @@ bool idSoundShader::ParseShader(idLexer& src) {
}
}
#ifdef QUAKE4
// if (!soundSystem->GetInsideLevelLoad()) {
// soundSystem->ValidateSoundShader(this);
// }
#else
if (parms.shakes > 0.0f) {
CheckShakesAndOgg();
}
#endif
return true;
}
@@ -680,3 +799,15 @@ const char *idSoundShader::GetSound( int index ) const {
}
return "";
}
#ifdef QUAKE4
/*
===============
idSoundShader::IsVO_ForPlayer
===============
*/
bool idSoundShader::IsVO_ForPlayer() const
{
return (parms.soundShaderFlags & SSF_VO_FOR_PLAYER) != 0;
}
#endif