diff --git a/src/engine/audio/defines.cpp b/src/engine/audio/defines.cpp index 64b1991d7..cbff12ee3 100644 --- a/src/engine/audio/defines.cpp +++ b/src/engine/audio/defines.cpp @@ -14,6 +14,8 @@ Uint32 numsounds = 0; +bool levelmusicplaying = false; // seems to be common to all sound libraries + #ifdef USE_FMOD FMOD::System* fmod_system = nullptr; @@ -55,7 +57,6 @@ FMOD::Sound* hamletmusic = nullptr; FMOD::Sound* tutorialmusic = nullptr; FMOD::Sound* gameovermusic = nullptr; FMOD::Sound* introstorymusic = nullptr; -bool levelmusicplaying = false; FMOD::Channel* music_channel = nullptr; FMOD::Channel* music_channel2 = nullptr; @@ -78,4 +79,29 @@ bool sfxUseDynamicAmbientVolume = true; bool sfxUseDynamicEnvironmentVolume = true; void* fmod_extraDriverData = nullptr; -#endif //USE_FMOD + +#elif defined USE_OPENAL + + +OPENAL_BUFFER* introductionmusic = nullptr; + +OPENAL_BUFFER** intromusic = nullptr; +OPENAL_BUFFER** minesmusic = nullptr; +OPENAL_BUFFER** swampmusic = nullptr; +OPENAL_BUFFER** labyrinthmusic = nullptr; +OPENAL_BUFFER** ruinsmusic = nullptr; +OPENAL_BUFFER** underworldmusic = nullptr; +OPENAL_BUFFER** hellmusic = nullptr; + +OPENAL_SOUND* music_channel = nullptr; +OPENAL_SOUND* music_channel2 = nullptr; +OPENAL_SOUND* music_resume = nullptr; + +OPENAL_CHANNELGROUP *sound_group = nullptr; +OPENAL_CHANNELGROUP *soundAmbient_group = nullptr; +OPENAL_CHANNELGROUP *soundEnvironment_group = nullptr; +OPENAL_CHANNELGROUP *soundNotification_group = nullptr; +OPENAL_CHANNELGROUP *music_group = nullptr; +OPENAL_CHANNELGROUP *music_notification_group = nullptr; + +#endif diff --git a/src/engine/audio/music.cpp b/src/engine/audio/music.cpp index 3acd502df..579359fdc 100644 --- a/src/engine/audio/music.cpp +++ b/src/engine/audio/music.cpp @@ -75,6 +75,28 @@ bool loadMusic() intromusic = (FMOD::Sound**)malloc(sizeof(FMOD::Sound*) * NUMINTROMUSIC); memset(intromusic, 0, sizeof(FMOD::Sound*) * NUMINTROMUSIC); } +#elif defined USE_OPENAL + minesmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(minesmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + swampmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(swampmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + labyrinthmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(labyrinthmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + ruinsmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(ruinsmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + underworldmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(underworldmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + hellmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(hellmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + minotaurmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(minotaurmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + cavesmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(cavesmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + citadelmusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(citadelmusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + intromusic = (OPENAL_BUFFER**)malloc(sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + memset(intromusic, 0, sizeof(OPENAL_BUFFER*) * NUMMINESMUSIC); + #endif bool introMusicChanged; @@ -442,6 +464,392 @@ void handleLevelMusic() playMusic(tutorialmusic, true, true, true); } else + { + playMusic(intermissionmusic, true, true, true); + } + olddarkmap = darkmap; + levelmusicplaying = true; + devilmusicplaying = false; + herxmusicplaying = false; + minotaurmusicplaying = false; + combatmusicplaying = false; + shopmusicplaying = false; + fadein_increment = default_fadein_increment; + fadeout_increment = default_fadeout_increment; + } + else if ( (!devilmusicplaying || !playing) && devilaround ) + { + playMusic(devilmusic, true, true, true); + levelmusicplaying = false; + devilmusicplaying = true; + herxmusicplaying = false; + minotaurmusicplaying = false; + combatmusicplaying = false; + shopmusicplaying = false; + fadein_increment = default_fadein_increment * 2; + fadeout_increment = default_fadeout_increment * 2; + } + else if ( (!herxmusicplaying || !playing) && !devilaround && herxaround ) + { + playMusic(herxmusic, true, true, true); + levelmusicplaying = false; + devilmusicplaying = false; + herxmusicplaying = true; + minotaurmusicplaying = false; + combatmusicplaying = false; + shopmusicplaying = false; + fadein_increment = default_fadein_increment * 2; + fadeout_increment = default_fadeout_increment * 2; + } + else if ( (!minotaurmusicplaying || !playing) && !herxaround && activeminotaur && strcmp(map.name, "Hell Boss") ) + { + playMusic(minotaurmusic[0], true, true, true); + levelmusicplaying = false; + devilmusicplaying = false; + herxmusicplaying = false; + minotaurmusicplaying = true; + combatmusicplaying = false; + shopmusicplaying = false; + fadein_increment = default_fadein_increment * 5; + fadeout_increment = default_fadeout_increment * 5; + } + else if ( (!sanctummusicplaying || !playing) && magisteraround ) + { + playMusic(sanctummusic, true, true, true); + levelmusicplaying = false; + devilmusicplaying = false; + herxmusicplaying = false; + minotaurmusicplaying = false; + combatmusicplaying = false; + sanctummusicplaying = true; + shopmusicplaying = false; + fadein_increment = default_fadein_increment * 2; + fadeout_increment = default_fadeout_increment * 2; + } + else if ( (!combatmusicplaying || !playing) + && !herxaround + && !activeminotaur + && combat + && strcmp(map.name, "Hell Boss") + && strcmp(map.name, "Sanctum") ) + { + if ( !strncmp(map.name, "The Swamp", 9) || !strncmp(map.name, "The Temple", 10) ) // the swamp + { + playMusic(swampmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "The Labyrinth", 13) || strstr(map.name, "Minotaur") ) // the labyrinth + { + playMusic(labyrinthmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "The Ruins", 9) ) // the ruins + { + playMusic(ruinsmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "Underworld", 10) ) // the underworld + { + playMusic(underworldmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "Hell", 4) ) // hell + { + playMusic(hellmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "Caves", 5) || !strcmp(map.name, "Cockatrice Lair") ) + { + playMusic(cavesmusic[0], true, true, true); + } + else if ( !strncmp(map.name, "Citadel", 7) || !strcmp(map.name, "Bram's Castle") ) + { + playMusic(citadelmusic[0], true, true, true); + } + else + { + playMusic(minesmusic[0], true, true, true); + } + levelmusicplaying = false; + devilmusicplaying = false; + herxmusicplaying = false; + combatmusicplaying = true; + shopmusicplaying = false; + minotaurmusicplaying = false; + fadein_increment = default_fadein_increment * 4; + fadeout_increment = default_fadeout_increment; + } + else if ( (!shopmusicplaying || !playing) && !herxaround && !activeminotaur && !combat && inshop ) + { + playMusic(shopmusic, true, true, true); + levelmusicplaying = false; + devilmusicplaying = false; + herxmusicplaying = false; + minotaurmusicplaying = false; + combatmusicplaying = false; + shopmusicplaying = true; + fadein_increment = default_fadein_increment * 4; + fadeout_increment = default_fadeout_increment; + } +} + +#elif defined USE_OPENAL + +void handleLevelMusic() +{ + if (no_sound) + { + return; + } +#ifndef SOUND + return; +#endif +#ifndef MUSIC + return; +#endif + bool inshop = false; + if (players[clientnum] && players[clientnum]->entity) + { + int x = (int)players[clientnum]->entity->x / 16; + int y = (int)players[clientnum]->entity->y / 16; + if ( x >= 0 && x < map.width && y >= 0 && y < map.height ) + if ( shoparea[y + x * map.height] ) + { + inshop = true; + } + } + + bool devilaround = false; + bool activeminotaur = false; + bool herxaround = false; + bool magisteraround = false; + node_t* node; + for ( node = map.creatures->first; node != NULL; node = node->next ) + { + Entity* entity = (Entity*)node->element; + if ( entity->sprite == 274 ) // herx head + { + herxaround = true; + break; + } + else if ( entity->sprite == 304 ) // devil body + { + devilaround = true; + break; + } + else if ( entity->sprite == 239 ) // minotaur head + { + activeminotaur = true; + break; + } + else if ( entity->sprite == 646 || entity->sprite == 650 ) // magister body + { + magisteraround = true; + break; + } + } + + ALboolean playing = true; + if (music_channel) + OPENAL_Channel_IsPlaying(music_channel, &playing); + + + if ( currenttrack == -1 ) + { + currenttrack = local_rng.rand(); + } + + if ( (!levelmusicplaying || !playing || olddarkmap != darkmap) + && (!combat || !strcmp(map.name, "Hell Boss")) + && !inshop + && (!activeminotaur || !strcmp(map.name, "Hell Boss")) && !herxaround && !devilaround && !magisteraround ) + { + if ( !strncmp(map.name, "The Mines", 9) ) // the mines + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMMINESMUSIC - 1); + } + currenttrack = currenttrack % NUMMINESMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(minesmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "The Swamp", 9) ) // the swamp + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMSWAMPMUSIC - 1); + } + currenttrack = currenttrack % NUMSWAMPMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(swampmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "The Labyrinth", 13) ) // the labyrinth + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMLABYRINTHMUSIC - 1); + } + currenttrack = currenttrack % NUMLABYRINTHMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(labyrinthmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "The Ruins", 9) ) // the ruins + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMRUINSMUSIC - 1); + } + currenttrack = currenttrack % NUMRUINSMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(ruinsmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "Underworld", 10) ) // the underworld + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMUNDERWORLDMUSIC - 1); + } + currenttrack = currenttrack % NUMUNDERWORLDMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(underworldmusic[currenttrack], false, true, true); + } + else if ( !strcmp(map.name, "Minetown") ) // minetown + { + playMusic(minetownmusic, true, true, true); + } + else if ( !strcmp(map.name, "The Gnomish Mines") ) + { + if ( gnomishminesmusic ) + { + playMusic(gnomishminesmusic, true, true, true); + } + else + { + playMusic(minetownmusic, true, true, true); + } + } + else if ( !strcmp(map.name, "The Haunted Castle") ) + { + if ( greatcastlemusic ) + { + playMusic(greatcastlemusic, true, true, true); + } + else + { + playMusic(intermissionmusic, true, true, true); + } + } + else if ( !strcmp(map.name, "Sokoban") ) + { + if ( sokobanmusic ) + { + playMusic(sokobanmusic, true, true, true); + } + else + { + playMusic(intermissionmusic, true, true, true); + } + } + else if ( !strcmp(map.name, "Cockatrice Lair") ) + { + if ( caveslairmusic ) + { + playMusic(caveslairmusic, true, true, true); + } + else + { + playMusic(cavesmusic[2], true, true, true); + } + } + else if ( !strcmp(map.name, "Bram's Castle") ) + { + if ( bramscastlemusic ) + { + playMusic(bramscastlemusic, true, true, true); + } + else + { + playMusic(citadelmusic[2], true, true, true); + } + } + else if ( !strcmp(map.name, "The Mystic Library") ) // mystic library + { + playMusic(librarymusic, true, true, true); + } + else if ( !strcmp(map.name, "The Minotaur Maze") ) // minotaur maze + { + playMusic(minotaurmusic[1], true, true, true); + } + else if ( !strcmp(map.name, "The Temple") ) // the temple + { + playMusic(templemusic, true, true, true); + } + else if ( !strcmp(map.name, "Hell Boss") ) // escape theme + { + playMusic(escapemusic, true, true, true); + } + else if ( !strncmp(map.name, "Hell", 4) ) // hell + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMHELLMUSIC - 1); + } + currenttrack = currenttrack % NUMHELLMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(hellmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "Caves", 5) ) + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMCAVESMUSIC - 1); + } + currenttrack = currenttrack % NUMCAVESMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(cavesmusic[currenttrack], false, true, true); + } + else if ( !strncmp(map.name, "Citadel", 7) || !strncmp(map.name, "Sanctum", 7) ) + { + if ( !playing ) + { + currenttrack = 1 + local_rng.rand() % (NUMCITADELMUSIC - 1); + } + currenttrack = currenttrack % NUMCITADELMUSIC; + if ( currenttrack == 0 ) + { + currenttrack = 1; + } + playMusic(citadelmusic[currenttrack], false, true, true); + } + else if ( !strcmp(map.name, "Mages Guild") ) + { + if ( hamletmusic ) + { + playMusic(hamletmusic, true, true, true); + } + else + { + playMusic(minesmusic[4], true, true, true); + } + } + else { playMusic(intermissionmusic, true, true, true); } @@ -565,4 +973,5 @@ void handleLevelMusic() fadeout_increment = default_fadeout_increment; } } + #endif diff --git a/src/engine/audio/sound.cpp b/src/engine/audio/sound.cpp index b591c3b9c..089406698 100644 --- a/src/engine/audio/sound.cpp +++ b/src/engine/audio/sound.cpp @@ -29,18 +29,6 @@ #endif #endif -#ifdef USE_FMOD -#elif defined USE_OPENAL -#else -void setGlobalVolume(real_t master, real_t music, real_t gameplay, real_t ambient, real_t environment, real_t notification) -{ - return; -} -void setAudioDevice(const std::string& device) -{ - return; -} -#endif #ifdef USE_FMOD @@ -328,36 +316,6 @@ void sound_update(int player, int index, int numplayers) #elif defined USE_OPENAL -struct OPENAL_BUFFER { - ALuint id; - bool stream; - char oggfile[64]; -}; -struct OPENAL_SOUND { - ALuint id; - OPENAL_CHANNELGROUP *group; - float volume; - OPENAL_BUFFER *buffer; - bool active; - char* oggdata; - int oggdata_length; - int ogg_seekoffset; - OggVorbis_File oggStream; - vorbis_info* vorbisInfo; - vorbis_comment* vorbisComment; - ALuint streambuff[4]; - bool loop; - bool stream_active; - int indice; -}; - -struct OPENAL_CHANNELGROUP { - float volume; - int num; - int cap; - OPENAL_SOUND **sounds; -}; - SDL_mutex *openal_mutex; static size_t openal_oggread(void* ptr, size_t size, size_t nmemb, void* datasource) { @@ -513,14 +471,7 @@ ALCdevice *openal_device = nullptr; //#define openal_maxchannels 100 OPENAL_BUFFER** sounds = nullptr; -Uint32 numsounds = 0; -OPENAL_BUFFER** minesmusic = NULL; -OPENAL_BUFFER** swampmusic = NULL; -OPENAL_BUFFER** labyrinthmusic = NULL; -OPENAL_BUFFER** ruinsmusic = NULL; -OPENAL_BUFFER** underworldmusic = NULL; -OPENAL_BUFFER** hellmusic = NULL; -OPENAL_BUFFER** intromusic = NULL; + OPENAL_BUFFER* intermissionmusic = NULL; OPENAL_BUFFER* minetownmusic = NULL; OPENAL_BUFFER* splashmusic = NULL; @@ -534,7 +485,6 @@ OPENAL_BUFFER* endgamemusic = NULL; OPENAL_BUFFER* devilmusic = NULL; OPENAL_BUFFER* escapemusic = NULL; OPENAL_BUFFER* sanctummusic = NULL; -OPENAL_BUFFER* introductionmusic = NULL; OPENAL_BUFFER** cavesmusic = NULL; OPENAL_BUFFER** citadelmusic = NULL; OPENAL_BUFFER* gnomishminesmusic = NULL; @@ -546,17 +496,6 @@ OPENAL_BUFFER* hamletmusic = NULL; OPENAL_BUFFER* tutorialmusic = nullptr; OPENAL_BUFFER* gameovermusic = nullptr; OPENAL_BUFFER* introstorymusic = nullptr; -bool levelmusicplaying = false; - -OPENAL_SOUND* music_channel = nullptr; -OPENAL_SOUND* music_channel2 = nullptr; -OPENAL_SOUND* music_resume = nullptr; - -OPENAL_CHANNELGROUP *sound_group = NULL; -OPENAL_CHANNELGROUP *soundAmbient_group = NULL; -OPENAL_CHANNELGROUP *soundEnvironment_group = NULL; -OPENAL_CHANNELGROUP *music_group = NULL; -OPENAL_CHANNELGROUP *music_notification_group = NULL; float fadein_increment = 0.002f; float default_fadein_increment = 0.002f; @@ -621,16 +560,24 @@ int OPENAL_ThreadFunction(void* data) { return 1; } +/** + * Initialize OpenAL library + * + * - Channel groups are initialized here + */ int initOPENAL() { static int initialized = 0; if(initialized) return 1; + printlog("[OpenAL]: initializing...\n"); + printlog("[OpenAL]: opening device...\n"); openal_device = alcOpenDevice(NULL); // preferred device if(!openal_device) return 0; + printlog("[OpenAL]: opening context...\n"); openal_context = alcCreateContext(openal_device,NULL); if(!openal_context) return 0; @@ -683,13 +630,15 @@ int initOPENAL() int closeOPENAL() { - if(OpenALSoundON) return 0; - + if(OpenALSoundON) + return 0; OpenALSoundON = false; + + printlog("[OpenAL]: closing...\n"); int i = 0; SDL_WaitThread(openal_soundthread, &i); if(i!=1) { - printlog("Warning, unable to stop Openal thread\n"); + printlog("[OpenAL]: unable to stop openal_soundthread thread\n"); } if(openal_mutex) { @@ -714,6 +663,26 @@ int closeOPENAL() return 1; } +/** + * taken from offical doc but not very "CPP" way + */ +int openalGetNumberOfDevices(const ALCchar *devices) +{ + const ALCchar *device = devices, *next = devices + 1; + size_t len = 0; + int num = 0; + + while (device && *device != '\0' && next && *next != '\0') { + //printlog("device detected: %s", device); + num += 1; + //fprintf(stdout, "%s\n", device); + len = strlen(device); + device += (len + 1); + next += (len + 2); + } + + return num; +} static int get_firstfreechannel() { @@ -734,7 +703,8 @@ static int get_firstfreechannel() return i; } -void setGlobalVolume(real_t master, real_t music, real_t gameplay, real_t ambient, real_t environment) { +void setGlobalVolume(real_t master, real_t music, real_t gameplay, real_t ambient, real_t environment, real_t notification) +{ master = std::min(std::max(0.0, master), 1.0); music = std::min(std::max(0.0, music / 4.0), 1.0); // music volume cut in half because the music is loud... gameplay = std::min(std::max(0.0, gameplay), 1.0); @@ -745,7 +715,11 @@ void setGlobalVolume(real_t master, real_t music, real_t gameplay, real_t ambien OPENAL_ChannelGroup_SetVolume(sound_group, master * gameplay); OPENAL_ChannelGroup_SetVolume(soundAmbient_group, master * ambient); OPENAL_ChannelGroup_SetVolume(soundEnvironment_group, master * environment); - OPENAL_ChannelGroup_SetVolume(music_notification_group, master * gameplay); + OPENAL_ChannelGroup_SetVolume(music_notification_group, master * notification); +} + +void setAudioDevice(const std::string& device){ + // TODO: implement device selection for OpenAL } void sound_update(int player, int index, int numplayers) @@ -977,7 +951,15 @@ int OPENAL_CreateSound(const char* name, bool b3D, OPENAL_BUFFER **buffer) { ov_clear(&oggFile); alGenBuffers(1, &(*buffer)->id); + ALenum al_error = alGetError(); + if (al_error != AL_NO_ERROR) { + printlog("OpenAL error: %d\n", al_error); + } alBufferData((*buffer)->id, (channels==1)?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, data2, sz, freq); + ALenum al_error2 = alGetError(); + if (al_error2 != AL_NO_ERROR) { + printlog("OpenAL error: %d\n", al_error2); + } if(data2!=data) free(data2); free(data); @@ -1113,11 +1095,27 @@ void OPENAL_Sound_GetLength(OPENAL_BUFFER* buffer, unsigned int *length) { void OPENAL_Sound_Release(OPENAL_BUFFER* buffer) { if(!buffer) return; - if(!buffer->stream) + if(!buffer->stream) { alDeleteBuffers( 1, &buffer->id ); + ALenum error = alGetError(); + if (error != AL_NO_ERROR) { + printlog("[OpenAL] error %d in alDeleteBuffers for buffer '%d' '%s'\n", error, buffer->id, buffer->oggfile); + return; + } + } free(buffer); } +#else // No FMOD or OpenAL + +void setGlobalVolume(real_t master, real_t music, real_t gameplay, real_t ambient, real_t environment, real_t notification) +{ +} + +void setAudioDevice(const std::string& device) +{ +} + #endif bool physfsSearchMusicToUpdate_helper_findModifiedMusic(uint32_t numMusic, const char* filenameTemplate) @@ -1258,6 +1256,42 @@ FMOD_RESULT physfsReloadMusic_helper_reloadMusicArray(uint32_t numMusic, const c return FMOD_OK; } +#elif defined USE_OPENAL +void physfsReloadMusic_helper_reloadMusicArray(uint32_t numMusic, const char* filenameTemplate, OPENAL_BUFFER** musicArray, bool reloadAll) +{ + for ( int c = 0; c < numMusic; c++ ) + { + snprintf(tempstr, 1000, filenameTemplate, c); + if ( PHYSFS_exists(tempstr) ) + { + printlog("[PhysFS]: Loading music file %s...", tempstr); + if ( musicArray ) + { + OPENAL_Sound_Release(musicArray[c]); + //musicArray[c]->release(); + } + if ( musicPreload ) + { + OPENAL_CreateSound(tempstr, false, &musicArray[c]); + //fmod_result = fmod_system->createSound(musicDir.c_str(), FMOD_2D, nullptr, &musicArray[c]); //TODO: Any other FMOD_MODEs should be used here? FMOD_SOFTWARE -> what now? FMOD_2D? LOOP? + } + else + { + OPENAL_CreateStreamSound(tempstr, &musicArray[c]); + //fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &musicArray[c]); //TODO: Any other FMOD_MODEs should be used here? FMOD_SOFTWARE -> what now? FMOD_2D? LOOP? + } + ALenum al_error2 = alGetError(); + /*if (fmod_result != FMOD_OK) + { + printlog("[PhysFS]: ERROR: Failed reloading music file \"%s\"."); + return; + }*/ + + } else { + printlog("[OpenAL]: fail to load music file %s...", tempstr); + } + } +} #endif void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This should probably return an error. @@ -1266,7 +1300,7 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { return; } -#ifdef SOUND +#ifdef MUSIC std::vector themeMusic; themeMusic.push_back("music/introduction.ogg"); @@ -1292,14 +1326,7 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho themeMusic.push_back("sound/ui/StoryMusicV3.ogg"); int index = 0; -#ifdef USE_OPENAL -#define FMOD_System_CreateStream(A, B, C, D, E) OPENAL_CreateStreamSound(B, E) //TODO: If this is still needed, it's probably now broke! -#define FMOD_SOUND OPENAL_BUFFER -#define fmod_system 0 -#define FMOD_SOFTWARE 0 -#define FMOD_Sound_Release OPENAL_Sound_Release int fmod_result; -#endif for ( std::vector::iterator it = themeMusic.begin(); it != themeMusic.end(); ++it ) { std::string filename = *it; @@ -1313,9 +1340,11 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho switch ( index ) { case 0: +#ifdef USE_FMOD if ( introductionmusic ) { introductionmusic->release(); + } if ( musicPreload ) { @@ -1325,8 +1354,16 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &introductionmusic); //TODO: FMOD_SOFTWARE -> what now? FMOD_2D? FMOD_LOOP_NORMAL? More things? Something else? } +#elif defined USE_OPENAL + if ( introductionmusic ) { + OPENAL_Sound_Release(introductionmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &introductionmusic); +#endif break; + case 1: +#ifdef USE_FMOD if ( intermissionmusic ) { intermissionmusic->release(); @@ -1339,8 +1376,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &intermissionmusic); } +#elif defined USE_OPENAL + if ( intermissionmusic ) { + OPENAL_Sound_Release(intermissionmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &intermissionmusic); +#endif break; case 2: +#ifdef USE_FMOD if ( minetownmusic ) { minetownmusic->release(); @@ -1353,8 +1397,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &minetownmusic); } +#elif defined USE_OPENAL + if ( minetownmusic ) { + OPENAL_Sound_Release(minetownmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &minetownmusic); +#endif break; case 3: +#ifdef USE_FMOD if ( splashmusic ) { splashmusic->release(); @@ -1367,8 +1418,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &splashmusic); } +#elif defined USE_OPENAL + if ( splashmusic ) { + OPENAL_Sound_Release(splashmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &splashmusic); +#endif break; case 4: +#ifdef USE_FMOD if ( librarymusic ) { librarymusic->release(); @@ -1381,8 +1439,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &librarymusic); } +#elif defined USE_OPENAL + if ( librarymusic ) { + OPENAL_Sound_Release(librarymusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &librarymusic); +#endif break; case 5: +#ifdef USE_FMOD if ( shopmusic ) { shopmusic->release(); @@ -1395,8 +1460,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &shopmusic); } +#elif defined USE_OPENAL + if ( shopmusic ) { + OPENAL_Sound_Release(shopmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &shopmusic); +#endif break; case 6: +#ifdef USE_FMOD if ( herxmusic ) { herxmusic->release(); @@ -1409,8 +1481,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &herxmusic); } +#elif defined USE_OPENAL + if ( herxmusic ) { + OPENAL_Sound_Release(herxmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &herxmusic); +#endif break; case 7: +#ifdef USE_FMOD if ( templemusic ) { templemusic->release(); @@ -1423,8 +1502,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &templemusic); } +#elif defined USE_OPENAL + if ( templemusic ) { + OPENAL_Sound_Release(templemusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &templemusic); +#endif break; case 8: +#ifdef USE_FMOD if ( endgamemusic ) { endgamemusic->release(); @@ -1437,8 +1523,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &endgamemusic); } +#elif defined USE_OPENAL + if ( endgamemusic ) { + OPENAL_Sound_Release(endgamemusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &endgamemusic); +#endif break; case 9: +#ifdef USE_FMOD if ( escapemusic ) { escapemusic->release(); @@ -1451,8 +1544,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &escapemusic); } +#elif defined USE_OPENAL + if ( escapemusic ) { + OPENAL_Sound_Release(escapemusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &escapemusic); +#endif break; case 10: +#ifdef USE_FMOD if ( devilmusic ) { devilmusic->release(); @@ -1465,8 +1565,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &devilmusic); } +#elif defined USE_OPENAL + if ( devilmusic ) { + OPENAL_Sound_Release(devilmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &devilmusic); +#endif break; case 11: +#ifdef USE_FMOD if ( sanctummusic ) { sanctummusic->release(); @@ -1479,8 +1586,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &sanctummusic); } +#elif defined USE_OPENAL + if ( sanctummusic ) { + OPENAL_Sound_Release(sanctummusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &sanctummusic); +#endif break; case 12: +#ifdef USE_FMOD if ( gnomishminesmusic ) { gnomishminesmusic->release(); @@ -1493,8 +1607,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &gnomishminesmusic); } +#elif defined USE_OPENAL + if ( gnomishminesmusic ) { + OPENAL_Sound_Release(gnomishminesmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &gnomishminesmusic); +#endif break; case 13: +#ifdef USE_FMOD if ( greatcastlemusic ) { greatcastlemusic->release(); @@ -1507,8 +1628,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &greatcastlemusic); } +#elif defined USE_OPENAL + if ( greatcastlemusic ) { + OPENAL_Sound_Release(greatcastlemusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &greatcastlemusic); +#endif break; case 14: +#ifdef USE_FMOD if ( sokobanmusic ) { sokobanmusic->release(); @@ -1521,8 +1649,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &sokobanmusic); } +#elif defined USE_OPENAL + if ( sokobanmusic ) { + OPENAL_Sound_Release(sokobanmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &sokobanmusic); +#endif break; case 15: +#ifdef USE_FMOD if ( caveslairmusic ) { caveslairmusic->release(); @@ -1535,8 +1670,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &caveslairmusic); } +#elif defined USE_OPENAL + if ( caveslairmusic ) { + OPENAL_Sound_Release(caveslairmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &caveslairmusic); +#endif break; case 16: +#ifdef USE_FMOD if ( bramscastlemusic ) { bramscastlemusic->release(); @@ -1549,8 +1691,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &bramscastlemusic); } +#elif defined USE_OPENAL + if ( bramscastlemusic ) { + OPENAL_Sound_Release(bramscastlemusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &bramscastlemusic); +#endif break; case 17: +#ifdef USE_FMOD if ( hamletmusic ) { hamletmusic->release(); @@ -1563,8 +1712,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &hamletmusic); } +#elif defined USE_OPENAL + if ( hamletmusic ) { + OPENAL_Sound_Release(hamletmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &hamletmusic); +#endif break; case 18: +#ifdef USE_FMOD if ( tutorialmusic ) { tutorialmusic->release(); @@ -1577,8 +1733,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &tutorialmusic); } +#elif defined USE_OPENAL + if ( tutorialmusic ) { + OPENAL_Sound_Release(tutorialmusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &tutorialmusic); +#endif break; case 19: +#ifdef USE_FMOD if ( gameovermusic ) { gameovermusic->release(); @@ -1591,8 +1754,15 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_DEFAULT, nullptr, &gameovermusic); } +#elif defined USE_OPENAL + if ( gameovermusic ) { + OPENAL_Sound_Release(gameovermusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &gameovermusic); +#endif break; case 20: +#ifdef USE_FMOD if ( introstorymusic ) { introstorymusic->release(); @@ -1605,64 +1775,45 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho { fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_DEFAULT, nullptr, &introstorymusic); } +#elif defined USE_OPENAL + if ( introstorymusic ) { + OPENAL_Sound_Release(introstorymusic); + } + OPENAL_CreateStreamSound(musicDir.c_str(), &introstorymusic); +#endif break; default: break; } +#ifdef USE_FMOD if ( FMODErrorCheck() ) { printlog("[PhysFS]: ERROR: Failed reloading music file \"%s\".", filename.c_str()); //TODO: Handle error? Abort? Fling pies at people? } +#endif } } ++index; } - int c; - FMOD::Sound** music = nullptr; - - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMMINESMUSIC, "music/mines%02d.ogg", minesmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload mines music array."); - //TODO: Handle error? Abort? Fling pies at people? - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMSWAMPMUSIC, "music/swamp%02d.ogg", swampmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload swamp music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMLABYRINTHMUSIC, "music/labyrinth%02d.ogg", labyrinthmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload labyrinth music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMRUINSMUSIC, "music/ruins%02d.ogg", ruinsmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload ruins music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMUNDERWORLDMUSIC, "music/underworld%02d.ogg", underworldmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload underworld music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMHELLMUSIC, "music/hell%02d.ogg", hellmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload hell music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMMINOTAURMUSIC, "music/minotaur%02d.ogg", minotaurmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload minotaur music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMCAVESMUSIC, "music/caves%02d.ogg", cavesmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload caves music array."); - } - if (FMOD_OK != (fmod_result = physfsReloadMusic_helper_reloadMusicArray(NUMCITADELMUSIC, "music/citadel%02d.ogg", citadelmusic, reloadAll)) ) - { - printlog("[PhysFS]: Failed to reload citadel music array."); - } + physfsReloadMusic_helper_reloadMusicArray(NUMMINESMUSIC, "music/mines%02d.ogg", minesmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMSWAMPMUSIC, "music/swamp%02d.ogg", swampmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMLABYRINTHMUSIC, "music/labyrinth%02d.ogg", labyrinthmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMRUINSMUSIC, "music/ruins%02d.ogg", ruinsmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMUNDERWORLDMUSIC, "music/underworld%02d.ogg", underworldmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMHELLMUSIC, "music/hell%02d.ogg", hellmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMMINOTAURMUSIC, "music/minotaur%02d.ogg", minotaurmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMCAVESMUSIC, "music/caves%02d.ogg", cavesmusic, reloadAll); + physfsReloadMusic_helper_reloadMusicArray(NUMCITADELMUSIC, "music/citadel%02d.ogg", citadelmusic, reloadAll); bool introChanged = false; - - for ( c = 0; c < NUMINTROMUSIC; c++ ) +#ifdef USE_FMOD + FMOD::Sound** music = nullptr; +#else + OPENAL_BUFFER** music = nullptr; +#endif + for ( int c = 0; c < NUMINTROMUSIC; c++ ) { if ( c == 0 ) { @@ -1682,45 +1833,46 @@ void physfsReloadMusic(bool &introMusicChanged, bool reloadAll) //TODO: This sho music = intromusic; if ( music ) { +#ifdef USE_FMOD music[c]->release(); +#elif defined USE_OPENAL + OPENAL_Sound_Release(music[c]); +#endif } if ( musicPreload ) { - fmod_result = fmod_system->createSound(musicDir.c_str(), FMOD_2D, nullptr, &music[c]); + //fmod_result = fmod_system->createSound(musicDir.c_str(), FMOD_2D, nullptr, &music[c]); + physfsReloadMusic_helper_reloadMusicArray(NUMINTROMUSIC, "music/intro%02d.ogg", music, reloadAll); } else { - fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &music[c]); + //fmod_result = fmod_system->createStream(musicDir.c_str(), FMOD_2D, nullptr, &music[c]); + physfsReloadMusic_helper_reloadMusicArray(NUMINTROMUSIC, "music/intro%02d.ogg", music, reloadAll); } introChanged = true; +#ifdef USE_FMOD if (fmod_result != FMOD_OK) { printlog("[PhysFS]: ERROR: Failed reloading music file \"%s\"."); break; //TODO: Handle the error? } +#endif } } } introMusicChanged = introChanged; // use this variable outside of this function to start playing a new fresh list of tracks in the main menu. -#ifdef USE_OPENAL -#undef FMOD_System_CreateStream -#undef FMOD_SOUND -#undef fmod_system -#undef FMOD_SOFTWARE -#undef FMOD_Sound_Release -#endif -#endif // SOUND +#endif // MUSIC } +/** + * Free custom music slots, not used by official music assets. + */ void gamemodsUnloadCustomThemeMusic() { #ifdef SOUND -#ifdef USE_OPENAL -#define FMOD_Sound_Release OPENAL_Sound_Release -#endif - // free custom music slots, not used by official music assets. +#ifdef USE_FMOD if ( gnomishminesmusic ) { gnomishminesmusic->release(); @@ -1751,8 +1903,9 @@ void gamemodsUnloadCustomThemeMusic() hamletmusic->release(); hamletmusic = nullptr; } +#endif #ifdef USE_OPENAL -#undef FMOD_Sound_Release + #endif #endif // !SOUND } diff --git a/src/engine/audio/sound.hpp b/src/engine/audio/sound.hpp index 80c00b332..aa051cf6e 100644 --- a/src/engine/audio/sound.hpp +++ b/src/engine/audio/sound.hpp @@ -11,6 +11,8 @@ #pragma once +#include "../../main.hpp" + #define FMOD_AUDIO_GUID_FMT "%.8x%.16llx" #include @@ -27,6 +29,18 @@ #endif #endif +#ifdef USE_FMOD +#include "fmod_errors.h" +#elif defined USE_OPENAL +#ifdef USE_TREMOR +#include +#else +#include +#include +#include +#endif +#endif + extern Uint32 numsounds; bool initSoundEngine(); //If it fails to initialize the sound engine, it'll just disable audio. void exitSoundEngine(); @@ -129,6 +143,37 @@ extern bool sfxUseDynamicAmbientVolume, sfxUseDynamicEnvironmentVolume; #define SOUND #define MUSIC +struct OPENAL_BUFFER { + ALuint id; + bool stream; + char oggfile[64]; +}; +struct OPENAL_CHANNELGROUP; +struct OPENAL_SOUND { + ALuint id; + OPENAL_CHANNELGROUP *group; + float volume; + OPENAL_BUFFER *buffer; + bool active; + char* oggdata; + int oggdata_length; + int ogg_seekoffset; + OggVorbis_File oggStream; + vorbis_info* vorbisInfo; + vorbis_comment* vorbisComment; + ALuint streambuff[4]; + bool loop; + bool stream_active; + int indice; +}; + +struct OPENAL_CHANNELGROUP { + float volume; + int num; + int cap; + OPENAL_SOUND **sounds; +}; + extern ALCcontext *openal_context; extern ALCdevice *openal_device; @@ -186,22 +231,29 @@ extern OPENAL_BUFFER* hamletmusic; extern OPENAL_SOUND* music_channel, *music_channel2, *music_resume; //TODO: List of music, play first one, fade out all the others? Eh, maybe some other day. //music_resume is the music to resume after, say, combat or shops. //TODO: Clear music_resume every biome change. Or otherwise validate it for that level set. extern OPENAL_CHANNELGROUP *sound_group, *music_group; -extern OPENAL_CHANNELGROUP *soundAmbient_group, *soundEnvironment_group, *music_notification_group; +extern OPENAL_CHANNELGROUP *soundAmbient_group; +extern OPENAL_CHANNELGROUP *soundEnvironment_group; +extern OPENAL_CHANNELGROUP *soundNotification_group; +extern OPENAL_CHANNELGROUP *music_notification_group; int initOPENAL(); int closeOPENAL(); +int openalGetNumberOfDevices(const ALCchar *devices); void sound_update(int player, int index, int numplayers); OPENAL_SOUND* playSoundPlayer(int player, Uint16 snd, Uint8 vol); +OPENAL_SOUND* playSoundNotificationPlayer(int player, Uint16 snd, Uint8 vol); //TODO: Write. OPENAL_SOUND* playSoundPos(real_t x, real_t y, Uint16 snd, Uint8 vol); OPENAL_SOUND* playSoundPosLocal(real_t x, real_t y, Uint16 snd, Uint8 vol); OPENAL_SOUND* playSoundEntity(Entity* entity, Uint16 snd, Uint8 vol); OPENAL_SOUND* playSoundEntityLocal(Entity* entity, Uint16 snd, Uint8 vol); OPENAL_SOUND* playSound(Uint16 snd, Uint8 vol); +OPENAL_SOUND* playSoundNotification(Uint16 snd, Uint8 vol); //TODO: Write. OPENAL_SOUND* playSoundVelocity(); //TODO: Write. -void playmusic(OPENAL_BUFFER* sound, bool loop, bool crossfade, bool resume); //Automatically crossfades. NOTE: Resets fadein and fadeout increments to the defaults every time it is called. You'll have to change the fadein and fadeout increments AFTER calling this function. +void stopMusic(); +void playMusic(OPENAL_BUFFER* sound, bool loop, bool crossfade, bool resume); //Automatically crossfades. NOTE: Resets fadein and fadeout increments to the defaults every time it is called. You'll have to change the fadein and fadeout increments AFTER calling this function. void handleLevelMusic(); //Manages and updates the level music. diff --git a/src/engine/audio/sound_game.cpp b/src/engine/audio/sound_game.cpp index fafc18cce..5e7454075 100644 --- a/src/engine/audio/sound_game.cpp +++ b/src/engine/audio/sound_game.cpp @@ -431,6 +431,40 @@ OPENAL_SOUND* playSoundPlayer(int player, Uint16 snd, Uint8 vol) return NULL; } +OPENAL_SOUND* playSoundNotificationPlayer(int player, Uint16 snd, Uint8 vol) +{ + if (no_sound) + { + return NULL; + } + + if ( player < 0 || player >= MAXPLAYERS ) //Perhaps this can be reprogrammed to remove MAXPLAYERS, and use a pointer to the player instead of an int? + { + return nullptr; + } + if ( players[player]->isLocalPlayer() ) + { + return playSoundNotification(snd, vol); + } + else if ( multiplayer == SERVER ) + { + if ( client_disconnected[player] || player <= 0 ) + { + return nullptr; + } + memcpy(net_packet->data, "SNDN", 4); + SDLNet_Write16(snd, &net_packet->data[4]); + net_packet->data[6] = vol; + net_packet->address.host = net_clients[player - 1].host; + net_packet->address.port = net_clients[player - 1].port; + net_packet->len = 7; + sendPacketSafe(net_sock, -1, net_packet, player - 1); + return nullptr; + } + + return nullptr; +} + /*------------------------------------------------------------------------------- playSoundPos @@ -609,6 +643,33 @@ OPENAL_SOUND* playSound(Uint16 snd, Uint8 vol) return channel; } +OPENAL_SOUND* playSoundNotification(Uint16 snd, Uint8 vol) +{ + if (no_sound) + { + return NULL; + } +#ifndef SOUND + return NULL; +#endif + if (!openal_context || snd < 0 || snd >= numsounds || !music_notification_group ) + { + return NULL; + } + if (sounds[snd] == NULL || vol == 0) + { + return NULL; + } + OPENAL_SOUND* channel = OPENAL_CreateChannel(sounds[snd]); + OPENAL_Channel_SetVolume(channel, vol / 255.f); + + OPENAL_Channel_SetChannelGroup(channel, music_notification_group); + + OPENAL_Channel_Play(channel); + + return channel; +} + void playMusic(OPENAL_BUFFER* sound, bool loop, bool crossfade, bool resume) { if (no_sound) @@ -670,398 +731,15 @@ void playMusic(OPENAL_BUFFER* sound, bool loop, bool crossfade, bool resume) OPENAL_Channel_Play(music_channel); } -bool shopmusicplaying = false; -bool combatmusicplaying = false; -bool minotaurmusicplaying = false; -bool herxmusicplaying = false; -bool devilmusicplaying = false; -bool olddarkmap = false; -bool sanctummusicplaying = false; - -int currenttrack = -1; - -void handleLevelMusic() -{ - if (no_sound) - { - return; - } -#ifndef SOUND - return; -#endif -#ifndef MUSIC - return; -#endif - bool inshop = false; - if (players[clientnum] && players[clientnum]->entity) - { - int x = (int)players[clientnum]->entity->x / 16; - int y = (int)players[clientnum]->entity->y / 16; - if ( x >= 0 && x < map.width && y >= 0 && y < map.height ) - if ( shoparea[y + x * map.height] ) - { - inshop = true; - } - } - - bool devilaround = false; - bool activeminotaur = false; - bool herxaround = false; - bool magisteraround = false; - node_t* node; - for ( node = map.creatures->first; node != NULL; node = node->next ) - { - Entity* entity = (Entity*)node->element; - if ( entity->sprite == 274 ) // herx head - { - herxaround = true; - break; - } - else if ( entity->sprite == 304 ) // devil body - { - devilaround = true; - break; - } - else if ( entity->sprite == 239 ) // minotaur head - { - activeminotaur = true; - break; - } - else if ( entity->sprite == 646 || entity->sprite == 650 ) // magister body - { - magisteraround = true; - break; - } - } - - ALboolean playing = true; - OPENAL_Channel_IsPlaying(music_channel, &playing); - - if ( currenttrack == -1 ) - { - currenttrack = local_rng.rand(); - } - - if ( (!levelmusicplaying || !playing || olddarkmap != darkmap) - && (!combat || !strcmp(map.name, "Hell Boss")) - && !inshop - && (!activeminotaur || !strcmp(map.name, "Hell Boss")) && !herxaround && !devilaround && !magisteraround ) - { - if ( !strncmp(map.name, "The Mines", 9) ) // the mines - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMMINESMUSIC - 1); - } - currenttrack = currenttrack % NUMMINESMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(minesmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "The Swamp", 9) ) // the swamp - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMSWAMPMUSIC - 1); - } - currenttrack = currenttrack % NUMSWAMPMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(swampmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "The Labyrinth", 13) ) // the labyrinth - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMLABYRINTHMUSIC - 1); - } - currenttrack = currenttrack % NUMLABYRINTHMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(labyrinthmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "The Ruins", 9) ) // the ruins - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMRUINSMUSIC - 1); - } - currenttrack = currenttrack % NUMRUINSMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(ruinsmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "Underworld", 10) ) // the underworld - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMUNDERWORLDMUSIC - 1); - } - currenttrack = currenttrack % NUMUNDERWORLDMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(underworldmusic[currenttrack], false, true, true); - } - else if ( !strcmp(map.name, "Minetown") ) // minetown - { - playMusic(minetownmusic, true, true, true); - } - else if ( !strcmp(map.name, "The Gnomish Mines") ) - { - if ( gnomishminesmusic ) - { - playMusic(gnomishminesmusic, true, true, true); - } - else - { - playMusic(minetownmusic, true, true, true); - } - } - else if ( !strcmp(map.name, "The Haunted Castle") ) - { - if ( greatcastlemusic ) - { - playMusic(greatcastlemusic, true, true, true); - } - else - { - playMusic(intermissionmusic, true, true, true); - } - } - else if ( !strcmp(map.name, "Sokoban") ) - { - if ( sokobanmusic ) - { - playMusic(sokobanmusic, true, true, true); - } - else - { - playMusic(intermissionmusic, true, true, true); - } - } - else if ( !strcmp(map.name, "Cockatrice Lair") ) - { - if ( caveslairmusic ) - { - playMusic(caveslairmusic, true, true, true); - } - else - { - playMusic(cavesmusic[2], true, true, true); - } - } - else if ( !strcmp(map.name, "Bram's Castle") ) - { - if ( bramscastlemusic ) - { - playMusic(bramscastlemusic, true, true, true); - } - else - { - playMusic(citadelmusic[2], true, true, true); - } - } - else if ( !strcmp(map.name, "The Mystic Library") ) // mystic library - { - playMusic(librarymusic, true, true, true); - } - else if ( !strcmp(map.name, "The Minotaur Maze") ) // minotaur maze - { - playMusic(minotaurmusic[1], true, true, true); - } - else if ( !strcmp(map.name, "The Temple") ) // the temple - { - playMusic(templemusic, true, true, true); - } - else if ( !strcmp(map.name, "Hell Boss") ) // escape theme - { - playMusic(escapemusic, true, true, true); - } - else if ( !strncmp(map.name, "Hell", 4) ) // hell - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMHELLMUSIC - 1); - } - currenttrack = currenttrack % NUMHELLMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(hellmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "Caves", 5) ) - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMCAVESMUSIC - 1); - } - currenttrack = currenttrack % NUMCAVESMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(cavesmusic[currenttrack], false, true, true); - } - else if ( !strncmp(map.name, "Citadel", 7) || !strncmp(map.name, "Sanctum", 7) ) - { - if ( !playing ) - { - currenttrack = 1 + local_rng.rand() % (NUMCITADELMUSIC - 1); - } - currenttrack = currenttrack % NUMCITADELMUSIC; - if ( currenttrack == 0 ) - { - currenttrack = 1; - } - playMusic(citadelmusic[currenttrack], false, true, true); - } - else if ( !strcmp(map.name, "Mages Guild") ) - { - if ( hamletmusic ) - { - playMusic(hamletmusic, true, true, true); - } - else - { - playMusic(minesmusic[4], true, true, true); - } - } - else - { - playMusic(intermissionmusic, true, true, true); - } - olddarkmap = darkmap; - levelmusicplaying = true; - devilmusicplaying = false; - herxmusicplaying = false; - minotaurmusicplaying = false; - combatmusicplaying = false; - shopmusicplaying = false; - fadein_increment = default_fadein_increment; - fadeout_increment = default_fadeout_increment; - } - else if ( (!devilmusicplaying || !playing) && devilaround ) - { - playMusic(devilmusic, true, true, true); - levelmusicplaying = false; - devilmusicplaying = true; - herxmusicplaying = false; - minotaurmusicplaying = false; - combatmusicplaying = false; - shopmusicplaying = false; - fadein_increment = default_fadein_increment * 2; - fadeout_increment = default_fadeout_increment * 2; - } - else if ( (!herxmusicplaying || !playing) && !devilaround && herxaround ) - { - playMusic(herxmusic, true, true, true); - levelmusicplaying = false; - devilmusicplaying = false; - herxmusicplaying = true; - minotaurmusicplaying = false; - combatmusicplaying = false; - shopmusicplaying = false; - fadein_increment = default_fadein_increment * 2; - fadeout_increment = default_fadeout_increment * 2; - } - else if ( (!minotaurmusicplaying || !playing) && !herxaround && activeminotaur && strcmp(map.name, "Hell Boss") ) - { - playMusic(minotaurmusic[0], true, true, true); - levelmusicplaying = false; - devilmusicplaying = false; - herxmusicplaying = false; - minotaurmusicplaying = true; - combatmusicplaying = false; - shopmusicplaying = false; - fadein_increment = default_fadein_increment * 5; - fadeout_increment = default_fadeout_increment * 5; - } - else if ( (!sanctummusicplaying || !playing) && magisteraround ) - { - playMusic(sanctummusic, true, true, true); - levelmusicplaying = false; - devilmusicplaying = false; - herxmusicplaying = false; - minotaurmusicplaying = false; - combatmusicplaying = false; - sanctummusicplaying = true; - shopmusicplaying = false; - fadein_increment = default_fadein_increment * 2; - fadeout_increment = default_fadeout_increment * 2; - } - else if ( (!combatmusicplaying || !playing) - && !herxaround - && !activeminotaur - && combat - && strcmp(map.name, "Hell Boss") - && strcmp(map.name, "Sanctum") ) - { - if ( !strncmp(map.name, "The Swamp", 9) || !strncmp(map.name, "The Temple", 10) ) // the swamp - { - playMusic(swampmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "The Labyrinth", 13) || strstr(map.name, "Minotaur") ) // the labyrinth - { - playMusic(labyrinthmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "The Ruins", 9) ) // the ruins - { - playMusic(ruinsmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "Underworld", 10) ) // the underworld - { - playMusic(underworldmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "Hell", 4) ) // hell - { - playMusic(hellmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "Caves", 5) || !strcmp(map.name, "Cockatrice Lair") ) - { - playMusic(cavesmusic[0], true, true, true); - } - else if ( !strncmp(map.name, "Citadel", 7) || !strcmp(map.name, "Bram's Castle") ) - { - playMusic(citadelmusic[0], true, true, true); - } - else - { - playMusic(minesmusic[0], true, true, true); - } - levelmusicplaying = false; - devilmusicplaying = false; - herxmusicplaying = false; - combatmusicplaying = true; - shopmusicplaying = false; - minotaurmusicplaying = false; - fadein_increment = default_fadein_increment * 4; - fadeout_increment = default_fadeout_increment; - } - else if ( (!shopmusicplaying || !playing) && !herxaround && !activeminotaur && !combat && inshop ) - { - playMusic(shopmusic, true, true, true); - levelmusicplaying = false; - devilmusicplaying = false; - herxmusicplaying = false; - minotaurmusicplaying = false; - combatmusicplaying = false; - shopmusicplaying = true; - fadein_increment = default_fadein_increment * 4; - fadeout_increment = default_fadeout_increment; - } -} +extern bool shopmusicplaying; +extern bool combatmusicplaying; +extern bool minotaurmusicplaying; +extern bool herxmusicplaying; +extern bool devilmusicplaying; +extern bool olddarkmap; +extern bool sanctummusicplaying; +extern int currenttrack; #else diff --git a/src/game.cpp b/src/game.cpp index 764f6a606..4f47940c6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1980,6 +1980,10 @@ void gameLogic(void) { OPENAL_ChannelGroup_Stop(soundEnvironment_group); } + if ( soundNotification_group ) + { + OPENAL_ChannelGroup_Stop(soundNotification_group); + } #endif // stop combat music // close chests diff --git a/src/init_game.cpp b/src/init_game.cpp index 655ddb2c4..2f0ef3f6a 100644 --- a/src/init_game.cpp +++ b/src/init_game.cpp @@ -561,39 +561,45 @@ void deinitGame() safePacketsReceivedMap[c].clear(); } #ifdef SOUND -#ifdef USE_OPENAL //TODO: OpenAL is now all of the broken... -#define FMOD_Channel_Stop OPENAL_Channel_Stop -#define FMOD_Sound_Release OPENAL_Sound_Release + +#ifdef USE_FMOD +#define RELEASE_CHANNEL( x ) (x->stop()) +#define RELEASE_SOUND( x ) (x->release()) +#elif defined USE_OPENAL +#define RELEASE_CHANNEL( x ) OPENAL_Channel_Stop(x) +#define RELEASE_SOUND( x ) OPENAL_Sound_Release(x) #endif + if ( !no_sound ) { - music_channel->stop(); - music_channel2->stop(); - introductionmusic->release(); - intermissionmusic->release(); - minetownmusic->release(); - splashmusic->release(); - librarymusic->release(); - shopmusic->release(); - herxmusic->release(); - templemusic->release(); - endgamemusic->release(); - escapemusic->release(); - devilmusic->release(); - sanctummusic->release(); - gnomishminesmusic->release(); - greatcastlemusic->release(); - sokobanmusic->release(); - caveslairmusic->release(); - bramscastlemusic->release(); - hamletmusic->release(); - tutorialmusic->release(); - gameovermusic->release(); - introstorymusic->release(); + RELEASE_CHANNEL( music_channel ); + RELEASE_CHANNEL( music_channel2 ); + + RELEASE_SOUND( introductionmusic ); + RELEASE_SOUND( intermissionmusic ); + RELEASE_SOUND( minetownmusic ); + RELEASE_SOUND( splashmusic ); + RELEASE_SOUND( librarymusic ); + RELEASE_SOUND( shopmusic ); + RELEASE_SOUND( herxmusic ); + RELEASE_SOUND( templemusic ); + RELEASE_SOUND( endgamemusic ); + RELEASE_SOUND( escapemusic ); + RELEASE_SOUND( devilmusic ); + RELEASE_SOUND( sanctummusic ); + RELEASE_SOUND( gnomishminesmusic ); + RELEASE_SOUND( greatcastlemusic ); + RELEASE_SOUND( sokobanmusic ); + RELEASE_SOUND( caveslairmusic ); + RELEASE_SOUND( bramscastlemusic ); + RELEASE_SOUND( hamletmusic ); + RELEASE_SOUND( tutorialmusic ); + RELEASE_SOUND( gameovermusic ); + RELEASE_SOUND( introstorymusic ); for ( int c = 0; c < NUMMINESMUSIC; c++ ) { - minesmusic[c]->release(); + RELEASE_SOUND( minesmusic[c] ); } if ( minesmusic ) { @@ -601,7 +607,7 @@ void deinitGame() } for ( int c = 0; c < NUMSWAMPMUSIC; c++ ) { - swampmusic[c]->release(); + RELEASE_SOUND( swampmusic[c] ); } if ( swampmusic ) { @@ -609,7 +615,7 @@ void deinitGame() } for ( int c = 0; c < NUMLABYRINTHMUSIC; c++ ) { - labyrinthmusic[c]->release(); + RELEASE_SOUND( labyrinthmusic[c] ); } if ( labyrinthmusic ) { @@ -617,7 +623,7 @@ void deinitGame() } for ( int c = 0; c < NUMRUINSMUSIC; c++ ) { - ruinsmusic[c]->release(); + RELEASE_SOUND( ruinsmusic[c] ); } if ( ruinsmusic ) { @@ -625,7 +631,7 @@ void deinitGame() } for ( int c = 0; c < NUMUNDERWORLDMUSIC; c++ ) { - underworldmusic[c]->release(); + RELEASE_SOUND( underworldmusic[c] ); } if ( underworldmusic ) { @@ -633,7 +639,7 @@ void deinitGame() } for ( int c = 0; c < NUMHELLMUSIC; c++ ) { - hellmusic[c]->release(); + RELEASE_SOUND( hellmusic[c] ); } if ( hellmusic ) { @@ -641,7 +647,7 @@ void deinitGame() } for ( int c = 0; c < NUMMINOTAURMUSIC; c++ ) { - minotaurmusic[c]->release(); + RELEASE_SOUND( minotaurmusic[c] ); } if ( minotaurmusic ) { @@ -649,7 +655,7 @@ void deinitGame() } for ( int c = 0; c < NUMCAVESMUSIC; c++ ) { - cavesmusic[c]->release(); + RELEASE_SOUND( cavesmusic[c] ); } if ( cavesmusic ) { @@ -657,7 +663,7 @@ void deinitGame() } for ( int c = 0; c < NUMCITADELMUSIC; c++ ) { - citadelmusic[c]->release(); + RELEASE_SOUND( citadelmusic[c] ); } if ( citadelmusic ) { @@ -665,17 +671,14 @@ void deinitGame() } for ( int c = 0; c < NUMINTROMUSIC; c++ ) { - intromusic[c]->release(); + RELEASE_SOUND( intromusic[c] ); } if ( intromusic ) { free(intromusic); } } -#ifdef USE_OPENAL -#undef FMOD_Channel_Stop -#undef FMOD_Sound_Release -#endif + #endif // free items diff --git a/src/menu.cpp b/src/menu.cpp index a75195e91..c6bf637c2 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -8776,6 +8776,10 @@ void doNewGame(bool makeHighscore) { { OPENAL_ChannelGroup_Stop(soundEnvironment_group); } + if ( soundNotification_group ) + { + OPENAL_ChannelGroup_Stop(soundNotification_group); + } #endif if ( !loadingsavegame ) @@ -9236,6 +9240,10 @@ void doNewGame(bool makeHighscore) { { OPENAL_ChannelGroup_Stop(soundEnvironment_group); } + if ( soundNotification_group ) + { + OPENAL_ChannelGroup_Stop(soundNotification_group); + } #endif // load next level entity_uids = 1; @@ -9741,6 +9749,10 @@ void doEndgame(bool saveHighscore, bool onServerDisconnect) { { OPENAL_ChannelGroup_Stop(soundEnvironment_group); } + if ( soundNotification_group ) + { + OPENAL_ChannelGroup_Stop(soundNotification_group); + } #endif if ( net_packet ) diff --git a/src/mod_tools.cpp b/src/mod_tools.cpp index c37005c35..09918ce68 100644 --- a/src/mod_tools.cpp +++ b/src/mod_tools.cpp @@ -9695,7 +9695,7 @@ void Mods::unloadMods(bool force) physfsReloadMusic(reloadIntroMusic, true); if (reloadIntroMusic) { -#ifdef SOUND +#ifdef MUSIC playMusic(intromusic[local_rng.rand() % (NUMINTROMUSIC - 1)], false, true, true); #endif } @@ -9810,7 +9810,7 @@ void Mods::loadMods() physfsReloadMusic(reloadIntroMusic, false); if ( reloadIntroMusic ) { -#ifdef SOUND +#ifdef MUSIC playMusic(intromusic[local_rng.rand() % (NUMINTROMUSIC - 1)], false, true, true); #endif } @@ -9823,7 +9823,7 @@ void Mods::loadMods() physfsReloadMusic(reloadIntroMusic, true); if ( reloadIntroMusic ) { -#ifdef SOUND +#ifdef MUSIC playMusic(intromusic[local_rng.rand() % (NUMINTROMUSIC - 1)], false, true, true); #endif } diff --git a/src/ui/MainMenu.cpp b/src/ui/MainMenu.cpp index 54e19cd6b..e52c5d0f9 100644 --- a/src/ui/MainMenu.cpp +++ b/src/ui/MainMenu.cpp @@ -2870,12 +2870,14 @@ namespace MainMenu { fpsLimit = std::min(std::max(MIN_FPS, *cvar_desiredFps), MAX_FPS); } current_audio_device = audio_device; +#ifdef USE_FMOD if (fmod_speakermode != speaker_mode) { fmod_speakermode = (FMOD_SPEAKERMODE)speaker_mode; if (initialized) { restartPromptRequired = true; } } +#endif MainMenu::master_volume = std::min(std::max(0.f, master_volume / 100.f), 1.f); sfxvolume = std::min(std::max(0.f, gameplay_volume / 100.f), 1.f); sfxAmbientVolume = std::min(std::max(0.f, ambient_volume / 100.f), 1.f); @@ -2974,7 +2976,9 @@ namespace MainMenu { settings.fov = ::fov; settings.fps = *cvar_desiredFps; settings.audio_device = current_audio_device; +#ifdef USE_FMOD settings.speaker_mode = (int)fmod_speakermode; +#endif settings.master_volume = MainMenu::master_volume * 100.f; settings.gameplay_volume = (float)sfxvolume * 100.f; settings.ambient_volume = (float)sfxAmbientVolume * 100.f; @@ -4479,16 +4483,18 @@ namespace MainMenu { }); } -#if defined(USE_FMOD) struct AudioDriver { char name[64]; +#ifdef USE_FMOD FMOD_GUID guid; int system_rate; FMOD_SPEAKERMODE speaker_mode; int speaker_mode_channels; +#endif }; static std::vector audio_drivers; +#ifdef USE_FMOD static void settingsAudioDevice(Button& button) { settingsOpenDropdown(button, "device", DropdownType::Wide, [](Frame::entry_t& entry){ soundActivate(); @@ -6357,9 +6363,9 @@ namespace MainMenu { } int y = 0; + int num_drivers = 0; #if !defined(NINTENDO) && defined(USE_FMOD) int selected_device = 0; - int num_drivers = 0; (void)fmod_system->getNumDrivers(&num_drivers); audio_drivers.clear(); audio_drivers.reserve(num_drivers); @@ -24981,7 +24987,7 @@ namespace MainMenu { // return to title screen destroyMainMenu(); -#ifdef SOUND +#ifdef MUSIC const int music = RNG.uniform(0, NUMINTROMUSIC - 2); playMusic(intromusic[music], true, false, false); #endif @@ -25051,7 +25057,7 @@ namespace MainMenu { // return to menu destroyMainMenu(); -#ifdef SOUND +#ifdef MUSIC const int music = RNG.uniform(0, NUMINTROMUSIC - 2); playMusic(intromusic[music], true, false, false); #endif @@ -25086,7 +25092,7 @@ namespace MainMenu { // create a highscore as token of remembrance. doEndgame(true, false); } -#ifdef SOUND +#ifdef MUSIC const int music = RNG.uniform(0, NUMINTROMUSIC - 2); playMusic(intromusic[music], true, false, false); #endif @@ -25118,7 +25124,7 @@ namespace MainMenu { destroyMainMenu(); createDummyMainMenu(); createCreditsScreen(true); -#ifdef SOUND +#ifdef MUSIC playMusic(intromusic[0], true, false, false); #endif