2019-01-07 21:10:31 +00:00
|
|
|
use crate::{
|
2019-05-06 16:27:21 +00:00
|
|
|
render::{Renderer, WinColorFmt, WinDepthFmt},
|
2019-04-29 20:37:19 +00:00
|
|
|
settings::Settings,
|
|
|
|
ui, Error,
|
2019-01-07 21:10:31 +00:00
|
|
|
};
|
2019-08-11 19:52:23 +00:00
|
|
|
use hashbrown::HashMap;
|
2019-06-06 14:48:41 +00:00
|
|
|
use log::{error, warn};
|
2019-05-25 14:39:27 +00:00
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2019-04-02 04:54:27 +00:00
|
|
|
use vek::*;
|
2019-01-02 21:25:01 +00:00
|
|
|
|
2019-05-25 14:39:27 +00:00
|
|
|
/// Represents a key that the game recognises after keyboard mapping.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
|
|
|
pub enum GameInput {
|
2019-08-30 22:13:45 +00:00
|
|
|
Primary,
|
|
|
|
Secondary,
|
2019-05-25 14:39:27 +00:00
|
|
|
ToggleCursor,
|
|
|
|
MoveForward,
|
|
|
|
MoveBack,
|
|
|
|
MoveLeft,
|
|
|
|
MoveRight,
|
|
|
|
Jump,
|
2019-09-09 19:11:40 +00:00
|
|
|
Sit,
|
2019-05-25 14:39:27 +00:00
|
|
|
Glide,
|
2019-09-09 19:11:40 +00:00
|
|
|
Climb,
|
|
|
|
ClimbDown,
|
|
|
|
WallLeap,
|
|
|
|
Mount,
|
2019-05-25 14:39:27 +00:00
|
|
|
Enter,
|
2019-07-05 16:21:11 +00:00
|
|
|
Command,
|
2019-05-25 14:39:27 +00:00
|
|
|
Escape,
|
|
|
|
Map,
|
|
|
|
Bag,
|
|
|
|
QuestLog,
|
|
|
|
CharacterWindow,
|
|
|
|
Social,
|
|
|
|
Spellbook,
|
|
|
|
Settings,
|
|
|
|
ToggleInterface,
|
|
|
|
Help,
|
|
|
|
ToggleDebug,
|
|
|
|
Fullscreen,
|
|
|
|
Screenshot,
|
|
|
|
ToggleIngameUi,
|
2019-06-11 04:08:55 +00:00
|
|
|
Roll,
|
2019-05-25 14:39:27 +00:00
|
|
|
Respawn,
|
2019-07-29 16:19:08 +00:00
|
|
|
Interact,
|
2019-11-29 15:20:35 +00:00
|
|
|
ToggleWield,
|
2019-05-25 14:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Represents an incoming event from the window.
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub enum Event {
|
|
|
|
/// The window has been requested to close.
|
|
|
|
Close,
|
|
|
|
/// The window has been resized.
|
|
|
|
Resize(Vec2<u32>),
|
|
|
|
/// A key has been typed that corresponds to a specific character.
|
|
|
|
Char(char),
|
|
|
|
/// The cursor has been panned across the screen while grabbed.
|
|
|
|
CursorPan(Vec2<f32>),
|
2019-09-18 16:46:12 +00:00
|
|
|
/// The cursor has been moved across the screen while ungrabbed.
|
|
|
|
CursorMove(Vec2<f32>),
|
|
|
|
/// A mouse button has been pressed or released
|
|
|
|
MouseButton(MouseButton, PressState),
|
2019-05-25 14:39:27 +00:00
|
|
|
/// The camera has been requested to zoom.
|
|
|
|
Zoom(f32),
|
|
|
|
/// A key that the game recognises has been pressed or released.
|
|
|
|
InputUpdate(GameInput, bool),
|
|
|
|
/// Event that the ui uses.
|
|
|
|
Ui(ui::Event),
|
2019-06-05 15:57:48 +00:00
|
|
|
/// The view distance has changed.
|
2019-05-25 14:39:27 +00:00
|
|
|
ViewDistanceChanged(u32),
|
|
|
|
/// Game settings have changed.
|
|
|
|
SettingsChanged,
|
2019-06-29 01:39:47 +00:00
|
|
|
/// The window is (un)focused
|
|
|
|
Focused(bool),
|
2019-05-25 14:39:27 +00:00
|
|
|
}
|
|
|
|
|
2019-09-18 16:46:12 +00:00
|
|
|
pub type MouseButton = winit::MouseButton;
|
|
|
|
pub type PressState = winit::ElementState;
|
|
|
|
|
2019-05-25 14:39:27 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
|
|
|
pub enum KeyMouse {
|
|
|
|
Key(glutin::VirtualKeyCode),
|
|
|
|
Mouse(glutin::MouseButton),
|
|
|
|
}
|
2019-05-25 12:53:44 +00:00
|
|
|
|
2019-01-02 21:25:01 +00:00
|
|
|
pub struct Window {
|
2019-01-11 17:30:13 +00:00
|
|
|
events_loop: glutin::EventsLoop,
|
2019-01-07 21:10:31 +00:00
|
|
|
renderer: Renderer,
|
2019-07-28 15:47:14 +00:00
|
|
|
window: glutin::ContextWrapper<glutin::PossiblyCurrent, winit::Window>,
|
2019-01-23 22:21:47 +00:00
|
|
|
cursor_grabbed: bool,
|
2019-06-06 17:42:13 +00:00
|
|
|
pub pan_sensitivity: u32,
|
|
|
|
pub zoom_sensitivity: u32,
|
2019-10-02 12:44:41 +00:00
|
|
|
pub zoom_inversion: bool,
|
2019-05-18 21:16:35 +00:00
|
|
|
fullscreen: bool,
|
2019-03-28 04:42:04 +00:00
|
|
|
needs_refresh_resize: bool,
|
2019-08-27 11:42:17 +00:00
|
|
|
key_map: HashMap<KeyMouse, Vec<GameInput>>,
|
2019-06-30 04:20:50 +00:00
|
|
|
keypress_map: HashMap<GameInput, glutin::ElementState>,
|
2019-04-25 15:32:59 +00:00
|
|
|
supplement_events: Vec<Event>,
|
2019-05-25 11:52:43 +00:00
|
|
|
focused: bool,
|
2019-01-02 21:25:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Window {
|
2019-04-15 17:51:26 +00:00
|
|
|
pub fn new(settings: &Settings) -> Result<Window, Error> {
|
2019-01-11 17:30:13 +00:00
|
|
|
let events_loop = glutin::EventsLoop::new();
|
2019-01-02 21:25:01 +00:00
|
|
|
|
2019-01-11 17:30:13 +00:00
|
|
|
let win_builder = glutin::WindowBuilder::new()
|
2019-03-15 04:55:52 +00:00
|
|
|
.with_title("Veloren")
|
2019-08-04 11:23:01 +00:00
|
|
|
.with_dimensions(glutin::dpi::LogicalSize::new(1920.0, 1080.0))
|
2019-03-15 04:55:52 +00:00
|
|
|
.with_maximized(true);
|
2019-01-11 17:30:13 +00:00
|
|
|
|
|
|
|
let ctx_builder = glutin::ContextBuilder::new()
|
|
|
|
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
|
2019-03-15 04:55:52 +00:00
|
|
|
.with_vsync(false);
|
2019-01-11 17:30:13 +00:00
|
|
|
|
2019-05-06 16:27:21 +00:00
|
|
|
let (window, device, factory, win_color_view, win_depth_view) =
|
|
|
|
gfx_window_glutin::init::<WinColorFmt, WinDepthFmt>(
|
2019-04-02 04:54:27 +00:00
|
|
|
win_builder,
|
|
|
|
ctx_builder,
|
|
|
|
&events_loop,
|
|
|
|
)
|
|
|
|
.map_err(|err| Error::BackendError(Box::new(err)))?;
|
2019-01-02 21:25:01 +00:00
|
|
|
|
2019-08-27 11:42:17 +00:00
|
|
|
let mut map: HashMap<_, Vec<_>> = HashMap::new();
|
2019-08-30 22:13:45 +00:00
|
|
|
map.entry(settings.controls.primary)
|
2019-08-27 11:42:17 +00:00
|
|
|
.or_default()
|
2019-08-30 22:13:45 +00:00
|
|
|
.push(GameInput::Primary);
|
|
|
|
map.entry(settings.controls.secondary)
|
2019-08-27 11:42:17 +00:00
|
|
|
.or_default()
|
2019-08-30 22:13:45 +00:00
|
|
|
.push(GameInput::Secondary);
|
2019-08-27 11:42:17 +00:00
|
|
|
map.entry(settings.controls.toggle_cursor)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ToggleCursor);
|
|
|
|
map.entry(settings.controls.escape)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Escape);
|
|
|
|
map.entry(settings.controls.enter)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Enter);
|
|
|
|
map.entry(settings.controls.command)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Command);
|
|
|
|
map.entry(settings.controls.move_forward)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::MoveForward);
|
|
|
|
map.entry(settings.controls.move_left)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::MoveLeft);
|
|
|
|
map.entry(settings.controls.move_back)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::MoveBack);
|
|
|
|
map.entry(settings.controls.move_right)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::MoveRight);
|
|
|
|
map.entry(settings.controls.jump)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Jump);
|
2019-09-09 19:11:40 +00:00
|
|
|
map.entry(settings.controls.sit)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Sit);
|
2019-08-27 11:42:17 +00:00
|
|
|
map.entry(settings.controls.glide)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Glide);
|
2019-09-09 19:11:40 +00:00
|
|
|
map.entry(settings.controls.climb)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Climb);
|
|
|
|
map.entry(settings.controls.climb_down)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ClimbDown);
|
|
|
|
map.entry(settings.controls.wall_leap)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::WallLeap);
|
|
|
|
map.entry(settings.controls.mount)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Mount);
|
2019-08-27 11:42:17 +00:00
|
|
|
map.entry(settings.controls.map)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Map);
|
|
|
|
map.entry(settings.controls.bag)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Bag);
|
|
|
|
map.entry(settings.controls.quest_log)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::QuestLog);
|
|
|
|
map.entry(settings.controls.character_window)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::CharacterWindow);
|
|
|
|
map.entry(settings.controls.social)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Social);
|
|
|
|
map.entry(settings.controls.spellbook)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Spellbook);
|
|
|
|
map.entry(settings.controls.settings)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Settings);
|
|
|
|
map.entry(settings.controls.help)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Help);
|
|
|
|
map.entry(settings.controls.toggle_interface)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ToggleInterface);
|
|
|
|
map.entry(settings.controls.toggle_debug)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ToggleDebug);
|
|
|
|
map.entry(settings.controls.fullscreen)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Fullscreen);
|
|
|
|
map.entry(settings.controls.screenshot)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Screenshot);
|
|
|
|
map.entry(settings.controls.toggle_ingame_ui)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ToggleIngameUi);
|
|
|
|
map.entry(settings.controls.roll)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Roll);
|
|
|
|
map.entry(settings.controls.respawn)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Respawn);
|
|
|
|
map.entry(settings.controls.interact)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::Interact);
|
2019-11-29 15:20:35 +00:00
|
|
|
map.entry(settings.controls.toggle_wield)
|
|
|
|
.or_default()
|
|
|
|
.push(GameInput::ToggleWield);
|
2019-06-11 04:08:55 +00:00
|
|
|
|
2019-06-30 04:20:50 +00:00
|
|
|
let keypress_map = HashMap::new();
|
|
|
|
|
2019-05-25 02:30:56 +00:00
|
|
|
Ok(Self {
|
2019-01-02 21:25:01 +00:00
|
|
|
events_loop,
|
2019-09-26 07:28:40 +00:00
|
|
|
renderer: Renderer::new(
|
|
|
|
device,
|
|
|
|
factory,
|
|
|
|
win_color_view,
|
|
|
|
win_depth_view,
|
|
|
|
settings.graphics.aa_mode,
|
|
|
|
)?,
|
2019-01-23 22:21:47 +00:00
|
|
|
window,
|
|
|
|
cursor_grabbed: false,
|
2019-06-05 15:57:48 +00:00
|
|
|
pan_sensitivity: settings.gameplay.pan_sensitivity,
|
|
|
|
zoom_sensitivity: settings.gameplay.zoom_sensitivity,
|
2019-10-02 12:44:41 +00:00
|
|
|
zoom_inversion: settings.gameplay.zoom_inversion,
|
2019-05-18 21:16:35 +00:00
|
|
|
fullscreen: false,
|
2019-03-28 04:42:04 +00:00
|
|
|
needs_refresh_resize: false,
|
2019-08-27 11:42:17 +00:00
|
|
|
key_map: map,
|
2019-06-30 04:20:50 +00:00
|
|
|
keypress_map,
|
2019-04-25 15:32:59 +00:00
|
|
|
supplement_events: vec![],
|
2019-05-25 11:52:43 +00:00
|
|
|
focused: true,
|
2019-05-25 02:30:56 +00:00
|
|
|
})
|
2019-01-02 21:25:01 +00:00
|
|
|
}
|
|
|
|
|
2019-04-02 04:54:27 +00:00
|
|
|
pub fn renderer(&self) -> &Renderer {
|
|
|
|
&self.renderer
|
|
|
|
}
|
|
|
|
pub fn renderer_mut(&mut self) -> &mut Renderer {
|
|
|
|
&mut self.renderer
|
|
|
|
}
|
2019-01-02 22:08:13 +00:00
|
|
|
|
2019-01-07 21:10:31 +00:00
|
|
|
pub fn fetch_events(&mut self) -> Vec<Event> {
|
2019-03-30 02:15:27 +00:00
|
|
|
let mut events = vec![];
|
2019-04-25 15:32:59 +00:00
|
|
|
events.append(&mut self.supplement_events);
|
2019-03-28 04:42:04 +00:00
|
|
|
// Refresh ui size (used when changing playstates)
|
|
|
|
if self.needs_refresh_resize {
|
|
|
|
events.push(Event::Ui(ui::Event::new_resize(self.logical_size())));
|
|
|
|
self.needs_refresh_resize = false;
|
|
|
|
}
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
// Copy data that is needed by the events closure to avoid lifetime errors.
|
|
|
|
// TODO: Remove this if/when the compiler permits it.
|
2019-01-23 22:21:47 +00:00
|
|
|
let cursor_grabbed = self.cursor_grabbed;
|
2019-01-23 22:39:31 +00:00
|
|
|
let renderer = &mut self.renderer;
|
|
|
|
let window = &mut self.window;
|
2019-05-25 11:52:43 +00:00
|
|
|
let focused = &mut self.focused;
|
2019-03-02 03:48:30 +00:00
|
|
|
let key_map = &self.key_map;
|
2019-07-02 21:29:38 +00:00
|
|
|
let keypress_map = &mut self.keypress_map;
|
2019-05-25 02:30:56 +00:00
|
|
|
let pan_sensitivity = self.pan_sensitivity;
|
|
|
|
let zoom_sensitivity = self.zoom_sensitivity;
|
2019-10-02 12:44:41 +00:00
|
|
|
let zoom_inversion = match self.zoom_inversion {
|
|
|
|
true => -1.0,
|
|
|
|
false => 1.0,
|
|
|
|
};
|
2019-05-18 21:16:35 +00:00
|
|
|
let mut toggle_fullscreen = false;
|
|
|
|
let mut take_screenshot = false;
|
2019-01-23 22:21:47 +00:00
|
|
|
|
2019-03-22 03:55:42 +00:00
|
|
|
self.events_loop.poll_events(|event| {
|
2019-05-17 09:22:32 +00:00
|
|
|
// Get events for ui.
|
2019-07-28 15:47:14 +00:00
|
|
|
if let Some(event) = ui::Event::try_from(event.clone(), window) {
|
2019-03-22 03:55:42 +00:00
|
|
|
events.push(Event::Ui(event));
|
|
|
|
}
|
|
|
|
|
|
|
|
match event {
|
|
|
|
glutin::Event::WindowEvent { event, .. } => match event {
|
|
|
|
glutin::WindowEvent::CloseRequested => events.push(Event::Close),
|
|
|
|
glutin::WindowEvent::Resized(glutin::dpi::LogicalSize { width, height }) => {
|
2019-05-07 11:27:40 +00:00
|
|
|
let (mut color_view, mut depth_view) = renderer.win_views_mut();
|
2019-07-28 15:47:14 +00:00
|
|
|
gfx_window_glutin::update_views(window, &mut color_view, &mut depth_view);
|
2019-05-06 08:22:47 +00:00
|
|
|
renderer.on_resize().unwrap();
|
2019-03-22 03:55:42 +00:00
|
|
|
events.push(Event::Resize(Vec2::new(width as u32, height as u32)));
|
2019-04-02 04:54:27 +00:00
|
|
|
}
|
2019-03-22 03:55:42 +00:00
|
|
|
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
|
2019-09-18 16:46:12 +00:00
|
|
|
glutin::WindowEvent::MouseInput { button, state, .. } => {
|
|
|
|
if let (true, Some(game_inputs)) =
|
|
|
|
(cursor_grabbed, key_map.get(&KeyMouse::Mouse(button)))
|
|
|
|
{
|
2019-08-27 11:42:17 +00:00
|
|
|
for game_input in game_inputs {
|
|
|
|
events.push(Event::InputUpdate(
|
|
|
|
*game_input,
|
|
|
|
state == glutin::ElementState::Pressed,
|
|
|
|
));
|
|
|
|
}
|
2019-05-25 14:39:27 +00:00
|
|
|
}
|
2019-09-18 16:46:12 +00:00
|
|
|
events.push(Event::MouseButton(button, state));
|
2019-05-17 20:47:58 +00:00
|
|
|
}
|
2019-04-02 04:54:27 +00:00
|
|
|
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode
|
|
|
|
{
|
2019-08-27 11:42:17 +00:00
|
|
|
Some(key) => {
|
|
|
|
let game_inputs = key_map.get(&KeyMouse::Key(key));
|
|
|
|
if let Some(game_inputs) = game_inputs {
|
|
|
|
for game_input in game_inputs {
|
|
|
|
match game_input {
|
|
|
|
GameInput::Fullscreen => {
|
|
|
|
if input.state == glutin::ElementState::Pressed
|
|
|
|
&& !Self::is_pressed(
|
|
|
|
keypress_map,
|
|
|
|
GameInput::Fullscreen,
|
|
|
|
)
|
|
|
|
{
|
|
|
|
toggle_fullscreen = !toggle_fullscreen;
|
|
|
|
}
|
|
|
|
Self::set_pressed(
|
|
|
|
keypress_map,
|
|
|
|
GameInput::Fullscreen,
|
|
|
|
input.state,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
GameInput::Screenshot => {
|
|
|
|
take_screenshot = input.state
|
|
|
|
== glutin::ElementState::Pressed
|
|
|
|
&& !Self::is_pressed(
|
|
|
|
keypress_map,
|
|
|
|
GameInput::Screenshot,
|
|
|
|
);
|
|
|
|
Self::set_pressed(
|
|
|
|
keypress_map,
|
|
|
|
GameInput::Screenshot,
|
|
|
|
input.state,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
_ => events.push(Event::InputUpdate(
|
|
|
|
*game_input,
|
|
|
|
input.state == glutin::ElementState::Pressed,
|
|
|
|
)),
|
|
|
|
}
|
2019-05-18 21:16:35 +00:00
|
|
|
}
|
2019-06-30 04:20:50 +00:00
|
|
|
}
|
2019-08-27 11:42:17 +00:00
|
|
|
}
|
2019-04-02 04:54:27 +00:00
|
|
|
_ => {}
|
2019-03-02 03:48:30 +00:00
|
|
|
},
|
2019-06-29 01:39:47 +00:00
|
|
|
glutin::WindowEvent::Focused(state) => {
|
|
|
|
*focused = state;
|
|
|
|
events.push(Event::Focused(state));
|
|
|
|
}
|
2019-04-15 17:51:26 +00:00
|
|
|
_ => {}
|
2019-02-02 20:18:40 +00:00
|
|
|
},
|
|
|
|
glutin::Event::DeviceEvent { event, .. } => match event {
|
2019-04-15 17:51:26 +00:00
|
|
|
glutin::DeviceEvent::MouseMotion {
|
|
|
|
delta: (dx, dy), ..
|
2019-09-18 16:46:12 +00:00
|
|
|
} if *focused => {
|
|
|
|
let delta = Vec2::new(
|
|
|
|
dx as f32 * (pan_sensitivity as f32 / 100.0),
|
|
|
|
dy as f32 * (pan_sensitivity as f32 / 100.0),
|
|
|
|
);
|
|
|
|
|
|
|
|
if cursor_grabbed {
|
|
|
|
events.push(Event::CursorPan(delta));
|
|
|
|
} else {
|
|
|
|
events.push(Event::CursorMove(delta));
|
|
|
|
}
|
|
|
|
}
|
2019-04-15 17:51:26 +00:00
|
|
|
glutin::DeviceEvent::MouseWheel {
|
|
|
|
delta: glutin::MouseScrollDelta::LineDelta(_x, y),
|
|
|
|
..
|
2019-10-02 23:16:46 +00:00
|
|
|
} if cursor_grabbed && *focused => events.push(Event::Zoom(
|
|
|
|
y * (zoom_sensitivity as f32 / 100.0) * zoom_inversion,
|
|
|
|
)),
|
2019-04-15 17:51:26 +00:00
|
|
|
_ => {}
|
2019-03-22 03:55:42 +00:00
|
|
|
},
|
2019-04-15 17:51:26 +00:00
|
|
|
_ => {}
|
2019-03-22 03:55:42 +00:00
|
|
|
}
|
2019-01-02 21:25:01 +00:00
|
|
|
});
|
2019-05-18 21:16:35 +00:00
|
|
|
|
|
|
|
if take_screenshot {
|
|
|
|
self.take_screenshot();
|
|
|
|
}
|
|
|
|
|
|
|
|
if toggle_fullscreen {
|
|
|
|
self.fullscreen(!self.is_fullscreen());
|
|
|
|
}
|
|
|
|
|
2019-01-07 21:10:31 +00:00
|
|
|
events
|
2019-01-02 21:25:01 +00:00
|
|
|
}
|
|
|
|
|
2019-01-12 01:14:58 +00:00
|
|
|
pub fn swap_buffers(&self) -> Result<(), Error> {
|
2019-04-02 04:54:27 +00:00
|
|
|
self.window
|
|
|
|
.swap_buffers()
|
2019-01-11 23:18:34 +00:00
|
|
|
.map_err(|err| Error::BackendError(Box::new(err)))
|
2019-01-02 21:25:01 +00:00
|
|
|
}
|
2019-01-12 01:14:58 +00:00
|
|
|
|
2019-01-23 22:21:47 +00:00
|
|
|
pub fn is_cursor_grabbed(&self) -> bool {
|
|
|
|
self.cursor_grabbed
|
2019-01-12 01:14:58 +00:00
|
|
|
}
|
|
|
|
|
2019-01-23 22:21:47 +00:00
|
|
|
pub fn grab_cursor(&mut self, grab: bool) {
|
|
|
|
self.cursor_grabbed = grab;
|
2019-07-28 15:47:14 +00:00
|
|
|
self.window.window().hide_cursor(grab);
|
|
|
|
let _ = self.window.window().grab_cursor(grab);
|
2019-01-12 01:14:58 +00:00
|
|
|
}
|
2019-02-16 03:01:42 +00:00
|
|
|
|
2019-05-18 21:16:35 +00:00
|
|
|
pub fn is_fullscreen(&self) -> bool {
|
|
|
|
self.fullscreen
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fullscreen(&mut self, fullscreen: bool) {
|
2019-07-28 15:47:14 +00:00
|
|
|
let window = self.window.window();
|
2019-05-18 21:16:35 +00:00
|
|
|
self.fullscreen = fullscreen;
|
|
|
|
if fullscreen {
|
2019-07-28 15:47:14 +00:00
|
|
|
window.set_fullscreen(Some(window.get_current_monitor()));
|
2019-05-18 21:16:35 +00:00
|
|
|
} else {
|
2019-07-28 15:47:14 +00:00
|
|
|
window.set_fullscreen(None);
|
2019-05-18 21:16:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-28 04:42:04 +00:00
|
|
|
pub fn needs_refresh_resize(&mut self) {
|
|
|
|
self.needs_refresh_resize = true;
|
|
|
|
}
|
|
|
|
|
2019-03-03 23:55:07 +00:00
|
|
|
pub fn logical_size(&self) -> Vec2<f64> {
|
2019-04-02 04:54:27 +00:00
|
|
|
let (w, h) = self
|
|
|
|
.window
|
2019-07-28 15:47:14 +00:00
|
|
|
.window()
|
2019-04-02 04:54:27 +00:00
|
|
|
.get_inner_size()
|
|
|
|
.unwrap_or(glutin::dpi::LogicalSize::new(0.0, 0.0))
|
|
|
|
.into();
|
2019-03-03 23:55:07 +00:00
|
|
|
Vec2::new(w, h)
|
2019-02-16 03:01:42 +00:00
|
|
|
}
|
2019-05-01 22:15:43 +00:00
|
|
|
|
2019-04-25 15:32:59 +00:00
|
|
|
pub fn send_supplement_event(&mut self, event: Event) {
|
|
|
|
self.supplement_events.push(event)
|
2019-04-25 13:10:01 +00:00
|
|
|
}
|
2019-05-18 21:16:35 +00:00
|
|
|
|
|
|
|
pub fn take_screenshot(&mut self) {
|
|
|
|
match self.renderer.create_screenshot() {
|
|
|
|
Ok(img) => {
|
|
|
|
std::thread::spawn(move || {
|
|
|
|
use std::{path::PathBuf, time::SystemTime};
|
|
|
|
// Check if folder exists and create it if it does not
|
2019-05-19 16:25:02 +00:00
|
|
|
let mut path = PathBuf::from("./screenshots");
|
2019-05-18 21:16:35 +00:00
|
|
|
if !path.exists() {
|
|
|
|
if let Err(err) = std::fs::create_dir(&path) {
|
2019-06-06 14:48:41 +00:00
|
|
|
warn!("Couldn't create folder for screenshot: {:?}", err);
|
2019-05-18 21:16:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
path.push(format!(
|
|
|
|
"screenshot_{}.png",
|
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.map(|d| d.as_millis())
|
|
|
|
.unwrap_or(0)
|
|
|
|
));
|
|
|
|
if let Err(err) = img.save(&path) {
|
2019-06-06 14:48:41 +00:00
|
|
|
warn!("Couldn't save screenshot: {:?}", err);
|
2019-05-18 21:16:35 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-06-06 14:48:41 +00:00
|
|
|
Err(err) => error!(
|
2019-05-31 01:43:52 +00:00
|
|
|
"Couldn't create screenshot due to renderer error: {:?}",
|
|
|
|
err
|
|
|
|
),
|
2019-05-18 21:16:35 +00:00
|
|
|
}
|
|
|
|
}
|
2019-06-30 04:20:50 +00:00
|
|
|
|
2019-08-27 11:15:26 +00:00
|
|
|
fn is_pressed(map: &mut HashMap<GameInput, glutin::ElementState>, input: GameInput) -> bool {
|
2019-06-30 04:20:50 +00:00
|
|
|
*(map.entry(input).or_insert(glutin::ElementState::Released))
|
|
|
|
== glutin::ElementState::Pressed
|
|
|
|
}
|
|
|
|
|
2019-08-27 11:15:26 +00:00
|
|
|
fn set_pressed(
|
2019-06-30 04:20:50 +00:00
|
|
|
map: &mut HashMap<GameInput, glutin::ElementState>,
|
|
|
|
input: GameInput,
|
|
|
|
state: glutin::ElementState,
|
|
|
|
) {
|
|
|
|
map.insert(input, state);
|
|
|
|
}
|
2019-01-02 21:25:01 +00:00
|
|
|
}
|