diff --git a/src/main.rs b/src/main.rs index 1d7bcf5..f22341d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,9 @@ use ash::Entry; use ash::Instance; use ash::khr::{surface, swapchain}; use ash::vk; +use sdl2::mouse::MouseUtil; +use std::cmp; use std::ffi::CStr; use std::ffi::CString; use std::thread; @@ -23,6 +25,13 @@ use sdl2::video::Window; const APP_NAME: &str = "MineClone"; +const MOV_STEP: f32 = 0.05; +const ROT_STEP: f32 = 0.05; +const ROT_MOUSE_SCALE: f32 = 0.001; + +const MAX_WIDTH: u32 = 3440; +const MAX_HEIGHT: u32 = 1440; + const MESH_SIZE: u64 = 36 * 2 * 4 * 4; const POSITIONS: [f32; 36 * 2 * 4] = [ @@ -571,8 +580,8 @@ fn setup_swapchain( .image_format(format.format) .image_color_space(format.color_space) .image_extent(vk::Extent2D { - width: std::cmp::max(caps.current_extent.width, width), - height: std::cmp::max(caps.current_extent.height, height), + width: cmp::min(cmp::max(caps.current_extent.width, width), MAX_WIDTH), + height: cmp::min(cmp::max(caps.current_extent.height, height), MAX_HEIGHT), }) .image_array_layers(1) .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) @@ -956,43 +965,29 @@ struct Camera { rotation: Vector3, } -fn handle_key(keycode: Keycode, camera: &mut Camera) { - let mov_scale = 0.05; - let rot_scale = 0.05; +fn handle_cont_key(keycode: Keycode, camera: &mut Camera, mouse: &MouseUtil) { match keycode { Keycode::W => { - camera.origin.x -= -camera.rotation.y.sin() * mov_scale; - camera.origin.z -= camera.rotation.y.cos() * mov_scale; + camera.origin.x -= -camera.rotation.y.sin() * MOV_STEP; + camera.origin.z -= camera.rotation.y.cos() * MOV_STEP; } Keycode::S => { - camera.origin.x += -camera.rotation.y.sin() * mov_scale; - camera.origin.z += camera.rotation.y.cos() * mov_scale; + camera.origin.x += -camera.rotation.y.sin() * MOV_STEP; + camera.origin.z += camera.rotation.y.cos() * MOV_STEP; } Keycode::A => { - camera.origin.x += camera.rotation.y.cos() * mov_scale; - camera.origin.z += camera.rotation.y.sin() * mov_scale; + camera.origin.x += camera.rotation.y.cos() * MOV_STEP; + camera.origin.z += camera.rotation.y.sin() * MOV_STEP; } Keycode::D => { - camera.origin.z -= camera.rotation.y.sin() * mov_scale; - camera.origin.x -= camera.rotation.y.cos() * mov_scale; - } - Keycode::R => { - camera.rotation.x += rot_scale; - } - Keycode::F => { - camera.rotation.x -= rot_scale; - } - Keycode::Q => { - camera.rotation.y += rot_scale; - } - Keycode::E => { - camera.rotation.y -= rot_scale; + camera.origin.z -= camera.rotation.y.sin() * MOV_STEP; + camera.origin.x -= camera.rotation.y.cos() * MOV_STEP; } Keycode::Space => { - camera.origin.y += mov_scale; + camera.origin.y += MOV_STEP; } Keycode::LShift => { - camera.origin.y -= mov_scale; + camera.origin.y -= MOV_STEP; } _ => {} } @@ -1001,20 +996,21 @@ fn handle_key(keycode: Keycode, camera: &mut Camera) { fn main() { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); + let mouse = sdl_context.mouse(); let mut width = 1024; let mut height = 768; - let max_width = 3440; - let max_height = 1440; - - let window = video_subsystem + let mut window = video_subsystem .window(APP_NAME, width, height) .vulkan() .resizable() .build() .unwrap(); + // We start in relative move + mouse.set_relative_mouse_mode(true); + let entry = Entry::linked(); let instance = create_instance(&window, &entry); @@ -1046,7 +1042,11 @@ fn main() { let mesh_mem = mem_alloc(&dev, host_visible_inx, MESH_SIZE); // Max viewport size is 3440x1440 - let depth_mem = mem_alloc(&dev, host_invisible_inx, max_width * max_height * 8); + let depth_mem = mem_alloc( + &dev, + host_invisible_inx, + (MAX_WIDTH * MAX_HEIGHT * 8) as u64, + ); let mut depth_img = make_depth_img( &dev, @@ -1188,6 +1188,28 @@ fn main() { framebufs = make_framebufs(&dev, &swap_views, &depth_view, &pass, width, height); } + // We do this key here and not in `handle_cont_key()` because we don't want key + // repeat, just a single press + Event::KeyDown { + keycode: Some(Keycode::ESCAPE), + repeat: false, + .. + } => { + mouse.set_relative_mouse_mode(!mouse.relative_mouse_mode()); + } + Event::MouseMotion { + window_id, + xrel, + yrel, + .. + } + // We only wanna do movement if the mouse is in relative mode (ie. its pinned to + // the center of the window and hidden) + if mouse.relative_mouse_mode() => { + camera.rotation.y -= xrel as f32 * ROT_MOUSE_SCALE; + camera.rotation.x += yrel as f32 * ROT_MOUSE_SCALE; + mouse.warp_mouse_in_window(&window, width as i32 / 2, height as i32 / 2); + } _ => {} } } @@ -1196,7 +1218,7 @@ fn main() { .keyboard_state() .pressed_scancodes() .filter_map(Keycode::from_scancode) - .for_each(|k| handle_key(k, &mut camera)); + .for_each(|k| handle_cont_key(k, &mut camera, &mouse)); wait_for_fence(&dev, &fence_flight); reset_fence(&dev, &fence_flight);