From 900ec1a69ae4dd7dd721aaa6f5896c6141850818 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 9 Apr 2020 12:17:17 +0800 Subject: [PATCH] Play theme music during login. Fix music when returning to character selection. Fix teleport screen and music selection. --- nel/include/nel/sound/music_channel_fader.h | 2 +- nel/src/sound/music_channel_fader.cpp | 12 +- ryzom/client/src/client_cfg.cpp | 14 +- ryzom/client/src/client_cfg.h | 9 +- ryzom/client/src/connection.cpp | 139 +++++++++++--------- ryzom/client/src/far_tp.cpp | 24 ++-- ryzom/client/src/init.cpp | 85 +++++------- ryzom/client/src/init_main_loop.cpp | 21 +++ ryzom/client/src/login.cpp | 2 + ryzom/client/src/main_loop.cpp | 16 ++- ryzom/client/src/net_manager.cpp | 39 +++--- ryzom/client/src/user_entity.cpp | 11 +- 12 files changed, 214 insertions(+), 160 deletions(-) diff --git a/nel/include/nel/sound/music_channel_fader.h b/nel/include/nel/sound/music_channel_fader.h index 6bb5677f9..577d23949 100644 --- a/nel/include/nel/sound/music_channel_fader.h +++ b/nel/include/nel/sound/music_channel_fader.h @@ -108,7 +108,7 @@ public: bool play(const std::string &filepath, uint xFadeTime = 0, bool async = true, bool loop = true); /// Stop the music previously loaded and played (the Memory is also freed) - void stop(uint xFadeTime = 0); + bool stop(uint xFadeTime = 0); /// Pause the music previously loaded and played (the Memory is not freed) void pause(); diff --git a/nel/src/sound/music_channel_fader.cpp b/nel/src/sound/music_channel_fader.cpp index ea2cc6341..70ab890d2 100644 --- a/nel/src/sound/music_channel_fader.cpp +++ b/nel/src/sound/music_channel_fader.cpp @@ -147,7 +147,7 @@ void CMusicChannelFader::updateVolume() */ bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool async, bool loop) { - stop(xFadeTime); + bool stopped = stop(xFadeTime); // Find the next best free music channel uint nextFader = _MaxMusicFader; @@ -164,7 +164,7 @@ bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool // Play a song in it :) _CMusicFader &fader = _MusicFader[_ActiveMusicFader]; - if (xFadeTime) fader.fadeIn(xFadeTime); + if (xFadeTime && !stopped) fader.fadeIn(xFadeTime); // only fade in when fading out else fader.XFadeVolume = 1.0f; fader.Playing = true; updateVolume(); // make sure at ok volume to start :) @@ -173,12 +173,17 @@ bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool } /// Stop the music previously loaded and played (the Memory is also freed) -void CMusicChannelFader::stop(uint xFadeTime) +bool CMusicChannelFader::stop(uint xFadeTime) { if (xFadeTime) { + bool stopped = true; for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].Playing) + { _MusicFader[i].fadeOut(xFadeTime); + stopped = false; // fading + } + return stopped; } else { @@ -188,6 +193,7 @@ void CMusicChannelFader::stop(uint xFadeTime) _MusicFader[i].Fade = false; _MusicFader[i].Playing = false; } + return true; } } diff --git a/ryzom/client/src/client_cfg.cpp b/ryzom/client/src/client_cfg.cpp index 985f052db..7588f6b57 100644 --- a/ryzom/client/src/client_cfg.cpp +++ b/ryzom/client/src/client_cfg.cpp @@ -465,7 +465,12 @@ CClientConfig::CClientConfig() SoundOn = true; // Default is with sound. DriverSound = SoundDrvAuto; SoundForceSoftwareBuffer = true; - SoundOutGameMusic = "main menu loop.ogg"; + StartMusic = "main theme air.ogg"; // Use at game startup + LoadingMusic = "main menu loop.ogg"; // Use after leaving character selection, and when going back to character selection + KamiTeleportMusic = "kami teleport.ogg"; // Kami teleport + KaravanTeleportMusic = "karavan teleport.ogg"; // Karavan teleport + TeleportLoadingMusic = "loading music loop.ogg"; // Use after character select, and for generic teleportations + DeathMusic = "death.ogg"; // Player death SoundSFXVolume = 1.f; SoundGameMusicVolume = 1.f; SoundTPFade = 500; @@ -1247,7 +1252,12 @@ void CClientConfig::setValues() // SoundForceSoftwareBuffer READ_BOOL_FV(SoundForceSoftwareBuffer); // SoundOutGameMusic - READ_STRING_DEV(SoundOutGameMusic) + READ_STRING_DEV(StartMusic) + READ_STRING_DEV(LoadingMusic) + READ_STRING_DEV(KamiTeleportMusic) + READ_STRING_DEV(KaravanTeleportMusic) + READ_STRING_DEV(TeleportLoadingMusic) + READ_STRING_DEV(DeathMusic) // SoundSFXVolume READ_FLOAT_FV(SoundSFXVolume); // SoundGameMusicVolume diff --git a/ryzom/client/src/client_cfg.h b/ryzom/client/src/client_cfg.h index a5eff6883..716972c3a 100644 --- a/ryzom/client/src/client_cfg.h +++ b/ryzom/client/src/client_cfg.h @@ -348,8 +348,13 @@ struct CClientConfig /// SoundForceSoftwareBuffer bool SoundForceSoftwareBuffer; - /// The outgame music file - string SoundOutGameMusic; + /// Music files + string StartMusic; + string LoadingMusic; + string KamiTeleportMusic; + string KaravanTeleportMusic; + string TeleportLoadingMusic; + string DeathMusic; /// The Sound SFX Volume (0-1) (ie all but music) float SoundSFXVolume; diff --git a/ryzom/client/src/connection.cpp b/ryzom/client/src/connection.cpp index b53c571e6..9c9dce6da 100644 --- a/ryzom/client/src/connection.cpp +++ b/ryzom/client/src/connection.cpp @@ -273,6 +273,73 @@ void setOutGameFullScreen() CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768); } +// ------------------------------------------------------------------------------------------------ +class CSoundGlobalMenu +{ +public: + CSoundGlobalMenu() + { + _MusicWantedAsync= false; + _NbFrameBeforeChange= NbFrameBeforeChangeMax; + } + void reset(); + void setMusic(const string &music, bool async); + void updateSound(); +private: + string _MusicPlayed; + string _MusicWanted; + bool _MusicWantedAsync; + sint _NbFrameBeforeChange; + enum {NbFrameBeforeChangeMax= 10}; +}; + +void CSoundGlobalMenu::reset() +{ + _MusicPlayed.clear(); + _MusicWanted.clear(); +} + +void CSoundGlobalMenu::updateSound() +{ + // **** update the music played + // The first music played is the music played at loading, before select char + if (_MusicPlayed.empty()) + _MusicPlayed = toLower(LoadingMusic.empty() ? ClientCfg.StartMusic : LoadingMusic); + if (_MusicWanted.empty()) + _MusicWanted = toLower(LoadingMusic.empty() ? ClientCfg.StartMusic : LoadingMusic); + + // because music is changed when the player select other race for instance, + // wait the 3D to load (stall some secs) + + // if the wanted music is the same as the one currently playing, just continue playing + if(_MusicPlayed!=_MusicWanted) + { + // wait nbFrameBeforeChangeMax before actually changing the music + _NbFrameBeforeChange--; + if(_NbFrameBeforeChange<=0) + { + _MusicPlayed= _MusicWanted; + // play the music + if (SoundMngr != NULL) + SoundMngr->playMusic(_MusicPlayed, 500, _MusicWantedAsync, true, true); + } + } + + + // **** update mngr + if (SoundMngr != NULL) + SoundMngr->update(); +} + +void CSoundGlobalMenu::setMusic(const string &music, bool async) +{ + _MusicWanted= toLower(music); + _MusicWantedAsync= async; + // reset the counter + _NbFrameBeforeChange= NbFrameBeforeChangeMax; +} +static CSoundGlobalMenu SoundGlobalMenu; + // New version of the menu after the server connection // @@ -405,6 +472,8 @@ bool connection (const string &cookie, const string &fsaddr) InterfaceState = GLOBAL_MENU; } + // No loading music here, this is right before character selection, using the existing music + // Create the loading texture. We can't do that before because we need to add search path first. beginLoading (LoadBackground); UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING; @@ -507,6 +576,7 @@ bool reconnection() ProgressBar.setFontFactor(1.0f); // Init out game + SoundGlobalMenu.reset(); pIM->initOutGame(); // Hide cursor for interface @@ -522,6 +592,9 @@ bool reconnection() FarTP.setOutgame(); + if (SoundMngr) + SoundMngr->setupFadeSound(1.0f, 1.0f); + // these two globals sequence GlobalMenu to display the character select dialog WaitServerAnswer = true; userChar = true; @@ -556,6 +629,8 @@ bool reconnection() // this also kicks the state machine to sendReady() so we stop spinning in farTPmainLoop FarTP.setIngame(); + // Not loading music here, this is before character selection, keep existing music + // Create the loading texture. We can't do that before because we need to add search path first. beginLoading (LoadBackground); UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING; @@ -731,66 +806,6 @@ std::string buildPlayerNameForSaveFile(const ucstring &playerNameIn) return ret; } -// ------------------------------------------------------------------------------------------------ -class CSoundGlobalMenu -{ -public: - CSoundGlobalMenu() - { - _MusicWantedAsync= false; - _NbFrameBeforeChange= NbFrameBeforeChangeMax; - } - void setMusic(const string &music, bool async); - void updateSound(); -private: - string _MusicPlayed; - string _MusicWanted; - bool _MusicWantedAsync; - sint _NbFrameBeforeChange; - enum {NbFrameBeforeChangeMax= 10}; -}; - -void CSoundGlobalMenu::updateSound() -{ - // **** update the music played - // The first music played is the music played at loading, before select char - if(_MusicPlayed.empty()) - _MusicPlayed= toLower(ClientCfg.SoundOutGameMusic); - if(_MusicWanted.empty()) - _MusicWanted= toLower(ClientCfg.SoundOutGameMusic); - - // because music is changed when the player select other race for instance, - // wait the 3D to load (stall some secs) - - // if the wanted music is the same as the one currently playing, just continue playing - if(_MusicPlayed!=_MusicWanted) - { - // wait nbFrameBeforeChangeMax before actually changing the music - _NbFrameBeforeChange--; - if(_NbFrameBeforeChange<=0) - { - _MusicPlayed= _MusicWanted; - // play the music - if (SoundMngr != NULL) - SoundMngr->playMusic(_MusicPlayed, 500, _MusicWantedAsync, true, true); - } - } - - - // **** update mngr - if (SoundMngr != NULL) - SoundMngr->update(); -} - -void CSoundGlobalMenu::setMusic(const string &music, bool async) -{ - _MusicWanted= toLower(music); - _MusicWantedAsync= async; - // reset the counter - _NbFrameBeforeChange= NbFrameBeforeChangeMax; -} -static CSoundGlobalMenu SoundGlobalMenu; - static bool LuaBGDSuccessFlag = true; // tmp, for debug @@ -2041,8 +2056,8 @@ public: fromString(getParam(Params, "async"), async); // if empty name, return to default mode - if(sName.empty()) - sName= ClientCfg.SoundOutGameMusic; + if (sName.empty()) + sName = ClientCfg.TeleportLoadingMusic; // change the music SoundGlobalMenu.setMusic(sName, async); diff --git a/ryzom/client/src/far_tp.cpp b/ryzom/client/src/far_tp.cpp index 0a594e540..80134f26b 100644 --- a/ryzom/client/src/far_tp.cpp +++ b/ryzom/client/src/far_tp.cpp @@ -1112,15 +1112,6 @@ void CFarTP::disconnectFromPreviousShard() beginLoading (StartBackground); UseEscapeDuringLoading = false; - // Play music and fade out the Game Sound - if (SoundMngr) - { - // Loading Music Loop.ogg - LoadingMusic = ClientCfg.SoundOutGameMusic; - SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true); - SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade); - } - // Change the tips selectTipsOfTheDay (rand()); @@ -1129,6 +1120,21 @@ void CFarTP::disconnectFromPreviousShard() ucstring nmsg("Loading..."); ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); ProgressBar.progress(0); + + // Play music and fade out the Game Sound + if (SoundMngr) + { + SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade); + + // Stop and enable music + SoundMngr->stopMusic(0); + SoundMngr->setupFadeSound(0.0f, 1.0f); + + // Loading Music Loop.ogg + LoadingMusic = ClientCfg.LoadingMusic; + // SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true); + SoundMngr->playMusic(LoadingMusic, 0, false, true, true); + } } // Disconnect from the FS diff --git a/ryzom/client/src/init.cpp b/ryzom/client/src/init.cpp index efc137ee6..5e7b03549 100644 --- a/ryzom/client/src/init.cpp +++ b/ryzom/client/src/init.cpp @@ -1410,6 +1410,42 @@ void prelogInit() StereoDisplay->setDriver(Driver); // VR_DRIVER } + { + H_AUTO(InitRZSound) + + // Init the sound manager + nmsg = "Initializing sound manager..."; + ProgressBar.newMessage(ClientCfg.buildLoadingString(nmsg)); + if (ClientCfg.SoundOn) + { + nlassert(!SoundMngr); + SoundMngr = new CSoundManager(&ProgressBar); + try + { + SoundMngr->init(&ProgressBar); + } + catch(const Exception &e) + { + nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); + delete SoundMngr; + SoundMngr = NULL; + } + + // Play Music just after the SoundMngr is inited + if (SoundMngr) + { + // init the SoundMngr with backuped volume + SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); + SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); + + // Play the login screen music + SoundMngr->playMusic(ClientCfg.StartMusic, 0, true, true, true); + } + } + + CPath::memoryCompress(); // Because sound calls addSearchPath + } + nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); FPU_CHECKER_ONCE @@ -1552,55 +1588,6 @@ void postlogInit() // set the primitive context CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; - { - H_AUTO(InitRZSound) - - // Init the sound manager - nmsg = "Initializing sound manager..."; - ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); - if(ClientCfg.SoundOn) - { - SoundMngr = new CSoundManager(&ProgressBar); - try - { - SoundMngr->init(&ProgressBar); - } - catch(const Exception &e) - { - nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); - delete SoundMngr; - SoundMngr = NULL; - } - - // Play Music just after the SoundMngr is inited - if(SoundMngr) - { - // init the SoundMngr with backuped volume - SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); - SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); - - // no fadein, and not async because don't work well because of loading in the main thread - // Force use GameMusic volume - const uint fadeInTime= 500; - SoundMngr->playMusic(ClientCfg.SoundOutGameMusic, fadeInTime, false, true, true); - // Because of blocking loading, force the fadeIn - TTime t0= ryzomGetLocalTime(); - TTime t1; - while((t1=ryzomGetLocalTime())updateAudioMixerOnly(); - } - } - } - - CPath::memoryCompress(); // Because sound call addSearchPath - - initLast = initCurrent; - initCurrent = ryzomGetLocalTime(); - //nlinfo ("PROFILE: %d seconds (%d total) for Initializing sound manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000); - } - { H_AUTO(InitRZShIdI) diff --git a/ryzom/client/src/init_main_loop.cpp b/ryzom/client/src/init_main_loop.cpp index 2b391114c..deeda2149 100644 --- a/ryzom/client/src/init_main_loop.cpp +++ b/ryzom/client/src/init_main_loop.cpp @@ -473,6 +473,27 @@ void initMainLoop() FPU_CHECKER_ONCE + if (SoundMngr) + { + // Loading Music + LoadingMusic = ClientCfg.LoadingMusic; + + // SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true); + // no fadein, and not async because don't work well because of loading in the main thread + // Force use GameMusic volume + const uint fadeInTime = 500; + SoundMngr->playMusic(LoadingMusic, fadeInTime, false, true, true); + // Because of blocking loading, force the fadeIn + TTime t0 = ryzomGetLocalTime(); + TTime t1; + do + { + ProgressBar.progress(0); + SoundMngr->updateAudioMixerOnly(); + nlSleep(10); + } while ((t1 = ryzomGetLocalTime()) < t0 + fadeInTime); + } + // Get the interface manager CInterfaceManager *pIM = CInterfaceManager::getInstance(); diff --git a/ryzom/client/src/login.cpp b/ryzom/client/src/login.cpp index c9c1fdeaf..cb6117744 100644 --- a/ryzom/client/src/login.cpp +++ b/ryzom/client/src/login.cpp @@ -3279,6 +3279,7 @@ bool loginIntroSkip; void loginIntro() { // Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one) +#if 0 for (uint i = 0; i < 1; i++) // previously display nevrax then nvidia { if (i != 0) @@ -3316,6 +3317,7 @@ void loginIntro() NLGUI::CDBManager::getInstance()->flushObserverCalls(); } } +#endif beginLoading(StartBackground); ProgressBar.finish(); } diff --git a/ryzom/client/src/main_loop.cpp b/ryzom/client/src/main_loop.cpp index 760a551c2..172c4056b 100644 --- a/ryzom/client/src/main_loop.cpp +++ b/ryzom/client/src/main_loop.cpp @@ -2240,19 +2240,21 @@ bool mainLoop() { StartPlayTime = NLMISC::CTime::getLocalTime(); } + // Start background sound play now ! (nb: restarted if load just ended, or if sound re-enabled) if (SoundMngr) { H_AUTO_USE ( RZ_Client_Main_Loop_Sound ) - SoundMngr->playBackgroundSound(); - } - // Fade in Game Sound now (before endLoading) - if(SoundMngr) - { // fade out loading music - if(LoadingMusic==SoundMngr->getEventMusicPlayed()) + if (SoundMngr->getEventMusicPlayed() == LoadingMusic) + { SoundMngr->stopEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade); + } + + SoundMngr->playBackgroundSound(); + + // Fade in Game Sound now (before endLoading) // fade in game sound SoundMngr->fadeInGameSound(ClientCfg.SoundTPFade); } @@ -2516,7 +2518,7 @@ bool mainLoop() EditActions.enable(true); // For stoping the outgame music, start after 30 frames, and duration of 3 seconds -// CMusicFader outgameFader(60, 3); + outgameFader = CMusicFader(60, 3); // check for banned player if (testPermanentBanMarkers()) diff --git a/ryzom/client/src/net_manager.cpp b/ryzom/client/src/net_manager.cpp index 7ce27c4d5..642935869 100644 --- a/ryzom/client/src/net_manager.cpp +++ b/ryzom/client/src/net_manager.cpp @@ -1483,32 +1483,33 @@ void impulseTPCommon(NLMISC::CBitMemStream &impulse, bool hasSeason) void impulseTPCommon2(NLMISC::CBitMemStream &impulse, bool hasSeason) { // choose a default screen if not setuped - if( LoadingBackground!=ResurectKamiBackground && LoadingBackground!=ResurectKaravanBackground && - LoadingBackground!=TeleportKamiBackground && LoadingBackground!=TeleportKaravanBackground) - LoadingBackground= TeleportKaravanBackground; + if (LoadingBackground != ResurectKamiBackground && LoadingBackground != ResurectKaravanBackground + && LoadingBackground != TeleportKamiBackground && LoadingBackground != TeleportKaravanBackground) + LoadingBackground = ElevatorBackground; // if resurect but user not dead, choose default. NB: this is a bug, the tp impulse should tell // which background to choose. \todo yoyo: this is a temp fix - if( UserEntity && !UserEntity->isDead() && - (LoadingBackground==ResurectKamiBackground || LoadingBackground==ResurectKaravanBackground) ) - LoadingBackground= TeleportKaravanBackground; + if (UserEntity && !UserEntity->isDead() && (LoadingBackground == ResurectKamiBackground || LoadingBackground == ResurectKaravanBackground)) + LoadingBackground = ElevatorBackground; // Play music according to the background - if(SoundMngr) + if (SoundMngr) { LoadingMusic.clear(); - if(LoadingBackground==TeleportKamiBackground) - LoadingMusic= "Kami Teleport.ogg"; - else if(LoadingBackground==TeleportKaravanBackground) - LoadingMusic= "Karavan Teleport.ogg"; - // if resurection, continue to play death music - else if(LoadingBackground==ResurectKamiBackground || LoadingBackground==ResurectKaravanBackground) - { - // noop - } - // default: loading music - else + switch (LoadingBackground) { - LoadingMusic= "Loading Music Loop.ogg"; + case TeleportKamiBackground: + LoadingMusic = ClientCfg.KamiTeleportMusic; + break; + case TeleportKaravanBackground: + LoadingMusic = ClientCfg.KaravanTeleportMusic; + break; + case ResurectKamiBackground: + case ResurectKaravanBackground: + // TODO: Resurrect music + break; + default: + LoadingMusic = ClientCfg.TeleportLoadingMusic; + break; } // start to play diff --git a/ryzom/client/src/user_entity.cpp b/ryzom/client/src/user_entity.cpp index 18cd832be..5c14bf82e 100644 --- a/ryzom/client/src/user_entity.cpp +++ b/ryzom/client/src/user_entity.cpp @@ -4309,20 +4309,19 @@ void CUserEntity::updatePreCollision(const NLMISC::TTime &time, CEntityCL *targe // test each frame if the mode has changed if(SoundMngr) { - string deadMusic= "death.ogg"; // Play/stop music if comes from or goes to dead - bool isDead= _Mode==MBEHAV::DEATH || _Mode==MBEHAV::SWIM_DEATH; + bool isDead = _Mode == MBEHAV::DEATH || _Mode == MBEHAV::SWIM_DEATH; // must start music? - if( isDead && SoundMngr->getEventMusicPlayed()!=deadMusic ) + if (isDead && SoundMngr->getEventMusicPlayed() != ClientCfg.DeathMusic) { - SoundMngr->playEventMusic(deadMusic, 0, true); + SoundMngr->playEventMusic(ClientCfg.DeathMusic, 0, true); } // must end music? - if( !isDead && SoundMngr->getEventMusicPlayed()==deadMusic ) + if (!isDead && SoundMngr->getEventMusicPlayed() == ClientCfg.DeathMusic) { - SoundMngr->stopEventMusic(deadMusic, CSoundManager::LoadingMusicXFade); + SoundMngr->stopEventMusic(ClientCfg.DeathMusic, CSoundManager::LoadingMusicXFade); } } }