diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 9af01232bb..0db23602aa 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -18,7 +18,7 @@ gfx = "0.17" gfx_device_gl = { version = "0.15", optional = true } gfx_window_glutin = "0.28" glutin = "0.19" -winit = "0.18" +winit = {version = "0.18", features = ["serde"]} conrod_core = { git = "https://gitlab.com/veloren/conrod.git" } conrod_winit = { git = "https://gitlab.com/veloren/conrod.git" } @@ -36,3 +36,7 @@ log = "0.4" pretty_env_logger = "0.3" dot_vox = "1.0" image = "0.21" +config = "0.9" +serde = "1.0" +serde_derive = "1.0" +toml = "0.4" diff --git a/voxygen/Settings.toml b/voxygen/Settings.toml new file mode 100644 index 0000000000..238f3fd281 --- /dev/null +++ b/voxygen/Settings.toml @@ -0,0 +1,17 @@ +[controls] +toggle_cursor = "tab" +escape = "escape" +enter = "return" +move_forward = "w" +move_left = "a" +move_back = "s" +move_right = "d" +map = "m" +bag = "b" +quest_log = "l" +character_window = "c" +social = "o" +spellbook = "p" +settings = "n" +help = "f1" +interface = "f2" diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index b2bdcf65aa..309f35b5d6 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -12,6 +12,10 @@ pub mod scene; pub mod session; pub mod ui; pub mod window; +pub mod settings; + +// Rust complains that the Settings struct is undeclared without this +use settings::Settings; // Reexports pub use crate::error::Error; @@ -31,6 +35,7 @@ use crate::{ /// A type used to store state that is shared between all play states pub struct GlobalState { + settings: Settings, window: Window, } @@ -72,9 +77,12 @@ fn main() { pretty_env_logger::init(); // Set up the global state + let settings = Settings::load().expect("Failed to load configuration file."); + let window = Window::new(&settings).expect("Failed to create window"); + let mut global_state = GlobalState { - window: Window::new() - .expect("Failed to create window"), + settings, + window, }; // Set up the initial play state diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs new file mode 100644 index 0000000000..1e37a48fd5 --- /dev/null +++ b/voxygen/src/settings.rs @@ -0,0 +1,40 @@ +use config::{ + Config, + ConfigError, +}; +use serde_derive::{Serialize, Deserialize}; + +use glutin::VirtualKeyCode; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Settings { + pub controls: ControlSettings, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ControlSettings { + pub toggle_cursor: VirtualKeyCode, + pub escape: VirtualKeyCode, + pub enter: VirtualKeyCode, + pub move_forward: VirtualKeyCode, + pub move_left: VirtualKeyCode, + pub move_back: VirtualKeyCode, + pub move_right: VirtualKeyCode, + pub map: VirtualKeyCode, + pub bag: VirtualKeyCode, + pub quest_log: VirtualKeyCode, + pub character_window: VirtualKeyCode, + pub social: VirtualKeyCode, + pub spellbook: VirtualKeyCode, + pub settings: VirtualKeyCode, + pub help: VirtualKeyCode, + pub interface: VirtualKeyCode, +} + +impl Settings { + pub fn load() -> Result { + let mut config = Config::new(); + config.merge(config::File::with_name("Settings"))?; + config.try_into() + } +} diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 39009e4b16..59913c0069 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -1,6 +1,6 @@ use crate::{ render::{Renderer, TgtColorFmt, TgtDepthFmt}, - ui, Error, + ui, Error, settings::Settings, }; use std::collections::HashMap; use vek::*; @@ -15,7 +15,7 @@ pub struct Window { } impl Window { - pub fn new() -> Result { + pub fn new(settings: &Settings) -> Result { let events_loop = glutin::EventsLoop::new(); let win_builder = glutin::WindowBuilder::new() @@ -36,22 +36,22 @@ impl Window { .map_err(|err| Error::BackendError(Box::new(err)))?; let mut key_map = HashMap::new(); - key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor); - key_map.insert(glutin::VirtualKeyCode::Escape, Key::Escape); - key_map.insert(glutin::VirtualKeyCode::Return, Key::Enter); - key_map.insert(glutin::VirtualKeyCode::W, Key::MoveForward); - key_map.insert(glutin::VirtualKeyCode::A, Key::MoveLeft); - key_map.insert(glutin::VirtualKeyCode::S, Key::MoveBack); - key_map.insert(glutin::VirtualKeyCode::D, Key::MoveRight); - key_map.insert(glutin::VirtualKeyCode::M, Key::Map); - key_map.insert(glutin::VirtualKeyCode::B, Key::Bag); - key_map.insert(glutin::VirtualKeyCode::L, Key::QuestLog); - key_map.insert(glutin::VirtualKeyCode::C, Key::CharacterWindow); - key_map.insert(glutin::VirtualKeyCode::O, Key::Social); - key_map.insert(glutin::VirtualKeyCode::P, Key::Spellbook); - key_map.insert(glutin::VirtualKeyCode::N, Key::Settings); - key_map.insert(glutin::VirtualKeyCode::F1, Key::Help); - key_map.insert(glutin::VirtualKeyCode::F2, Key::Interface); + key_map.insert(settings.controls.toggle_cursor, Key::ToggleCursor); + key_map.insert(settings.controls.escape, Key::Escape); + key_map.insert(settings.controls.enter, Key::Enter); + key_map.insert(settings.controls.move_forward, Key::MoveForward); + key_map.insert(settings.controls.move_left, Key::MoveLeft); + key_map.insert(settings.controls.move_back, Key::MoveBack); + key_map.insert(settings.controls.move_right, Key::MoveRight); + key_map.insert(settings.controls.map, Key::Map); + key_map.insert(settings.controls.bag, Key::Bag); + key_map.insert(settings.controls.quest_log, Key::QuestLog); + key_map.insert(settings.controls.character_window, Key::CharacterWindow); + key_map.insert(settings.controls.social, Key::Social); + key_map.insert(settings.controls.spellbook, Key::Spellbook); + key_map.insert(settings.controls.settings, Key::Settings); + key_map.insert(settings.controls.help, Key::Help); + key_map.insert(settings.controls.interface, Key::Interface); let tmp = Ok(Self { events_loop, @@ -113,18 +113,21 @@ impl Window { }, _ => {} }, - glutin::WindowEvent::MouseWheel { - delta: glutin::MouseScrollDelta::LineDelta(_x, y), - .. - } => events.push(Event::Zoom(y as f32)), - _ => {}, + _ => {} }, glutin::Event::DeviceEvent { event, .. } => match event { - glutin::DeviceEvent::MouseMotion { delta: (dx, dy), .. } if cursor_grabbed => - events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32))), - _ => {}, + glutin::DeviceEvent::MouseMotion { + delta: (dx, dy), .. + } if cursor_grabbed => { + events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32))) + } + glutin::DeviceEvent::MouseWheel { + delta: glutin::MouseScrollDelta::LineDelta(_x, y), + .. + } if cursor_grabbed => events.push(Event::Zoom(y as f32)), + _ => {} }, - _ => {}, + _ => {} } }); events