/* ================ idDeclParticle::ParseParms Parses a variable length list of parms on one line ================ */ void idDeclParticle::ParseParms( idLexer &src, float *parms, int maxParms ) { idToken token; memset( parms, 0, maxParms * sizeof( *parms ) ); int count = 0; while( 1 ) { if ( !src.ReadTokenOnLine( &token ) ) { return; } if ( count == maxParms ) { src.Error( "too many parms on line" ); return; } token.StripQuotes(); parms[count] = atof( token ); count++; } }
/* =============== idSoundShader::ParseShader =============== */ bool idSoundShader::ParseShader( idLexer &src ) { int i; idToken token; parms.minDistance = 1; parms.maxDistance = 10; parms.volume = 1; parms.shakes = 0; parms.soundShaderFlags = 0; parms.soundClass = 0; 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 else if ( token == "}" ) { break; } // minimum number of sounds else if ( !token.Icmp( "minSamples" ) ) { maxSamples = idMath::ClampInt( src.ParseInt(), SOUND_MAX_LIST_WAVS, maxSamples ); } // 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; } } // reverb else if ( !token.Icmp( "reverb" ) ) { int reg0 = src.ParseFloat(); if ( !src.ExpectTokenString( "," ) ) { src.FreeSource(); return false; } int reg1 = src.ParseFloat(); // no longer supported } // volume else if ( !token.Icmp( "volume" ) ) { parms.volume = src.ParseFloat(); } // 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 mask else if ( !token.Icmp( "mask_center" ) ) { speakerMask |= 1<<SPEAKER_CENTER; } // speaker mask else if ( !token.Icmp( "mask_left" ) ) { speakerMask |= 1<<SPEAKER_LEFT; } // speaker mask else if ( !token.Icmp( "mask_right" ) ) { speakerMask |= 1<<SPEAKER_RIGHT; } // speaker mask else if ( !token.Icmp( "mask_backright" ) ) { speakerMask |= 1<<SPEAKER_BACKRIGHT; } // speaker mask else if ( !token.Icmp( "mask_backleft" ) ) { speakerMask |= 1<<SPEAKER_BACKLEFT; } // speaker mask else if ( !token.Icmp( "mask_lfe" ) ) { speakerMask |= 1<<SPEAKER_LFE; } // soundClass else if ( !token.Icmp( "soundClass" ) ) { parms.soundClass = src.ParseInt(); if ( parms.soundClass < 0 || parms.soundClass >= SOUND_MAX_CLASSES ) { src.Warning( "SoundClass out of range" ); return false; } } // altSound else if ( !token.Icmp( "altSound" ) ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } altSound = declManager->FindSound( token.c_str() ); } // ordered else if ( !token.Icmp( "ordered" ) ) { // no longer supported } // 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 else if ( !token.Icmp( "plain" ) ) { // no longer supported } // looping else if ( !token.Icmp( "looping" ) ) { parms.soundShaderFlags |= SSF_LOOPING; } // no occlusion else if ( !token.Icmp( "no_occlusion" ) ) { parms.soundShaderFlags |= SSF_NO_OCCLUSION; } // 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; } // 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; } // the wave files else if ( !token.Icmp( "leadin" ) ) { // add to the leadin list if ( !src.ReadToken( &token ) ) { src.Warning( "Expected sound after leadin" ); return false; } if ( soundSystemLocal.soundCache && numLeadins < maxSamples ) { leadins[ numLeadins ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand ); numLeadins++; } } else if ( token.Find( ".wav", false ) != -1 || token.Find( ".ogg", false ) != -1 ) { // add to the wav list if ( soundSystemLocal.soundCache && numEntries < maxSamples ) { token.BackSlashesToSlashes(); 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; } } } entries[ numEntries ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand ); numEntries++; } } else { src.Warning( "unknown token '%s'", token.c_str() ); return false; } } if ( parms.shakes > 0.0f ) { CheckShakesAndOgg(); } return true; }
bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) { idToken name, token; if ( !src.ReadToken( &token ) ) return false; // reverb effect if ( token != "reverb" ) { // other effect (not supported at the moment) src.Error( "idEFXFile::ReadEffect: Unknown effect definition" ); return false; } src.ReadTokenOnLine( &token ); name = token; if ( !src.ReadToken( &token ) ) return false; if ( token != "{" ) { src.Error( "idEFXFile::ReadEffect: { not found, found %s", token.c_str() ); return false; } ALenum err; alGetError(); EFXprintf("Loading EFX effect '%s' (#%u)\n", name.c_str(), effect->effect); do { if ( !src.ReadToken( &token ) ) { src.Error( "idEFXFile::ReadEffect: EOF without closing brace" ); return false; } if ( token == "}" ) { effect->name = name; break; } if ( token == "environment" ) { // <+KittyCat> the "environment" token should be ignored (efx has nothing equatable to it) src.ParseInt(); } else if ( token == "environment size" ) { float size = src.ParseFloat(); efxf(AL_EAXREVERB_DENSITY, (size < 2.0f) ? (size - 1.0f) : 1.0f); } else if ( token == "environment diffusion" ) { efxf(AL_EAXREVERB_DIFFUSION, src.ParseFloat()); } else if ( token == "room" ) { efxf(AL_EAXREVERB_GAIN, mB_to_gain(src.ParseInt(), GAIN)); } else if ( token == "room hf" ) { efxf(AL_EAXREVERB_GAINHF, mB_to_gain(src.ParseInt(), GAINHF)); } else if ( token == "room lf" ) { efxf(AL_EAXREVERB_GAINLF, mB_to_gain(src.ParseInt(), GAINLF)); } else if ( token == "decay time" ) { efxf(AL_EAXREVERB_DECAY_TIME, src.ParseFloat()); } else if ( token == "decay hf ratio" ) { efxf(AL_EAXREVERB_DECAY_HFRATIO, src.ParseFloat()); } else if ( token == "decay lf ratio" ) { efxf(AL_EAXREVERB_DECAY_LFRATIO, src.ParseFloat()); } else if ( token == "reflections" ) { efxf(AL_EAXREVERB_REFLECTIONS_GAIN, mB_to_gain(src.ParseInt(), REFLECTIONS_GAIN)); } else if ( token == "reflections delay" ) { efxf(AL_EAXREVERB_REFLECTIONS_DELAY, src.ParseFloat()); } else if ( token == "reflections pan" ) { efxfv(AL_EAXREVERB_REFLECTIONS_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat()); } else if ( token == "reverb" ) { efxf(AL_EAXREVERB_LATE_REVERB_GAIN, mB_to_gain(src.ParseInt(), LATE_REVERB_GAIN)); } else if ( token == "reverb delay" ) { efxf(AL_EAXREVERB_LATE_REVERB_DELAY, src.ParseFloat()); } else if ( token == "reverb pan" ) { efxfv(AL_EAXREVERB_LATE_REVERB_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat()); } else if ( token == "echo time" ) { efxf(AL_EAXREVERB_ECHO_TIME, src.ParseFloat()); } else if ( token == "echo depth" ) { efxf(AL_EAXREVERB_ECHO_DEPTH, src.ParseFloat()); } else if ( token == "modulation time" ) { efxf(AL_EAXREVERB_MODULATION_TIME, src.ParseFloat()); } else if ( token == "modulation depth" ) { efxf(AL_EAXREVERB_MODULATION_DEPTH, src.ParseFloat()); } else if ( token == "air absorption hf" ) { efxf(AL_EAXREVERB_AIR_ABSORPTION_GAINHF, mB_to_gain(src.ParseFloat(), AIR_ABSORPTION_GAINHF)); } else if ( token == "hf reference" ) { efxf(AL_EAXREVERB_HFREFERENCE, src.ParseFloat()); } else if ( token == "lf reference" ) { efxf(AL_EAXREVERB_LFREFERENCE, src.ParseFloat()); } else if ( token == "room rolloff factor" ) { efxf(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, src.ParseFloat()); } else if ( token == "flags" ) { src.ReadTokenOnLine( &token ); unsigned int flags = token.GetUnsignedLongValue(); efxi(AL_EAXREVERB_DECAY_HFLIMIT, (flags & 0x20) ? AL_TRUE : AL_FALSE); // the other SCALE flags have no equivalent in efx } else { src.ReadTokenOnLine( &token ); src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" ); } } while ( 1 ); return true; }
/* =============== idEFXFile::ReadEffect =============== */ bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) { idToken name, token; if ( !src.ReadToken( &token ) ) return false; // reverb effect if ( token == "reverb" ) { EAXREVERBPROPERTIES *reverb = ( EAXREVERBPROPERTIES * )Mem_Alloc( sizeof( EAXREVERBPROPERTIES ) ); if ( reverb ) { src.ReadTokenOnLine( &token ); name = token; if ( !src.ReadToken( &token ) ) { Mem_Free( reverb ); return false; } if ( token != "{" ) { src.Error( "idEFXFile::ReadEffect: { not found, found %s", token.c_str() ); Mem_Free( reverb ); return false; } do { if ( !src.ReadToken( &token ) ) { src.Error( "idEFXFile::ReadEffect: EOF without closing brace" ); Mem_Free( reverb ); return false; } if ( token == "}" ) { effect->name = name; effect->data = ( void * )reverb; effect->datasize = sizeof( EAXREVERBPROPERTIES ); break; } if ( token == "environment" ) { src.ReadTokenOnLine( &token ); reverb->ulEnvironment = token.GetUnsignedIntValue(); } else if ( token == "environment size" ) { reverb->flEnvironmentSize = src.ParseFloat(); } else if ( token == "environment diffusion" ) { reverb->flEnvironmentDiffusion = src.ParseFloat(); } else if ( token == "room" ) { reverb->lRoom = src.ParseInt(); } else if ( token == "room hf" ) { reverb->lRoomHF = src.ParseInt(); } else if ( token == "room lf" ) { reverb->lRoomLF = src.ParseInt(); } else if ( token == "decay time" ) { reverb->flDecayTime = src.ParseFloat(); } else if ( token == "decay hf ratio" ) { reverb->flDecayHFRatio = src.ParseFloat(); } else if ( token == "decay lf ratio" ) { reverb->flDecayLFRatio = src.ParseFloat(); } else if ( token == "reflections" ) { reverb->lReflections = src.ParseInt(); } else if ( token == "reflections delay" ) { reverb->flReflectionsDelay = src.ParseFloat(); } else if ( token == "reflections pan" ) { reverb->vReflectionsPan.x = src.ParseFloat(); reverb->vReflectionsPan.y = src.ParseFloat(); reverb->vReflectionsPan.z = src.ParseFloat(); } else if ( token == "reverb" ) { reverb->lReverb = src.ParseInt(); } else if ( token == "reverb delay" ) { reverb->flReverbDelay = src.ParseFloat(); } else if ( token == "reverb pan" ) { reverb->vReverbPan.x = src.ParseFloat(); reverb->vReverbPan.y = src.ParseFloat(); reverb->vReverbPan.z = src.ParseFloat(); } else if ( token == "echo time" ) { reverb->flEchoTime = src.ParseFloat(); } else if ( token == "echo depth" ) { reverb->flEchoDepth = src.ParseFloat(); } else if ( token == "modulation time" ) { reverb->flModulationTime = src.ParseFloat(); } else if ( token == "modulation depth" ) { reverb->flModulationDepth = src.ParseFloat(); } else if ( token == "air absorption hf" ) { reverb->flAirAbsorptionHF = src.ParseFloat(); } else if ( token == "hf reference" ) { reverb->flHFReference = src.ParseFloat(); } else if ( token == "lf reference" ) { reverb->flLFReference = src.ParseFloat(); } else if ( token == "room rolloff factor" ) { reverb->flRoomRolloffFactor = src.ParseFloat(); } else if ( token == "flags" ) { src.ReadTokenOnLine( &token ); reverb->ulFlags = token.GetUnsignedIntValue(); } else { src.ReadTokenOnLine( &token ); src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" ); Mem_Free( reverb ); } } while ( 1 ); return true; } } else { // other effect (not supported at the moment) src.Error( "idEFXFile::ReadEffect: Unknown effect definition" ); } return false; }
/* =============== idSoundShader::ParseShader =============== */ bool idSoundShader::ParseShader( idLexer &src ) { idToken token; parms.minDistance = 1; parms.maxDistance = 10; parms.volume = 1; parms.shakes = 0; parms.soundShaderFlags = 0; parms.soundClass = 0; speakerMask = 0; altSound = NULL; entries.Clear(); while ( 1 ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } // end of definition else if ( token == "}" ) { break; } // minimum number of sounds else if ( !token.Icmp( "minSamples" ) ) { src.ParseInt(); } // description else if ( !token.Icmp( "description" ) ) { src.ReadTokenOnLine( &token ); } // 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; } } // reverb else if ( !token.Icmp( "reverb" ) ) { src.ParseFloat(); if ( !src.ExpectTokenString( "," ) ) { src.FreeSource(); return false; } src.ParseFloat(); // no longer supported } // volume else if ( !token.Icmp( "volume" ) ) { parms.volume = src.ParseFloat(); } // 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(); leadin = true; } // speaker mask else if ( !token.Icmp( "mask_center" ) ) { speakerMask |= 1<<SPEAKER_CENTER; } // speaker mask else if ( !token.Icmp( "mask_left" ) ) { speakerMask |= 1<<SPEAKER_LEFT; } // speaker mask else if ( !token.Icmp( "mask_right" ) ) { speakerMask |= 1<<SPEAKER_RIGHT; } // speaker mask else if ( !token.Icmp( "mask_backright" ) ) { speakerMask |= 1<<SPEAKER_BACKRIGHT; } // speaker mask else if ( !token.Icmp( "mask_backleft" ) ) { speakerMask |= 1<<SPEAKER_BACKLEFT; } // speaker mask else if ( !token.Icmp( "mask_lfe" ) ) { speakerMask |= 1<<SPEAKER_LFE; } // soundClass else if ( !token.Icmp( "soundClass" ) ) { parms.soundClass = src.ParseInt(); if ( parms.soundClass < 0 || parms.soundClass >= SOUND_MAX_CLASSES ) { src.Warning( "SoundClass out of range" ); return false; } } // altSound else if ( !token.Icmp( "altSound" ) ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } altSound = declManager->FindSound( token.c_str() ); } // ordered else if ( !token.Icmp( "ordered" ) ) { // no longer supported } // 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 else if ( !token.Icmp( "plain" ) ) { // no longer supported } // looping else if ( !token.Icmp( "looping" ) ) { parms.soundShaderFlags |= SSF_LOOPING; } // no occlusion else if ( !token.Icmp( "no_occlusion" ) ) { parms.soundShaderFlags |= SSF_NO_OCCLUSION; } // 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; } else if ( !token.Icmp( "onDemand" ) ) { // no longer loading sounds on demand } // the wave files else if ( !token.Icmp( "leadin" ) ) { leadin = true; } else if ( token.Find( ".wav", false ) != -1 || token.Find( ".ogg", false ) != -1 ) { if ( token.IcmpPrefixPath( "sound/vo/" ) == 0 || token.IcmpPrefixPath( "sound/guis/" ) == 0 ) { parms.soundShaderFlags |= SSF_VO; } if ( token.IcmpPrefixPath( "sound/musical/" ) == 0 ) { parms.soundShaderFlags |= SSF_MUSIC; } // add to the wav list if ( s_maxSamples.GetInteger() == 0 || ( s_maxSamples.GetInteger() > 0 && entries.Num() < s_maxSamples.GetInteger() ) ) { entries.Append( soundSystemLocal.LoadSample( token.c_str() ) ); } } else { src.Warning( "unknown token '%s'", token.c_str() ); return false; } } return true; }