diff --git a/examples/test.rs b/examples/test.rs index 167f420..9ca96ee 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -1,7 +1,7 @@ use skunk2d::*; -const WIDTH: i32 = 1280 / 2; -const HEIGHT: i32 = 720 / 2; +const WIDTH: i32 = 1920 / 3; +const HEIGHT: i32 = 1080 / 3; struct World { img: Image, diff --git a/src/window.rs b/src/window.rs index e971f44..8d890f3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,13 +1,16 @@ use crate::image::Image; use crate::vec2::Vec2; use rand::Rng; +use std::cmp::{max, min}; use std::num::NonZeroU32; +use std::time::{Duration, Instant}; use winit::dpi::LogicalSize; use winit::event::VirtualKeyCode::Escape; use winit::event::{ ElementState, Event as WinitEvent, MouseButton as WinitMouseButton, WindowEvent, }; use winit::event_loop::{ControlFlow, EventLoop}; +use winit::platform::run_return::EventLoopExtRunReturn; use winit::window::WindowBuilder; pub enum MouseButton { @@ -61,15 +64,15 @@ impl WindowState { } pub fn run(width: i32, height: i32) { - let event_loop = EventLoop::new(); + let mut event_loop = EventLoop::new(); let window = { let size = LogicalSize::new(width as f64, height as f64); WindowBuilder::new() .with_title("Skunk 2D") .with_inner_size(size) .with_min_inner_size(size) - //.with_decorations(false) - //.with_maximized(true) + .with_decorations(false) + .with_maximized(true) .build(&event_loop) .unwrap() }; @@ -84,7 +87,26 @@ pub fn run(width: i32, height: i32) { let mut window_state = WindowState::new(); let mut game = T::new(&mut window_state); - event_loop.run(move |event, _, control_flow| { + let mut frames_since_last_second = 0; + let mut last_second = Instant::now(); + + let mut last_frame = last_second; + let target_fps = 60; + let target_frame_duration = Duration::from_secs(1) / target_fps; + + let mut scale = 1usize; + let mut off_x = 0usize; + let mut off_y = 0usize; + + event_loop.run_return(move |event, _, control_flow| { + let mut scale = &mut scale; + let mut off_x = &mut off_x; + let mut off_y = &mut off_y; + if Instant::now() - last_second > Duration::from_secs(1) { + println!("fps: {}", frames_since_last_second); + frames_since_last_second = 0; + last_second += Duration::from_secs(1); + } match event { WinitEvent::NewEvents(_) => {} WinitEvent::WindowEvent { @@ -108,16 +130,15 @@ pub fn run(width: i32, height: i32) { *control_flow = ControlFlow::Exit; } }; - if *control_flow == ControlFlow::Exit { - return; - } } WindowEvent::ModifiersChanged(_) => {} WindowEvent::Ime(_) => {} WindowEvent::CursorMoved { position, .. } => { + let x = (position.x as i32 - *off_x as i32) / *scale as i32; + let y = (position.y as i32 - *off_y as i32) / *scale as i32; window_state.mouse_pos = Vec2 { - x: position.x as i32, - y: position.y as i32, + x: min(width - 1, max(0, x)), + y: min(height - 1, max(0, y)), } } WindowEvent::CursorEntered { .. } => {} @@ -156,32 +177,47 @@ pub fn run(width: i32, height: i32) { WinitEvent::UserEvent(_) => {} WinitEvent::Suspended => {} WinitEvent::Resumed => {} - WinitEvent::MainEventsCleared => {} - WinitEvent::RedrawRequested(_) => { - game.draw(&mut screen); + WinitEvent::MainEventsCleared => { + if Instant::now() - last_frame >= target_frame_duration { + game.update(&mut window_state); + game.draw(&mut screen); - let (width, height) = { let size = window.inner_size(); - (size.width, size.height) - }; - surface - .resize( - NonZeroU32::new(width).unwrap(), - NonZeroU32::new(height).unwrap(), - ) - .unwrap(); + surface + .resize( + NonZeroU32::new(size.width).unwrap(), + NonZeroU32::new(size.height).unwrap(), + ) + .unwrap(); - let mut buf = surface.buffer_mut().unwrap(); - for i in 0..(width * height) as usize { - buf[i] = window_state.palette[screen.data()[i] as usize]; + *scale = min(size.width / width as u32, size.height / height as u32) as usize; + *off_x = (size.width as usize - width as usize * *scale) / 2; + *off_y = (size.height as usize - height as usize * *scale) / 2; + + let mut buf = surface.buffer_mut().unwrap(); + for y in 0..height as usize { + for x in 0..width as usize { + let p = window_state.palette + [screen.data()[x + y * width as usize] as usize]; + for iy in 0..*scale { + for ix in 0..*scale { + let tx = x * *scale + ix + *off_x; + let ty = y * *scale + iy + *off_y; + buf[tx + ty * size.width as usize] = p; + } + } + } + } + buf.present().unwrap(); + frames_since_last_second += 1; + last_frame += target_frame_duration; + } else { + std::thread::sleep(Duration::from_millis(1)); } - buf.present().unwrap(); } + WinitEvent::RedrawRequested(_) => {} WinitEvent::RedrawEventsCleared => {} WinitEvent::LoopDestroyed => {} } - - game.update(&mut window_state); - window.request_redraw(); }); }