From b04cab3ec0ad5f89cd2fbe6c6374c5c680405316 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 1 May 2019 16:11:48 +0800 Subject: [PATCH] Enable music in snowballs --- code/snowballs2/bin/snowballs_client.cfg | 6 +- .../bin/snowballs_client_default.cfg | 3 +- code/snowballs2/client/src/CMakeLists.txt | 4 +- code/snowballs2/client/src/entities.cpp | 4 +- .../client/src/snowballs_client.cpp | 56 +-- code/snowballs2/client/src/snowballs_config.h | 4 +- code/snowballs2/client/src/sound.cpp | 360 ++++++++++-------- code/snowballs2/client/src/sound.h | 36 +- 8 files changed, 252 insertions(+), 221 deletions(-) diff --git a/code/snowballs2/bin/snowballs_client.cfg b/code/snowballs2/bin/snowballs_client.cfg index 9cc10b7ad..b2432c733 100644 --- a/code/snowballs2/bin/snowballs_client.cfg +++ b/code/snowballs2/bin/snowballs_client.cfg @@ -7,10 +7,12 @@ Password = "password2"; LSHost = "opennel.org:49994"; FSHost = ""; SaveConfig = 1; -SoundEnabled = 0; -SoundDriver = "FMod"; +SoundEnabled = 1; +SoundDriver = "OpenAl"; +MusicVolume = 0.2; ScreenWidth = 1024; ScreenHeight = 768; +ScreenFull = 0; ShardId = 300; UseDirectClient = 1; ClientApplication = "snowballs"; diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index f8af00386..af099a449 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -75,12 +75,13 @@ HMDDevice = "Auto"; ////////////////////////////////////////////////////////////////////////////// // The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl" -SoundDriver = "FMod"; +SoundDriver = "OpenAl"; SoundMaxTracks = 32; SoundUseEax = 1; SoundUseADPCM = 1; SoundForceSoftware = 1; SoundEnabled = 1; +MusicVolume = 0.2; ////////////////////////////////////////////////////////////////////////////// diff --git a/code/snowballs2/client/src/CMakeLists.txt b/code/snowballs2/client/src/CMakeLists.txt index 8125eb3c2..18a2c126c 100644 --- a/code/snowballs2/client/src/CMakeLists.txt +++ b/code/snowballs2/client/src/CMakeLists.txt @@ -12,9 +12,9 @@ NL_DEFAULT_PROPS(snowballs_client "Snowballs, Client: Snowballs Client") NL_ADD_RUNTIME_FLAGS(snowballs_client) # If sound is enabled then add the definitions and link the libraries. -IF(ENABLE_SOUND) +IF(WITH_SOUND) ADD_DEFINITIONS(-DSBCLIENT_WITH_SOUND) - TARGET_LINK_LIBRARIES(snowballs_client ${NELSOUND_LIBRARY}) + TARGET_LINK_LIBRARIES(snowballs_client nelsound) ENDIF() INSTALL(TARGETS snowballs_client RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT snowballsclient) diff --git a/code/snowballs2/client/src/entities.cpp b/code/snowballs2/client/src/entities.cpp index 2972aebf1..dde6df257 100644 --- a/code/snowballs2/client/src/entities.cpp +++ b/code/snowballs2/client/src/entities.cpp @@ -762,10 +762,10 @@ void updateEntities () switch (entity.Type) { case CEntity::Self: - jdir = CVector(-(float)cos(entity.Angle), -(float)sin(entity.Angle), 0.0f); + jdir = CVector(-(float)cos(entity.Angle - (Pi * 0.5)), -(float)sin(entity.Angle - (Pi * 0.5)), 0.0f); break; case CEntity::Other: - jdir = CVector(-(float)cos(entity.Angle), -(float)sin(entity.Angle), 0.0f); + jdir = CVector(-(float)cos(entity.Angle - (Pi * 0.5)), -(float)sin(entity.Angle - (Pi * 0.5)), 0.0f); break; case CEntity::Snowball: jdir = entity.Trajectory.evalSpeed(LocalTime).normed(); diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 059960922..28f957589 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -68,6 +68,7 @@ #include "interface.h" #include "lens_flare.h" #include "mouse_listener.h" +#include "sound.h" #include "configuration.h" #include "internationalization.h" #include "game_time.h" @@ -301,6 +302,8 @@ void initCore() LoadedCore = true; // Seed the randomizer srand(uint(time(0))); + // Sheet Id + CSheetId::initWithoutSheet(); // Temporary for sound // Load configuration file, set paths, extension remapping CConfiguration::init(); // Load language file @@ -333,11 +336,9 @@ void initCore() displayLoadingState("Initialize Loading"); initLoadingState(); // Initialize sound for loading screens etc -//#ifdef NL_OS_WINDOWS -// displayLoadingState("Initialize Sound"); -// initSound(); -// playMusic(SBCLIENT_MUSIC_WAIT); -//#endif + displayLoadingState("Initialize Sound"); + initSound(); + playMusic(SBCLIENT_MUSIC_WAIT); // Required for 3d rendering (3d nel logo etc) displayLoadingState("Initialize Light"); initLight(); @@ -366,9 +367,7 @@ void initIngame() if (!LoadedIngame) { LoadedIngame = true; -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_WAIT); -//#endif + playMusic(SBCLIENT_MUSIC_WAIT); displayLoadingState("Initialize"); // Create a scene @@ -441,10 +440,9 @@ void initIngame() void initOnline() { - if (LoadedOnline) return; -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_WAIT); -//#endif + if (LoadedOnline) + return; + playMusic(SBCLIENT_MUSIC_WAIT); displayLoadingState("Connecting"); @@ -460,9 +458,7 @@ void initOnline() displayLoadingState("Ready!"); -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_BACKGROUND); -//#endif + playMusic(SBCLIENT_MUSIC_BACKGROUND); LoadedOnline = true; } @@ -471,9 +467,7 @@ void initOffline() if (!LoadedOffline) { LoadedOffline = true; -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_WAIT); -//#endif + playMusic(SBCLIENT_MUSIC_WAIT); uint32 id = NextEID++; Login = ucstring("Entity" + toString(id)); @@ -492,9 +486,7 @@ void initOffline() displayLoadingState("Ready!"); -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_BACKGROUND); -//#endif + playMusic(SBCLIENT_MUSIC_BACKGROUND); } } @@ -517,9 +509,7 @@ void releaseCore() // Release the loading state textures releaseLoadingState(); // Release the sound -//#ifdef NL_OS_WINDOWS -// releaseSound(); -//#endif + releaseSound(); // Release the text context Driver->deleteTextContext(TextContext); TextContext = NULL; @@ -529,11 +519,13 @@ void releaseCore() Driver = NULL; // Release timing system - CGameTime::init(); + CGameTime::release(); // Release language file - CInternationalization::init(); + CInternationalization::release(); // Release the configuration CConfiguration::release(); + // Release sheet id + CSheetId::uninit(); // Temporary for sound } } @@ -611,9 +603,7 @@ void releaseOffline() void loopLogin() { -//#ifdef NL_OS_WINDOWS -// playMusic(SBCLIENT_MUSIC_LOGIN); -//#endif + playMusic(SBCLIENT_MUSIC_LOGIN); // todo: login screen, move this stuff to a button or something displayLoadingState("Login"); if (ConfigFile->getVar("Local").asInt() == 0) @@ -730,9 +720,7 @@ void loopIngame() // ... // 11. Update Sound (sound driver) -//#ifdef NL_OS_WINDOWS -// updateSound(); // Update the sound -//#endif + updateSound(); // Update the sound // 12. Update Outgoing (network, send new position etc) // ... @@ -1118,9 +1106,7 @@ void updateLoadingState(const char *state, bool network, bool information) void updateLoadingState(ucstring state, bool network, bool information) { CGameTime::updateTime(); // important that time is updated here!!! -//#ifdef NL_OS_WINDOWS -// updateSound(); -//#endif + updateSound(); renderLoadingState(state, true); if (information) renderInformation(); if (network) updateNetwork(); diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h index 2e6b848fb..ee216f3c5 100644 --- a/code/snowballs2/client/src/snowballs_config.h +++ b/code/snowballs2/client/src/snowballs_config.h @@ -41,7 +41,9 @@ // - Bloom // 2.2 // - OculusVR support -#define SBCLIENT_VERSION "2.2" +// 2.3 +// - Add music +#define SBCLIENT_VERSION "2.3" diff --git a/code/snowballs2/client/src/sound.cpp b/code/snowballs2/client/src/sound.cpp index 7ad802e03..f0a767825 100644 --- a/code/snowballs2/client/src/sound.cpp +++ b/code/snowballs2/client/src/sound.cpp @@ -30,8 +30,10 @@ #include #include +#include "snowballs_client.h" #include "sound.h" #include "entities.h" +#include "configuration.h" // // Namespaces @@ -41,116 +43,149 @@ using namespace std; using namespace NLMISC; using namespace NLSOUND; -#ifdef SBCLIENT_WITH_SOUND +namespace SBCLIENT +{ -//// -//// Variables -//// // -//UAudioMixer *AudioMixer = NULL; +// Variables +/// + +#ifdef SBCLIENT_WITH_SOUND +UAudioMixer *AudioMixer = NULL; //TSoundId SoundId; //const vector *SoundIdArray; -//static bool SoundEnabled; -// -//// -//// Functions -//// -// -//#ifdef NL_OS_WINDOWS -//void initSound2(); -//void releaseSound2(); -//#endif -// -//void cbConfigFileSoundMaxTracks(NLMISC::CConfigFile::CVar &var) -//{ -////#ifdef NL_OS_WINDOWS -//// AudioMixer->changeMaxTrack(var.asInt()); -////#endif -//} -// -//void cbConfigFileSoundEnabled(NLMISC::CConfigFile::CVar &var) -//{ -////#ifdef NL_OS_WINDOWS -//// if (var.asBool() != SoundEnabled) -//// { -//// if (var.asBool()) initSound2(); -//// else releaseSound2(); -//// } -////#endif -//} -// -//void cbConfigFileFail(NLMISC::CConfigFile::CVar &var) -//{ -// //nlwarning("You can't modify the config variable '%s' at runtime for now, please restart the game", var.asString().c_str()); -//} -// -////#ifdef NL_OS_WINDOWS -////void initSound2() -////{ -//// AudioMixer = UAudioMixer::createAudioMixer (); -//// std::string driverName; -//// NLSOUND::UAudioMixer::TDriver driverType; -//// if (!ConfigFile->exists("SoundDriver")) -////#ifdef NL_OS_WINDOWS -//// driverType = NLSOUND::UAudioMixer::DriverFMod; -////#elif defined (NL_OS_UNIX) -//// driverType = NLSOUND::UAudioMixer::DriverOpenAl; -////#else -//// driverType = NLSOUND::UAudioMixer::DriverAuto; -////#endif -//// else -//// { -//// driverName = ConfigFile->getVar("SoundDriver").asString(); -//// if (driverName == "Auto") driverType = NLSOUND::UAudioMixer::DriverAuto; -//// else if (driverName == "FMod") driverType = NLSOUND::UAudioMixer::DriverFMod; -//// else if (driverName == "DSound") driverType = NLSOUND::UAudioMixer::DriverDSound; -//// else if (driverName == "OpenAl") driverType = NLSOUND::UAudioMixer::DriverOpenAl; -//// else nlerror("SoundDriver value '%s' is invalid.", driverName.c_str()); -//// } -//// -//// AudioMixer->init( -//// ConfigFile->exists("SoundMaxTracks") -//// ? ConfigFile->getVar("SoundMaxTracks").asInt() : 32, -//// ConfigFile->exists("SoundUseEax") -//// ? ConfigFile->getVar("SoundUseEax").asBool() : true, -//// ConfigFile->exists("SoundUseADPCM") -//// ? ConfigFile->getVar("SoundUseADPCM").asBool() : true, -//// NULL, false, driverType, -//// ConfigFile->exists("SoundForceSoftware") -//// ? ConfigFile->getVar("SoundForceSoftware").asBool() : true); -//// -//// ConfigFile->setCallback("SoundMaxTracks", cbConfigFileSoundMaxTracks); -//// ConfigFile->setCallback("SoundUseEax", cbConfigFileFail); -//// ConfigFile->setCallback("SoundUseADPCM", cbConfigFileFail); -//// ConfigFile->setCallback("SoundForceSoftware", cbConfigFileFail); -//// ConfigFile->setCallback("SoundDriver", cbConfigFileFail); -//// -//// PlaylistManager = new SBCLIENT::CMusicPlaylistManager(AudioMixer, ConfigFile, "SoundPlaylist"); -//// -//// /* AudioMixer->loadSoundBuffers ("sounds.nss", &SoundIdArray); -//// nlassert( SoundIdArray->size() == 2 ); -//// SoundId = (*SoundIdArray)[0]; -//// // StSoundId = (*SoundIdArray)[1]; */ -//// -//// SoundEnabled = true; -////} -////#endif +static bool SoundEnabled; +#endif + // -//void initSound() -//{ -////#ifdef NL_OS_WINDOWS -//// if (ConfigFile->exists("SoundEnabled") ? ConfigFile->getVar("SoundEnabled").asBool() : false) initSound2(); -//// ConfigFile->setCallback("SoundEnabled", cbConfigFileSoundEnabled); -////#endif -//} +// Functions // + +#ifdef SBCLIENT_WITH_SOUND + +void initSound2(); +void releaseSound2(); + +void cbConfigFileSoundMaxTracks(NLMISC::CConfigFile::CVar &var) +{ + if (AudioMixer) + AudioMixer->changeMaxTrack(var.asInt()); +} + +void cbConfigFileSoundEnabled(NLMISC::CConfigFile::CVar &var) +{ + if (var.asBool() != SoundEnabled) + { + if (var.asBool()) + initSound2(); + else + releaseSound2(); + } +} + +void cbConfigFileMusicVolume(NLMISC::CConfigFile::CVar &var) +{ + if (AudioMixer) + AudioMixer->setMusicVolume(var.asFloat()); +} + +void cbConfigFileFail(NLMISC::CConfigFile::CVar &var) +{ + nlwarning("You can't modify the config variable '%s' at runtime for now, please restart the game", var.asString().c_str()); +} + +void initSound2() +{ + AudioMixer = UAudioMixer::createAudioMixer(); + std::string driverName; + NLSOUND::UAudioMixer::TDriver driverType; + if (!ConfigFile->exists("SoundDriver")) +#ifdef NL_OS_WINDOWS + driverType = NLSOUND::UAudioMixer::DriverFMod; +#elif defined(NL_OS_UNIX) + driverType = NLSOUND::UAudioMixer::DriverOpenAl; +#else + driverType = NLSOUND::UAudioMixer::DriverAuto; +#endif + else + { + driverName = ConfigFile->getVar("SoundDriver").asString(); + if (driverName == "Auto") + driverType = NLSOUND::UAudioMixer::DriverAuto; + else if (driverName == "FMod") + driverType = NLSOUND::UAudioMixer::DriverFMod; + else if (driverName == "DSound") + driverType = NLSOUND::UAudioMixer::DriverDSound; + else if (driverName == "OpenAl") + driverType = NLSOUND::UAudioMixer::DriverOpenAl; + else + nlerror("SoundDriver value '%s' is invalid.", driverName.c_str()); + } + + AudioMixer->init( + ConfigFile->exists("SoundMaxTracks") + ? ConfigFile->getVar("SoundMaxTracks").asInt() + : 32, + ConfigFile->exists("SoundUseEax") + ? ConfigFile->getVar("SoundUseEax").asBool() + : true, + ConfigFile->exists("SoundUseADPCM") + ? ConfigFile->getVar("SoundUseADPCM").asBool() + : true, + NULL, true, driverType, + ConfigFile->exists("SoundForceSoftware") + ? ConfigFile->getVar("SoundForceSoftware").asBool() + : true); + + ConfigFile->setCallback("SoundMaxTracks", cbConfigFileSoundMaxTracks); + ConfigFile->setCallback("SoundUseEax", cbConfigFileFail); + ConfigFile->setCallback("SoundUseADPCM", cbConfigFileFail); + ConfigFile->setCallback("SoundForceSoftware", cbConfigFileFail); + ConfigFile->setCallback("SoundDriver", cbConfigFileFail); + CConfiguration::setAndCallback("MusicVolume", cbConfigFileMusicVolume); + + // PlaylistManager = new SBCLIENT::CMusicPlaylistManager(AudioMixer, ConfigFile, "SoundPlaylist"); + + /* AudioMixer->loadSoundBuffers ("sounds.nss", &SoundIdArray); + nlassert( SoundIdArray->size() == 2 ); + SoundId = (*SoundIdArray)[0]; + // StSoundId = (*SoundIdArray)[1]; */ + + SoundEnabled = true; +} + +void releaseSound2() +{ + SoundEnabled = false; + ConfigFile->setCallback("SoundMaxTracks", NULL); + ConfigFile->setCallback("SoundUseEax", NULL); + ConfigFile->setCallback("SoundUseADPCM", NULL); + ConfigFile->setCallback("SoundForceSoftware", NULL); + ConfigFile->setCallback("SoundDriver", NULL); + // delete PlaylistManager; + // PlaylistManager = NULL; + delete AudioMixer; + AudioMixer = NULL; +} + +#endif + +void initSound() +{ +#ifdef SBCLIENT_WITH_SOUND + if (ConfigFile->exists("SoundEnabled") ? ConfigFile->getVar("SoundEnabled").asBool() : false) + initSound2(); + ConfigFile->setCallback("SoundEnabled", cbConfigFileSoundEnabled); +#endif +} + //void playSound (CEntity &entity, TSoundId id) //{ ///* entity.Source = AudioMixer->createSource (id); // entity.Source->setLooping (true); // entity.Source->play (); //*/} -// + //void deleteSound (CEntity &entity) //{ ///* if (entity.Source != NULL) @@ -162,42 +197,36 @@ using namespace NLSOUND; // entity.Source = NULL; // } //*/} -// -//void updateSound() -//{ -////#ifdef NL_OS_WINDOWS -//// if (SoundEnabled) -//// { -//// PlaylistManager->update(DiffTime); -//// AudioMixer->update(); -//// } -////#endif -//} -// -////#ifdef NL_OS_WINDOWS -////void releaseSound2() -////{ -//// SoundEnabled = false; -//// ConfigFile->setCallback("SoundMaxTracks", NULL); -//// ConfigFile->setCallback("SoundUseEax", NULL); -//// ConfigFile->setCallback("SoundUseADPCM", NULL); -//// ConfigFile->setCallback("SoundForceSoftware", NULL); -//// ConfigFile->setCallback("SoundDriver", NULL); -//// delete PlaylistManager; -//// PlaylistManager = NULL; -//// delete AudioMixer; -//// AudioMixer = NULL; -////} -////#endif -// -//void releaseSound() -//{ -////#ifdef NL_OS_WINDOWS -//// ConfigFile->setCallback("SoundEnabled", NULL); -//// if (SoundEnabled) releaseSound2(); -////#endif -//} -// + +void updateSound() +{ +#ifdef SBCLIENT_WITH_SOUND + if (SoundEnabled) + { + // PlaylistManager->update(DiffTime); + AudioMixer->update(); + } + #endif +} + +void releaseSound() +{ +#ifdef SBCLIENT_WITH_SOUND + ConfigFile->setCallback("SoundEnabled", NULL); + if (SoundEnabled) releaseSound2(); +#endif +} + +void playMusic(const char *file) +{ +#ifdef SBCLIENT_WITH_SOUND + if (AudioMixer) + AudioMixer->playMusic(file, 1000, true, true); +#endif +} + +} /* namespace SBCLIENT */ + ////#ifdef NL_OS_WINDOWS //// ////void playMusic(sint32 playlist, sint32 track) @@ -211,35 +240,38 @@ using namespace NLSOUND; //// if (SoundEnabled) //// PlaylistManager->setVolume(playlist, volume); ////} -//// -////NLMISC_COMMAND(music_bg,"background music","") -////{ -//// if (args.size() != 0) return false; -//// playMusic(SBCLIENT_MUSIC_BACKGROUND); -//// return true; -////} -//// -////NLMISC_COMMAND(music_bg_beat,"background music with beat","") -////{ -//// if (args.size() != 0) return false; -//// PlaylistManager->playMusic(SBCLIENT_MUSIC_BACKGROUND_BEAT); -//// return true; -////} -//// -////NLMISC_COMMAND(music_wait,"loading music","") -////{ -//// if (args.size() != 0) return false; -//// PlaylistManager->playMusic(SBCLIENT_MUSIC_WAIT); -//// return true; -////} -//// -////NLMISC_COMMAND(music_login,"login screen music","") -////{ -//// if (args.size() != 0) return false; -//// PlaylistManager->playMusic(SBCLIENT_MUSIC_LOGIN); -//// return true; -////} -//// + +NLMISC_COMMAND(music_bg,"background music","") +{ + if (args.size() != 0) return false; + SBCLIENT::playMusic(SBCLIENT_MUSIC_BACKGROUND); + return true; +} + +NLMISC_COMMAND(music_bg_beat,"background music with beat","") +{ + if (args.size() != 0) + return false; + SBCLIENT::playMusic(SBCLIENT_MUSIC_BACKGROUND_BEAT); + return true; +} + +NLMISC_COMMAND(music_wait,"loading music","") +{ + if (args.size() != 0) + return false; + SBCLIENT::playMusic(SBCLIENT_MUSIC_WAIT); + return true; +} + +NLMISC_COMMAND(music_login,"login screen music","") +{ + if (args.size() != 0) + return false; + SBCLIENT::playMusic(SBCLIENT_MUSIC_LOGIN); + return true; +} + ////#endif -#endif // SBCLIENT_WITH_SOUND +/* end of file */ diff --git a/code/snowballs2/client/src/sound.h b/code/snowballs2/client/src/sound.h index 2862d141c..34b0d6723 100644 --- a/code/snowballs2/client/src/sound.h +++ b/code/snowballs2/client/src/sound.h @@ -35,35 +35,43 @@ // Defines // -//#define SBCLIENT_MUSIC_WAIT (0), (0) -//#define SBCLIENT_MUSIC_LOGIN (1), (0) -//#define SBCLIENT_MUSIC_BACKGROUND (2), (0) -//#define SBCLIENT_MUSIC_BACKGROUND_BEAT (2), (1) +#define SBCLIENT_MUSIC_WAIT "xtarsia_evil-snowballs_wait.ogg" +#define SBCLIENT_MUSIC_LOGIN "xtarsia_evil-snowballs_login.ogg" +#define SBCLIENT_MUSIC_BACKGROUND "xtarsia_evil-snowballs_beat.ogg" /* "xtarsia_evil-snowballs_game.ogg" */ +#define SBCLIENT_MUSIC_BACKGROUND_BEAT "xtarsia_evil-snowballs_beat.ogg" + +namespace SBCLIENT { // // External variables // -//extern NLSOUND::UAudioMixer *AudioMixer; +#ifdef SBCLIENT_WITH_SOUND +extern NLSOUND::UAudioMixer *AudioMixer; //extern NLSOUND::TSoundId SoundId; +#endif + // -//// -//// External functions -//// +// External functions // + //void playMusic(sint32 playlist, sint32 track); //void setMusicVolume(sint32 playlist, float volume); -// -//void initSound(); -//void updateSound(); -//void releaseSound(); -// + +void initSound(); +void updateSound(); +void releaseSound(); + +void playMusic(const char *file); + //// Set and play a sound on an entity //void playSound(CEntity &entity, NLSOUND::TSoundId id); -// + //// Remove the sound system link to the entity //void deleteSound(CEntity &entity); +} /* namespace SBCLIENT */ + #endif // SBCLIENT_SOUND_H /* End of sound.h */ // duh