diff --git a/src/main.rs b/src/main.rs index dc45838..d99913a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -973,7 +973,12 @@ async fn main() { // 900 rows (360 -> 1080), on a desktop and on a touch screen alike (a phone has about // 1080 device rows in landscape; a smaller screen draws in device pixels) let need: u32 = 900; - ui::set_virtual_rows(rows * need.div_ceil(rows)); + // measured on the shorter side: upright (portrait) the width gets those pixels and the + // height grows with the screen, so the world and the menus keep their size + let short = rows * need.div_ceil(rows); + let (w, h) = (screen_width().max(1.0), screen_height().max(1.0)); + let vrows = if h > w { (short as f32 * h / w).round() as u32 } else { short }; + ui::set_virtual_rows(vrows); if touch_mode { // the pointer is the finger, or the position of this frame's gesture let gpos = gestures.iter().rev().find_map(|g| match *g { diff --git a/src/render3d.rs b/src/render3d.rs index 43b2624..ad70d6b 100644 --- a/src/render3d.rs +++ b/src/render3d.rs @@ -85,12 +85,18 @@ impl Cam { vec3(self.rx, 0.0, self.rz) } + // visible world height in tiles: the zoom counts on the shorter side (upright screens: across) + pub fn view_h(&self) -> f32 { + let (w, h) = (screen_width().max(1.0), screen_height().max(1.0)); + if h > w { self.zoom * h / w } else { self.zoom } + } + pub fn camera(&self) -> Camera3D { Camera3D { position: self.target() + self.eye_dir() * 60.0, target: self.target(), up: Vec3::Y, - fovy: self.zoom, + fovy: self.view_h(), projection: Projection::Orthographics, z_near: 1.0, z_far: 200.0, @@ -114,7 +120,7 @@ impl Cam { pub fn ray(&self, sx: f32, sy: f32) -> (Vec3, Vec3) { let (f, r, u) = self.basis(); - let half_h = self.zoom * 0.5; + let half_h = self.view_h() * 0.5; let half_w = half_h * screen_width() / screen_height(); let nx = sx / screen_width() * 2.0 - 1.0; let ny = 1.0 - sy / screen_height() * 2.0; @@ -1468,7 +1474,7 @@ impl R3d { // Entity under the mouse (screen-space test against the projected sprite) pub fn pick_ent(&self, g: &Game, cam: &Cam, sx: f32, sy: f32, player_only: bool) -> Option { let m = cam.matrix(); - let px_per_tile = screen_height() / cam.zoom; + let px_per_tile = screen_height() / cam.view_h(); let mut best = None; let mut bd = (px_per_tile * 0.4).max(10.0); for (j, e) in g.ents.iter().enumerate() { @@ -1494,7 +1500,9 @@ impl R3d { // on the virtual screen (ui.rs) the world takes exactly k x k interface pixels per pixel let vrows = crate::ui::virtual_rows(); let pix = if vrows > 0 && self.pixel_rows > 0 { - let k = (vrows / self.pixel_rows).max(1); + // the pixel rows count on the shorter side (upright screens: across) + let short = vrows.min(crate::ui::sw().round() as u32); + let k = (short / self.pixel_rows).max(1); let th = vrows / k; Some(((crate::ui::sw() / k as f32).ceil() as u32, th, k as f32)) } else {