mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 16:21:04 +02:00
813 lines
18 KiB
C++
813 lines
18 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
IceTech GPL Source Code
|
|
Copyright (C) 2026 Justin Marshall
|
|
|
|
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
|
|
|
|
IceTech Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
IceTech Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "snd_local.h"
|
|
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::Init
|
|
===============
|
|
*/
|
|
void idSoundShader::Init( void ) {
|
|
desc = "<no description>";
|
|
errorDuringParse = false;
|
|
onDemand = false;
|
|
numEntries = 0;
|
|
numLeadins = 0;
|
|
leadinVolume = 0;
|
|
altSound = NULL;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::idSoundShader
|
|
===============
|
|
*/
|
|
idSoundShader::idSoundShader( void ) {
|
|
Init();
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::~idSoundShader
|
|
===============
|
|
*/
|
|
idSoundShader::~idSoundShader( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idSoundShader::Size
|
|
=================
|
|
*/
|
|
size_t idSoundShader::Size( void ) const {
|
|
return sizeof( idSoundShader );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::idSoundShader::FreeData
|
|
===============
|
|
*/
|
|
void idSoundShader::FreeData() {
|
|
numEntries = 0;
|
|
numLeadins = 0;
|
|
}
|
|
|
|
/*
|
|
===================
|
|
idSoundShader::SetDefaultText
|
|
===================
|
|
*/
|
|
bool idSoundShader::SetDefaultText( void ) {
|
|
idStr wavname;
|
|
|
|
wavname = GetName();
|
|
wavname.DefaultFileExtension( ".wav" ); // if the name has .ogg in it, that will stay
|
|
|
|
// if there exists a wav file with the same name
|
|
if ( 1 ) { //fileSystem->ReadFile( wavname, NULL ) != -1 ) {
|
|
char generated[2048];
|
|
idStr::snPrintf( generated, sizeof( generated ),
|
|
"sound %s // IMPLICITLY GENERATED\n"
|
|
"{\n"
|
|
"%s\n"
|
|
"}\n", GetName(), wavname.c_str() );
|
|
SetText( generated );
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
===================
|
|
DefaultDefinition
|
|
===================
|
|
*/
|
|
const char *idSoundShader::DefaultDefinition() const {
|
|
return
|
|
"{\n"
|
|
"\t" "_default.wav\n"
|
|
"}";
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::Parse
|
|
|
|
this is called by the declManager
|
|
===============
|
|
*/
|
|
bool idSoundShader::Parse( const char *text, const int textLength ) {
|
|
idLexer src;
|
|
|
|
src.LoadMemory( text, textLength, GetFileName(), GetLineNum() );
|
|
src.SetFlags( DECL_LEXER_FLAGS );
|
|
src.SkipUntilString( "{" );
|
|
|
|
// deeper functions can set this, which will cause MakeDefault() to be called at the end
|
|
errorDuringParse = false;
|
|
|
|
if ( !ParseShader( src ) || errorDuringParse ) {
|
|
MakeDefault();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::ParseShader
|
|
===============
|
|
*/
|
|
/*
|
|
===============
|
|
idSoundShader::ParseShader
|
|
===============
|
|
*/
|
|
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;
|
|
parms.profanityIndex = -1;
|
|
parms.profanityDelay = 0.0f;
|
|
parms.profanityDuration = 0.0f;
|
|
#endif
|
|
|
|
speakerMask = 0;
|
|
altSound = NULL;
|
|
|
|
for (i = 0; i < SOUND_MAX_LIST_WAVS; i++) {
|
|
leadins[i] = NULL;
|
|
entries[i] = NULL;
|
|
}
|
|
|
|
numEntries = 0;
|
|
numLeadins = 0;
|
|
|
|
int maxSamples = idSoundSystemLocal::s_maxSoundsPerShader.GetInteger();
|
|
if (com_makingBuild.GetBool() || maxSamples <= 0 || maxSamples > SOUND_MAX_LIST_WAVS) {
|
|
maxSamples = SOUND_MAX_LIST_WAVS;
|
|
}
|
|
|
|
while (1) {
|
|
if (!src.ExpectAnyToken(&token)) {
|
|
return false;
|
|
}
|
|
|
|
// end of definition
|
|
if (token == "}") {
|
|
break;
|
|
}
|
|
|
|
// 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);
|
|
desc = token.c_str();
|
|
}
|
|
|
|
// mindistance
|
|
else if (!token.Icmp("mindistance")) {
|
|
parms.minDistance = src.ParseFloat();
|
|
}
|
|
|
|
// maxdistance
|
|
else if (!token.Icmp("maxdistance")) {
|
|
parms.maxDistance = src.ParseFloat();
|
|
}
|
|
|
|
// shakes screen
|
|
else if (!token.Icmp("shakes")) {
|
|
src.ExpectAnyToken(&token);
|
|
if (token.type == TT_NUMBER) {
|
|
parms.shakes = token.GetFloatValue();
|
|
}
|
|
else {
|
|
src.UnreadToken(&token);
|
|
parms.shakes = 1.0f;
|
|
}
|
|
}
|
|
|
|
#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();
|
|
|
|
if (!src.ExpectTokenString(",")) {
|
|
src.FreeSource();
|
|
return false;
|
|
}
|
|
|
|
src.ParseFloat();
|
|
}
|
|
|
|
// volume
|
|
else if (!token.Icmp("volume")) {
|
|
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();
|
|
}
|
|
|
|
// speaker masks
|
|
else if (!token.Icmp("mask_center")) {
|
|
speakerMask |= 1 << SPEAKER_CENTER;
|
|
}
|
|
else if (!token.Icmp("mask_left")) {
|
|
speakerMask |= 1 << SPEAKER_LEFT;
|
|
}
|
|
else if (!token.Icmp("mask_right")) {
|
|
speakerMask |= 1 << SPEAKER_RIGHT;
|
|
}
|
|
else if (!token.Icmp("mask_backright")) {
|
|
speakerMask |= 1 << SPEAKER_BACKRIGHT;
|
|
}
|
|
else if (!token.Icmp("mask_backleft")) {
|
|
speakerMask |= 1 << SPEAKER_BACKLEFT;
|
|
}
|
|
else if (!token.Icmp("mask_lfe")) {
|
|
speakerMask |= 1 << SPEAKER_LFE;
|
|
}
|
|
|
|
// soundClass
|
|
else if (!token.Icmp("soundClass")) {
|
|
#ifdef PREY
|
|
if (!src.ReadToken(&token)) {
|
|
src.Warning("Expected classname after soundClass");
|
|
return false;
|
|
}
|
|
|
|
if (!token.Icmp("SC_NORMAL")) {
|
|
parms.soundClass = SOUNDCLASS_NORMAL;
|
|
}
|
|
else if (!token.Icmp("SC_VOICEDUCKER")) {
|
|
parms.soundClass = SOUNDCLASS_VOICEDUCKER;
|
|
}
|
|
else if (!token.Icmp("SC_SPIRIT")) {
|
|
parms.soundClass = SOUNDCLASS_SPIRITWALK;
|
|
}
|
|
else if (!token.Icmp("SC_VOICE")) {
|
|
parms.soundClass = SOUNDCLASS_VOICE;
|
|
}
|
|
else if (!token.Icmp("SC_MUSIC")) {
|
|
parms.soundClass = SOUNDCLASS_MUSIC;
|
|
}
|
|
else {
|
|
src.Warning("SoundClass takes args of SC_NORMAL, SC_SPIRIT, SC_VOICE, SC_VOICEDUCKER");
|
|
return false;
|
|
}
|
|
#else
|
|
parms.soundClass = src.ParseInt();
|
|
if (parms.soundClass < 0 || parms.soundClass >= SOUND_MAX_CLASSES) {
|
|
src.Warning("SoundClass out of range");
|
|
return false;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// altSound
|
|
else if (!token.Icmp("altSound")) {
|
|
if (!src.ExpectAnyToken(&token)) {
|
|
return false;
|
|
}
|
|
altSound = declManager->FindSound(token.c_str());
|
|
}
|
|
|
|
// ordered -- unsupported
|
|
else if (!token.Icmp("ordered")) {
|
|
}
|
|
|
|
// no_dups
|
|
else if (!token.Icmp("no_dups")) {
|
|
parms.soundShaderFlags |= SSF_NO_DUPS;
|
|
}
|
|
|
|
// no_flicker
|
|
else if (!token.Icmp("no_flicker")) {
|
|
parms.soundShaderFlags |= SSF_NO_FLICKER;
|
|
}
|
|
|
|
// plain -- unsupported
|
|
else if (!token.Icmp("plain")) {
|
|
}
|
|
|
|
// looping
|
|
else if (!token.Icmp("looping")) {
|
|
parms.soundShaderFlags |= SSF_LOOPING;
|
|
}
|
|
|
|
// no occlusion
|
|
else if (!token.Icmp("no_occlusion")) {
|
|
parms.soundShaderFlags |= SSF_NO_OCCLUSION;
|
|
}
|
|
|
|
#ifdef PREY
|
|
// HumanHead/Prey: no game portal sound flow
|
|
else if (!token.Icmp("noportalflow")) {
|
|
#if GAMEPORTAL_SOUND
|
|
parms.soundShaderFlags |= SSF_NOPORTALFLOW;
|
|
#endif
|
|
}
|
|
|
|
// HumanHead/Prey: no reverb
|
|
else if (!token.Icmp("noreverb")) {
|
|
parms.soundShaderFlags |= SSF_NOREVERB;
|
|
}
|
|
|
|
// HumanHead/Prey: include this shader in voice amplitude queries
|
|
else if (!token.Icmp("jawflap")) {
|
|
parms.soundShaderFlags |= SSF_VOICEAMPLITUDE;
|
|
}
|
|
|
|
// HumanHead/Prey: become omni when inside minDistance
|
|
else if (!token.Icmp("omniwhenclose")) {
|
|
parms.soundShaderFlags |= SSF_OMNI_WHEN_CLOSE;
|
|
}
|
|
#endif
|
|
|
|
// private
|
|
else if (!token.Icmp("private")) {
|
|
parms.soundShaderFlags |= SSF_PRIVATE_SOUND;
|
|
}
|
|
|
|
// antiPrivate
|
|
else if (!token.Icmp("antiPrivate")) {
|
|
parms.soundShaderFlags |= SSF_ANTI_PRIVATE_SOUND;
|
|
}
|
|
|
|
// once
|
|
else if (!token.Icmp("playonce")) {
|
|
parms.soundShaderFlags |= SSF_PLAY_ONCE;
|
|
}
|
|
|
|
// global
|
|
else if (!token.Icmp("global")) {
|
|
parms.soundShaderFlags |= SSF_GLOBAL;
|
|
}
|
|
|
|
// unclamped
|
|
else if (!token.Icmp("unclamped")) {
|
|
parms.soundShaderFlags |= SSF_UNCLAMPED;
|
|
}
|
|
|
|
// omnidirectional
|
|
else if (!token.Icmp("omnidirectional")) {
|
|
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
|
|
// onDemand = true;
|
|
}
|
|
|
|
#ifdef PREY
|
|
// HumanHead/Prey: profanity bleep data
|
|
else if (!token.Icmp("bleep")) {
|
|
parms.profanityIndex = src.ParseInt();
|
|
parms.profanityDelay = src.ParseFloat();
|
|
parms.profanityDuration = src.ParseFloat();
|
|
}
|
|
|
|
// HumanHead/Prey: subtitle / subtitlecombat parser
|
|
else if (!token.Icmpn("subtitle", 8)) {
|
|
const bool combatSubtitle = (token.Icmpn("subtitlecombat", 14) == 0);
|
|
|
|
const char* numText;
|
|
if (combatSubtitle) {
|
|
numText = token.c_str() + 14;
|
|
}
|
|
else {
|
|
numText = token.c_str() + 8;
|
|
}
|
|
|
|
const int subNum = (numText[0] != '\0') ? atoi(numText) : 1;
|
|
|
|
if (!src.ReadToken(&token)) {
|
|
src.Warning("Expected time after subtext");
|
|
return false;
|
|
}
|
|
|
|
int subChannel = 0;
|
|
|
|
if (token.c_str()[0] == 'c' || token.c_str()[0] == 'C') {
|
|
const int channelNumber = atoi(token.c_str() + 1);
|
|
subChannel = channelNumber - 1;
|
|
|
|
if (subChannel < 0 || subChannel >= MAX_SUBTITLE_CHANNELS) {
|
|
src.Warning("Value '%i' is out of range for MAX_SUBTITLE_CHANNELS.", channelNumber);
|
|
return false;
|
|
}
|
|
|
|
if (!src.ReadToken(&token)) {
|
|
src.Warning("Expected time after subtitle channel");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const float subTime = atof(token.c_str());
|
|
|
|
if (!src.ReadToken(&token)) {
|
|
src.Warning("Expected text after subtext and time");
|
|
return false;
|
|
}
|
|
|
|
if (combatSubtitle) {
|
|
subChannel += 3;
|
|
}
|
|
|
|
if (parms.subIndex == 0) {
|
|
parms.subIndex = soundSystemLocal.GetSubtitleIndex(GetName());
|
|
}
|
|
|
|
soundSystemLocal.SetSubtitleData(parms.subIndex, subNum, token.c_str(), subTime, subChannel);
|
|
}
|
|
#endif
|
|
|
|
// the leadin wave files
|
|
else if (!token.Icmp("leadin")) {
|
|
if (!src.ReadToken(&token)) {
|
|
src.Warning("Expected sound after leadin");
|
|
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
|
|
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();
|
|
|
|
#ifdef PREY
|
|
// Prey behavior grabs sys_lang but does not do Doom 3's
|
|
// sound/vo/<lang>/ replacement lookup before FindSound.
|
|
idStr lang = cvarSystem->GetCVarString("sys_lang");
|
|
#else
|
|
idStr lang = cvarSystem->GetCVarString("sys_lang");
|
|
if (lang.Icmp("english") != 0 && token.Find("sound/vo/", false) >= 0) {
|
|
idStr work = token;
|
|
work.ToLower();
|
|
work.StripLeading("sound/vo/");
|
|
work = va("sound/vo/%s/%s", lang.c_str(), work.c_str());
|
|
|
|
if (fileSystem->ReadFile(work, NULL, NULL) > 0) {
|
|
token = work;
|
|
}
|
|
else {
|
|
// also try to find it with the .ogg extension
|
|
work.SetFileExtension(".ogg");
|
|
if (fileSystem->ReadFile(work, NULL, NULL) > 0) {
|
|
token = work;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
entries[numEntries] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
|
|
numEntries++;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
else {
|
|
src.Warning("unknown token '%s'", token.c_str());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
// if (!soundSystem->GetInsideLevelLoad()) {
|
|
// soundSystem->ValidateSoundShader(this);
|
|
// }
|
|
#else
|
|
if (parms.shakes > 0.0f) {
|
|
CheckShakesAndOgg();
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::CheckShakesAndOgg
|
|
===============
|
|
*/
|
|
bool idSoundShader::CheckShakesAndOgg( void ) const {
|
|
int i;
|
|
bool ret = false;
|
|
|
|
for ( i = 0; i < numLeadins; i++ ) {
|
|
if ( leadins[ i ]->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) {
|
|
common->Warning( "sound shader '%s' has shakes and uses OGG file '%s'",
|
|
GetName(), leadins[ i ]->name.c_str() );
|
|
ret = true;
|
|
}
|
|
}
|
|
for ( i = 0; i < numEntries; i++ ) {
|
|
if ( entries[ i ]->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) {
|
|
common->Warning( "sound shader '%s' has shakes and uses OGG file '%s'",
|
|
GetName(), entries[ i ]->name.c_str() );
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::List
|
|
===============
|
|
*/
|
|
void idSoundShader::List() const {
|
|
idStrList shaders;
|
|
|
|
common->Printf( "%4i: %s\n", Index(), GetName() );
|
|
if ( idStr::Icmp( GetDescription(), "<no description>" ) != 0 ) {
|
|
common->Printf( " description: %s\n", GetDescription() );
|
|
}
|
|
for( int k = 0; k < numLeadins ; k++ ) {
|
|
const idSoundSample *objectp = leadins[k];
|
|
if ( objectp ) {
|
|
common->Printf( " %5dms %4dKb %s (LEADIN)\n", soundSystemLocal.SamplesToMilliseconds(objectp->LengthIn44kHzSamples()), (objectp->objectMemSize/1024)
|
|
,objectp->name.c_str() );
|
|
}
|
|
}
|
|
for( int k = 0; k < numEntries; k++ ) {
|
|
const idSoundSample *objectp = entries[k];
|
|
if ( objectp ) {
|
|
common->Printf( " %5dms %4dKb %s\n", soundSystemLocal.SamplesToMilliseconds(objectp->LengthIn44kHzSamples()), (objectp->objectMemSize/1024)
|
|
,objectp->name.c_str() );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetAltSound
|
|
===============
|
|
*/
|
|
const idSoundShader *idSoundShader::GetAltSound( void ) const {
|
|
return altSound;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetMinDistance
|
|
===============
|
|
*/
|
|
float idSoundShader::GetMinDistance() const {
|
|
return parms.minDistance;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetMaxDistance
|
|
===============
|
|
*/
|
|
float idSoundShader::GetMaxDistance() const {
|
|
return parms.maxDistance;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetDescription
|
|
===============
|
|
*/
|
|
const char *idSoundShader::GetDescription() const {
|
|
return desc;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::HasDefaultSound
|
|
===============
|
|
*/
|
|
bool idSoundShader::HasDefaultSound() const {
|
|
for ( int i = 0; i < numEntries; i++ ) {
|
|
if ( entries[i] && entries[i]->defaultSound ) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetParms
|
|
===============
|
|
*/
|
|
const soundShaderParms_t *idSoundShader::GetParms() const {
|
|
return &parms;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetNumSounds
|
|
===============
|
|
*/
|
|
int idSoundShader::GetNumSounds() const {
|
|
return numLeadins + numEntries;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idSoundShader::GetSound
|
|
===============
|
|
*/
|
|
const char *idSoundShader::GetSound( int index ) const {
|
|
if ( index >= 0 ) {
|
|
if ( index < numLeadins ) {
|
|
return leadins[index]->name.c_str();
|
|
}
|
|
index -= numLeadins;
|
|
if ( index < numEntries ) {
|
|
return entries[index]->name.c_str();
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
===============
|
|
idSoundShader::IsVO_ForPlayer
|
|
===============
|
|
*/
|
|
bool idSoundShader::IsVO_ForPlayer() const
|
|
{
|
|
return (parms.soundShaderFlags & SSF_VO_FOR_PLAYER) != 0;
|
|
}
|
|
#endif |