Support resizing the window
This commit is contained in:
parent
593475960d
commit
75fa3be25c
67
src/app.rs
67
src/app.rs
|
@ -8,7 +8,7 @@ use wgpu::util::DeviceExt as _;
|
||||||
use winit::platform::windows::{CornerPreference, WindowAttributesExtWindows as _};
|
use winit::platform::windows::{CornerPreference, WindowAttributesExtWindows as _};
|
||||||
use winit::{
|
use winit::{
|
||||||
application::ApplicationHandler,
|
application::ApplicationHandler,
|
||||||
dpi::LogicalSize,
|
dpi::{LogicalSize, PhysicalSize},
|
||||||
event::{ElementState, Event, WindowEvent},
|
event::{ElementState, Event, WindowEvent},
|
||||||
event_loop::ActiveEventLoop,
|
event_loop::ActiveEventLoop,
|
||||||
keyboard::Key,
|
keyboard::Key,
|
||||||
|
@ -297,17 +297,8 @@ impl ApplicationHandler for App {
|
||||||
|
|
||||||
match &event {
|
match &event {
|
||||||
WindowEvent::Resized(size) => {
|
WindowEvent::Resized(size) => {
|
||||||
window.surface_desc = wgpu::SurfaceConfiguration {
|
window.surface_desc.width = size.width;
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
window.surface_desc.height = size.height;
|
||||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
|
||||||
width: size.width,
|
|
||||||
height: size.height,
|
|
||||||
present_mode: wgpu::PresentMode::Fifo,
|
|
||||||
desired_maximum_frame_latency: 2,
|
|
||||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
|
||||||
view_formats: vec![wgpu::TextureFormat::Bgra8Unorm],
|
|
||||||
};
|
|
||||||
|
|
||||||
window
|
window
|
||||||
.surface
|
.surface
|
||||||
.configure(&window.device, &window.surface_desc);
|
.configure(&window.device, &window.surface_desc);
|
||||||
|
@ -345,9 +336,9 @@ impl ApplicationHandler for App {
|
||||||
.prepare_frame(imgui.context.io_mut(), &window.window)
|
.prepare_frame(imgui.context.io_mut(), &window.window)
|
||||||
.expect("Failed to prepare frame");
|
.expect("Failed to prepare frame");
|
||||||
let ui = imgui.context.frame();
|
let ui = imgui.context.frame();
|
||||||
let mut height = 0.0;
|
let mut menu_height = 0.0;
|
||||||
ui.main_menu_bar(|| {
|
ui.main_menu_bar(|| {
|
||||||
height = ui.window_size()[1];
|
menu_height = ui.window_size()[1];
|
||||||
ui.menu("ROM", || {
|
ui.menu("ROM", || {
|
||||||
if ui.menu_item("Open ROM") {
|
if ui.menu_item("Open ROM") {
|
||||||
let rom = native_dialog::FileDialog::new()
|
let rom = native_dialog::FileDialog::new()
|
||||||
|
@ -374,6 +365,27 @@ impl ApplicationHandler for App {
|
||||||
self.client.send_command(EmulatorCommand::Reset);
|
self.client.send_command(EmulatorCommand::Reset);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ui.menu("Video", || {
|
||||||
|
let current_dims = PhysicalSize::new(
|
||||||
|
window.surface_desc.width,
|
||||||
|
window.surface_desc.height,
|
||||||
|
)
|
||||||
|
.to_logical(window.hidpi_factor);
|
||||||
|
for scale in 1..=4 {
|
||||||
|
let label = format!("x{scale}");
|
||||||
|
let dims = LogicalSize::new(384 * scale, 224 * scale + 20);
|
||||||
|
let selected = dims == current_dims;
|
||||||
|
if ui.menu_item_config(label).selected(selected).build() {
|
||||||
|
if let Some(size) = window.window.request_inner_size(dims) {
|
||||||
|
window.surface_desc.width = size.width;
|
||||||
|
window.surface_desc.height = size.height;
|
||||||
|
window
|
||||||
|
.surface
|
||||||
|
.configure(&window.device, &window.surface_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut encoder: wgpu::CommandEncoder = window
|
let mut encoder: wgpu::CommandEncoder = window
|
||||||
|
@ -403,13 +415,19 @@ impl ApplicationHandler for App {
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Draw the game
|
||||||
rpass.set_pipeline(&window.pipeline);
|
rpass.set_pipeline(&window.pipeline);
|
||||||
let hidpi = window.hidpi_factor as f32;
|
let window_width = window.surface_desc.width as f32;
|
||||||
rpass.set_viewport(0.0, height * hidpi, 384.0 * hidpi, 224.0 * hidpi, 0.0, 1.0);
|
let window_height = window.surface_desc.height as f32;
|
||||||
|
let menu_height = menu_height * window.hidpi_factor as f32;
|
||||||
|
let ((x, y), (width, height)) =
|
||||||
|
compute_game_bounds(window_width, window_height, menu_height);
|
||||||
|
rpass.set_viewport(x, y, width, height, 0.0, 1.0);
|
||||||
rpass.set_bind_group(0, &window.bind_group, &[]);
|
rpass.set_bind_group(0, &window.bind_group, &[]);
|
||||||
rpass.draw(0..6, 0..1);
|
rpass.draw(0..6, 0..1);
|
||||||
|
|
||||||
rpass.set_viewport(0.0, 0.0, 384.0 * hidpi, 224.0 * hidpi, 0.0, 1.0);
|
// Draw the menu on top of the game
|
||||||
|
rpass.set_viewport(0.0, 0.0, window_width, window_height, 0.0, 1.0);
|
||||||
imgui
|
imgui
|
||||||
.renderer
|
.renderer
|
||||||
.render(
|
.render(
|
||||||
|
@ -473,6 +491,21 @@ impl ApplicationHandler for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_game_bounds(
|
||||||
|
window_width: f32,
|
||||||
|
window_height: f32,
|
||||||
|
menu_height: f32,
|
||||||
|
) -> ((f32, f32), (f32, f32)) {
|
||||||
|
let available_width = window_width;
|
||||||
|
let available_height = window_height - menu_height;
|
||||||
|
|
||||||
|
let width = available_width.min(available_height * 384.0 / 224.0);
|
||||||
|
let height = available_height.min(available_width * 224.0 / 384.0);
|
||||||
|
let x = (available_width - width) / 2.0;
|
||||||
|
let y = menu_height + (available_height - height) / 2.0;
|
||||||
|
((x, y), (width, height))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct Colors {
|
struct Colors {
|
||||||
|
|
Loading…
Reference in New Issue