mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'capucho/inactive-master' into 'master'
Lower volume of window on focus loss See merge request veloren/veloren!2150
This commit is contained in:
commit
8c9d4dc3dd
@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Players can now opt-in to server-authoritiative physics in gameplay settings.
|
||||
- Added `/server_physics` admin command.
|
||||
- Sort inventory button
|
||||
- Option to change the master volume when window is unfocused
|
||||
|
||||
|
||||
### Changed
|
||||
@ -77,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Combat rating no longer takes buffs into account
|
||||
- Minimap icons are now displayed in both map modes
|
||||
- Server now denies any running trades when a user exits to the character selection screen.
|
||||
- Sfx volume changes now also change the ambient sounds volume
|
||||
|
||||
## [0.9.0] - 2021-03-20
|
||||
|
||||
|
@ -94,6 +94,8 @@
|
||||
"hud.settings.reset_graphics": "Reset to Defaults",
|
||||
|
||||
|
||||
"hud.settings.master_volume": "Master Volume",
|
||||
"hud.settings.inactive_master_volume": "Master Volume (inactive window)",
|
||||
"hud.settings.music_volume": "Music Volume",
|
||||
"hud.settings.sound_effect_volume": "Sound Effects Volume",
|
||||
"hud.settings.audio_device": "Audio Device",
|
||||
|
@ -165,18 +165,24 @@ pub enum AmbientChannelTag {
|
||||
/// which are always heard at the camera's position.
|
||||
pub struct AmbientChannel {
|
||||
tag: AmbientChannelTag,
|
||||
multiplier: f32,
|
||||
sink: Sink,
|
||||
}
|
||||
|
||||
impl AmbientChannel {
|
||||
pub fn new(stream: &OutputStreamHandle, tag: AmbientChannelTag) -> Self {
|
||||
pub fn new(stream: &OutputStreamHandle, tag: AmbientChannelTag, multiplier: f32) -> Self {
|
||||
let new_sink = Sink::try_new(stream);
|
||||
match new_sink {
|
||||
Ok(sink) => Self { tag, sink },
|
||||
Ok(sink) => Self {
|
||||
tag,
|
||||
multiplier,
|
||||
sink,
|
||||
},
|
||||
Err(_) => {
|
||||
warn!("Failed to create rodio sink. May not play wind sounds.");
|
||||
Self {
|
||||
tag,
|
||||
multiplier,
|
||||
sink: Sink::new_idle().0,
|
||||
}
|
||||
},
|
||||
@ -195,7 +201,9 @@ impl AmbientChannel {
|
||||
|
||||
pub fn stop(&mut self) { self.sink.stop(); }
|
||||
|
||||
pub fn set_volume(&mut self, volume: f32) { self.sink.set_volume(volume); }
|
||||
pub fn set_volume(&mut self, volume: f32) { self.sink.set_volume(volume * self.multiplier); }
|
||||
|
||||
pub fn set_multiplier(&mut self, multiplier: f32) { self.multiplier = multiplier; }
|
||||
|
||||
pub fn get_volume(&mut self) -> f32 { self.sink.volume() }
|
||||
|
||||
|
@ -45,6 +45,7 @@ pub struct AudioFrontend {
|
||||
sfx_channels: Vec<SfxChannel>,
|
||||
sfx_volume: f32,
|
||||
music_volume: f32,
|
||||
master_volume: f32,
|
||||
listener: Listener,
|
||||
|
||||
mtm: AssetHandle<MusicTransitionManifest>,
|
||||
@ -92,6 +93,7 @@ impl AudioFrontend {
|
||||
ambient_channels: Vec::new(),
|
||||
sfx_volume: 1.0,
|
||||
music_volume: 1.0,
|
||||
master_volume: 1.0,
|
||||
listener: Listener::default(),
|
||||
mtm: AssetExt::load_expect("voxygen.audio.music_transition_manifest"),
|
||||
}
|
||||
@ -111,6 +113,7 @@ impl AudioFrontend {
|
||||
ambient_channels: Vec::new(),
|
||||
sfx_volume: 1.0,
|
||||
music_volume: 1.0,
|
||||
master_volume: 1.0,
|
||||
listener: Listener::default(),
|
||||
// This expect should be fine, since `<MusicTransitionManifest as Asset>::default_value`
|
||||
// is specified
|
||||
@ -130,8 +133,9 @@ impl AudioFrontend {
|
||||
/// Retrive an empty sfx channel from the list
|
||||
fn get_sfx_channel(&mut self) -> Option<&mut SfxChannel> {
|
||||
if self.audio_stream.is_some() {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
if let Some(channel) = self.sfx_channels.iter_mut().find(|c| c.is_done()) {
|
||||
channel.set_volume(self.sfx_volume);
|
||||
channel.set_volume(sfx_volume);
|
||||
|
||||
return Some(channel);
|
||||
}
|
||||
@ -152,10 +156,11 @@ impl AudioFrontend {
|
||||
if let Some(audio_stream) = &self.audio_stream {
|
||||
if self.music_channels.is_empty() {
|
||||
let mut next_music_channel = MusicChannel::new(audio_stream);
|
||||
next_music_channel.set_volume(self.music_volume);
|
||||
next_music_channel.set_volume(self.get_music_volume());
|
||||
|
||||
self.music_channels.push(next_music_channel);
|
||||
} else {
|
||||
let music_volume = self.get_music_volume();
|
||||
let existing_channel = self.music_channels.last_mut()?;
|
||||
|
||||
if existing_channel.get_tag() != next_channel_tag {
|
||||
@ -167,11 +172,11 @@ impl AudioFrontend {
|
||||
let fade_out = Duration::from_secs_f32(*fade_out);
|
||||
let fade_in = Duration::from_secs_f32(*fade_in);
|
||||
// Fade the existing channel out. It will be removed when the fade completes.
|
||||
existing_channel.set_fader(Fader::fade_out(fade_out, self.music_volume));
|
||||
existing_channel.set_fader(Fader::fade_out(fade_out, music_volume));
|
||||
|
||||
let mut next_music_channel = MusicChannel::new(&audio_stream);
|
||||
|
||||
next_music_channel.set_fader(Fader::fade_in(fade_in, self.music_volume));
|
||||
next_music_channel.set_fader(Fader::fade_in(fade_in, self.get_music_volume()));
|
||||
|
||||
self.music_channels.push(next_music_channel);
|
||||
}
|
||||
@ -303,13 +308,16 @@ impl AudioFrontend {
|
||||
) -> Option<&mut AmbientChannel> {
|
||||
if let Some(audio_stream) = &self.audio_stream {
|
||||
if self.ambient_channels.is_empty() {
|
||||
let mut ambient_channel = AmbientChannel::new(audio_stream, channel_tag);
|
||||
ambient_channel.set_volume(self.sfx_volume * volume_multiplier);
|
||||
let mut ambient_channel =
|
||||
AmbientChannel::new(audio_stream, channel_tag, volume_multiplier);
|
||||
ambient_channel.set_volume(self.get_sfx_volume());
|
||||
self.ambient_channels.push(ambient_channel);
|
||||
} else {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
for channel in self.ambient_channels.iter_mut() {
|
||||
if channel.get_tag() == channel_tag {
|
||||
channel.set_volume(self.sfx_volume * volume_multiplier);
|
||||
channel.set_multiplier(volume_multiplier);
|
||||
channel.set_volume(sfx_volume);
|
||||
return Some(channel);
|
||||
}
|
||||
}
|
||||
@ -321,8 +329,10 @@ impl AudioFrontend {
|
||||
|
||||
fn set_ambient_volume(&mut self, volume_multiplier: f32) {
|
||||
if self.audio_stream.is_some() {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
if let Some(channel) = self.ambient_channels.iter_mut().last() {
|
||||
channel.set_volume(self.sfx_volume * volume_multiplier);
|
||||
channel.set_multiplier(volume_multiplier);
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -330,7 +340,7 @@ impl AudioFrontend {
|
||||
fn get_ambient_volume(&mut self) -> f32 {
|
||||
if self.audio_stream.is_some() {
|
||||
if let Some(channel) = self.ambient_channels.iter_mut().last() {
|
||||
channel.get_volume() / self.sfx_volume
|
||||
channel.get_volume() / self.get_sfx_volume()
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
@ -398,30 +408,51 @@ impl AudioFrontend {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume }
|
||||
pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume * self.master_volume }
|
||||
|
||||
pub fn get_music_volume(&self) -> f32 { self.music_volume }
|
||||
pub fn get_music_volume(&self) -> f32 { self.music_volume * self.master_volume }
|
||||
|
||||
pub fn sfx_enabled(&self) -> bool { self.sfx_volume > 0.0 }
|
||||
pub fn sfx_enabled(&self) -> bool { self.get_sfx_volume() > 0.0 }
|
||||
|
||||
pub fn music_enabled(&self) -> bool { self.music_volume > 0.0 }
|
||||
pub fn music_enabled(&self) -> bool { self.get_music_volume() > 0.0 }
|
||||
|
||||
pub fn set_sfx_volume(&mut self, sfx_volume: f32) {
|
||||
self.sfx_volume = sfx_volume;
|
||||
|
||||
for channel in self.sfx_channels.iter_mut() {
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
self.update_sfx_volumes();
|
||||
}
|
||||
|
||||
pub fn set_music_volume(&mut self, music_volume: f32) {
|
||||
self.music_volume = music_volume;
|
||||
|
||||
let music_volume = self.get_music_volume();
|
||||
for channel in self.music_channels.iter_mut() {
|
||||
channel.set_volume(music_volume);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_master_volume(&mut self, master_volume: f32) {
|
||||
self.master_volume = master_volume;
|
||||
|
||||
let music_volume = self.get_music_volume();
|
||||
for channel in self.music_channels.iter_mut() {
|
||||
channel.set_volume(music_volume);
|
||||
}
|
||||
|
||||
self.update_sfx_volumes();
|
||||
}
|
||||
|
||||
fn update_sfx_volumes(&mut self) {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
for channel in self.sfx_channels.iter_mut() {
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
|
||||
for channel in self.ambient_channels.iter_mut() {
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop_ambient_sounds(&mut self) {
|
||||
for channel in self.ambient_channels.iter_mut() {
|
||||
channel.stop()
|
||||
|
@ -24,6 +24,10 @@ widget_ids! {
|
||||
audio_volume_text,
|
||||
sfx_volume_slider,
|
||||
sfx_volume_text,
|
||||
master_volume_slider,
|
||||
master_volume_text,
|
||||
inactive_master_volume_slider,
|
||||
inactive_master_volume_text,
|
||||
audio_device_list,
|
||||
audio_device_text,
|
||||
}
|
||||
@ -93,9 +97,63 @@ impl<'a> Widget for Sound<'a> {
|
||||
.rgba(0.33, 0.33, 0.33, 1.0)
|
||||
.set(state.ids.window_scrollbar, ui);
|
||||
|
||||
// Master Volume ----------------------------------------------------
|
||||
Text::new(&self.localized_strings.get("hud.settings.master_volume"))
|
||||
.top_left_with_margins_on(state.ids.window, 10.0, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.master_volume_text, ui);
|
||||
|
||||
if let Some(new_val) = ImageSlider::continuous(
|
||||
self.global_state.settings.audio.master_volume,
|
||||
0.0,
|
||||
1.0,
|
||||
self.imgs.slider_indicator,
|
||||
self.imgs.slider,
|
||||
)
|
||||
.w_h(104.0, 22.0)
|
||||
.down_from(state.ids.master_volume_text, 10.0)
|
||||
.track_breadth(12.0)
|
||||
.slider_length(10.0)
|
||||
.pad_track((5.0, 5.0))
|
||||
.set(state.ids.master_volume_slider, ui)
|
||||
{
|
||||
events.push(AdjustMasterVolume(new_val));
|
||||
}
|
||||
|
||||
// Master Volume (inactive window) ----------------------------------
|
||||
Text::new(
|
||||
&self
|
||||
.localized_strings
|
||||
.get("hud.settings.inactive_master_volume"),
|
||||
)
|
||||
.down_from(state.ids.master_volume_slider, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.inactive_master_volume_text, ui);
|
||||
|
||||
if let Some(new_val) = ImageSlider::continuous(
|
||||
self.global_state.settings.audio.inactive_master_volume,
|
||||
0.0,
|
||||
1.0,
|
||||
self.imgs.slider_indicator,
|
||||
self.imgs.slider,
|
||||
)
|
||||
.w_h(104.0, 22.0)
|
||||
.down_from(state.ids.inactive_master_volume_text, 10.0)
|
||||
.track_breadth(12.0)
|
||||
.slider_length(10.0)
|
||||
.pad_track((5.0, 5.0))
|
||||
.set(state.ids.inactive_master_volume_slider, ui)
|
||||
{
|
||||
events.push(AdjustInactiveMasterVolume(new_val));
|
||||
}
|
||||
|
||||
// Music Volume -----------------------------------------------------
|
||||
Text::new(&self.localized_strings.get("hud.settings.music_volume"))
|
||||
.top_left_with_margins_on(state.ids.window, 10.0, 10.0)
|
||||
.down_from(state.ids.inactive_master_volume_slider, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
|
@ -156,6 +156,7 @@ fn main() {
|
||||
// AudioOutput::Device(ref dev) => Some(dev.clone()),
|
||||
};
|
||||
|
||||
audio.set_master_volume(settings.audio.master_volume);
|
||||
audio.set_music_volume(settings.audio.music_volume);
|
||||
audio.set_sfx_volume(settings.audio.sfx_volume);
|
||||
|
||||
|
@ -61,6 +61,15 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
|
||||
},
|
||||
winit::event::Event::WindowEvent { event, .. } => {
|
||||
span!(_guard, "Handle WindowEvent");
|
||||
|
||||
if let winit::event::WindowEvent::Focused(focused) = event {
|
||||
global_state.audio.set_master_volume(if focused {
|
||||
global_state.settings.audio.master_volume
|
||||
} else {
|
||||
global_state.settings.audio.inactive_master_volume
|
||||
});
|
||||
}
|
||||
|
||||
global_state
|
||||
.window
|
||||
.handle_window_event(event, &mut global_state.settings)
|
||||
|
@ -19,6 +19,8 @@ use vek::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Audio {
|
||||
AdjustMasterVolume(f32),
|
||||
AdjustInactiveMasterVolume(f32),
|
||||
AdjustMusicVolume(f32),
|
||||
AdjustSfxVolume(f32),
|
||||
//ChangeAudioDevice(String),
|
||||
@ -154,6 +156,14 @@ impl SettingsChange {
|
||||
match self {
|
||||
SettingsChange::Audio(audio_change) => {
|
||||
match audio_change {
|
||||
Audio::AdjustMasterVolume(master_volume) => {
|
||||
global_state.audio.set_master_volume(master_volume);
|
||||
|
||||
settings.audio.master_volume = master_volume;
|
||||
},
|
||||
Audio::AdjustInactiveMasterVolume(inactive_master_volume) => {
|
||||
settings.audio.inactive_master_volume = inactive_master_volume;
|
||||
},
|
||||
Audio::AdjustMusicVolume(music_volume) => {
|
||||
global_state.audio.set_music_volume(music_volume);
|
||||
|
||||
|
@ -21,6 +21,7 @@ impl AudioOutput {
|
||||
#[serde(default)]
|
||||
pub struct AudioSettings {
|
||||
pub master_volume: f32,
|
||||
pub inactive_master_volume: f32,
|
||||
pub music_volume: f32,
|
||||
pub sfx_volume: f32,
|
||||
pub max_sfx_channels: usize,
|
||||
@ -33,6 +34,7 @@ impl Default for AudioSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
master_volume: 1.0,
|
||||
inactive_master_volume: 0.5,
|
||||
music_volume: 0.4,
|
||||
sfx_volume: 0.6,
|
||||
max_sfx_channels: 30,
|
||||
|
Loading…
Reference in New Issue
Block a user