Adds an FPS setting and slider.

This commit is contained in:
Cody 2019-06-06 15:11:39 -04:00
parent 8a19a6f2a3
commit 527f33a778
No known key found for this signature in database
GPG Key ID: 4953DADF9B6AD3C8
7 changed files with 70 additions and 26 deletions

View File

@ -3,7 +3,7 @@ use common::{clock::Clock, comp};
use log::{error, info}; use log::{error, info};
use std::time::Duration; use std::time::Duration;
const FPS: u64 = 60; const TICK_RATE: u64 = 10; // Low value is okay, just reading messages.
fn main() { fn main() {
// Initialize logging. // Initialize logging.
@ -48,6 +48,6 @@ fn main() {
client.cleanup(); client.cleanup();
// Wait for the next tick. // Wait for the next tick.
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(1000 / TICK_RATE));
} }
} }

View File

@ -113,7 +113,7 @@ pub enum Event {
AdjustViewDistance(u32), AdjustViewDistance(u32),
AdjustVolume(f32), AdjustVolume(f32),
ChangeAudioDevice(String), ChangeAudioDevice(String),
MaximumFPS(u32), ChangeMaxFPS(u32),
CharacterSelection, CharacterSelection,
Logout, Logout,
Quit, Quit,
@ -583,7 +583,7 @@ impl Hud {
events.push(Event::AdjustVolume(volume)); events.push(Event::AdjustVolume(volume));
} }
settings_window::Event::MaximumFPS(max_fps) => { settings_window::Event::MaximumFPS(max_fps) => {
events.push(Event::MaximumFPS(max_fps)); events.push(Event::ChangeMaxFPS(max_fps));
} }
settings_window::Event::ChangeAudioDevice(name) => { settings_window::Event::ChangeAudioDevice(name) => {
events.push(Event::ChangeAudioDevice(name)); events.push(Event::ChangeAudioDevice(name));

View File

@ -8,6 +8,9 @@ use conrod_core::{
widget::{self, Button, DropDownList, Image, Rectangle, Scrollbar, Text}, widget::{self, Button, DropDownList, Image, Rectangle, Scrollbar, Text},
widget_ids, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, widget_ids, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
}; };
const FPS_CHOICES: [u32; 11] = [1, 30, 40, 50, 60, 90, 120, 144, 240, 300, 500];
widget_ids! { widget_ids! {
struct Ids { struct Ids {
settings_content, settings_content,
@ -42,7 +45,8 @@ widget_ids! {
test, test,
video, video,
vd_slider, vd_slider,
vd_slider_text, vd_text,
vd_value,
max_fps_slider, max_fps_slider,
max_fps_text, max_fps_text,
max_fps_value, max_fps_value,
@ -300,6 +304,7 @@ impl<'a> Widget for SettingsWindow<'a> {
let display_pan = self.global_state.settings.gameplay.pan_sensitivity; let display_pan = self.global_state.settings.gameplay.pan_sensitivity;
let display_zoom = self.global_state.settings.gameplay.zoom_sensitivity; let display_zoom = self.global_state.settings.gameplay.zoom_sensitivity;
// Mouse Pan Sensitivity
Text::new("Pan Sensitivity") Text::new("Pan Sensitivity")
.top_left_with_margins_on(state.ids.settings_content, 10.0, 10.0) .top_left_with_margins_on(state.ids.settings_content, 10.0, 10.0)
.font_size(14) .font_size(14)
@ -331,6 +336,7 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.mouse_pan_value, ui); .set(state.ids.mouse_pan_value, ui);
// Mouse Zoom Sensitivity
Text::new("Zoom Sensitivity") Text::new("Zoom Sensitivity")
.down_from(state.ids.mouse_pan_slider, 10.0) .down_from(state.ids.mouse_pan_slider, 10.0)
.font_size(14) .font_size(14)
@ -575,12 +581,13 @@ impl<'a> Widget for SettingsWindow<'a> {
// Contents // Contents
if let SettingsTab::Video = self.show.settings_tab { if let SettingsTab::Video = self.show.settings_tab {
// View Distance
Text::new("View Distance") Text::new("View Distance")
.top_left_with_margins_on(state.ids.settings_content, 10.0, 10.0) .top_left_with_margins_on(state.ids.settings_content, 10.0, 10.0)
.font_size(14) .font_size(14)
.font_id(self.fonts.opensans) .font_id(self.fonts.opensans)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.vd_slider_text, ui); .set(state.ids.vd_text, ui);
if let Some(new_val) = ImageSlider::discrete( if let Some(new_val) = ImageSlider::discrete(
self.global_state.settings.graphics.view_distance, self.global_state.settings.graphics.view_distance,
@ -590,7 +597,7 @@ impl<'a> Widget for SettingsWindow<'a> {
self.imgs.slider, self.imgs.slider,
) )
.w_h(104.0, 22.0) .w_h(104.0, 22.0)
.down_from(state.ids.vd_slider_text, 8.0) .down_from(state.ids.vd_text, 8.0)
.track_breadth(12.0) .track_breadth(12.0)
.slider_length(10.0) .slider_length(10.0)
.pad_track((5.0, 5.0)) .pad_track((5.0, 5.0))
@ -598,17 +605,32 @@ impl<'a> Widget for SettingsWindow<'a> {
{ {
events.push(Event::AdjustViewDistance(new_val)); events.push(Event::AdjustViewDistance(new_val));
} }
Text::new(&format!(
"{}",
self.global_state.settings.graphics.view_distance
))
.right_from(state.ids.vd_slider, 8.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.vd_value, ui);
// Max FPS
Text::new("Maximum FPS") Text::new("Maximum FPS")
.top_left_with_margins_on(state.ids.settings_content, 60.0, 10.0) .down_from(state.ids.vd_slider, 10.0)
.font_size(14) .font_size(14)
.font_id(self.fonts.opensans) .font_id(self.fonts.opensans)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.max_fps_text, ui); .set(state.ids.max_fps_text, ui);
if let Some(new_val) = ImageSlider::discrete( if let Some(which) = ImageSlider::discrete(
self.global_state.settings.graphics.view_distance, FPS_CHOICES
50, .iter()
150, .position(|&x| x == self.global_state.settings.graphics.max_fps)
.unwrap_or(0),
1,
10,
self.imgs.slider_indicator, self.imgs.slider_indicator,
self.imgs.slider, self.imgs.slider,
) )
@ -619,8 +641,15 @@ impl<'a> Widget for SettingsWindow<'a> {
.pad_track((5.0, 5.0)) .pad_track((5.0, 5.0))
.set(state.ids.max_fps_slider, ui) .set(state.ids.max_fps_slider, ui)
{ {
events.push(Event::MaximumFPS(new_val)); events.push(Event::MaximumFPS(FPS_CHOICES[which]));
} }
Text::new(&format!("{}", self.global_state.settings.graphics.max_fps))
.right_from(state.ids.max_fps_slider, 8.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.max_fps_value, ui);
} }
// 5) Sound Tab ----------------------------------- // 5) Sound Tab -----------------------------------

View File

@ -14,8 +14,6 @@ use std::{cell::RefCell, rc::Rc, time::Duration};
use ui::CharSelectionUi; use ui::CharSelectionUi;
use vek::*; use vek::*;
const FPS: u64 = 60;
pub struct CharSelectionState { pub struct CharSelectionState {
char_selection_ui: CharSelectionUi, char_selection_ui: CharSelectionUi,
client: Rc<RefCell<Client>>, client: Rc<RefCell<Client>>,
@ -125,7 +123,9 @@ impl PlayState for CharSelectionState {
.expect("Failed to swap window buffers"); .expect("Failed to swap window buffers");
// Wait for the next tick. // Wait for the next tick.
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(
1000 / (global_state.settings.graphics.max_fps as u64),
));
current_client_state = self.client.borrow().get_client_state(); current_client_state = self.client.borrow().get_client_state();
} }

View File

@ -12,8 +12,6 @@ use std::time::Duration;
use ui::{Event as MainMenuEvent, MainMenuUi}; use ui::{Event as MainMenuEvent, MainMenuUi};
use vek::*; use vek::*;
const FPS: u64 = 60;
pub struct MainMenuState { pub struct MainMenuState {
main_menu_ui: MainMenuUi, main_menu_ui: MainMenuUi,
} }
@ -133,7 +131,9 @@ impl PlayState for MainMenuState {
.expect("Failed to swap window buffers!"); .expect("Failed to swap window buffers!");
// Wait for the next tick // Wait for the next tick
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(
1000 / (global_state.settings.graphics.max_fps as u64),
));
} }
} }

View File

@ -13,8 +13,6 @@ use log::{error, warn};
use std::{cell::RefCell, rc::Rc, time::Duration}; use std::{cell::RefCell, rc::Rc, time::Duration};
use vek::*; use vek::*;
const FPS: u64 = 1000;
pub struct SessionState { pub struct SessionState {
scene: Scene, scene: Scene,
client: Rc<RefCell<Client>>, client: Rc<RefCell<Client>>,
@ -188,12 +186,16 @@ impl PlayState for SessionState {
HudEvent::AdjustMousePan(sensitivity) => { HudEvent::AdjustMousePan(sensitivity) => {
global_state.window.pan_sensitivity = sensitivity; global_state.window.pan_sensitivity = sensitivity;
global_state.settings.gameplay.pan_sensitivity = sensitivity; global_state.settings.gameplay.pan_sensitivity = sensitivity;
global_state.settings.save_to_file(); if let Err(err) = global_state.settings.save_to_file() {
warn!("Failed to save settings: {:?}", err);
}
} }
HudEvent::AdjustMouseZoom(sensitivity) => { HudEvent::AdjustMouseZoom(sensitivity) => {
global_state.window.zoom_sensitivity = sensitivity; global_state.window.zoom_sensitivity = sensitivity;
global_state.settings.gameplay.zoom_sensitivity = sensitivity; global_state.settings.gameplay.zoom_sensitivity = sensitivity;
global_state.settings.save_to_file(); if let Err(err) = global_state.settings.save_to_file() {
warn!("Failed to save settings: {:?}", err);
}
} }
HudEvent::AdjustViewDistance(view_distance) => { HudEvent::AdjustViewDistance(view_distance) => {
self.client.borrow_mut().set_view_distance(view_distance); self.client.borrow_mut().set_view_distance(view_distance);
@ -219,6 +221,12 @@ impl PlayState for SessionState {
warn!("Failed to save settings!\n{:?}", err); warn!("Failed to save settings!\n{:?}", err);
} }
} }
HudEvent::ChangeMaxFPS(fps) => {
global_state.settings.graphics.max_fps = fps;
if let Err(err) = global_state.settings.save_to_file() {
warn!("Failed to save settings!\n{:?}", err);
}
}
} }
} }
@ -236,7 +244,9 @@ impl PlayState for SessionState {
.expect("Failed to swap window buffers!"); .expect("Failed to swap window buffers!");
// Wait for the next tick. // Wait for the next tick.
clock.tick(Duration::from_millis(1000 / FPS)); clock.tick(Duration::from_millis(
1000 / global_state.settings.graphics.max_fps as u64,
));
// Clean things up after the tick. // Clean things up after the tick.
self.cleanup(); self.cleanup();

View File

@ -64,12 +64,14 @@ pub struct Log {
pub file: PathBuf, pub file: PathBuf,
} }
/// `GraphicsSettings` contains settings related to framerate and in-game visuals.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GraphicsSettings { pub struct GraphicsSettings {
pub view_distance: u32, pub view_distance: u32,
pub max_fps: u32,
} }
/// AudioSettings controls the volume of different audio subsystems and which /// `AudioSettings` controls the volume of different audio subsystems and which
/// device is used. /// device is used.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AudioSettings { pub struct AudioSettings {
@ -120,7 +122,10 @@ impl Default for Settings {
log: Log { log: Log {
file: "voxygen.log".into(), file: "voxygen.log".into(),
}, },
graphics: GraphicsSettings { view_distance: 5 }, graphics: GraphicsSettings {
view_distance: 5,
max_fps: 60,
},
audio: AudioSettings { audio: AudioSettings {
music_volume: 0.5, music_volume: 0.5,
sfx_volume: 0.5, sfx_volume: 0.5,