mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'master' into TheYsconator/several_minor_improvements
This commit is contained in:
commit
2599131e79
@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add detection of entities under the cursor
|
- Add detection of entities under the cursor
|
||||||
- Functional group-system with exp-sharing and disabled damage to group members
|
- Functional group-system with exp-sharing and disabled damage to group members
|
||||||
- Some Campfire, fireball & bomb; particle, light & sound effects.
|
- Some Campfire, fireball & bomb; particle, light & sound effects.
|
||||||
|
- Added setting to change resolution
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4719,6 +4719,7 @@ dependencies = [
|
|||||||
"guillotiere",
|
"guillotiere",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"image",
|
"image",
|
||||||
|
"itertools",
|
||||||
"msgbox",
|
"msgbox",
|
||||||
"num 0.2.1",
|
"num 0.2.1",
|
||||||
"old_school_gfx_glutin_ext",
|
"old_school_gfx_glutin_ext",
|
||||||
|
@ -70,6 +70,7 @@ VoxygenLocalization(
|
|||||||
"common.fatal_error": "Fataler Fehler",
|
"common.fatal_error": "Fataler Fehler",
|
||||||
"common.decline": "Ablehnen",
|
"common.decline": "Ablehnen",
|
||||||
"common.you": "Ihr",
|
"common.you": "Ihr",
|
||||||
|
"common.automatic": "Auto",
|
||||||
/// End Common section
|
/// End Common section
|
||||||
|
|
||||||
// Message when connection to the server is lost
|
// Message when connection to the server is lost
|
||||||
@ -297,6 +298,10 @@ magischen Gegenstände ergattern?"#,
|
|||||||
"hud.settings.fluid_rendering_mode.cheap": "Niedrig",
|
"hud.settings.fluid_rendering_mode.cheap": "Niedrig",
|
||||||
"hud.settings.fluid_rendering_mode.shiny": "Hoch",
|
"hud.settings.fluid_rendering_mode.shiny": "Hoch",
|
||||||
"hud.settings.cloud_rendering_mode.regular": "Realistisch",
|
"hud.settings.cloud_rendering_mode.regular": "Realistisch",
|
||||||
|
"hud.settings.particles": "Partikel",
|
||||||
|
"hud.settings.resolution": "Auflösung",
|
||||||
|
"hud.settings.bit_depth": "Bittiefe",
|
||||||
|
"hud.settings.refresh_rate": "Bildwiederholrate",
|
||||||
"hud.settings.fullscreen": "Vollbild",
|
"hud.settings.fullscreen": "Vollbild",
|
||||||
"hud.settings.save_window_size": "Größe speichern",
|
"hud.settings.save_window_size": "Größe speichern",
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ VoxygenLocalization(
|
|||||||
"common.error": "Error",
|
"common.error": "Error",
|
||||||
"common.fatal_error": "Fatal Error",
|
"common.fatal_error": "Fatal Error",
|
||||||
"common.you": "You",
|
"common.you": "You",
|
||||||
|
"common.automatic": "Auto",
|
||||||
|
|
||||||
// Message when connection to the server is lost
|
// Message when connection to the server is lost
|
||||||
"common.connection_lost": r#"Connection lost!
|
"common.connection_lost": r#"Connection lost!
|
||||||
@ -298,6 +299,9 @@ magically infused items?"#,
|
|||||||
"hud.settings.fluid_rendering_mode.shiny": "Shiny",
|
"hud.settings.fluid_rendering_mode.shiny": "Shiny",
|
||||||
"hud.settings.cloud_rendering_mode.regular": "Regular",
|
"hud.settings.cloud_rendering_mode.regular": "Regular",
|
||||||
"hud.settings.particles": "Particles",
|
"hud.settings.particles": "Particles",
|
||||||
|
"hud.settings.resolution": "Resolution",
|
||||||
|
"hud.settings.bit_depth": "Bit Depth",
|
||||||
|
"hud.settings.refresh_rate": "Refresh Rate",
|
||||||
"hud.settings.fullscreen": "Fullscreen",
|
"hud.settings.fullscreen": "Fullscreen",
|
||||||
"hud.settings.save_window_size": "Save window size",
|
"hud.settings.save_window_size": "Save window size",
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ bincode = "1.2"
|
|||||||
deunicode = "1.0"
|
deunicode = "1.0"
|
||||||
uvth = "3.1.1"
|
uvth = "3.1.1"
|
||||||
const-tweaker = { version = "0.3.1", optional = true }
|
const-tweaker = { version = "0.3.1", optional = true }
|
||||||
|
itertools = "0.9.0"
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
@ -283,6 +283,9 @@ pub enum Event {
|
|||||||
ChangeAaMode(AaMode),
|
ChangeAaMode(AaMode),
|
||||||
ChangeCloudMode(CloudMode),
|
ChangeCloudMode(CloudMode),
|
||||||
ChangeFluidMode(FluidMode),
|
ChangeFluidMode(FluidMode),
|
||||||
|
ChangeResolution([u16; 2]),
|
||||||
|
ChangeBitDepth(Option<u16>),
|
||||||
|
ChangeRefreshRate(Option<u16>),
|
||||||
CrosshairTransp(f32),
|
CrosshairTransp(f32),
|
||||||
ChatTransp(f32),
|
ChatTransp(f32),
|
||||||
ChatCharName(bool),
|
ChatCharName(bool),
|
||||||
@ -1908,6 +1911,15 @@ impl Hud {
|
|||||||
settings_window::Event::ChangeFluidMode(new_fluid_mode) => {
|
settings_window::Event::ChangeFluidMode(new_fluid_mode) => {
|
||||||
events.push(Event::ChangeFluidMode(new_fluid_mode));
|
events.push(Event::ChangeFluidMode(new_fluid_mode));
|
||||||
},
|
},
|
||||||
|
settings_window::Event::ChangeResolution(new_resolution) => {
|
||||||
|
events.push(Event::ChangeResolution(new_resolution));
|
||||||
|
},
|
||||||
|
settings_window::Event::ChangeBitDepth(new_bit_depth) => {
|
||||||
|
events.push(Event::ChangeBitDepth(new_bit_depth));
|
||||||
|
},
|
||||||
|
settings_window::Event::ChangeRefreshRate(new_refresh_rate) => {
|
||||||
|
events.push(Event::ChangeRefreshRate(new_refresh_rate));
|
||||||
|
},
|
||||||
settings_window::Event::ChangeLanguage(language) => {
|
settings_window::Event::ChangeLanguage(language) => {
|
||||||
events.push(Event::ChangeLanguage(language));
|
events.push(Event::ChangeLanguage(language));
|
||||||
},
|
},
|
||||||
|
@ -17,6 +17,10 @@ use conrod_core::{
|
|||||||
WidgetCommon,
|
WidgetCommon,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
use std::iter::once;
|
||||||
|
use winit::monitor::VideoMode;
|
||||||
|
|
||||||
const FPS_CHOICES: [u32; 11] = [15, 30, 40, 50, 60, 90, 120, 144, 240, 300, 500];
|
const FPS_CHOICES: [u32; 11] = [15, 30, 40, 50, 60, 90, 120, 144, 240, 300, 500];
|
||||||
|
|
||||||
widget_ids! {
|
widget_ids! {
|
||||||
@ -111,8 +115,17 @@ widget_ids! {
|
|||||||
cloud_mode_list,
|
cloud_mode_list,
|
||||||
fluid_mode_text,
|
fluid_mode_text,
|
||||||
fluid_mode_list,
|
fluid_mode_list,
|
||||||
|
//
|
||||||
|
resolution,
|
||||||
|
resolution_label,
|
||||||
|
bit_depth,
|
||||||
|
bit_depth_label,
|
||||||
|
refresh_rate,
|
||||||
|
refresh_rate_label,
|
||||||
|
//
|
||||||
particles_button,
|
particles_button,
|
||||||
particles_label,
|
particles_label,
|
||||||
|
//
|
||||||
fullscreen_button,
|
fullscreen_button,
|
||||||
fullscreen_label,
|
fullscreen_label,
|
||||||
save_window_size_button,
|
save_window_size_button,
|
||||||
@ -239,6 +252,9 @@ pub enum Event {
|
|||||||
ChangeAaMode(AaMode),
|
ChangeAaMode(AaMode),
|
||||||
ChangeCloudMode(CloudMode),
|
ChangeCloudMode(CloudMode),
|
||||||
ChangeFluidMode(FluidMode),
|
ChangeFluidMode(FluidMode),
|
||||||
|
ChangeResolution([u16; 2]),
|
||||||
|
ChangeBitDepth(Option<u16>),
|
||||||
|
ChangeRefreshRate(Option<u16>),
|
||||||
AdjustMusicVolume(f32),
|
AdjustMusicVolume(f32),
|
||||||
AdjustSfxVolume(f32),
|
AdjustSfxVolume(f32),
|
||||||
ChangeAudioDevice(String),
|
ChangeAudioDevice(String),
|
||||||
@ -2039,11 +2055,168 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
events.push(Event::ToggleParticlesEnabled(particles_enabled));
|
events.push(Event::ToggleParticlesEnabled(particles_enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolution, Bit Depth and Refresh Rate
|
||||||
|
let video_modes: Vec<VideoMode> = self
|
||||||
|
.global_state
|
||||||
|
.window
|
||||||
|
.window()
|
||||||
|
.window()
|
||||||
|
.current_monitor()
|
||||||
|
.video_modes()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Resolution
|
||||||
|
let resolutions: Vec<[u16; 2]> = video_modes
|
||||||
|
.iter()
|
||||||
|
.sorted_by_key(|mode| mode.size().height)
|
||||||
|
.sorted_by_key(|mode| mode.size().width)
|
||||||
|
.map(|mode| [mode.size().width as u16, mode.size().height as u16])
|
||||||
|
.dedup()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.resolution"))
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.down_from(state.ids.particles_label, 8.0)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.resolution_label, ui);
|
||||||
|
|
||||||
|
if let Some(clicked) = DropDownList::new(
|
||||||
|
resolutions
|
||||||
|
.iter()
|
||||||
|
.map(|res| format!("{}x{}", res[0], res[1]))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.as_slice(),
|
||||||
|
resolutions
|
||||||
|
.iter()
|
||||||
|
.position(|res| res == &self.global_state.settings.graphics.resolution),
|
||||||
|
)
|
||||||
|
.w_h(128.0, 22.0)
|
||||||
|
.color(MENU_BG)
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.opensans.conrod_id)
|
||||||
|
.down_from(state.ids.resolution_label, 10.0)
|
||||||
|
.set(state.ids.resolution, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeResolution(resolutions[clicked]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bit Depth and Refresh Rate
|
||||||
|
let correct_res: Vec<VideoMode> = video_modes
|
||||||
|
.into_iter()
|
||||||
|
.filter(|mode| {
|
||||||
|
mode.size().width == self.global_state.settings.graphics.resolution[0] as u32
|
||||||
|
})
|
||||||
|
.filter(|mode| {
|
||||||
|
mode.size().height == self.global_state.settings.graphics.resolution[1] as u32
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Bit Depth
|
||||||
|
let bit_depths: Vec<u16> = correct_res
|
||||||
|
.iter()
|
||||||
|
.filter(
|
||||||
|
|mode| match self.global_state.settings.graphics.refresh_rate {
|
||||||
|
Some(refresh_rate) => mode.refresh_rate() == refresh_rate,
|
||||||
|
None => true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.sorted_by_key(|mode| mode.bit_depth())
|
||||||
|
.map(|mode| mode.bit_depth())
|
||||||
|
.rev()
|
||||||
|
.dedup()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.bit_depth"))
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.down_from(state.ids.particles_label, 8.0)
|
||||||
|
.right_from(state.ids.resolution, 8.0)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.bit_depth_label, ui);
|
||||||
|
|
||||||
|
if let Some(clicked) = DropDownList::new(
|
||||||
|
once(String::from(self.localized_strings.get("common.automatic")))
|
||||||
|
.chain(bit_depths.iter().map(|depth| format!("{}", depth)))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.as_slice(),
|
||||||
|
match self.global_state.settings.graphics.bit_depth {
|
||||||
|
Some(bit_depth) => bit_depths
|
||||||
|
.iter()
|
||||||
|
.position(|depth| depth == &bit_depth)
|
||||||
|
.map(|index| index + 1),
|
||||||
|
None => Some(0),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.w_h(128.0, 22.0)
|
||||||
|
.color(MENU_BG)
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.opensans.conrod_id)
|
||||||
|
.down_from(state.ids.bit_depth_label, 10.0)
|
||||||
|
.right_from(state.ids.resolution, 8.0)
|
||||||
|
.set(state.ids.bit_depth, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeBitDepth(if clicked == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(bit_depths[clicked - 1])
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh Rate
|
||||||
|
let refresh_rates: Vec<u16> = correct_res
|
||||||
|
.into_iter()
|
||||||
|
.filter(|mode| match self.global_state.settings.graphics.bit_depth {
|
||||||
|
Some(bit_depth) => mode.bit_depth() == bit_depth,
|
||||||
|
None => true,
|
||||||
|
})
|
||||||
|
.sorted_by_key(|mode| mode.refresh_rate())
|
||||||
|
.map(|mode| mode.refresh_rate())
|
||||||
|
.rev()
|
||||||
|
.dedup()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.refresh_rate"))
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.down_from(state.ids.particles_label, 8.0)
|
||||||
|
.right_from(state.ids.bit_depth, 8.0)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.refresh_rate_label, ui);
|
||||||
|
|
||||||
|
if let Some(clicked) = DropDownList::new(
|
||||||
|
once(String::from(self.localized_strings.get("common.automatic")))
|
||||||
|
.chain(refresh_rates.iter().map(|rate| format!("{}", rate)))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.as_slice(),
|
||||||
|
match self.global_state.settings.graphics.refresh_rate {
|
||||||
|
Some(refresh_rate) => refresh_rates
|
||||||
|
.iter()
|
||||||
|
.position(|rate| rate == &refresh_rate)
|
||||||
|
.map(|index| index + 1),
|
||||||
|
None => Some(0),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.w_h(128.0, 22.0)
|
||||||
|
.color(MENU_BG)
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.opensans.conrod_id)
|
||||||
|
.down_from(state.ids.refresh_rate_label, 10.0)
|
||||||
|
.right_from(state.ids.bit_depth, 8.0)
|
||||||
|
.set(state.ids.refresh_rate, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeRefreshRate(if clicked == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(refresh_rates[clicked - 1])
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
|
Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.down_from(state.ids.particles_label, 8.0)
|
.down_from(state.ids.resolution, 8.0)
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.fullscreen_label, ui);
|
.set(state.ids.fullscreen_label, ui);
|
||||||
|
|
||||||
|
@ -964,6 +964,37 @@ impl PlayState for SessionState {
|
|||||||
global_state.settings.graphics.fluid_mode = new_fluid_mode;
|
global_state.settings.graphics.fluid_mode = new_fluid_mode;
|
||||||
global_state.settings.save_to_file_warn();
|
global_state.settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
|
HudEvent::ChangeResolution(new_resolution) => {
|
||||||
|
// Do this first so if it crashes the setting isn't saved :)
|
||||||
|
global_state.window.fullscreen(
|
||||||
|
global_state.settings.graphics.fullscreen,
|
||||||
|
new_resolution,
|
||||||
|
global_state.settings.graphics.bit_depth,
|
||||||
|
global_state.settings.graphics.refresh_rate,
|
||||||
|
);
|
||||||
|
global_state.settings.graphics.resolution = new_resolution;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
|
HudEvent::ChangeBitDepth(new_bit_depth) => {
|
||||||
|
global_state.window.fullscreen(
|
||||||
|
global_state.settings.graphics.fullscreen,
|
||||||
|
global_state.settings.graphics.resolution,
|
||||||
|
new_bit_depth,
|
||||||
|
global_state.settings.graphics.refresh_rate,
|
||||||
|
);
|
||||||
|
global_state.settings.graphics.bit_depth = new_bit_depth;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
|
HudEvent::ChangeRefreshRate(new_refresh_rate) => {
|
||||||
|
global_state.window.fullscreen(
|
||||||
|
global_state.settings.graphics.fullscreen,
|
||||||
|
global_state.settings.graphics.resolution,
|
||||||
|
global_state.settings.graphics.bit_depth,
|
||||||
|
new_refresh_rate,
|
||||||
|
);
|
||||||
|
global_state.settings.graphics.refresh_rate = new_refresh_rate;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
HudEvent::ChangeLanguage(new_language) => {
|
HudEvent::ChangeLanguage(new_language) => {
|
||||||
global_state.settings.language.selected_language =
|
global_state.settings.language.selected_language =
|
||||||
new_language.language_identifier;
|
new_language.language_identifier;
|
||||||
|
@ -619,6 +619,9 @@ pub struct GraphicsSettings {
|
|||||||
pub aa_mode: AaMode,
|
pub aa_mode: AaMode,
|
||||||
pub cloud_mode: CloudMode,
|
pub cloud_mode: CloudMode,
|
||||||
pub fluid_mode: FluidMode,
|
pub fluid_mode: FluidMode,
|
||||||
|
pub resolution: [u16; 2],
|
||||||
|
pub bit_depth: Option<u16>,
|
||||||
|
pub refresh_rate: Option<u16>,
|
||||||
pub window_size: [u16; 2],
|
pub window_size: [u16; 2],
|
||||||
pub fullscreen: bool,
|
pub fullscreen: bool,
|
||||||
}
|
}
|
||||||
@ -636,6 +639,9 @@ impl Default for GraphicsSettings {
|
|||||||
aa_mode: AaMode::Fxaa,
|
aa_mode: AaMode::Fxaa,
|
||||||
cloud_mode: CloudMode::Regular,
|
cloud_mode: CloudMode::Regular,
|
||||||
fluid_mode: FluidMode::Shiny,
|
fluid_mode: FluidMode::Shiny,
|
||||||
|
resolution: [1920, 1080],
|
||||||
|
bit_depth: None,
|
||||||
|
refresh_rate: None,
|
||||||
window_size: [1920, 1080],
|
window_size: [1920, 1080],
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ use crate::{
|
|||||||
use crossbeam::channel;
|
use crossbeam::channel;
|
||||||
use gilrs::{EventType, Gilrs};
|
use gilrs::{EventType, Gilrs};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use itertools::Itertools;
|
||||||
use old_school_gfx_glutin_ext::{ContextBuilderExt, WindowInitExt, WindowUpdateExt};
|
use old_school_gfx_glutin_ext::{ContextBuilderExt, WindowInitExt, WindowUpdateExt};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use winit::monitor::VideoMode;
|
||||||
|
|
||||||
/// Represents a key that the game recognises after input mapping.
|
/// Represents a key that the game recognises after input mapping.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
||||||
@ -610,7 +612,12 @@ impl Window {
|
|||||||
toggle_fullscreen: false,
|
toggle_fullscreen: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.fullscreen(settings.graphics.fullscreen);
|
this.fullscreen(
|
||||||
|
settings.graphics.fullscreen,
|
||||||
|
settings.graphics.resolution,
|
||||||
|
settings.graphics.bit_depth,
|
||||||
|
settings.graphics.refresh_rate,
|
||||||
|
);
|
||||||
|
|
||||||
Ok((this, event_loop))
|
Ok((this, event_loop))
|
||||||
}
|
}
|
||||||
@ -1056,34 +1063,206 @@ impl Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_fullscreen(&mut self, settings: &mut Settings) {
|
pub fn toggle_fullscreen(&mut self, settings: &mut Settings) {
|
||||||
self.fullscreen(!self.is_fullscreen());
|
self.fullscreen(
|
||||||
|
!self.is_fullscreen(),
|
||||||
|
settings.graphics.resolution,
|
||||||
|
settings.graphics.bit_depth,
|
||||||
|
settings.graphics.refresh_rate,
|
||||||
|
);
|
||||||
settings.graphics.fullscreen = self.is_fullscreen();
|
settings.graphics.fullscreen = self.is_fullscreen();
|
||||||
settings.save_to_file_warn();
|
settings.save_to_file_warn();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_fullscreen(&self) -> bool { self.fullscreen }
|
pub fn is_fullscreen(&self) -> bool { self.fullscreen }
|
||||||
|
|
||||||
pub fn fullscreen(&mut self, fullscreen: bool) {
|
pub fn select_video_mode_rec(
|
||||||
|
&self,
|
||||||
|
resolution: [u16; 2],
|
||||||
|
bit_depth: Option<u16>,
|
||||||
|
refresh_rate: Option<u16>,
|
||||||
|
correct_res: Option<Vec<VideoMode>>,
|
||||||
|
correct_depth: Option<Option<VideoMode>>,
|
||||||
|
correct_rate: Option<Option<VideoMode>>,
|
||||||
|
) -> Option<VideoMode> {
|
||||||
|
// if a previous iteration of this method filtered the available video modes for
|
||||||
|
// the correct resolution already, load that value, otherwise filter it
|
||||||
|
// in this iteration
|
||||||
|
let correct_res = correct_res.unwrap_or_else(|| {
|
||||||
|
let window = self.window.window();
|
||||||
|
window
|
||||||
|
.current_monitor()
|
||||||
|
.video_modes()
|
||||||
|
.filter(|mode| mode.size().width == resolution[0] as u32)
|
||||||
|
.filter(|mode| mode.size().height == resolution[1] as u32)
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
|
||||||
|
match bit_depth {
|
||||||
|
// A bit depth is given
|
||||||
|
Some(depth) => {
|
||||||
|
// analogous to correct_res
|
||||||
|
let correct_depth = correct_depth.unwrap_or_else(|| {
|
||||||
|
correct_res
|
||||||
|
.iter()
|
||||||
|
.find(|mode| mode.bit_depth() == depth)
|
||||||
|
.cloned()
|
||||||
|
});
|
||||||
|
|
||||||
|
match refresh_rate {
|
||||||
|
// A bit depth and a refresh rate is given
|
||||||
|
Some(rate) => {
|
||||||
|
// analogous to correct_res
|
||||||
|
let correct_rate = correct_rate.unwrap_or_else(|| {
|
||||||
|
correct_res
|
||||||
|
.iter()
|
||||||
|
.find(|mode| mode.refresh_rate() == rate)
|
||||||
|
.cloned()
|
||||||
|
});
|
||||||
|
|
||||||
|
// if no video mode with the given bit depth and refresh rate exists, fall
|
||||||
|
// back to a video mode that fits the resolution and either bit depth or
|
||||||
|
// refresh rate depending on which parameter was causing the correct video
|
||||||
|
// mode not to be found
|
||||||
|
correct_res
|
||||||
|
.iter()
|
||||||
|
.filter(|mode| mode.bit_depth() == depth)
|
||||||
|
.find(|mode| mode.refresh_rate() == rate)
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| {
|
||||||
|
if correct_depth.is_none() && correct_rate.is_none() {
|
||||||
|
warn!(
|
||||||
|
"Bit depth and refresh rate specified in settings are \
|
||||||
|
incompatible with the monitor. Choosing highest bit \
|
||||||
|
depth and refresh rate possible instead."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.select_video_mode_rec(
|
||||||
|
resolution,
|
||||||
|
correct_depth.is_some().then_some(depth),
|
||||||
|
correct_rate.is_some().then_some(rate),
|
||||||
|
Some(correct_res),
|
||||||
|
Some(correct_depth),
|
||||||
|
Some(correct_rate),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// A bit depth and no refresh rate is given
|
||||||
|
// if no video mode with the given bit depth exists, fall
|
||||||
|
// back to a video mode that fits only the resolution
|
||||||
|
None => match correct_depth {
|
||||||
|
Some(mode) => Some(mode),
|
||||||
|
None => {
|
||||||
|
warn!(
|
||||||
|
"Bit depth specified in settings is incompatible with the \
|
||||||
|
monitor. Choosing highest bit depth possible instead."
|
||||||
|
);
|
||||||
|
|
||||||
|
self.select_video_mode_rec(
|
||||||
|
resolution,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(correct_res),
|
||||||
|
Some(correct_depth),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// No bit depth is given
|
||||||
|
None => match refresh_rate {
|
||||||
|
// No bit depth and a refresh rate is given
|
||||||
|
Some(rate) => {
|
||||||
|
// analogous to correct_res
|
||||||
|
let correct_rate = correct_rate.unwrap_or_else(|| {
|
||||||
|
correct_res
|
||||||
|
.iter()
|
||||||
|
.find(|mode| mode.refresh_rate() == rate)
|
||||||
|
.cloned()
|
||||||
|
});
|
||||||
|
|
||||||
|
// if no video mode with the given bit depth exists, fall
|
||||||
|
// back to a video mode that fits only the resolution
|
||||||
|
match correct_rate {
|
||||||
|
Some(mode) => Some(mode),
|
||||||
|
None => {
|
||||||
|
warn!(
|
||||||
|
"Refresh rate specified in settings is incompatible with the \
|
||||||
|
monitor. Choosing highest refresh rate possible instead."
|
||||||
|
);
|
||||||
|
|
||||||
|
self.select_video_mode_rec(
|
||||||
|
resolution,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(correct_res),
|
||||||
|
None,
|
||||||
|
Some(correct_rate),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// No bit depth and no refresh rate is given
|
||||||
|
// get the video mode with the specified resolution and the max bit depth and
|
||||||
|
// refresh rate
|
||||||
|
None => correct_res
|
||||||
|
.into_iter()
|
||||||
|
// Prefer bit depth over refresh rate
|
||||||
|
.sorted_by_key(|mode| mode.bit_depth())
|
||||||
|
.max_by_key(|mode| mode.refresh_rate()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_video_mode(
|
||||||
|
&self,
|
||||||
|
resolution: [u16; 2],
|
||||||
|
bit_depth: Option<u16>,
|
||||||
|
refresh_rate: Option<u16>,
|
||||||
|
) -> VideoMode {
|
||||||
|
// (resolution, bit depth, refresh rate) represents a video mode
|
||||||
|
// spec: as specified
|
||||||
|
// max: maximum value available
|
||||||
|
|
||||||
|
// order of fallbacks as follows:
|
||||||
|
// (spec, spec, spec)
|
||||||
|
// (spec, spec, max), (spec, max, spec)
|
||||||
|
// (spec, max, max)
|
||||||
|
// (max, max, max)
|
||||||
|
self.select_video_mode_rec(resolution, bit_depth, refresh_rate, None, None, None)
|
||||||
|
// if there is no video mode with the specified resolution, fall back to the video mode with max resolution, bit depth and refresh rate
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
warn!(
|
||||||
|
"Resolution specified in settings is incompatible with the monitor. Choosing \
|
||||||
|
highest resolution possible instead."
|
||||||
|
);
|
||||||
|
|
||||||
|
self
|
||||||
|
.window
|
||||||
|
.window()
|
||||||
|
.current_monitor()
|
||||||
|
.video_modes()
|
||||||
|
// Prefer bit depth over refresh rate
|
||||||
|
.sorted_by_key(|mode| mode.refresh_rate())
|
||||||
|
.sorted_by_key(|mode| mode.bit_depth())
|
||||||
|
.max_by_key(|mode| mode.size().width)
|
||||||
|
.expect("No video modes available!!")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fullscreen(
|
||||||
|
&mut self,
|
||||||
|
fullscreen: bool,
|
||||||
|
resolution: [u16; 2],
|
||||||
|
bit_depth: Option<u16>,
|
||||||
|
refresh_rate: Option<u16>,
|
||||||
|
) {
|
||||||
let window = self.window.window();
|
let window = self.window.window();
|
||||||
self.fullscreen = fullscreen;
|
self.fullscreen = fullscreen;
|
||||||
if fullscreen {
|
if fullscreen {
|
||||||
window.set_fullscreen(Some(winit::window::Fullscreen::Exclusive(
|
window.set_fullscreen(Some(winit::window::Fullscreen::Exclusive(
|
||||||
window
|
self.select_video_mode(resolution, bit_depth, refresh_rate),
|
||||||
.current_monitor()
|
|
||||||
.video_modes()
|
|
||||||
.filter(|mode| mode.bit_depth() >= 24 && mode.refresh_rate() >= 59)
|
|
||||||
.max_by_key(|mode| mode.size().width)
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
warn!(
|
|
||||||
"No video mode with a bit depth of at least 24 and a refresh rate of \
|
|
||||||
at least 60Hz found"
|
|
||||||
);
|
|
||||||
window
|
|
||||||
.current_monitor()
|
|
||||||
.video_modes()
|
|
||||||
.max_by_key(|mode| mode.size().width)
|
|
||||||
.expect("No video modes available!!")
|
|
||||||
}),
|
|
||||||
)));
|
)));
|
||||||
} else {
|
} else {
|
||||||
window.set_fullscreen(None);
|
window.set_fullscreen(None);
|
||||||
|
Loading…
Reference in New Issue
Block a user