diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 989be91004..fe62005b69 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,3 +1,4 @@ +use crate::settings::AudioSettings; use common::assets; use rand::prelude::*; use rodio::{Decoder, Device, Source, SpatialSink}; @@ -21,11 +22,15 @@ pub struct AudioFrontend { } impl AudioFrontend { - pub fn new() -> Self { - let mut device = AudioFrontend::get_devices_raw()[0].clone(); + pub fn new(settings: &AudioSettings) -> Self { + let mut device = rodio::output_devices() + .find(|x| x.name() == settings.audio_device) + .or_else(rodio::default_output_device) + .expect("No Audio devices found"); let mut sink = rodio::SpatialSink::new(&device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]); + sink.set_volume(settings.music_volume); AudioFrontend { device, @@ -66,20 +71,20 @@ impl AudioFrontend { self.stream.set_volume(volume.min(1.0).max(0.0)) } - /// Internal method for working with rodio. Filters out the jack audio server. - fn get_devices_raw() -> Vec { - rodio::output_devices() - .filter(|x| !x.name().contains("jack")) - .collect() - } - /// Returns a vec of the audio devices available. /// Does not return rodio Device struct in case our audio backend changes. - // TODO: Decide if this should be an associated function - pub fn get_devices(&self) -> Vec { + pub fn get_devices() -> Vec { rodio::output_devices().map(|x| x.name()).collect() } + /// Returns the default audio device. + /// Does not return rodio Device struct in case our audio backend changes. + pub fn get_default_device() -> String { + rodio::default_output_device() + .expect("No audio output devices detected.") + .name() + } + /// Returns the name of the current audio device. /// Does not return rodio Device struct in case our audio backend changes. pub fn get_device(&self) -> String { diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index a8d4a18c62..70a9c216f8 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -208,12 +208,11 @@ pub struct Hud { inventory_space: u32, show: Show, to_focus: Option>, - settings: Settings, force_ungrab: bool, } impl Hud { - pub fn new(window: &mut Window, settings: Settings) -> Self { + pub fn new(window: &mut Window) -> Self { let mut ui = Ui::new(window).unwrap(); // TODO: Adjust/remove this, right now it is used to demonstrate window scaling functionality. ui.scaling_mode(ScaleMode::RelativeToWindow([1920.0, 1080.0].into())); @@ -244,12 +243,11 @@ impl Hud { want_grab: true, }, to_focus: None, - settings, force_ungrab: false, } } - fn update_layout(&mut self, tps: f64) -> Vec { + fn update_layout(&mut self, tps: f64, global_state: &GlobalState) -> Vec { let mut events = Vec::new(); let ref mut ui_widgets = self.ui.set_widgets(); let version = env!("CARGO_PKG_VERSION"); @@ -298,7 +296,7 @@ impl Hud { .top_left_with_margins_on(ui_widgets.window, 3.0, 3.0) .w_h(300.0, 190.0) .set(self.ids.help_bg, ui_widgets); - Text::new(get_help_text(&self.settings.controls).as_str()) + Text::new(get_help_text(&global_state.settings.controls).as_str()) .color(TEXT_COLOR) .top_left_with_margins_on(self.ids.help_bg, 20.0, 20.0) .font_id(self.fonts.opensans) @@ -375,7 +373,7 @@ impl Hud { // Settings if let Windows::Settings = self.show.open_windows { - for event in SettingsWindow::new(&self.show, &self.imgs, &self.fonts, &self.settings) + for event in SettingsWindow::new(&self.show, &self.imgs, &self.fonts, &global_state) .set(self.ids.settings_window, ui_widgets) { match event { @@ -386,15 +384,12 @@ impl Hud { settings_window::Event::ToggleDebug => self.show.debug = !self.show.debug, settings_window::Event::Close => self.show.open_windows = Windows::None, settings_window::Event::AdjustViewDistance(view_distance) => { - self.settings.graphics.view_distance = view_distance; events.push(Event::AdjustViewDistance(view_distance)); } settings_window::Event::AdjustVolume(volume) => { - self.settings.audio.music_volume = volume; events.push(Event::AdjustVolume(volume)); } settings_window::Event::ChangeAudioDevice(name) => { - self.settings.audio.audio_device = name.clone(); events.push(Event::ChangeAudioDevice(name)); } } @@ -477,10 +472,6 @@ impl Hud { pub fn handle_event(&mut self, event: WinEvent, global_state: &mut GlobalState) -> bool { let cursor_grabbed = global_state.window.is_cursor_grabbed(); let handled = match event { - WinEvent::SettingsChanged => { - self.settings = global_state.settings.clone(); - false - } WinEvent::Ui(event) => { if (self.typing() && event.is_keyboard() && self.show.ui) || !(cursor_grabbed && event.is_keyboard_or_mouse()) @@ -575,12 +566,12 @@ impl Hud { handled } - pub fn maintain(&mut self, renderer: &mut Renderer, tps: f64) -> Vec { + pub fn maintain(&mut self, global_state: &mut GlobalState, tps: f64) -> Vec { if let Some(maybe_id) = self.to_focus.take() { self.ui.focus_widget(maybe_id); } - let events = self.update_layout(tps); - self.ui.maintain(renderer); + let events = self.update_layout(tps, &global_state); + self.ui.maintain(&mut global_state.window.renderer_mut()); events } diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index 62b0fbb29e..d2f18a915b 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -7,7 +7,7 @@ use crate::{ ImageSlider, ScaleMode, ToggleButton, Ui, }, window::Window, - Settings, + GlobalState, }; use conrod_core::{ color, @@ -66,19 +66,24 @@ pub struct SettingsWindow<'a> { imgs: &'a Imgs, fonts: &'a Fonts, - settings: &'a Settings, + global_state: &'a GlobalState, #[conrod(common_builder)] common: widget::CommonBuilder, } impl<'a> SettingsWindow<'a> { - pub fn new(show: &'a Show, imgs: &'a Imgs, fonts: &'a Fonts, settings: &'a Settings) -> Self { + pub fn new( + show: &'a Show, + imgs: &'a Imgs, + fonts: &'a Fonts, + global_state: &'a GlobalState, + ) -> Self { Self { show, imgs, fonts, - settings, + global_state, common: widget::CommonBuilder::default(), } } @@ -486,7 +491,7 @@ impl<'a> Widget for SettingsWindow<'a> { .set(state.ids.vd_slider_text, ui); if let Some(new_val) = ImageSlider::discrete( - self.settings.graphics.view_distance, + self.global_state.settings.graphics.view_distance, 1, 25, self.imgs.slider_indicator, @@ -540,7 +545,7 @@ impl<'a> Widget for SettingsWindow<'a> { .set(state.ids.audio_volume_text, ui); if let Some(new_val) = ImageSlider::continuous( - self.settings.audio.music_volume, + self.global_state.settings.audio.music_volume, 0.0, 1.0, self.imgs.slider_indicator, @@ -566,19 +571,21 @@ impl<'a> Widget for SettingsWindow<'a> { // Get which device is currently selected let selected = self + .global_state .settings .audio .audio_devices .iter() - .position(|x| x.contains(&self.settings.audio.audio_device)); + .position(|x| x.contains(&self.global_state.settings.audio.audio_device)); - if let Some(clicked) = DropDownList::new(&self.settings.audio.audio_devices, selected) - .w_h(400.0, 22.0) - .down_from(state.ids.audio_device_text, 10.0) - .label_font_id(self.fonts.opensans) - .set(state.ids.audio_device_list, ui) + if let Some(clicked) = + DropDownList::new(&self.global_state.settings.audio.audio_devices, selected) + .w_h(400.0, 22.0) + .down_from(state.ids.audio_device_text, 10.0) + .label_font_id(self.fonts.opensans) + .set(state.ids.audio_device_list, ui) { - let new_val = self.settings.audio.audio_devices[clicked].clone(); + let new_val = self.global_state.settings.audio.audio_devices[clicked].clone(); events.push(Event::ChangeAudioDevice(new_val)); } } diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 0ad98ce515..838a2b0c5a 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -79,7 +79,7 @@ pub trait PlayState { fn main() { // Set up the global state. - let settings = Settings::load(); + let mut settings = Settings::load(); let window = Window::new(&settings).expect("Failed to create window!"); // Initialize logging. @@ -159,30 +159,16 @@ fn main() { default_hook(panic_info); })); - let mut global_state = GlobalState { - settings, - window, - audio: AudioFrontend::new(), - }; - - // Load volume from audio file - global_state - .audio - .set_volume(global_state.settings.audio.music_volume); - - global_state.settings.audio.audio_devices = global_state.audio.get_devices(); - - // Load last used audio device, or set the current audio device as the last - // used if there is no last used - if global_state.settings.audio.audio_device != "" { - global_state - .audio - .set_device(global_state.settings.audio.audio_device.clone()); - } else { - global_state.settings.audio.audio_device = global_state.audio.get_device(); - global_state.settings.save_to_file(); + if settings.audio.audio_device == "" { + settings.audio.audio_device = AudioFrontend::get_default_device(); } + let mut global_state = GlobalState { + audio: AudioFrontend::new(&settings.audio), + window, + settings, + }; + // Set up the initial play state. let mut states: Vec> = vec![Box::new(MainMenuState::new(&mut global_state))]; states diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index beb1f9c40d..3cfc945528 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -32,7 +32,7 @@ impl SessionState { scene, client, key_state: KeyState::new(), - hud: Hud::new(window, settings), + hud: Hud::new(window), input_events: Vec::new(), } } @@ -173,14 +173,11 @@ impl PlayState for SessionState { // Maintain the scene. self.scene.maintain( global_state.window.renderer_mut(), - &mut self.client.borrow_mut(), + &self.client.borrow_mut(), ); // Maintain the UI. - for event in self - .hud - .maintain(global_state.window.renderer_mut(), clock.get_tps()) - { + for event in self.hud.maintain(&mut global_state, clock.get_tps()) { match event { HudEvent::SendMessage(msg) => { // TODO: Handle result