#include "quakedef.h" #ifdef USE_FMOD #include "fmod.h" #include "fmod_errors.h" FMOD_SYSTEM *fmod_system = NULL; #if 1 //void S_Init(void) //{ // // Register cvars (see snd_dma.c) and check parameters // // Call S_Startup // // Call S_StopAllSounds(true) // // // Note: could actually keep the original S_Init from snd_dma.c and have it call the above functions in here //} void S_Startup(void) { // Create FMOD System if it doesn't exist already // Create SFX channel group // Could use System::set3DRolloffCallback to set up a (attenuation / sound_nominal_clip_dist) distance multiplier (would need to use ChannelControl::setUserData to hold ref to attn value) // Note: sound_nominal_clip_dist could be dynamic to allow a small sound 'bubble' for local multiplayer // Set sound_started to true Con_DPrintf("[FMOD] Startup\n"); } void S_Shutdown(void) { // Destroy SFX channel group // If we created FMOD System (and consequently own it), destroy it here Con_DPrintf("[FMOD] Shutdown\n"); } void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) { // Find channel group for entity number (or create) => note entnum can also be some random hash value // ChannelControl::setMode => set to 3D // Pre-define channels for each entity (could be an array of ints, probably array of entchannel_t structs) // For entchannel 0, dynamically select a free channel (or just play without doing anything, let FMOD handle it) // If channel at index entchannel >0 is already playing: stop // Special case entchannel -1 => just play locally on listener, no 3D // System::playSound with paused = true // ChannelControl::set3DAttributes // Use ChannelControl::setDelay and ChannelControl::getDSPClock to add a delay to move sounds out of phase if necessary // ChannelControl::setPaused = false // Store channel handle at position entchannel if (sfx) Con_DPrintf("[FMOD] Start sound %s for entity %d channel %d\n", sfx->name, entnum, entchannel); else Con_DPrintf("[FMOD] Start sound NULL for entity %d channel %d\n", entnum, entchannel); } void S_StaticSound(sfx_t *sfx, vec3_t origin, float vol, float attenuation) { // Similar to above, but without the per-entity channel group song and dance // Check if sound is looped (should be) and FMOD_Channel_SetMode to looped // Set Channel::setLoopPoints if the sfxcache specifies something non-standard if (sfx) Con_DPrintf("[FMOD] Static sound: %s\n", sfx->name); else Con_DPrintf("[FMOD] Static sound: NULL\n"); } void S_StopSound(int entnum, int entchannel) { Con_DPrintf("[FMOD] Stop sound for entity %d channel %d\n", entnum, entchannel); } void S_StopAllSounds(qboolean clear) { } void S_ClearBuffer(void) { } void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) { // System::set3DListenerAttributes FMOD_System_Update(fmod_system); } void S_ExtraUpdate(void) { FMOD_System_Update(fmod_system); } static void S_SetMasterMute(FMOD_BOOL mute) { FMOD_CHANNELGROUP *master; if (!fmod_system) return; FMOD_System_GetMasterChannelGroup(fmod_system, &master); FMOD_ChannelGroup_SetMute(master, mute); } void S_BlockSound(void) { S_SetMasterMute(1); } void S_UnblockSound(void) { S_SetMasterMute(0); } sfx_t *S_PrecacheSound(const char *sample) { // System::createSound with FMOD_3D (sfx_t will need a pointer to FMOD_Sound) // Might need to set rate and width? FMOD can probably figure this out by itself based on the WAV file contents Con_DPrintf("[FMOD] Precaching sound: %s\n", sample); return NULL; } void S_TouchSound(const char *sample) { } #endif #endif // USE_FMOD