/* * S_Frame */ void S_Frame(void) { s_channel_t *ch; int i, j; if (!s_env.initialized) return; S_FrameMusic(); if (cls.state != CL_ACTIVE) { if (Mix_Playing(-1) > 0) S_Stop(); return; } if (s_reverse->modified) { // update reverse stereo Mix_SetReverseStereo(MIX_CHANNEL_POST, s_reverse->integer); s_reverse->modified = false; } // update spatialization for current sounds ch = s_env.channels; for (i = 0; i < MAX_CHANNELS; i++, ch++) { if (!ch->sample) continue; // reset channel's count for loop samples ch->count = 0; S_SpatializeChannel(ch); } // add new dynamic sounds for (i = 0; i < cl.frame.num_entities; i++) { const int e = (cl.frame.entity_state + i) & ENTITY_STATE_MASK; const entity_state_t *ent = &cl.entity_states[e]; if (!ent->sound) continue; for (j = 0; j < MAX_CHANNELS; j++) { if (s_env.channels[j].ent_num == ent->number) break; } if (j == MAX_CHANNELS) S_PlaySample(NULL, ent->number, cl.sound_precache[ent->sound], ATTN_NORM); } if (cl.underwater) // add under water sample if appropriate S_LoopSample(r_view.origin, S_LoadSample("world/under_water")); // reset the update flag s_env.update = false; }
/** * @brief does what the name implies in just one function to avoid exposing s_sample_t * @param s name of the sample * @param origin where to play it * @param attenuation how to reduce volume by distance * @param volume well, the volume */ bool S_LoadAndPlaySample (const char *s, const vec3_t origin, float attenuation, float volume) { s_sample_t *sample = S_LoadSample(s); if (!sample) return false; S_PlaySample(origin, sample, attenuation, volume); return true; }
/** * @brief Plays a sample without spatialization * @param[in] name The sample name * @param[in] relVolume Max mixer volume factor (0.0 - 1.0) * @sa S_PlaySample * @sa S_LoadSample */ void S_StartLocalSample (const char* name, float relVolume) { s_sample_t* sample; if (!s_env.initialized) return; sample = S_LoadSample(name); if (!sample) { Com_Printf("S_StartLocalSample: Failed to load %s\n", name); return; } S_PlaySample(nullptr, sample, SOUND_ATTN_NORM, relVolume); }
/* * S_StartLocalSample */ void S_StartLocalSample(const char *name) { s_sample_t *sample; if (!s_env.initialized) return; sample = S_LoadSample(name); if (!sample) { Com_Warn("S_StartLocalSample: Failed to load %s.\n", name); return; } S_PlaySample(NULL, cl.player_num + 1, sample, ATTN_NONE); }
/* * @brief */ static void Cl_ParseSound(void) { vec3_t origin; vec_t *org; uint16_t index; uint16_t ent_num; int32_t atten; int32_t flags; flags = Net_ReadByte(&net_message); if ((index = Net_ReadByte(&net_message)) > MAX_SOUNDS) Com_Error(ERR_DROP, "Bad index (%d)\n", index); if (flags & S_ATTEN) atten = Net_ReadByte(&net_message); else atten = ATTEN_DEFAULT; if (flags & S_ENTNUM) { // entity relative ent_num = Net_ReadShort(&net_message); if (ent_num > MAX_EDICTS) Com_Error(ERR_DROP, "Bad entity number (%d)\n", ent_num); } else { ent_num = 0; } if (flags & S_ORIGIN) { // positioned in space Net_ReadPosition(&net_message, origin); org = origin; } else // use ent_num org = NULL; if (!cl.sound_precache[index]) return; S_PlaySample(org, ent_num, cl.sound_precache[index], atten); }
/** * @brief plays one of the precached samples * @param sId ID of the sample * @param origin where to play it * @param attenuation how to reduce volume by distance * @param volume well, the volume */ void S_PlayStdSample (const stdsound_t sId, const vec3_t origin, float attenuation, float volume) { S_PlaySample(origin, stdSoundPool[sId], attenuation, volume); }