/// The magnitude of deviation from our internal aspect ratio that we allow
/// the window to have (before we start boxing the screen)
// TODO add sidebars (pillar/letterboxes) and stuff?
const ASPECT_DEVIATION: f32 = 0.1;
/// Updates the camera for displaying to the given window
///
/// Returns the amount of scaling the camera did in the (x, y) directions
/// None is returned if the amount did not change
fn update_aspect(&mut self, window: &Window) -> Option<(f32, f32)> {
let window_size = window.inner_size();
if self
.cached_window_size
.is_some_and(|cws| cws == window_size)
{
// If the window's size hasn't changed, then we don't need to update
return None;
} else {
// Calculate for the new window size
self.cached_window_size = Some(window_size);
}
let window_aspect_ratio = window_size.width as f32 / window_size.height as f32;
let target_aspect_ratio = self.width / self.height;
if (window_aspect_ratio - target_aspect_ratio).abs() <= Self::ASPECT_DEVIATION {
self.real_width = self.width;
self.real_height = self.height;
Some((1.0, 1.0))
} else if window_aspect_ratio < target_aspect_ratio {
// window is not wide enough, scale to match width
let correction = target_aspect_ratio / window_aspect_ratio;
// TODO add pillarboxes with width (1.0 - correction) / 2.0 * window_size.width;
log::warn!(
"Aspect difference: {window_aspect_ratio} > {target_aspect_ratio} c {correction}"
);
self.real_width = self.width * correction;
self.real_height = self.height;
// These are always reciprocals because we scaled the width *up* internally
// by that much to all the necessary width into the window, so the window should make the entire
// display of the game world take up (1.0 - correction.recip()), so we reciprocate now, so
// we don't have to later
Some((correction.recip(), 1.0))
} else {
// window is not tall enough, scale to match height
let correction = window_aspect_ratio / target_aspect_ratio;
// TODO add letterboxes with height (1.0 - correction) / 2.0 * window_size.height;
log::warn!(
"Aspect difference: {window_aspect_ratio} < {target_aspect_ratio} c {correction}"
);
self.real_width = self.width;
self.real_height = self.height * correction;
// ditto
Some((1.0, correction.recip()))
}
}