From 57172e48ed5511615050adb96136f7604f8fb58b Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 27 Apr 2021 01:57:27 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20=E2=9A=99=EF=B8=8F=20=20CMake:?= =?UTF-8?q?=20Add=20NOSOUND=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This option completely disables all audio handling, including audio loading code and dependencies. Dialog text length is estimated to be somewhere between Cain and Griswold speed. --- CMakeLists.txt | 50 +++++++++++++++++++++++++------------ Source/diablo.cpp | 9 ++++++- Source/effects.h | 5 +++- Source/effects_stubs.cpp | 26 +++++++++++++++++++ Source/gamemenu.cpp | 11 +++++++- Source/minitext.cpp | 9 ++++++- Source/monster.h | 5 ++++ Source/movie.cpp | 12 ++++++++- Source/sound.h | 6 ++++- Source/sound_stubs.cpp | 28 +++++++++++++++++++++ Source/storm/storm_svid.cpp | 21 +++++++++++++--- Source/utils/display.cpp | 5 +++- 12 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 Source/effects_stubs.cpp create mode 100644 Source/sound_stubs.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5784ad3a0..fcd152009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,8 @@ option(DIST "Dynamically link only glibc and SDL2" OFF) option(BINARY_RELEASE "Enable options for binary release" OFF) option(NIGHTLY_BUILD "Enable options for nightly build" OFF) option(USE_SDL1 "Use SDL1.2 instead of SDL2" OFF) -option(NONET "Disable network" OFF) +option(NONET "Disable network support" OFF) +option(NOSOUND "Disable sound support" OFF) option(RUN_TESTS "Build and run tests" OFF) option(USE_GETTEXT "Build translation files using gettext" OFF) @@ -47,13 +48,17 @@ if(NIGHTLY_BUILD OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") set(CPACK ON) endif() -option(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB "Use system-provided SDL_audiolib" OFF) -cmake_dependent_option(DEVILUTIONX_STATIC_SDL_AUDIOLIB "Link static SDL_audiolib" OFF - "DEVILUTIONX_SYSTEM_SDL_AUDIOLIB AND NOT DIST" ON) +if(NOT NOSOUND) + option(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB "Use system-provided SDL_audiolib" OFF) + cmake_dependent_option(DEVILUTIONX_STATIC_SDL_AUDIOLIB "Link static SDL_audiolib" OFF + "DEVILUTIONX_SYSTEM_SDL_AUDIOLIB AND NOT DIST" ON) +endif() -option(DEVILUTIONX_SYSTEM_LIBSODIUM "Use system-provided libsodium" ON) -cmake_dependent_option(DEVILUTIONX_STATIC_LIBSODIUM "Link static libsodium" OFF - "DEVILUTIONX_SYSTEM_LIBSODIUM AND NOT DIST" ON) +if(NOT NONET) + option(DEVILUTIONX_SYSTEM_LIBSODIUM "Use system-provided libsodium" ON) + cmake_dependent_option(DEVILUTIONX_STATIC_LIBSODIUM "Link static libsodium" OFF + "DEVILUTIONX_SYSTEM_LIBSODIUM AND NOT DIST" ON) +endif() option(DEVILUTIONX_SYSTEM_LIBFMT "Use system-provided libfmt" ON) cmake_dependent_option(DEVILUTIONX_STATIC_LIBFMT "Link static libfmt" OFF @@ -173,10 +178,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # for clang-tidy set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) -if(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB) - find_package(SDL_audiolib REQUIRED) -else() - add_subdirectory(3rdParty/SDL_audiolib) +if(NOT NOSOUND) + if(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB) + find_package(SDL_audiolib REQUIRED) + else() + add_subdirectory(3rdParty/SDL_audiolib) + endif() endif() if(NOT N3DS) @@ -278,7 +285,6 @@ set(devilutionx_SRCS Source/drlg_l4.cpp Source/dthread.cpp Source/dx.cpp - Source/effects.cpp Source/encrypt.cpp Source/engine.cpp Source/error.cpp @@ -320,7 +326,6 @@ set(devilutionx_SRCS Source/scrollrt.cpp Source/setmaps.cpp Source/sha.cpp - Source/sound.cpp Source/spelldat.cpp Source/spells.cpp Source/stores.cpp @@ -353,8 +358,6 @@ set(devilutionx_SRCS Source/utils/file_util.cpp Source/utils/language.cpp Source/utils/paths.cpp - Source/utils/push_aulib_decoder.cpp - Source/utils/soundsample.cpp Source/utils/thread.cpp Source/DiabloUI/art.cpp Source/DiabloUI/art_draw.cpp @@ -398,6 +401,18 @@ if(USE_SDL1) list(APPEND devilutionx_SRCS Source/utils/sdl2_to_1_2_backports.cpp) endif() +if(NOSOUND) + list(APPEND devilutionx_SRCS + Source/effects_stubs.cpp + Source/sound_stubs.cpp) +else() + list(APPEND devilutionx_SRCS + Source/effects.cpp + Source/sound.cpp + Source/utils/push_aulib_decoder.cpp + Source/utils/soundsample.cpp) +endif() + if(NOT NONET) list(APPEND devilutionx_SRCS Source/dvlnet/tcp_client.cpp @@ -536,6 +551,7 @@ target_compile_definitions(${BIN_TARGET} PRIVATE ASIO_STANDALONE) # Defines without value foreach( def_name + NOSOUND NONET PREFILL_PLAYER_NAME DISABLE_STREAMING_MUSIC @@ -633,7 +649,9 @@ else() SDL2::SDL2_ttf) endif() -target_link_libraries(${BIN_TARGET} PRIVATE SDL_audiolib) +if(NOT NOSOUND) + target_link_libraries(${BIN_TARGET} PRIVATE SDL_audiolib) +endif() if(SWITCH) target_link_libraries(${BIN_TARGET} PRIVATE switch::libnx diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 01a53fa83..a06862941 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -41,7 +41,6 @@ #include "qol/common.h" #include "restrict.h" #include "setmaps.h" -#include "sound.h" #include "stores.h" #include "storm/storm.h" #include "themes.h" @@ -54,6 +53,10 @@ #include "utils/paths.h" #include "utils/language.h" +#ifndef NOSOUND +#include "sound.h" +#endif + namespace devilution { #ifndef DEFAULT_WIDTH @@ -667,8 +670,10 @@ static void diablo_init() diablo_init_screen(); +#ifndef NOSOUND snd_init(); was_snd_init = true; +#endif ui_sound_init(); } @@ -699,7 +704,9 @@ static void diablo_deinit() if (was_snd_init) { effects_cleanup_sfx(); } +#ifndef NOSOUND Aulib::quit(); +#endif if (was_ui_init) UiDestroy(); if (was_archives_init) diff --git a/Source/effects.h b/Source/effects.h index c3c25d046..f145a62a0 100644 --- a/Source/effects.h +++ b/Source/effects.h @@ -1069,7 +1069,6 @@ bool effect_is_playing(int nSFX); void stream_stop(); void InitMonsterSND(int monst); void FreeMonsterSnd(); -bool calc_snd_position(int x, int y, int *plVolume, int *plPan); void PlayEffect(int i, int mode); void PlaySFX(_sfx_id psfx); void PlaySfxLoc(_sfx_id psfx, int x, int y, bool randomizeByCategory = true); @@ -1079,6 +1078,10 @@ void effects_cleanup_sfx(); void sound_init(); void ui_sound_init(); void effects_play_sound(const char *snd_file); + +#ifndef NOSOUND +bool calc_snd_position(int x, int y, int *plVolume, int *plPan); int GetSFXLength(int nSFX); +#endif } // namespace devilution diff --git a/Source/effects_stubs.cpp b/Source/effects_stubs.cpp new file mode 100644 index 000000000..8c405825c --- /dev/null +++ b/Source/effects_stubs.cpp @@ -0,0 +1,26 @@ +// Stubbed implementations of effects for the NOSOUND mode. +#include "effects.h" + +namespace devilution { +int sfxdelay; +_sfx_id sfxdnum; + +// Disable clang-format here because our config says: +// AllowShortFunctionsOnASingleLine: None +// clang-format off +bool effect_is_playing(int nSFX) { return false; } +void stream_stop() { } +void InitMonsterSND(int monst) { } +void FreeMonsterSnd() { } +void PlayEffect(int i, int mode) { } +void PlaySFX(_sfx_id psfx) { } +void PlaySfxLoc(_sfx_id psfx, int x, int y, bool randomizeByCategory) { } +void sound_stop() { } +void sound_update() { } +void effects_cleanup_sfx() { } +void sound_init() { } +void ui_sound_init() { } +void effects_play_sound(const char *snd_file) { } +// clang-format off + +} // namespace devilution diff --git a/Source/gamemenu.cpp b/Source/gamemenu.cpp index 58b0e9476..42113a775 100644 --- a/Source/gamemenu.cpp +++ b/Source/gamemenu.cpp @@ -12,9 +12,12 @@ #include "loadsave.h" #include "options.h" #include "pfile.h" -#include "sound.h" #include "utils/language.h" +#ifndef NOSOUND +#include "sound.h" +#endif + namespace devilution { namespace { @@ -179,6 +182,7 @@ void gamemenu_restart_town(bool bActivate) void gamemenu_sound_music_toggle(const char *const *names, TMenuItem *menu_item, int volume) { +#ifndef NOSOUND if (gbSndInited) { menu_item->dwFlags |= GMENU_ENABLED | GMENU_SLIDER; menu_item->pszStr = names[0]; @@ -186,6 +190,7 @@ void gamemenu_sound_music_toggle(const char *const *names, TMenuItem *menu_item, gmenu_slider_set(menu_item, VOLUME_MIN, VOLUME_MAX, volume); return; } +#endif menu_item->dwFlags &= ~(GMENU_ENABLED | GMENU_SLIDER); menu_item->pszStr = names[1]; @@ -252,6 +257,7 @@ void gamemenu_music_volume(bool bActivate) { int volume; +#ifndef NOSOUND if (bActivate) { if (gbMusicOn) { gbMusicOn = false; @@ -291,11 +297,13 @@ void gamemenu_music_volume(bool bActivate) music_start(lt); } } +#endif gamemenu_get_music(); } void gamemenu_sound_volume(bool bActivate) { +#ifndef NOSOUND int volume; if (bActivate) { if (gbSoundOn) { @@ -320,6 +328,7 @@ void gamemenu_sound_volume(bool bActivate) } PlaySFX(IS_TITLEMOV); gamemenu_get_sound(); +#endif } void gamemenu_gamma(bool bActivate) diff --git a/Source/minitext.cpp b/Source/minitext.cpp index 1f2e3a00e..426bb9934 100644 --- a/Source/minitext.cpp +++ b/Source/minitext.cpp @@ -130,10 +130,17 @@ int CalcTextSpeed(int nSFX) int TextHeight; Uint32 SfxFrames; + const int numLines = GetLinesInText(qtextptr); + +#ifndef NOSOUND SfxFrames = GetSFXLength(nSFX); assert(SfxFrames != 0); +#else + // Sound is disabled -- estimate length from the number of lines. + SfxFrames = numLines * 3000; +#endif - TextHeight = lineHeight * GetLinesInText(qtextptr); + TextHeight = lineHeight * numLines; TextHeight += lineHeight * 5; // adjust so when speaker is done two line are left return SfxFrames / TextHeight; diff --git a/Source/monster.h b/Source/monster.h index 94e9395cc..c075e4851 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -11,7 +11,10 @@ #include "engine.h" #include "miniwin/miniwin.h" #include "monstdat.h" + +#ifndef NOSOUND #include "sound.h" +#endif namespace devilution { @@ -117,7 +120,9 @@ struct CMonster { /** placeflag enum as a flags*/ uint8_t mPlaceFlags; AnimStruct Anims[6]; +#ifndef NOSOUND TSnd *Snds[4][2]; +#endif int width; uint16_t mMinHP; uint16_t mMaxHP; diff --git a/Source/movie.cpp b/Source/movie.cpp index 58ee05f14..8df902be4 100644 --- a/Source/movie.cpp +++ b/Source/movie.cpp @@ -6,10 +6,13 @@ #include "diablo.h" #include "effects.h" -#include "sound.h" #include "storm/storm_svid.h" #include "utils/display.h" +#ifndef NOSOUND +#include "sound.h" +#endif + namespace devilution { /** Should the movie continue playing. */ @@ -27,9 +30,12 @@ void play_movie(const char *pszMovie, bool user_can_close) HANDLE video_stream; movie_playing = true; + +#ifndef NOSOUND sound_disable_music(true); stream_stop(); effects_play_sound("Sfx\\Misc\\blank.wav"); +#endif SVidPlayBegin(pszMovie, loop_movie ? 0x100C0808 : 0x10280808, &video_stream); MSG Msg; @@ -53,7 +59,11 @@ void play_movie(const char *pszMovie, bool user_can_close) } if (video_stream != nullptr) SVidPlayEnd(video_stream); + +#ifndef NOSOUND sound_disable_music(false); +#endif + movie_playing = false; SDL_GetMouseState(&MouseX, &MouseY); OutputToLogical(&MouseX, &MouseY); diff --git a/Source/sound.h b/Source/sound.h index ab2aeeecb..da259eed4 100644 --- a/Source/sound.h +++ b/Source/sound.h @@ -8,7 +8,10 @@ #include #include "miniwin/miniwin.h" + +#ifndef NOSOUND #include "utils/soundsample.h" +#endif namespace devilution { @@ -28,11 +31,13 @@ enum _music_id : uint8_t { }; struct TSnd { +#ifndef NOSOUND const char *sound_path; /** Used for streamed audio */ HANDLE file_handle; SoundSample *DSB; Uint32 start_tc; +#endif }; extern bool gbSndInited; @@ -55,6 +60,5 @@ int sound_get_or_set_sound_volume(int volume); extern bool gbMusicOn; extern bool gbSoundOn; -extern bool gbDupSounds; } // namespace devilution diff --git a/Source/sound_stubs.cpp b/Source/sound_stubs.cpp new file mode 100644 index 000000000..6c1beb9a9 --- /dev/null +++ b/Source/sound_stubs.cpp @@ -0,0 +1,28 @@ +// Stubbed implementations of sound functions for the NOSOUND mode. +#include "sound.h" + +namespace devilution { + +bool gbSndInited; +bool gbMusicOn; +bool gbSoundOn; + +// Disable clang-format here because our config says: +// AllowShortFunctionsOnASingleLine: None +// clang-format off +void snd_update(bool bStopAll) { } +void snd_stop_snd(TSnd *pSnd) { } +bool snd_playing(TSnd *pSnd) { return false; } +void snd_play_snd(TSnd *pSnd, int lVolume, int lPan) { } +TSnd *sound_file_load(const char *path, bool stream) { return nullptr; } +void sound_file_cleanup(TSnd *sound_file) { } +void snd_init() { } +void snd_deinit() { } +void music_stop() { } +void music_start(uint8_t nTrack) { } +void sound_disable_music(bool disable) { } +int sound_get_or_set_music_volume(int volume) { return 0; } +int sound_get_or_set_sound_volume(int volume) { return 0; } +// clang-format on + +} // namespace devilution diff --git a/Source/storm/storm_svid.cpp b/Source/storm/storm_svid.cpp index d40c25611..717a2fa6d 100644 --- a/Source/storm/storm_svid.cpp +++ b/Source/storm/storm_svid.cpp @@ -6,28 +6,34 @@ #include #include + +#ifndef NOSOUND #include #include +#include "utils/push_aulib_decoder.h" +#endif + #include "dx.h" #include "options.h" #include "palette.h" #include "storm/storm.h" #include "utils/display.h" -#include "utils/push_aulib_decoder.h" #include "utils/sdl_compat.h" #include "utils/log.hpp" namespace devilution { namespace { +#ifndef NOSOUND std::optional SVidAudioStream; PushAulibDecoder *SVidAudioDecoder; +std::uint8_t SVidAudioDepth; +#endif unsigned long SVidWidth, SVidHeight; double SVidFrameEnd; double SVidFrameLength; -std::uint8_t SVidAudioDepth; BYTE SVidLoop; smk SVidSMK; SDL_Color SVidPreviousPalette[256]; @@ -99,10 +105,12 @@ void TrySetVideoModeToSVidForSDL1() } #endif +#ifndef NOSOUND bool HaveAudio() { return SVidAudioStream && SVidAudioStream->isPlaying(); } +#endif bool SVidLoadNextFrame() { @@ -131,7 +139,6 @@ void SVidPlayBegin(const char *filename, int flags, HANDLE *video) if ((flags & 0x40000) != 0) SVidLoop = true; bool enableVideo = (flags & 0x100000) == 0; - bool enableAudio = (flags & 0x1000000) == 0; //0x8 // Non-interlaced //0x200, 0x800 // Upscale video //0x80000 // Center horizontally @@ -149,6 +156,9 @@ void SVidPlayBegin(const char *filename, int flags, HANDLE *video) return; } +#ifndef NOSOUND + const bool enableAudio = (flags & 0x1000000) == 0; + constexpr std::size_t MaxSmkChannels = 7; unsigned char channels[MaxSmkChannels]; unsigned char depth[MaxSmkChannels]; @@ -178,6 +188,7 @@ void SVidPlayBegin(const char *filename, int flags, HANDLE *video) SVidAudioDecoder = nullptr; } } +#endif unsigned long nFrames; smk_info_all(SVidSMK, nullptr, &nFrames, &SVidFrameLength); @@ -257,6 +268,7 @@ bool SVidPlayContinue() return SVidLoadNextFrame(); // Skip video and audio if the system is to slow } +#ifndef NOSOUND if (HaveAudio()) { const auto len = smk_get_audio_size(SVidSMK, 0); const unsigned char *buf = smk_get_audio(SVidSMK, 0); @@ -266,6 +278,7 @@ bool SVidPlayContinue() SVidAudioDecoder->PushSamples(reinterpret_cast(buf), len); } } +#endif if (SDL_GetTicks() * 1000 >= SVidFrameEnd) { return SVidLoadNextFrame(); // Skip video if the system is to slow @@ -335,10 +348,12 @@ bool SVidPlayContinue() void SVidPlayEnd(HANDLE video) { +#ifndef NOSOUND if (HaveAudio()) { SVidAudioStream = std::nullopt; SVidAudioDecoder = nullptr; } +#endif if (SVidSMK != nullptr) smk_close(SVidSMK); diff --git a/Source/utils/display.cpp b/Source/utils/display.cpp index d6113dab3..2f3294b92 100644 --- a/Source/utils/display.cpp +++ b/Source/utils/display.cpp @@ -134,7 +134,10 @@ bool SpawnWindow(const char *lpWindowName) SDL_setenv("SDL_AUDIODRIVER", "winmm", /*overwrite=*/false); #endif - int initFlags = SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; + int initFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; +#ifndef NOSOUND + initFlags |= SDL_INIT_AUDIO; +#endif #ifndef USE_SDL1 initFlags |= SDL_INIT_GAMECONTROLLER; #endif