ScummVM API documentation
viewport.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 //=============================================================================
23 //
24 // Definition for the game viewports and cameras.
25 //
26 //=============================================================================
27 
28 #ifndef AGS_ENGINE_GAME_VIEWPORT_H
29 #define AGS_ENGINE_GAME_VIEWPORT_H
30 
31 #include "common/std/memory.h"
32 #include "common/std/vector.h"
33 #include "ags/shared/util/geometry.h"
34 #include "ags/shared/util/scaling.h"
35 
36 namespace AGS3 {
37 
38 class Camera;
39 class Viewport;
40 
41 typedef std::shared_ptr<Camera> PCamera;
42 typedef std::shared_ptr<Viewport> PViewport;
43 typedef std::weak_ptr<Camera> CameraRef;
44 typedef std::weak_ptr<Viewport> ViewportRef;
45 
46 // TODO: move to utility header
47 // From https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned
48 // Tests that weak_ptr is empty (was not initialized with valid reference)
49 template <typename T>
50 bool is_uninitialized(std::weak_ptr<T> const &weak) {
51  using wt = std::weak_ptr<T>;
52  return !weak.owner_before(wt{}) &&!wt{} .owner_before(weak);
53 }
54 
55 
56 // Camera defines a "looking eye" inside the room, its position and size.
57 // It does not render anywhere on its own, instead it is linked to a viewport
58 // and latter draws what that camera sees.
59 // One camera may be linked to multiple viewports.
60 // Camera does not move on its own, this is performed by separate behavior
61 // algorithm. But it provides "lock" property that tells if its position is
62 // currently owned by user script.
63 class Camera {
64 public:
65  // Gets camera ID (serves as an index)
66  inline int GetID() const {
67  return _id;
68  }
69  // Sets new camera ID
70  void SetID(int id);
71  // Returns Room camera position and size inside the room (in room coordinates)
72  const Rect &GetRect() const;
73  // Sets explicit room camera's orthographic size
74  void SetSize(const Size sz);
75  // Puts room camera to the new location in the room
76  void SetAt(int x, int y);
77  // Tells if camera is currently locked at custom position
78  bool IsLocked() const;
79  // Locks room camera at its current position
80  void Lock();
81  // Similar to SetAt, but also locks camera preventing it from following player character
82  void LockAt(int x, int y);
83  // Releases camera lock, letting it follow player character
84  void Release();
85 
86  // Link this camera to a new viewport; this does not unlink any linked ones
87  void LinkToViewport(ViewportRef viewport);
88  // Unlinks this camera from a given viewport; does nothing if link did not exist
89  void UnlinkFromViewport(int id);
90  // Get the array of linked viewport references
91  const std::vector<ViewportRef> &GetLinkedViewports() const;
92 
93  // Tell if this camera has changed recently
94  inline bool HasChangedPosition() const {
95  return _hasChangedPosition;
96  }
97  inline bool HasChangedSize() const {
98  return _hasChangedSize;
99  }
100  // Clears the changed flags
101  void ClearChangedFlags() {
102  _hasChangedPosition = false;
103  _hasChangedSize = false;
104  }
105 
106 private:
107  int _id = -1;
108  // Actual position and orthographic size
109  Rect _position;
110  // Locked or following player automatically
111  bool _locked = false;
112  // Linked viewport refs, used to notify viewports of camera changes
113  std::vector<ViewportRef> _viewportRefs;
114  // Flags that tell whether this camera's position on screen has changed recently
115  bool _hasChangedPosition = false;
116  bool _hasChangedSize = false;
117 };
118 
119 
120 // A result of coordinate conversion between screen and the room,
121 // tells which viewport was used to pass the "touch" through.
123 
124 
125 // Viewport class defines a rectangular area on game screen where the contents
126 // of a Camera are rendered.
127 // Viewport may have one linked camera at a time.
128 class Viewport {
129 public:
130  // Gets viewport ID (serves as an index)
131  inline int GetID() const {
132  return _id;
133  }
134  // Sets new viewport ID
135  void SetID(int id);
136  // Returns viewport's position on screen
137  inline const Rect &GetRect() const {
138  return _position;
139  }
140  // Returns viewport's room-to-screen transformation
141  inline const AGS::Shared::PlaneScaling &GetTransform() const {
142  return _transform;
143  }
144  // Set viewport's rectangle on screen
145  void SetRect(const Rect &rc);
146  // Sets viewport size
147  void SetSize(const Size sz);
148  // Sets viewport's position on screen
149  void SetAt(int x, int y);
150 
151  // Tells whether viewport content is rendered on screen
152  bool IsVisible() const {
153  return _visible;
154  }
155  // Changes viewport visibility
156  void SetVisible(bool on);
157  // Gets the order viewport is displayed on screen
158  int GetZOrder() const {
159  return _zorder;
160  }
161  // Sets the viewport's z-order on screen
162  void SetZOrder(int zorder);
163 
164  // Calculates room-to-viewport coordinate conversion.
165  void AdjustTransformation();
166  // Returns linked camera
167  PCamera GetCamera() const;
168  // Links new camera to this viewport, overriding existing link;
169  // pass nullptr to leave viewport without a camera link
170  void LinkCamera(PCamera cam);
171 
172  // TODO: provide a Transform object here that does these conversions instead
173  // Converts room coordinates to the game screen coordinates through this viewport;
174  // if clipping is on, the function will fail for room coordinates outside of camera
175  VpPoint RoomToScreen(int roomx, int roomy, bool clip = false) const;
176  // Converts game screen coordinates to the room coordinates through this viewport;
177  // if clipping is on, the function will fail for screen coordinates outside of viewport;
178  // convert_cam_to_data parameter converts camera "game" coordinates to "data" units (legacy mode)
179  VpPoint ScreenToRoom(int scrx, int scry, bool clip = false, bool convert_cam_to_data = false) const;
180 
181  // Following functions tell if this viewport has changed recently
182  inline bool HasChangedPosition() const {
183  return _hasChangedPosition;
184  }
185  inline bool HasChangedSize() const {
186  return _hasChangedSize;
187  }
188  inline bool HasChangedVisible() const {
189  return _hasChangedVisible;
190  }
191  inline void SetChangedVisible() {
192  _hasChangedVisible = true;
193  }
194  // Clears the changed flags
195  inline void ClearChangedFlags() {
196  _hasChangedPosition = false;
197  _hasChangedSize = false;
198  _hasChangedVisible = false;
199  }
200 
201 private:
202  // Parameterized implementation of screen-to-room coordinate conversion
203  VpPoint ScreenToRoomImpl(int scrx, int scry, bool clip, bool convert_cam_to_data);
204 
205  int _id = -1;
206  // Position of the viewport on screen
207  Rect _position;
208  // TODO: Camera reference (when supporting multiple cameras)
209  // Coordinate transform between camera and viewport
210  // TODO: need to add rotate conversion to let script API support that;
211  // (maybe use full 3D matrix for that)
212  AGS::Shared::PlaneScaling _transform;
213  // Linked camera reference
214  CameraRef _camera;
215  bool _visible = true;
216  int _zorder = 0;
217  // Flags that tell whether this viewport's position on screen has changed recently
218  bool _hasChangedPosition = false;
219  bool _hasChangedOffscreen = false;
220  bool _hasChangedSize = false;
221  bool _hasChangedVisible = false;
222 };
223 
224 } // namespace AGS3
225 
226 #endif // AGS_ENGINE_AC_VIEWPORT_H
Definition: vector.h:39
Definition: ptr.h:115
bool owner_before(const WeakPtr< T2 > &other) const
Definition: ptr.h:474
Definition: utility.h:39
Definition: viewport.h:128
Definition: viewport.h:63
Definition: scaling.h:108
Definition: geometry.h:215
Definition: geometry.h:144
Definition: ptr.h:159
Definition: ags.h:40