diff --git a/CMake/ctr/n3ds_defs.cmake b/CMake/ctr/n3ds_defs.cmake index eed358494..f7a36127a 100644 --- a/CMake/ctr/n3ds_defs.cmake +++ b/CMake/ctr/n3ds_defs.cmake @@ -2,6 +2,11 @@ set(NONET ON) set(USE_SDL1 ON) +# Streaming audio is broken on the 3DS as of 25 Mar 2021: +# https://github.com/devkitPro/SDL/issues/72 +set(DISABLE_STREAMING_MUSIC ON) +set(DISABLE_STREAMING_SOUNDS ON) + #3DS libraries list(APPEND CMAKE_MODULE_PATH "${DevilutionX_SOURCE_DIR}/CMake/ctr/modules") find_package(CITRO3D REQUIRED) diff --git a/CMake/switch/switch_defs.cmake b/CMake/switch/switch_defs.cmake index 2f1b1a86b..ea0fec81b 100644 --- a/CMake/switch/switch_defs.cmake +++ b/CMake/switch/switch_defs.cmake @@ -1,5 +1,11 @@ set(NONET ON) set(PREFILL_PLAYER_NAME ON) + +# Streaming audio is broken on the Switch as of 25 Mar 2021: +# https://github.com/devkitPro/SDL/issues/72 +set(DISABLE_STREAMING_MUSIC ON) +set(DISABLE_STREAMING_SOUNDS ON) + set(JOY_BUTTON_DPAD_LEFT 16) set(JOY_BUTTON_DPAD_UP 17) set(JOY_BUTTON_DPAD_RIGHT 18) diff --git a/CMakeLists.txt b/CMakeLists.txt index d465260e0..78a071024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,12 @@ option(USE_SDL1 "Use SDL1.2 instead of SDL2" OFF) option(NONET "Disable network" OFF) option(RUN_TESTS "Build and run tests" OFF) option(HELLFIRE "Build hellfire version" OFF) + +option(DISABLE_STREAMING_MUSIC "Disable streaming music (to work around broken platform implementations)" OFF) +mark_as_advanced(DISABLE_STREAMING_MUSIC) +option(DISABLE_STREAMING_SOUNDS "Disable streaming sounds (to work around broken platform implementations)" OFF) +mark_as_advanced(DISABLE_STREAMING_SOUNDS) + RELEASE_OPTION(CPACK "Configure CPack") @@ -462,6 +468,8 @@ foreach( def_name NONET PREFILL_PLAYER_NAME + DISABLE_STREAMING_MUSIC + DISABLE_STREAMING_SOUNDS ) if(${def_name}) list(APPEND def_list ${def_name}) diff --git a/Source/effects.cpp b/Source/effects.cpp index b4c26322a..c704c3ec5 100644 --- a/Source/effects.cpp +++ b/Source/effects.cpp @@ -1084,6 +1084,11 @@ void stream_stop() static void stream_play(TSFX *pSFX, int lVolume, int lPan) { BOOL success; +#ifndef DISABLE_STREAMING_SOUNDS + constexpr bool kAllowStreaming = true; +#else + constexpr bool kAllowStreaming = false; +#endif assert(pSFX); assert(pSFX->bFlags & sfx_STREAM); @@ -1093,7 +1098,7 @@ static void stream_play(TSFX *pSFX, int lVolume, int lPan) if (lVolume > VOLUME_MAX) lVolume = VOLUME_MAX; if (pSFX->pSnd == NULL) - pSFX->pSnd = sound_file_load(pSFX->pszName, /*stream=*/true); + pSFX->pSnd = sound_file_load(pSFX->pszName, kAllowStreaming); pSFX->pSnd->DSB->Play(lVolume, lPan, 0); sgpStreamSFX = pSFX; } diff --git a/SourceX/sound.cpp b/SourceX/sound.cpp index bdb74b541..501d1c029 100644 --- a/SourceX/sound.cpp +++ b/SourceX/sound.cpp @@ -20,6 +20,18 @@ namespace { Mix_Music *music; +#ifdef DISABLE_STREAMING_MUSIC +char *musicBuffer; + +void FreeMusicBuffer() +{ + if (musicBuffer != nullptr) { + mem_free_dbg(musicBuffer); + musicBuffer = nullptr; + } +} +#endif // DISABLE_STREAMING_MUSIC + } // namespace /* data */ @@ -169,13 +181,18 @@ void snd_init() void music_stop() { - if (sghMusic) { + if (music != nullptr) { Mix_HaltMusic(); Mix_FreeMusic(music); music = NULL; +#ifndef DISABLE_STREAMING_MUSIC SFileCloseFile(sghMusic); sghMusic = NULL; +#endif sgnMusicTrack = NUM_MUSIC; +#ifdef DISABLE_STREAMING_MUSIC + FreeMusicBuffer(); +#endif } } @@ -195,12 +212,30 @@ void music_start(int nTrack) if (!success) { sghMusic = NULL; } else { - music = Mix_LoadMUSType_RW(SFileRw_FromStormHandle(sghMusic), MUS_NONE, /*freesrc=*/1); +#ifndef DISABLE_STREAMING_MUSIC + SDL_RWops *musicRw = SFileRw_FromStormHandle(sghMusic); +#else + int bytestoread = SFileGetFileSize(sghMusic, 0); + musicBuffer = (char *)DiabloAllocPtr(bytestoread); + SFileReadFile(sghMusic, musicBuffer, bytestoread, NULL, 0); + SFileCloseFile(sghMusic); + sghMusic = NULL; + + SDL_RWops *musicRw = SDL_RWFromConstMem(musicBuffer, bytestoread); + if (musicRw == nullptr) + ErrSdl(); +#endif + music = Mix_LoadMUSType_RW(musicRw, MUS_NONE, /*freesrc=*/1); if (music == NULL) { SDL_Log("Mix_LoadMUSType_RW: %s", Mix_GetError()); +#ifndef DISABLE_STREAMING_MUSIC SFileCloseFile(sghMusic); sghMusic = NULL; +#endif sgnMusicTrack = NUM_MUSIC; +#ifdef DISABLE_STREAMING_MUSIC + FreeMusicBuffer(); +#endif return; } @@ -208,10 +243,15 @@ void music_start(int nTrack) if (Mix_PlayMusic(music, -1) < 0) { SDL_Log("Mix_PlayMusic: %s", Mix_GetError()); Mix_FreeMusic(music); + music = NULL; +#ifndef DISABLE_STREAMING_MUSIC SFileCloseFile(sghMusic); sghMusic = NULL; - music = NULL; +#endif sgnMusicTrack = NUM_MUSIC; +#ifdef DISABLE_STREAMING_MUSIC + FreeMusicBuffer(); +#endif return; } @@ -236,7 +276,7 @@ int sound_get_or_set_music_volume(int volume) sgOptions.Audio.nMusicVolume = volume; - if (sghMusic) + if (music != nullptr) Mix_VolumeMusic(MIX_MAX_VOLUME - MIX_MAX_VOLUME * volume / VOLUME_MIN); return sgOptions.Audio.nMusicVolume;