diff --git a/examples/conway/src/main.rs b/examples/conway/src/main.rs index e1b2e74..1c4ed1d 100644 --- a/examples/conway/src/main.rs +++ b/examples/conway/src/main.rs @@ -3,25 +3,40 @@ use log::{debug, error}; use pixels::{Error, Pixels, SurfaceTexture}; -use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; -use winit::event::{Event, VirtualKeyCode}; -use winit::event_loop::{ControlFlow, EventLoop}; +use winit::{ + dpi::LogicalSize, + event::{Event, VirtualKeyCode}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; use winit_input_helper::WinitInputHelper; -const SCREEN_WIDTH: u32 = 400; -const SCREEN_HEIGHT: u32 = 300; +const WIDTH: u32 = 400; +const HEIGHT: u32 = 300; fn main() -> Result<(), Error> { env_logger::init(); let event_loop = EventLoop::new(); let mut input = WinitInputHelper::new(); - let (window, p_width, p_height, mut _hidpi_factor) = - create_window("Conway's Game of Life", &event_loop); - let surface_texture = SurfaceTexture::new(p_width, p_height, &window); + let window = { + let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64); + let scaled_size = LogicalSize::new(WIDTH as f64 * 3.0, HEIGHT as f64 * 3.0); + WindowBuilder::new() + .with_title("Conway's Game of Life") + .with_inner_size(scaled_size) + .with_min_inner_size(size) + .build(&event_loop) + .unwrap() + }; - let mut life = ConwayGrid::new_random(SCREEN_WIDTH as usize, SCREEN_HEIGHT as usize); - let mut pixels = Pixels::new(SCREEN_WIDTH, SCREEN_HEIGHT, surface_texture)?; + let mut pixels = { + let window_size = window.inner_size(); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + Pixels::new(WIDTH, HEIGHT, surface_texture)? + }; + + let mut life = ConwayGrid::new_random(WIDTH as usize, HEIGHT as usize); let mut paused = false; let mut draw_state: Option = None; @@ -108,10 +123,6 @@ fn main() -> Result<(), Error> { draw_state = None; } } - // Adjust high DPI factor - if let Some(factor) = input.scale_factor_changed() { - _hidpi_factor = factor; - } // Resize the window if let Some(size) = input.window_resized() { pixels.resize_surface(size.width, size.height); @@ -124,64 +135,6 @@ fn main() -> Result<(), Error> { }); } -// COPYPASTE: ideally this could be shared. - -/// Create a window for the game. -/// -/// Automatically scales the window to cover about 2/3 of the monitor height. -/// -/// # Returns -/// -/// Tuple of `(window, surface, width, height, hidpi_factor)` -/// `width` and `height` are in `PhysicalSize` units. -fn create_window( - title: &str, - event_loop: &EventLoop<()>, -) -> (winit::window::Window, u32, u32, f64) { - // Create a hidden window so we can estimate a good default window size - let window = winit::window::WindowBuilder::new() - .with_visible(false) - .with_title(title) - .build(event_loop) - .unwrap(); - let hidpi_factor = window.scale_factor(); - - // Get dimensions - let width = SCREEN_WIDTH as f64; - let height = SCREEN_HEIGHT as f64; - let (monitor_width, monitor_height) = { - if let Some(monitor) = window.current_monitor() { - let size = monitor.size().to_logical(hidpi_factor); - (size.width, size.height) - } else { - (width, height) - } - }; - let scale = (monitor_height / height * 2.0 / 3.0).round().max(1.0); - - // Resize, center, and display the window - let min_size: winit::dpi::LogicalSize = - PhysicalSize::new(width, height).to_logical(hidpi_factor); - let default_size = LogicalSize::new(width * scale, height * scale); - let center = LogicalPosition::new( - (monitor_width - width * scale) / 2.0, - (monitor_height - height * scale) / 2.0, - ); - window.set_inner_size(default_size); - window.set_min_inner_size(Some(min_size)); - window.set_outer_position(center); - window.set_visible(true); - - let size = default_size.to_physical::(hidpi_factor); - - ( - window, - size.width.round() as u32, - size.height.round() as u32, - hidpi_factor, - ) -} - /// Generate a pseudorandom seed for the game's PRNG. fn generate_seed() -> (u64, u64) { use byteorder::{ByteOrder, NativeEndian}; diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs index bfc6ddf..55c326d 100644 --- a/examples/invaders/simple-invaders/src/lib.rs +++ b/examples/invaders/simple-invaders/src/lib.rs @@ -24,9 +24,9 @@ mod loader; mod sprites; /// The screen width is constant (units are in pixels) -pub const SCREEN_WIDTH: usize = 224; +pub const WIDTH: usize = 224; /// The screen height is constant (units are in pixels) -pub const SCREEN_HEIGHT: usize = 256; +pub const HEIGHT: usize = 256; // Invader positioning const START: Point = Point::new(24, 64); @@ -343,7 +343,7 @@ impl World { } } Direction::Right => { - if right > SCREEN_WIDTH - 2 { + if right > WIDTH - 2 { self.invaders.bounds.pos.x -= 2; self.invaders.bounds.pos.y += 8; self.invaders.descend = true; @@ -406,7 +406,7 @@ impl World { } Direction::Right => { - if self.player.pos.x < SCREEN_WIDTH - width * 2 { + if self.player.pos.x < WIDTH - width * 2 { self.player.pos.x += frames; self.player.sprite.animate(&self.assets, dt); } diff --git a/examples/invaders/simple-invaders/src/sprites.rs b/examples/invaders/simple-invaders/src/sprites.rs index 7b8f1c9..9130a2c 100644 --- a/examples/invaders/simple-invaders/src/sprites.rs +++ b/examples/invaders/simple-invaders/src/sprites.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use std::time::Duration; use crate::loader::Assets; -use crate::{Point, SCREEN_HEIGHT, SCREEN_WIDTH}; +use crate::{Point, HEIGHT, WIDTH}; use line_drawing::Bresenham; // This is the type stored in the `Assets` hash map @@ -191,15 +191,15 @@ pub(crate) fn blit(screen: &mut [u8], dest: &Point, sprite: &S) where S: Drawable, { - assert!(dest.x + sprite.width() <= SCREEN_WIDTH); - assert!(dest.y + sprite.height() <= SCREEN_HEIGHT); + assert!(dest.x + sprite.width() <= WIDTH); + assert!(dest.y + sprite.height() <= HEIGHT); let pixels = sprite.pixels(); let width = sprite.width() * 4; let mut s = 0; for y in 0..sprite.height() { - let i = dest.x * 4 + dest.y * SCREEN_WIDTH * 4 + y * SCREEN_WIDTH * 4; + let i = dest.x * 4 + dest.y * WIDTH * 4 + y * WIDTH * 4; // Merge pixels from sprite into screen let zipped = screen[i..i + width].iter_mut().zip(&pixels[s..s + width]); @@ -219,9 +219,9 @@ pub(crate) fn line(screen: &mut [u8], p1: &Point, p2: &Point, color: [u8; 4]) { let p2 = (p2.x as i64, p2.y as i64); for (x, y) in Bresenham::new(p1, p2) { - let x = min(x as usize, SCREEN_WIDTH - 1); - let y = min(y as usize, SCREEN_HEIGHT - 1); - let i = x * 4 + y * SCREEN_WIDTH * 4; + let x = min(x as usize, WIDTH - 1); + let y = min(y as usize, HEIGHT - 1); + let i = x * 4 + y * WIDTH * 4; screen[i..i + 4].copy_from_slice(&color); } diff --git a/examples/invaders/src/main.rs b/examples/invaders/src/main.rs index 4e611d2..6058a56 100644 --- a/examples/invaders/src/main.rs +++ b/examples/invaders/src/main.rs @@ -1,16 +1,17 @@ #![deny(clippy::all)] #![forbid(unsafe_code)] -use std::env; -use std::time::Instant; - use gilrs::{Button, Gilrs}; use log::{debug, error}; use pixels::{Error, Pixels, SurfaceTexture}; -use simple_invaders::{Controls, Direction, World, SCREEN_HEIGHT, SCREEN_WIDTH}; -use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; -use winit::event::{Event, VirtualKeyCode}; -use winit::event_loop::{ControlFlow, EventLoop}; +use simple_invaders::{Controls, Direction, World, HEIGHT, WIDTH}; +use std::{env, time::Instant}; +use winit::{ + dpi::LogicalSize, + event::{Event, VirtualKeyCode}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; use winit_input_helper::WinitInputHelper; fn main() -> Result<(), Error> { @@ -25,9 +26,23 @@ fn main() -> Result<(), Error> { .parse() .unwrap_or(false); - let (window, width, height, mut _hidpi_factor) = create_window("pixel invaders", &event_loop); - let surface_texture = SurfaceTexture::new(width, height, &window); - let mut pixels = Pixels::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32, surface_texture)?; + let window = { + let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64); + let scaled_size = LogicalSize::new(WIDTH as f64 * 3.0, HEIGHT as f64 * 3.0); + WindowBuilder::new() + .with_title("pixel invaders") + .with_inner_size(scaled_size) + .with_min_inner_size(size) + .build(&event_loop) + .unwrap() + }; + + let mut pixels = { + let window_size = window.inner_size(); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + Pixels::new(WIDTH as u32, HEIGHT as u32, surface_texture)? + }; + let mut invaders = World::new(generate_seed(), debug); let mut time = Instant::now(); let mut gamepad = None; @@ -96,11 +111,6 @@ fn main() -> Result<(), Error> { Controls { direction, fire } }; - // Adjust high DPI factor - if let Some(factor) = input.scale_factor_changed() { - _hidpi_factor = factor; - } - // Resize the window if let Some(size) = input.window_resized() { pixels.resize_surface(size.width, size.height); @@ -118,61 +128,6 @@ fn main() -> Result<(), Error> { }); } -/// Create a window for the game. -/// -/// Automatically scales the window to cover about 2/3 of the monitor height. -/// -/// # Returns -/// -/// Tuple of `(window, surface, width, height, hidpi_factor)` -/// `width` and `height` are in `PhysicalSize` units. -fn create_window( - title: &str, - event_loop: &EventLoop<()>, -) -> (winit::window::Window, u32, u32, f64) { - // Create a hidden window so we can estimate a good default window size - let window = winit::window::WindowBuilder::new() - .with_visible(false) - .with_title(title) - .build(event_loop) - .unwrap(); - let hidpi_factor = window.scale_factor(); - - // Get dimensions - let width = SCREEN_WIDTH as f64; - let height = SCREEN_HEIGHT as f64; - let (monitor_width, monitor_height) = { - if let Some(monitor) = window.current_monitor() { - let size = monitor.size().to_logical(hidpi_factor); - (size.width, size.height) - } else { - (width, height) - } - }; - let scale = (monitor_height / height * 2.0 / 3.0).round().max(1.0); - - // Resize, center, and display the window - let min_size = PhysicalSize::new(width, height).to_logical::(hidpi_factor); - let default_size = LogicalSize::new(width * scale, height * scale); - let center = LogicalPosition::new( - (monitor_width - width * scale) / 2.0, - (monitor_height - height * scale) / 2.0, - ); - window.set_inner_size(default_size); - window.set_min_inner_size(Some(min_size)); - window.set_outer_position(center); - window.set_visible(true); - - let size = default_size.to_physical::(hidpi_factor); - - ( - window, - size.width.round() as u32, - size.height.round() as u32, - hidpi_factor, - ) -} - /// Generate a pseudorandom seed for the game's PRNG. fn generate_seed() -> (u64, u64) { use byteorder::{ByteOrder, NativeEndian};