diff options
Diffstat (limited to 'gameui/OptionsSubAudio.cpp')
| -rw-r--r-- | gameui/OptionsSubAudio.cpp | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/gameui/OptionsSubAudio.cpp b/gameui/OptionsSubAudio.cpp new file mode 100644 index 0000000..9a4d6ae --- /dev/null +++ b/gameui/OptionsSubAudio.cpp @@ -0,0 +1,432 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "OptionsSubAudio.h" + +#include "cvarslider.h" +#include "EngineInterface.h" +#include "ModInfo.h" +#include "vgui_controls/ComboBox.h" +#include "vgui_controls/QueryBox.h" +#include "CvarToggleCheckButton.h" +#include "tier1/KeyValues.h" +#include "tier1/convar.h" +#include <vgui/IInput.h> +#include <steam/steam_api.h> +#include <tier1/strtools.h> + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace vgui; + +// This member is static so that the updated audio language can be referenced during shutdown +char* COptionsSubAudio::m_pchUpdatedAudioLanguage = (char*)GetLanguageShortName( k_Lang_English ); + +enum SoundQuality_e +{ + SOUNDQUALITY_LOW, + SOUNDQUALITY_MEDIUM, + SOUNDQUALITY_HIGH, +}; + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +COptionsSubAudio::COptionsSubAudio(vgui::Panel *parent) : PropertyPage(parent, NULL) +{ + m_pSFXSlider = new CCvarSlider( this, "SFXSlider", "#GameUI_SoundEffectVolume", 0.0f, 1.0f, "volume" ); + m_pMusicSlider = new CCvarSlider( this, "MusicSlider", "#GameUI_MusicVolume", 0.0f, 1.0f, "Snd_MusicVolume" ); + + m_pCloseCaptionCombo = new ComboBox( this, "CloseCaptionCheck", 6, false ); + m_pCloseCaptionCombo->AddItem( "#GameUI_NoClosedCaptions", NULL ); + m_pCloseCaptionCombo->AddItem( "#GameUI_SubtitlesAndSoundEffects", NULL ); + m_pCloseCaptionCombo->AddItem( "#GameUI_Subtitles", NULL ); + + m_pSoundQualityCombo = new ComboBox( this, "SoundQuality", 6, false ); + m_pSoundQualityCombo->AddItem( "#GameUI_High", new KeyValues("SoundQuality", "quality", SOUNDQUALITY_HIGH) ); + m_pSoundQualityCombo->AddItem( "#GameUI_Medium", new KeyValues("SoundQuality", "quality", SOUNDQUALITY_MEDIUM) ); + m_pSoundQualityCombo->AddItem( "#GameUI_Low", new KeyValues("SoundQuality", "quality", SOUNDQUALITY_LOW) ); + + m_pSpeakerSetupCombo = new ComboBox( this, "SpeakerSetup", 6, false ); +#ifndef POSIX + m_pSpeakerSetupCombo->AddItem( "#GameUI_Headphones", new KeyValues("SpeakerSetup", "speakers", 0) ); +#endif + m_pSpeakerSetupCombo->AddItem( "#GameUI_2Speakers", new KeyValues("SpeakerSetup", "speakers", 2) ); +#ifndef POSIX + m_pSpeakerSetupCombo->AddItem( "#GameUI_4Speakers", new KeyValues("SpeakerSetup", "speakers", 4) ); + m_pSpeakerSetupCombo->AddItem( "#GameUI_5Speakers", new KeyValues("SpeakerSetup", "speakers", 5) ); + m_pSpeakerSetupCombo->AddItem( "#GameUI_7Speakers", new KeyValues("SpeakerSetup", "speakers", 7) ); +#endif + m_pSpokenLanguageCombo = new ComboBox (this, "AudioSpokenLanguage", 6, false ); + + m_pSoundMuteLoseFocusCheckButton = new CCvarToggleCheckButton( this, "snd_mute_losefocus", "#GameUI_SndMuteLoseFocus", "snd_mute_losefocus" ); + + LoadControlSettings("Resource\\OptionsSubAudio.res"); +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +COptionsSubAudio::~COptionsSubAudio() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Reloads data +//----------------------------------------------------------------------------- +void COptionsSubAudio::OnResetData() +{ + m_bRequireRestart = false; + m_pSFXSlider->Reset(); + m_pMusicSlider->Reset(); + + + // reset the combo boxes + + // close captions + ConVarRef closecaption("closecaption"); + ConVarRef cc_subtitles("cc_subtitles"); + if (closecaption.GetBool()) + { + if (cc_subtitles.GetBool()) + { + m_pCloseCaptionCombo->ActivateItem(2); + } + else + { + m_pCloseCaptionCombo->ActivateItem(1); + } + } + else + { + m_pCloseCaptionCombo->ActivateItem(0); + } + + // speakers + ConVarRef snd_surround_speakers("Snd_Surround_Speakers"); + int speakers = snd_surround_speakers.GetInt(); + +#ifdef POSIX + // On Posix there is no headphone option, so we upgrade to 2 speakers if Snd_Surround_Speakers == 0 + if ( speakers == 0 ) + speakers = 2; +#endif + + // if Snd_Surround_Speakers is -1, then upgrade to 2 speakers + if ( speakers < 0 ) + speakers = 2; + + {for (int itemID = 0; itemID < m_pSpeakerSetupCombo->GetItemCount(); itemID++) + { + KeyValues *kv = m_pSpeakerSetupCombo->GetItemUserData( itemID ); + if (kv && kv->GetInt( "speakers" ) == speakers) + { + m_pSpeakerSetupCombo->ActivateItem( itemID ); + break; + } + }} + + // sound quality is made up from several cvars + ConVarRef Snd_PitchQuality("Snd_PitchQuality"); + ConVarRef dsp_slow_cpu("dsp_slow_cpu"); + int quality = SOUNDQUALITY_LOW; + if (dsp_slow_cpu.GetBool() == false) + { + quality = SOUNDQUALITY_MEDIUM; + } + if (Snd_PitchQuality.GetBool()) + { + quality = SOUNDQUALITY_HIGH; + } + // find the item in the list and activate it + {for (int itemID = 0; itemID < m_pSoundQualityCombo->GetItemCount(); itemID++) + { + KeyValues *kv = m_pSoundQualityCombo->GetItemUserData(itemID); + if (kv && kv->GetInt("quality") == quality) + { + m_pSoundQualityCombo->ActivateItem(itemID); + } + }} + + // + // Audio Languages + // + char szCurrentLanguage[50]; + char szAvailableLanguages[512]; + szCurrentLanguage[0] = 0; + szAvailableLanguages[0] = 0; + + // Fallback to current engine language + engine->GetUILanguage( szCurrentLanguage, sizeof( szCurrentLanguage )); + + // In a Steam environment we get the current language +#if !defined( NO_STEAM ) + // When Steam isn't running we can't get the language info... + if ( steamapicontext->SteamApps() ) + { + Q_strncpy( szCurrentLanguage, steamapicontext->SteamApps()->GetCurrentGameLanguage(), sizeof(szCurrentLanguage) ); + Q_strncpy( szAvailableLanguages, steamapicontext->SteamApps()->GetAvailableGameLanguages(), sizeof(szAvailableLanguages) ); + } +#endif + + // Get the spoken language and store it for comparison purposes + m_nCurrentAudioLanguage = PchLanguageToELanguage( szCurrentLanguage ); + + // Check to see if we have a list of languages from Steam + if ( V_strlen( szAvailableLanguages ) ) + { + // Populate the combo box with each available language + CUtlVector<char*> languagesList; + V_SplitString( szAvailableLanguages, ",", languagesList ); + + for ( int i=0; i < languagesList.Count(); i++ ) + { + const ELanguage languageCode = PchLanguageToELanguage( languagesList[i] ); + m_pSpokenLanguageCombo->AddItem( GetLanguageVGUILocalization( languageCode ), new KeyValues ("Audio Languages", "language", languageCode) ); + } + + languagesList.PurgeAndDeleteElements(); + } + else + { + // Add the current language to the combo + m_pSpokenLanguageCombo->AddItem( GetLanguageVGUILocalization( m_nCurrentAudioLanguage ), new KeyValues ("Audio Languages", "language", m_nCurrentAudioLanguage) ); + } + + // Activate the current language in the combo + {for (int itemID = 0; itemID < m_pSpokenLanguageCombo->GetItemCount(); itemID++) + { + KeyValues *kv = m_pSpokenLanguageCombo->GetItemUserData( itemID ); + if ( kv && kv->GetInt( "language" ) == m_nCurrentAudioLanguage ) + { + m_pSpokenLanguageCombo->ActivateItem( itemID ); + break; + } + }} + + m_pSoundMuteLoseFocusCheckButton->Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: Applies changes +//----------------------------------------------------------------------------- +void COptionsSubAudio::OnApplyChanges() +{ + m_pSFXSlider->ApplyChanges(); + m_pMusicSlider->ApplyChanges(); + + // set the cvars appropriately + // Tracker 28933: Note we can't do this because closecaption is marked + // FCVAR_USERINFO and it won't get sent to server is we direct set it, we + // need to pass it along to the engine parser!!! + // ConVar *closecaption = (ConVar *)cvar->FindVar("closecaption"); + int closecaption_value = 0; + + ConVarRef cc_subtitles( "cc_subtitles" ); + switch (m_pCloseCaptionCombo->GetActiveItem()) + { + default: + case 0: + closecaption_value = 0; + cc_subtitles.SetValue( 0 ); + break; + case 1: + closecaption_value = 1; + cc_subtitles.SetValue( 0 ); + break; + case 2: + closecaption_value = 1; + cc_subtitles.SetValue( 1 ); + break; + } + + // Stuff the close caption change to the console so that it can be + // sent to the server (FCVAR_USERINFO) so that you don't have to restart + // the level for the change to take effect. + char cmd[ 64 ]; + Q_snprintf( cmd, sizeof( cmd ), "closecaption %i\n", closecaption_value ); + engine->ClientCmd_Unrestricted( cmd ); + + ConVarRef snd_surround_speakers( "Snd_Surround_Speakers" ); + int speakers = m_pSpeakerSetupCombo->GetActiveItemUserData()->GetInt( "speakers" ); + snd_surround_speakers.SetValue( speakers ); + + // quality + ConVarRef Snd_PitchQuality( "Snd_PitchQuality" ); + ConVarRef dsp_slow_cpu( "dsp_slow_cpu" ); + int quality = m_pSoundQualityCombo->GetActiveItemUserData()->GetInt( "quality" ); + switch ( quality ) + { + case SOUNDQUALITY_LOW: + dsp_slow_cpu.SetValue(true); + Snd_PitchQuality.SetValue(false); + break; + case SOUNDQUALITY_MEDIUM: + dsp_slow_cpu.SetValue(false); + Snd_PitchQuality.SetValue(false); + break; + default: + Assert("Undefined sound quality setting."); + case SOUNDQUALITY_HIGH: + dsp_slow_cpu.SetValue(false); + Snd_PitchQuality.SetValue(true); + break; + }; + + // headphones at high quality get enhanced stereo turned on + ConVarRef dsp_enhance_stereo( "dsp_enhance_stereo" ); + if (speakers == 0 && quality == SOUNDQUALITY_HIGH) + { + dsp_enhance_stereo.SetValue( 1 ); + } + else + { + dsp_enhance_stereo.SetValue( 0 ); + } + + // Audio spoken language + KeyValues *kv = m_pSpokenLanguageCombo->GetItemUserData( m_pSpokenLanguageCombo->GetActiveItem() ); + const ELanguage nUpdatedAudioLanguage = (ELanguage)( kv ? kv->GetInt( "language" ) : k_Lang_English ); + + if ( nUpdatedAudioLanguage != m_nCurrentAudioLanguage ) + { + // Store new language in static member so that it can be accessed during shutdown when this instance is gone + m_pchUpdatedAudioLanguage = (char *) GetLanguageShortName( nUpdatedAudioLanguage ); + + // Inform user that they need to restart in order change language at this time + QueryBox *qb = new QueryBox( "#GameUI_ChangeLanguageRestart_Title", "#GameUI_ChangeLanguageRestart_Info", GetParent()->GetParent()->GetParent() ); + if (qb != NULL) + { + qb->SetOKCommand( new KeyValues( "Command", "command", "RestartWithNewLanguage" ) ); + qb->SetOKButtonText( "#GameUI_ChangeLanguageRestart_OkButton" ); + qb->SetCancelButtonText( "#GameUI_ChangeLanguageRestart_CancelButton" ); + qb->AddActionSignalTarget( GetParent()->GetParent()->GetParent() ); + qb->DoModal(); + } + } + + m_pSoundMuteLoseFocusCheckButton->ApplyChanges(); +} + +//----------------------------------------------------------------------------- +// Purpose: Called on controls changing, enables the Apply button +//----------------------------------------------------------------------------- +void COptionsSubAudio::OnControlModified() +{ + PostActionSignal(new KeyValues("ApplyButtonEnable")); +} + +//----------------------------------------------------------------------------- +// Purpose: returns true if the engine needs to be restarted +//----------------------------------------------------------------------------- +bool COptionsSubAudio::RequiresRestart() +{ + // nothing in audio requires a restart like now + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void COptionsSubAudio::OnCommand( const char *command ) +{ + if ( !stricmp( command, "TestSpeakers" ) ) + { + // ask them if they REALLY want to test the speakers if they're in a game already. + if (engine->IsConnected()) + { + QueryBox *qb = new QueryBox("#GameUI_TestSpeakersWarning_Title", "#GameUI_TestSpeakersWarning_Info" ); + if (qb != NULL) + { + qb->SetOKCommand(new KeyValues("RunTestSpeakers")); + qb->SetOKButtonText("#GameUI_TestSpeakersWarning_OkButton"); + qb->SetCancelButtonText("#GameUI_TestSpeakersWarning_CancelButton"); + qb->AddActionSignalTarget( this ); + qb->DoModal(); + } + else + { + // couldn't create the warning dialog for some reason, so just test the speakers. + RunTestSpeakers(); + } + } + else + { + // player isn't connected to a game so there's no reason to warn them about being disconnected. + // create the command to execute + RunTestSpeakers(); + } + } + else if ( !stricmp( command, "ShowThirdPartyAudioCredits" ) ) + { + OpenThirdPartySoundCreditsDialog(); + } + + BaseClass::OnCommand( command ); +} + +//----------------------------------------------------------------------------- +// Purpose: Run the test speakers map. +//----------------------------------------------------------------------------- +void COptionsSubAudio::RunTestSpeakers() +{ + engine->ClientCmd_Unrestricted( "disconnect\nwait\nwait\nsv_lan 1\nsetmaster enable\nmaxplayers 1\n\nhostname \"Speaker Test\"\nprogress_enable\nmap test_speakers\n" ); +} + +//----------------------------------------------------------------------------- +// Purpose: third-party audio credits dialog +//----------------------------------------------------------------------------- +class COptionsSubAudioThirdPartyCreditsDlg : public vgui::Frame +{ + DECLARE_CLASS_SIMPLE( COptionsSubAudioThirdPartyCreditsDlg, vgui::Frame ); +public: + COptionsSubAudioThirdPartyCreditsDlg( vgui::VPANEL hParent ) : BaseClass( NULL, NULL ) + { + // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below) + + SetTitle("#GameUI_ThirdPartyAudio_Title", true); + SetSize( 500, 200 ); + LoadControlSettings( "resource/OptionsSubAudioThirdPartyDlg.res" ); + MoveToCenterOfScreen(); + SetSizeable( false ); + SetDeleteSelfOnClose( true ); + } + + virtual void Activate() + { + BaseClass::Activate(); + + input()->SetAppModalSurface(GetVPanel()); + } + + void OnKeyCodeTyped(KeyCode code) + { + // force ourselves to be closed if the escape key it pressed + if (code == KEY_ESCAPE) + { + Close(); + } + else + { + BaseClass::OnKeyCodeTyped(code); + } + } +}; + + +//----------------------------------------------------------------------------- +// Purpose: Open third party audio credits dialog +//----------------------------------------------------------------------------- +void COptionsSubAudio::OpenThirdPartySoundCreditsDialog() +{ + if (!m_OptionsSubAudioThirdPartyCreditsDlg.Get()) + { + m_OptionsSubAudioThirdPartyCreditsDlg = new COptionsSubAudioThirdPartyCreditsDlg(GetVParent()); + } + m_OptionsSubAudioThirdPartyCreditsDlg->Activate(); +} |