Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
LogicalViewport.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <optional>
4
6{
7 // The legacy 2D/UI contract remains 4:3. The historical 3D viewport is
8 // independently 800x450 (16:9) and can therefore use the full modern
9 // presentation surface without stretching the UI.
10 inline constexpr double LogicalWidth = 800.0;
11 inline constexpr double LogicalHeight = 600.0;
12 inline constexpr double World3DWidth = 800.0;
13 inline constexpr double World3DHeight = 450.0;
14
15 struct Transform
16 {
17 double scale = 0.0;
18 double offsetX = 0.0;
19 double offsetY = 0.0;
20 double pixelWidth = 0.0;
21 double pixelHeight = 0.0;
22
23 [[nodiscard]] bool valid() const noexcept;
24 };
25
27 {
28 double x = 0.0;
29 double y = 0.0;
30 };
31
33 {
34 double x = 0.0;
35 double y = 0.0;
36 double width = 0.0;
37 double height = 0.0;
38 };
39
40 struct PixelRect
41 {
42 double x = 0.0;
43 double y = 0.0;
44 double width = 0.0;
45 double height = 0.0;
46 };
47
48 // Fits the original 800x600 coordinate system inside a pixel extent while
49 // preserving its aspect ratio. Any unused area forms centered letterbox
50 // or pillarbox bars. A non-positive extent produces an invalid transform.
52 int targetWidth,
53 int targetHeight
54 ) noexcept;
55
56 // Fits the historical 16:9 3D canvas independently of the 4:3 UI.
58 int targetWidth,
59 int targetHeight
60 ) noexcept;
61
62 // The content area is half-open: its top and left edges are included,
63 // while its right and bottom edges belong to the surrounding bars/outside
64 // area. This matches the coordinate range produced by pixel-based input.
65 [[nodiscard]] std::optional<LogicalPoint> windowToLogical(
66 const Transform& transform,
67 double windowX,
68 double windowY
69 ) noexcept;
70
71 // The bottom retail UI strip overlays the expanded 16:9 board surface.
72 // Its input stays in the 800x600 canvas, ahead of 3D input remapping.
73 [[nodiscard]] std::optional<LogicalPoint> windowToUIOverlay(
74 const Transform& uiTransform, double windowX, double windowY) noexcept;
75
76 // UI outside the authored 3D viewport overlays its expanded pixel area.
77 // A modal owns the entire UI canvas, including any area over the board.
78 [[nodiscard]] std::optional<LogicalPoint> windowToUIOverlay(
79 const Transform& uiTransform, double windowX, double windowY,
80 const LogicalRect& worldViewport, bool modal = false) noexcept;
81
82 // Converts a logical rectangle without clipping or integer rounding. The
83 // caller can apply the rounding policy required by its rendering backend.
85 const Transform& transform,
87 ) noexcept;
88}
std::uint32_t height
std::uint32_t width
unsigned index
std::optional< LogicalPoint > windowToUIOverlay(const Transform &uiTransform, double windowX, double windowY) noexcept
Transform makeTransform(int targetWidth, int targetHeight) noexcept
PixelRect logicalToPixelRect(const Transform &transform, const LogicalRect &logicalRect) noexcept
std::optional< LogicalPoint > windowToLogical(const Transform &transform, double windowX, double windowY) noexcept
Transform makeWorld3DTransform(int targetWidth, int targetHeight) noexcept